From 3af75db12e3d3537bc01c06bbdc876cb17e82b35 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 24 Aug 2017 09:22:57 +0900 Subject: iio: adc: ti-ads1015: fix comparator polarity setting The comparator polarity field in config register is not correctly initialized as per the interrupt trigger setting. Because the bitfield definision is wrong and bit shifting is missed. Fixes: d9f39babd8ba ("iio: adc: ti-ads1015: add threshold event support") Cc: Daniel Baluta Cc: Jonathan Cameron Signed-off-by: Akinobu Mita Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads1015.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index d1210024f6bc..e0dc20488335 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -52,7 +52,7 @@ #define ADS1015_CFG_COMP_QUE_MASK GENMASK(1, 0) #define ADS1015_CFG_COMP_LAT_MASK BIT(2) -#define ADS1015_CFG_COMP_POL_MASK BIT(2) +#define ADS1015_CFG_COMP_POL_MASK BIT(3) #define ADS1015_CFG_COMP_MODE_MASK BIT(4) #define ADS1015_CFG_DR_MASK GENMASK(7, 5) #define ADS1015_CFG_MOD_MASK BIT(8) @@ -1017,10 +1017,12 @@ static int ads1015_probe(struct i2c_client *client, switch (irq_trig) { case IRQF_TRIGGER_LOW: - cfg_comp |= ADS1015_CFG_COMP_POL_LOW; + cfg_comp |= ADS1015_CFG_COMP_POL_LOW << + ADS1015_CFG_COMP_POL_SHIFT; break; case IRQF_TRIGGER_HIGH: - cfg_comp |= ADS1015_CFG_COMP_POL_HIGH; + cfg_comp |= ADS1015_CFG_COMP_POL_HIGH << + ADS1015_CFG_COMP_POL_SHIFT; break; default: return -EINVAL; -- cgit v1.2.3 From c65e3d6ef4bfdc4c8460509f08507cf7dc026974 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 29 Aug 2017 13:45:11 +0200 Subject: iio: magnetometer: st_magn: fix drdy line configuration for LIS3MDL Data-ready line in LIS3MDL is routed to drdy pin and it is not possible to select a different INT pin. st_sensors_set_dataready_irq() assumes that if drdy int address is not exported in register map, irq trigger is not supported by the sensor and hw_irq_trigger is always false. Based on this configuration st_sensors_irq_thread does not consume generated interrupt causing an unhandled irq. Fix this taking into account status register address in st_sensors_set_dataready_irq() Fixes: 90efe0556292 (iio: st_sensors: harden interrupt handling) Signed-off-by: Lorenzo Bianconi Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/common/st_sensors/st_sensors_core.c | 11 ++++++++++- drivers/iio/magnetometer/st_magn_core.c | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index d99bb1460fe2..02e833b14db0 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -463,8 +463,17 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) u8 drdy_mask; struct st_sensor_data *sdata = iio_priv(indio_dev); - if (!sdata->sensor_settings->drdy_irq.addr) + if (!sdata->sensor_settings->drdy_irq.addr) { + /* + * there are some devices (e.g. LIS3MDL) where drdy line is + * routed to a given pin and it is not possible to select a + * different one. Take into account irq status register + * to understand if irq trigger can be properly supported + */ + if (sdata->sensor_settings->drdy_irq.addr_stat_drdy) + sdata->hw_irq_trigger = enable; return 0; + } /* Enable/Disable the interrupt generator 1. */ if (sdata->sensor_settings->drdy_irq.ig1.en_addr > 0) { diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 703e77008652..2e36d746f5bc 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -315,6 +315,10 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { }, }, }, + .drdy_irq = { + /* drdy line is routed drdy pin */ + .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + }, .multi_read_bit = true, .bootime = 2, }, -- cgit v1.2.3 From ce06760ba46b66dae50f2519ae76bd15e89b5710 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 31 Aug 2017 15:50:03 -0700 Subject: HID: wacom: bits shifted too much for 9th and 10th buttons Cintiq 12 has 10 expresskey buttons. The bit shift for the last two buttons were off by 5. Fixes: c7f0522 ("HID: wacom: Slim down wacom_intuos_pad processing") Signed-off-by: Ping Cheng Tested-by: Matthieu Robin Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bb17d7bbefd3..f8ddcaaa2ac6 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -567,8 +567,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) keys = data[9] & 0x07; } } else { - buttons = ((data[6] & 0x10) << 10) | - ((data[5] & 0x10) << 9) | + buttons = ((data[6] & 0x10) << 5) | + ((data[5] & 0x10) << 4) | ((data[6] & 0x0F) << 4) | (data[5] & 0x0F); } -- cgit v1.2.3 From 74aebed6dc13425233f2224668353cff7a112776 Mon Sep 17 00:00:00 2001 From: Aaron Armstrong Skomra Date: Mon, 28 Aug 2017 14:15:39 -0700 Subject: HID: wacom: leds: Don't try to control the EKR's read-only LEDs Commit a50aac7193f1 introduces 'led.groups' and adds EKR support for these groups. However, unlike the other devices with LEDs, the EKR's LEDs are read-only and we shouldn't attempt to control them in wacom_led_control(). See bug: https://sourceforge.net/p/linuxwacom/bugs/342/ Fixes: a50aac7193f1 ("HID: wacom: leds: dynamically allocate LED groups") Cc: stable # 4.9 Signed-off-by: Aaron Armstrong Skomra Reviewed-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e82a696a1d07..735bfbbcaa82 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -766,6 +766,9 @@ static int wacom_led_control(struct wacom *wacom) if (!wacom->led.groups) return -ENOTSUPP; + if (wacom->wacom_wac.features.type == REMOTE) + return -ENOTSUPP; + if (wacom->wacom_wac.pid) { /* wireless connected */ report_id = WAC_CMD_WL_LED_CONTROL; buf_size = 13; -- cgit v1.2.3 From a3ae552b5259e6ffd8d124a9fa9923283af2828a Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 4 Sep 2017 15:40:42 -0400 Subject: HID: add multi-input quirk for IDC6680 touchscreen The Ideacom 6680 touchscreen is found in the Dell Latitude 2100. It has two USB descriptors, the first of which has two input reports. The HID_QUIRK_MULTI_INPUT quirk is needed to keep the correct maximum value for ABS_X/ABS_Y (8191 instead of 65535). Signed-off-by: Nicholas Bishop Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b397a14ab970..11798b10e522 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -533,6 +533,7 @@ #define USB_VENDOR_ID_IDEACOM 0x1cb6 #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 +#define USB_DEVICE_ID_IDEACOM_IDC6680 0x6680 #define USB_VENDOR_ID_ILITEK 0x222a #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a83fa76655b9..f489a5cfcb48 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -99,6 +99,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET }, -- cgit v1.2.3 From e57f4e67a0c73ca1c3afb68928b917906bd82eaf Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 Aug 2017 08:37:52 +0200 Subject: HID: multitouch: Fix system-control buttons not working Some laptops have system-control buttons (e.g. KEY_SLEEP) on the same interface as a hid-multitouch touch-pad. This commit fixes these buttons not working. Signed-off-by: Hans de Goede Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 440b999304a5..5609725df714 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -930,6 +930,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, field->application != HID_DG_PEN && field->application != HID_DG_TOUCHPAD && field->application != HID_GD_KEYBOARD && + field->application != HID_GD_SYSTEM_CONTROL && field->application != HID_CP_CONSUMER_CONTROL && field->application != HID_GD_WIRELESS_RADIO_CTLS && !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && -- cgit v1.2.3 From b63c4c2718d641ba9bec888994f0cb0c23a1ef45 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 30 Aug 2017 15:13:25 -0700 Subject: HID: wacom: Properly report negative values from Intuos Pro 2 Bluetooth The wacom driver's IRQ handler for Bluetooth reports from the 2nd-gen Intuos Pro does not correctly process negative numbers. Values for tilt and rotation (which can go negative) are instead interpreted as unsigned and so jump to very large values when the data should be negative. This commit properly casts the data to ensure we report negative numbers when necessary. Fixes: 4922cd2 ("HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface") Cc: stable@vger.kernel.org # v4.11 Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index f8ddcaaa2ac6..1d9e32d2bc63 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1229,9 +1229,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) if (range) { input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); - input_report_abs(pen_input, ABS_TILT_X, frame[7]); - input_report_abs(pen_input, ABS_TILT_Y, frame[8]); - input_report_abs(pen_input, ABS_Z, get_unaligned_le16(&frame[9])); + input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]); + input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]); + input_report_abs(pen_input, ABS_Z, (int16_t)get_unaligned_le16(&frame[9])); input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); } input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); -- cgit v1.2.3 From d252f4a10fb9c8f7187c6c936ff530039f8cb799 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 30 Aug 2017 15:13:26 -0700 Subject: HID: wacom: Correct coordinate system of touchring and pen twist The MobileStudio Pro, Cintiq Pro, and 2nd-gen Intuos Pro devices use a different coordinate system for their touchring and pen twist than prior devices. Prior devices had zero aligned to the tablet's left and would increase clockwise. Userspace expects data from the kernel to be in this old coordinate space, so adjustments are necessary. While the coordinate system for pen twist is formally defined by the HID standard, no such definition existed for the touchring at the time these tablets were introduced. Future tablets are expected to report touchring data using the same "zero-up clockwise-increasing" coordinate system defined for twist. Fixes: 50066a042d ("HID: wacom: generic: Add support for height, tilt, and twist usages") Fixes: 4922cd26f0 ("HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface") Fixes: 60a2218698 ("HID: wacom: generic: add support for touchring") Cc: stable@vger.kernel.org # 4.10, 4.11 Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 73 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1d9e32d2bc63..78d0398904dc 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1227,11 +1227,17 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) continue; if (range) { + /* Fix rotation alignment: userspace expects zero at left */ + int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]); + rotation += 1800/4; + if (rotation > 899) + rotation -= 1800; + input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]); input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]); - input_report_abs(pen_input, ABS_Z, (int16_t)get_unaligned_le16(&frame[9])); + input_report_abs(pen_input, ABS_Z, rotation); input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); } input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); @@ -1319,12 +1325,19 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom) unsigned char *data = wacom->data; int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01); - int ring = data[285]; - int prox = buttons | (ring & 0x80); + int ring = data[285] & 0x7F; + bool ringstatus = data[285] & 0x80; + bool prox = buttons || ringstatus; + + /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ + ring = 71 - ring; + ring += 3*72/16; + if (ring > 71) + ring -= 72; wacom_report_numbered_buttons(pad_input, 9, buttons); - input_report_abs(pad_input, ABS_WHEEL, (ring & 0x80) ? (ring & 0x7f) : 0); + input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0); input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); @@ -1616,6 +1629,20 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_offset_rotation(struct input_dev *input, struct hid_usage *usage, + int value, int num, int denom) +{ + struct input_absinfo *abs = &input->absinfo[usage->code]; + int range = (abs->maximum - abs->minimum + 1); + + value += num*range/denom; + if (value > abs->maximum) + value -= range; + else if (value < abs->minimum) + value += range; + return value; +} + int wacom_equivalent_usage(int usage) { if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) { @@ -1898,6 +1925,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); int i; bool is_touch_on = value; + bool do_report = false; /* * Avoid reporting this event and setting inrange_state if this usage @@ -1912,6 +1940,29 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field } switch (equivalent_usage) { + case WACOM_HID_WD_TOUCHRING: + /* + * Userspace expects touchrings to increase in value with + * clockwise gestures and have their zero point at the + * tablet's left. HID events "should" be clockwise- + * increasing and zero at top, though the MobileStudio + * Pro and 2nd-gen Intuos Pro don't do this... + */ + if (hdev->vendor == 0x56a && + (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ + hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */ + value = (field->logical_maximum - value); + + if (hdev->product == 0x357 || hdev->product == 0x358) + value = wacom_offset_rotation(input, usage, value, 3, 16); + else if (hdev->product == 0x34d || hdev->product == 0x34e) + value = wacom_offset_rotation(input, usage, value, 1, 2); + } + else { + value = wacom_offset_rotation(input, usage, value, 1, 4); + } + do_report = true; + break; case WACOM_HID_WD_TOUCHRINGSTATUS: if (!value) input_event(input, usage->type, usage->code, 0); @@ -1945,10 +1996,14 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field value, i); /* fall through*/ default: + do_report = true; + break; + } + + if (do_report) { input_event(input, usage->type, usage->code, value); if (value) wacom_wac->hid_data.pad_input_event_flag = true; - break; } } @@ -2089,6 +2144,14 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); wacom_wac->serial[0] |= (__u32)value; return; + case HID_DG_TWIST: + /* + * Userspace expects pen twist to have its zero point when + * the buttons/finger is on the tablet's left. HID values + * are zero when buttons are toward the top. + */ + value = wacom_offset_rotation(input, usage, value, 1, 4); + break; case WACOM_HID_WD_SENSE: wacom_wac->hid_data.sense_state = value; return; -- cgit v1.2.3 From 56d859e11aad4016e1cf864d65a0954d83120571 Mon Sep 17 00:00:00 2001 From: Pavel Tatashin Date: Fri, 25 Aug 2017 18:06:04 -0400 Subject: HID: multitouch: support buttons and trackpoint on Lenovo X1 Tab Gen2 On the 2nd generation Lenovo Tablet only clickpad is working; the trackpoint and three mouse buttons do not work. hid_multitouch must export all inputs in order to get trackpoint and buttons to function. Signed-off-by: Pavel Tatashin Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 11798b10e522..a98919199858 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -661,6 +661,7 @@ #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 +#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 #define USB_VENDOR_ID_LG 0x1fd2 #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 5609725df714..9e8c4d2ba11d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1420,6 +1420,12 @@ static const struct hid_device_id mt_devices[] = { USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, + /* Lenovo X1 TAB Gen 2 */ + { .driver_data = MT_CLS_WIN_8_DUAL, + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_LENOVO, + USB_DEVICE_ID_LENOVO_X1_TAB) }, + /* Anton devices */ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS, MT_USB_DEVICE(USB_VENDOR_ID_ANTON, -- cgit v1.2.3 From fcaa4a07d2a4b541e91da7a55d8b3331f96d1865 Mon Sep 17 00:00:00 2001 From: Shrirang Bagul Date: Thu, 10 Aug 2017 17:54:01 +0800 Subject: HID: multitouch: Support ALPS PTP stick with pid 0x120A This patch adds ALPS PTP sticks with pid/device id 0x120A to the list of devices supported by hid-multitouch. Signed-off-by: Shrirang Bagul Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index a98919199858..832897d4a849 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -75,6 +75,7 @@ #define USB_VENDOR_ID_ALPS_JP 0x044E #define HID_DEVICE_ID_ALPS_U1_DUAL 0x120B +#define HID_DEVICE_ID_ALPS_U1_PTP_2 0x120A #define HID_DEVICE_ID_ALPS_U1_DUAL_PTP 0x121F #define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP 0x1220 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 9e8c4d2ba11d..c78625dceced 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1419,6 +1419,10 @@ static const struct hid_device_id mt_devices[] = { HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, + { .driver_data = MT_CLS_WIN_8_DUAL, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_ALPS_JP, + HID_DEVICE_ID_ALPS_U1_PTP_2) }, /* Lenovo X1 TAB Gen 2 */ { .driver_data = MT_CLS_WIN_8_DUAL, -- cgit v1.2.3 From df0700e53047662c167836bd6fdeea55d5d8dcfa Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 6 Sep 2017 20:24:24 +0100 Subject: drm/i915: Disable snooping (userptr, set-cache-level) on gen4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original gen4 has an issue where writes (both render and blt) into snoopable pages are lost. We've previously worked around this in userspace (ddx, igt) by simply not requesting snoopable buffers, but upon rediscovering this problem for a third time, make the kernel reject such requests with -ENODEV. This disables snooping on userspace buffers for i965g and i965gm (original gen4) machines. Signed-off-by: Chris Wilson Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170906192424.26970-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_pci.c | 2 ++ drivers/gpu/drm/i915/intel_device_info.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 881b5d6708aa..e95baf3c4314 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -168,6 +168,7 @@ static const struct intel_device_info intel_i965g_info __initconst = { .platform = INTEL_I965G, .has_overlay = 1, .hws_needs_physical = 1, + .has_snoop = false, }; static const struct intel_device_info intel_i965gm_info __initconst = { @@ -177,6 +178,7 @@ static const struct intel_device_info intel_i965gm_info __initconst = { .has_overlay = 1, .supports_tv = 1, .hws_needs_physical = 1, + .has_snoop = false, }; static const struct intel_device_info intel_g45_info __initconst = { diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index b17f7045c8f8..43831b09b47a 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -412,8 +412,6 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) else if (INTEL_INFO(dev_priv)->gen >= 9) gen9_sseu_info_init(dev_priv); - WARN_ON(info->has_snoop != !info->has_llc); - DRM_DEBUG_DRIVER("slice mask: %04x\n", info->sseu.slice_mask); DRM_DEBUG_DRIVER("slice total: %u\n", hweight8(info->sseu.slice_mask)); DRM_DEBUG_DRIVER("subslice total: %u\n", -- cgit v1.2.3 From c4860ad60564838994b74e7ee7dd12ceeda0f520 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 31 Jul 2017 19:55:08 +0100 Subject: lib/scatterlist: Fix offset type in sg_alloc_table_from_pages Scatterlist entries have an unsigned int for the offset so correct the sg_alloc_table_from_pages function accordingly. Since these are offsets withing a page, unsigned int is wide enough. Also converts callers which were using unsigned long locally with the lower_32_bits annotation to make it explicitly clear what is happening. v2: Use offset_in_page. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Masahiro Yamada Cc: Pawel Osciak Cc: Marek Szyprowski Cc: Kyungmin Park Cc: Tomasz Stanislawski Cc: Matt Porter Cc: Alexandre Bounine Cc: linux-media@vger.kernel.org Cc: linux-kernel@vger.kernel.org Acked-by: Marek Szyprowski (v1) Reviewed-by: Chris Wilson Reviewed-by: Mauro Carvalho Chehab Link: https://patchwork.freedesktop.org/patch/msgid/20170731185512.20010-1-tvrtko.ursulin@linux.intel.com --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- drivers/rapidio/devices/rio_mport_cdev.c | 4 ++-- include/linux/scatterlist.h | 2 +- lib/scatterlist.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 4f246d166111..2405077fdc71 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -479,7 +479,7 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, { struct vb2_dc_buf *buf; struct frame_vector *vec; - unsigned long offset; + unsigned int offset; int n_pages, i; int ret = 0; struct sg_table *sgt; @@ -507,7 +507,7 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, buf->dev = dev; buf->dma_dir = dma_dir; - offset = vaddr & ~PAGE_MASK; + offset = lower_32_bits(offset_in_page(vaddr)); vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); if (IS_ERR(vec)) { ret = PTR_ERR(vec); diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 5beb0c361076..5c1b6388122a 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -876,10 +876,10 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, * offset within the internal buffer specified by handle parameter. */ if (xfer->loc_addr) { - unsigned long offset; + unsigned int offset; long pinned; - offset = (unsigned long)(uintptr_t)xfer->loc_addr & ~PAGE_MASK; + offset = lower_32_bits(offset_in_page(xfer->loc_addr)); nr_pages = PAGE_ALIGN(xfer->length + offset) >> PAGE_SHIFT; page_list = kmalloc_array(nr_pages, diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 4b3286ac60c8..205aefb4ed93 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -263,7 +263,7 @@ int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, int sg_alloc_table(struct sg_table *, unsigned int, gfp_t); int sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages, unsigned int n_pages, - unsigned long offset, unsigned long size, + unsigned int offset, unsigned long size, gfp_t gfp_mask); size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, diff --git a/lib/scatterlist.c b/lib/scatterlist.c index be7b4dd6b68d..dee0c5004e2f 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -391,7 +391,7 @@ EXPORT_SYMBOL(sg_alloc_table); */ int sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages, unsigned int n_pages, - unsigned long offset, unsigned long size, + unsigned int offset, unsigned long size, gfp_t gfp_mask) { unsigned int chunks; -- cgit v1.2.3 From 5602452e4c9943a81c9cd049d10d37d3f137b0c0 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 3 Aug 2017 10:14:17 +0100 Subject: drm/i915: Use __sg_alloc_table_from_pages for userptr allocations With the addition of __sg_alloc_table_from_pages we can control the maximum coalescing size and eliminate a separate path for allocating backing store here. Similar to 871dfbd67d4e ("drm/i915: Allow compaction upto SWIOTLB max segment size") this enables more compact sg lists to be created and so has a beneficial effect on workloads with many and/or large objects of this class. v2: * Rename helper to i915_sg_segment_size and fix swiotlb override. * Commit message update. v3: * Actually include the swiotlb override fix. v4: * Regroup parameters a bit. (Chris Wilson) v5: * Rebase for swiotlb_max_segment. * Add DMA map failure handling as in abb0deacb5a6 ("drm/i915: Fallback to single PAGE_SIZE segments for DMA remapping"). v6: Handle swiotlb_max_segment() returning 1. (Joonas Lahtinen) v7: Rebase. v8: Commit spelling fix. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: linux-kernel@vger.kernel.org Reviewed-by: Chris Wilson Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170803091417.23677-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 15 +++++++ drivers/gpu/drm/i915/i915_gem.c | 6 +-- drivers/gpu/drm/i915/i915_gem_userptr.c | 79 ++++++++++++--------------------- 3 files changed, 45 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c1aef3a1ceb9..2b08bbf608aa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2828,6 +2828,21 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg) (((__iter).curr += PAGE_SIZE) < (__iter).max) || \ ((__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0)) +static inline unsigned int i915_sg_segment_size(void) +{ + unsigned int size = swiotlb_max_segment(); + + if (size == 0) + return SCATTERLIST_MAX_SEGMENT; + + size = rounddown(size, PAGE_SIZE); + /* swiotlb_max_segment_size can return 1 byte when it means one page. */ + if (size < PAGE_SIZE) + size = PAGE_SIZE; + + return size; +} + static inline const struct intel_device_info * intel_info(const struct drm_i915_private *dev_priv) { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1545a4ef09c4..4dffebae5601 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2303,7 +2303,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) struct sgt_iter sgt_iter; struct page *page; unsigned long last_pfn = 0; /* suppress gcc warning */ - unsigned int max_segment; + unsigned int max_segment = i915_sg_segment_size(); gfp_t noreclaim; int ret; @@ -2314,10 +2314,6 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); - max_segment = swiotlb_max_segment(); - if (!max_segment) - max_segment = rounddown(UINT_MAX, PAGE_SIZE); - st = kmalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index f152a38d7079..2ce078e8c763 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -399,64 +399,42 @@ struct get_pages_work { struct task_struct *task; }; -#if IS_ENABLED(CONFIG_SWIOTLB) -#define swiotlb_active() swiotlb_nr_tbl() -#else -#define swiotlb_active() 0 -#endif - -static int -st_set_pages(struct sg_table **st, struct page **pvec, int num_pages) -{ - struct scatterlist *sg; - int ret, n; - - *st = kmalloc(sizeof(**st), GFP_KERNEL); - if (*st == NULL) - return -ENOMEM; - - if (swiotlb_active()) { - ret = sg_alloc_table(*st, num_pages, GFP_KERNEL); - if (ret) - goto err; - - for_each_sg((*st)->sgl, sg, num_pages, n) - sg_set_page(sg, pvec[n], PAGE_SIZE, 0); - } else { - ret = sg_alloc_table_from_pages(*st, pvec, num_pages, - 0, num_pages << PAGE_SHIFT, - GFP_KERNEL); - if (ret) - goto err; - } - - return 0; - -err: - kfree(*st); - *st = NULL; - return ret; -} - static struct sg_table * -__i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj, - struct page **pvec, int num_pages) +__i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj, + struct page **pvec, int num_pages) { - struct sg_table *pages; + unsigned int max_segment = i915_sg_segment_size(); + struct sg_table *st; int ret; - ret = st_set_pages(&pages, pvec, num_pages); - if (ret) + st = kmalloc(sizeof(*st), GFP_KERNEL); + if (!st) + return ERR_PTR(-ENOMEM); + +alloc_table: + ret = __sg_alloc_table_from_pages(st, pvec, num_pages, + 0, num_pages << PAGE_SHIFT, + max_segment, + GFP_KERNEL); + if (ret) { + kfree(st); return ERR_PTR(ret); + } - ret = i915_gem_gtt_prepare_pages(obj, pages); + ret = i915_gem_gtt_prepare_pages(obj, st); if (ret) { - sg_free_table(pages); - kfree(pages); + sg_free_table(st); + + if (max_segment > PAGE_SIZE) { + max_segment = PAGE_SIZE; + goto alloc_table; + } + + kfree(st); return ERR_PTR(ret); } - return pages; + return st; } static int @@ -540,7 +518,8 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) struct sg_table *pages = ERR_PTR(ret); if (pinned == npages) { - pages = __i915_gem_userptr_set_pages(obj, pvec, npages); + pages = __i915_gem_userptr_alloc_pages(obj, pvec, + npages); if (!IS_ERR(pages)) { __i915_gem_object_set_pages(obj, pages); pinned = 0; @@ -661,7 +640,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) pages = __i915_gem_userptr_get_pages_schedule(obj); active = pages == ERR_PTR(-EAGAIN); } else { - pages = __i915_gem_userptr_set_pages(obj, pvec, num_pages); + pages = __i915_gem_userptr_alloc_pages(obj, pvec, num_pages); active = !IS_ERR(pages); } if (active) -- cgit v1.2.3 From 0b4d7cbff2be27c89617e1ca60a546019f7ff276 Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Thu, 17 Aug 2017 19:15:22 +0530 Subject: drm/i915: Fixed point fixed16 wrapper cleanup As per suggestion from Jani, cleanup the code. Cleanup includes - Instead of left shifting & check, compare with U32/16_MAX - Use typecast instead of clamp_t Signed-off-by: Mahesh Kumar Cc: Jani Nikula Reviewed-by: Jani Nikula Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-2-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2b08bbf608aa..2f12373d2f54 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -126,7 +126,7 @@ static inline uint_fixed_16_16_t u32_to_fixed16(uint32_t val) { uint_fixed_16_16_t fp; - WARN_ON(val >> 16); + WARN_ON(val > U16_MAX); fp.val = val << 16; return fp; @@ -163,8 +163,8 @@ static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1, static inline uint_fixed_16_16_t clamp_u64_to_fixed16(uint64_t val) { uint_fixed_16_16_t fp; - WARN_ON(val >> 32); - fp.val = clamp_t(uint32_t, val, 0, ~0); + WARN_ON(val > U32_MAX); + fp.val = (uint32_t) val; return fp; } @@ -181,8 +181,8 @@ static inline uint32_t mul_round_up_u32_fixed16(uint32_t val, intermediate_val = (uint64_t) val * mul.val; intermediate_val = DIV_ROUND_UP_ULL(intermediate_val, 1 << 16); - WARN_ON(intermediate_val >> 32); - return clamp_t(uint32_t, intermediate_val, 0, ~0); + WARN_ON(intermediate_val > U32_MAX); + return (uint32_t) intermediate_val; } static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val, @@ -211,8 +211,8 @@ static inline uint32_t div_round_up_u32_fixed16(uint32_t val, interm_val = (uint64_t)val << 16; interm_val = DIV_ROUND_UP_ULL(interm_val, d.val); - WARN_ON(interm_val >> 32); - return clamp_t(uint32_t, interm_val, 0, ~0); + WARN_ON(interm_val > U32_MAX); + return (uint32_t) interm_val; } static inline uint_fixed_16_16_t mul_u32_fixed16(uint32_t val, -- cgit v1.2.3 From 7e452fdbfca85cd279ecb0d8e9ab6fdd1e8c97fc Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Thu, 17 Aug 2017 19:15:23 +0530 Subject: drm/i915/skl+: Optimize WM calculation Plane configuration parameters doesn't change for each WM-level calculation. Currently we compute same parameters 8 times for each wm-level. This patch optimizes it by calculating these parameters in beginning & reuse during each level-wm calculation. Changes since V1: - rebase on top of Rodrigo's series for CNL Signed-off-by: Mahesh Kumar Acked-by: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-3-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 14 +++ drivers/gpu/drm/i915/intel_pm.c | 190 ++++++++++++++++++++++------------------ 2 files changed, 119 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2f12373d2f54..0df2b0f620f7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1837,6 +1837,20 @@ struct skl_wm_level { uint8_t plane_res_l; }; +/* Stores plane specific WM parameters */ +struct skl_wm_params { + bool x_tiled, y_tiled; + bool rc_surface; + uint32_t width; + uint8_t cpp; + uint32_t plane_pixel_rate; + uint32_t y_min_scanlines; + uint32_t plane_bytes_per_line; + uint_fixed_16_16_t plane_blocks_per_line; + uint_fixed_16_16_t y_tile_minimum; + uint32_t linetime_us; +}; + /* * This struct helps tracking the state needed for runtime PM, which puts the * device in PCI D3 state. Notice that when this happens, nothing on the diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0201816a4229..2dd3af3debe9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4376,134 +4376,146 @@ skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cstate, downscale_amount); } -static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, - struct intel_crtc_state *cstate, - const struct intel_plane_state *intel_pstate, - uint16_t ddb_allocation, - int level, - uint16_t *out_blocks, /* out */ - uint8_t *out_lines, /* out */ - bool *enabled /* out */) +static int +skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv, + struct intel_crtc_state *cstate, + const struct intel_plane_state *intel_pstate, + struct skl_wm_params *wp) { struct intel_plane *plane = to_intel_plane(intel_pstate->base.plane); const struct drm_plane_state *pstate = &intel_pstate->base; const struct drm_framebuffer *fb = pstate->fb; - uint32_t latency = dev_priv->wm.skl_latency[level]; - uint_fixed_16_16_t method1, method2; - uint_fixed_16_16_t plane_blocks_per_line; - uint_fixed_16_16_t selected_result; uint32_t interm_pbpl; - uint32_t plane_bytes_per_line; - uint32_t res_blocks, res_lines; - uint8_t cpp; - uint32_t width = 0; - uint32_t plane_pixel_rate; - uint_fixed_16_16_t y_tile_minimum; - uint32_t y_min_scanlines; struct intel_atomic_state *state = to_intel_atomic_state(cstate->base.state); bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); - bool y_tiled, x_tiled; - if (latency == 0 || - !intel_wm_plane_visible(cstate, intel_pstate)) { - *enabled = false; + if (!intel_wm_plane_visible(cstate, intel_pstate)) return 0; - } - y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED || - fb->modifier == I915_FORMAT_MOD_Yf_TILED || - fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || - fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS; - x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED; - - /* Display WA #1141: kbl,cfl */ - if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && - dev_priv->ipc_enabled) - latency += 4; - - if (apply_memory_bw_wa && x_tiled) - latency += 15; + wp->y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED || + fb->modifier == I915_FORMAT_MOD_Yf_TILED || + fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || + fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS; + wp->x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED; + wp->rc_surface = fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || + fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS; if (plane->id == PLANE_CURSOR) { - width = intel_pstate->base.crtc_w; + wp->width = intel_pstate->base.crtc_w; } else { /* * Src coordinates are already rotated by 270 degrees for * the 90/270 degree plane rotation cases (to match the * GTT mapping), hence no need to account for rotation here. */ - width = drm_rect_width(&intel_pstate->base.src) >> 16; + wp->width = drm_rect_width(&intel_pstate->base.src) >> 16; } - cpp = (fb->format->format == DRM_FORMAT_NV12) ? fb->format->cpp[1] : - fb->format->cpp[0]; - plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate); + wp->cpp = (fb->format->format == DRM_FORMAT_NV12) ? fb->format->cpp[1] : + fb->format->cpp[0]; + wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, + intel_pstate); if (drm_rotation_90_or_270(pstate->rotation)) { - switch (cpp) { + switch (wp->cpp) { case 1: - y_min_scanlines = 16; + wp->y_min_scanlines = 16; break; case 2: - y_min_scanlines = 8; + wp->y_min_scanlines = 8; break; case 4: - y_min_scanlines = 4; + wp->y_min_scanlines = 4; break; default: - MISSING_CASE(cpp); + MISSING_CASE(wp->cpp); return -EINVAL; } } else { - y_min_scanlines = 4; + wp->y_min_scanlines = 4; } if (apply_memory_bw_wa) - y_min_scanlines *= 2; + wp->y_min_scanlines *= 2; - plane_bytes_per_line = width * cpp; - if (y_tiled) { - interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line * - y_min_scanlines, 512); + wp->plane_bytes_per_line = wp->width * wp->cpp; + if (wp->y_tiled) { + interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line * + wp->y_min_scanlines, 512); if (INTEL_GEN(dev_priv) >= 10) interm_pbpl++; - plane_blocks_per_line = div_fixed16(interm_pbpl, - y_min_scanlines); - } else if (x_tiled && INTEL_GEN(dev_priv) == 9) { - interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line, 512); - plane_blocks_per_line = u32_to_fixed16(interm_pbpl); + wp->plane_blocks_per_line = div_fixed16(interm_pbpl, + wp->y_min_scanlines); + } else if (wp->x_tiled && IS_GEN9(dev_priv)) { + interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line, 512); + wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl); } else { - interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1; - plane_blocks_per_line = u32_to_fixed16(interm_pbpl); + interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line, 512) + 1; + wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl); } - method1 = skl_wm_method1(dev_priv, plane_pixel_rate, cpp, latency); - method2 = skl_wm_method2(plane_pixel_rate, + wp->y_tile_minimum = mul_u32_fixed16(wp->y_min_scanlines, + wp->plane_blocks_per_line); + wp->linetime_us = fixed16_to_u32_round_up( + intel_get_linetime_us(cstate)); + + return 0; +} + +static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, + struct intel_crtc_state *cstate, + const struct intel_plane_state *intel_pstate, + uint16_t ddb_allocation, + int level, + const struct skl_wm_params *wp, + uint16_t *out_blocks, /* out */ + uint8_t *out_lines, /* out */ + bool *enabled /* out */) +{ + const struct drm_plane_state *pstate = &intel_pstate->base; + uint32_t latency = dev_priv->wm.skl_latency[level]; + uint_fixed_16_16_t method1, method2; + uint_fixed_16_16_t selected_result; + uint32_t res_blocks, res_lines; + struct intel_atomic_state *state = + to_intel_atomic_state(cstate->base.state); + bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); + + if (latency == 0 || + !intel_wm_plane_visible(cstate, intel_pstate)) { + *enabled = false; + return 0; + } + + /* Display WA #1141: kbl,cfl */ + if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && + dev_priv->ipc_enabled) + latency += 4; + + if (apply_memory_bw_wa && wp->x_tiled) + latency += 15; + + method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate, + wp->cpp, latency); + method2 = skl_wm_method2(wp->plane_pixel_rate, cstate->base.adjusted_mode.crtc_htotal, latency, - plane_blocks_per_line); - - y_tile_minimum = mul_u32_fixed16(y_min_scanlines, - plane_blocks_per_line); + wp->plane_blocks_per_line); - if (y_tiled) { - selected_result = max_fixed16(method2, y_tile_minimum); + if (wp->y_tiled) { + selected_result = max_fixed16(method2, wp->y_tile_minimum); } else { - uint32_t linetime_us; - - linetime_us = fixed16_to_u32_round_up( - intel_get_linetime_us(cstate)); - if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) && - (plane_bytes_per_line / 512 < 1)) + if ((wp->cpp * cstate->base.adjusted_mode.crtc_htotal / + 512 < 1) && (wp->plane_bytes_per_line / 512 < 1)) selected_result = method2; else if (ddb_allocation >= - fixed16_to_u32_round_up(plane_blocks_per_line)) + fixed16_to_u32_round_up(wp->plane_blocks_per_line)) selected_result = min_fixed16(method1, method2); - else if (latency >= linetime_us) + else if (latency >= wp->linetime_us) selected_result = min_fixed16(method1, method2); else selected_result = method1; @@ -4511,19 +4523,18 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, res_blocks = fixed16_to_u32_round_up(selected_result) + 1; res_lines = div_round_up_fixed16(selected_result, - plane_blocks_per_line); + wp->plane_blocks_per_line); /* Display WA #1125: skl,bxt,kbl,glk */ - if (level == 0 && - (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || - fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) - res_blocks += fixed16_to_u32_round_up(y_tile_minimum); + if (level == 0 && wp->rc_surface) + res_blocks += fixed16_to_u32_round_up(wp->y_tile_minimum); /* Display WA #1126: skl,bxt,kbl,glk */ if (level >= 1 && level <= 7) { - if (y_tiled) { - res_blocks += fixed16_to_u32_round_up(y_tile_minimum); - res_lines += y_min_scanlines; + if (wp->y_tiled) { + res_blocks += fixed16_to_u32_round_up( + wp->y_tile_minimum); + res_lines += wp->y_min_scanlines; } else { res_blocks++; } @@ -4561,6 +4572,7 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv, struct skl_ddb_allocation *ddb, struct intel_crtc_state *cstate, const struct intel_plane_state *intel_pstate, + const struct skl_wm_params *wm_params, struct skl_plane_wm *wm) { struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); @@ -4584,6 +4596,7 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv, intel_pstate, ddb_blocks, level, + wm_params, &result->plane_res_b, &result->plane_res_l, &result->plane_en); @@ -4648,11 +4661,18 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate, const struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); enum plane_id plane_id = to_intel_plane(plane)->id; + struct skl_wm_params wm_params; wm = &pipe_wm->planes[plane_id]; + memset(&wm_params, 0, sizeof(struct skl_wm_params)); + + ret = skl_compute_plane_wm_params(dev_priv, cstate, + intel_pstate, &wm_params); + if (ret) + return ret; ret = skl_compute_wm_levels(dev_priv, ddb, cstate, - intel_pstate, wm); + intel_pstate, &wm_params, wm); if (ret) return ret; skl_compute_transition_wm(cstate, &wm->trans_wm); -- cgit v1.2.3 From ca47667f523e588318f89c735e127c256de6cb16 Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Thu, 17 Aug 2017 19:15:24 +0530 Subject: drm/i915/gen10: Calculate and enable transition WM GEN > 9 require transition WM to be programmed if IPC is enabled. This patch calculates & enable transition WM for supported platforms. If transition WM is enabled, Plane read requests are sent at high priority until filling above the transition watermark, then the requests are sent at lower priority until dropping below the level-0 WM. The lower priority requests allow other memory clients to have better memory access. transition minimum is the minimum amount needed for trans_wm to work to ensure the demote does not happen before enough data has been read to meet the level 0 watermark requirements. transition amount is configurable value. Higher values will tend to cause longer periods of high priority reads followed by longer periods of lower priority reads. Tuning to lower values will tend to cause shorter periods of high and lower priority reads. Keeping transition amount to 10 in this patch, as suggested by HW team. Changes since V1: - Address review comments from Maarten Signed-off-by: Mahesh Kumar Acked-by: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-4-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 52 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2dd3af3debe9..3168a5577773 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4630,12 +4630,56 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate) } static void skl_compute_transition_wm(struct intel_crtc_state *cstate, + struct skl_wm_params *wp, + struct skl_wm_level *wm_l0, + uint16_t ddb_allocation, struct skl_wm_level *trans_wm /* out */) { + struct drm_device *dev = cstate->base.crtc->dev; + const struct drm_i915_private *dev_priv = to_i915(dev); + uint16_t trans_min, trans_y_tile_min; + const uint16_t trans_amount = 10; /* This is configurable amount */ + uint16_t trans_offset_b, res_blocks; + if (!cstate->base.active) + goto exit; + + /* Transition WM are not recommended by HW team for GEN9 */ + if (INTEL_GEN(dev_priv) <= 9) + goto exit; + + /* Transition WM don't make any sense if ipc is disabled */ + if (!dev_priv->ipc_enabled) + goto exit; + + if (INTEL_GEN(dev_priv) >= 10) + trans_min = 4; + + trans_offset_b = trans_min + trans_amount; + + if (wp->y_tiled) { + trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2, + wp->y_tile_minimum); + res_blocks = max(wm_l0->plane_res_b, trans_y_tile_min) + + trans_offset_b; + } else { + res_blocks = wm_l0->plane_res_b + trans_offset_b; + + /* WA BUG:1938466 add one block for non y-tile planes */ + if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0)) + res_blocks += 1; + + } + + res_blocks += 1; + + if (res_blocks < ddb_allocation) { + trans_wm->plane_res_b = res_blocks; + trans_wm->plane_en = true; return; + } - /* Until we know more, just disable transition WMs */ +exit: trans_wm->plane_en = false; } @@ -4662,8 +4706,11 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate, to_intel_plane_state(pstate); enum plane_id plane_id = to_intel_plane(plane)->id; struct skl_wm_params wm_params; + enum pipe pipe = to_intel_crtc(cstate->base.crtc)->pipe; + uint16_t ddb_blocks; wm = &pipe_wm->planes[plane_id]; + ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]); memset(&wm_params, 0, sizeof(struct skl_wm_params)); ret = skl_compute_plane_wm_params(dev_priv, cstate, @@ -4675,7 +4722,8 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate, intel_pstate, &wm_params, wm); if (ret) return ret; - skl_compute_transition_wm(cstate, &wm->trans_wm); + skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0], + ddb_blocks, &wm->trans_wm); } pipe_wm->linetime = skl_compute_linetime_wm(cstate); -- cgit v1.2.3 From 446e850c38d9092688df3f1e5d610f3bff2a4152 Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Thu, 17 Aug 2017 19:15:25 +0530 Subject: drm/i915/glk: IPC linetime watermark workaround for GLK IF IPC is enabled LINETIME_WM value should be half of calculated value line time = ROUNDDOWN(1/2 * Calculated Line Time) Earlier code was rounding-up the value, But updated Bspec says we should take the ROUNDDOWN. This patch corrects that as well. Signed-off-by: Mahesh Kumar Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-5-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3168a5577773..629ad54e2797 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4622,9 +4622,10 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate) linetime_wm = fixed16_to_u32_round_up(mul_u32_fixed16(8, linetime_us)); - /* Display WA #1135: bxt. */ - if (IS_BROXTON(dev_priv) && dev_priv->ipc_enabled) - linetime_wm = DIV_ROUND_UP(linetime_wm, 2); + /* Display WA #1135: bxt:ALL GLK:ALL */ + if ((IS_BROXTON(dev_priv) || IS_GEMINILAKE(dev_priv)) && + dev_priv->ipc_enabled) + linetime_wm /= 2; return linetime_wm; } -- cgit v1.2.3 From d86ba628ce4bfd83c987e4dab9d917cbb3622854 Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Thu, 17 Aug 2017 19:15:26 +0530 Subject: drm/i915/cnl: Extend WM workaround with IPC for CNL CNL:A & CNL:B have same workaround as KBL to increase wm level latency by 4us if IPC is enabled. Signed-off-by: Mahesh Kumar Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-6-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 629ad54e2797..f2911de69ea9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4492,7 +4492,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, } /* Display WA #1141: kbl,cfl */ - if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && + if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) || + IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) && dev_priv->ipc_enabled) latency += 4; -- cgit v1.2.3 From e57f1c02155f4f108b9d3ba2bed687e8e9f95e18 Mon Sep 17 00:00:00 2001 From: Mahesh Kumar Date: Thu, 17 Aug 2017 19:15:27 +0530 Subject: drm/i915/gen9+: Add has_ipc flag in device info structure New Isochronous Priority Control (IPC) capability is introduced in newer GEN platforms. This patch adds a device info flag to indicate if platform supports IPC. Patch also sets this flag in supported platforms. Signed-off-by: Mahesh Kumar Cc: Chris Wilson Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-7-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 5 ++++- drivers/gpu/drm/i915/i915_pci.c | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0df2b0f620f7..63ca2ffcafef 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -798,7 +798,8 @@ struct intel_csr { func(cursor_needs_physical); \ func(hws_needs_physical); \ func(overlay_needs_physical); \ - func(supports_tv); + func(supports_tv); \ + func(has_ipc); struct sseu_dev_info { u8 slice_mask; @@ -3119,6 +3120,8 @@ intel_info(const struct drm_i915_private *dev_priv) #define HAS_RUNTIME_PM(dev_priv) ((dev_priv)->info.has_runtime_pm) #define HAS_64BIT_RELOC(dev_priv) ((dev_priv)->info.has_64bit_reloc) +#define HAS_IPC(dev_priv) ((dev_priv)->info.has_ipc) + /* * For now, anything with a GuC requires uCode loading, and then supports * command submission once loaded. But these are logically independent diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index e95baf3c4314..129877b94c20 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -482,6 +482,7 @@ static const struct intel_device_info intel_skylake_gt4_info __initconst = { .has_full_48bit_ppgtt = 1, \ .has_reset_engine = 1, \ .has_snoop = true, \ + .has_ipc = 1, \ GEN_DEFAULT_PIPEOFFSETS, \ IVB_CURSOR_OFFSETS, \ BDW_COLORS @@ -505,6 +506,7 @@ static const struct intel_device_info intel_geminilake_info __initconst = { .platform = INTEL_KABYLAKE, \ .has_csr = 1, \ .has_guc = 1, \ + .has_ipc = 1, \ .ddb_size = 896 static const struct intel_device_info intel_kabylake_gt1_info __initconst = { @@ -530,6 +532,7 @@ static const struct intel_device_info intel_kabylake_gt3_info __initconst = { .platform = INTEL_COFFEELAKE, \ .has_csr = 1, \ .has_guc = 1, \ + .has_ipc = 1, \ .ddb_size = 896 static const struct intel_device_info intel_coffeelake_gt1_info __initconst = { @@ -556,6 +559,7 @@ static const struct intel_device_info intel_cannonlake_gt2_info __initconst = { .gt = 2, .ddb_size = 1024, .has_csr = 1, + .has_ipc = 1, .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } }; -- cgit v1.2.3 From 2503a0fef214ddadfdf5844d62453591de35586f Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Thu, 17 Aug 2017 19:15:28 +0530 Subject: drm/i915/bxt+: Enable IPC support This patch adds IPC support. This patch also enables IPC in all supported platforms based on has_ipc flag. IPC (Isochronous Priority Control) is the hardware feature, which dynamically controls the memory read priority of Display. When IPC is enabled, plane read requests are sent at high priority until filling above the transition watermark, then the requests are sent at lower priority until dropping below the level 0 watermark. The lower priority requests allow other memory clients to have better memory access. When IPC is disabled, all plane read requests are sent at high priority. Changes since V1: - Remove commandline parameter to disable ipc - Address Paulo's comments Changes since V2: - Address review comments - Set ipc_enabled flag Changes since V3: - move ipc_enabled flag assignment inside intel_ipc_enable function Changes since V4: - Re-enable IPC after suspend/resume Changes since V5: - Enable IPC for all gen >=9 except SKL Changes since V6: - fix commit msg - after resume program IPC based on SW state. Changes since V7: - Modify IPC support check based on HAS_IPC macro (suggested by Chris) Signed-off-by: Mahesh Kumar Cc: Chris Wilson Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-8-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 4 +++- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_pm.c | 24 ++++++++++++++++++++++++ 5 files changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ff70fc45ba7c..5c111ea96e80 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1341,7 +1341,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) intel_runtime_pm_enable(dev_priv); - dev_priv->ipc_enabled = false; + intel_init_ipc(dev_priv); if (IS_ENABLED(CONFIG_DRM_I915_DEBUG)) DRM_INFO("DRM_I915_DEBUG enabled\n"); @@ -2609,6 +2609,8 @@ static int intel_runtime_resume(struct device *kdev) if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) intel_hpd_init(dev_priv); + intel_enable_ipc(dev_priv); + enable_rpm_wakeref_asserts(dev_priv); if (ret) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2eff98cdcfad..9a73ea0a3293 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6949,6 +6949,7 @@ enum { #define DISP_FBC_WM_DIS (1<<15) #define DISP_ARB_CTL2 _MMIO(0x45004) #define DISP_DATA_PARTITION_5_6 (1<<6) +#define DISP_IPC_ENABLE (1<<3) #define DBUF_CTL _MMIO(0x45008) #define DBUF_POWER_REQUEST (1<<31) #define DBUF_POWER_STATE (1<<30) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5291e08f3436..844efd45fed3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15255,6 +15255,7 @@ void intel_display_resume(struct drm_device *dev) if (!ret) ret = __intel_display_resume(dev, state, &ctx); + intel_enable_ipc(dev_priv); drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 463ed152e6b1..307807672896 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1898,6 +1898,8 @@ bool ilk_disable_lp_wm(struct drm_device *dev); int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, struct intel_crtc_state *cstate); +void intel_init_ipc(struct drm_i915_private *dev_priv); +void intel_enable_ipc(struct drm_i915_private *dev_priv); static inline int intel_enable_rc6(void) { return i915.enable_rc6; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f2911de69ea9..fa9055a4f790 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5824,6 +5824,30 @@ void intel_update_watermarks(struct intel_crtc *crtc) dev_priv->display.update_wm(crtc); } +void intel_enable_ipc(struct drm_i915_private *dev_priv) +{ + u32 val; + + val = I915_READ(DISP_ARB_CTL2); + + if (dev_priv->ipc_enabled) + val |= DISP_IPC_ENABLE; + else + val &= ~DISP_IPC_ENABLE; + + I915_WRITE(DISP_ARB_CTL2, val); +} + +void intel_init_ipc(struct drm_i915_private *dev_priv) +{ + dev_priv->ipc_enabled = false; + if (!HAS_IPC(dev_priv)) + return; + + dev_priv->ipc_enabled = true; + intel_enable_ipc(dev_priv); +} + /* * Lock protecting IPS related data structures */ -- cgit v1.2.3 From d2d4f39b1e6407323e568c174e17b022b8f98a40 Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Thu, 17 Aug 2017 19:15:29 +0530 Subject: drm/i915/skl+: debugfs entry to control IPC This patch creates an entry in debugfs to check the status of IPC. This can also be used to enable/disable IPC in supported platforms. Changes since V1: - fix use of HAS_IPC - use kstrtobool_from_user (Maarten) - drm_info log, while enabling IPC (Maarten) Signed-off-by: Mahesh Kumar Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20170817134529.2839-9-mahesh1.kumar@intel.com [mlankhorst: enableddisabled -> yesno to match ipc write] --- drivers/gpu/drm/i915/i915_debugfs.c | 54 ++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 48572b157222..8d432e50a196 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3522,6 +3522,57 @@ static int i915_wa_registers(struct seq_file *m, void *unused) return 0; } +static int i915_ipc_status_show(struct seq_file *m, void *data) +{ + struct drm_i915_private *dev_priv = m->private; + + seq_printf(m, "Isochronous Priority Control: %s\n", + yesno(dev_priv->ipc_enabled)); + return 0; +} + +static int i915_ipc_status_open(struct inode *inode, struct file *file) +{ + struct drm_i915_private *dev_priv = inode->i_private; + + if (!HAS_IPC(dev_priv)) + return -ENODEV; + + return single_open(file, i915_ipc_status_show, dev_priv); +} + +static ssize_t i915_ipc_status_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct drm_i915_private *dev_priv = m->private; + int ret; + bool enable; + + ret = kstrtobool_from_user(ubuf, len, &enable); + if (ret < 0) + return ret; + + intel_runtime_pm_get(dev_priv); + if (!dev_priv->ipc_enabled && enable) + DRM_INFO("Enabling IPC: WM will be proper only after next commit\n"); + dev_priv->wm.distrust_bios_wm = true; + dev_priv->ipc_enabled = enable; + intel_enable_ipc(dev_priv); + intel_runtime_pm_put(dev_priv); + + return len; +} + +static const struct file_operations i915_ipc_status_fops = { + .owner = THIS_MODULE, + .open = i915_ipc_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = i915_ipc_status_write +}; + static int i915_ddb_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -4858,7 +4909,8 @@ static const struct i915_debugfs_files { {"i915_dp_test_type", &i915_displayport_test_type_fops}, {"i915_dp_test_active", &i915_displayport_test_active_fops}, {"i915_guc_log_control", &i915_guc_log_control_fops}, - {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops} + {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops}, + {"i915_ipc_status", &i915_ipc_status_fops} }; int i915_debugfs_register(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From d7a133d886b45651e36e7065998b1413d379ac1f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 Sep 2017 14:44:41 +0100 Subject: drm/i915: Disable mmio debugging during user access If the user bypasses i915 and accesses mmio directly, that easily confuses our automatic mmio debugging (any error we then detect is likely to be as a result of the user). Since we expect userspace to open debugfs/i915_forcewake_user if i915.ko is loaded and they want mmio access, that makes the opportune time to disable our debugging for duration of the bypass. v2: Move the fiddling of uncore internals to uncore.c References: https://bugs.freedesktop.org/show_bug.cgi?id=102543 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20170907134441.12881-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 19 ++++++++------ drivers/gpu/drm/i915/intel_uncore.c | 51 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uncore.h | 10 ++++++++ 3 files changed, 72 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 8d432e50a196..6338018f655d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1421,6 +1421,9 @@ static int i915_forcewake_domains(struct seq_file *m, void *data) struct intel_uncore_forcewake_domain *fw_domain; unsigned int tmp; + seq_printf(m, "user.bypass_count = %u\n", + i915->uncore.user_forcewake.count); + for_each_fw_domain(fw_domain, i915, tmp) seq_printf(m, "%s.wake_count = %u\n", intel_uncore_forcewake_domain_to_str(fw_domain->id), @@ -4724,26 +4727,26 @@ static int i915_sseu_status(struct seq_file *m, void *unused) static int i915_forcewake_open(struct inode *inode, struct file *file) { - struct drm_i915_private *dev_priv = inode->i_private; + struct drm_i915_private *i915 = inode->i_private; - if (INTEL_GEN(dev_priv) < 6) + if (INTEL_GEN(i915) < 6) return 0; - intel_runtime_pm_get(dev_priv); - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + intel_runtime_pm_get(i915); + intel_uncore_forcewake_user_get(i915); return 0; } static int i915_forcewake_release(struct inode *inode, struct file *file) { - struct drm_i915_private *dev_priv = inode->i_private; + struct drm_i915_private *i915 = inode->i_private; - if (INTEL_GEN(dev_priv) < 6) + if (INTEL_GEN(i915) < 6) return 0; - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); - intel_runtime_pm_put(dev_priv); + intel_uncore_forcewake_user_put(i915); + intel_runtime_pm_put(i915); return 0; } diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 0529af7cfbb8..1b38eb94d461 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -489,6 +489,57 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv, spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); } +/** + * intel_uncore_forcewake_user_get - claim forcewake on behalf of userspace + * @dev_priv: i915 device instance + * + * This function is a wrapper around intel_uncore_forcewake_get() to acquire + * the GT powerwell and in the process disable our debugging for the + * duration of userspace's bypass. + */ +void intel_uncore_forcewake_user_get(struct drm_i915_private *dev_priv) +{ + spin_lock_irq(&dev_priv->uncore.lock); + if (!dev_priv->uncore.user_forcewake.count++) { + intel_uncore_forcewake_get__locked(dev_priv, FORCEWAKE_ALL); + + /* Save and disable mmio debugging for the user bypass */ + dev_priv->uncore.user_forcewake.saved_mmio_check = + dev_priv->uncore.unclaimed_mmio_check; + dev_priv->uncore.user_forcewake.saved_mmio_debug = + i915.mmio_debug; + + dev_priv->uncore.unclaimed_mmio_check = 0; + i915.mmio_debug = 0; + } + spin_unlock_irq(&dev_priv->uncore.lock); +} + +/** + * intel_uncore_forcewake_user_put - release forcewake on behalf of userspace + * @dev_priv: i915 device instance + * + * This function complements intel_uncore_forcewake_user_get() and releases + * the GT powerwell taken on behalf of the userspace bypass. + */ +void intel_uncore_forcewake_user_put(struct drm_i915_private *dev_priv) +{ + spin_lock_irq(&dev_priv->uncore.lock); + if (!--dev_priv->uncore.user_forcewake.count) { + if (intel_uncore_unclaimed_mmio(dev_priv)) + dev_info(dev_priv->drm.dev, + "Invalid mmio detected during user access\n"); + + dev_priv->uncore.unclaimed_mmio_check = + dev_priv->uncore.user_forcewake.saved_mmio_check; + i915.mmio_debug = + dev_priv->uncore.user_forcewake.saved_mmio_debug; + + intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); + } + spin_unlock_irq(&dev_priv->uncore.lock); +} + /** * intel_uncore_forcewake_get__locked - grab forcewake domain references * @dev_priv: i915 device instance diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 5f90278da461..03786f931905 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -102,6 +102,13 @@ struct intel_uncore { i915_reg_t reg_ack; } fw_domain[FW_DOMAIN_ID_COUNT]; + struct { + unsigned int count; + + int saved_mmio_check; + int saved_mmio_debug; + } user_forcewake; + int unclaimed_mmio_check; }; @@ -144,6 +151,9 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv, void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv, enum forcewake_domains domains); +void intel_uncore_forcewake_user_get(struct drm_i915_private *dev_priv); +void intel_uncore_forcewake_user_put(struct drm_i915_private *dev_priv); + int intel_wait_for_register(struct drm_i915_private *dev_priv, i915_reg_t reg, u32 mask, -- cgit v1.2.3 From 750fae232480fee9d799eaced198ec98c20769a3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 7 Sep 2017 17:32:03 +0300 Subject: i915: Fix obj size vs. alignment for drm_pci_alloc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_pci_alloc() refuses to cooperate if the passed alignment exceeds the object size. So round up the obj size to the next power of two as well to make this actually work. Obviously things work just fine as long as the size was a power of two to begin with. However kms_cursor_crc doesn't always use power of two sizes so we hit a failure when we try to allocate the phys memory. Testcase: igt/kms_cursor_crc Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170907143203.13055-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4dffebae5601..822719fa1b52 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -179,7 +179,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) * the alignment of the buddy allocation will naturally match. */ phys = drm_pci_alloc(obj->base.dev, - obj->base.size, + roundup_pow_of_two(obj->base.size), roundup_pow_of_two(obj->base.size)); if (!phys) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From 23e4c67ae13da7549a54f4e8c0014f48b2ef5204 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 6 Sep 2017 23:45:34 +0200 Subject: ata: avoid gcc-7 warning in ata_timing_quantize gcc-7 warns about the result of a constant multiplication used as a boolean: drivers/ata/libata-core.c: In function 'ata_timing_quantize': drivers/ata/libata-core.c:3164:30: warning: '*' in boolean context, suggest '&&' instead [-Wint-in-bool-context] This slightly rearranges the macro to simplify the code and avoid the warning at the same time. Signed-off-by: Arnd Bergmann Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 1945a8ea2099..ee4c1ec9dca0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3234,19 +3234,19 @@ static const struct ata_timing ata_timing[] = { }; #define ENOUGH(v, unit) (((v)-1)/(unit)+1) -#define EZ(v, unit) ((v)?ENOUGH(v, unit):0) +#define EZ(v, unit) ((v)?ENOUGH(((v) * 1000), unit):0) static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) { - q->setup = EZ(t->setup * 1000, T); - q->act8b = EZ(t->act8b * 1000, T); - q->rec8b = EZ(t->rec8b * 1000, T); - q->cyc8b = EZ(t->cyc8b * 1000, T); - q->active = EZ(t->active * 1000, T); - q->recover = EZ(t->recover * 1000, T); - q->dmack_hold = EZ(t->dmack_hold * 1000, T); - q->cycle = EZ(t->cycle * 1000, T); - q->udma = EZ(t->udma * 1000, UT); + q->setup = EZ(t->setup, T); + q->act8b = EZ(t->act8b, T); + q->rec8b = EZ(t->rec8b, T); + q->cyc8b = EZ(t->cyc8b, T); + q->active = EZ(t->active, T); + q->recover = EZ(t->recover, T); + q->dmack_hold = EZ(t->dmack_hold, T); + q->cycle = EZ(t->cycle, T); + q->udma = EZ(t->udma, UT); } void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, -- cgit v1.2.3 From c5ba5b24657e473b1c64b0a614b168a635a2c935 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 Sep 2017 19:45:20 +0100 Subject: drm/i915: Apply the GTT write flush for all !llc machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We also see the delayed GTT write issue on i915g/i915gm, so let's presume that it is a universal problem for all !llc machines, and that we just haven't yet noticed on g33, gen4 and gen5 machines. v2: Use a register that exists on all platforms Testcase: igt/gem_mmap_gtt/coherency # i915gm References: https://bugs.freedesktop.org/show_bug.cgi?id=102577 Signed-off-by: Chris Wilson Cc: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170907184520.5032-1-chris@chris-wilson.co.uk Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 822719fa1b52..f445587c1a4b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -694,10 +694,10 @@ flush_write_domain(struct drm_i915_gem_object *obj, unsigned int flush_domains) switch (obj->base.write_domain) { case I915_GEM_DOMAIN_GTT: - if (INTEL_GEN(dev_priv) >= 6 && !HAS_LLC(dev_priv)) { + if (!HAS_LLC(dev_priv)) { intel_runtime_pm_get(dev_priv); spin_lock_irq(&dev_priv->uncore.lock); - POSTING_READ_FW(RING_ACTHD(dev_priv->engine[RCS]->mmio_base)); + POSTING_READ_FW(RING_HEAD(dev_priv->engine[RCS]->mmio_base)); spin_unlock_irq(&dev_priv->uncore.lock); intel_runtime_pm_put(dev_priv); } -- cgit v1.2.3 From efc886cb135595c7bec481a32d000dce865b7971 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 7 Sep 2017 08:40:04 -0700 Subject: drm/i915: Transform WaInPlaceDecompressionHang into a simple reg write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Afaict, GEN9_GAMT_ECO_REG_RW_IA does not live in the context, so writing it on every context creation is overkill (and wrong). v2: Missing end parenthesis Cc: Chris Wilson Cc: Mika Kuoppala Cc: Rodrigo Vivi Signed-off-by: Oscar Mateo Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/1504798809-5653-1-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index b8e9a234af2d..674d686286b1 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -985,8 +985,9 @@ static int skl_init_workarounds(struct intel_engine_cs *engine) /* WaInPlaceDecompressionHang:skl */ if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER)) - WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA, - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); + I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, + (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); /* WaDisableLSQCROPERFforOCL:skl */ ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4); @@ -1059,8 +1060,9 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine) /* WaInPlaceDecompressionHang:bxt */ if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER)) - WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA, - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); + I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, + (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); return 0; } @@ -1093,8 +1095,9 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine) GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE); /* WaInPlaceDecompressionHang:cnl */ - WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA, - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); + I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, + (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); /* WaPushConstantDereferenceHoldDisable:cnl */ WA_SET_BIT(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE); @@ -1147,8 +1150,9 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine) GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); /* WaInPlaceDecompressionHang:kbl */ - WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA, - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); + I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, + (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); /* WaDisableLSQCROPERFforOCL:kbl */ ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4); @@ -1200,8 +1204,9 @@ static int cfl_init_workarounds(struct intel_engine_cs *engine) GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); /* WaInPlaceDecompressionHang:cfl */ - WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA, - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); + I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, + (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); return 0; } -- cgit v1.2.3 From 6cf20a0128fab5368937d719bcd9ec1b233491b7 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 7 Sep 2017 08:40:05 -0700 Subject: drm/i915: Transform WaDisableI2mCycleOnWRPort into a simple reg write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GAMT_CHKN_BIT_REG does not live in the context. Cc: Chris Wilson Cc: Mika Kuoppala Cc: Rodrigo Vivi Signed-off-by: Oscar Mateo Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/1504798809-5653-2-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 674d686286b1..0fb012369077 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1072,10 +1072,11 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine) struct drm_i915_private *dev_priv = engine->i915; int ret; - /* WaDisableI2mCycleOnWRPort: cnl (pre-prod) */ + /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */ if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0)) - WA_SET_BIT(GAMT_CHKN_BIT_REG, - GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT); + I915_WRITE(GAMT_CHKN_BIT_REG, + (I915_READ(GAMT_CHKN_BIT_REG) | + GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT)); /* WaForceContextSaveRestoreNonCoherent:cnl */ WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0, -- cgit v1.2.3 From b27f59010f27628f1d96e746fdf7e6e916c451d5 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 7 Sep 2017 08:40:06 -0700 Subject: drm/i915: WaPushConstantDereferenceHoldDisable needs to modify a masked register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So do it correctly. Cc: Chris Wilson Cc: Mika Kuoppala Cc: Rodrigo Vivi Signed-off-by: Oscar Mateo Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/1504798809-5653-3-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 0fb012369077..6e24711c106c 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1101,7 +1101,7 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine) GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); /* WaPushConstantDereferenceHoldDisable:cnl */ - WA_SET_BIT(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE); + WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE); /* FtrEnableFastAnisoL1BankingFix: cnl */ WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX); -- cgit v1.2.3 From 4827c547c51f81579edb8f3958d53c15e0a3f662 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 7 Sep 2017 08:40:07 -0700 Subject: drm/i915: Transform WaDisableGafsUnitClkGating into a simple reg write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEN7_UCGCTL4 does not live in the context. v2: Missing parenthesis Cc: Chris Wilson Cc: Mika Kuoppala Cc: Rodrigo Vivi Signed-off-by: Oscar Mateo Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/1504798809-5653-4-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 6e24711c106c..48c7eb36d633 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -981,7 +981,8 @@ static int skl_init_workarounds(struct intel_engine_cs *engine) GEN9_GAPS_TSV_CREDIT_DISABLE)); /* WaDisableGafsUnitClkGating:skl */ - WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); + I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) | + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE)); /* WaInPlaceDecompressionHang:skl */ if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER)) @@ -1143,7 +1144,8 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine) GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); /* WaDisableGafsUnitClkGating:kbl */ - WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); + I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) | + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE)); /* WaDisableSbeCacheDispatchPortSharing:kbl */ WA_SET_BIT_MASKED( @@ -1197,7 +1199,8 @@ static int cfl_init_workarounds(struct intel_engine_cs *engine) GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); /* WaDisableGafsUnitClkGating:cfl */ - WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); + I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) | + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE)); /* WaDisableSbeCacheDispatchPortSharing:cfl */ WA_SET_BIT_MASKED( -- cgit v1.2.3 From c6ea497c40b46aaf77d9018e27b26bffdbdac6f7 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 7 Sep 2017 08:40:08 -0700 Subject: drm/i915: Transform WaDisableDynamicCreditSharing into a simple register write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GAMT_CHKN_BIT_REG does not live in the context image. Cc: Chris Wilson Cc: Mika Kuoppala Cc: Rodrigo Vivi Signed-off-by: Oscar Mateo Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/1504798809-5653-5-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 48c7eb36d633..0701ddb68b6a 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1130,8 +1130,9 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine) /* WaDisableDynamicCreditSharing:kbl */ if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) - WA_SET_BIT(GAMT_CHKN_BIT_REG, - GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING); + I915_WRITE(GAMT_CHKN_BIT_REG, + (I915_READ(GAMT_CHKN_BIT_REG) | + GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING)); /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */ if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0)) -- cgit v1.2.3 From 212154ba4d1c31ad828b8e1e2d4ecd4adcb02796 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 7 Sep 2017 08:40:09 -0700 Subject: drm/i915: Transform WaDisablePooledEuLoadBalancingFix into a simple register write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FF_SLICE_CS_CHICKEN2 does not belong to the context image. Cc: Chris Wilson Cc: Mika Kuoppala Cc: Rodrigo Vivi Signed-off-by: Oscar Mateo Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/1504798809-5653-6-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 0701ddb68b6a..3ae89a9d6241 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1024,8 +1024,8 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine) /* WaDisablePooledEuLoadBalancingFix:bxt */ if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) { - WA_SET_BIT_MASKED(FF_SLICE_CS_CHICKEN2, - GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE); + I915_WRITE(FF_SLICE_CS_CHICKEN2, + _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE)); } /* WaDisableSbeCacheDispatchPortSharing:bxt */ -- cgit v1.2.3 From 5d5fe176155e6cfa4a53accb90e4010baa5266d0 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Tue, 15 Aug 2017 13:20:51 +0800 Subject: drm/i915/kvmgt: Sanitize PCI bar emulation For PCI, 64bit bar consumes two BAR registers, but this doesn't mean both of two BAR are valid. Actually the second BAR is regarded as reserved in this case. So we shouldn't emulate the second BAR. Signed-off-by: Changbin Du Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/kvmgt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 83e88c70272a..9201db0892f1 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -661,7 +661,6 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, buf, count); break; case VFIO_PCI_BAR0_REGION_INDEX: - case VFIO_PCI_BAR1_REGION_INDEX: if (is_write) { uint64_t bar0_start = intel_vgpu_get_bar0_addr(vgpu); @@ -674,6 +673,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, bar0_start + pos, buf, count); } break; + case VFIO_PCI_BAR1_REGION_INDEX: case VFIO_PCI_BAR2_REGION_INDEX: case VFIO_PCI_BAR3_REGION_INDEX: case VFIO_PCI_BAR4_REGION_INDEX: -- cgit v1.2.3 From f090a00df9ecdab5d066b099c1797e0070e27a36 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Tue, 15 Aug 2017 13:14:04 +0800 Subject: drm/i915/gvt: Add emulation for BAR2 (aperture) with normal file RW approach For vfio-pci, if the region support MMAP then it should support both mmap and normal file access. The user-space is free to choose which is being used. For qemu, we just need add 'x-no-mmap=on' for vfio-pci option. Currently GVTg only support MMAP for BAR2. So GVTg will not work when user turn on x-no-mmap option. This patch added file style access for BAR2, aka the GPU aperture. We map the entire aperture partition of active vGPU to kernel space when guest driver try to enable PCI Memory Space. Then we redirect the file RW operation from kvmgt to this mapped area. Link: https://bugzilla.redhat.com/show_bug.cgi?id=1458032 Signed-off-by: Changbin Du Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cfg_space.c | 26 +++++++++++++++----- drivers/gpu/drm/i915/gvt/gvt.h | 8 ++++++ drivers/gpu/drm/i915/gvt/kvmgt.c | 42 +++++++++++++++++++------------- drivers/gpu/drm/i915/gvt/mmio.c | 47 ++++++++++++++++++++++++++++++++++-- 4 files changed, 98 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index 40af17ec6312..be0dd8534993 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -110,13 +110,25 @@ int intel_vgpu_emulate_cfg_read(struct intel_vgpu *vgpu, unsigned int offset, static int map_aperture(struct intel_vgpu *vgpu, bool map) { - u64 first_gfn, first_mfn; + phys_addr_t aperture_pa = vgpu_aperture_pa_base(vgpu); + unsigned long aperture_sz = vgpu_aperture_sz(vgpu); + u64 first_gfn; u64 val; int ret; if (map == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked) return 0; + if (map) { + vgpu->gm.aperture_va = memremap(aperture_pa, aperture_sz, + MEMREMAP_WC); + if (!vgpu->gm.aperture_va) + return -ENOMEM; + } else { + memunmap(vgpu->gm.aperture_va); + vgpu->gm.aperture_va = NULL; + } + val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_2]; if (val & PCI_BASE_ADDRESS_MEM_TYPE_64) val = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2); @@ -124,14 +136,16 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map) val = *(u32 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2); first_gfn = (val + vgpu_aperture_offset(vgpu)) >> PAGE_SHIFT; - first_mfn = vgpu_aperture_pa_base(vgpu) >> PAGE_SHIFT; ret = intel_gvt_hypervisor_map_gfn_to_mfn(vgpu, first_gfn, - first_mfn, - vgpu_aperture_sz(vgpu) >> - PAGE_SHIFT, map); - if (ret) + aperture_pa >> PAGE_SHIFT, + aperture_sz >> PAGE_SHIFT, + map); + if (ret) { + memunmap(vgpu->gm.aperture_va); + vgpu->gm.aperture_va = NULL; return ret; + } vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked = map; return 0; diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 44b719eda8c4..2fe22e1b517c 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -80,6 +80,7 @@ struct intel_gvt_device_info { struct intel_vgpu_gm { u64 aperture_sz; u64 hidden_sz; + void *aperture_va; struct drm_mm_node low_gm_node; struct drm_mm_node high_gm_node; }; @@ -474,6 +475,13 @@ int intel_vgpu_emulate_cfg_read(struct intel_vgpu *vgpu, unsigned int offset, int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes); +static inline u64 intel_vgpu_get_bar_gpa(struct intel_vgpu *vgpu, int bar) +{ + /* We are 64bit bar. */ + return (*(u64 *)(vgpu->cfg_space.virtual_cfg_space + bar)) & + PCI_BASE_ADDRESS_MEM_MASK; +} + void intel_gvt_clean_opregion(struct intel_gvt *gvt); int intel_gvt_init_opregion(struct intel_gvt *gvt); diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 9201db0892f1..ae65268efce3 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -609,21 +609,20 @@ static void intel_vgpu_release_work(struct work_struct *work) __intel_vgpu_release(vgpu); } -static uint64_t intel_vgpu_get_bar0_addr(struct intel_vgpu *vgpu) +static uint64_t intel_vgpu_get_bar_addr(struct intel_vgpu *vgpu, int bar) { u32 start_lo, start_hi; u32 mem_type; - int pos = PCI_BASE_ADDRESS_0; - start_lo = (*(u32 *)(vgpu->cfg_space.virtual_cfg_space + pos)) & + start_lo = (*(u32 *)(vgpu->cfg_space.virtual_cfg_space + bar)) & PCI_BASE_ADDRESS_MEM_MASK; - mem_type = (*(u32 *)(vgpu->cfg_space.virtual_cfg_space + pos)) & + mem_type = (*(u32 *)(vgpu->cfg_space.virtual_cfg_space + bar)) & PCI_BASE_ADDRESS_MEM_TYPE_MASK; switch (mem_type) { case PCI_BASE_ADDRESS_MEM_TYPE_64: start_hi = (*(u32 *)(vgpu->cfg_space.virtual_cfg_space - + pos + 4)); + + bar + 4)); break; case PCI_BASE_ADDRESS_MEM_TYPE_32: case PCI_BASE_ADDRESS_MEM_TYPE_1M: @@ -637,6 +636,21 @@ static uint64_t intel_vgpu_get_bar0_addr(struct intel_vgpu *vgpu) return ((u64)start_hi << 32) | start_lo; } +static int intel_vgpu_bar_rw(struct intel_vgpu *vgpu, int bar, uint64_t off, + void *buf, unsigned int count, bool is_write) +{ + uint64_t bar_start = intel_vgpu_get_bar_addr(vgpu, bar); + int ret; + + if (is_write) + ret = intel_gvt_ops->emulate_mmio_write(vgpu, + bar_start + off, buf, count); + else + ret = intel_gvt_ops->emulate_mmio_read(vgpu, + bar_start + off, buf, count); + return ret; +} + static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, size_t count, loff_t *ppos, bool is_write) { @@ -661,20 +675,14 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, buf, count); break; case VFIO_PCI_BAR0_REGION_INDEX: - if (is_write) { - uint64_t bar0_start = intel_vgpu_get_bar0_addr(vgpu); - - ret = intel_gvt_ops->emulate_mmio_write(vgpu, - bar0_start + pos, buf, count); - } else { - uint64_t bar0_start = intel_vgpu_get_bar0_addr(vgpu); - - ret = intel_gvt_ops->emulate_mmio_read(vgpu, - bar0_start + pos, buf, count); - } + ret = intel_vgpu_bar_rw(vgpu, PCI_BASE_ADDRESS_0, pos, + buf, count, is_write); break; - case VFIO_PCI_BAR1_REGION_INDEX: case VFIO_PCI_BAR2_REGION_INDEX: + ret = intel_vgpu_bar_rw(vgpu, PCI_BASE_ADDRESS_2, pos, + buf, count, is_write); + break; + case VFIO_PCI_BAR1_REGION_INDEX: case VFIO_PCI_BAR3_REGION_INDEX: case VFIO_PCI_BAR4_REGION_INDEX: case VFIO_PCI_BAR5_REGION_INDEX: diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index 980ec8906b1e..1e1310f50289 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -45,8 +45,7 @@ */ int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa) { - u64 gttmmio_gpa = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_0) & - ~GENMASK(3, 0); + u64 gttmmio_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_0); return gpa - gttmmio_gpa; } @@ -57,6 +56,38 @@ int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa) (reg >= gvt->device_info.gtt_start_offset \ && reg < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt)) +static bool vgpu_gpa_is_aperture(struct intel_vgpu *vgpu, uint64_t gpa) +{ + u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2); + u64 aperture_sz = vgpu_aperture_sz(vgpu); + + return gpa >= aperture_gpa && gpa < aperture_gpa + aperture_sz; +} + +static int vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t gpa, + void *pdata, unsigned int size, bool is_read) +{ + u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2); + u64 offset = gpa - aperture_gpa; + + if (!vgpu_gpa_is_aperture(vgpu, gpa + size - 1)) { + gvt_vgpu_err("Aperture rw out of range, offset %llx, size %d\n", + offset, size); + return -EINVAL; + } + + if (!vgpu->gm.aperture_va) { + gvt_vgpu_err("BAR is not enabled\n"); + return -ENXIO; + } + + if (is_read) + memcpy(pdata, vgpu->gm.aperture_va + offset, size); + else + memcpy(vgpu->gm.aperture_va + offset, pdata, size); + return 0; +} + static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa, void *p_data, unsigned int bytes, bool read) { @@ -133,6 +164,12 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, } mutex_lock(&gvt->lock); + if (vgpu_gpa_is_aperture(vgpu, pa)) { + ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, true); + mutex_unlock(&gvt->lock); + return ret; + } + if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { struct intel_vgpu_guest_page *gp; @@ -224,6 +261,12 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, mutex_lock(&gvt->lock); + if (vgpu_gpa_is_aperture(vgpu, pa)) { + ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, false); + mutex_unlock(&gvt->lock); + return ret; + } + if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { struct intel_vgpu_guest_page *gp; -- cgit v1.2.3 From 0a53bc07f044c4c51eb0dc1386c504db80ca8d00 Mon Sep 17 00:00:00 2001 From: fred gao Date: Fri, 18 Aug 2017 15:41:06 +0800 Subject: drm/i915/gvt: Separate cmd scan from request allocation Currently i915 request structure and shadow ring buffer are allocated before command scan, so it will have to restore to previous states once any error happens afterwards in the long dispatch_workload path. This patch is to introduce a reserved ring buffer created at the beginning of vGPU initialization. Workload will be coped to this reserved buffer and be scanned first, the i915 request and shadow ring buffer are only allocated after the result of scan is successful. To balance the memory usage and buffer alloc time, the coming bigger ring buffer will be reallocated and kept until more bigger buffer is coming. v2: - use kmalloc for the smaller ring buffer, realloc if required. (Zhenyu) v3: - remove the dynamically allocated ring buffer. (Zhenyu) v4: - code style polish. - kfree previous allocated buffer once kmalloc failed. (Zhenyu) Signed-off-by: fred gao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 31 ++++++++----- drivers/gpu/drm/i915/gvt/execlist.c | 30 +++++++++++++ drivers/gpu/drm/i915/gvt/gvt.h | 3 ++ drivers/gpu/drm/i915/gvt/scheduler.c | 84 ++++++++++++++++++++++++----------- 4 files changed, 110 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 72b97ce525e8..e53efc0524f4 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -2603,7 +2603,8 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload) { struct intel_vgpu *vgpu = workload->vgpu; unsigned long gma_head, gma_tail, gma_top, guest_rb_size; - u32 *cs; + void *shadow_ring_buffer_va; + int ring_id = workload->ring_id; int ret; guest_rb_size = _RING_CTL_BUF_SIZE(workload->rb_ctl); @@ -2616,34 +2617,42 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload) gma_tail = workload->rb_start + workload->rb_tail; gma_top = workload->rb_start + guest_rb_size; - /* allocate shadow ring buffer */ - cs = intel_ring_begin(workload->req, workload->rb_len / sizeof(u32)); - if (IS_ERR(cs)) - return PTR_ERR(cs); + if (workload->rb_len > vgpu->reserve_ring_buffer_size[ring_id]) { + void *va = vgpu->reserve_ring_buffer_va[ring_id]; + /* realloc the new ring buffer if needed */ + vgpu->reserve_ring_buffer_va[ring_id] = + krealloc(va, workload->rb_len, GFP_KERNEL); + if (!vgpu->reserve_ring_buffer_va[ring_id]) { + gvt_vgpu_err("fail to alloc reserve ring buffer\n"); + return -ENOMEM; + } + vgpu->reserve_ring_buffer_size[ring_id] = workload->rb_len; + } + + shadow_ring_buffer_va = vgpu->reserve_ring_buffer_va[ring_id]; /* get shadow ring buffer va */ - workload->shadow_ring_buffer_va = cs; + workload->shadow_ring_buffer_va = shadow_ring_buffer_va; /* head > tail --> copy head <-> top */ if (gma_head > gma_tail) { ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm, - gma_head, gma_top, cs); + gma_head, gma_top, shadow_ring_buffer_va); if (ret < 0) { gvt_vgpu_err("fail to copy guest ring buffer\n"); return ret; } - cs += ret / sizeof(u32); + shadow_ring_buffer_va += ret; gma_head = workload->rb_start; } /* copy head or start <-> tail */ - ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm, gma_head, gma_tail, cs); + ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm, gma_head, gma_tail, + shadow_ring_buffer_va); if (ret < 0) { gvt_vgpu_err("fail to copy guest ring buffer\n"); return ret; } - cs += ret / sizeof(u32); - intel_ring_advance(workload->req, cs); return 0; } diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index 91b4300f3b39..1e2c27704be5 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -820,10 +820,21 @@ static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask) void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu) { + enum intel_engine_id i; + struct intel_engine_cs *engine; + clean_workloads(vgpu, ALL_ENGINES); kmem_cache_destroy(vgpu->workloads); + + for_each_engine(engine, vgpu->gvt->dev_priv, i) { + kfree(vgpu->reserve_ring_buffer_va[i]); + vgpu->reserve_ring_buffer_va[i] = NULL; + vgpu->reserve_ring_buffer_size[i] = 0; + } + } +#define RESERVE_RING_BUFFER_SIZE ((1 * PAGE_SIZE)/8) int intel_vgpu_init_execlist(struct intel_vgpu *vgpu) { enum intel_engine_id i; @@ -843,7 +854,26 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu) if (!vgpu->workloads) return -ENOMEM; + /* each ring has a shadow ring buffer until vgpu destroyed */ + for_each_engine(engine, vgpu->gvt->dev_priv, i) { + vgpu->reserve_ring_buffer_va[i] = + kmalloc(RESERVE_RING_BUFFER_SIZE, GFP_KERNEL); + if (!vgpu->reserve_ring_buffer_va[i]) { + gvt_vgpu_err("fail to alloc reserve ring buffer\n"); + goto out; + } + vgpu->reserve_ring_buffer_size[i] = RESERVE_RING_BUFFER_SIZE; + } return 0; +out: + for_each_engine(engine, vgpu->gvt->dev_priv, i) { + if (vgpu->reserve_ring_buffer_size[i]) { + kfree(vgpu->reserve_ring_buffer_va[i]); + vgpu->reserve_ring_buffer_va[i] = NULL; + vgpu->reserve_ring_buffer_size[i] = 0; + } + } + return -ENOMEM; } void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu, diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 2fe22e1b517c..031868f08e1c 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -166,6 +166,9 @@ struct intel_vgpu { struct list_head workload_q_head[I915_NUM_ENGINES]; struct kmem_cache *workloads; atomic_t running_workload_num; + /* 1/2K for each reserve ring buffer */ + void *reserve_ring_buffer_va[I915_NUM_ENGINES]; + int reserve_ring_buffer_size[I915_NUM_ENGINES]; DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES); struct i915_gem_context *shadow_ctx; DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES); diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 391800d2067b..0e480f59f659 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -201,6 +201,34 @@ static void shadow_context_descriptor_update(struct i915_gem_context *ctx, ce->lrc_desc = desc; } +static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload) +{ + struct intel_vgpu *vgpu = workload->vgpu; + void *shadow_ring_buffer_va; + u32 *cs; + + /* allocate shadow ring buffer */ + cs = intel_ring_begin(workload->req, workload->rb_len / sizeof(u32)); + if (IS_ERR(cs)) { + gvt_vgpu_err("fail to alloc size =%ld shadow ring buffer\n", + workload->rb_len); + return PTR_ERR(cs); + } + + shadow_ring_buffer_va = workload->shadow_ring_buffer_va; + + /* get shadow ring buffer va */ + workload->shadow_ring_buffer_va = cs; + + memcpy(cs, shadow_ring_buffer_va, + workload->rb_len); + + cs += workload->rb_len / sizeof(u32); + intel_ring_advance(workload->req, cs); + + return 0; +} + /** * intel_gvt_scan_and_shadow_workload - audit the workload by scanning and * shadow it as well, include ringbuffer,wa_ctx and ctx. @@ -214,8 +242,10 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) int ring_id = workload->ring_id; struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; + struct intel_engine_cs *engine = dev_priv->engine[ring_id]; struct drm_i915_gem_request *rq; struct intel_vgpu *vgpu = workload->vgpu; + struct intel_ring *ring; int ret; lockdep_assert_held(&dev_priv->drm.struct_mutex); @@ -231,17 +261,6 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) shadow_context_descriptor_update(shadow_ctx, dev_priv->engine[ring_id]); - rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx); - if (IS_ERR(rq)) { - gvt_vgpu_err("fail to allocate gem request\n"); - ret = PTR_ERR(rq); - goto out; - } - - gvt_dbg_sched("ring id %d get i915 gem request %p\n", ring_id, rq); - - workload->req = i915_gem_request_get(rq); - ret = intel_gvt_scan_and_shadow_ringbuffer(workload); if (ret) goto out; @@ -253,10 +272,37 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) goto out; } + /* pin shadow context by gvt even the shadow context will be pinned + * when i915 alloc request. That is because gvt will update the guest + * context from shadow context when workload is completed, and at that + * moment, i915 may already unpined the shadow context to make the + * shadow_ctx pages invalid. So gvt need to pin itself. After update + * the guest context, gvt can unpin the shadow_ctx safely. + */ + ring = engine->context_pin(engine, shadow_ctx); + if (IS_ERR(ring)) { + ret = PTR_ERR(ring); + gvt_vgpu_err("fail to pin shadow context\n"); + goto out; + } + ret = populate_shadow_context(workload); if (ret) goto out; + rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx); + if (IS_ERR(rq)) { + gvt_vgpu_err("fail to allocate gem request\n"); + ret = PTR_ERR(rq); + goto out; + } + + gvt_dbg_sched("ring id %d get i915 gem request %p\n", ring_id, rq); + + workload->req = i915_gem_request_get(rq); + ret = copy_workload_to_ring_buffer(workload); + if (ret) + goto out; workload->shadowed = true; out: @@ -269,8 +315,6 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; struct intel_engine_cs *engine = dev_priv->engine[ring_id]; - struct intel_vgpu *vgpu = workload->vgpu; - struct intel_ring *ring; int ret = 0; gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n", @@ -288,20 +332,6 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) goto out; } - /* pin shadow context by gvt even the shadow context will be pinned - * when i915 alloc request. That is because gvt will update the guest - * context from shadow context when workload is completed, and at that - * moment, i915 may already unpined the shadow context to make the - * shadow_ctx pages invalid. So gvt need to pin itself. After update - * the guest context, gvt can unpin the shadow_ctx safely. - */ - ring = engine->context_pin(engine, shadow_ctx); - if (IS_ERR(ring)) { - ret = PTR_ERR(ring); - gvt_vgpu_err("fail to pin shadow context\n"); - goto out; - } - out: if (ret) workload->status = ret; -- cgit v1.2.3 From a3cfdca920b274618d6046d85a474308ee28e5bb Mon Sep 17 00:00:00 2001 From: fred gao Date: Fri, 18 Aug 2017 15:41:07 +0800 Subject: drm/i915/gvt: Add error handling for intel_gvt_scan_and_shadow_workload When an error occurs after shadow_indirect_ctx, this patch is to do the proper cleanup and rollback to the original states for shadowed indirect context before the workload is abandoned. v2: - split the mixed several error paths for better review. (Zhenyu) v3: - no return check for clean up functions. (Changbin) v4: - expose and reuse the existing release_shadow_wa_ctx. (Zhenyu) v5: - move the release function to scheduler.c file. (Zhenyu) v6: - move error handling code of intel_gvt_scan_and_shadow_workload to here. (Zhenyu) Signed-off-by: fred gao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/execlist.c | 9 --------- drivers/gpu/drm/i915/gvt/scheduler.c | 28 +++++++++++++++++++++------- drivers/gpu/drm/i915/gvt/scheduler.h | 1 + 3 files changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index 1e2c27704be5..cbb2e8da1c7a 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -489,15 +489,6 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload) } } -static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) -{ - if (!wa_ctx->indirect_ctx.obj) - return; - - i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj); - i915_gem_object_put(wa_ctx->indirect_ctx.obj); -} - static int complete_execlist_workload(struct intel_vgpu_workload *workload) { struct intel_vgpu *vgpu = workload->vgpu; diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 0e480f59f659..29171961af5e 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -229,6 +229,15 @@ static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload) return 0; } +void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) +{ + if (!wa_ctx->indirect_ctx.obj) + return; + + i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj); + i915_gem_object_put(wa_ctx->indirect_ctx.obj); +} + /** * intel_gvt_scan_and_shadow_workload - audit the workload by scanning and * shadow it as well, include ringbuffer,wa_ctx and ctx. @@ -263,13 +272,13 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) ret = intel_gvt_scan_and_shadow_ringbuffer(workload); if (ret) - goto out; + goto err_scan; if ((workload->ring_id == RCS) && (workload->wa_ctx.indirect_ctx.size != 0)) { ret = intel_gvt_scan_and_shadow_wa_ctx(&workload->wa_ctx); if (ret) - goto out; + goto err_scan; } /* pin shadow context by gvt even the shadow context will be pinned @@ -283,18 +292,18 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) if (IS_ERR(ring)) { ret = PTR_ERR(ring); gvt_vgpu_err("fail to pin shadow context\n"); - goto out; + goto err_shadow; } ret = populate_shadow_context(workload); if (ret) - goto out; + goto err_unpin; rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx); if (IS_ERR(rq)) { gvt_vgpu_err("fail to allocate gem request\n"); ret = PTR_ERR(rq); - goto out; + goto err_unpin; } gvt_dbg_sched("ring id %d get i915 gem request %p\n", ring_id, rq); @@ -302,10 +311,15 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) workload->req = i915_gem_request_get(rq); ret = copy_workload_to_ring_buffer(workload); if (ret) - goto out; + goto err_unpin; workload->shadowed = true; + return 0; -out: +err_unpin: + engine->context_unpin(engine, shadow_ctx); +err_shadow: + release_shadow_wa_ctx(&workload->wa_ctx); +err_scan: return ret; } diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h index 0d431a968a32..f36b85fd6d01 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.h +++ b/drivers/gpu/drm/i915/gvt/scheduler.h @@ -140,4 +140,5 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu); void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu); +void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx); #endif -- cgit v1.2.3 From 0cce2823ed37b75555749c0969528d8c74887ada Mon Sep 17 00:00:00 2001 From: fred gao Date: Fri, 18 Aug 2017 15:41:08 +0800 Subject: drm/i915/gvt: Refine error handling for prepare_execlist_workload refine the error handling for prepare_execlist_workload to restore to the original states once error occurs. only release the shadowed batch buffer and wa ctx when the workload is completed successfully. v2: - split the mixed several error paths for better review. (Zhenyu) v3: - handle prepare batch buffer/wa ctx pin errors and - emulate_schedule_in null issue. (Zhenyu) v4: - no need to handle emulate_schedule_in null issue. (Zhenyu) v5: - release the shadowed batch buffer and wa ctx only for the successful workload. (Zhenyu) v6: - polish the return style. (Zhenyu) Signed-off-by: fred gao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/execlist.c | 96 ++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index cbb2e8da1c7a..5ec07ecf33ad 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -368,7 +368,7 @@ static void free_workload(struct intel_vgpu_workload *workload) #define get_desc_from_elsp_dwords(ed, i) \ ((struct execlist_ctx_descriptor_format *)&((ed)->data[i * 2])) -static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) +static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) { const int gmadr_bytes = workload->vgpu->gvt->device_info.gmadr_bytes_in_cmd; struct intel_shadow_bb_entry *entry_obj; @@ -379,7 +379,7 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0, 4, 0); if (IS_ERR(vma)) { - return; + return PTR_ERR(vma); } /* FIXME: we are not tracking our pinned VMA leaving it @@ -392,6 +392,7 @@ static void prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) if (gmadr_bytes == 8) entry_obj->bb_start_cmd_va[2] = 0; } + return 0; } static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx) @@ -420,7 +421,7 @@ static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx) return 0; } -static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) +static int prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) { struct i915_vma *vma; unsigned char *per_ctx_va = @@ -428,12 +429,12 @@ static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) wa_ctx->indirect_ctx.size; if (wa_ctx->indirect_ctx.size == 0) - return; + return 0; vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL, 0, CACHELINE_BYTES, 0); if (IS_ERR(vma)) { - return; + return PTR_ERR(vma); } /* FIXME: we are not tracking our pinned VMA leaving it @@ -447,26 +448,7 @@ static void prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) memset(per_ctx_va, 0, CACHELINE_BYTES); update_wa_ctx_2_shadow_ctx(wa_ctx); -} - -static int prepare_execlist_workload(struct intel_vgpu_workload *workload) -{ - struct intel_vgpu *vgpu = workload->vgpu; - struct execlist_ctx_descriptor_format ctx[2]; - int ring_id = workload->ring_id; - - intel_vgpu_pin_mm(workload->shadow_mm); - intel_vgpu_sync_oos_pages(workload->vgpu); - intel_vgpu_flush_post_shadow(workload->vgpu); - prepare_shadow_batch_buffer(workload); - prepare_shadow_wa_ctx(&workload->wa_ctx); - if (!workload->emulate_schedule_in) - return 0; - - ctx[0] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 1); - ctx[1] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 0); - - return emulate_execlist_schedule_in(&vgpu->execlist[ring_id], ctx); + return 0; } static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload) @@ -489,6 +471,64 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload) } } +static int prepare_execlist_workload(struct intel_vgpu_workload *workload) +{ + struct intel_vgpu *vgpu = workload->vgpu; + struct execlist_ctx_descriptor_format ctx[2]; + int ring_id = workload->ring_id; + int ret; + + ret = intel_vgpu_pin_mm(workload->shadow_mm); + if (ret) { + gvt_vgpu_err("fail to vgpu pin mm\n"); + goto out; + } + + ret = intel_vgpu_sync_oos_pages(workload->vgpu); + if (ret) { + gvt_vgpu_err("fail to vgpu sync oos pages\n"); + goto err_unpin_mm; + } + + ret = intel_vgpu_flush_post_shadow(workload->vgpu); + if (ret) { + gvt_vgpu_err("fail to flush post shadow\n"); + goto err_unpin_mm; + } + + ret = prepare_shadow_batch_buffer(workload); + if (ret) { + gvt_vgpu_err("fail to prepare_shadow_batch_buffer\n"); + goto err_unpin_mm; + } + + ret = prepare_shadow_wa_ctx(&workload->wa_ctx); + if (ret) { + gvt_vgpu_err("fail to prepare_shadow_wa_ctx\n"); + goto err_shadow_batch; + } + + if (!workload->emulate_schedule_in) + return 0; + + ctx[0] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 1); + ctx[1] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 0); + + ret = emulate_execlist_schedule_in(&vgpu->execlist[ring_id], ctx); + if (!ret) + goto out; + else + gvt_vgpu_err("fail to emulate execlist schedule in\n"); + + release_shadow_wa_ctx(&workload->wa_ctx); +err_shadow_batch: + release_shadow_batch_buffer(workload); +err_unpin_mm: + intel_vgpu_unpin_mm(workload->shadow_mm); +out: + return ret; +} + static int complete_execlist_workload(struct intel_vgpu_workload *workload) { struct intel_vgpu *vgpu = workload->vgpu; @@ -502,8 +542,10 @@ static int complete_execlist_workload(struct intel_vgpu_workload *workload) gvt_dbg_el("complete workload %p status %d\n", workload, workload->status); - release_shadow_batch_buffer(workload); - release_shadow_wa_ctx(&workload->wa_ctx); + if (!workload->status) { + release_shadow_batch_buffer(workload); + release_shadow_wa_ctx(&workload->wa_ctx); + } if (workload->status || (vgpu->resetting_eng & ENGINE_MASK(ring_id))) { /* if workload->status is not successful means HW GPU -- cgit v1.2.3 From 46b441efa374cf1581c267a16089c205f2fc0ded Mon Sep 17 00:00:00 2001 From: fred gao Date: Fri, 18 Aug 2017 15:41:09 +0800 Subject: drm/i915/gvt: Refine error handling for intel_vgpu_pin_mm When it is failed in shadow_mm, the pin_count should rollback to the original states before return. v2: - split the mixed several error paths for better review. (Zhenyu) v3: increase the pincount after shadow success. (Zhenyu) Signed-off-by: fred gao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index e6dfc3331f4b..0bd028f8fef5 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1647,14 +1647,13 @@ int intel_vgpu_pin_mm(struct intel_vgpu_mm *mm) if (WARN_ON(mm->type != INTEL_GVT_MM_PPGTT)) return 0; - atomic_inc(&mm->pincount); - if (!mm->shadowed) { ret = shadow_mm(mm); if (ret) return ret; } + atomic_inc(&mm->pincount); list_del_init(&mm->lru_list); list_add_tail(&mm->lru_list, &mm->vgpu->gvt->gtt.mm_lru_list_head); return 0; -- cgit v1.2.3 From 0f43702a334b2848ae2e942dbc0677ddc4566b57 Mon Sep 17 00:00:00 2001 From: fred gao Date: Fri, 18 Aug 2017 15:41:10 +0800 Subject: drm/i915/gvt: Refine error handling in dispatch_workload When an error occurs in dispatch_workload, this patch is to do the proper cleanup and rollback to the original states before the workload is abandoned. v2: - split the mixed several error paths for better review. (Zhenyu) v3: - original PTR_ERR(cs) is good and code cleanup. (Zhenyu) v4: - reuse the existing i915_add_request for error handling. (Zhenyu) v5: - remove the duplicate error handling release_shadow_wa_ctx and move the engine->context_unpin upper. (Zhenyu) v6: - keep the old label "out". (Zhenyu) Signed-off-by: fred gao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/scheduler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 29171961af5e..6fb9b589276d 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -342,8 +342,10 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) if (workload->prepare) { ret = workload->prepare(workload); - if (ret) + if (ret) { + engine->context_unpin(engine, shadow_ctx); goto out; + } } out: -- cgit v1.2.3 From 1e3197d6ad73ef34b71d96cfb37ddf0b7bddac0e Mon Sep 17 00:00:00 2001 From: fred gao Date: Fri, 18 Aug 2017 15:41:11 +0800 Subject: drm/i915/gvt: Refine error handling for perform_bb_shadow fix the wrong return type and return error once the unknown command is scanned. v2: - separate this error handle from healthy rating code. (Zhenyu) Signed-off-by: fred gao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index e53efc0524f4..23a9bbbb6565 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -1576,11 +1576,11 @@ static int batch_buffer_needs_scan(struct parser_exec_state *s) return 1; } -static uint32_t find_bb_size(struct parser_exec_state *s) +static int find_bb_size(struct parser_exec_state *s) { unsigned long gma = 0; struct cmd_info *info; - uint32_t bb_size = 0; + int bb_size = 0; uint32_t cmd_len = 0; bool met_bb_end = false; struct intel_vgpu *vgpu = s->vgpu; @@ -1637,6 +1637,8 @@ static int perform_bb_shadow(struct parser_exec_state *s) /* get the size of the batch buffer */ bb_size = find_bb_size(s); + if (bb_size < 0) + return -EINVAL; /* allocate shadow batch buffer */ entry_obj = kmalloc(sizeof(*entry_obj), GFP_KERNEL); -- cgit v1.2.3 From f1751362d6357a90bc6e53176cec715ff2dbed74 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Fri, 18 Aug 2017 17:49:58 +0800 Subject: drm/i915/gvt: Fix incorrect PCI BARs reporting Looking at our virtual PCI device, we can see surprising Region 4 and Region 5. 00:10.0 VGA compatible controller: Intel Corporation Sky Lake Integrated Graphics (rev 06) (prog-if 00 [VGA controller]) .... Region 0: Memory at 140000000 (64-bit, non-prefetchable) [size=16M] Region 2: Memory at 180000000 (64-bit, prefetchable) [size=1G] Region 4: Memory at (32-bit, non-prefetchable) Region 5: Memory at (32-bit, non-prefetchable) Expansion ROM at febd6000 [disabled] [size=2K] The fact is that we only implemented BAR0 and BAR2. Surprising Region 4 and Region 5 are shown because we report their size as 0xffffffff. They should report size 0 instead. BTW, the physical GPU has a PIO BAR. GVTg hasn't implemented PIO access, so we ignored this BAR for vGPU device. v2: fix BAR size value calculation. Link: https://bugzilla.redhat.com/show_bug.cgi?id=1458032 Signed-off-by: Changbin Du Cc: stable@vger.kernel.org Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cfg_space.c | 113 +++++++++++++++-------------------- 1 file changed, 48 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index be0dd8534993..ce71b5878d65 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -211,78 +211,65 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu, static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { - unsigned int bar_index = - (rounddown(offset, 8) % PCI_BASE_ADDRESS_0) / 8; u32 new = *(u32 *)(p_data); bool lo = IS_ALIGNED(offset, 8); u64 size; int ret = 0; bool mmio_enabled = vgpu_cfg_space(vgpu)[PCI_COMMAND] & PCI_COMMAND_MEMORY; + struct intel_vgpu_pci_bar *bars = vgpu->cfg_space.bar; - if (WARN_ON(bar_index >= INTEL_GVT_PCI_BAR_MAX)) - return -EINVAL; - + /* + * Power-up software can determine how much address + * space the device requires by writing a value of + * all 1's to the register and then reading the value + * back. The device will return 0's in all don't-care + * address bits. + */ if (new == 0xffffffff) { - /* - * Power-up software can determine how much address - * space the device requires by writing a value of - * all 1's to the register and then reading the value - * back. The device will return 0's in all don't-care - * address bits. - */ - size = vgpu->cfg_space.bar[bar_index].size; - if (lo) { - new = rounddown(new, size); - } else { - u32 val = vgpu_cfg_space(vgpu)[rounddown(offset, 8)]; - /* for 32bit mode bar it returns all-0 in upper 32 - * bit, for 64bit mode bar it will calculate the - * size with lower 32bit and return the corresponding - * value + switch (offset) { + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: + size = ~(bars[INTEL_GVT_PCI_BAR_GTTMMIO].size -1); + intel_vgpu_write_pci_bar(vgpu, offset, + size >> (lo ? 0 : 32), lo); + /* + * Untrap the BAR, since guest hasn't configured a + * valid GPA */ - if (val & PCI_BASE_ADDRESS_MEM_TYPE_64) - new &= (~(size-1)) >> 32; - else - new = 0; - } - /* - * Unmapp & untrap the BAR, since guest hasn't configured a - * valid GPA - */ - switch (bar_index) { - case INTEL_GVT_PCI_BAR_GTTMMIO: ret = trap_gttmmio(vgpu, false); break; - case INTEL_GVT_PCI_BAR_APERTURE: + case PCI_BASE_ADDRESS_2: + case PCI_BASE_ADDRESS_3: + size = ~(bars[INTEL_GVT_PCI_BAR_APERTURE].size -1); + intel_vgpu_write_pci_bar(vgpu, offset, + size >> (lo ? 0 : 32), lo); ret = map_aperture(vgpu, false); break; + default: + /* Unimplemented BARs */ + intel_vgpu_write_pci_bar(vgpu, offset, 0x0, false); } - intel_vgpu_write_pci_bar(vgpu, offset, new, lo); } else { - /* - * Unmapp & untrap the old BAR first, since guest has - * re-configured the BAR - */ - switch (bar_index) { - case INTEL_GVT_PCI_BAR_GTTMMIO: - ret = trap_gttmmio(vgpu, false); + switch (offset) { + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: + /* + * Untrap the old BAR first, since guest has + * re-configured the BAR + */ + trap_gttmmio(vgpu, false); + intel_vgpu_write_pci_bar(vgpu, offset, new, lo); + ret = trap_gttmmio(vgpu, mmio_enabled); break; - case INTEL_GVT_PCI_BAR_APERTURE: - ret = map_aperture(vgpu, false); + case PCI_BASE_ADDRESS_2: + case PCI_BASE_ADDRESS_3: + map_aperture(vgpu, false); + intel_vgpu_write_pci_bar(vgpu, offset, new, lo); + ret = map_aperture(vgpu, mmio_enabled); break; - } - intel_vgpu_write_pci_bar(vgpu, offset, new, lo); - /* Track the new BAR */ - if (mmio_enabled) { - switch (bar_index) { - case INTEL_GVT_PCI_BAR_GTTMMIO: - ret = trap_gttmmio(vgpu, true); - break; - case INTEL_GVT_PCI_BAR_APERTURE: - ret = map_aperture(vgpu, true); - break; - } + default: + intel_vgpu_write_pci_bar(vgpu, offset, new, lo); } } return ret; @@ -313,10 +300,7 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, } switch (rounddown(offset, 4)) { - case PCI_BASE_ADDRESS_0: - case PCI_BASE_ADDRESS_1: - case PCI_BASE_ADDRESS_2: - case PCI_BASE_ADDRESS_3: + case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5: if (WARN_ON(!IS_ALIGNED(offset, 4))) return -EINVAL; return emulate_pci_bar_write(vgpu, offset, p_data, bytes); @@ -358,7 +342,6 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu, struct intel_gvt *gvt = vgpu->gvt; const struct intel_gvt_device_info *info = &gvt->device_info; u16 *gmch_ctl; - int i; memcpy(vgpu_cfg_space(vgpu), gvt->firmware.cfg_space, info->cfg_space_size); @@ -385,13 +368,13 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu, */ memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_1, 0, 4); memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_3, 0, 4); + memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_4, 0, 8); memset(vgpu_cfg_space(vgpu) + INTEL_GVT_PCI_OPREGION, 0, 4); - for (i = 0; i < INTEL_GVT_MAX_BAR_NUM; i++) { - vgpu->cfg_space.bar[i].size = pci_resource_len( - gvt->dev_priv->drm.pdev, i * 2); - vgpu->cfg_space.bar[i].tracked = false; - } + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].size = + pci_resource_len(gvt->dev_priv->drm.pdev, 0); + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size = + pci_resource_len(gvt->dev_priv->drm.pdev, 2); } /** -- cgit v1.2.3 From 02d578e5edd980eac3fbed15db4d9e5665f22089 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Wed, 23 Aug 2017 14:08:10 +0800 Subject: drm/i915/gvt: Add support for PCIe extended configuration space IGD is PCIe device and has extended configuration space. Checking the binary dump, we can see we have Caps located out of PCI compatible Configuration Space range. 0x000: 86 80 12 19 17 04 10 00 06 00 00 03 00 00 00 00 0x010: 04 00 00 10 08 00 00 00 0c 00 00 00 08 00 00 00 0x020: 00 00 00 00 00 00 00 00 00 00 00 00 28 10 b9 06 0x030: 00 f8 ff ff 40 00 00 00 00 00 00 00 0b 01 00 00 0x040: 09 70 0c 01 71 26 01 62 c8 00 04 84 00 00 00 00 0x050: c1 00 00 00 39 00 00 00 00 00 00 00 01 00 00 a2 0x060: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0x070: 10 ac 92 00 00 80 00 10 00 00 00 00 00 00 00 00 0x080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0a0: 00 00 00 00 00 00 00 00 00 00 00 00 05 d0 01 00 0x0b0: 18 00 e0 fe 00 00 00 00 00 00 00 00 00 00 00 00 0x0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0d0: 01 00 22 00 00 80 00 00 00 00 00 00 00 00 00 00 0x0e0: 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 0x0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100: 1b 00 01 20 02 14 00 00 00 00 00 00 00 00 00 00 ... Currently, we only emulate the PCI compatible Configuration Space. This is okay if we attach vGPU to PCI bus. But when we attach to a PCI Express bus (when Qemu emulates a Intel Q35 chipset which has PCIe slot), it will not work. Extended Configuration Space is required for a PCIe device. This patch extended the virtual configuration space from 256 bytes to 4KB bytes. So we are to be a *real* PCIe device. And for the Extended CapList we keep same to physical GPU. Cc: Laszlo Ersek Tested-by: Laszlo Ersek Signed-off-by: Changbin Du Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cfg_space.c | 4 ++-- drivers/gpu/drm/i915/gvt/gvt.c | 2 +- drivers/gpu/drm/i915/gvt/gvt.h | 3 +-- drivers/gpu/drm/i915/gvt/kvmgt.c | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index ce71b5878d65..ab19545d59a1 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -101,7 +101,7 @@ int intel_vgpu_emulate_cfg_read(struct intel_vgpu *vgpu, unsigned int offset, if (WARN_ON(bytes > 4)) return -EINVAL; - if (WARN_ON(offset + bytes > INTEL_GVT_MAX_CFG_SPACE_SZ)) + if (WARN_ON(offset + bytes > vgpu->gvt->device_info.cfg_space_size)) return -EINVAL; memcpy(p_data, vgpu_cfg_space(vgpu) + offset, bytes); @@ -289,7 +289,7 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, if (WARN_ON(bytes > 4)) return -EINVAL; - if (WARN_ON(offset + bytes > INTEL_GVT_MAX_CFG_SPACE_SZ)) + if (WARN_ON(offset + bytes > vgpu->gvt->device_info.cfg_space_size)) return -EINVAL; /* First check if it's PCI_COMMAND */ diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index c27c6838eaca..aaa347f8620c 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c @@ -111,7 +111,7 @@ static void init_device_info(struct intel_gvt *gvt) if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv) || IS_KABYLAKE(gvt->dev_priv)) { info->max_support_vgpus = 8; - info->cfg_space_size = 256; + info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE; info->mmio_size = 2 * 1024 * 1024; info->mmio_bar = 0; info->gtt_start_offset = 8 * 1024 * 1024; diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 031868f08e1c..9c2e7c0aa38f 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -100,7 +100,6 @@ struct intel_vgpu_mmio { bool disable_warn_untrack; }; -#define INTEL_GVT_MAX_CFG_SPACE_SZ 256 #define INTEL_GVT_MAX_BAR_NUM 4 struct intel_vgpu_pci_bar { @@ -109,7 +108,7 @@ struct intel_vgpu_pci_bar { }; struct intel_vgpu_cfg_space { - unsigned char virtual_cfg_space[INTEL_GVT_MAX_CFG_SPACE_SZ]; + unsigned char virtual_cfg_space[PCI_CFG_SPACE_EXP_SIZE]; struct intel_vgpu_pci_bar bar[INTEL_GVT_MAX_BAR_NUM]; }; diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index ae65268efce3..96060920a6fe 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -978,7 +978,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd, switch (info.index) { case VFIO_PCI_CONFIG_REGION_INDEX: info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); - info.size = INTEL_GVT_MAX_CFG_SPACE_SZ; + info.size = vgpu->gvt->device_info.cfg_space_size; info.flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE; break; -- cgit v1.2.3 From 59cd827f26019ac790b2f34cbad478037f51c570 Mon Sep 17 00:00:00 2001 From: Matt Chen Date: Mon, 28 Aug 2017 14:57:54 +0800 Subject: iwlwifi: mvm: fix wowlan resume failed to load INIT ucode If we set disconnect on wowlan and run suspend/resume, will run into: ...snipped iwlwifi 0000:01:00.0: Failed to load firmware chunk! iwlwifi 0000:01:00.0: Could not load the [0] uCode section iwlwifi 0000:01:00.0: Failed to start INIT ucode: -110 iwlwifi 0000:01:00.0: Failed to run INIT ucode: -110 iwlwifi 0000:01:00.0: Failed to start RT ucode: -110 It is because we still keep IWL_MVM_STATUS_IN_HW_RESTART in __iwl_mvm_resume. When mac80211 starts the device as __iwl_mvm_mac_start(), we will miss iwl_mvm_restart_cleanup(mvm). Signed-off-by: Matt Chen Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 5de19ea10575..b205a7bfb828 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2167,7 +2167,7 @@ out: * 1. We are not using a unified image * 2. We are using a unified image but had an error while exiting D3 */ - set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); + set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); /* * When switching images we return 1, which causes mac80211 -- cgit v1.2.3 From 6110d9e5bdd15c4e60fb67f330fbf74681e7daf7 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Tue, 29 Aug 2017 13:56:02 +0300 Subject: iwlwifi: mvm: Flush non STA TX queues When starting wowlan mac80211 requests flush w/o vif and we ignore this request. As a result some packets stay stuck in the queue and it may end up with a queue hang. Allow the driver to flush queues even if station isn't specified. Signed-off-by: David Spinadel Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 15f2d826bb4b..64b0be73ea72 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3975,6 +3975,43 @@ out_unlock: return ret; } +static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop) +{ + if (drop) { + if (iwl_mvm_has_new_tx_api(mvm)) + /* TODO new tx api */ + WARN_ONCE(1, + "Need to implement flush TX queue\n"); + else + iwl_mvm_flush_tx_path(mvm, + iwl_mvm_flushable_queues(mvm) & queues, + 0); + } else { + if (iwl_mvm_has_new_tx_api(mvm)) { + struct ieee80211_sta *sta; + int i; + + mutex_lock(&mvm->mutex); + + for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { + sta = rcu_dereference_protected( + mvm->fw_id_to_mac_id[i], + lockdep_is_held(&mvm->mutex)); + if (IS_ERR_OR_NULL(sta)) + continue; + + iwl_mvm_wait_sta_queues_empty(mvm, + iwl_mvm_sta_from_mac80211(sta)); + } + + mutex_unlock(&mvm->mutex); + } else { + iwl_trans_wait_tx_queues_empty(mvm->trans, + queues); + } + } +} + static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop) { @@ -3985,7 +4022,12 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, int i; u32 msk = 0; - if (!vif || vif->type != NL80211_IFTYPE_STATION) + if (!vif) { + iwl_mvm_flush_no_vif(mvm, queues, drop); + return; + } + + if (vif->type != NL80211_IFTYPE_STATION) return; /* Make sure we're done with the deferred traffic before flushing */ -- cgit v1.2.3 From 0fe8bed6e37c259b85d123ef9667f972305c9d6b Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Thu, 31 Aug 2017 16:27:06 +0300 Subject: iwlwifi: mvm: send all non-bufferable frames on the probe queue AP interfaces now send all non-bufferable frames using the broadcast station. Thus allow them to use the probe queue and don't warn about it. Fixes: eb045e6e0389 ("iwlwifi: mvm: Avoid deferring non bufferable frames") Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 172b5e63d3fb..6f2e2af23219 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -564,8 +564,8 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: /* - * Handle legacy hostapd as well, where station will be added - * only just before sending the association response. + * Non-bufferable frames use the broadcast station, thus they + * use the probe queue. * Also take care of the case where we send a deauth to a * station that we don't have, or similarly an association * response (with non-success status) for a station we can't @@ -573,9 +573,9 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, * Also, disassociate frames might happen, particular with * reason 7 ("Class 3 frame received from nonassociated STA"). */ - if (ieee80211_is_probe_resp(fc) || ieee80211_is_auth(fc) || - ieee80211_is_deauth(fc) || ieee80211_is_assoc_resp(fc) || - ieee80211_is_disassoc(fc)) + if (ieee80211_is_mgmt(fc) && + (!ieee80211_is_bufferable_mmpdu(fc) || + ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc))) return mvm->probe_queue; if (info->hw_queue == info->control.vif->cab_queue) return mvmvif->cab_queue; -- cgit v1.2.3 From bd800e41a3de5c7e56b2fd27088bdaf5e228d227 Mon Sep 17 00:00:00 2001 From: Naftali Goldstein Date: Mon, 28 Aug 2017 11:51:05 +0300 Subject: iwlwifi: mvm: change state when queueing agg start work Add a new state to enum iwl_mvm_agg_state, which is used between queueing the work that starts tx aggregations and actually starting that work (changing to state IWL_AGG_STARTING). This solves a race where ieee80211_start_tx_ba_session is called a second time, before the work queued by the first run has a chance to change the agg_state. In this case the second call to ieee80211_start_tx_ba_session returns an error, and the fallback is to abort the ba session start. Fixes: 482e48440a0e ("iwlwifi: mvm: change open and close criteria of a BA session") Signed-off-by: Naftali Goldstein Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 3 ++- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 6 ++++-- drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index ba7bd049d3d4..0fe723ca844e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -661,7 +661,8 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, (lq_sta->tx_agg_tid_en & BIT(tid)) && (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) { IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid); - rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta); + if (rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta) == 0) + tid_data->state = IWL_AGG_QUEUED; } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 411a2055dc45..2dafe9bb4d8b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -2385,8 +2385,10 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) return -EINVAL; - if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) { - IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n", + if (mvmsta->tid_data[tid].state != IWL_AGG_QUEUED && + mvmsta->tid_data[tid].state != IWL_AGG_OFF) { + IWL_ERR(mvm, + "Start AGG when state is not IWL_AGG_QUEUED or IWL_AGG_OFF %d!\n", mvmsta->tid_data[tid].state); return -ENXIO; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index d13893806513..aedabe101cf0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -281,6 +281,7 @@ struct iwl_mvm_vif; * These states relate to a specific RA / TID. * * @IWL_AGG_OFF: aggregation is not used + * @IWL_AGG_QUEUED: aggregation start work has been queued * @IWL_AGG_STARTING: aggregation are starting (between start and oper) * @IWL_AGG_ON: aggregation session is up * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the @@ -290,6 +291,7 @@ struct iwl_mvm_vif; */ enum iwl_mvm_agg_state { IWL_AGG_OFF = 0, + IWL_AGG_QUEUED, IWL_AGG_STARTING, IWL_AGG_ON, IWL_EMPTYING_HW_QUEUE_ADDBA, -- cgit v1.2.3 From 8458e48ac7ad86a5ab7f3d1a8cacd9205a9a97ce Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Sun, 3 Sep 2017 16:04:38 +0300 Subject: iwlwifi: mvm: wake the correct mac80211 queue iwl_mvm_start_mac_queues() takes a bitmap of the queues to wake. When deferred tx is purged, set the bit of the hw_queue so the correct queue will be waken up. Fixes: 7e39a00d5931 ("iwlwifi: mvm: start mac queues when deferred tx frames are purged") Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 64b0be73ea72..3a6ce4222ff5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2563,7 +2563,7 @@ static void iwl_mvm_purge_deferred_tx_frames(struct iwl_mvm *mvm, * queues, so we should never get a second deferred * frame for the RA/TID. */ - iwl_mvm_start_mac_queues(mvm, info->hw_queue); + iwl_mvm_start_mac_queues(mvm, BIT(info->hw_queue)); ieee80211_free_txskb(mvm->hw, skb); } } -- cgit v1.2.3 From 97bce57bd7f96e1218751996f549a6e61f18cc8c Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 1 Sep 2017 17:59:15 +0300 Subject: iwlwifi: mvm: use IWL_HCMD_NOCOPY for MCAST_FILTER_CMD The MCAST_FILTER_CMD can get quite large when we have many mcast addresses to set (we support up to 255). So the command should be send as NOCOPY to prevent a warning caused by too-long commands: WARNING: CPU: 0 PID: 9700 at /root/iwlwifi/stack-dev/drivers/net/wireless/intel/iwlwifi/pcie/tx.c:1550 iwl_pcie_enqueue_hcmd+0x8c7/0xb40 [iwlwifi] Command MCAST_FILTER_CMD (0x1d0) is too large (328 bytes) This fixes: https://bugzilla.kernel.org/show_bug.cgi?id=196743 Cc: stable@vger.kernel.org Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3a6ce4222ff5..635db63f972e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1546,6 +1546,11 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, struct iwl_mvm_mc_iter_data *data = _data; struct iwl_mvm *mvm = data->mvm; struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd; + struct iwl_host_cmd hcmd = { + .id = MCAST_FILTER_CMD, + .flags = CMD_ASYNC, + .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + }; int ret, len; /* if we don't have free ports, mcast frames will be dropped */ @@ -1560,7 +1565,10 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); - ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd); + hcmd.len[0] = len; + hcmd.data[0] = cmd; + + ret = iwl_mvm_send_cmd(mvm, &hcmd); if (ret) IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); } -- cgit v1.2.3 From 61e7d91bcf7725b9fcd9cbfc5fa0e0f84f19e6de Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 1 Sep 2017 18:57:35 +0300 Subject: iwlwifi: mvm: handle FIF_ALLMULTI when setting multicast addresses We were ignoring the FIF_ALLMULTI flag when setting the multicast addresses with MCAST_FILTER_CMD. Check if this flag is set and enable pass_all accordingly. We also need to set the count to 0 if pass_all is enable so we don't pass addresses to the firmware when not needed (as doing so causes an assert). This fixes https://bugzilla.kernel.org/show_bug.cgi?id=196741 Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 635db63f972e..3bcaa82f59b2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1643,6 +1643,12 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, if (!cmd) goto out; + if (changed_flags & FIF_ALLMULTI) + cmd->pass_all = !!(*total_flags & FIF_ALLMULTI); + + if (cmd->pass_all) + cmd->count = 0; + iwl_mvm_recalc_multicast(mvm); out: mutex_unlock(&mvm->mutex); -- cgit v1.2.3 From 3f497de997c7ed34ad8a90b64f1ca53a41d428b4 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sat, 2 Sep 2017 11:05:22 +0300 Subject: iwlwifi: mvm: initialize status in iwl_mvm_add_int_sta_common() We always need to initialize the status argument to the success case before calling iwl_mvm_send_cmd_status() or iwl_mvm_send_cmd_pdu_status() (which calls the former) otherwise we may get an uninitialized value back. In this case, we use ADD_STA_SUCCESS as success. Fixes: 732d06e9d9cf ("iwlwifi: mvm: add station before allocating a queue") Reported by: Dan Carpenter Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 2dafe9bb4d8b..c4a343534c5e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1285,7 +1285,7 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm, { struct iwl_mvm_add_sta_cmd cmd; int ret; - u32 status; + u32 status = ADD_STA_SUCCESS; lockdep_assert_held(&mvm->mutex); -- cgit v1.2.3 From d460f1fb83a44833a09c8eaa34b30ce553cab8c5 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sat, 2 Sep 2017 11:25:40 +0300 Subject: iwlwifi: mvm: set status before calling iwl_mvm_send_cmd_status() We always must set the status to what we consider success before calling iwl_mvm_send_cmd_status() (also iwl_mvm_send_cmd_pdu_status() which calls it). Fix a few places where initialization is missing. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 50983615dce6..774122fed454 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -555,7 +555,7 @@ static int iwl_mvm_lmac_scan_abort(struct iwl_mvm *mvm) struct iwl_host_cmd cmd = { .id = SCAN_OFFLOAD_ABORT_CMD, }; - u32 status; + u32 status = CAN_ABORT_STATUS; ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); if (ret) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index 8876c2abc440..4d907f60bce9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -529,6 +529,7 @@ int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state) lockdep_assert_held(&mvm->mutex); + status = 0; ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP, CTDP_CONFIG_CMD), sizeof(cmd), &cmd, &status); -- cgit v1.2.3 From 5f90472c00ddf1e64c2865f71cced297bd5f80a2 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Mon, 4 Sep 2017 20:27:04 +0300 Subject: iwlwifi: mvm: fix reorder buffer for 9000 devices The condition to check if reorder buffer ran out of space is faulty, as it takes into account only the NSSN. In case the head SN was too far behind the reorder buffer should move forward, regardless of the NSSN status. This caused the driver to release packets out of order in some scenarios. Fixes: b915c10174fb ("iwlwifi: mvm: add reorder buffer per queue") Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 67ffd9774712..77f77bc5d083 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -672,11 +672,12 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, * If there was a significant jump in the nssn - adjust. * If the SN is smaller than the NSSN it might need to first go into * the reorder buffer, in which case we just release up to it and the - * rest of the function will take of storing it and releasing up to the - * nssn + * rest of the function will take care of storing it and releasing up to + * the nssn */ if (!iwl_mvm_is_sn_less(nssn, buffer->head_sn + buffer->buf_size, - buffer->buf_size)) { + buffer->buf_size) || + !ieee80211_sn_less(sn, buffer->head_sn + buffer->buf_size)) { u16 min_sn = ieee80211_sn_less(sn, nssn) ? sn : nssn; iwl_mvm_release_frames(mvm, sta, napi, buffer, min_sn); -- cgit v1.2.3 From cac72b990d34f4c70208998a86f910ba38253c94 Mon Sep 17 00:00:00 2001 From: Lyude Date: Sat, 22 Jul 2017 21:15:09 -0400 Subject: HID: rmi: Make sure the HID device is opened on resume So it looks like that suspend/resume has actually always been broken on hid-rmi. The fact it worked was a rather silly coincidence that was relying on the HID device to already be opened upon resume. This means that so long as anything was reading the /dev/input/eventX node for for an RMI device, it would suspend and resume correctly. As well, if nothing happened to be keeping the HID device away it would shut off, then the RMI driver would get confused on resume when it stopped responding and explode. So, call hid_hw_open() in rmi_post_resume() so we make sure that the device is alive before we try talking to it. This fixes RMI device suspend/resume over HID. Link: https://bugzilla.kernel.org/show_bug.cgi?id=196851 [jkosina@suse.cz: removed useless hunk that was zero-initializing 'ret'] Signed-off-by: Lyude Cc: Andrew Duggan Cc: stable@vger.kernel.org Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-rmi.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 5b40c2614599..ef241d66562e 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c @@ -436,17 +436,24 @@ static int rmi_post_resume(struct hid_device *hdev) if (!(data->device_flags & RMI_DEVICE)) return 0; - ret = rmi_reset_attn_mode(hdev); + /* Make sure the HID device is ready to receive events */ + ret = hid_hw_open(hdev); if (ret) return ret; + ret = rmi_reset_attn_mode(hdev); + if (ret) + goto out; + ret = rmi_driver_resume(rmi_dev, false); if (ret) { hid_warn(hdev, "Failed to resume device: %d\n", ret); - return ret; + goto out; } - return 0; +out: + hid_hw_close(hdev); + return ret; } #endif /* CONFIG_PM */ -- cgit v1.2.3 From a2d3d2655ea6d09edfcc6d9b11fb58729c8d5b95 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Wed, 30 Aug 2017 11:01:15 -0700 Subject: drm/i915: Add a default case in gen7 hwsp switch-case Gen7 won't get any new engines, and we already added VCS2 there to just silence gcc's not handled in switch warnings. Use a default case instead, otherwise we will need to keep adding extra cases if changes happen in the future. v2: Since reaching the default case is impossible, use GEM_BUG_ON (Chris). Cc: Chris Wilson Signed-off-by: Michel Thierry Link: https://patchwork.freedesktop.org/patch/msgid/20170830180115.907-1-michel.thierry@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index cdf084ef5aae..268342433a8e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -402,17 +402,18 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *engine) */ if (IS_GEN7(dev_priv)) { switch (engine->id) { + /* + * No more rings exist on Gen7. Default case is only to shut up + * gcc switch check warning. + */ + default: + GEM_BUG_ON(engine->id); case RCS: mmio = RENDER_HWS_PGA_GEN7; break; case BCS: mmio = BLT_HWS_PGA_GEN7; break; - /* - * VCS2 actually doesn't exist on Gen7. Only shut up - * gcc switch check warning - */ - case VCS2: case VCS: mmio = BSD_HWS_PGA_GEN7; break; -- cgit v1.2.3 From 1790625b1deaafb564def63a3a070602656134a1 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 8 Sep 2017 16:11:30 +0000 Subject: drm/i915: Make PAT macros more robust Macro params shall be wrapped into () to avoid unexpected results. Signed-off-by: Michal Wajdeczko Cc: Rodrigo Vivi Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170908161130.22424-1-michal.wajdeczko@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 +- drivers/gpu/drm/i915/i915_reg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index b4e3aa7c0ce1..d9a076a2673a 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -132,7 +132,7 @@ typedef u64 gen8_ppgtt_pml4e_t; #define PPAT_DISPLAY_ELLC_INDEX _PAGE_PCD /* WT eLLC */ #define CHV_PPAT_SNOOP (1<<6) -#define GEN8_PPAT_AGE(x) (x<<4) +#define GEN8_PPAT_AGE(x) ((x)<<4) #define GEN8_PPAT_LLCeLLC (3<<2) #define GEN8_PPAT_LLCELLC (2<<2) #define GEN8_PPAT_LLC (1<<2) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9a73ea0a3293..0b03260a3967 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2336,7 +2336,7 @@ enum i915_power_well_id { #define DONE_REG _MMIO(0x40b0) #define GEN8_PRIVATE_PAT_LO _MMIO(0x40e0) #define GEN8_PRIVATE_PAT_HI _MMIO(0x40e0 + 4) -#define GEN10_PAT_INDEX(index) _MMIO(0x40e0 + index*4) +#define GEN10_PAT_INDEX(index) _MMIO(0x40e0 + (index)*4) #define BSD_HWS_PGA_GEN7 _MMIO(0x04180) #define BLT_HWS_PGA_GEN7 _MMIO(0x04280) #define VEBOX_HWS_PGA_GEN7 _MMIO(0x04380) -- cgit v1.2.3 From 14826673247eaf36b16fd821fac27efa663f3fa6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Sep 2017 19:16:22 +0100 Subject: drm/i915: Only initialize partially filled pagetables If we know that we will completely fill a pagetable (i.e. we are inserting a complete set of 512 pages), we can skip prefilling that PT with scratch entries. If we have to abort the insertion prior to writing the real entries, we will teardown the pagetable and remove it from the page directory (so that we will restart the allocation next time). We could do similar tricks for the PD and PDP, but the likelihood of a single insertion covering the entire 512 entries diminishes, as do the cycle savings. The saving are even greater (relatively) when we are preallocating page tables for huge pages, as then we never need to fill the page table. Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170908181622.17791-1-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/i915_gem_gtt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index c33c2f97c814..33181d6eac3f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1168,19 +1168,22 @@ static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm, unsigned int pde; gen8_for_each_pde(pt, pd, start, length, pde) { + int count = gen8_pte_count(start, length); + if (pt == vm->scratch_pt) { pt = alloc_pt(vm); if (IS_ERR(pt)) goto unwind; - gen8_initialize_pt(vm, pt); + if (count < GEN8_PTES) + gen8_initialize_pt(vm, pt); gen8_ppgtt_set_pde(vm, pd, pt, pde); pd->used_pdes++; GEM_BUG_ON(pd->used_pdes > I915_PDES); } - pt->used_ptes += gen8_pte_count(start, length); + pt->used_ptes += count; } return 0; -- cgit v1.2.3 From 37875d6b3af702425ce292de81b77faf94766616 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 10 Sep 2017 10:56:42 +0200 Subject: drm/i915: Fix an error handling in 'intel_framebuffer_init()' We should go through the error handling path to decrease the 'framebuffer_references' as done everywhere else in this function. Fixes: 2e2adb05736c ("drm/i915: Add render decompression support") Signed-off-by: Christophe JAILLET Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170910085642.13673-1-christophe.jaillet@wanadoo.fr --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 844efd45fed3..dbe7d8682c97 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14105,7 +14105,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, if (mode_cmd->handles[i] != mode_cmd->handles[0]) { DRM_DEBUG_KMS("bad plane %d handle\n", i); - return -EINVAL; + goto err; } stride_alignment = intel_fb_stride_alignment(fb, i); -- cgit v1.2.3 From 0f328da611953d078e86ea250eaeeb840dd7f5d0 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:31 -0700 Subject: drm/i915/psr: Avoid any PSR stuff on platforms without support. We really don't want to setup vfuncs and lock mutexes on platforms that has no support to PSR. Also we know what platforms they are so let's do it quietly. Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-2-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index f62ab05d3d62..60a1ece6d4c9 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -496,10 +496,8 @@ void intel_psr_enable(struct intel_dp *intel_dp, enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 chicken; - if (!HAS_PSR(dev_priv)) { - DRM_DEBUG_KMS("PSR not supported on this platform\n"); + if (!HAS_PSR(dev_priv)) return; - } if (!is_edp_psr(intel_dp)) { DRM_DEBUG_KMS("PSR not supported by this panel\n"); @@ -678,6 +676,9 @@ void intel_psr_disable(struct intel_dp *intel_dp, struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); + if (!HAS_PSR(dev_priv)) + return; + mutex_lock(&dev_priv->psr.lock); if (!dev_priv->psr.enabled) { mutex_unlock(&dev_priv->psr.lock); @@ -829,6 +830,9 @@ void intel_psr_single_frame_update(struct drm_i915_private *dev_priv, enum pipe pipe; u32 val; + if (!HAS_PSR(dev_priv)) + return; + /* * Single frame update is already supported on BDW+ but it requires * many W/A and it isn't really needed. @@ -875,6 +879,9 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv, struct drm_crtc *crtc; enum pipe pipe; + if (!HAS_PSR(dev_priv)) + return; + mutex_lock(&dev_priv->psr.lock); if (!dev_priv->psr.enabled) { mutex_unlock(&dev_priv->psr.lock); @@ -912,6 +919,9 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, struct drm_crtc *crtc; enum pipe pipe; + if (!HAS_PSR(dev_priv)) + return; + mutex_lock(&dev_priv->psr.lock); if (!dev_priv->psr.enabled) { mutex_unlock(&dev_priv->psr.lock); @@ -944,6 +954,9 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, */ void intel_psr_init(struct drm_i915_private *dev_priv) { + if (!HAS_PSR(dev_priv)) + return; + dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ? HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE; -- cgit v1.2.3 From 424644c2504299e00b450328be9e3c5a12e9c9f9 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:32 -0700 Subject: drm/i915/psr: vfunc for disabling source. VLV/CHV has a total different PSR implementation than the other platforms, so let's start moving that to vfuncs. Let's start with disable_src one. v2: Rebased on top of commit d2419ffc10e4 ("drm/i915: Plumb crtc_state to PSR enable/disable") Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-3-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/intel_psr.c | 12 +++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 63ca2ffcafef..d24793cdf949 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1180,6 +1180,9 @@ struct i915_psr { bool y_cord_support; bool colorimetry_support; bool alpm; + + void (*disable_source)(struct intel_dp *, + const struct intel_crtc_state *); }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 60a1ece6d4c9..1d2b52e6a6d4 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -685,11 +685,7 @@ void intel_psr_disable(struct intel_dp *intel_dp, return; } - /* Disable PSR on Source */ - if (HAS_DDI(dev_priv)) - hsw_psr_disable(intel_dp, old_crtc_state); - else - vlv_psr_disable(intel_dp, old_crtc_state); + dev_priv->psr.disable_source(intel_dp, old_crtc_state); /* Disable PSR on Sink */ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0); @@ -987,4 +983,10 @@ void intel_psr_init(struct drm_i915_private *dev_priv) INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work); mutex_init(&dev_priv->psr.lock); + + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + dev_priv->psr.disable_source = vlv_psr_disable; + } else { + dev_priv->psr.disable_source = hsw_psr_disable; + } } -- cgit v1.2.3 From ed63d24b4d19aee649fbec28b7c11e887eff6861 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:33 -0700 Subject: drm/i915/psr: hsw_psr_activate. On HSW+ the real activate of PSR is decided by the source after certain amount of configured idle frames. However for the driver perspective where we track psr.active variable this function here is the actual activate one. So let's rename it before moving to vfunc with that. v2: Fix typo on commit message (DK). Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-4-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 1d2b52e6a6d4..92b3db3aa830 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -263,7 +263,7 @@ static void vlv_psr_activate(struct intel_dp *intel_dp) VLV_EDP_PSR_ACTIVE_ENTRY); } -static void intel_enable_source_psr1(struct intel_dp *intel_dp) +static void hsw_activate_psr1(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; @@ -317,7 +317,7 @@ static void intel_enable_source_psr1(struct intel_dp *intel_dp) I915_WRITE(EDP_PSR_CTL, val); } -static void intel_enable_source_psr2(struct intel_dp *intel_dp) +static void hsw_activate_psr2(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; @@ -353,17 +353,22 @@ static void intel_enable_source_psr2(struct intel_dp *intel_dp) I915_WRITE(EDP_PSR2_CTL, val); } -static void hsw_psr_enable_source(struct intel_dp *intel_dp) +static void hsw_psr_activate(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); + /* On HSW+ after we enable PSR on source it will activate it + * as soon as it match configure idle_frame count. So + * we just actually enable it here on activation time. + */ + /* psr1 and psr2 are mutually exclusive.*/ if (dev_priv->psr.psr2_support) - intel_enable_source_psr2(intel_dp); + hsw_activate_psr2(intel_dp); else - intel_enable_source_psr1(intel_dp); + hsw_activate_psr1(intel_dp); } static bool intel_psr_match_conditions(struct intel_dp *intel_dp) @@ -469,11 +474,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp) /* Enable/Re-enable PSR on the host */ if (HAS_DDI(dev_priv)) - /* On HSW+ after we enable PSR on source it will activate it - * as soon as it match configure idle_frame count. So - * we just actually enable it here on activation time. - */ - hsw_psr_enable_source(intel_dp); + hsw_psr_activate(intel_dp); else vlv_psr_activate(intel_dp); -- cgit v1.2.3 From e3702ac9a2c128690b2219eb1282367584a3b7bb Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:34 -0700 Subject: drm/i915/psr: Add activate vfunc. Continue on VLV PSR split with vfunc, let's move activate function there. Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-5-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_psr.c | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d24793cdf949..fa279f3cc838 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1183,6 +1183,7 @@ struct i915_psr { void (*disable_source)(struct intel_dp *, const struct intel_crtc_state *); + void (*activate)(struct intel_dp *); }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 92b3db3aa830..b3c1e601a8b2 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -472,12 +472,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp) WARN_ON(dev_priv->psr.active); lockdep_assert_held(&dev_priv->psr.lock); - /* Enable/Re-enable PSR on the host */ - if (HAS_DDI(dev_priv)) - hsw_psr_activate(intel_dp); - else - vlv_psr_activate(intel_dp); - + dev_priv->psr.activate(intel_dp); dev_priv->psr.active = true; } @@ -987,7 +982,9 @@ void intel_psr_init(struct drm_i915_private *dev_priv) if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { dev_priv->psr.disable_source = vlv_psr_disable; + dev_priv->psr.activate = vlv_psr_activate; } else { dev_priv->psr.disable_source = hsw_psr_disable; + dev_priv->psr.activate = hsw_psr_activate; } } -- cgit v1.2.3 From 2ce4df87f133913dff26ae0f578d6b46f01fa6d3 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:35 -0700 Subject: drm/i915/psr: Unify VSC setup functions. VSC package is decided per eDP spec for psr1 or psr2, and not per platform, so let's unify it and kill "skl" func. v2: Rebased on top of commit d2419ffc10e4 ("drm/i915: Plumb crtc_state to PSR enable/disable") Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-6-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 61 ++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index b3c1e601a8b2..eca6170becdc 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -117,46 +117,41 @@ static void vlv_psr_setup_vsc(struct intel_dp *intel_dp, I915_WRITE(VLV_VSCSDP(crtc->pipe), val); } -static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +static void hsw_psr_setup_vsc(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); struct edp_vsc_psr psr_vsc; - /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ - memset(&psr_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - if (dev_priv->psr.colorimetry_support && - dev_priv->psr.y_cord_support) { - psr_vsc.sdp_header.HB2 = 0x5; - psr_vsc.sdp_header.HB3 = 0x13; - } else if (dev_priv->psr.y_cord_support) { - psr_vsc.sdp_header.HB2 = 0x4; - psr_vsc.sdp_header.HB3 = 0xe; + if (dev_priv->psr.psr2_support) { + /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + if (dev_priv->psr.colorimetry_support && + dev_priv->psr.y_cord_support) { + psr_vsc.sdp_header.HB2 = 0x5; + psr_vsc.sdp_header.HB3 = 0x13; + } else if (dev_priv->psr.y_cord_support) { + psr_vsc.sdp_header.HB2 = 0x4; + psr_vsc.sdp_header.HB3 = 0xe; + } else { + psr_vsc.sdp_header.HB2 = 0x3; + psr_vsc.sdp_header.HB3 = 0xc; + } } else { - psr_vsc.sdp_header.HB2 = 0x3; - psr_vsc.sdp_header.HB3 = 0xc; + /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; } intel_psr_write_vsc(intel_dp, &psr_vsc); } -static void hsw_psr_setup_vsc(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - struct edp_vsc_psr psr_vsc; - - /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ - memset(&psr_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - intel_psr_write_vsc(intel_dp, &psr_vsc); -} - static void vlv_psr_enable_sink(struct intel_dp *intel_dp) { drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, @@ -512,9 +507,10 @@ void intel_psr_enable(struct intel_dp *intel_dp, dev_priv->psr.busy_frontbuffer_bits = 0; if (HAS_DDI(dev_priv)) { - if (dev_priv->psr.psr2_support) { - skl_psr_setup_su_vsc(intel_dp, crtc_state); + hsw_psr_setup_vsc(intel_dp, crtc_state); + + if (dev_priv->psr.psr2_support) { chicken = PSR2_VSC_ENABLE_PROG_HEADER; if (dev_priv->psr.y_cord_support) chicken |= PSR2_ADD_VERTICAL_LINE_COUNT; @@ -527,9 +523,6 @@ void intel_psr_enable(struct intel_dp *intel_dp, EDP_PSR_DEBUG_MASK_MAX_SLEEP | EDP_PSR_DEBUG_MASK_DISP_REG_WRITE); } else { - /* set up vsc header for psr1 */ - hsw_psr_setup_vsc(intel_dp, crtc_state); - /* * Per Spec: Avoid continuous PSR exit by masking MEMUP * and HPD. also mask LPSP to avoid dependency on other -- cgit v1.2.3 From 4d1fa22f4372f27ebbf2376de79a665d23623c8c Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:36 -0700 Subject: drm/i915/psr: Re-create a hsw_psr_enable_source. This sequence is part of enable source anyways, but they only need to be executed once and not on every activation, So let's re-create hsw_enable_source. v2: Avoid changing order here to avoid changing behaviour as suggested by Jani. v3: Rebased on top of commit d2419ffc10e4 ("drm/i915: Plumb crtc_state to PSR enable/disable") Cc: Jani Nikula Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-7-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 70 +++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index eca6170becdc..575c8b93e96f 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -471,6 +471,42 @@ static void intel_psr_activate(struct intel_dp *intel_dp) dev_priv->psr.active = true; } +static void hsw_psr_enable_source(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 chicken; + + if (dev_priv->psr.psr2_support) { + chicken = PSR2_VSC_ENABLE_PROG_HEADER; + if (dev_priv->psr.y_cord_support) + chicken |= PSR2_ADD_VERTICAL_LINE_COUNT; + I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken); + + I915_WRITE(EDP_PSR_DEBUG_CTL, + EDP_PSR_DEBUG_MASK_MEMUP | + EDP_PSR_DEBUG_MASK_HPD | + EDP_PSR_DEBUG_MASK_LPSP | + EDP_PSR_DEBUG_MASK_MAX_SLEEP | + EDP_PSR_DEBUG_MASK_DISP_REG_WRITE); + } else { + /* + * Per Spec: Avoid continuous PSR exit by masking MEMUP + * and HPD. also mask LPSP to avoid dependency on other + * drivers that might block runtime_pm besides + * preventing other hw tracking issues now we can rely + * on frontbuffer tracking. + */ + I915_WRITE(EDP_PSR_DEBUG_CTL, + EDP_PSR_DEBUG_MASK_MEMUP | + EDP_PSR_DEBUG_MASK_HPD | + EDP_PSR_DEBUG_MASK_LPSP); + } +} + /** * intel_psr_enable - Enable PSR * @intel_dp: Intel DP @@ -484,8 +520,6 @@ void intel_psr_enable(struct intel_dp *intel_dp, struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - u32 chicken; if (!HAS_PSR(dev_priv)) return; @@ -510,31 +544,7 @@ void intel_psr_enable(struct intel_dp *intel_dp, hsw_psr_setup_vsc(intel_dp, crtc_state); - if (dev_priv->psr.psr2_support) { - chicken = PSR2_VSC_ENABLE_PROG_HEADER; - if (dev_priv->psr.y_cord_support) - chicken |= PSR2_ADD_VERTICAL_LINE_COUNT; - I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken); - - I915_WRITE(EDP_PSR_DEBUG_CTL, - EDP_PSR_DEBUG_MASK_MEMUP | - EDP_PSR_DEBUG_MASK_HPD | - EDP_PSR_DEBUG_MASK_LPSP | - EDP_PSR_DEBUG_MASK_MAX_SLEEP | - EDP_PSR_DEBUG_MASK_DISP_REG_WRITE); - } else { - /* - * Per Spec: Avoid continuous PSR exit by masking MEMUP - * and HPD. also mask LPSP to avoid dependency on other - * drivers that might block runtime_pm besides - * preventing other hw tracking issues now we can rely - * on frontbuffer tracking. - */ - I915_WRITE(EDP_PSR_DEBUG_CTL, - EDP_PSR_DEBUG_MASK_MEMUP | - EDP_PSR_DEBUG_MASK_HPD | - EDP_PSR_DEBUG_MASK_LPSP); - } + hsw_psr_enable_source(intel_dp, crtc_state); /* Enable PSR on the panel */ hsw_psr_enable_sink(intel_dp); @@ -547,12 +557,6 @@ void intel_psr_enable(struct intel_dp *intel_dp, /* Enable PSR on the panel */ vlv_psr_enable_sink(intel_dp); - /* On HSW+ enable_source also means go to PSR entry/active - * state as soon as idle_frame achieved and here would be - * to soon. However on VLV enable_source just enable PSR - * but let it on inactive state. So we might do this prior - * to active transition, i.e. here. - */ vlv_psr_enable_source(intel_dp, crtc_state); } -- cgit v1.2.3 From 196cebddde80dd06b2de557ea393082bf5a06c3d Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:37 -0700 Subject: drm/i915/psr: Move hsw_enable_source after enabling sink. No functional change is expected here since at this point PSR is not allowed to go to any active state. In other words, not really enabled. However let's do in a separated patch so it gets clear on what is change and specially it can helps on bisect case if we figure something has caused changes in behaviour. But this needs to be done before we make the vfunc to enable source to be in parity with VLV implementation. Cc: Jani Nikula Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-8-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 575c8b93e96f..245cf3ee979f 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -544,11 +544,11 @@ void intel_psr_enable(struct intel_dp *intel_dp, hsw_psr_setup_vsc(intel_dp, crtc_state); - hsw_psr_enable_source(intel_dp, crtc_state); - /* Enable PSR on the panel */ hsw_psr_enable_sink(intel_dp); + hsw_psr_enable_source(intel_dp, crtc_state); + if (INTEL_GEN(dev_priv) >= 9) intel_psr_activate(intel_dp); } else { -- cgit v1.2.3 From 29d1efe070d3cb5c52d51d82af71790ffaf0a64f Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:38 -0700 Subject: drm/i915/psr: Re-org Activate after enable Let's move the activation calls together after enable is done. No real functional change should be expected here. Just an attempt to get it clear when we are really activating PSR after enabling it. v2: Add braces on if/else because commit message there is too long as suggested by Jani. v3: Rebased on top of commit d2419ffc10e4 ("drm/i915: Plumb crtc_state to PSR enable/disable") Cc: Jani Nikula Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-9-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 245cf3ee979f..7031dfd50ae9 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -549,8 +549,6 @@ void intel_psr_enable(struct intel_dp *intel_dp, hsw_psr_enable_source(intel_dp, crtc_state); - if (INTEL_GEN(dev_priv) >= 9) - intel_psr_activate(intel_dp); } else { vlv_psr_setup_vsc(intel_dp, crtc_state); @@ -560,20 +558,25 @@ void intel_psr_enable(struct intel_dp *intel_dp, vlv_psr_enable_source(intel_dp, crtc_state); } - /* - * FIXME: Activation should happen immediately since this function - * is just called after pipe is fully trained and enabled. - * However on every platform we face issues when first activation - * follows a modeset so quickly. - * - On VLV/CHV we get bank screen on first activation - * - On HSW/BDW we get a recoverable frozen screen until next - * exit-activate sequence. - */ - if (INTEL_GEN(dev_priv) < 9) + dev_priv->psr.enabled = intel_dp; + + if (INTEL_GEN(dev_priv) >= 9) { + intel_psr_activate(intel_dp); + } else { + /* + * FIXME: Activation should happen immediately since this + * function is just called after pipe is fully trained and + * enabled. + * However on some platforms we face issues when first + * activation follows a modeset so quickly. + * - On VLV/CHV we get bank screen on first activation + * - On HSW/BDW we get a recoverable frozen screen until + * next exit-activate sequence. + */ schedule_delayed_work(&dev_priv->psr.work, msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5)); + } - dev_priv->psr.enabled = intel_dp; unlock: mutex_unlock(&dev_priv->psr.lock); } -- cgit v1.2.3 From 2a5db87f82cb6b2763d5e07cc4eef8cd94e56395 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:39 -0700 Subject: drm/i915/psr: Add setup VSC vfunc. Continue on VLV PSR split with vfunc, let's also create one for setting up VSC. v2: Rebased on top of commit d2419ffc10e4 ("drm/i915: Plumb crtc_state to PSR enable/disable") Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-10-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_psr.c | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fa279f3cc838..54786bc73263 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1184,6 +1184,7 @@ struct i915_psr { void (*disable_source)(struct intel_dp *, const struct intel_crtc_state *); void (*activate)(struct intel_dp *); + void (*setup_vsc)(struct intel_dp *, const struct intel_crtc_state *); }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 7031dfd50ae9..2516d2a50022 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -540,18 +540,15 @@ void intel_psr_enable(struct intel_dp *intel_dp, dev_priv->psr.busy_frontbuffer_bits = 0; - if (HAS_DDI(dev_priv)) { - - hsw_psr_setup_vsc(intel_dp, crtc_state); + dev_priv->psr.setup_vsc(intel_dp, crtc_state); + if (HAS_DDI(dev_priv)) { /* Enable PSR on the panel */ hsw_psr_enable_sink(intel_dp); hsw_psr_enable_source(intel_dp, crtc_state); } else { - vlv_psr_setup_vsc(intel_dp, crtc_state); - /* Enable PSR on the panel */ vlv_psr_enable_sink(intel_dp); @@ -983,8 +980,10 @@ void intel_psr_init(struct drm_i915_private *dev_priv) if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { dev_priv->psr.disable_source = vlv_psr_disable; dev_priv->psr.activate = vlv_psr_activate; + dev_priv->psr.setup_vsc = vlv_psr_setup_vsc; } else { dev_priv->psr.disable_source = hsw_psr_disable; dev_priv->psr.activate = hsw_psr_activate; + dev_priv->psr.setup_vsc = hsw_psr_setup_vsc; } } -- cgit v1.2.3 From 49ad316f87f17b8eaf6985c7baac7bc069dccddc Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:40 -0700 Subject: drm/i915/psr: Add enable_sink vfunc. Continue on VLV PSR split with vfunc, let's also create one for enabling sink. v2: Fix typo on commit message (DK). Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-11-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_psr.c | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54786bc73263..4efc2b591f6f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1183,6 +1183,7 @@ struct i915_psr { void (*disable_source)(struct intel_dp *, const struct intel_crtc_state *); + void (*enable_sink)(struct intel_dp *); void (*activate)(struct intel_dp *); void (*setup_vsc)(struct intel_dp *, const struct intel_crtc_state *); }; diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 2516d2a50022..02c32cc38648 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -541,17 +541,12 @@ void intel_psr_enable(struct intel_dp *intel_dp, dev_priv->psr.busy_frontbuffer_bits = 0; dev_priv->psr.setup_vsc(intel_dp, crtc_state); + dev_priv->psr.enable_sink(intel_dp); if (HAS_DDI(dev_priv)) { - /* Enable PSR on the panel */ - hsw_psr_enable_sink(intel_dp); - hsw_psr_enable_source(intel_dp, crtc_state); } else { - /* Enable PSR on the panel */ - vlv_psr_enable_sink(intel_dp); - vlv_psr_enable_source(intel_dp, crtc_state); } @@ -979,10 +974,12 @@ void intel_psr_init(struct drm_i915_private *dev_priv) if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { dev_priv->psr.disable_source = vlv_psr_disable; + dev_priv->psr.enable_sink = vlv_psr_enable_sink; dev_priv->psr.activate = vlv_psr_activate; dev_priv->psr.setup_vsc = vlv_psr_setup_vsc; } else { dev_priv->psr.disable_source = hsw_psr_disable; + dev_priv->psr.enable_sink = hsw_psr_enable_sink; dev_priv->psr.activate = hsw_psr_activate; dev_priv->psr.setup_vsc = hsw_psr_setup_vsc; } -- cgit v1.2.3 From d0d5e0d7b11359ccdc7276339ec29d98f4739453 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:00:41 -0700 Subject: drm/i915/psr: Add enable_source vfunc. Continue on VLV PSR split with vfunc, let's also create one for enabling source. Also since we are touching *_enable_source functions let's fix a comment with wrong name for vlv's one. v2: Fix typo on commit message (DK). Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Cc: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230041.22978-12-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_psr.c | 14 ++++---------- 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4efc2b591f6f..ec70121410e4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1181,6 +1181,8 @@ struct i915_psr { bool colorimetry_support; bool alpm; + void (*enable_source)(struct intel_dp *, + const struct intel_crtc_state *); void (*disable_source)(struct intel_dp *, const struct intel_crtc_state *); void (*enable_sink)(struct intel_dp *); diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 02c32cc38648..fdd9e3d95efb 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -542,14 +542,7 @@ void intel_psr_enable(struct intel_dp *intel_dp, dev_priv->psr.setup_vsc(intel_dp, crtc_state); dev_priv->psr.enable_sink(intel_dp); - - if (HAS_DDI(dev_priv)) { - hsw_psr_enable_source(intel_dp, crtc_state); - - } else { - vlv_psr_enable_source(intel_dp, crtc_state); - } - + dev_priv->psr.enable_source(intel_dp, crtc_state); dev_priv->psr.enabled = intel_dp; if (INTEL_GEN(dev_priv) >= 9) { @@ -777,8 +770,7 @@ static void intel_psr_exit(struct drm_i915_private *dev_priv) * directly once PSR State 4 that is active with single frame * update can be skipped. PSR_state 5 that is PSR exit then * Hardware is responsible to transition back to PSR_state 1 - * that is PSR inactive. Same state after - * vlv_edp_psr_enable_source. + * that is PSR inactive. Same state after vlv_psr_enable_source. */ val &= ~VLV_EDP_PSR_ACTIVE_ENTRY; I915_WRITE(VLV_PSRCTL(pipe), val); @@ -973,11 +965,13 @@ void intel_psr_init(struct drm_i915_private *dev_priv) mutex_init(&dev_priv->psr.lock); if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + dev_priv->psr.enable_source = vlv_psr_enable_source; dev_priv->psr.disable_source = vlv_psr_disable; dev_priv->psr.enable_sink = vlv_psr_enable_sink; dev_priv->psr.activate = vlv_psr_activate; dev_priv->psr.setup_vsc = vlv_psr_setup_vsc; } else { + dev_priv->psr.enable_source = hsw_psr_enable_source; dev_priv->psr.disable_source = hsw_psr_disable; dev_priv->psr.enable_sink = hsw_psr_enable_sink; dev_priv->psr.activate = hsw_psr_activate; -- cgit v1.2.3 From 3164888a40469c102b5d6d1b756c7646e7eb19e7 Mon Sep 17 00:00:00 2001 From: Marta Lofstedt Date: Fri, 8 Sep 2017 16:28:29 +0300 Subject: drm/i915: Increase poll time for BDW FCLK_DONE During IGT testing it has been shown that the specification defined polling time of 1 us for FCLK_DONE, is sometimes not enough. The issue is still reproducible while disabling C-states through the PM QoS framework and also while disabling preemtion. From this the most plausible explanation is that the issue is due to a firmware flaw. As a workaround, it is better to wait a little bit longer for the FCLK_DONE to come around, than to leave with an DRM_ERROR and having FCLK_DONE at a randome time after. While spinning a list of igt tests prone to reproduce the issue the FCLK_DONE poll failed at approximately 2% of the invocations of the bdw_set_cdclk function. The longest poll time during this testing was measured to ~7us. So, the suggested new poll time of 100us is on the safe side. v2: Added more documentation about investigations done. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102243 Signed-off-by: Marta Lofstedt Reviewed-by: Daniel Vetter Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20170908132829.6312-1-marta.lofstedt@intel.com --- drivers/gpu/drm/i915/intel_cdclk.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index d32911816fc2..87fc42b19336 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -669,8 +669,12 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, val |= LCPLL_CD_SOURCE_FCLK; I915_WRITE(LCPLL_CTL, val); + /* + * According to the spec, it should be enough to poll for this 1 us. + * However, extensive testing shows that this can take longer. + */ if (wait_for_us(I915_READ(LCPLL_CTL) & - LCPLL_CD_SOURCE_FCLK_DONE, 1)) + LCPLL_CD_SOURCE_FCLK_DONE, 100)) DRM_ERROR("Switching to FCLK failed\n"); val = I915_READ(LCPLL_CTL); -- cgit v1.2.3 From c3881128cb672cf484a52fbb36b5daa9044d9168 Mon Sep 17 00:00:00 2001 From: "Lee, Shawn C" Date: Tue, 12 Sep 2017 11:36:30 +0800 Subject: drm/i915/bxt: set min brightness from VBT Min brightness value from vbt was missing for BXT platform. This setting have to refer backlight ic spec to restrict min backlight output. Without this restriction, driver would allow to configure lower brightness value and violate backlight ic requirement. Fixes: 0fb890c01349 ("drm/i915/bxt: BLC implementation") Cc: Jani Nikula Cc: Cooper Chiou Cc: Gary C Wang Signed-off-by: Shawn Lee Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1505187390-7039-1-git-send-email-shawn.c.lee@intel.com --- drivers/gpu/drm/i915/intel_panel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index a17b1de7d7e0..d4dd248ac9a8 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1699,6 +1699,8 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) if (!panel->backlight.max) return -ENODEV; + panel->backlight.min = get_backlight_min_vbt(connector); + val = bxt_get_backlight(connector); val = intel_panel_compute_brightness(connector, val); panel->backlight.level = clamp(val, panel->backlight.min, -- cgit v1.2.3 From 36e16c49dbfec806754862f63136de552d4de4ba Mon Sep 17 00:00:00 2001 From: Zhi Wang Date: Tue, 12 Sep 2017 15:42:24 +0800 Subject: drm/i915: Factor out setup_private_pat() Factor out setup_private_pat() for introducing the following patches. Signed-off-by: Zhi Wang Cc: Ben Widawsky Cc: Rodrigo Vivi Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Reviewed-by: Ben Widawsky Link: https://patchwork.freedesktop.org/patch/msgid/1505202148-22959-1-git-send-email-zhi.a.wang@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_gtt.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 33181d6eac3f..09e524dbc090 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2918,6 +2918,16 @@ static void gen6_gmch_remove(struct i915_address_space *vm) cleanup_scratch_page(vm); } +static void setup_private_pat(struct drm_i915_private *dev_priv) +{ + if (INTEL_GEN(dev_priv) >= 10) + cnl_setup_private_ppat(dev_priv); + else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) + chv_setup_private_ppat(dev_priv); + else + bdw_setup_private_ppat(dev_priv); +} + static int gen8_gmch_probe(struct i915_ggtt *ggtt) { struct drm_i915_private *dev_priv = ggtt->base.i915; @@ -2950,14 +2960,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) } ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT; - - if (INTEL_GEN(dev_priv) >= 10) - cnl_setup_private_ppat(dev_priv); - else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) - chv_setup_private_ppat(dev_priv); - else - bdw_setup_private_ppat(dev_priv); - ggtt->base.cleanup = gen6_gmch_remove; ggtt->base.bind_vma = ggtt_bind_vma; ggtt->base.unbind_vma = ggtt_unbind_vma; @@ -2978,6 +2980,8 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) ggtt->invalidate = gen6_ggtt_invalidate; + setup_private_pat(dev_priv); + return ggtt_probe_common(ggtt, size); } -- cgit v1.2.3 From 3e8ddd9e5071841827ec32a7a5ff11eaac5ad3d0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 12 Sep 2017 18:34:10 +0300 Subject: drm/i915: Nuke some bogus tabs from the pcode defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170912153411.20171-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0b03260a3967..f9f9fcc833c5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7954,8 +7954,8 @@ enum { #define GEN7_PCODE_TIMEOUT 0x2 #define GEN7_PCODE_ILLEGAL_DATA 0x3 #define GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x10 -#define GEN6_PCODE_WRITE_RC6VIDS 0x4 -#define GEN6_PCODE_READ_RC6VIDS 0x5 +#define GEN6_PCODE_WRITE_RC6VIDS 0x4 +#define GEN6_PCODE_READ_RC6VIDS 0x5 #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) #define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245) #define BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ 0x18 @@ -7974,7 +7974,7 @@ enum { #define GEN6_PCODE_WRITE_D_COMP 0x11 #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 #define DISPLAY_IPS_CONTROL 0x19 -#define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A +#define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A #define GEN9_PCODE_SAGV_CONTROL 0x21 #define GEN9_SAGV_DISABLE 0x0 #define GEN9_SAGV_IS_DISABLED 0x1 -- cgit v1.2.3 From 61843f0e6212a8592cba26ff554af4af0dd93778 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 12 Sep 2017 18:34:11 +0300 Subject: drm/i915: Name the IPS_PCODE_CONTROL bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Give a name to the bit which tells pcode to control IPS. v2: Note that IPS_CTL bits apply to DISPLAY_IPS_CONTROL as well (Chris) Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170912153411.20171-2-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f9f9fcc833c5..9f03cd063afe 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7974,6 +7974,8 @@ enum { #define GEN6_PCODE_WRITE_D_COMP 0x11 #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 #define DISPLAY_IPS_CONTROL 0x19 + /* See also IPS_CTL */ +#define IPS_PCODE_CONTROL (1 << 30) #define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A #define GEN9_PCODE_SAGV_CONTROL 0x21 #define GEN9_SAGV_DISABLE 0x0 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dbe7d8682c97..c4d8bb75686a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4956,7 +4956,8 @@ void hsw_enable_ips(struct intel_crtc *crtc) assert_plane_enabled(dev_priv, crtc->plane); if (IS_BROADWELL(dev_priv)) { mutex_lock(&dev_priv->rps.hw_lock); - WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0xc0000000)); + WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, + IPS_ENABLE | IPS_PCODE_CONTROL)); mutex_unlock(&dev_priv->rps.hw_lock); /* Quoting Art Runyan: "its not safe to expect any particular * value in IPS_CTL bit 31 after enabling IPS through the -- cgit v1.2.3 From 4ebc65092ca3d9713d48ea43e7db5b3f07faf1bc Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Fri, 8 Sep 2017 17:42:55 -0700 Subject: drm/i915/spt+: Don't reset invalid AUX channel interrupt bits in SDEIMR The SDE interrupt bits 25, 26 and 27 are either reserved or meant for DDI E hotplug in SPT+. These bits are meant for AUX channels only in LPT and CPT, so add the appropriate checks. Signed-off-by: Dhinakaran Pandiyan Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20170909004255.14827-1-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d391e689070..91a2c5dbf2da 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3241,8 +3241,10 @@ static void ibx_irq_postinstall(struct drm_device *dev) if (HAS_PCH_IBX(dev_priv)) mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; - else + else if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; + else + mask = SDE_GMBUS_CPT; gen5_assert_iir_is_zero(dev_priv, SDEIIR); I915_WRITE(SDEIMR, ~mask); -- cgit v1.2.3 From ac70ebe873f5161e46fbd3a5ed318f7c34d0d157 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 12 Sep 2017 16:07:52 +0100 Subject: drm/i915: Cleanup error paths through eb_lookup_vma() Following the simplification to a single lookup loop in commit 170fa29b14fa ("drm/i915: Simplify eb_lookup_vmas()") and commit d1b48c1e7184 ("drm/i915: Replace execbuf vma ht with an idr"), we can go one step further and reorder the error paths so that the state of the local variable obj is always known to the compiler and doesn't need the uninitialized_var markup to squelch a compiler warning. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170912150752.20411-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 7687483ff218..214a850b4b3c 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -679,7 +679,7 @@ static int eb_select_context(struct i915_execbuffer *eb) static int eb_lookup_vmas(struct i915_execbuffer *eb) { struct radix_tree_root *handles_vma = &eb->ctx->handles_vma; - struct drm_i915_gem_object *uninitialized_var(obj); + struct drm_i915_gem_object *obj; unsigned int i; int err; @@ -725,19 +725,17 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) goto err_obj; } + /* transfer ref to ctx */ vma->open_count++; list_add(&lut->obj_link, &obj->lut_list); list_add(&lut->ctx_link, &eb->ctx->handles_list); lut->ctx = eb->ctx; lut->handle = handle; - /* transfer ref to ctx */ - obj = NULL; - add_vma: err = eb_add_vma(eb, i, vma); if (unlikely(err)) - goto err_obj; + goto err_vma; GEM_BUG_ON(vma != eb->vma[i]); GEM_BUG_ON(vma->exec_flags != &eb->flags[i]); @@ -766,8 +764,7 @@ add_vma: return eb_reserve(eb); err_obj: - if (obj) - i915_gem_object_put(obj); + i915_gem_object_put(obj); err_vma: eb->vma[i] = NULL; return err; -- cgit v1.2.3 From 33c8d8870c67faf3161898a56af98ac3c1c71450 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 5 Sep 2017 15:14:31 +0530 Subject: Revert "drm/i915/bxt: Disable device ready before shutdown command" This reverts commit bbdf0b2ff32a ("drm/i915/bxt: Disable device ready before shutdown command"). Disable device ready before shutdown command was added previously to avoid a split screen issue seen on dual link DSI panels. As of now, dual link is not supported and will need some rework in the upstream code. For single link DSI panels, the change is not required. This will cause failure in sending SHUTDOWN packet during disable. Hence reverting the change. Will handle the change as part of dual link enabling in upstream. Fixes: bbdf0b2ff32a ("drm/i915/bxt: Disable device ready before shutdown command") Cc: # v4.12+ Signed-off-by: Uma Shankar Signed-off-by: Vidya Srinivas Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1504604671-17237-1-git-send-email-vidya.srinivas@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 2a0f5d337bea..fc25d7d2d942 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -892,8 +892,6 @@ static void intel_dsi_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; @@ -902,15 +900,6 @@ static void intel_dsi_disable(struct intel_encoder *encoder, intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); intel_panel_disable_backlight(old_conn_state); - /* - * Disable Device ready before the port shutdown in order - * to avoid split screen - */ - if (IS_BROXTON(dev_priv)) { - for_each_dsi_port(port, intel_dsi->ports) - I915_WRITE(MIPI_DEVICE_READY(port), 0); - } - /* * According to the spec we should send SHUTDOWN before * MIPI_SEQ_DISPLAY_OFF only for v3+ VBTs, but field testing -- cgit v1.2.3 From f44e354f857f207cd361269c5e38e1f96e0b616c Mon Sep 17 00:00:00 2001 From: "Lee, Shawn C" Date: Wed, 13 Sep 2017 13:19:20 +0800 Subject: drm/i915/cnp: set min brightness from VBT Min brightness value from vbt was missing for CNP platform. This setting have to refer backlight ic spec to restrict min backlight output. Without this restriction, driver would allow to configure lower brightness value and violate backlight ic requirement. Fixes: 4c9f7086ac6d ("drm/i915/cnp: Backlight support for CNP.") Cc: Jani Nikula Signed-off-by: Shawn Lee Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1505279961-16140-1-git-send-email-shawn.c.lee@intel.com --- drivers/gpu/drm/i915/intel_panel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index d4dd248ac9a8..3b1c5d783ee7 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1737,6 +1737,8 @@ cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) if (!panel->backlight.max) return -ENODEV; + panel->backlight.min = get_backlight_min_vbt(connector); + val = bxt_get_backlight(connector); val = intel_panel_compute_brightness(connector, val); panel->backlight.level = clamp(val, panel->backlight.min, -- cgit v1.2.3 From 5b60fc09806a9db0fb46e6821bc1ed3203b6740e Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Fri, 1 Sep 2017 10:51:01 +0300 Subject: drm/i915/dsi: Replace MIPI command error message with debug message Error message indicating that the same MIPI command is sent consecutively is perhaps too strongly said. Let's replace that as a debug message instead. Signed-off-by: Mika Kahola Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1504252261-28964-3-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index fc25d7d2d942..578254ac799c 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -263,7 +263,7 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs, /* XXX: old code skips write if control unchanged */ if (cmd == I915_READ(MIPI_DPI_CONTROL(port))) - DRM_ERROR("Same special packet %02x twice in a row.\n", cmd); + DRM_DEBUG_KMS("Same special packet %02x twice in a row.\n", cmd); I915_WRITE(MIPI_DPI_CONTROL(port), cmd); -- cgit v1.2.3 From 2013ddebd2f4b5ef90625c8b82da216df0123134 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 12 Sep 2017 22:49:05 +0100 Subject: drm/i915: Move the context descriptor to an inline helper The context descriptor is stored inside the per-engine context state, as we only need to compute it once and access it frequently. However, currently only intel_lrc.c has easy access, but i915_guc_submission.c would like to frequently read it as well, and more so only ever needs the lower 32bits. Make it an inline as the compiler should be able to retrieve the value in less instructions than it takes to do the function call: add/remove: 0/1 grow/shrink: 1/0 up/down: 8/-45 (-37) function old new delta i915_guc_submit 621 629 +8 intel_lr_context_descriptor 45 - -45 Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170912214905.21987-1-chris@chris-wilson.co.uk Reviewed-by: Oscar Mateo --- drivers/gpu/drm/i915/intel_lrc.c | 6 ------ drivers/gpu/drm/i915/intel_lrc.h | 11 +++++++++-- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index d89e1b8e1cc5..9e4342b8e52b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -286,12 +286,6 @@ intel_lr_context_descriptor_update(struct i915_gem_context *ctx, ce->lrc_desc = desc; } -uint64_t intel_lr_context_descriptor(struct i915_gem_context *ctx, - struct intel_engine_cs *engine) -{ - return ctx->engine[engine->id].lrc_desc; -} - static inline void execlists_context_status_change(struct drm_i915_gem_request *rq, unsigned long status) diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 57ef5833c427..3b1de327e504 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -25,6 +25,7 @@ #define _INTEL_LRC_H_ #include "intel_ringbuffer.h" +#include "i915_gem_context.h" #define GEN8_LR_CONTEXT_ALIGN I915_GTT_MIN_ALIGNMENT @@ -78,8 +79,14 @@ struct drm_i915_private; struct i915_gem_context; void intel_lr_context_resume(struct drm_i915_private *dev_priv); -uint64_t intel_lr_context_descriptor(struct i915_gem_context *ctx, - struct intel_engine_cs *engine); + +static inline uint64_t +intel_lr_context_descriptor(struct i915_gem_context *ctx, + struct intel_engine_cs *engine) +{ + return ctx->engine[engine->id].lrc_desc; +} + /* Execlists */ int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, -- cgit v1.2.3 From e9eb8039ba0cb902817fafb5a0217dba0544f165 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Tue, 12 Sep 2017 14:36:35 -0700 Subject: drm/i915/guc: Name the default GuC scheduling policy The default values for the default scheduling policy come from the GuC firmware itself. Transform the magic numbers into defines. Suggested-by: Joonas Lahtinen Signed-off-by: Oscar Mateo Link: https://patchwork.freedesktop.org/patch/msgid/1505252197-27696-1-git-send-email-oscar.mateo@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_guc_submission.c | 15 ++++++++++----- drivers/gpu/drm/i915/intel_guc_fwif.h | 6 +++++- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 48a1e9349a2c..0f1536edc1ea 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -996,22 +996,27 @@ static void guc_client_free(struct i915_guc_client *client) kfree(client); } +static void guc_policy_init(struct guc_policy *policy) +{ + policy->execution_quantum = POLICY_DEFAULT_EXECUTION_QUANTUM_US; + policy->preemption_time = POLICY_DEFAULT_PREEMPTION_TIME_US; + policy->fault_time = POLICY_DEFAULT_FAULT_TIME_US; + policy->policy_flags = 0; +} + static void guc_policies_init(struct guc_policies *policies) { struct guc_policy *policy; u32 p, i; - policies->dpc_promote_time = 500000; + policies->dpc_promote_time = POLICY_DEFAULT_DPC_PROMOTE_TIME_US; policies->max_num_work_items = POLICY_MAX_NUM_WI; for (p = 0; p < GUC_CLIENT_PRIORITY_NUM; p++) { for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) { policy = &policies->policy[p][i]; - policy->execution_quantum = 1000000; - policy->preemption_time = 500000; - policy->fault_time = 250000; - policy->policy_flags = 0; + guc_policy_init(policy); } } diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 5fa286074811..83bd401196eb 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -388,7 +388,11 @@ struct guc_ct_buffer_desc { /* Preempt to idle on quantum expiry */ #define POLICY_PREEMPT_TO_IDLE (1<<1) -#define POLICY_MAX_NUM_WI 15 +#define POLICY_MAX_NUM_WI 15 +#define POLICY_DEFAULT_DPC_PROMOTE_TIME_US 500000 +#define POLICY_DEFAULT_EXECUTION_QUANTUM_US 1000000 +#define POLICY_DEFAULT_PREEMPTION_TIME_US 500000 +#define POLICY_DEFAULT_FAULT_TIME_US 250000 struct guc_policy { /* Time for one workload to execute. (in micro seconds) */ -- cgit v1.2.3 From 048d2847d76df2a7e801d77d411216910b0643c4 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Tue, 12 Sep 2017 14:36:36 -0700 Subject: drm/i915/guc: Remove WQ_WORKLOAD_SHIFT define We never used it in i915 and it's going to be removed in newer GuC firmwares anyway. Signed-off-by: Oscar Mateo Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1505252197-27696-2-git-send-email-oscar.mateo@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_guc_fwif.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 83bd401196eb..7eb6b4fa1d6f 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -56,10 +56,6 @@ #define WQ_LEN_SHIFT 16 #define WQ_NO_WCFLUSH_WAIT (1 << 27) #define WQ_PRESENT_WORKLOAD (1 << 28) -#define WQ_WORKLOAD_SHIFT 29 -#define WQ_WORKLOAD_GENERAL (0 << WQ_WORKLOAD_SHIFT) -#define WQ_WORKLOAD_GPGPU (1 << WQ_WORKLOAD_SHIFT) -#define WQ_WORKLOAD_TOUCH (2 << WQ_WORKLOAD_SHIFT) #define WQ_RING_TAIL_SHIFT 20 #define WQ_RING_TAIL_MAX 0x7FF /* 2^11 QWords */ -- cgit v1.2.3 From ada8c4139fbad766fdf9e63b31c49874299fd60c Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Tue, 12 Sep 2017 14:36:37 -0700 Subject: drm/i915/guc: Small improvements to guc_wq_item_append Spare some comments and other small style changes. Suggested-by: Joonas Lahtinen Signed-off-by: Oscar Mateo Link: https://patchwork.freedesktop.org/patch/msgid/1505252197-27696-3-git-send-email-oscar.mateo@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_guc_submission.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 0f1536edc1ea..5c81d5f2353d 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -469,8 +469,9 @@ static void guc_wq_item_append(struct i915_guc_client *client, { /* wqi_len is in DWords, and does not include the one-word header */ const size_t wqi_size = sizeof(struct guc_wq_item); - const u32 wqi_len = wqi_size/sizeof(u32) - 1; + const u32 wqi_len = wqi_size / sizeof(u32) - 1; struct intel_engine_cs *engine = rq->engine; + struct i915_gem_context *ctx = rq->ctx; struct guc_process_desc *desc = __get_process_desc(client); struct guc_wq_item *wqi; u32 freespace, tail, wq_off; @@ -479,8 +480,7 @@ static void guc_wq_item_append(struct i915_guc_client *client, freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size); GEM_BUG_ON(freespace < wqi_size); - /* The GuC firmware wants the tail index in QWords, not bytes */ - tail = intel_ring_set_tail(rq->ring, rq->tail) >> 3; + tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64); GEM_BUG_ON(tail > WQ_RING_TAIL_MAX); /* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we @@ -505,12 +505,11 @@ static void guc_wq_item_append(struct i915_guc_client *client, /* Now fill in the 4-word work queue item */ wqi->header = WQ_TYPE_INORDER | - (wqi_len << WQ_LEN_SHIFT) | - (engine->guc_id << WQ_TARGET_SHIFT) | - WQ_NO_WCFLUSH_WAIT; + (wqi_len << WQ_LEN_SHIFT) | + (engine->guc_id << WQ_TARGET_SHIFT) | + WQ_NO_WCFLUSH_WAIT; - /* The GuC wants only the low-order word of the context descriptor */ - wqi->context_desc = (u32)intel_lr_context_descriptor(rq->ctx, engine); + wqi->context_desc = lower_32_bits(intel_lr_context_descriptor(ctx, engine)); wqi->submit_element_info = tail << WQ_RING_TAIL_SHIFT; wqi->fence_id = rq->global_seqno; -- cgit v1.2.3 From e60b36f76c2ee0ba90b431daa534bc262798fb26 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Sep 2017 11:57:54 +0100 Subject: drm/i915: Squelch smatch warning for statement with no effect The sgt iterators cause an drivers/gpu/drm/i915/i915_gpu_error.c:846 i915_error_object_create() warn: statement has no effect 7 everywhere they are used. If we change the code slightly, we can achieve the same increment without altering the output or raising a warning. text data bss dec hex filename 1267906 20587 3168 1291661 13b58d before 1267906 20587 3168 1291661 13b58d after Signed-off-by: Chris Wilson Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170913105754.4423-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ec70121410e4..9dba1b2e8019 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2835,8 +2835,8 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg) #define for_each_sgt_dma(__dmap, __iter, __sgt) \ for ((__iter) = __sgt_iter((__sgt)->sgl, true); \ ((__dmap) = (__iter).dma + (__iter).curr); \ - (((__iter).curr += PAGE_SIZE) < (__iter).max) || \ - ((__iter) = __sgt_iter(__sg_next((__iter).sgp), true), 0)) + (((__iter).curr += PAGE_SIZE) >= (__iter).max) ? \ + (__iter) = __sgt_iter(__sg_next((__iter).sgp), true), 0 : 0) /** * for_each_sgt_page - iterate over the pages of the given sg_table @@ -2848,8 +2848,8 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg) for ((__iter) = __sgt_iter((__sgt)->sgl, false); \ ((__pp) = (__iter).pfn == 0 ? NULL : \ pfn_to_page((__iter).pfn + ((__iter).curr >> PAGE_SHIFT))); \ - (((__iter).curr += PAGE_SIZE) < (__iter).max) || \ - ((__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0)) + (((__iter).curr += PAGE_SIZE) >= (__iter).max) ? \ + (__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0 : 0) static inline unsigned int i915_sg_segment_size(void) { -- cgit v1.2.3 From 3123698f50fe4ac9ddb775dcd2b34a1d9cdd603f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Sep 2017 11:51:53 +0100 Subject: drm/i915: Use mul_u32_u32() for 32b x 32b -> 64b result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As realised by commit 9e3d6223d209 ("math64, timers: Fix 32bit mul_u64_u32_shr() and friends"), GCC does not always generate ideal code for performing a 32b x 32b multiply returning a 64b result (i.e. where we idiomatically use u64 result = (u64)x * (u32)x). This catches a couple of instances in the display code using (u64)x * (u32)y. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170913105154.2910-1-chris@chris-wilson.co.uk Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_tv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c4d8bb75686a..3bfcf187a0a1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10224,7 +10224,7 @@ int intel_dotclock_calculate(int link_freq, if (!m_n->link_n) return 0; - return div_u64((u64)m_n->link_m * link_freq, m_n->link_n); + return div_u64(mul_u32_u32(m_n->link_m, link_freq), m_n->link_n); } static void ironlake_pch_clock_get(struct intel_crtc *crtc, diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 0cc999fa09c5..a79a7591b2cf 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1385,7 +1385,7 @@ intel_tv_get_modes(struct drm_connector *connector) mode_ptr->vsync_end = mode_ptr->vsync_start + 1; mode_ptr->vtotal = vactive_s + 33; - tmp = (u64) tv_mode->refresh * mode_ptr->vtotal; + tmp = mul_u32_u32(tv_mode->refresh, mode_ptr->vtotal); tmp *= mode_ptr->htotal; tmp = div_u64(tmp, 1000000); mode_ptr->clock = (int) tmp; -- cgit v1.2.3 From 7ce5b6850b47824a2b8d0a17b5fe75f9942e5cd1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Sep 2017 11:51:54 +0100 Subject: drm/i915/selftests: Use mul_u32_u32() for 32b x 32b -> 64b result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As realised by commit 9e3d6223d209 ("math64, timers: Fix 32bit mul_u64_u32_shr() and friends"), GCC does not always generate ideal code for performing a 32b x 32b multiply returning a 64b result (i.e. where we idiomatically use u64 result = (u64)x * (u32)x). Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170913105154.2910-2-chris@chris-wilson.co.uk Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 2 +- drivers/gpu/drm/i915/selftests/i915_random.c | 5 ----- drivers/gpu/drm/i915/selftests/i915_random.h | 5 +++++ 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c index 7a44dab631b8..4795877abe56 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c @@ -121,7 +121,7 @@ out: static unsigned int random_engine(struct rnd_state *rnd) { - return ((u64)prandom_u32_state(rnd) * I915_NUM_ENGINES) >> 32; + return i915_prandom_u32_max_state(I915_NUM_ENGINES, rnd); } static int bench_sync(void *arg) diff --git a/drivers/gpu/drm/i915/selftests/i915_random.c b/drivers/gpu/drm/i915/selftests/i915_random.c index d044bf9a6feb..ea0f5dbc0eb7 100644 --- a/drivers/gpu/drm/i915/selftests/i915_random.c +++ b/drivers/gpu/drm/i915/selftests/i915_random.c @@ -41,11 +41,6 @@ u64 i915_prandom_u64_state(struct rnd_state *rnd) return x; } -static inline u32 i915_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state) -{ - return upper_32_bits((u64)prandom_u32_state(state) * ep_ro); -} - void i915_random_reorder(unsigned int *order, unsigned int count, struct rnd_state *state) { diff --git a/drivers/gpu/drm/i915/selftests/i915_random.h b/drivers/gpu/drm/i915/selftests/i915_random.h index 6c9379871384..7dffedc501ca 100644 --- a/drivers/gpu/drm/i915/selftests/i915_random.h +++ b/drivers/gpu/drm/i915/selftests/i915_random.h @@ -43,6 +43,11 @@ u64 i915_prandom_u64_state(struct rnd_state *rnd); +static inline u32 i915_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state) +{ + return upper_32_bits(mul_u32_u32(prandom_u32_state(state), ep_ro)); +} + unsigned int *i915_random_order(unsigned int count, struct rnd_state *state); void i915_random_reorder(unsigned int *order, -- cgit v1.2.3 From 0b29c75a01e5413d9c1f368b8357b589c7b5a922 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Wed, 13 Sep 2017 09:56:00 +0100 Subject: drm/i915/lrc: Clarify the format of the context image Not only the context image consist of two parts (the PPHWSP, and the logical context state), but we also allocate a header at the start of for sharing data with GuC. Thus every lrc looks like this: | [guc] | [hwsp] [logical state] | |<- our header ->|<- context image ->| So far, we have oversimplified whenever we use each of these parts of the context, just because the GuC header happens to be in page 0, and the (PP)HWSP is in page 1. But this had led to using the same define for more than one meaning (as a page index in the lrc and as 1 page). This patch adds defines for the GuC shared page, the PPHWSP page and the start of the logical state. It also updated the places where the old define was being used. Since we are not changing the size (or format) of the context, there are no functional changes. v2: Use PPHWSP index for hws again. Suggested-by: Chris Wilson Signed-off-by: Michel Thierry Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Michal Wajdeczko Cc: Oscar Mateo Cc: intel-gvt-dev@lists.freedesktop.org Link: http://patchwork.freedesktop.org/patch/msgid/20170712193032.27080-1-michel.thierry@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170913085605.18299-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gvt/scheduler.c | 4 ++-- drivers/gpu/drm/i915/i915_guc_submission.c | 4 ++-- drivers/gpu/drm/i915/intel_lrc.c | 9 ++++++--- drivers/gpu/drm/i915/intel_lrc.h | 25 ++++++++++++++++++++++--- 4 files changed, 32 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 6fb9b589276d..d5892d24f0b6 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -87,7 +87,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) return -EINVAL; } - page = i915_gem_object_get_page(ctx_obj, LRC_PPHWSP_PN + i); + page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); dst = kmap(page); intel_gvt_hypervisor_read_gpa(vgpu, context_gpa, dst, GTT_PAGE_SIZE); @@ -454,7 +454,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload) return; } - page = i915_gem_object_get_page(ctx_obj, LRC_PPHWSP_PN + i); + page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); src = kmap(page); intel_gvt_hypervisor_write_gpa(vgpu, context_gpa, src, GTT_PAGE_SIZE); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 5c81d5f2353d..226e5393d3c0 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -1314,7 +1314,7 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv) /* any value greater than GUC_POWER_D0 */ data[1] = GUC_POWER_D1; /* first page is shared data with GuC */ - data[2] = guc_ggtt_offset(ctx->engine[RCS].state); + data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + LRC_GUCSHR_PN * PAGE_SIZE; return intel_guc_send(guc, data, ARRAY_SIZE(data)); } @@ -1340,7 +1340,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv) data[0] = INTEL_GUC_ACTION_EXIT_S_STATE; data[1] = GUC_POWER_D0; /* first page is shared data with GuC */ - data[2] = guc_ggtt_offset(ctx->engine[RCS].state); + data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + LRC_GUCSHR_PN * PAGE_SIZE; return intel_guc_send(guc, data, ARRAY_SIZE(data)); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9e4342b8e52b..3b8f1a79d640 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -279,7 +279,7 @@ intel_lr_context_descriptor_update(struct i915_gem_context *ctx, BUILD_BUG_ON(MAX_CONTEXT_HW_ID > (1<desc_template; /* bits 0-11 */ - desc |= i915_ggtt_offset(ce->state) + LRC_PPHWSP_PN * PAGE_SIZE; + desc |= i915_ggtt_offset(ce->state) + LRC_HEADER_PAGES * PAGE_SIZE; /* bits 12-31 */ desc |= (u64)ctx->hw_id << GEN8_CTX_ID_SHIFT; /* bits 32-52 */ @@ -2048,8 +2048,11 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, context_size = round_up(engine->context_size, I915_GTT_PAGE_SIZE); - /* One extra page as the sharing data between driver and GuC */ - context_size += PAGE_SIZE * LRC_PPHWSP_PN; + /* + * Before the actual start of the context image, we insert a few pages + * for our own use and for sharing with the GuC. + */ + context_size += LRC_HEADER_PAGES * PAGE_SIZE; ctx_obj = i915_gem_object_create(ctx->i915, context_size); if (IS_ERR(ctx_obj)) { diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 3b1de327e504..314adee7127a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -70,10 +70,29 @@ int logical_xcs_ring_init(struct intel_engine_cs *engine); /* Logical Ring Contexts */ -/* One extra page is added before LRC for GuC as shared data */ +/* + * We allocate a header at the start of the context image for our own + * use, therefore the actual location of the logical state is offset + * from the start of the VMA. The layout is + * + * | [guc] | [hwsp] [logical state] | + * |<- our header ->|<- context image ->| + * + */ +/* The first page is used for sharing data with the GuC */ #define LRC_GUCSHR_PN (0) -#define LRC_PPHWSP_PN (LRC_GUCSHR_PN + 1) -#define LRC_STATE_PN (LRC_PPHWSP_PN + 1) +#define LRC_GUCSHR_SZ (1) +/* At the start of the context image is its per-process HWS page */ +#define LRC_PPHWSP_PN (LRC_GUCSHR_PN + LRC_GUCSHR_SZ) +#define LRC_PPHWSP_SZ (1) +/* Finally we have the logical state for the context */ +#define LRC_STATE_PN (LRC_PPHWSP_PN + LRC_PPHWSP_SZ) + +/* + * Currently we include the PPHWSP in __intel_engine_context_size() so + * the size of the header is synonymous with the start of the PPHWSP. + */ +#define LRC_HEADER_PAGES LRC_PPHWSP_PN struct drm_i915_private; struct i915_gem_context; -- cgit v1.2.3 From a922c0c7a6b7b84351c4051fc9defe1222185c16 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Wed, 13 Sep 2017 09:56:01 +0100 Subject: drm/i915/guc: Don't make assumptions while getting the lrca offset Using the HWSP ggtt_offset to get the lrca offset is only correct if the HWSP happens to be before it (when we reuse the PPHWSP of the kernel context as the engine HWSP). Instead of making this assumption, get the lrca offset from the kernel_context engine state. And while looking at this part of the GuC interaction, it was also noticed that the firmware expects the size of only the engine context (context minus the execlist part, i.e. don't include the first 80 dwords), so pass the right size. v2: Use the new macros to prevent abusive overuse of the old ones (Chris). Reported-by: Daniele Ceraolo Spurio Signed-off-by: Michel Thierry Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Michal Wajdeczko Cc: Oscar Mateo Link: http://patchwork.freedesktop.org/patch/msgid/20170712193032.27080-2-michel.thierry@intel.com Reviewed-by: Chris Wilson Acked-by: Daniele Ceraolo Spurio Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170913085605.18299-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_guc_submission.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 226e5393d3c0..b28677e5a4f2 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -1022,6 +1022,12 @@ static void guc_policies_init(struct guc_policies *policies) policies->is_valid = 1; } +/* + * The first 80 dwords of the register state context, containing the + * execlists and ppgtt registers. + */ +#define LR_HW_CONTEXT_SIZE (80 * sizeof(u32)) + static int guc_ads_create(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); @@ -1036,6 +1042,8 @@ static int guc_ads_create(struct intel_guc *guc) } __packed *blob; struct intel_engine_cs *engine; enum intel_engine_id id; + const u32 skipped_offset = LRC_HEADER_PAGES * PAGE_SIZE; + const u32 skipped_size = LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE; u32 base; GEM_BUG_ON(guc->ads_vma); @@ -1066,13 +1074,20 @@ static int guc_ads_create(struct intel_guc *guc) * engines after a reset. Here we use the Render ring default * context, which must already exist and be pinned in the GGTT, * so its address won't change after we've told the GuC where - * to find it. + * to find it. Note that we have to skip our header (1 page), + * because our GuC shared data is there. */ blob->ads.golden_context_lrca = - dev_priv->engine[RCS]->status_page.ggtt_offset; + guc_ggtt_offset(dev_priv->kernel_context->engine[RCS].state) + skipped_offset; + /* + * The GuC expects us to exclude the portion of the context image that + * it skips from the size it is to read. It starts reading from after + * the execlist context (so skipping the first page [PPHWSP] and 80 + * dwords). Weird guc is weird. + */ for_each_engine(engine, dev_priv, id) - blob->ads.eng_state_size[engine->guc_id] = engine->context_size; + blob->ads.eng_state_size[engine->guc_id] = engine->context_size - skipped_size; base = guc_ggtt_offset(vma); blob->ads.scheduler_policies = base + ptr_offset(blob, policies); -- cgit v1.2.3 From 486e93f72abd41559b740f017717c7f6b3f8bb1f Mon Sep 17 00:00:00 2001 From: Daniele Ceraolo Spurio Date: Wed, 13 Sep 2017 09:56:02 +0100 Subject: drm/i915/lrc: allocate separate page for HWSP On gen8+ we're currently using the PPHWSP of the kernel ctx as the global HWSP. However, when the kernel ctx gets submitted (e.g. from __intel_autoenable_gt_powersave) the HW will use that page as both HWSP and PPHWSP. This causes a conflict in the register arena of the HWSP, i.e. dword indices below 0x30. We don't current utilize this arena, but in the following patches we will take advantage of the cached register state for handling execlist's context status interrupt. To avoid the conflict, instead of re-using the PPHWSP of the kernel ctx we can allocate a separate page for the HWSP like what happens for pre-execlists platform. v2: Add a use-case for the register arena of the HWSP. Signed-off-by: Daniele Ceraolo Spurio Cc: Michel Thierry Link: http://patchwork.freedesktop.org/patch/msgid/1499357440-34688-1-git-send-email-daniele.ceraolospurio@intel.com Signed-off-by: Chris Wilson Reviewed-by: Michel Thierry Link: https://patchwork.freedesktop.org/patch/msgid/20170913085605.18299-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_engine_cs.c | 126 +++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_lrc.c | 34 +-------- drivers/gpu/drm/i915/intel_ringbuffer.c | 125 +------------------------------ 3 files changed, 127 insertions(+), 158 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 3ae89a9d6241..8a5535ad6552 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -442,6 +442,114 @@ static void intel_engine_cleanup_scratch(struct intel_engine_cs *engine) i915_vma_unpin_and_release(&engine->scratch); } +static void cleanup_phys_status_page(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + + if (!dev_priv->status_page_dmah) + return; + + drm_pci_free(&dev_priv->drm, dev_priv->status_page_dmah); + engine->status_page.page_addr = NULL; +} + +static void cleanup_status_page(struct intel_engine_cs *engine) +{ + struct i915_vma *vma; + struct drm_i915_gem_object *obj; + + vma = fetch_and_zero(&engine->status_page.vma); + if (!vma) + return; + + obj = vma->obj; + + i915_vma_unpin(vma); + i915_vma_close(vma); + + i915_gem_object_unpin_map(obj); + __i915_gem_object_release_unless_active(obj); +} + +static int init_status_page(struct intel_engine_cs *engine) +{ + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + unsigned int flags; + void *vaddr; + int ret; + + obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE); + if (IS_ERR(obj)) { + DRM_ERROR("Failed to allocate status page\n"); + return PTR_ERR(obj); + } + + ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); + if (ret) + goto err; + + vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto err; + } + + flags = PIN_GLOBAL; + if (!HAS_LLC(engine->i915)) + /* On g33, we cannot place HWS above 256MiB, so + * restrict its pinning to the low mappable arena. + * Though this restriction is not documented for + * gen4, gen5, or byt, they also behave similarly + * and hang if the HWS is placed at the top of the + * GTT. To generalise, it appears that all !llc + * platforms have issues with us placing the HWS + * above the mappable region (even though we never + * actually map it). + */ + flags |= PIN_MAPPABLE; + ret = i915_vma_pin(vma, 0, 4096, flags); + if (ret) + goto err; + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(vaddr)) { + ret = PTR_ERR(vaddr); + goto err_unpin; + } + + engine->status_page.vma = vma; + engine->status_page.ggtt_offset = i915_ggtt_offset(vma); + engine->status_page.page_addr = memset(vaddr, 0, PAGE_SIZE); + + DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", + engine->name, i915_ggtt_offset(vma)); + return 0; + +err_unpin: + i915_vma_unpin(vma); +err: + i915_gem_object_put(obj); + return ret; +} + +static int init_phys_status_page(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + + GEM_BUG_ON(engine->id != RCS); + + dev_priv->status_page_dmah = + drm_pci_alloc(&dev_priv->drm, PAGE_SIZE, PAGE_SIZE); + if (!dev_priv->status_page_dmah) + return -ENOMEM; + + engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr; + memset(engine->status_page.page_addr, 0, PAGE_SIZE); + + return 0; +} + /** * intel_engines_init_common - initialize cengine state which might require hw access * @engine: Engine to initialize. @@ -477,10 +585,21 @@ int intel_engine_init_common(struct intel_engine_cs *engine) ret = i915_gem_render_state_init(engine); if (ret) - goto err_unpin; + goto err_breadcrumbs; + + if (HWS_NEEDS_PHYSICAL(engine->i915)) + ret = init_phys_status_page(engine); + else + ret = init_status_page(engine); + if (ret) + goto err_rs_fini; return 0; +err_rs_fini: + i915_gem_render_state_fini(engine); +err_breadcrumbs: + intel_engine_fini_breadcrumbs(engine); err_unpin: engine->context_unpin(engine, engine->i915->kernel_context); return ret; @@ -497,6 +616,11 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine) { intel_engine_cleanup_scratch(engine); + if (HWS_NEEDS_PHYSICAL(engine->i915)) + cleanup_phys_status_page(engine); + else + cleanup_status_page(engine); + i915_gem_render_state_fini(engine); intel_engine_fini_breadcrumbs(engine); intel_engine_cleanup_cmd_parser(engine); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3b8f1a79d640..8886e3b60e82 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1674,11 +1674,6 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) if (engine->cleanup) engine->cleanup(engine); - if (engine->status_page.vma) { - i915_gem_object_unpin_map(engine->status_page.vma->obj); - engine->status_page.vma = NULL; - } - intel_engine_cleanup_common(engine); lrc_destroy_wa_ctx(engine); @@ -1725,24 +1720,6 @@ logical_ring_default_irqs(struct intel_engine_cs *engine) engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; } -static int -lrc_setup_hws(struct intel_engine_cs *engine, struct i915_vma *vma) -{ - const int hws_offset = LRC_PPHWSP_PN * PAGE_SIZE; - void *hws; - - /* The HWSP is part of the default context object in LRC mode. */ - hws = i915_gem_object_pin_map(vma->obj, I915_MAP_WB); - if (IS_ERR(hws)) - return PTR_ERR(hws); - - engine->status_page.page_addr = hws + hws_offset; - engine->status_page.ggtt_offset = i915_ggtt_offset(vma) + hws_offset; - engine->status_page.vma = vma; - - return 0; -} - static void logical_ring_setup(struct intel_engine_cs *engine) { @@ -1775,23 +1752,14 @@ logical_ring_setup(struct intel_engine_cs *engine) logical_ring_default_irqs(engine); } -static int -logical_ring_init(struct intel_engine_cs *engine) +static int logical_ring_init(struct intel_engine_cs *engine) { - struct i915_gem_context *dctx = engine->i915->kernel_context; int ret; ret = intel_engine_init_common(engine); if (ret) goto error; - /* And setup the hardware status page. */ - ret = lrc_setup_hws(engine, dctx->engine[engine->id].state); - if (ret) { - DRM_ERROR("Failed to set up hws %s: %d\n", engine->name, ret); - goto error; - } - return 0; error: diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 268342433a8e..8af8871a8594 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1175,113 +1175,7 @@ i915_emit_bb_start(struct drm_i915_gem_request *req, return 0; } -static void cleanup_phys_status_page(struct intel_engine_cs *engine) -{ - struct drm_i915_private *dev_priv = engine->i915; - - if (!dev_priv->status_page_dmah) - return; - - drm_pci_free(&dev_priv->drm, dev_priv->status_page_dmah); - engine->status_page.page_addr = NULL; -} - -static void cleanup_status_page(struct intel_engine_cs *engine) -{ - struct i915_vma *vma; - struct drm_i915_gem_object *obj; - - vma = fetch_and_zero(&engine->status_page.vma); - if (!vma) - return; - - obj = vma->obj; - - i915_vma_unpin(vma); - i915_vma_close(vma); - - i915_gem_object_unpin_map(obj); - __i915_gem_object_release_unless_active(obj); -} -static int init_status_page(struct intel_engine_cs *engine) -{ - struct drm_i915_gem_object *obj; - struct i915_vma *vma; - unsigned int flags; - void *vaddr; - int ret; - - obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE); - if (IS_ERR(obj)) { - DRM_ERROR("Failed to allocate status page\n"); - return PTR_ERR(obj); - } - - ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); - if (ret) - goto err; - - vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL); - if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - goto err; - } - - flags = PIN_GLOBAL; - if (!HAS_LLC(engine->i915)) - /* On g33, we cannot place HWS above 256MiB, so - * restrict its pinning to the low mappable arena. - * Though this restriction is not documented for - * gen4, gen5, or byt, they also behave similarly - * and hang if the HWS is placed at the top of the - * GTT. To generalise, it appears that all !llc - * platforms have issues with us placing the HWS - * above the mappable region (even though we never - * actualy map it). - */ - flags |= PIN_MAPPABLE; - ret = i915_vma_pin(vma, 0, 4096, flags); - if (ret) - goto err; - - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); - if (IS_ERR(vaddr)) { - ret = PTR_ERR(vaddr); - goto err_unpin; - } - - engine->status_page.vma = vma; - engine->status_page.ggtt_offset = i915_ggtt_offset(vma); - engine->status_page.page_addr = memset(vaddr, 0, PAGE_SIZE); - - DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", - engine->name, i915_ggtt_offset(vma)); - return 0; - -err_unpin: - i915_vma_unpin(vma); -err: - i915_gem_object_put(obj); - return ret; -} - -static int init_phys_status_page(struct intel_engine_cs *engine) -{ - struct drm_i915_private *dev_priv = engine->i915; - - GEM_BUG_ON(engine->id != RCS); - - dev_priv->status_page_dmah = - drm_pci_alloc(&dev_priv->drm, PAGE_SIZE, PAGE_SIZE); - if (!dev_priv->status_page_dmah) - return -ENOMEM; - - engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr; - memset(engine->status_page.page_addr, 0, PAGE_SIZE); - - return 0; -} int intel_ring_pin(struct intel_ring *ring, struct drm_i915_private *i915, @@ -1568,17 +1462,10 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) if (err) goto err; - if (HWS_NEEDS_PHYSICAL(engine->i915)) - err = init_phys_status_page(engine); - else - err = init_status_page(engine); - if (err) - goto err; - ring = intel_engine_create_ring(engine, 32 * PAGE_SIZE); if (IS_ERR(ring)) { err = PTR_ERR(ring); - goto err_hws; + goto err; } /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ @@ -1593,11 +1480,6 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) err_ring: intel_ring_free(ring); -err_hws: - if (HWS_NEEDS_PHYSICAL(engine->i915)) - cleanup_phys_status_page(engine); - else - cleanup_status_page(engine); err: intel_engine_cleanup_common(engine); return err; @@ -1616,11 +1498,6 @@ void intel_engine_cleanup(struct intel_engine_cs *engine) if (engine->cleanup) engine->cleanup(engine); - if (HWS_NEEDS_PHYSICAL(dev_priv)) - cleanup_phys_status_page(engine); - else - cleanup_status_page(engine); - intel_engine_cleanup_common(engine); dev_priv->engine[engine->id] = NULL; -- cgit v1.2.3 From 34a04e5e46cb984a6bab336484fa856574db332f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Sep 2017 09:56:03 +0100 Subject: drm/i915: Allow HW status page to be bound high MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the time of commit 1f767e02d69f ("drm/i915: HWS must be in the mappable region for g33"), drm_mm insertion would often default to placing a new object high in the zone forcing us to specify that certain HWSP must be bound within the low mappable region. Since then, drm_mm has gained more finesse over its placement and exposes that to the caller, commit 4e64e5539d15 ("drm: Improve drm_mm search (and fix topdown allocation) with rbtrees"). As such where possible we want the HWSP to be outside of the mappable aperture and so need to specify that can be pinned high. Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Ville Syrjälä Cc: Michel Thierry Cc: Tvrtko Ursulin Cc: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170913085605.18299-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_engine_cs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 8a5535ad6552..32d35f32d289 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -508,6 +508,8 @@ static int init_status_page(struct intel_engine_cs *engine) * actually map it). */ flags |= PIN_MAPPABLE; + else + flags |= PIN_HIGH; ret = i915_vma_pin(vma, 0, 4096, flags); if (ret) goto err; -- cgit v1.2.3 From 8320caeeffdefec3b58b9d4a7ed8e1079492fe7b Mon Sep 17 00:00:00 2001 From: Adrian Salido Date: Fri, 8 Sep 2017 10:55:27 -0700 Subject: HID: i2c-hid: allocate hid buffers for real worst case The buffer allocation is not currently accounting for an extra byte for the report id. This can cause an out of bounds access in function i2c_hid_set_or_send_report() with reportID > 15. Cc: stable@vger.kernel.org Signed-off-by: Adrian Salido Reviewed-by: Benson Leung Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 77396145d2d0..9145c2129a96 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -543,7 +543,8 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) { /* the worst case is computed from the set_report command with a * reportID > 15 and the maximum report length */ - int args_len = sizeof(__u8) + /* optional ReportID byte */ + int args_len = sizeof(__u8) + /* ReportID */ + sizeof(__u8) + /* optional ReportID byte */ sizeof(__u16) + /* data register */ sizeof(__u16) + /* size of the report */ report_size; /* report */ -- cgit v1.2.3 From 6d2cb5aa383bf020ee95e33d9d107975f340ae1c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Sep 2017 14:35:34 +0100 Subject: drm/i915/execlists: Read the context-status buffer from the HWSP The engine provides a mirror of the CSB in the HWSP. If we use the cacheable reads from the HWSP, we can shave off a few mmio reads per context-switch interrupt (which are quite frequent!). Just removing a couple of mmio is not enough to actually reduce any latency, but a small reduction in overall cpu usage. Much appreciation for Ben dropping the bombshell that the CSB was in the HWSP and for Michel in digging out the details. v2: Don't be lazy, add the defines for the indices. v3: Include the HWSP in debugfs/i915_engine_info v4: Check for GVT-g, it currently depends on intercepting CSB mmio v5: Fixup GVT-g mmio path v6: Disable HWSP if VT-d is active as the iommu adds unpredictable memory latency. (Mika) v7: Also markup the CSB read with READ_ONCE() as it may still be an mmio read and we want to stop the compiler from issuing a later (v.slow) reload. Suggested-by: Ben Widawsky Signed-off-by: Chris Wilson Cc: Michel Thierry Cc: Tvrtko Ursulin Cc: Mika Kuoppala Cc: Daniele Ceraolo Spurio Cc: Zhenyu Wang Cc: Zhi Wang Acked-by: Michel Thierry Link: https://patchwork.freedesktop.org/patch/msgid/20170913133534.26927-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_debugfs.c | 7 +++++-- drivers/gpu/drm/i915/intel_lrc.c | 35 ++++++++++++++++++++++++++++----- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +++ 3 files changed, 38 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6338018f655d..7062cde94a49 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3315,6 +3315,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) upper_32_bits(addr), lower_32_bits(addr)); if (i915.enable_execlists) { + const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; u32 ptr, read, write; unsigned int idx; @@ -3337,10 +3338,12 @@ static int i915_engine_info(struct seq_file *m, void *unused) write += GEN8_CSB_ENTRIES; while (read < write) { idx = ++read % GEN8_CSB_ENTRIES; - seq_printf(m, "\tExeclist CSB[%d]: 0x%08x, context: %d\n", + seq_printf(m, "\tExeclist CSB[%d]: 0x%08x [0x%08x in hwsp], context: %d [%d in hwsp]\n", idx, I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)), - I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx))); + hws[idx * 2], + I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx)), + hws[idx * 2 + 1]); } rcu_read_lock(); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8886e3b60e82..6d7bbb9e769a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -541,10 +541,17 @@ static void intel_lrc_irq_handler(unsigned long data) while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { u32 __iomem *csb_mmio = dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)); - u32 __iomem *buf = - dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0)); + /* The HWSP contains a (cacheable) mirror of the CSB */ + const u32 *buf = + &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; unsigned int head, tail; + /* However GVT emulation depends upon intercepting CSB mmio */ + if (unlikely(engine->csb_use_mmio)) { + buf = (u32 * __force) + (dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); + } + /* The write will be ordered by the uncached read (itself * a memory barrier), so we do not need another in the form * of a locked instruction. The race between the interrupt @@ -584,13 +591,12 @@ static void intel_lrc_irq_handler(unsigned long data) * status notifier. */ - status = readl(buf + 2 * head); + status = READ_ONCE(buf[2 * head]); /* maybe mmio! */ if (!(status & GEN8_CTX_STATUS_COMPLETED_MASK)) continue; /* Check the context/desc id for this event matches */ - GEM_DEBUG_BUG_ON(readl(buf + 2 * head + 1) != - port->context_id); + GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); rq = port_unpack(port, &count); GEM_BUG_ON(count == 0); @@ -1720,6 +1726,23 @@ logical_ring_default_irqs(struct intel_engine_cs *engine) engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; } +static bool irq_handler_force_mmio(struct drm_i915_private *i915) +{ + /* GVT emulation depends upon intercepting CSB mmio */ + if (intel_vgpu_active(i915)) + return true; + + /* + * IOMMU adds unpredictable latency causing the CSB write (from the + * GPU into the HWSP) to only be visible some time after the interrupt + * (missed breadcrumb syndrome). + */ + if (intel_vtd_active()) + return true; + + return false; +} + static void logical_ring_setup(struct intel_engine_cs *engine) { @@ -1731,6 +1754,8 @@ logical_ring_setup(struct intel_engine_cs *engine) /* Intentionally left blank. */ engine->buffer = NULL; + engine->csb_use_mmio = irq_handler_force_mmio(dev_priv); + fw_domains = intel_uncore_forcewake_for_reg(dev_priv, RING_ELSP(engine), FW_REG_WRITE); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 79c0021f3700..5c055b62966d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -391,6 +391,7 @@ struct intel_engine_cs { struct rb_root execlist_queue; struct rb_node *execlist_first; unsigned int fw_domains; + bool csb_use_mmio; /* Contexts are pinned whilst they are active on the GPU. The last * context executed remains active whilst the GPU is idle - the @@ -496,6 +497,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value) #define I915_GEM_HWS_SCRATCH_INDEX 0x40 #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) +#define I915_HWS_CSB_BUF0_INDEX 0x10 + struct intel_ring * intel_engine_create_ring(struct intel_engine_cs *engine, int size); int intel_ring_pin(struct intel_ring *ring, -- cgit v1.2.3 From 767a983ab25564e8fcc84fa203d1c51d2e50c6ef Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Sep 2017 09:56:05 +0100 Subject: drm/i915/execlists: Read the context-status HEAD from the HWSP The engine also provides a mirror of the CSB write pointer in the HWSP, but not of our read pointer. To take advantage of this we need to remember where we read up to on the last interrupt and continue off from there. This poses a problem following a reset, as we don't know where the hw will start writing from, and due to the use of power contexts we cannot perform that query during the reset itself. So we continue the current modus operandi of delaying the first read of the context-status read/write pointers until after the first interrupt. With this we should now have eliminated all uncached mmio reads in handling the context-status interrupt, though we still have the uncached mmio writes for submitting new work, and many uncached mmio reads in the global interrupt handler itself. Still a step in the right direction towards reducing our resubmit latency, although it appears lost in the noise! v2: Cannonlake moved the CSB write index v3: Include the sw/hwsp state in debugfs/i915_engine_info v4: Also revert to using CSB mmio for GVT-g v5: Prevent the compiler reloading tail (Mika) Signed-off-by: Chris Wilson Cc: Michel Thierry Cc: Tvrtko Ursulin Cc: Mika Kuoppala Cc: Daniele Ceraolo Spurio Cc: Zhenyu Wang Cc: Zhi Wang Acked-by: Michel Thierry Link: https://patchwork.freedesktop.org/patch/msgid/20170913085605.18299-6-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++-- drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++ drivers/gpu/drm/i915/intel_lrc.c | 27 ++++++++++++++++++++------- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +++ 4 files changed, 35 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 7062cde94a49..12381045ed6a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3326,8 +3326,10 @@ static int i915_engine_info(struct seq_file *m, void *unused) ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine)); read = GEN8_CSB_READ_PTR(ptr); write = GEN8_CSB_WRITE_PTR(ptr); - seq_printf(m, "\tExeclist CSB read %d, write %d, interrupt posted? %s\n", - read, write, + seq_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s\n", + read, engine->csb_head, + write, + intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)), yesno(test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))); if (read >= GEN8_CSB_ENTRIES) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9dba1b2e8019..b657df74c92c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -4400,4 +4400,12 @@ int remap_io_mapping(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, struct io_mapping *iomap); +static inline int intel_hws_csb_write_index(struct drm_i915_private *i915) +{ + if (INTEL_GEN(i915) >= 10) + return CNL_HWS_CSB_WRITE_INDEX; + else + return I915_HWS_CSB_WRITE_INDEX; +} + #endif diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6d7bbb9e769a..1960ba5ff9e4 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -539,8 +539,6 @@ static void intel_lrc_irq_handler(unsigned long data) * new request (outside of the context-switch interrupt). */ while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { - u32 __iomem *csb_mmio = - dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)); /* The HWSP contains a (cacheable) mirror of the CSB */ const u32 *buf = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; @@ -550,6 +548,7 @@ static void intel_lrc_irq_handler(unsigned long data) if (unlikely(engine->csb_use_mmio)) { buf = (u32 * __force) (dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); + engine->csb_head = -1; /* force mmio read of CSB ptrs */ } /* The write will be ordered by the uncached read (itself @@ -563,9 +562,19 @@ static void intel_lrc_irq_handler(unsigned long data) * is set and we do a new loop. */ __clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - head = readl(csb_mmio); - tail = GEN8_CSB_WRITE_PTR(head); - head = GEN8_CSB_READ_PTR(head); + if (unlikely(engine->csb_head == -1)) { /* following a reset */ + head = readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); + tail = GEN8_CSB_WRITE_PTR(head); + head = GEN8_CSB_READ_PTR(head); + engine->csb_head = head; + } else { + const int write_idx = + intel_hws_csb_write_index(dev_priv) - + I915_HWS_CSB_BUF0_INDEX; + + head = engine->csb_head; + tail = READ_ONCE(buf[write_idx]); + } while (head != tail) { struct drm_i915_gem_request *rq; unsigned int status; @@ -619,8 +628,11 @@ static void intel_lrc_irq_handler(unsigned long data) !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); } - writel(_MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, head << 8), - csb_mmio); + if (head != engine->csb_head) { + engine->csb_head = head; + writel(_MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, head << 8), + dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); + } } if (execlists_elsp_ready(engine)) @@ -1269,6 +1281,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]), GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift); clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); + engine->csb_head = -1; /* After a GPU reset, we may have requests to replay */ submit = false; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 5c055b62966d..abf171c3cb9c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -391,6 +391,7 @@ struct intel_engine_cs { struct rb_root execlist_queue; struct rb_node *execlist_first; unsigned int fw_domains; + unsigned int csb_head; bool csb_use_mmio; /* Contexts are pinned whilst they are active on the GPU. The last @@ -498,6 +499,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value) #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) #define I915_HWS_CSB_BUF0_INDEX 0x10 +#define I915_HWS_CSB_WRITE_INDEX 0x1f +#define CNL_HWS_CSB_WRITE_INDEX 0x2f struct intel_ring * intel_engine_create_ring(struct intel_engine_cs *engine, int size); -- cgit v1.2.3 From 747e1f60470b975363cbbfcde0c41a3166391be5 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 13 Sep 2017 18:21:38 +0200 Subject: spi: armada-3700: Fix failing commands with quad-SPI A3700 SPI controller datasheet states that only the first line (IO0) is used to receive and send instructions, addresses and dummy bytes, unless for addresses during an RX operation in a quad SPI configuration (see p.821 of the Armada-3720-DB datasheet). Otherwise, some commands such as SPI NOR commands like READ_FROM_CACHE_DUAL_IO(0xeb) and READ_FROM_CACHE_DUAL_IO(0xbb) will fail because these commands must send address bytes through the four pins. Data transfer always use the four bytes with this setup. Thus, in quad SPI configuration, the A3700_SPI_ADDR_PIN bit must be set only in this case to inform the controller that it must use the number of pins indicated in the {A3700_SPI_DATA_PIN1,A3700_SPI_DATA_PIN0} field during the address cycles of an RX operation. Suggested-by: Ken Ma Signed-off-by: Miquel Raynal Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-armada-3700.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index 6c7d7a460689..a28702b1fa05 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -161,7 +161,7 @@ static void a3700_spi_deactivate_cs(struct a3700_spi *a3700_spi, } static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, - unsigned int pin_mode) + unsigned int pin_mode, bool receiving) { u32 val; @@ -177,6 +177,9 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, break; case SPI_NBITS_QUAD: val |= A3700_SPI_DATA_PIN1; + /* RX during address reception uses 4-pin */ + if (receiving) + val |= A3700_SPI_ADDR_PIN; break; default: dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode); @@ -653,7 +656,7 @@ static int a3700_spi_transfer_one(struct spi_master *master, else if (xfer->rx_buf) nbits = xfer->rx_nbits; - a3700_spi_pin_mode_set(a3700_spi, nbits); + a3700_spi_pin_mode_set(a3700_spi, nbits, xfer->rx_buf ? true : false); if (xfer->rx_buf) { /* Set read data length */ -- cgit v1.2.3 From 6fd6fd68c9e2f3a206a098ef57b1d5548f9d00d1 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Wed, 13 Sep 2017 18:21:39 +0200 Subject: spi: armada-3700: Fix padding when sending not 4-byte aligned data In 4-byte transfer mode, extra padding/dummy bytes '0xff' would be sent in write operation if TX data is not 4-byte aligned since the SPI data register is always shifted out as whole 4 bytes. Fix this by using the header count feature that allows to transfer 0 to 4 bytes. Use it to actually send the first 1 to 3 bytes of data before the rest of the buffer that will hence be 4-byte aligned. Signed-off-by: Zachary Zhang Signed-off-by: Miquel Raynal Signed-off-by: Mark Brown --- drivers/spi/spi-armada-3700.c | 135 +++++++++++++----------------------------- 1 file changed, 41 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index a28702b1fa05..9172cb2d2e7a 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -99,11 +99,6 @@ /* A3700_SPI_IF_TIME_REG */ #define A3700_SPI_CLK_CAPT_EDGE BIT(7) -/* Flags and macros for struct a3700_spi */ -#define A3700_INSTR_CNT 1 -#define A3700_ADDR_CNT 3 -#define A3700_DUMMY_CNT 1 - struct a3700_spi { struct spi_master *master; void __iomem *base; @@ -117,9 +112,6 @@ struct a3700_spi { u8 byte_len; u32 wait_mask; struct completion done; - u32 addr_cnt; - u32 instr_cnt; - size_t hdr_cnt; }; static u32 spireg_read(struct a3700_spi *a3700_spi, u32 offset) @@ -449,59 +441,43 @@ static void a3700_spi_set_cs(struct spi_device *spi, bool enable) static void a3700_spi_header_set(struct a3700_spi *a3700_spi) { - u32 instr_cnt = 0, addr_cnt = 0, dummy_cnt = 0; + unsigned int addr_cnt; u32 val = 0; /* Clear the header registers */ spireg_write(a3700_spi, A3700_SPI_IF_INST_REG, 0); spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, 0); spireg_write(a3700_spi, A3700_SPI_IF_RMODE_REG, 0); + spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0); /* Set header counters */ if (a3700_spi->tx_buf) { - if (a3700_spi->buf_len <= a3700_spi->instr_cnt) { - instr_cnt = a3700_spi->buf_len; - } else if (a3700_spi->buf_len <= (a3700_spi->instr_cnt + - a3700_spi->addr_cnt)) { - instr_cnt = a3700_spi->instr_cnt; - addr_cnt = a3700_spi->buf_len - instr_cnt; - } else if (a3700_spi->buf_len <= a3700_spi->hdr_cnt) { - instr_cnt = a3700_spi->instr_cnt; - addr_cnt = a3700_spi->addr_cnt; - /* Need to handle the normal write case with 1 byte - * data - */ - if (!a3700_spi->tx_buf[instr_cnt + addr_cnt]) - dummy_cnt = a3700_spi->buf_len - instr_cnt - - addr_cnt; + /* + * when tx data is not 4 bytes aligned, there will be unexpected + * bytes out of SPI output register, since it always shifts out + * as whole 4 bytes. This might cause incorrect transaction with + * some devices. To avoid that, use SPI header count feature to + * transfer up to 3 bytes of data first, and then make the rest + * of data 4-byte aligned. + */ + addr_cnt = a3700_spi->buf_len % 4; + if (addr_cnt) { + val = (addr_cnt & A3700_SPI_ADDR_CNT_MASK) + << A3700_SPI_ADDR_CNT_BIT; + spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, val); + + /* Update the buffer length to be transferred */ + a3700_spi->buf_len -= addr_cnt; + + /* transfer 1~3 bytes through address count */ + val = 0; + while (addr_cnt--) { + val = (val << 8) | a3700_spi->tx_buf[0]; + a3700_spi->tx_buf++; + } + spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, val); } - val |= ((instr_cnt & A3700_SPI_INSTR_CNT_MASK) - << A3700_SPI_INSTR_CNT_BIT); - val |= ((addr_cnt & A3700_SPI_ADDR_CNT_MASK) - << A3700_SPI_ADDR_CNT_BIT); - val |= ((dummy_cnt & A3700_SPI_DUMMY_CNT_MASK) - << A3700_SPI_DUMMY_CNT_BIT); } - spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, val); - - /* Update the buffer length to be transferred */ - a3700_spi->buf_len -= (instr_cnt + addr_cnt + dummy_cnt); - - /* Set Instruction */ - val = 0; - while (instr_cnt--) { - val = (val << 8) | a3700_spi->tx_buf[0]; - a3700_spi->tx_buf++; - } - spireg_write(a3700_spi, A3700_SPI_IF_INST_REG, val); - - /* Set Address */ - val = 0; - while (addr_cnt--) { - val = (val << 8) | a3700_spi->tx_buf[0]; - a3700_spi->tx_buf++; - } - spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, val); } static int a3700_is_wfifo_full(struct a3700_spi *a3700_spi) @@ -515,35 +491,12 @@ static int a3700_is_wfifo_full(struct a3700_spi *a3700_spi) static int a3700_spi_fifo_write(struct a3700_spi *a3700_spi) { u32 val; - int i = 0; while (!a3700_is_wfifo_full(a3700_spi) && a3700_spi->buf_len) { - val = 0; - if (a3700_spi->buf_len >= 4) { - val = cpu_to_le32(*(u32 *)a3700_spi->tx_buf); - spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, val); - - a3700_spi->buf_len -= 4; - a3700_spi->tx_buf += 4; - } else { - /* - * If the remained buffer length is less than 4-bytes, - * we should pad the write buffer with all ones. So that - * it avoids overwrite the unexpected bytes following - * the last one. - */ - val = GENMASK(31, 0); - while (a3700_spi->buf_len) { - val &= ~(0xff << (8 * i)); - val |= *a3700_spi->tx_buf++ << (8 * i); - i++; - a3700_spi->buf_len--; - - spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, - val); - } - break; - } + val = cpu_to_le32(*(u32 *)a3700_spi->tx_buf); + spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, val); + a3700_spi->buf_len -= 4; + a3700_spi->tx_buf += 4; } return 0; @@ -648,9 +601,6 @@ static int a3700_spi_transfer_one(struct spi_master *master, a3700_spi->rx_buf = xfer->rx_buf; a3700_spi->buf_len = xfer->len; - /* SPI transfer headers */ - a3700_spi_header_set(a3700_spi); - if (xfer->tx_buf) nbits = xfer->tx_nbits; else if (xfer->rx_buf) @@ -658,6 +608,12 @@ static int a3700_spi_transfer_one(struct spi_master *master, a3700_spi_pin_mode_set(a3700_spi, nbits, xfer->rx_buf ? true : false); + /* Flush the FIFOs */ + a3700_spi_fifo_flush(a3700_spi); + + /* Transfer first bytes of data when buffer is not 4-byte aligned */ + a3700_spi_header_set(a3700_spi); + if (xfer->rx_buf) { /* Set read data length */ spireg_write(a3700_spi, A3700_SPI_IF_DIN_CNT_REG, @@ -736,16 +692,11 @@ static int a3700_spi_transfer_one(struct spi_master *master, dev_err(&spi->dev, "wait wfifo empty timed out\n"); return -ETIMEDOUT; } - } else { - /* - * If the instruction in SPI_INSTR does not require data - * to be written to the SPI device, wait until SPI_RDY - * is 1 for the SPI interface to be in idle. - */ - if (!a3700_spi_transfer_wait(spi, A3700_SPI_XFER_RDY)) { - dev_err(&spi->dev, "wait xfer ready timed out\n"); - return -ETIMEDOUT; - } + } + + if (!a3700_spi_transfer_wait(spi, A3700_SPI_XFER_RDY)) { + dev_err(&spi->dev, "wait xfer ready timed out\n"); + return -ETIMEDOUT; } val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); @@ -837,10 +788,6 @@ static int a3700_spi_probe(struct platform_device *pdev) memset(spi, 0, sizeof(struct a3700_spi)); spi->master = master; - spi->instr_cnt = A3700_INSTR_CNT; - spi->addr_cnt = A3700_ADDR_CNT; - spi->hdr_cnt = A3700_INSTR_CNT + A3700_ADDR_CNT + - A3700_DUMMY_CNT; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); spi->base = devm_ioremap_resource(dev, res); -- cgit v1.2.3 From 8b5d729a3a8a07fe273af266e90bc52114dd69a6 Mon Sep 17 00:00:00 2001 From: Christos Gkekas Date: Sun, 10 Sep 2017 14:55:29 +0100 Subject: spi: stm32: Fix logical error in stm32_spi_prepare_mbr() stm32_spi_prepare_mbr() is returning an error value when div is less than SPI_MBR_DIV_MIN *and* greater than SPI_MBR_DIV_MAX, which always evaluates to false. This should change to use *or*. Signed-off-by: Christos Gkekas Signed-off-by: Mark Brown --- drivers/spi/spi-stm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index 680cdf549506..ba9743fa2326 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -263,8 +263,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz) * no need to check it there. * However, we need to ensure the following calculations. */ - if ((div < SPI_MBR_DIV_MIN) && - (div > SPI_MBR_DIV_MAX)) + if (div < SPI_MBR_DIV_MIN || + div > SPI_MBR_DIV_MAX) return -EINVAL; /* Determine the first power of 2 greater than or equal to div */ -- cgit v1.2.3 From 0d0c279405ec8eb1171c5de1bc4256bb803df77f Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 12 Sep 2017 11:30:59 -0700 Subject: drm/i915: Refresh VLV/CHV PSR comments on HW PSR_state machine. DK had pointed out a comment there was hard to understand, so I tried to read back again and I couldn't understand that as well. So let me re-phrase that in a way that anyone can understand later, even myself. Also fixed the comment block style. v2: Accept DK's suggestion on PSR_state 2 and PSR_state 3 named as spec. Cc: Dhinakaran Pandiyan Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170912183059.5086-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index fdd9e3d95efb..55b4002bbe53 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -234,7 +234,7 @@ static void vlv_psr_enable_source(struct intel_dp *intel_dp, struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); - /* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */ + /* Transition from PSR_state 0 (disabled) to PSR_state 1 (inactive) */ I915_WRITE(VLV_PSRCTL(crtc->pipe), VLV_EDP_PSR_MODE_SW_TIMER | VLV_EDP_PSR_SRC_TRANSMITTER_STATE | @@ -249,10 +249,11 @@ static void vlv_psr_activate(struct intel_dp *intel_dp) struct drm_crtc *crtc = dig_port->base.base.crtc; enum pipe pipe = to_intel_crtc(crtc)->pipe; - /* Let's do the transition from PSR_state 1 to PSR_state 2 - * that is PSR transition to active - static frame transmission. - * Then Hardware is responsible for the transition to PSR_state 3 - * that is PSR active - no Remote Frame Buffer (RFB) update. + /* + * Let's do the transition from PSR_state 1 (inactive) to + * PSR_state 2 (transition to active - static frame transmission). + * Then Hardware is responsible for the transition to + * PSR_state 3 (active - no Remote Frame Buffer (RFB) update). */ I915_WRITE(VLV_PSRCTL(pipe), I915_READ(VLV_PSRCTL(pipe)) | VLV_EDP_PSR_ACTIVE_ENTRY); @@ -576,7 +577,7 @@ static void vlv_psr_disable(struct intel_dp *intel_dp, uint32_t val; if (dev_priv->psr.active) { - /* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */ + /* Put VLV PSR back to PSR_state 0 (disabled). */ if (intel_wait_for_register(dev_priv, VLV_PSRSTAT(crtc->pipe), VLV_EDP_PSR_IN_TRANS, @@ -766,16 +767,20 @@ static void intel_psr_exit(struct drm_i915_private *dev_priv) } else { val = I915_READ(VLV_PSRCTL(pipe)); - /* Here we do the transition from PSR_state 3 to PSR_state 5 - * directly once PSR State 4 that is active with single frame - * update can be skipped. PSR_state 5 that is PSR exit then - * Hardware is responsible to transition back to PSR_state 1 - * that is PSR inactive. Same state after vlv_psr_enable_source. + /* + * Here we do the transition drirectly from + * PSR_state 3 (active - no Remote Frame Buffer (RFB) update) to + * PSR_state 5 (exit). + * PSR State 4 (active with single frame update) can be skipped. + * On PSR_state 5 (exit) Hardware is responsible to transition + * back to PSR_state 1 (inactive). + * Now we are at Same state after vlv_psr_enable_source. */ val &= ~VLV_EDP_PSR_ACTIVE_ENTRY; I915_WRITE(VLV_PSRCTL(pipe), val); - /* Send AUX wake up - Spec says after transitioning to PSR + /* + * Send AUX wake up - Spec says after transitioning to PSR * active we have to send AUX wake up by writing 01h in DPCD * 600h of sink device. * XXX: This might slow down the transition, but without this -- cgit v1.2.3 From 993f0d93f8538c15bd5c12a1a9fd74c777efea1b Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Thu, 7 Sep 2017 17:44:12 -0700 Subject: HID: wacom: generic: Send MSC_SERIAL and ABS_MISC when leaving prox The latest generation of pro devices (MobileStudio Pro, 2nd-gen Intuos Pro, Cintiq Pro) send a serial number of '0' whenever the pen is too far away for reliable communication. Userspace defines that a serial number of '0' is invalid, so we need to be careful not to actually forward this value. Additionally, since EMR ISDv4 devices do not support serial numbers or tool IDs, we'd like to not send these events if they aren't necessary. The existing code achieves these goals by adding a check for a non-zero serial number within the wacom_wac_pen_report function. The MSC_SERIAL and ABS_MISC events are only sent if the serial number is non-zero. This code fails, however when the pen for a pro device leaves proximity. When the pen leaves prox and the tablet sends a serial of 0, wacom_wac_pen_event dutifully clears the serial number. When wacom_wac_pen_report is called, it does not send either the MSC_SERIAL of the exiting tool nor an ABS_MISC event. This patch prevents the wacom_wac_pen_event function from clearing an already-set serial number. This ensures that we have the serial number handy when exiting proximity, but requires us to manually clear it afterwards to ensure the driver does not send stale data (e.g. when switching between AES pens that report a serial nubmer of 0 for the first few fully in-proximity packets). Fixes: f85c9dc678 ("HID: wacom: generic: Support tool ID and additional tool types") Cc: stable # v4.10 Signed-off-by: Ping Cheng Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 78d0398904dc..e2ba36da6e20 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2141,8 +2141,10 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field wacom_wac->hid_data.tipswitch |= value; return; case HID_DG_TOOLSERIALNUMBER: - wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); - wacom_wac->serial[0] |= (__u32)value; + if (value) { + wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); + wacom_wac->serial[0] |= (__u32)value; + } return; case HID_DG_TWIST: /* @@ -2156,15 +2158,17 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field wacom_wac->hid_data.sense_state = value; return; case WACOM_HID_WD_SERIALHI: - wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); - wacom_wac->serial[0] |= ((__u64)value) << 32; - /* - * Non-USI EMR devices may contain additional tool type - * information here. See WACOM_HID_WD_TOOLTYPE case for - * more details. - */ - if (value >> 20 == 1) { - wacom_wac->id[0] |= value & 0xFFFFF; + if (value) { + wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); + wacom_wac->serial[0] |= ((__u64)value) << 32; + /* + * Non-USI EMR devices may contain additional tool type + * information here. See WACOM_HID_WD_TOOLTYPE case for + * more details. + */ + if (value >> 20 == 1) { + wacom_wac->id[0] |= value & 0xFFFFF; + } } return; case WACOM_HID_WD_TOOLTYPE: @@ -2279,6 +2283,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, if (!prox) { wacom_wac->tool[0] = 0; wacom_wac->id[0] = 0; + wacom_wac->serial[0] = 0; } } -- cgit v1.2.3 From 92380b572d95caf48f8424746aeee63c5a2b1922 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Thu, 7 Sep 2017 17:47:38 -0700 Subject: HID: wacom: generic: Clear ABS_MISC when tool leaves proximity The tool ID information sent in ABS_MISC is expected to be reset to 0 when a tool leaves proximity. Not doing this can cause problems if a tool is removed and then re-introduced. Kernel event filtering will prevent the (identical) ABS_MISC event from being sent when the tool re-enters proxmity. This can cause userspace to not properly set the tool ID. Fixes: f85c9dc678 ("HID: wacom: generic: Support tool ID and additional tool types") Cc: stable # v4.10 Signed-off-by: Ping Cheng Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index e2ba36da6e20..aa692e28b2cd 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2272,7 +2272,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, input_report_key(input, wacom_wac->tool[0], prox); if (wacom_wac->serial[0]) { input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); - input_report_abs(input, ABS_MISC, id); + input_report_abs(input, ABS_MISC, prox ? id : 0); } wacom_wac->hid_data.tipswitch = false; -- cgit v1.2.3 From fe52e597fdbfd1098d47bdf314a1974dac003227 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Wed, 13 Sep 2017 14:52:54 +0300 Subject: drm/i915: Introduce INTEL_GEN_MASK Split INTEL_GEN_MASK out of IS_GEN macro, and make it usable within static declarations (unlike compound statements). v2: - s/combound/compound/ (Tvrtko) - Fix whitespace (yes, we need automatic checkpatch.pl) Signed-off-by: Joonas Lahtinen Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: Jani Nikula Reviewed-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170913115255.13851-1-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b657df74c92c..2e1498cae893 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2881,23 +2881,21 @@ intel_info(const struct drm_i915_private *dev_priv) #define INTEL_REVID(dev_priv) ((dev_priv)->drm.pdev->revision) #define GEN_FOREVER (0) + +#define INTEL_GEN_MASK(s, e) ( \ + BUILD_BUG_ON_ZERO(!__builtin_constant_p(s)) + \ + BUILD_BUG_ON_ZERO(!__builtin_constant_p(e)) + \ + GENMASK((e) != GEN_FOREVER ? (e) - 1 : BITS_PER_LONG - 1, \ + (s) != GEN_FOREVER ? (s) - 1 : 0) \ +) + /* * Returns true if Gen is in inclusive range [Start, End]. * * Use GEN_FOREVER for unbound start and or end. */ -#define IS_GEN(dev_priv, s, e) ({ \ - unsigned int __s = (s), __e = (e); \ - BUILD_BUG_ON(!__builtin_constant_p(s)); \ - BUILD_BUG_ON(!__builtin_constant_p(e)); \ - if ((__s) != GEN_FOREVER) \ - __s = (s) - 1; \ - if ((__e) == GEN_FOREVER) \ - __e = BITS_PER_LONG - 1; \ - else \ - __e = (e) - 1; \ - !!((dev_priv)->info.gen_mask & GENMASK((__e), (__s))); \ -}) +#define IS_GEN(dev_priv, s, e) \ + (!!((dev_priv)->info.gen_mask & INTEL_GEN_MASK((s), (e)))) /* * Return true if revision is in range [since,until] inclusive. -- cgit v1.2.3 From 3fd3a6ffe279827543cbf4063e307ed18bad6763 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Wed, 13 Sep 2017 14:52:55 +0300 Subject: drm/i915: Simplify i915_reg_read_ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert to use the freshly available made INTEL_GEN_MASK for easier grepping and improve function readability and clarify the UABI documentation. No functional changes. v2: - Lift GEM_BUG_ONs and use is_power_of_2 (Chris) - Retain -EINVAL on bad flags behavior (Chris) v3: - Extract flags with 'entry->size - 1' (Chris) v4: - Add GEM_BUG_ON on for flags vs entry offset (Chris) v5: - Use 'u16' to match 'dev_priv' (Ville) v6: - Fix checkpatch.pl errors Signed-off-by: Joonas Lahtinen Cc: Tvrtko Ursulin Cc: Chris Wilson Cc: Ville Syrjälä Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170913115255.13851-2-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 95 +++++++++++++++++-------------------- include/uapi/drm/i915_drm.h | 6 ++- 2 files changed, 48 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 1b38eb94d461..97525de2cee4 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1292,72 +1292,65 @@ void intel_uncore_fini(struct drm_i915_private *dev_priv) intel_uncore_forcewake_reset(dev_priv, false); } -#define GEN_RANGE(l, h) GENMASK((h) - 1, (l) - 1) - -static const struct register_whitelist { - i915_reg_t offset_ldw, offset_udw; - uint32_t size; - /* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */ - uint32_t gen_bitmask; -} whitelist[] = { - { .offset_ldw = RING_TIMESTAMP(RENDER_RING_BASE), - .offset_udw = RING_TIMESTAMP_UDW(RENDER_RING_BASE), - .size = 8, .gen_bitmask = GEN_RANGE(4, 10) }, -}; +static const struct reg_whitelist { + i915_reg_t offset_ldw; + i915_reg_t offset_udw; + u16 gen_mask; + u8 size; +} reg_read_whitelist[] = { { + .offset_ldw = RING_TIMESTAMP(RENDER_RING_BASE), + .offset_udw = RING_TIMESTAMP_UDW(RENDER_RING_BASE), + .gen_mask = INTEL_GEN_MASK(4, 10), + .size = 8 +} }; int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_reg_read *reg = data; - struct register_whitelist const *entry = whitelist; - unsigned size; - i915_reg_t offset_ldw, offset_udw; - int i, ret = 0; - - for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { - if (i915_mmio_reg_offset(entry->offset_ldw) == (reg->offset & -entry->size) && - (INTEL_INFO(dev_priv)->gen_mask & entry->gen_bitmask)) + struct reg_whitelist const *entry; + unsigned int flags; + int remain; + int ret = 0; + + entry = reg_read_whitelist; + remain = ARRAY_SIZE(reg_read_whitelist); + while (remain) { + u32 entry_offset = i915_mmio_reg_offset(entry->offset_ldw); + + GEM_BUG_ON(!is_power_of_2(entry->size)); + GEM_BUG_ON(entry->size > 8); + GEM_BUG_ON(entry_offset & (entry->size - 1)); + + if (INTEL_INFO(dev_priv)->gen_mask & entry->gen_mask && + entry_offset == (reg->offset & -entry->size)) break; + entry++; + remain--; } - if (i == ARRAY_SIZE(whitelist)) + if (!remain) return -EINVAL; - /* We use the low bits to encode extra flags as the register should - * be naturally aligned (and those that are not so aligned merely - * limit the available flags for that register). - */ - offset_ldw = entry->offset_ldw; - offset_udw = entry->offset_udw; - size = entry->size; - size |= reg->offset ^ i915_mmio_reg_offset(offset_ldw); + flags = reg->offset & (entry->size - 1); intel_runtime_pm_get(dev_priv); - - switch (size) { - case 8 | 1: - reg->val = I915_READ64_2x32(offset_ldw, offset_udw); - break; - case 8: - reg->val = I915_READ64(offset_ldw); - break; - case 4: - reg->val = I915_READ(offset_ldw); - break; - case 2: - reg->val = I915_READ16(offset_ldw); - break; - case 1: - reg->val = I915_READ8(offset_ldw); - break; - default: + if (entry->size == 8 && flags == I915_REG_READ_8B_WA) + reg->val = I915_READ64_2x32(entry->offset_ldw, + entry->offset_udw); + else if (entry->size == 8 && flags == 0) + reg->val = I915_READ64(entry->offset_ldw); + else if (entry->size == 4 && flags == 0) + reg->val = I915_READ(entry->offset_ldw); + else if (entry->size == 2 && flags == 0) + reg->val = I915_READ16(entry->offset_ldw); + else if (entry->size == 1 && flags == 0) + reg->val = I915_READ8(entry->offset_ldw); + else ret = -EINVAL; - goto out; - } - -out: intel_runtime_pm_put(dev_priv); + return ret; } diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index d8d10d932759..b4505d55990d 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -1308,14 +1308,16 @@ struct drm_i915_reg_read { * be specified */ __u64 offset; +#define I915_REG_READ_8B_WA BIT(0) + __u64 val; /* Return value */ }; /* Known registers: * * Render engine timestamp - 0x2358 + 64bit - gen7+ * - Note this register returns an invalid value if using the default - * single instruction 8byte read, in order to workaround that use - * offset (0x2538 | 1) instead. + * single instruction 8byte read, in order to workaround that pass + * flag I915_REG_READ_8B_WA in offset field. * */ -- cgit v1.2.3 From 93564044fb2c938e8ee4a91323157ded28072972 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 24 Aug 2017 22:10:51 +0300 Subject: drm/i915: Switch over to the LLC/eLLC hotspot avoidance hash mode for CCS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the LLC/eLLC hotspot avoidance mode for CCS on LLC machines. This is reported to give better performance. Testing has indicated that we don't need to enforce any massive 2 or 4 MiB alignment for all compressed resources even though there are still plenty of stale comments in the spec suggesting that we do. We do need to make sure every hardware unit that deals with the compressed data uses the same hash mode. Cc: Ben Widawsky Cc: Jason Ekstrand Cc: Daniel Stone Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170824191100.10949-4-ville.syrjala@linux.intel.com Reviewed-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_reg.h | 8 +++++++- drivers/gpu/drm/i915/intel_engine_cs.c | 13 +++++++++++++ drivers/gpu/drm/i915/intel_pm.c | 27 +++++++++++++-------------- 3 files changed, 33 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9f03cd063afe..0befefec7327 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6913,7 +6913,7 @@ enum { # define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2) #define CHICKEN_PAR1_1 _MMIO(0x42080) -#define SKL_RC_HASH_OUTSIDE (1 << 15) +#define SKL_DE_COMPRESSED_HASH_MODE (1 << 15) #define DPA_MASK_VBLANK_SRD (1 << 15) #define FORCE_ARB_IDLE_PLANES (1 << 14) #define SKL_EDP_PSR_FIX_RDWRAP (1 << 3) @@ -6991,6 +6991,7 @@ enum { # define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) # define GEN9_RHWO_OPTIMIZATION_DISABLE (1<<14) #define COMMON_SLICE_CHICKEN2 _MMIO(0x7014) +# define GEN9_PBE_COMPRESSED_HASH_SELECTION (1<<13) # define GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE (1<<12) # define GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION (1<<8) # define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1<<0) @@ -8085,6 +8086,7 @@ enum { #define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) #define GEN9_HALF_SLICE_CHICKEN7 _MMIO(0xe194) +#define GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR (1<<8) #define GEN9_ENABLE_YV12_BUGFIX (1<<4) #define GEN9_ENABLE_GPGPU_PREEMPTION (1<<2) @@ -9385,4 +9387,8 @@ enum skl_power_gate { #define GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL 0x67F1427F /* " " */ #define GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT 0x5FF101FF /* " " */ +#define MMCD_MISC_CTRL _MMIO(0x4ddc) /* skl+ */ +#define MMCD_PCLA (1 << 31) +#define MMCD_HOTSPOT_EN (1 << 27) + #endif /* _I915_REG_H_ */ diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 32d35f32d289..3d135c3cd380 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -938,6 +938,19 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | ECOCHK_DIS_TLB); + if (HAS_LLC(dev_priv)) { + /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl + * + * Must match Display Engine. See + * WaCompressedResourceDisplayNewHashMode. + */ + WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, + GEN9_PBE_COMPRESSED_HASH_SELECTION); + WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, + GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR); + WA_SET_BIT(MMCD_MISC_CTRL, MMCD_PCLA | MMCD_HOTSPOT_EN); + } + /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */ /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */ WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index fa9055a4f790..94624ede3479 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -58,24 +58,23 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) { + if (HAS_LLC(dev_priv)) { + /* + * WaCompressedResourceDisplayNewHashMode:skl,kbl + * Display WA#0390: skl,kbl + * + * Must match Sampler, Pixel Back End, and Media. See + * WaCompressedResourceSamplerPbeMediaNewHashMode. + */ + I915_WRITE(CHICKEN_PAR1_1, + I915_READ(CHICKEN_PAR1_1) | + SKL_DE_COMPRESSED_HASH_MODE); + } + /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ I915_WRITE(CHICKEN_PAR1_1, I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); - /* - * Display WA#0390: skl,bxt,kbl,glk - * - * Must match Sampler, Pixel Back End, and Media - * (0xE194 bit 8, 0x7014 bit 13, 0x4DDC bits 27 and 31). - * - * Including bits outside the page in the hash would - * require 2 (or 4?) MiB alignment of resources. Just - * assume the defaul hashing mode which only uses bits - * within the page. - */ - I915_WRITE(CHICKEN_PAR1_1, - I915_READ(CHICKEN_PAR1_1) & ~SKL_RC_HASH_OUTSIDE); - I915_WRITE(GEN8_CONFIG0, I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES); -- cgit v1.2.3 From 4395890a48551982549d222d1923e2833dac47cf Mon Sep 17 00:00:00 2001 From: Zhi Wang Date: Thu, 14 Sep 2017 20:39:40 +0800 Subject: drm/i915: Introduce private PAT management The private PAT management is to support PPAT entry manipulation. Two APIs are introduced for dynamically managing PPAT entries: intel_ppat_get and intel_ppat_put. intel_ppat_get will search for an existing PPAT entry which perfectly matches the required PPAT value. If not, it will try to allocate a new entry if there is any available PPAT indexs, or return a partially matched PPAT entry if there is no available PPAT indexes. intel_ppat_put will put back the PPAT entry which comes from intel_ppat_get. If it's dynamically allocated, the reference count will be decreased. If the reference count turns into zero, the PPAT index is freed again. Besides, another two callbacks are introduced to support the private PAT management framework. One is ppat->update_hw(), which writes the PPAT configurations in ppat->entries into HW. Another one is ppat->match, which will return a score to show how two PPAT values match with each other. v17: - Refine the comparision of score of BDW. (Joonas) v16: - Fix a bug in PPAT match function of BDW. (Joonas) v15: - Refine some code flow. (Joonas) v12: - Fix a problem "not returning the entry of best score". (Zhenyu) v7: - Keep all the register writes unchanged in this patch. (Joonas) v6: - Address all comments from Chris: http://www.spinics.net/lists/intel-gfx/msg136850.html - Address all comments from Joonas: http://www.spinics.net/lists/intel-gfx/msg136845.html v5: - Add check and warnnings for those platforms which don't have PPAT. v3: - Introduce dirty bitmap for PPAT registers. (Chris) - Change the name of the pointer "dev_priv" to "i915". (Chris) - intel_ppat_{get, put} returns/takes a const intel_ppat_entry *. (Chris) v2: - API re-design. (Chris) Signed-off-by: Zhi Wang Cc: Ben Widawsky Cc: Rodrigo Vivi Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Chris Wilson #v7 Reviewed-by: Joonas Lahtinen [Joonas: Use BIT() in the enum in bdw_private_pat_match] Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1505392783-4084-1-git-send-email-zhi.a.wang@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem_gtt.c | 285 +++++++++++++++++++++++++++++------- drivers/gpu/drm/i915/i915_gem_gtt.h | 36 +++++ 3 files changed, 274 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2e1498cae893..5d379c89722c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2355,6 +2355,8 @@ struct drm_i915_private { DECLARE_HASHTABLE(mm_structs, 7); struct mutex mm_lock; + struct intel_ppat ppat; + /* Kernel Modesetting */ struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 09e524dbc090..c7ee7d8f1b43 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2819,41 +2819,209 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size) return 0; } -static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv) +static struct intel_ppat_entry * +__alloc_ppat_entry(struct intel_ppat *ppat, unsigned int index, u8 value) { + struct intel_ppat_entry *entry = &ppat->entries[index]; + + GEM_BUG_ON(index >= ppat->max_entries); + GEM_BUG_ON(test_bit(index, ppat->used)); + + entry->ppat = ppat; + entry->value = value; + kref_init(&entry->ref); + set_bit(index, ppat->used); + set_bit(index, ppat->dirty); + + return entry; +} + +static void __free_ppat_entry(struct intel_ppat_entry *entry) +{ + struct intel_ppat *ppat = entry->ppat; + unsigned int index = entry - ppat->entries; + + GEM_BUG_ON(index >= ppat->max_entries); + GEM_BUG_ON(!test_bit(index, ppat->used)); + + entry->value = ppat->clear_value; + clear_bit(index, ppat->used); + set_bit(index, ppat->dirty); +} + +/** + * intel_ppat_get - get a usable PPAT entry + * @i915: i915 device instance + * @value: the PPAT value required by the caller + * + * The function tries to search if there is an existing PPAT entry which + * matches with the required value. If perfectly matched, the existing PPAT + * entry will be used. If only partially matched, it will try to check if + * there is any available PPAT index. If yes, it will allocate a new PPAT + * index for the required entry and update the HW. If not, the partially + * matched entry will be used. + */ +const struct intel_ppat_entry * +intel_ppat_get(struct drm_i915_private *i915, u8 value) +{ + struct intel_ppat *ppat = &i915->ppat; + struct intel_ppat_entry *entry; + unsigned int scanned, best_score; + int i; + + GEM_BUG_ON(!ppat->max_entries); + + scanned = best_score = 0; + for_each_set_bit(i, ppat->used, ppat->max_entries) { + unsigned int score; + + score = ppat->match(ppat->entries[i].value, value); + if (score > best_score) { + entry = &ppat->entries[i]; + if (score == INTEL_PPAT_PERFECT_MATCH) { + kref_get(&entry->ref); + return entry; + } + best_score = score; + } + scanned++; + } + + if (scanned == ppat->max_entries) { + if (!best_score) + return ERR_PTR(-ENOSPC); + + kref_get(&entry->ref); + return entry; + } + + i = find_first_zero_bit(ppat->used, ppat->max_entries); + entry = __alloc_ppat_entry(ppat, i, value); + ppat->update_hw(i915); + return entry; +} + +static void release_ppat(struct kref *kref) +{ + struct intel_ppat_entry *entry = + container_of(kref, struct intel_ppat_entry, ref); + struct drm_i915_private *i915 = entry->ppat->i915; + + __free_ppat_entry(entry); + entry->ppat->update_hw(i915); +} + +/** + * intel_ppat_put - put back the PPAT entry got from intel_ppat_get() + * @entry: an intel PPAT entry + * + * Put back the PPAT entry got from intel_ppat_get(). If the PPAT index of the + * entry is dynamically allocated, its reference count will be decreased. Once + * the reference count becomes into zero, the PPAT index becomes free again. + */ +void intel_ppat_put(const struct intel_ppat_entry *entry) +{ + struct intel_ppat *ppat = entry->ppat; + unsigned int index = entry - ppat->entries; + + GEM_BUG_ON(!ppat->max_entries); + + kref_put(&ppat->entries[index].ref, release_ppat); +} + +static void cnl_private_pat_update_hw(struct drm_i915_private *dev_priv) +{ + struct intel_ppat *ppat = &dev_priv->ppat; + int i; + + for_each_set_bit(i, ppat->dirty, ppat->max_entries) { + I915_WRITE(GEN10_PAT_INDEX(i), ppat->entries[i].value); + clear_bit(i, ppat->dirty); + } +} + +static void bdw_private_pat_update_hw(struct drm_i915_private *dev_priv) +{ + struct intel_ppat *ppat = &dev_priv->ppat; + u64 pat = 0; + int i; + + for (i = 0; i < ppat->max_entries; i++) + pat |= GEN8_PPAT(i, ppat->entries[i].value); + + bitmap_clear(ppat->dirty, 0, ppat->max_entries); + + I915_WRITE(GEN8_PRIVATE_PAT_LO, lower_32_bits(pat)); + I915_WRITE(GEN8_PRIVATE_PAT_HI, upper_32_bits(pat)); +} + +static unsigned int bdw_private_pat_match(u8 src, u8 dst) +{ + unsigned int score = 0; + enum { + AGE_MATCH = BIT(0), + TC_MATCH = BIT(1), + CA_MATCH = BIT(2), + }; + + /* Cache attribute has to be matched. */ + if (GEN8_PPAT_GET_CA(src) == GEN8_PPAT_GET_CA(dst)) + return 0; + + score |= CA_MATCH; + + if (GEN8_PPAT_GET_TC(src) == GEN8_PPAT_GET_TC(dst)) + score |= TC_MATCH; + + if (GEN8_PPAT_GET_AGE(src) == GEN8_PPAT_GET_AGE(dst)) + score |= AGE_MATCH; + + if (score == (AGE_MATCH | TC_MATCH | CA_MATCH)) + return INTEL_PPAT_PERFECT_MATCH; + + return score; +} + +static unsigned int chv_private_pat_match(u8 src, u8 dst) +{ + return (CHV_PPAT_GET_SNOOP(src) == CHV_PPAT_GET_SNOOP(dst)) ? + INTEL_PPAT_PERFECT_MATCH : 0; +} + +static void cnl_setup_private_ppat(struct intel_ppat *ppat) +{ + ppat->max_entries = 8; + ppat->update_hw = cnl_private_pat_update_hw; + ppat->match = bdw_private_pat_match; + ppat->clear_value = GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); + /* XXX: spec is unclear if this is still needed for CNL+ */ - if (!USES_PPGTT(dev_priv)) { - I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_UC); + if (!USES_PPGTT(ppat->i915)) { + __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC); return; } - I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_WB | GEN8_PPAT_LLC); - I915_WRITE(GEN10_PAT_INDEX(1), GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); - I915_WRITE(GEN10_PAT_INDEX(2), GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); - I915_WRITE(GEN10_PAT_INDEX(3), GEN8_PPAT_UC); - I915_WRITE(GEN10_PAT_INDEX(4), GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)); - I915_WRITE(GEN10_PAT_INDEX(5), GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)); - I915_WRITE(GEN10_PAT_INDEX(6), GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)); - I915_WRITE(GEN10_PAT_INDEX(7), GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); + __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC); + __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); + __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); + __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC); + __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)); + __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)); + __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)); + __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); } /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability * bits. When using advanced contexts each context stores its own PAT, but * writing this data shouldn't be harmful even in those cases. */ -static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv) +static void bdw_setup_private_ppat(struct intel_ppat *ppat) { - u64 pat; + ppat->max_entries = 8; + ppat->update_hw = bdw_private_pat_update_hw; + ppat->match = bdw_private_pat_match; + ppat->clear_value = GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); - pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */ - GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for something pointing to ptes? */ - GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for scanout with eLLC */ - GEN8_PPAT(3, GEN8_PPAT_UC) | /* Uncached objects, mostly for scanout */ - GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) | - GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) | - GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) | - GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); - - if (!USES_PPGTT(dev_priv)) + if (!USES_PPGTT(ppat->i915)) { /* Spec: "For GGTT, there is NO pat_sel[2:0] from the entry, * so RTL will always use the value corresponding to * pat_sel = 000". @@ -2867,17 +3035,26 @@ static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv) * So we can still hold onto all our assumptions wrt cpu * clflushing on LLC machines. */ - pat = GEN8_PPAT(0, GEN8_PPAT_UC); + __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC); + return; + } - /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b - * write would work. */ - I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); - I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); + __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC); /* for normal objects, no eLLC */ + __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); /* for something pointing to ptes? */ + __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); /* for scanout with eLLC */ + __alloc_ppat_entry(ppat, 3, GEN8_PPAT_UC); /* Uncached objects, mostly for scanout */ + __alloc_ppat_entry(ppat, 4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)); + __alloc_ppat_entry(ppat, 5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)); + __alloc_ppat_entry(ppat, 6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)); + __alloc_ppat_entry(ppat, 7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); } -static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) +static void chv_setup_private_ppat(struct intel_ppat *ppat) { - u64 pat; + ppat->max_entries = 8; + ppat->update_hw = bdw_private_pat_update_hw; + ppat->match = chv_private_pat_match; + ppat->clear_value = CHV_PPAT_SNOOP; /* * Map WB on BDW to snooped on CHV. @@ -2897,17 +3074,15 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) * Which means we must set the snoop bit in PAT entry 0 * in order to keep the global status page working. */ - pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) | - GEN8_PPAT(1, 0) | - GEN8_PPAT(2, 0) | - GEN8_PPAT(3, 0) | - GEN8_PPAT(4, CHV_PPAT_SNOOP) | - GEN8_PPAT(5, CHV_PPAT_SNOOP) | - GEN8_PPAT(6, CHV_PPAT_SNOOP) | - GEN8_PPAT(7, CHV_PPAT_SNOOP); - I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); - I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); + __alloc_ppat_entry(ppat, 0, CHV_PPAT_SNOOP); + __alloc_ppat_entry(ppat, 1, 0); + __alloc_ppat_entry(ppat, 2, 0); + __alloc_ppat_entry(ppat, 3, 0); + __alloc_ppat_entry(ppat, 4, CHV_PPAT_SNOOP); + __alloc_ppat_entry(ppat, 5, CHV_PPAT_SNOOP); + __alloc_ppat_entry(ppat, 6, CHV_PPAT_SNOOP); + __alloc_ppat_entry(ppat, 7, CHV_PPAT_SNOOP); } static void gen6_gmch_remove(struct i915_address_space *vm) @@ -2920,12 +3095,27 @@ static void gen6_gmch_remove(struct i915_address_space *vm) static void setup_private_pat(struct drm_i915_private *dev_priv) { + struct intel_ppat *ppat = &dev_priv->ppat; + int i; + + ppat->i915 = dev_priv; + if (INTEL_GEN(dev_priv) >= 10) - cnl_setup_private_ppat(dev_priv); + cnl_setup_private_ppat(ppat); else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) - chv_setup_private_ppat(dev_priv); + chv_setup_private_ppat(ppat); else - bdw_setup_private_ppat(dev_priv); + bdw_setup_private_ppat(ppat); + + GEM_BUG_ON(ppat->max_entries > INTEL_MAX_PPAT_ENTRIES); + + for_each_clear_bit(i, ppat->used, ppat->max_entries) { + ppat->entries[i].value = ppat->clear_value; + ppat->entries[i].ppat = ppat; + set_bit(i, ppat->dirty); + } + + ppat->update_hw(dev_priv); } static int gen8_gmch_probe(struct i915_ggtt *ggtt) @@ -3239,13 +3429,10 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv) ggtt->base.closed = false; if (INTEL_GEN(dev_priv) >= 8) { - if (INTEL_GEN(dev_priv) >= 10) - cnl_setup_private_ppat(dev_priv); - else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv)) - chv_setup_private_ppat(dev_priv); - else - bdw_setup_private_ppat(dev_priv); + struct intel_ppat *ppat = &dev_priv->ppat; + bitmap_set(ppat->dirty, 0, ppat->max_entries); + dev_priv->ppat.update_hw(dev_priv); return; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index d9a076a2673a..f3943b6ab30c 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -143,6 +143,11 @@ typedef u64 gen8_ppgtt_pml4e_t; #define GEN8_PPAT_ELLC_OVERRIDE (0<<2) #define GEN8_PPAT(i, x) ((u64)(x) << ((i) * 8)) +#define GEN8_PPAT_GET_CA(x) ((x) & 3) +#define GEN8_PPAT_GET_TC(x) ((x) & (3 << 2)) +#define GEN8_PPAT_GET_AGE(x) ((x) & (3 << 4)) +#define CHV_PPAT_GET_SNOOP(x) ((x) & (1 << 6)) + struct sg_table; struct intel_rotation_info { @@ -536,6 +541,37 @@ i915_vm_to_ggtt(struct i915_address_space *vm) return container_of(vm, struct i915_ggtt, base); } +#define INTEL_MAX_PPAT_ENTRIES 8 +#define INTEL_PPAT_PERFECT_MATCH (~0U) + +struct intel_ppat; + +struct intel_ppat_entry { + struct intel_ppat *ppat; + struct kref ref; + u8 value; +}; + +struct intel_ppat { + struct intel_ppat_entry entries[INTEL_MAX_PPAT_ENTRIES]; + DECLARE_BITMAP(used, INTEL_MAX_PPAT_ENTRIES); + DECLARE_BITMAP(dirty, INTEL_MAX_PPAT_ENTRIES); + unsigned int max_entries; + u8 clear_value; + /* + * Return a score to show how two PPAT values match, + * a INTEL_PPAT_PERFECT_MATCH indicates a perfect match + */ + unsigned int (*match)(u8 src, u8 dst); + void (*update_hw)(struct drm_i915_private *i915); + + struct drm_i915_private *i915; +}; + +const struct intel_ppat_entry * +intel_ppat_get(struct drm_i915_private *i915, u8 value); +void intel_ppat_put(const struct intel_ppat_entry *entry); + int i915_gem_init_aliasing_ppgtt(struct drm_i915_private *i915); void i915_gem_fini_aliasing_ppgtt(struct drm_i915_private *i915); -- cgit v1.2.3 From c095b97c1e972d67d08bb90de99118a95a6390cd Mon Sep 17 00:00:00 2001 From: Zhi Wang Date: Thu, 14 Sep 2017 20:39:41 +0800 Subject: drm/i915: Remove the "INDEX" suffix from PPAT marcos Remove the "INDEX" suffix from PPAT marcos as they are bits actually, not indexes. Suggested-by: Chris Wilson Signed-off-by: Zhi Wang Cc: Ben Widawsky Cc: Rodrigo Vivi Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1505392783-4084-2-git-send-email-zhi.a.wang@intel.com --- drivers/gpu/drm/i915/gvt/gtt.c | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 10 +++++----- drivers/gpu/drm/i915/i915_gem_gtt.h | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 0bd028f8fef5..2801d70579d8 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1971,7 +1971,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu, */ se.val64 |= _PAGE_PRESENT | _PAGE_RW; if (type == GTT_TYPE_PPGTT_PDE_PT) - se.val64 |= PPAT_CACHED_INDEX; + se.val64 |= PPAT_CACHED; for (i = 0; i < page_entry_num; i++) ops->set_entry(scratch_pt, &se, i, false, 0, vgpu); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index c7ee7d8f1b43..729ebaf29b71 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -230,13 +230,13 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr, switch (level) { case I915_CACHE_NONE: - pte |= PPAT_UNCACHED_INDEX; + pte |= PPAT_UNCACHED; break; case I915_CACHE_WT: - pte |= PPAT_DISPLAY_ELLC_INDEX; + pte |= PPAT_DISPLAY_ELLC; break; default: - pte |= PPAT_CACHED_INDEX; + pte |= PPAT_CACHED; break; } @@ -249,9 +249,9 @@ static gen8_pde_t gen8_pde_encode(const dma_addr_t addr, gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW; pde |= addr; if (level != I915_CACHE_NONE) - pde |= PPAT_CACHED_PDE_INDEX; + pde |= PPAT_CACHED_PDE; else - pde |= PPAT_UNCACHED_INDEX; + pde |= PPAT_UNCACHED; return pde; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index f3943b6ab30c..f62fb903dc24 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -126,10 +126,10 @@ typedef u64 gen8_ppgtt_pml4e_t; * tables */ #define GEN8_PDPE_MASK 0x1ff -#define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD) -#define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */ -#define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */ -#define PPAT_DISPLAY_ELLC_INDEX _PAGE_PCD /* WT eLLC */ +#define PPAT_UNCACHED (_PAGE_PWT | _PAGE_PCD) +#define PPAT_CACHED_PDE 0 /* WB LLC */ +#define PPAT_CACHED _PAGE_PAT /* WB LLCeLLC */ +#define PPAT_DISPLAY_ELLC _PAGE_PCD /* WT eLLC */ #define CHV_PPAT_SNOOP (1<<6) #define GEN8_PPAT_AGE(x) ((x)<<4) -- cgit v1.2.3 From 842ebf7aeb1d6d5d679491d33d8c3f113de7964e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:50 +0300 Subject: drm/i915: Don't enable/unmask flip interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit fd3a40242e87 ("drm/i915: Rip out legacy page_flip completion/irq handling") removed the code to hande the flip done/pending interrupts, but it failed to actually disable/mask those interrupts. Let's do that now. Also remove a stale comment that was left behind. Cc: Daniel Vetter Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-2-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_irq.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 91a2c5dbf2da..9b5be5c4bef7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2925,8 +2925,7 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) u32 enable_mask; enum pipe pipe; - pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | - PIPE_CRC_DONE_INTERRUPT_STATUS; + pipestat_mask = PIPE_CRC_DONE_INTERRUPT_STATUS; i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); for_each_pipe(dev_priv, pipe) @@ -3301,18 +3300,14 @@ static int ironlake_irq_postinstall(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 7) { display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | - DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | - DE_PLANEB_FLIP_DONE_IVB | - DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB); + DE_PCH_EVENT_IVB | DE_AUX_CHANNEL_A_IVB); extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB | DE_DP_A_HOTPLUG_IVB); } else { display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | - DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | - DE_AUX_CHANNEL_A | - DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | - DE_POISON); + DE_AUX_CHANNEL_A | DE_PIPEB_CRC_DONE | + DE_PIPEA_CRC_DONE | DE_POISON); extra_mask = (DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN | DE_DP_A_HOTPLUG); @@ -3434,15 +3429,13 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) enum pipe pipe; if (INTEL_GEN(dev_priv) >= 9) { - de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE | - GEN9_DE_PIPE_IRQ_FAULT_ERRORS; + de_pipe_masked |= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | GEN9_AUX_CHANNEL_D; if (IS_GEN9_LP(dev_priv)) de_port_masked |= BXT_DE_PORT_GMBUS; } else { - de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE | - GEN8_DE_PIPE_IRQ_FAULT_ERRORS; + de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; } de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | @@ -3592,9 +3585,7 @@ static int i8xx_irq_postinstall(struct drm_device *dev) /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | - I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT); + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); I915_WRITE16(IMR, dev_priv->irq_mask); I915_WRITE16(IER, @@ -3613,9 +3604,6 @@ static int i8xx_irq_postinstall(struct drm_device *dev) return 0; } -/* - * Returns true when a page flip has completed. - */ static irqreturn_t i8xx_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; @@ -3734,9 +3722,7 @@ static int i915_irq_postinstall(struct drm_device *dev) dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | - I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT); + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); enable_mask = I915_ASLE_INTERRUPT | @@ -3921,13 +3907,9 @@ static int i965_irq_postinstall(struct drm_device *dev) I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | - I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); enable_mask = ~dev_priv->irq_mask; - enable_mask &= ~(I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | - I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT); enable_mask |= I915_USER_INTERRUPT; if (IS_G4X(dev_priv)) -- cgit v1.2.3 From 44d9241e3e62a6938b5ae2ec6b3b4cd5abfdb717 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:51 +0300 Subject: drm/i915: Clear pipestat consistently MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have a lot of different ways of clearing the PIPESTAT registers. Let's unify it all into one function. There's no magic in PIPESTAT that would require any of the double clearing and whatnot that some of the code tries to do. All we can really do is clear the status bits and disable the enable bits. There is no way to mask anything so as soon as another event happens the status bit will become set again, and trying to clear them twice or something can't protect against that. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-3-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_irq.c | 67 ++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9b5be5c4bef7..12c5af965833 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1709,6 +1709,19 @@ static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) } } +static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) +{ + enum pipe pipe; + + for_each_pipe(dev_priv, pipe) { + I915_WRITE(PIPESTAT(pipe), + PIPESTAT_INT_STATUS_MASK | + PIPE_FIFO_UNDERRUN_STATUS); + + dev_priv->pipestat_irq_mask[pipe] = 0; + } +} + static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { @@ -2898,8 +2911,6 @@ static void gen5_gt_irq_reset(struct drm_i915_private *dev_priv) static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) { - enum pipe pipe; - if (IS_CHERRYVIEW(dev_priv)) I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK_CHV); else @@ -2908,12 +2919,7 @@ static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - for_each_pipe(dev_priv, pipe) { - I915_WRITE(PIPESTAT(pipe), - PIPE_FIFO_UNDERRUN_STATUS | - PIPESTAT_INT_STATUS_MASK); - dev_priv->pipestat_irq_mask[pipe] = 0; - } + i9xx_pipestat_irq_reset(dev_priv); GEN5_IRQ_RESET(VLV_); dev_priv->irq_mask = ~0; @@ -3566,10 +3572,9 @@ static void ironlake_irq_uninstall(struct drm_device *dev) static void i8xx_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = to_i915(dev); - int pipe; - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0); + i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE16(IMR, 0xffff); I915_WRITE16(IER, 0x0); POSTING_READ16(IER); @@ -3681,13 +3686,9 @@ out: static void i8xx_irq_uninstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = to_i915(dev); - int pipe; - for_each_pipe(dev_priv, pipe) { - /* Clear enable bits; then clear status bits */ - I915_WRITE(PIPESTAT(pipe), 0); - I915_WRITE(PIPESTAT(pipe), I915_READ(PIPESTAT(pipe))); - } + i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE16(IMR, 0xffff); I915_WRITE16(IER, 0x0); I915_WRITE16(IIR, I915_READ16(IIR)); @@ -3696,16 +3697,16 @@ static void i8xx_irq_uninstall(struct drm_device * dev) static void i915_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = to_i915(dev); - int pipe; if (I915_HAS_HOTPLUG(dev_priv)) { i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); } + i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE16(HWSTAM, 0xeffe); - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0); + I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); POSTING_READ(IER); @@ -3861,36 +3862,32 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) static void i915_irq_uninstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = to_i915(dev); - int pipe; if (I915_HAS_HOTPLUG(dev_priv)) { i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); } + i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE16(HWSTAM, 0xffff); - for_each_pipe(dev_priv, pipe) { - /* Clear enable bits; then clear status bits */ - I915_WRITE(PIPESTAT(pipe), 0); - I915_WRITE(PIPESTAT(pipe), I915_READ(PIPESTAT(pipe))); - } + I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); - I915_WRITE(IIR, I915_READ(IIR)); } static void i965_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = to_i915(dev); - int pipe; i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE(HWSTAM, 0xeffe); - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0); + I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); POSTING_READ(IER); @@ -4084,7 +4081,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) static void i965_irq_uninstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = to_i915(dev); - int pipe; if (!dev_priv) return; @@ -4092,15 +4088,12 @@ static void i965_irq_uninstall(struct drm_device * dev) i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE(HWSTAM, 0xffffffff); - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0); + I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); - - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), - I915_READ(PIPESTAT(pipe)) & 0x8000ffff); I915_WRITE(IIR, I915_READ(IIR)); } -- cgit v1.2.3 From 3488d4eb43aaf63bc4db7d878b106f73de547d7a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:52 +0300 Subject: drm/i915: s/GEN5/GEN3/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GEN5_IRQ_RESET/INIT macros are perfectly suitable even for gen3/4 hardware as those have 32 bit interrupt registers. Let's rename the macros to reflect that fact. Gen2 on the other hand has 16 bit interrupt registers so these macros aren't really appropriate there. v2: Fix patch subject (Maarten) Reviewed-by: Chris Wilson Acked-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 44 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 12c5af965833..6dba97e28347 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -126,7 +126,7 @@ static const u32 hpd_bxt[HPD_NUM_PINS] = { POSTING_READ(GEN8_##type##_IIR(which)); \ } while (0) -#define GEN5_IRQ_RESET(type) do { \ +#define GEN3_IRQ_RESET(type) do { \ I915_WRITE(type##IMR, 0xffffffff); \ POSTING_READ(type##IMR); \ I915_WRITE(type##IER, 0); \ @@ -139,7 +139,7 @@ static const u32 hpd_bxt[HPD_NUM_PINS] = { /* * We should clear IMR at preinstall/uninstall, and just check at postinstall. */ -static void gen5_assert_iir_is_zero(struct drm_i915_private *dev_priv, +static void gen3_assert_iir_is_zero(struct drm_i915_private *dev_priv, i915_reg_t reg) { u32 val = I915_READ(reg); @@ -156,14 +156,14 @@ static void gen5_assert_iir_is_zero(struct drm_i915_private *dev_priv, } #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \ - gen5_assert_iir_is_zero(dev_priv, GEN8_##type##_IIR(which)); \ + gen3_assert_iir_is_zero(dev_priv, GEN8_##type##_IIR(which)); \ I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \ I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \ POSTING_READ(GEN8_##type##_IMR(which)); \ } while (0) -#define GEN5_IRQ_INIT(type, imr_val, ier_val) do { \ - gen5_assert_iir_is_zero(dev_priv, type##IIR); \ +#define GEN3_IRQ_INIT(type, imr_val, ier_val) do { \ + gen3_assert_iir_is_zero(dev_priv, type##IIR); \ I915_WRITE(type##IER, (ier_val)); \ I915_WRITE(type##IMR, (imr_val)); \ POSTING_READ(type##IMR); \ @@ -2876,7 +2876,7 @@ static void ibx_irq_reset(struct drm_i915_private *dev_priv) if (HAS_PCH_NOP(dev_priv)) return; - GEN5_IRQ_RESET(SDE); + GEN3_IRQ_RESET(SDE); if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) I915_WRITE(SERR_INT, 0xffffffff); @@ -2904,9 +2904,9 @@ static void ibx_irq_pre_postinstall(struct drm_device *dev) static void gen5_gt_irq_reset(struct drm_i915_private *dev_priv) { - GEN5_IRQ_RESET(GT); + GEN3_IRQ_RESET(GT); if (INTEL_GEN(dev_priv) >= 6) - GEN5_IRQ_RESET(GEN6_PM); + GEN3_IRQ_RESET(GEN6_PM); } static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) @@ -2921,7 +2921,7 @@ static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) i9xx_pipestat_irq_reset(dev_priv); - GEN5_IRQ_RESET(VLV_); + GEN3_IRQ_RESET(VLV_); dev_priv->irq_mask = ~0; } @@ -2951,7 +2951,7 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->irq_mask = ~enable_mask; - GEN5_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask); + GEN3_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask); } /* drm_dma.h hooks @@ -2962,7 +2962,7 @@ static void ironlake_irq_reset(struct drm_device *dev) I915_WRITE(HWSTAM, 0xffffffff); - GEN5_IRQ_RESET(DE); + GEN3_IRQ_RESET(DE); if (IS_GEN7(dev_priv)) I915_WRITE(GEN7_ERR_INT, 0xffffffff); @@ -3009,9 +3009,9 @@ static void gen8_irq_reset(struct drm_device *dev) POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); - GEN5_IRQ_RESET(GEN8_DE_PORT_); - GEN5_IRQ_RESET(GEN8_DE_MISC_); - GEN5_IRQ_RESET(GEN8_PCU_); + GEN3_IRQ_RESET(GEN8_DE_PORT_); + GEN3_IRQ_RESET(GEN8_DE_MISC_); + GEN3_IRQ_RESET(GEN8_PCU_); if (HAS_PCH_SPLIT(dev_priv)) ibx_irq_reset(dev_priv); @@ -3054,7 +3054,7 @@ static void cherryview_irq_preinstall(struct drm_device *dev) gen8_gt_irq_reset(dev_priv); - GEN5_IRQ_RESET(GEN8_PCU_); + GEN3_IRQ_RESET(GEN8_PCU_); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) @@ -3251,7 +3251,7 @@ static void ibx_irq_postinstall(struct drm_device *dev) else mask = SDE_GMBUS_CPT; - gen5_assert_iir_is_zero(dev_priv, SDEIIR); + gen3_assert_iir_is_zero(dev_priv, SDEIIR); I915_WRITE(SDEIMR, ~mask); if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) || @@ -3282,7 +3282,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; } - GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); + GEN3_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); if (INTEL_GEN(dev_priv) >= 6) { /* @@ -3295,7 +3295,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) } dev_priv->pm_imr = 0xffffffff; - GEN5_IRQ_INIT(GEN6_PM, dev_priv->pm_imr, pm_irqs); + GEN3_IRQ_INIT(GEN6_PM, dev_priv->pm_imr, pm_irqs); } } @@ -3325,7 +3325,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) ibx_irq_pre_postinstall(dev); - GEN5_IRQ_INIT(DE, dev_priv->irq_mask, display_mask | extra_mask); + GEN3_IRQ_INIT(DE, dev_priv->irq_mask, display_mask | extra_mask); gen5_gt_irq_postinstall(dev); @@ -3464,8 +3464,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->de_irq_mask[pipe], de_pipe_enables); - GEN5_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables); - GEN5_IRQ_INIT(GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); + GEN3_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables); + GEN3_IRQ_INIT(GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); if (IS_GEN9_LP(dev_priv)) bxt_hpd_detection_setup(dev_priv); @@ -3551,7 +3551,7 @@ static void cherryview_irq_uninstall(struct drm_device *dev) gen8_gt_irq_reset(dev_priv); - GEN5_IRQ_RESET(GEN8_PCU_); + GEN3_IRQ_RESET(GEN8_PCU_); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) -- cgit v1.2.3 From ba7eb78932173ce6e315a754b7b32eb0a4f155ed Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:53 +0300 Subject: drm/i915: Use GEN3_IRQ_RESET/INIT on gen3/4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the manual IMR+IER+IIR write sequences with the appropriate GEN3_IRQ_RESET/INIT macro invocations in gen3/4. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-5-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6dba97e28347..788d37166872 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3707,9 +3707,7 @@ static void i915_irq_preinstall(struct drm_device * dev) I915_WRITE16(HWSTAM, 0xeffe); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); - POSTING_READ(IER); + GEN3_IRQ_RESET(); } static int i915_irq_postinstall(struct drm_device *dev) @@ -3741,9 +3739,7 @@ static int i915_irq_postinstall(struct drm_device *dev) dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; } - I915_WRITE(IMR, dev_priv->irq_mask); - I915_WRITE(IER, enable_mask); - POSTING_READ(IER); + GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); i915_enable_asle_pipestat(dev_priv); @@ -3872,9 +3868,7 @@ static void i915_irq_uninstall(struct drm_device * dev) I915_WRITE16(HWSTAM, 0xffff); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); - I915_WRITE(IIR, I915_READ(IIR)); + GEN3_IRQ_RESET(); } static void i965_irq_preinstall(struct drm_device * dev) @@ -3888,9 +3882,7 @@ static void i965_irq_preinstall(struct drm_device * dev) I915_WRITE(HWSTAM, 0xeffe); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); - POSTING_READ(IER); + GEN3_IRQ_RESET(); } static int i965_irq_postinstall(struct drm_device *dev) @@ -3935,9 +3927,7 @@ static int i965_irq_postinstall(struct drm_device *dev) } I915_WRITE(EMR, error_mask); - I915_WRITE(IMR, dev_priv->irq_mask); - I915_WRITE(IER, enable_mask); - POSTING_READ(IER); + GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); POSTING_READ(PORT_HOTPLUG_EN); @@ -4092,9 +4082,7 @@ static void i965_irq_uninstall(struct drm_device * dev) I915_WRITE(HWSTAM, 0xffffffff); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); - I915_WRITE(IIR, I915_READ(IIR)); + GEN3_IRQ_RESET(); } /** -- cgit v1.2.3 From e9e9848a6bcfb635c94e1d5f0b3f60799cfe8955 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:54 +0300 Subject: drm/i915: Introduce GEN2_IRQ_RESET/INIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify the appearance of the gen2 irq code with the gen3+ code by introducing the GEN2_IRQ_RESET/INIT macros. Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 54 ++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 788d37166872..daf8ea719f6f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -136,6 +136,16 @@ static const u32 hpd_bxt[HPD_NUM_PINS] = { POSTING_READ(type##IIR); \ } while (0) +#define GEN2_IRQ_RESET(type) do { \ + I915_WRITE16(type##IMR, 0xffff); \ + POSTING_READ16(type##IMR); \ + I915_WRITE16(type##IER, 0); \ + I915_WRITE16(type##IIR, 0xffff); \ + POSTING_READ16(type##IIR); \ + I915_WRITE16(type##IIR, 0xffff); \ + POSTING_READ16(type##IIR); \ +} while (0) + /* * We should clear IMR at preinstall/uninstall, and just check at postinstall. */ @@ -155,6 +165,22 @@ static void gen3_assert_iir_is_zero(struct drm_i915_private *dev_priv, POSTING_READ(reg); } +static void gen2_assert_iir_is_zero(struct drm_i915_private *dev_priv, + i915_reg_t reg) +{ + u16 val = I915_READ16(reg); + + if (val == 0) + return; + + WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", + i915_mmio_reg_offset(reg), val); + I915_WRITE16(reg, 0xffff); + POSTING_READ16(reg); + I915_WRITE16(reg, 0xffff); + POSTING_READ16(reg); +} + #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \ gen3_assert_iir_is_zero(dev_priv, GEN8_##type##_IIR(which)); \ I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \ @@ -169,6 +195,13 @@ static void gen3_assert_iir_is_zero(struct drm_i915_private *dev_priv, POSTING_READ(type##IMR); \ } while (0) +#define GEN2_IRQ_INIT(type, imr_val, ier_val) do { \ + gen2_assert_iir_is_zero(dev_priv, type##IIR); \ + I915_WRITE16(type##IER, (ier_val)); \ + I915_WRITE16(type##IMR, (imr_val)); \ + POSTING_READ16(type##IMR); \ +} while (0) + static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); @@ -3575,14 +3608,13 @@ static void i8xx_irq_preinstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); - I915_WRITE16(IMR, 0xffff); - I915_WRITE16(IER, 0x0); - POSTING_READ16(IER); + GEN2_IRQ_RESET(); } static int i8xx_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + u16 enable_mask; I915_WRITE16(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); @@ -3591,13 +3623,13 @@ static int i8xx_irq_postinstall(struct drm_device *dev) dev_priv->irq_mask = ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); - I915_WRITE16(IMR, dev_priv->irq_mask); - I915_WRITE16(IER, - I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_USER_INTERRUPT); - POSTING_READ16(IER); + enable_mask = + I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | + I915_USER_INTERRUPT; + + GEN2_IRQ_INIT(, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -3689,9 +3721,7 @@ static void i8xx_irq_uninstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); - I915_WRITE16(IMR, 0xffff); - I915_WRITE16(IER, 0x0); - I915_WRITE16(IIR, I915_READ16(IIR)); + GEN2_IRQ_RESET(); } static void i915_irq_preinstall(struct drm_device * dev) -- cgit v1.2.3 From 045cebd2e4c29c55e46a1044fa1d0dd38b790392 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:55 +0300 Subject: drm/i915: Setup EMR first on all gen2-4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify the appaerance of the gen2-4 irq postinstall hooks a little bit by doing the EMR setup first on all the platforms. Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index daf8ea719f6f..ebaac9cf8823 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3616,8 +3616,8 @@ static int i8xx_irq_postinstall(struct drm_device *dev) struct drm_i915_private *dev_priv = to_i915(dev); u16 enable_mask; - I915_WRITE16(EMR, - ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); + I915_WRITE16(EMR, ~(I915_ERROR_PAGE_TABLE | + I915_ERROR_MEMORY_REFRESH)); /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = @@ -3745,7 +3745,8 @@ static int i915_irq_postinstall(struct drm_device *dev) struct drm_i915_private *dev_priv = to_i915(dev); u32 enable_mask; - I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); + I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | + I915_ERROR_MEMORY_REFRESH)); /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = @@ -3921,6 +3922,21 @@ static int i965_irq_postinstall(struct drm_device *dev) u32 enable_mask; u32 error_mask; + /* + * Enable some error detection, note the instruction error mask + * bit is reserved, so we leave it masked. + */ + if (IS_G4X(dev_priv)) { + error_mask = ~(GM45_ERROR_PAGE_TABLE | + GM45_ERROR_MEM_PRIV | + GM45_ERROR_CP_PRIV | + I915_ERROR_MEMORY_REFRESH); + } else { + error_mask = ~(I915_ERROR_PAGE_TABLE | + I915_ERROR_MEMORY_REFRESH); + } + I915_WRITE(EMR, error_mask); + /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | I915_DISPLAY_PORT_INTERRUPT | @@ -3942,21 +3958,6 @@ static int i965_irq_postinstall(struct drm_device *dev) i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); - /* - * Enable some error detection, note the instruction error mask - * bit is reserved, so we leave it masked. - */ - if (IS_G4X(dev_priv)) { - error_mask = ~(GM45_ERROR_PAGE_TABLE | - GM45_ERROR_MEM_PRIV | - GM45_ERROR_CP_PRIV | - I915_ERROR_MEMORY_REFRESH); - } else { - error_mask = ~(I915_ERROR_PAGE_TABLE | - I915_ERROR_MEMORY_REFRESH); - } - I915_WRITE(EMR, error_mask); - GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); -- cgit v1.2.3 From e13924a8c2d32dc86d25771acc484e5f63426bda Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:56 +0300 Subject: drm/i915: Eliminate PORT_HOTPLUG_EN setup from gen3/4 irq_postinstall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've already cleared PORT_HOTPLUG_EN in the .irq_preinstall hook so doing it again in the .irq_postinstall is pointless. Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ebaac9cf8823..6431f4ebb726 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3761,9 +3761,6 @@ static int i915_irq_postinstall(struct drm_device *dev) I915_USER_INTERRUPT; if (I915_HAS_HOTPLUG(dev_priv)) { - i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - POSTING_READ(PORT_HOTPLUG_EN); - /* Enable in IER... */ enable_mask |= I915_DISPLAY_PORT_INTERRUPT; /* and unmask in IMR */ @@ -3960,9 +3957,6 @@ static int i965_irq_postinstall(struct drm_device *dev) GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); - i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - POSTING_READ(PORT_HOTPLUG_EN); - i915_enable_asle_pipestat(dev_priv); return 0; -- cgit v1.2.3 From c30bb1fd384c459bf70d4780a3ad2dec7211ee9d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:57 +0300 Subject: drm/i915: Unify the appearance of gen3/4 irq_postistall hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do the irq_mask/enable_mask setup in the same way on gen3/4, and also reorder the steps to make the code more uniform. Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6431f4ebb726..b51aeed59e71 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3769,8 +3769,6 @@ static int i915_irq_postinstall(struct drm_device *dev) GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); - i915_enable_asle_pipestat(dev_priv); - /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ spin_lock_irq(&dev_priv->irq_lock); @@ -3778,6 +3776,8 @@ static int i915_irq_postinstall(struct drm_device *dev) i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); + i915_enable_asle_pipestat(dev_priv); + return 0; } @@ -3935,18 +3935,26 @@ static int i965_irq_postinstall(struct drm_device *dev) I915_WRITE(EMR, error_mask); /* Unmask the interrupts that we always want on. */ - dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | - I915_DISPLAY_PORT_INTERRUPT | - I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); + dev_priv->irq_mask = + ~(I915_ASLE_INTERRUPT | + I915_DISPLAY_PORT_INTERRUPT | + I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | + I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); - enable_mask = ~dev_priv->irq_mask; - enable_mask |= I915_USER_INTERRUPT; + enable_mask = + I915_ASLE_INTERRUPT | + I915_DISPLAY_PORT_INTERRUPT | + I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | + I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT | + I915_USER_INTERRUPT; if (IS_G4X(dev_priv)) enable_mask |= I915_BSD_USER_INTERRUPT; + GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); + /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ spin_lock_irq(&dev_priv->irq_lock); @@ -3955,8 +3963,6 @@ static int i965_irq_postinstall(struct drm_device *dev) i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); - GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); - i915_enable_asle_pipestat(dev_priv); return 0; -- cgit v1.2.3 From 9515d7b8eb0bff20f9a2fa973331674e8abe06c8 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:58 +0300 Subject: drm/i915: Remove NULL dev_priv checks from irq_uninstall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There should be no way to land in irq_uninstall without a valid dev_priv. Let's kill off the remaining checks, which are probably some kind of UMS leftovers. Not all the irq_uninstall hooks even had them anymore. Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-10-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b51aeed59e71..93cba2de32bc 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3544,11 +3544,6 @@ static int cherryview_irq_postinstall(struct drm_device *dev) static void gen8_irq_uninstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = to_i915(dev); - - if (!dev_priv) - return; - gen8_irq_reset(dev); } @@ -3556,9 +3551,6 @@ static void valleyview_irq_uninstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); - if (!dev_priv) - return; - I915_WRITE(VLV_MASTER_IER, 0); POSTING_READ(VLV_MASTER_IER); @@ -3576,9 +3568,6 @@ static void cherryview_irq_uninstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); - if (!dev_priv) - return; - I915_WRITE(GEN8_MASTER_IRQ, 0); POSTING_READ(GEN8_MASTER_IRQ); @@ -3594,11 +3583,6 @@ static void cherryview_irq_uninstall(struct drm_device *dev) static void ironlake_irq_uninstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = to_i915(dev); - - if (!dev_priv) - return; - ironlake_irq_reset(dev); } @@ -4103,9 +4087,6 @@ static void i965_irq_uninstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = to_i915(dev); - if (!dev_priv) - return; - i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); -- cgit v1.2.3 From eb64343ca6dd03241579400e037f0e15e6831b0c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:36:59 +0300 Subject: drm/i915: Extract PIPESTAT irq handling into separate functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the gen2-4 PIPESTAT irq handling into separate functions just like we already do on VLV/CHV. We can share valleyview_pipestat_irq_ack() on all gmch platforms to actually read and clear the PIPESTAT status bits, so let's rename it to i9xx_pipestat_irq_ack(). Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-11-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 215 +++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 122 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 93cba2de32bc..27fd8e91084d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1755,8 +1755,8 @@ static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) } } -static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv, - u32 iir, u32 pipe_stats[I915_MAX_PIPES]) +static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, + u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { int pipe; @@ -1813,6 +1813,74 @@ static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv, spin_unlock(&dev_priv->irq_lock); } +static void i8xx_pipestat_irq_handler(struct drm_i915_private *dev_priv, + u16 iir, u32 pipe_stats[I915_MAX_PIPES]) +{ + enum pipe pipe; + + for_each_pipe(dev_priv, pipe) { + if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) + drm_handle_vblank(&dev_priv->drm, pipe); + + if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) + i9xx_pipe_crc_irq_handler(dev_priv, pipe); + + if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + } +} + +static void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, + u32 iir, u32 pipe_stats[I915_MAX_PIPES]) +{ + bool blc_event = false; + enum pipe pipe; + + for_each_pipe(dev_priv, pipe) { + if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) + drm_handle_vblank(&dev_priv->drm, pipe); + + if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) + blc_event = true; + + if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) + i9xx_pipe_crc_irq_handler(dev_priv, pipe); + + if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + } + + if (blc_event || (iir & I915_ASLE_INTERRUPT)) + intel_opregion_asle_intr(dev_priv); +} + +static void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv, + u32 iir, u32 pipe_stats[I915_MAX_PIPES]) +{ + bool blc_event = false; + enum pipe pipe; + + for_each_pipe(dev_priv, pipe) { + if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) + drm_handle_vblank(&dev_priv->drm, pipe); + + if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) + blc_event = true; + + if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) + i9xx_pipe_crc_irq_handler(dev_priv, pipe); + + if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); + } + + if (blc_event || (iir & I915_ASLE_INTERRUPT)) + intel_opregion_asle_intr(dev_priv); + + if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) + gmbus_irq_handler(dev_priv); +} + static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, u32 pipe_stats[I915_MAX_PIPES]) { @@ -1928,7 +1996,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) /* Call regardless, as some status bits might not be * signalled in iir */ - valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats); + i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT)) @@ -2012,7 +2080,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) /* Call regardless, as some status bits might not be * signalled in iir */ - valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats); + i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT | @@ -3630,8 +3698,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); u16 iir, new_iir; - u32 pipe_stats[2]; - int pipe; irqreturn_t ret; if (!intel_irqs_enabled(dev_priv)) @@ -3646,26 +3712,14 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) goto out; while (iir) { - /* Can't rely on pipestat interrupt bit in iir as it might - * have been cleared after the pipestat interrupt was received. - * It doesn't set the bit in iir again, but it still produces - * interrupts (for non-MSI). - */ - spin_lock(&dev_priv->irq_lock); + u32 pipe_stats[I915_MAX_PIPES] = {}; + if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); - for_each_pipe(dev_priv, pipe) { - i915_reg_t reg = PIPESTAT(pipe); - pipe_stats[pipe] = I915_READ(reg); - - /* - * Clear the PIPE*STAT regs before the IIR - */ - if (pipe_stats[pipe] & 0x8000ffff) - I915_WRITE(reg, pipe_stats[pipe]); - } - spin_unlock(&dev_priv->irq_lock); + /* Call regardless, as some status bits might not be + * signalled in iir */ + i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); I915_WRITE16(IIR, iir); new_iir = I915_READ16(IIR); /* Flush posted writes */ @@ -3673,21 +3727,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); - for_each_pipe(dev_priv, pipe) { - int plane = pipe; - if (HAS_FBC(dev_priv)) - plane = !plane; - - if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) - drm_handle_vblank(&dev_priv->drm, pipe); - - if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); - - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - intel_cpu_fifo_underrun_irq_handler(dev_priv, - pipe); - } + i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats); iir = new_iir; } @@ -3769,8 +3809,8 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); - u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; - int pipe, ret = IRQ_NONE; + u32 iir, new_iir; + int ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; @@ -3780,29 +3820,15 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) iir = I915_READ(IIR); do { - bool irq_received = (iir) != 0; - bool blc_event = false; + u32 pipe_stats[I915_MAX_PIPES] = {}; + bool irq_received = iir != 0; - /* Can't rely on pipestat interrupt bit in iir as it might - * have been cleared after the pipestat interrupt was received. - * It doesn't set the bit in iir again, but it still produces - * interrupts (for non-MSI). - */ - spin_lock(&dev_priv->irq_lock); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); - for_each_pipe(dev_priv, pipe) { - i915_reg_t reg = PIPESTAT(pipe); - pipe_stats[pipe] = I915_READ(reg); - - /* Clear the PIPE*STAT regs before the IIR */ - if (pipe_stats[pipe] & 0x8000ffff) { - I915_WRITE(reg, pipe_stats[pipe]); - irq_received = true; - } - } - spin_unlock(&dev_priv->irq_lock); + /* Call regardless, as some status bits might not be + * signalled in iir */ + i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (!irq_received) break; @@ -3821,27 +3847,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); - for_each_pipe(dev_priv, pipe) { - int plane = pipe; - if (HAS_FBC(dev_priv)) - plane = !plane; - - if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) - drm_handle_vblank(&dev_priv->drm, pipe); - - if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) - blc_event = true; - - if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); - - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - intel_cpu_fifo_underrun_irq_handler(dev_priv, - pipe); - } - - if (blc_event || (iir & I915_ASLE_INTERRUPT)) - intel_opregion_asle_intr(dev_priv); + i915_pipestat_irq_handler(dev_priv, iir, pipe_stats); /* With MSI, interrupts are only generated when iir * transitions from zero to nonzero. If another bit got @@ -3982,8 +3988,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); u32 iir, new_iir; - u32 pipe_stats[I915_MAX_PIPES]; - int ret = IRQ_NONE, pipe; + int ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; @@ -3994,31 +3999,15 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) iir = I915_READ(IIR); for (;;) { - bool irq_received = (iir) != 0; - bool blc_event = false; + u32 pipe_stats[I915_MAX_PIPES] = {}; + bool irq_received = iir != 0; - /* Can't rely on pipestat interrupt bit in iir as it might - * have been cleared after the pipestat interrupt was received. - * It doesn't set the bit in iir again, but it still produces - * interrupts (for non-MSI). - */ - spin_lock(&dev_priv->irq_lock); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); - for_each_pipe(dev_priv, pipe) { - i915_reg_t reg = PIPESTAT(pipe); - pipe_stats[pipe] = I915_READ(reg); - - /* - * Clear the PIPE*STAT regs before the IIR - */ - if (pipe_stats[pipe] & 0x8000ffff) { - I915_WRITE(reg, pipe_stats[pipe]); - irq_received = true; - } - } - spin_unlock(&dev_priv->irq_lock); + /* Call regardless, as some status bits might not be + * signalled in iir */ + i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (!irq_received) break; @@ -4040,25 +4029,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) if (iir & I915_BSD_USER_INTERRUPT) notify_ring(dev_priv->engine[VCS]); - for_each_pipe(dev_priv, pipe) { - if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) - drm_handle_vblank(&dev_priv->drm, pipe); - - if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) - blc_event = true; - - if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); - - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); - } - - if (blc_event || (iir & I915_ASLE_INTERRUPT)) - intel_opregion_asle_intr(dev_priv); - - if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) - gmbus_irq_handler(dev_priv); + i965_pipestat_irq_handler(dev_priv, iir, pipe_stats); /* With MSI, interrupts are only generated when iir * transitions from zero to nonzero. If another bit got -- cgit v1.2.3 From af722d280e8551e918b22e96f487824935470c9a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:37:00 +0300 Subject: drm/i915: Rewrite GMCH irq handlers to avoid loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminate the loops from the gen2-3 irq handlers. Since we don't use MSI anymore on these platforms, and thus the CPU interrupt will be level triggered, we shouldn't need to play any tricks with IER to induce edges from IIR. IIR itself still detects only edges from PIPESTAT & co. on gen4 but since IIR is double buffered and we only clear one bit per irq handler invocation we can use the normal "clear PIPESTAT & co. -> clear IIR" approach to ack the interrupts. On gen2 everything is level triggered, and gen3 presumably follows either the gen2 or gen4 approach since nothing else would really make sense. v2: Drop the IER tricks since we no longer use MSI Cc: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-12-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 143 ++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 27fd8e91084d..26569a00b40c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3697,8 +3697,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); - u16 iir, new_iir; - irqreturn_t ret; + irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; @@ -3706,34 +3705,31 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); - ret = IRQ_NONE; - iir = I915_READ16(IIR); - if (iir == 0) - goto out; - - while (iir) { + do { u32 pipe_stats[I915_MAX_PIPES] = {}; + u16 iir; - if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) - DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); + iir = I915_READ16(IIR); + if (iir == 0) + break; + + ret = IRQ_HANDLED; /* Call regardless, as some status bits might not be * signalled in iir */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); I915_WRITE16(IIR, iir); - new_iir = I915_READ16(IIR); /* Flush posted writes */ if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); - i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats); + if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) + DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); - iir = new_iir; - } - ret = IRQ_HANDLED; + i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats); + } while (0); -out: enable_rpm_wakeref_asserts(dev_priv); return ret; @@ -3809,8 +3805,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); - u32 iir, new_iir; - int ret = IRQ_NONE; + irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; @@ -3818,55 +3813,38 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); - iir = I915_READ(IIR); do { u32 pipe_stats[I915_MAX_PIPES] = {}; - bool irq_received = iir != 0; + u32 hotplug_status = 0; + u32 iir; - if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) - DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); + iir = I915_READ(IIR); + if (iir == 0) + break; + + ret = IRQ_HANDLED; + + if (I915_HAS_HOTPLUG(dev_priv) && + iir & I915_DISPLAY_PORT_INTERRUPT) + hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be * signalled in iir */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); - if (!irq_received) - break; - - /* Consume port. Then clear IIR or we'll miss events */ - if (I915_HAS_HOTPLUG(dev_priv) && - iir & I915_DISPLAY_PORT_INTERRUPT) { - u32 hotplug_status = i9xx_hpd_irq_ack(dev_priv); - if (hotplug_status) - i9xx_hpd_irq_handler(dev_priv, hotplug_status); - } - I915_WRITE(IIR, iir); - new_iir = I915_READ(IIR); /* Flush posted writes */ if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); - i915_pipestat_irq_handler(dev_priv, iir, pipe_stats); + if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) + DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); - /* With MSI, interrupts are only generated when iir - * transitions from zero to nonzero. If another bit got - * set while we were handling the existing iir bits, then - * we would never get another interrupt. - * - * This is fine on non-MSI as well, as if we hit this path - * we avoid exiting the interrupt handler only to generate - * another one. - * - * Note that for MSI this could cause a stray interrupt report - * if an interrupt landed in the time between writing IIR and - * the posting read. This should be rare enough to never - * trigger the 99% of 100,000 interrupts test for disabling - * stray interrupts. - */ - ret = IRQ_HANDLED; - iir = new_iir; - } while (iir); + if (hotplug_status) + i9xx_hpd_irq_handler(dev_priv, hotplug_status); + + i915_pipestat_irq_handler(dev_priv, iir, pipe_stats); + } while (0); enable_rpm_wakeref_asserts(dev_priv); @@ -3987,8 +3965,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); - u32 iir, new_iir; - int ret = IRQ_NONE; + irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; @@ -3996,58 +3973,40 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); - iir = I915_READ(IIR); - - for (;;) { + do { u32 pipe_stats[I915_MAX_PIPES] = {}; - bool irq_received = iir != 0; - - if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) - DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); - - /* Call regardless, as some status bits might not be - * signalled in iir */ - i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); + u32 hotplug_status = 0; + u32 iir; - if (!irq_received) + iir = I915_READ(IIR); + if (iir == 0) break; ret = IRQ_HANDLED; - /* Consume port. Then clear IIR or we'll miss events */ - if (iir & I915_DISPLAY_PORT_INTERRUPT) { - u32 hotplug_status = i9xx_hpd_irq_ack(dev_priv); - if (hotplug_status) - i9xx_hpd_irq_handler(dev_priv, hotplug_status); - } + if (iir & I915_DISPLAY_PORT_INTERRUPT) + hotplug_status = i9xx_hpd_irq_ack(dev_priv); + + /* Call regardless, as some status bits might not be + * signalled in iir */ + i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); I915_WRITE(IIR, iir); - new_iir = I915_READ(IIR); /* Flush posted writes */ if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); + if (iir & I915_BSD_USER_INTERRUPT) notify_ring(dev_priv->engine[VCS]); - i965_pipestat_irq_handler(dev_priv, iir, pipe_stats); + if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) + DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); - /* With MSI, interrupts are only generated when iir - * transitions from zero to nonzero. If another bit got - * set while we were handling the existing iir bits, then - * we would never get another interrupt. - * - * This is fine on non-MSI as well, as if we hit this path - * we avoid exiting the interrupt handler only to generate - * another one. - * - * Note that for MSI this could cause a stray interrupt report - * if an interrupt landed in the time between writing IIR and - * the posting read. This should be rare enough to never - * trigger the 99% of 100,000 interrupts test for disabling - * stray interrupts. - */ - iir = new_iir; - } + if (hotplug_status) + i9xx_hpd_irq_handler(dev_priv, hotplug_status); + + i965_pipestat_irq_handler(dev_priv, iir, pipe_stats); + } while (0); enable_rpm_wakeref_asserts(dev_priv); -- cgit v1.2.3 From 5190707e7a4fc701e94cd7e152d15dbba90b63ff Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:37:02 +0300 Subject: drm/i915: Gen3 HWSTAM is actually 32 bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bspec claims that HWSTAM is only 16 bits on gen3, but the other interrupts registers are 32 bits and there are 18 valid interrupt bits. Hence a 16 bit HWSTAM wouldn't be able to contain all the bits, so it seems the spec is incorrect about the size of the register. And indeed I can clear bits 16 and 17 just fine with a 32 bit write. So let's adjust the code to treat the register as 32 bits. Acked-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-14-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26569a00b40c..003a92857102 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3755,7 +3755,7 @@ static void i915_irq_preinstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); - I915_WRITE16(HWSTAM, 0xeffe); + I915_WRITE(HWSTAM, 0xffffeffe); GEN3_IRQ_RESET(); } @@ -3862,7 +3862,7 @@ static void i915_irq_uninstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); - I915_WRITE16(HWSTAM, 0xffff); + I915_WRITE(HWSTAM, 0xffffffff); GEN3_IRQ_RESET(); } -- cgit v1.2.3 From 442aa277c066cec6cfe8508b3edbdda022b10568 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Thu, 14 Sep 2017 11:31:39 -0700 Subject: drm/i915/cnl: Change the macro name to DPLL_CFGCR0_DCO_FRACTION_SHIFT No functional changes. Only change the macro from "DPLL_CFGCR0_DC0_FRAC_SHIFT to DPLL_CFGCR0_DCO_FRACTION_SHIFT to be consistent with DPLL_CFGCR0_DCO_FRACTION_MASK and DPLL_CFGCR0_DCO_FRACTION Cc: Rodrigo Vivi Signed-off-by: Manasi Navare Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/1505413899-30876-1-git-send-email-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 2 +- drivers/gpu/drm/i915/intel_ddi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0befefec7327..94b40a469afd 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8599,7 +8599,7 @@ enum skl_power_gate { #define DPLL_CFGCR0_LINK_RATE_3240 (6 << 25) #define DPLL_CFGCR0_LINK_RATE_4050 (7 << 25) #define DPLL_CFGCR0_DCO_FRACTION_MASK (0x7fff << 10) -#define DPLL_CFGCR0_DCO_FRAC_SHIFT (10) +#define DPLL_CFGCR0_DCO_FRACTION_SHIFT (10) #define DPLL_CFGCR0_DCO_FRACTION(x) ((x) << 10) #define DPLL_CFGCR0_DCO_INTEGER_MASK (0x3ff) #define CNL_DPLL_CFGCR0(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR0, _CNL_DPLL1_CFGCR0) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1da3bb2cc4b4..31d14587ad86 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1212,7 +1212,7 @@ static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, dco_freq = (cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) * ref_clock; dco_freq += (((cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >> - DPLL_CFGCR0_DCO_FRAC_SHIFT) * ref_clock) / 0x8000; + DPLL_CFGCR0_DCO_FRACTION_SHIFT) * ref_clock) / 0x8000; return dco_freq / (p0 * p1 * p2 * 5); } -- cgit v1.2.3 From e01e71fc49d4c95090a04f898a3fe788c652a04b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 14 Sep 2017 17:42:13 +0100 Subject: drm/i915: Remove unused 'in_vbl' from i915_get_crtc_scanoutpos() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 1bf6ad622b9b ("drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos") removed the use of in_vbl, but did not remove the local variable. Do so now. Fixes: 1bf6ad622b9b ("drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos") Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170914164213.18461-1-chris@chris-wilson.co.uk Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_irq.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 003a92857102..e8bb6c644fa4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -872,7 +872,6 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, pipe); int position; int vbl_start, vbl_end, hsync_start, htotal, vtotal; - bool in_vbl = true; unsigned long irqflags; if (WARN_ON(!mode->crtc_clock)) { @@ -955,8 +954,6 @@ static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); - in_vbl = position >= vbl_start && position < vbl_end; - /* * While in vblank, position will be negative * counting up towards 0 at vbl_end. And outside -- cgit v1.2.3 From 21cc6431e0c2d7c3a2e2fd4dd002400be73cb270 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 11 Sep 2017 09:41:25 +0100 Subject: drm/i915: Mark the userptr invalidate workqueue as WQ_MEM_RECLAIM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To silence the critcs: [56532.161115] workqueue: PF_MEMALLOC task 36(khugepaged) is flushing !WQ_MEM_RECLAIM i915-userptr-release: (null) [56532.161138] ------------[ cut here ]------------ [56532.161144] WARNING: CPU: 1 PID: 36 at kernel/workqueue.c:2418 check_flush_dependency+0xe8/0xf0 [56532.161145] Modules linked in: wmi_bmof [56532.161148] CPU: 1 PID: 36 Comm: khugepaged Not tainted 4.13.0-krejzi #1 [56532.161149] Hardware name: HP HP ProBook 470 G3/8102, BIOS N78 Ver. 01.17 06/08/2017 [56532.161150] task: ffff8802371ee200 task.stack: ffffc90000174000 [56532.161152] RIP: 0010:check_flush_dependency+0xe8/0xf0 [56532.161152] RSP: 0018:ffffc900001777b8 EFLAGS: 00010286 [56532.161153] RAX: 000000000000006c RBX: ffff88022fc5a000 RCX: 0000000000000001 [56532.161154] RDX: 0000000000000000 RSI: 0000000000000086 RDI: 00000000ffffffff [56532.161155] RBP: 0000000000000000 R08: 14f038bb55f6dae0 R09: 0000000000000516 [56532.161155] R10: ffffc900001778a0 R11: 000000006c756e28 R12: ffff8802371ee200 [56532.161156] R13: 0000000000000000 R14: 000000000000000b R15: ffffc90000177810 [56532.161157] FS: 0000000000000000(0000) GS:ffff880240480000(0000) knlGS:0000000000000000 [56532.161158] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [56532.161158] CR2: 0000000004795ff8 CR3: 000000000220a000 CR4: 00000000003406e0 [56532.161159] Call Trace: [56532.161161] ? flush_workqueue+0x136/0x3e0 [56532.161178] ? _raw_spin_unlock_irqrestore+0xf/0x30 [56532.161179] ? try_to_wake_up+0x1ce/0x3b0 [56532.161183] ? i915_gem_userptr_mn_invalidate_range_start+0x13f/0x150 [56532.161184] ? _raw_spin_unlock+0xd/0x20 [56532.161186] ? i915_gem_userptr_mn_invalidate_range_start+0x13f/0x150 [56532.161189] ? __mmu_notifier_invalidate_range_start+0x4a/0x70 [56532.161191] ? try_to_unmap_one+0x5e5/0x660 [56532.161193] ? rmap_walk_file+0xe4/0x240 [56532.161195] ? __ClearPageMovable+0x10/0x10 [56532.161196] ? try_to_unmap+0x8c/0xe0 [56532.161197] ? page_remove_rmap+0x280/0x280 [56532.161199] ? page_not_mapped+0x10/0x10 [56532.161200] ? page_get_anon_vma+0x90/0x90 [56532.161202] ? migrate_pages+0x6a5/0x940 [56532.161203] ? isolate_freepages_block+0x330/0x330 [56532.161205] ? compact_zone+0x593/0x6a0 [56532.161206] ? enqueue_task_fair+0xc3/0x1180 [56532.161208] ? compact_zone_order+0x9b/0xc0 [56532.161210] ? get_page_from_freelist+0x24a/0x900 [56532.161212] ? try_to_compact_pages+0xc8/0x240 [56532.161213] ? try_to_compact_pages+0xc8/0x240 [56532.161215] ? __alloc_pages_direct_compact+0x45/0xe0 [56532.161216] ? __alloc_pages_slowpath+0x845/0xb90 [56532.161218] ? __alloc_pages_nodemask+0x176/0x1f0 [56532.161220] ? wait_woken+0x80/0x80 [56532.161222] ? khugepaged+0x29e/0x17d0 [56532.161223] ? wait_woken+0x80/0x80 [56532.161225] ? collapse_shmem.isra.39+0xa60/0xa60 [56532.161226] ? kthread+0x10d/0x130 [56532.161227] ? kthread_create_on_node+0x60/0x60 [56532.161228] ? ret_from_fork+0x22/0x30 [56532.161229] Code: 00 8b b0 10 05 00 00 48 8d 8b b0 00 00 00 48 8d 90 b8 06 00 00 49 89 e8 48 c7 c7 38 55 09 82 c6 05 f9 c6 1d 01 01 e8 0e a1 03 00 <0f> ff e9 6b ff ff ff 90 48 8b 37 40 f6 c6 04 75 1b 48 c1 ee 05 [56532.161251] ---[ end trace 2ce2b4f5f69b803b ]--- Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170911084135.22903-2-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski --- drivers/gpu/drm/i915/i915_gem_userptr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 2ce078e8c763..15547c8f7d3f 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -813,7 +813,9 @@ int i915_gem_init_userptr(struct drm_i915_private *dev_priv) hash_init(dev_priv->mm_structs); dev_priv->mm.userptr_wq = - alloc_workqueue("i915-userptr-acquire", WQ_HIGHPRI, 0); + alloc_workqueue("i915-userptr-acquire", + WQ_HIGHPRI | WQ_MEM_RECLAIM, + 0); if (!dev_priv->mm.userptr_wq) return -ENOMEM; -- cgit v1.2.3 From 17533bf95719466c524e07a5880d47a8d7aaa0cd Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 14 Sep 2017 15:08:01 +0000 Subject: drm/i915: Rename lvds_use_ssc modparam to panel_use_ssc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This modparam affects not only LVDS but also eDP panels. Additionally with this rename we will keep modparam and i915_params field name in sync. This patch will unblock us with further improvements around params defs. Suggested-by: Ville Syrjala Signed-off-by: Michal Wajdeczko Cc: Ville Syrjala Cc: Chris Wilson Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170914150805.28376-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 8ab003dca113..221f7d4caae6 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -105,8 +105,8 @@ MODULE_PARM_DESC(lvds_channel_mode, "Specify LVDS channel mode " "(0=probe BIOS [default], 1=single-channel, 2=dual-channel)"); -module_param_named_unsafe(lvds_use_ssc, i915.panel_use_ssc, int, 0600); -MODULE_PARM_DESC(lvds_use_ssc, +module_param_named_unsafe(panel_use_ssc, i915.panel_use_ssc, int, 0600); +MODULE_PARM_DESC(panel_use_ssc, "Use Spread Spectrum Clock with panels [LVDS/eDP] " "(default: auto from VBT)"); -- cgit v1.2.3 From c95469324518f3ab216d7e3a820b5f0609569681 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 14 Sep 2017 15:08:02 +0000 Subject: drm/i915: Introduce custom variant of module_param_named macro As we now use same name for public module param and its local representation we can simplify param definition macro. Changes done with Coccinelle: @@ declarer name module_param_named; declarer name module_param_named_unsafe; declarer name i915_param_named; declarer name i915_param_named_unsafe; identifier n; @@ ( -module_param_named(n, i915.n, +i915_module_param_named(n, ...); | -module_param_named_unsafe(n, i915.n, +i915_module_param_named_unsafe(n, ...); ) Suggested-by: Chris Wilson Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170914150805.28376-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_params.c | 85 ++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 221f7d4caae6..891e0a5e9336 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -25,6 +25,11 @@ #include "i915_params.h" #include "i915_drv.h" +#define i915_param_named(name, T, perm) \ + module_param_named(name, i915.name, T, perm) +#define i915_param_named_unsafe(name, T, perm) \ + module_param_named_unsafe(name, i915.name, T, perm) + struct i915_params i915 __read_mostly = { .modeset = -1, .panel_ignore_lid = 1, @@ -67,22 +72,22 @@ struct i915_params i915 __read_mostly = { .enable_gvt = false, }; -module_param_named(modeset, i915.modeset, int, 0400); +i915_param_named(modeset, int, 0400); MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (0=disable, " "1=on, -1=force vga console preference [default])"); -module_param_named_unsafe(panel_ignore_lid, i915.panel_ignore_lid, int, 0600); +i915_param_named_unsafe(panel_ignore_lid, int, 0600); MODULE_PARM_DESC(panel_ignore_lid, "Override lid status (0=autodetect, 1=autodetect disabled [default], " "-1=force lid closed, -2=force lid open)"); -module_param_named_unsafe(semaphores, i915.semaphores, int, 0400); +i915_param_named_unsafe(semaphores, int, 0400); MODULE_PARM_DESC(semaphores, "Use semaphores for inter-ring sync " "(default: -1 (use per-chip defaults))"); -module_param_named_unsafe(enable_rc6, i915.enable_rc6, int, 0400); +i915_param_named_unsafe(enable_rc6, int, 0400); MODULE_PARM_DESC(enable_rc6, "Enable power-saving render C-state 6. " "Different stages can be selected via bitmask values " @@ -90,100 +95,100 @@ MODULE_PARM_DESC(enable_rc6, "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " "default: -1 (use per-chip default)"); -module_param_named_unsafe(enable_dc, i915.enable_dc, int, 0400); +i915_param_named_unsafe(enable_dc, int, 0400); MODULE_PARM_DESC(enable_dc, "Enable power-saving display C-states. " "(-1=auto [default]; 0=disable; 1=up to DC5; 2=up to DC6)"); -module_param_named_unsafe(enable_fbc, i915.enable_fbc, int, 0600); +i915_param_named_unsafe(enable_fbc, int, 0600); MODULE_PARM_DESC(enable_fbc, "Enable frame buffer compression for power savings " "(default: -1 (use per-chip default))"); -module_param_named_unsafe(lvds_channel_mode, i915.lvds_channel_mode, int, 0400); +i915_param_named_unsafe(lvds_channel_mode, int, 0400); MODULE_PARM_DESC(lvds_channel_mode, "Specify LVDS channel mode " "(0=probe BIOS [default], 1=single-channel, 2=dual-channel)"); -module_param_named_unsafe(panel_use_ssc, i915.panel_use_ssc, int, 0600); +i915_param_named_unsafe(panel_use_ssc, int, 0600); MODULE_PARM_DESC(panel_use_ssc, "Use Spread Spectrum Clock with panels [LVDS/eDP] " "(default: auto from VBT)"); -module_param_named_unsafe(vbt_sdvo_panel_type, i915.vbt_sdvo_panel_type, int, 0400); +i915_param_named_unsafe(vbt_sdvo_panel_type, int, 0400); MODULE_PARM_DESC(vbt_sdvo_panel_type, "Override/Ignore selection of SDVO panel mode in the VBT " "(-2=ignore, -1=auto [default], index in VBT BIOS table)"); -module_param_named_unsafe(reset, i915.reset, int, 0600); +i915_param_named_unsafe(reset, int, 0600); MODULE_PARM_DESC(reset, "Attempt GPU resets (0=disabled, 1=full gpu reset, 2=engine reset [default])"); -module_param_named_unsafe(vbt_firmware, i915.vbt_firmware, charp, 0400); +i915_param_named_unsafe(vbt_firmware, charp, 0400); MODULE_PARM_DESC(vbt_firmware, "Load VBT from specified file under /lib/firmware"); #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) -module_param_named(error_capture, i915.error_capture, bool, 0600); +i915_param_named(error_capture, bool, 0600); MODULE_PARM_DESC(error_capture, "Record the GPU state following a hang. " "This information in /sys/class/drm/card/error is vital for " "triaging and debugging hangs."); #endif -module_param_named_unsafe(enable_hangcheck, i915.enable_hangcheck, bool, 0644); +i915_param_named_unsafe(enable_hangcheck, bool, 0644); MODULE_PARM_DESC(enable_hangcheck, "Periodically check GPU activity for detecting hangs. " "WARNING: Disabling this can cause system wide hangs. " "(default: true)"); -module_param_named_unsafe(enable_ppgtt, i915.enable_ppgtt, int, 0400); +i915_param_named_unsafe(enable_ppgtt, int, 0400); MODULE_PARM_DESC(enable_ppgtt, "Override PPGTT usage. " "(-1=auto [default], 0=disabled, 1=aliasing, 2=full, 3=full with extended address space)"); -module_param_named_unsafe(enable_execlists, i915.enable_execlists, int, 0400); +i915_param_named_unsafe(enable_execlists, int, 0400); MODULE_PARM_DESC(enable_execlists, "Override execlists usage. " "(-1=auto [default], 0=disabled, 1=enabled)"); -module_param_named_unsafe(enable_psr, i915.enable_psr, int, 0600); +i915_param_named_unsafe(enable_psr, int, 0600); MODULE_PARM_DESC(enable_psr, "Enable PSR " "(0=disabled, 1=enabled - link mode chosen per-platform, 2=force link-standby mode, 3=force link-off mode) " "Default: -1 (use per-chip default)"); -module_param_named_unsafe(alpha_support, i915.alpha_support, bool, 0400); +i915_param_named_unsafe(alpha_support, bool, 0400); MODULE_PARM_DESC(alpha_support, "Enable alpha quality driver support for latest hardware. " "See also CONFIG_DRM_I915_ALPHA_SUPPORT."); -module_param_named_unsafe(disable_power_well, i915.disable_power_well, int, 0400); +i915_param_named_unsafe(disable_power_well, int, 0400); MODULE_PARM_DESC(disable_power_well, "Disable display power wells when possible " "(-1=auto [default], 0=power wells always on, 1=power wells disabled when possible)"); -module_param_named_unsafe(enable_ips, i915.enable_ips, int, 0600); +i915_param_named_unsafe(enable_ips, int, 0600); MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)"); -module_param_named(fastboot, i915.fastboot, bool, 0600); +i915_param_named(fastboot, bool, 0600); MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time (default: false)"); -module_param_named_unsafe(prefault_disable, i915.prefault_disable, bool, 0600); +i915_param_named_unsafe(prefault_disable, bool, 0600); MODULE_PARM_DESC(prefault_disable, "Disable page prefaulting for pread/pwrite/reloc (default:false). " "For developers only."); -module_param_named_unsafe(load_detect_test, i915.load_detect_test, bool, 0600); +i915_param_named_unsafe(load_detect_test, bool, 0600); MODULE_PARM_DESC(load_detect_test, "Force-enable the VGA load detect code for testing (default:false). " "For developers only."); -module_param_named_unsafe(force_reset_modeset_test, i915.force_reset_modeset_test, bool, 0600); +i915_param_named_unsafe(force_reset_modeset_test, bool, 0600); MODULE_PARM_DESC(force_reset_modeset_test, "Force a modeset during gpu reset for testing (default:false). " "For developers only."); -module_param_named_unsafe(invert_brightness, i915.invert_brightness, int, 0600); +i915_param_named_unsafe(invert_brightness, int, 0600); MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness " "(-1 force normal, 0 machine defaults, 1 force inversion), please " @@ -191,69 +196,69 @@ MODULE_PARM_DESC(invert_brightness, "to dri-devel@lists.freedesktop.org, if your machine needs it. " "It will then be included in an upcoming module version."); -module_param_named(disable_display, i915.disable_display, bool, 0400); +i915_param_named(disable_display, bool, 0400); MODULE_PARM_DESC(disable_display, "Disable display (default: false)"); -module_param_named_unsafe(enable_cmd_parser, i915.enable_cmd_parser, bool, 0400); +i915_param_named_unsafe(enable_cmd_parser, bool, 0400); MODULE_PARM_DESC(enable_cmd_parser, "Enable command parsing (true=enabled [default], false=disabled)"); -module_param_named_unsafe(use_mmio_flip, i915.use_mmio_flip, int, 0600); +i915_param_named_unsafe(use_mmio_flip, int, 0600); MODULE_PARM_DESC(use_mmio_flip, "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)"); -module_param_named(mmio_debug, i915.mmio_debug, int, 0600); +i915_param_named(mmio_debug, int, 0600); MODULE_PARM_DESC(mmio_debug, "Enable the MMIO debug code for the first N failures (default: off). " "This may negatively affect performance."); -module_param_named(verbose_state_checks, i915.verbose_state_checks, bool, 0600); +i915_param_named(verbose_state_checks, bool, 0600); MODULE_PARM_DESC(verbose_state_checks, "Enable verbose logs (ie. WARN_ON()) in case of unexpected hw state conditions."); -module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0400); +i915_param_named_unsafe(nuclear_pageflip, bool, 0400); MODULE_PARM_DESC(nuclear_pageflip, "Force enable atomic functionality on platforms that don't have full support yet."); /* WA to get away with the default setting in VBT for early platforms.Will be removed */ -module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0400); +i915_param_named_unsafe(edp_vswing, int, 0400); MODULE_PARM_DESC(edp_vswing, "Ignore/Override vswing pre-emph table selection from VBT " "(0=use value from vbt [default], 1=low power swing(200mV)," "2=default swing(400mV))"); -module_param_named_unsafe(enable_guc_loading, i915.enable_guc_loading, int, 0400); +i915_param_named_unsafe(enable_guc_loading, int, 0400); MODULE_PARM_DESC(enable_guc_loading, "Enable GuC firmware loading " "(-1=auto, 0=never [default], 1=if available, 2=required)"); -module_param_named_unsafe(enable_guc_submission, i915.enable_guc_submission, int, 0400); +i915_param_named_unsafe(enable_guc_submission, int, 0400); MODULE_PARM_DESC(enable_guc_submission, "Enable GuC submission " "(-1=auto, 0=never [default], 1=if available, 2=required)"); -module_param_named(guc_log_level, i915.guc_log_level, int, 0400); +i915_param_named(guc_log_level, int, 0400); MODULE_PARM_DESC(guc_log_level, "GuC firmware logging level (-1:disabled (default), 0-3:enabled)"); -module_param_named_unsafe(guc_firmware_path, i915.guc_firmware_path, charp, 0400); +i915_param_named_unsafe(guc_firmware_path, charp, 0400); MODULE_PARM_DESC(guc_firmware_path, "GuC firmware path to use instead of the default one"); -module_param_named_unsafe(huc_firmware_path, i915.huc_firmware_path, charp, 0400); +i915_param_named_unsafe(huc_firmware_path, charp, 0400); MODULE_PARM_DESC(huc_firmware_path, "HuC firmware path to use instead of the default one"); -module_param_named_unsafe(enable_dp_mst, i915.enable_dp_mst, bool, 0600); +i915_param_named_unsafe(enable_dp_mst, bool, 0600); MODULE_PARM_DESC(enable_dp_mst, "Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)"); -module_param_named_unsafe(inject_load_failure, i915.inject_load_failure, uint, 0400); +i915_param_named_unsafe(inject_load_failure, uint, 0400); MODULE_PARM_DESC(inject_load_failure, "Force an error after a number of failure check points (0:disabled (default), N:force failure at the Nth failure check point)"); -module_param_named(enable_dpcd_backlight, i915.enable_dpcd_backlight, bool, 0600); +i915_param_named(enable_dpcd_backlight, bool, 0600); MODULE_PARM_DESC(enable_dpcd_backlight, "Enable support for DPCD backlight control (default:false)"); -module_param_named(enable_gvt, i915.enable_gvt, bool, 0400); +i915_param_named(enable_gvt, bool, 0400); MODULE_PARM_DESC(enable_gvt, "Enable support for Intel GVT-g graphics virtualization host support(default:false)"); -- cgit v1.2.3 From 3dcf4f207e8e0703cc00d5384e46ed6eb6902613 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 14 Sep 2017 15:08:03 +0000 Subject: drm/i915: Extend private i915_param_named macro with description We're always specifying description of each module param in separate macro. Let's combine description into our main macro. Started with Coccinelle, followed by minor cleanup. @match1@ declarer name MODULE_PARM_DESC; identifier n; constant c; @@ ( - MODULE_PARM_DESC(n, c); ) @fix1 depends on match1@ declarer name i915_param_named; declarer name i915_param_named_unsafe; identifier match1.n; constant match1.c; @@ ( i915_param_named(n, ... + , c ); | i915_param_named_unsafe(n, ... + , c ); ) Suggested-by: Jani Nikula Signed-off-by: Michal Wajdeczko Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170914150805.28376-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_params.c | 167 +++++++++++++++---------------------- 1 file changed, 67 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 891e0a5e9336..ddda513cc7f4 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -25,10 +25,12 @@ #include "i915_params.h" #include "i915_drv.h" -#define i915_param_named(name, T, perm) \ - module_param_named(name, i915.name, T, perm) -#define i915_param_named_unsafe(name, T, perm) \ - module_param_named_unsafe(name, i915.name, T, perm) +#define i915_param_named(name, T, perm, desc) \ + module_param_named(name, i915.name, T, perm); \ + MODULE_PARM_DESC(name, desc) +#define i915_param_named_unsafe(name, T, perm, desc) \ + module_param_named_unsafe(name, i915.name, T, perm); \ + MODULE_PARM_DESC(name, desc) struct i915_params i915 __read_mostly = { .modeset = -1, @@ -72,193 +74,158 @@ struct i915_params i915 __read_mostly = { .enable_gvt = false, }; -i915_param_named(modeset, int, 0400); -MODULE_PARM_DESC(modeset, +i915_param_named(modeset, int, 0400, "Use kernel modesetting [KMS] (0=disable, " "1=on, -1=force vga console preference [default])"); -i915_param_named_unsafe(panel_ignore_lid, int, 0600); -MODULE_PARM_DESC(panel_ignore_lid, +i915_param_named_unsafe(panel_ignore_lid, int, 0600, "Override lid status (0=autodetect, 1=autodetect disabled [default], " "-1=force lid closed, -2=force lid open)"); -i915_param_named_unsafe(semaphores, int, 0400); -MODULE_PARM_DESC(semaphores, +i915_param_named_unsafe(semaphores, int, 0400, "Use semaphores for inter-ring sync " "(default: -1 (use per-chip defaults))"); -i915_param_named_unsafe(enable_rc6, int, 0400); -MODULE_PARM_DESC(enable_rc6, +i915_param_named_unsafe(enable_rc6, int, 0400, "Enable power-saving render C-state 6. " "Different stages can be selected via bitmask values " "(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). " "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " "default: -1 (use per-chip default)"); -i915_param_named_unsafe(enable_dc, int, 0400); -MODULE_PARM_DESC(enable_dc, +i915_param_named_unsafe(enable_dc, int, 0400, "Enable power-saving display C-states. " "(-1=auto [default]; 0=disable; 1=up to DC5; 2=up to DC6)"); -i915_param_named_unsafe(enable_fbc, int, 0600); -MODULE_PARM_DESC(enable_fbc, +i915_param_named_unsafe(enable_fbc, int, 0600, "Enable frame buffer compression for power savings " "(default: -1 (use per-chip default))"); -i915_param_named_unsafe(lvds_channel_mode, int, 0400); -MODULE_PARM_DESC(lvds_channel_mode, +i915_param_named_unsafe(lvds_channel_mode, int, 0400, "Specify LVDS channel mode " "(0=probe BIOS [default], 1=single-channel, 2=dual-channel)"); -i915_param_named_unsafe(panel_use_ssc, int, 0600); -MODULE_PARM_DESC(panel_use_ssc, +i915_param_named_unsafe(panel_use_ssc, int, 0600, "Use Spread Spectrum Clock with panels [LVDS/eDP] " "(default: auto from VBT)"); -i915_param_named_unsafe(vbt_sdvo_panel_type, int, 0400); -MODULE_PARM_DESC(vbt_sdvo_panel_type, +i915_param_named_unsafe(vbt_sdvo_panel_type, int, 0400, "Override/Ignore selection of SDVO panel mode in the VBT " "(-2=ignore, -1=auto [default], index in VBT BIOS table)"); -i915_param_named_unsafe(reset, int, 0600); -MODULE_PARM_DESC(reset, "Attempt GPU resets (0=disabled, 1=full gpu reset, 2=engine reset [default])"); +i915_param_named_unsafe(reset, int, 0600, + "Attempt GPU resets (0=disabled, 1=full gpu reset, 2=engine reset [default])"); -i915_param_named_unsafe(vbt_firmware, charp, 0400); -MODULE_PARM_DESC(vbt_firmware, - "Load VBT from specified file under /lib/firmware"); +i915_param_named_unsafe(vbt_firmware, charp, 0400, + "Load VBT from specified file under /lib/firmware"); #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) -i915_param_named(error_capture, bool, 0600); -MODULE_PARM_DESC(error_capture, +i915_param_named(error_capture, bool, 0600, "Record the GPU state following a hang. " "This information in /sys/class/drm/card/error is vital for " "triaging and debugging hangs."); #endif -i915_param_named_unsafe(enable_hangcheck, bool, 0644); -MODULE_PARM_DESC(enable_hangcheck, +i915_param_named_unsafe(enable_hangcheck, bool, 0644, "Periodically check GPU activity for detecting hangs. " "WARNING: Disabling this can cause system wide hangs. " "(default: true)"); -i915_param_named_unsafe(enable_ppgtt, int, 0400); -MODULE_PARM_DESC(enable_ppgtt, +i915_param_named_unsafe(enable_ppgtt, int, 0400, "Override PPGTT usage. " "(-1=auto [default], 0=disabled, 1=aliasing, 2=full, 3=full with extended address space)"); -i915_param_named_unsafe(enable_execlists, int, 0400); -MODULE_PARM_DESC(enable_execlists, +i915_param_named_unsafe(enable_execlists, int, 0400, "Override execlists usage. " "(-1=auto [default], 0=disabled, 1=enabled)"); -i915_param_named_unsafe(enable_psr, int, 0600); -MODULE_PARM_DESC(enable_psr, "Enable PSR " - "(0=disabled, 1=enabled - link mode chosen per-platform, 2=force link-standby mode, 3=force link-off mode) " - "Default: -1 (use per-chip default)"); +i915_param_named_unsafe(enable_psr, int, 0600, + "Enable PSR " + "(0=disabled, 1=enabled - link mode chosen per-platform, 2=force link-standby mode, 3=force link-off mode) " + "Default: -1 (use per-chip default)"); -i915_param_named_unsafe(alpha_support, bool, 0400); -MODULE_PARM_DESC(alpha_support, +i915_param_named_unsafe(alpha_support, bool, 0400, "Enable alpha quality driver support for latest hardware. " "See also CONFIG_DRM_I915_ALPHA_SUPPORT."); -i915_param_named_unsafe(disable_power_well, int, 0400); -MODULE_PARM_DESC(disable_power_well, +i915_param_named_unsafe(disable_power_well, int, 0400, "Disable display power wells when possible " "(-1=auto [default], 0=power wells always on, 1=power wells disabled when possible)"); -i915_param_named_unsafe(enable_ips, int, 0600); -MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)"); +i915_param_named_unsafe(enable_ips, int, 0600, "Enable IPS (default: true)"); -i915_param_named(fastboot, bool, 0600); -MODULE_PARM_DESC(fastboot, +i915_param_named(fastboot, bool, 0600, "Try to skip unnecessary mode sets at boot time (default: false)"); -i915_param_named_unsafe(prefault_disable, bool, 0600); -MODULE_PARM_DESC(prefault_disable, +i915_param_named_unsafe(prefault_disable, bool, 0600, "Disable page prefaulting for pread/pwrite/reloc (default:false). " "For developers only."); -i915_param_named_unsafe(load_detect_test, bool, 0600); -MODULE_PARM_DESC(load_detect_test, +i915_param_named_unsafe(load_detect_test, bool, 0600, "Force-enable the VGA load detect code for testing (default:false). " "For developers only."); -i915_param_named_unsafe(force_reset_modeset_test, bool, 0600); -MODULE_PARM_DESC(force_reset_modeset_test, +i915_param_named_unsafe(force_reset_modeset_test, bool, 0600, "Force a modeset during gpu reset for testing (default:false). " "For developers only."); -i915_param_named_unsafe(invert_brightness, int, 0600); -MODULE_PARM_DESC(invert_brightness, +i915_param_named_unsafe(invert_brightness, int, 0600, "Invert backlight brightness " "(-1 force normal, 0 machine defaults, 1 force inversion), please " "report PCI device ID, subsystem vendor and subsystem device ID " "to dri-devel@lists.freedesktop.org, if your machine needs it. " "It will then be included in an upcoming module version."); -i915_param_named(disable_display, bool, 0400); -MODULE_PARM_DESC(disable_display, "Disable display (default: false)"); +i915_param_named(disable_display, bool, 0400, + "Disable display (default: false)"); -i915_param_named_unsafe(enable_cmd_parser, bool, 0400); -MODULE_PARM_DESC(enable_cmd_parser, - "Enable command parsing (true=enabled [default], false=disabled)"); +i915_param_named_unsafe(enable_cmd_parser, bool, 0400, + "Enable command parsing (true=enabled [default], false=disabled)"); -i915_param_named_unsafe(use_mmio_flip, int, 0600); -MODULE_PARM_DESC(use_mmio_flip, - "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)"); +i915_param_named_unsafe(use_mmio_flip, int, 0600, + "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)"); -i915_param_named(mmio_debug, int, 0600); -MODULE_PARM_DESC(mmio_debug, +i915_param_named(mmio_debug, int, 0600, "Enable the MMIO debug code for the first N failures (default: off). " "This may negatively affect performance."); -i915_param_named(verbose_state_checks, bool, 0600); -MODULE_PARM_DESC(verbose_state_checks, +i915_param_named(verbose_state_checks, bool, 0600, "Enable verbose logs (ie. WARN_ON()) in case of unexpected hw state conditions."); -i915_param_named_unsafe(nuclear_pageflip, bool, 0400); -MODULE_PARM_DESC(nuclear_pageflip, - "Force enable atomic functionality on platforms that don't have full support yet."); +i915_param_named_unsafe(nuclear_pageflip, bool, 0400, + "Force enable atomic functionality on platforms that don't have full support yet."); /* WA to get away with the default setting in VBT for early platforms.Will be removed */ -i915_param_named_unsafe(edp_vswing, int, 0400); -MODULE_PARM_DESC(edp_vswing, - "Ignore/Override vswing pre-emph table selection from VBT " - "(0=use value from vbt [default], 1=low power swing(200mV)," - "2=default swing(400mV))"); - -i915_param_named_unsafe(enable_guc_loading, int, 0400); -MODULE_PARM_DESC(enable_guc_loading, - "Enable GuC firmware loading " - "(-1=auto, 0=never [default], 1=if available, 2=required)"); - -i915_param_named_unsafe(enable_guc_submission, int, 0400); -MODULE_PARM_DESC(enable_guc_submission, - "Enable GuC submission " - "(-1=auto, 0=never [default], 1=if available, 2=required)"); - -i915_param_named(guc_log_level, int, 0400); -MODULE_PARM_DESC(guc_log_level, +i915_param_named_unsafe(edp_vswing, int, 0400, + "Ignore/Override vswing pre-emph table selection from VBT " + "(0=use value from vbt [default], 1=low power swing(200mV)," + "2=default swing(400mV))"); + +i915_param_named_unsafe(enable_guc_loading, int, 0400, + "Enable GuC firmware loading " + "(-1=auto, 0=never [default], 1=if available, 2=required)"); + +i915_param_named_unsafe(enable_guc_submission, int, 0400, + "Enable GuC submission " + "(-1=auto, 0=never [default], 1=if available, 2=required)"); + +i915_param_named(guc_log_level, int, 0400, "GuC firmware logging level (-1:disabled (default), 0-3:enabled)"); -i915_param_named_unsafe(guc_firmware_path, charp, 0400); -MODULE_PARM_DESC(guc_firmware_path, +i915_param_named_unsafe(guc_firmware_path, charp, 0400, "GuC firmware path to use instead of the default one"); -i915_param_named_unsafe(huc_firmware_path, charp, 0400); -MODULE_PARM_DESC(huc_firmware_path, +i915_param_named_unsafe(huc_firmware_path, charp, 0400, "HuC firmware path to use instead of the default one"); -i915_param_named_unsafe(enable_dp_mst, bool, 0600); -MODULE_PARM_DESC(enable_dp_mst, +i915_param_named_unsafe(enable_dp_mst, bool, 0600, "Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)"); -i915_param_named_unsafe(inject_load_failure, uint, 0400); -MODULE_PARM_DESC(inject_load_failure, + +i915_param_named_unsafe(inject_load_failure, uint, 0400, "Force an error after a number of failure check points (0:disabled (default), N:force failure at the Nth failure check point)"); -i915_param_named(enable_dpcd_backlight, bool, 0600); -MODULE_PARM_DESC(enable_dpcd_backlight, + +i915_param_named(enable_dpcd_backlight, bool, 0600, "Enable support for DPCD backlight control (default:false)"); -i915_param_named(enable_gvt, bool, 0400); -MODULE_PARM_DESC(enable_gvt, +i915_param_named(enable_gvt, bool, 0400, "Enable support for Intel GVT-g graphics virtualization host support(default:false)"); -- cgit v1.2.3 From c5498089463b94690085158eba7dd29835c8c9b8 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:37:01 +0300 Subject: drm/i915: Mask everything in ring HWSTAM on gen6+ in ringbuffer mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The execlist code already masks everything in the ring HWSTAM, but the ringbuffer code doesn't. Let's go ahead and do that. Pre-gen6 platforms setup HWSTAM during irq setup already since there's just the one register, and it also contains bits for non-ring interrupts. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-13-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 8af8871a8594..22e5ea8516b6 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -428,6 +428,9 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *engine) mmio = RING_HWS_PGA(engine->mmio_base); } + if (INTEL_GEN(dev_priv) >= 6) + I915_WRITE(RING_HWSTAM(engine->mmio_base), 0xffffffff); + I915_WRITE(mmio, engine->status_page.ggtt_offset); POSTING_READ(mmio); -- cgit v1.2.3 From d420a50c21efa4ec9e43494547de4f2b1826e167 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:37:03 +0300 Subject: drm/i915: Clean up the HWSTAM mess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we're unmasking some random looking bits in HWSTAM on gen3/4/5. The two bits we apparently unmask are 0 and 12, and also bits 16-31 on gen4/5. What those bits do depends on the gen as follows: bit 0: Breakpoint (gen2), ASLE (gen3), reserved (gen4), render user interrupt (gen5) bit 12: Sync flush statusa (gen2-4), reserved (gen5) bit 16-31: The ones that can unmasked seem to be mostly some display stuff on gen4. Bit 18 is the PIPE_CONTROL notify, which might be the only intresting one. On gen5 all the bits are reserved. So I don't know whether we actually depend on that status page write somehow. Extra seqno coherency by accident perhaps? Except we don't even unmask the user interrupt bit in HWSTAM except on gen5, and sync flush isn't something we use normally, so seems unlikely. So let's just assume we don't need any of this and mask everything in HWSTAM. From gen6 onwards there's a separate HWSTAM for each engine, and so we deal with them during the engine setup. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-15-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e8bb6c644fa4..2b3a84de9460 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3058,7 +3058,8 @@ static void ironlake_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); - I915_WRITE(HWSTAM, 0xffffffff); + if (IS_GEN5(dev_priv)) + I915_WRITE(HWSTAM, 0xffffffff); GEN3_IRQ_RESET(DE); if (IS_GEN7(dev_priv)) @@ -3419,8 +3420,6 @@ static int ironlake_irq_postinstall(struct drm_device *dev) dev_priv->irq_mask = ~display_mask; - I915_WRITE(HWSTAM, 0xeffe); - ibx_irq_pre_postinstall(dev); GEN3_IRQ_INIT(DE, dev_priv->irq_mask, display_mask | extra_mask); @@ -3621,8 +3620,6 @@ static void valleyview_irq_uninstall(struct drm_device *dev) gen5_gt_irq_reset(dev_priv); - I915_WRITE(HWSTAM, 0xffffffff); - spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) vlv_display_irq_reset(dev_priv); @@ -3657,6 +3654,8 @@ static void i8xx_irq_preinstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE16(HWSTAM, 0xffff); + GEN2_IRQ_RESET(); } @@ -3738,6 +3737,8 @@ static void i8xx_irq_uninstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); + I915_WRITE16(HWSTAM, 0xffff); + GEN2_IRQ_RESET(); } @@ -3752,7 +3753,7 @@ static void i915_irq_preinstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); - I915_WRITE(HWSTAM, 0xffffeffe); + I915_WRITE(HWSTAM, 0xffffffff); GEN3_IRQ_RESET(); } @@ -3873,7 +3874,7 @@ static void i965_irq_preinstall(struct drm_device * dev) i9xx_pipestat_irq_reset(dev_priv); - I915_WRITE(HWSTAM, 0xeffe); + I915_WRITE(HWSTAM, 0xffffffff); GEN3_IRQ_RESET(); } -- cgit v1.2.3 From 6bcdb1c839b5d75270d4a492221a7af891d8a484 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:37:04 +0300 Subject: drm/i915: Remove duplicated irq_preinstall/uninstall hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the irq_preinstall and irq_uninstall hooks are now identical. Let's just rename them all the irq_reset and remove the pointless duplicates. Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-16-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 117 ++++++---------------------------------- 1 file changed, 17 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2b3a84de9460..4d0e8f76ed1a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3070,7 +3070,7 @@ static void ironlake_irq_reset(struct drm_device *dev) ibx_irq_reset(dev_priv); } -static void valleyview_irq_preinstall(struct drm_device *dev) +static void valleyview_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -3144,7 +3144,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, synchronize_irq(dev_priv->drm.irq); } -static void cherryview_irq_preinstall(struct drm_device *dev) +static void cherryview_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -3606,49 +3606,7 @@ static int cherryview_irq_postinstall(struct drm_device *dev) return 0; } -static void gen8_irq_uninstall(struct drm_device *dev) -{ - gen8_irq_reset(dev); -} - -static void valleyview_irq_uninstall(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - I915_WRITE(VLV_MASTER_IER, 0); - POSTING_READ(VLV_MASTER_IER); - - gen5_gt_irq_reset(dev_priv); - - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display_irqs_enabled) - vlv_display_irq_reset(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); -} - -static void cherryview_irq_uninstall(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - I915_WRITE(GEN8_MASTER_IRQ, 0); - POSTING_READ(GEN8_MASTER_IRQ); - - gen8_gt_irq_reset(dev_priv); - - GEN3_IRQ_RESET(GEN8_PCU_); - - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display_irqs_enabled) - vlv_display_irq_reset(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); -} - -static void ironlake_irq_uninstall(struct drm_device *dev) -{ - ironlake_irq_reset(dev); -} - -static void i8xx_irq_preinstall(struct drm_device * dev) +static void i8xx_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -3731,18 +3689,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) return ret; } -static void i8xx_irq_uninstall(struct drm_device * dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - i9xx_pipestat_irq_reset(dev_priv); - - I915_WRITE16(HWSTAM, 0xffff); - - GEN2_IRQ_RESET(); -} - -static void i915_irq_preinstall(struct drm_device * dev) +static void i915_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -3849,23 +3796,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) return ret; } -static void i915_irq_uninstall(struct drm_device * dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - if (I915_HAS_HOTPLUG(dev_priv)) { - i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - } - - i9xx_pipestat_irq_reset(dev_priv); - - I915_WRITE(HWSTAM, 0xffffffff); - - GEN3_IRQ_RESET(); -} - -static void i965_irq_preinstall(struct drm_device * dev) +static void i965_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -4011,20 +3942,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) return ret; } -static void i965_irq_uninstall(struct drm_device * dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - - i9xx_pipestat_irq_reset(dev_priv); - - I915_WRITE(HWSTAM, 0xffffffff); - - GEN3_IRQ_RESET(); -} - /** * intel_irq_init - initializes irq support * @dev_priv: i915 device instance @@ -4105,17 +4022,17 @@ void intel_irq_init(struct drm_i915_private *dev_priv) if (IS_CHERRYVIEW(dev_priv)) { dev->driver->irq_handler = cherryview_irq_handler; - dev->driver->irq_preinstall = cherryview_irq_preinstall; + dev->driver->irq_preinstall = cherryview_irq_reset; dev->driver->irq_postinstall = cherryview_irq_postinstall; - dev->driver->irq_uninstall = cherryview_irq_uninstall; + dev->driver->irq_uninstall = cherryview_irq_reset; dev->driver->enable_vblank = i965_enable_vblank; dev->driver->disable_vblank = i965_disable_vblank; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; } else if (IS_VALLEYVIEW(dev_priv)) { dev->driver->irq_handler = valleyview_irq_handler; - dev->driver->irq_preinstall = valleyview_irq_preinstall; + dev->driver->irq_preinstall = valleyview_irq_reset; dev->driver->irq_postinstall = valleyview_irq_postinstall; - dev->driver->irq_uninstall = valleyview_irq_uninstall; + dev->driver->irq_uninstall = valleyview_irq_reset; dev->driver->enable_vblank = i965_enable_vblank; dev->driver->disable_vblank = i965_disable_vblank; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; @@ -4123,7 +4040,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev->driver->irq_handler = gen8_irq_handler; dev->driver->irq_preinstall = gen8_irq_reset; dev->driver->irq_postinstall = gen8_irq_postinstall; - dev->driver->irq_uninstall = gen8_irq_uninstall; + dev->driver->irq_uninstall = gen8_irq_reset; dev->driver->enable_vblank = gen8_enable_vblank; dev->driver->disable_vblank = gen8_disable_vblank; if (IS_GEN9_LP(dev_priv)) @@ -4137,29 +4054,29 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev->driver->irq_handler = ironlake_irq_handler; dev->driver->irq_preinstall = ironlake_irq_reset; dev->driver->irq_postinstall = ironlake_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; + dev->driver->irq_uninstall = ironlake_irq_reset; dev->driver->enable_vblank = ironlake_enable_vblank; dev->driver->disable_vblank = ironlake_disable_vblank; dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; } else { if (IS_GEN2(dev_priv)) { - dev->driver->irq_preinstall = i8xx_irq_preinstall; + dev->driver->irq_preinstall = i8xx_irq_reset; dev->driver->irq_postinstall = i8xx_irq_postinstall; dev->driver->irq_handler = i8xx_irq_handler; - dev->driver->irq_uninstall = i8xx_irq_uninstall; + dev->driver->irq_uninstall = i8xx_irq_reset; dev->driver->enable_vblank = i8xx_enable_vblank; dev->driver->disable_vblank = i8xx_disable_vblank; } else if (IS_GEN3(dev_priv)) { - dev->driver->irq_preinstall = i915_irq_preinstall; + dev->driver->irq_preinstall = i915_irq_reset; dev->driver->irq_postinstall = i915_irq_postinstall; - dev->driver->irq_uninstall = i915_irq_uninstall; + dev->driver->irq_uninstall = i915_irq_reset; dev->driver->irq_handler = i915_irq_handler; dev->driver->enable_vblank = i8xx_enable_vblank; dev->driver->disable_vblank = i8xx_disable_vblank; } else { - dev->driver->irq_preinstall = i965_irq_preinstall; + dev->driver->irq_preinstall = i965_irq_reset; dev->driver->irq_postinstall = i965_irq_postinstall; - dev->driver->irq_uninstall = i965_irq_uninstall; + dev->driver->irq_uninstall = i965_irq_reset; dev->driver->irq_handler = i965_irq_handler; dev->driver->enable_vblank = i965_enable_vblank; dev->driver->disable_vblank = i965_disable_vblank; -- cgit v1.2.3 From 309bd8ed464fc08f79152e4a18b1da2b11410842 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 18 Aug 2017 21:37:05 +0300 Subject: drm/i915: Reinstate GMBUS and AUX interrupts on gen4/g4x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we're not using MSI anymore on gen4 we can start using GMBUS and AUX interrupts again. These were disabled on account of them causing the hardware to somehow generate legacy interrupts even when MSI was enabled. See commit c12aba5aa0e6 ("drm/i915: stop using GMBUS IRQs on Gen4 chips") and commit 4e6b788c3f23 ("drm/i915: Disable dp aux irq on g4x") for more details. Cc: Daniel Vetter Cc: Chris Wilson Cc: Jiri Kosina Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170818183705.27850-17-ville.syrjala@linux.intel.com Acked-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 8 +++++--- drivers/gpu/drm/i915/i915_pci.c | 6 ------ 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5d379c89722c..a24659b5e6b5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -777,7 +777,6 @@ struct intel_csr { func(has_fpga_dbg); \ func(has_full_ppgtt); \ func(has_full_48bit_ppgtt); \ - func(has_gmbus_irq); \ func(has_gmch_display); \ func(has_guc); \ func(has_guc_ct); \ @@ -3095,9 +3094,12 @@ intel_info(const struct drm_i915_private *dev_priv) * even when in MSI mode. This results in spurious interrupt warnings if the * legacy irq no. is shared with another device. The kernel then disables that * interrupt source and so prevents the other device from working properly. + * + * Since we don't enable MSI anymore on gen4, we can always use GMBUS/AUX + * interrupts. */ -#define HAS_AUX_IRQ(dev_priv) ((dev_priv)->info.gen >= 5) -#define HAS_GMBUS_IRQ(dev_priv) ((dev_priv)->info.has_gmbus_irq) +#define HAS_AUX_IRQ(dev_priv) true +#define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4) /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte * rows, which changed the alignment requirements and fence programming. diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 129877b94c20..853002fb0371 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -200,7 +200,6 @@ static const struct intel_device_info intel_gm45_info __initconst = { #define GEN5_FEATURES \ .gen = 5, .num_pipes = 2, \ .has_hotplug = 1, \ - .has_gmbus_irq = 1, \ .ring_mask = RENDER_RING | BSD_RING, \ .has_snoop = true, \ GEN_DEFAULT_PIPEOFFSETS, \ @@ -225,7 +224,6 @@ static const struct intel_device_info intel_ironlake_m_info __initconst = { .has_llc = 1, \ .has_rc6 = 1, \ .has_rc6p = 1, \ - .has_gmbus_irq = 1, \ .has_aliasing_ppgtt = 1, \ GEN_DEFAULT_PIPEOFFSETS, \ CURSOR_OFFSETS @@ -268,7 +266,6 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info __initconst = .has_llc = 1, \ .has_rc6 = 1, \ .has_rc6p = 1, \ - .has_gmbus_irq = 1, \ .has_aliasing_ppgtt = 1, \ .has_full_ppgtt = 1, \ GEN_DEFAULT_PIPEOFFSETS, \ @@ -321,7 +318,6 @@ static const struct intel_device_info intel_valleyview_info __initconst = { .has_psr = 1, .has_runtime_pm = 1, .has_rc6 = 1, - .has_gmbus_irq = 1, .has_gmch_display = 1, .has_hotplug = 1, .has_aliasing_ppgtt = 1, @@ -412,7 +408,6 @@ static const struct intel_device_info intel_cherryview_info __initconst = { .has_runtime_pm = 1, .has_resource_streamer = 1, .has_rc6 = 1, - .has_gmbus_irq = 1, .has_logical_ring_contexts = 1, .has_gmch_display = 1, .has_aliasing_ppgtt = 1, @@ -474,7 +469,6 @@ static const struct intel_device_info intel_skylake_gt4_info __initconst = { .has_resource_streamer = 1, \ .has_rc6 = 1, \ .has_dp_mst = 1, \ - .has_gmbus_irq = 1, \ .has_logical_ring_contexts = 1, \ .has_guc = 1, \ .has_aliasing_ppgtt = 1, \ -- cgit v1.2.3 From e8620acc90785ecbde041d241a13778044df9208 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Fri, 1 Sep 2017 10:01:44 +0800 Subject: clk: rockchip: add pclk_pmu as critical clock on rk3128 pclk_pmu need always on, and no dts node to handle this clk, so make it as critical clock Signed-off-by: Elaine Zhang Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3128.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c index 62d7854e4b87..f15c9b874911 100644 --- a/drivers/clk/rockchip/clk-rk3128.c +++ b/drivers/clk/rockchip/clk-rk3128.c @@ -541,7 +541,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), GATE(0, "pclk_mipiphy", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 0, GFLAGS), - GATE(0, "pclk_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 2, GFLAGS), + GATE(0, "pclk_pmu", "pclk_pmu_pre", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS), GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 3, GFLAGS), /* PD_MMC */ @@ -577,6 +577,7 @@ static const char *const rk3128_critical_clocks[] __initconst = { "aclk_peri", "hclk_peri", "pclk_peri", + "pclk_pmu", }; static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np) -- cgit v1.2.3 From a4eb286565eb07ee5acfe6a1409f68ad9f663845 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Fri, 1 Sep 2017 10:01:45 +0800 Subject: clk: rockchip: fix up rk3128 pvtm and mipi_24m gate regs error A copy-paste error made them use the wrong bits in the register. Signed-off-by: Elaine Zhang Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3128.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c index f15c9b874911..ce02d2cff608 100644 --- a/drivers/clk/rockchip/clk-rk3128.c +++ b/drivers/clk/rockchip/clk-rk3128.c @@ -315,13 +315,13 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { RK2928_CLKGATE_CON(10), 8, GFLAGS), GATE(SCLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0, - RK2928_CLKGATE_CON(10), 8, GFLAGS), + RK2928_CLKGATE_CON(10), 0, GFLAGS), GATE(SCLK_PVTM_GPU, "clk_pvtm_gpu", "xin24m", 0, - RK2928_CLKGATE_CON(10), 8, GFLAGS), + RK2928_CLKGATE_CON(10), 1, GFLAGS), GATE(SCLK_PVTM_FUNC, "clk_pvtm_func", "xin24m", 0, - RK2928_CLKGATE_CON(10), 8, GFLAGS), + RK2928_CLKGATE_CON(10), 2, GFLAGS), GATE(SCLK_MIPI_24M, "clk_mipi_24m", "xin24m", CLK_IGNORE_UNUSED, - RK2928_CLKGATE_CON(10), 8, GFLAGS), + RK2928_CLKGATE_CON(2), 15, GFLAGS), COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0, RK2928_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS, -- cgit v1.2.3 From 00e6751ffc9e6e0651e514961316fd15f0409683 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Fri, 1 Sep 2017 10:01:46 +0800 Subject: clk: rockchip: add sclk_timer5 as critical clock on rk3128 sclk_timer5 is for arm arch counter, so need always on. but no dts node to handle this clk, so make it as critical clock Signed-off-by: Elaine Zhang Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3128.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c index ce02d2cff608..5970a50671b9 100644 --- a/drivers/clk/rockchip/clk-rk3128.c +++ b/drivers/clk/rockchip/clk-rk3128.c @@ -578,6 +578,7 @@ static const char *const rk3128_critical_clocks[] __initconst = { "hclk_peri", "pclk_peri", "pclk_pmu", + "sclk_timer5", }; static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np) -- cgit v1.2.3 From a6c215e21b0dc5fe9416dce90f9acc2ea53c4502 Mon Sep 17 00:00:00 2001 From: Jeffrey Chu Date: Fri, 8 Sep 2017 21:08:58 +0000 Subject: USB: serial: ftdi_sio: add id for Cypress WICED dev board Add CYPRESS_VID vid and CYPRESS_WICED_BT_USB and CYPRESS_WICED_WL_USB device IDs to ftdi_sio driver. Signed-off-by: Jeffrey Chu Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 7 +++++++ 2 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1cec03799cdf..49d1b2d4606d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, + { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 4fcf1cecb6d7..f9d15bd62785 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -609,6 +609,13 @@ #define ADI_GNICE_PID 0xF000 #define ADI_GNICEPLUS_PID 0xF001 +/* + * Cypress WICED USB UART + */ +#define CYPRESS_VID 0x04B4 +#define CYPRESS_WICED_BT_USB_PID 0x009B +#define CYPRESS_WICED_WL_USB_PID 0xF900 + /* * Microchip Technology, Inc. * -- cgit v1.2.3 From 837ddc4793a69b256ac5e781a5e729b448a8d983 Mon Sep 17 00:00:00 2001 From: Henryk Heisig Date: Mon, 11 Sep 2017 17:57:34 +0200 Subject: USB: serial: option: add support for TP-Link LTE module This commit adds support for TP-Link LTE mPCIe module is used in in TP-Link MR200v1, MR6400v1 and v2 routers. Signed-off-by: Henryk Heisig Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 54bfef13966a..ba672cf4e888 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb); /* TP-LINK Incorporated products */ #define TPLINK_VENDOR_ID 0x2357 +#define TPLINK_PRODUCT_LTE 0x000D #define TPLINK_PRODUCT_MA180 0x0201 /* Changhong products */ @@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, + { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ -- cgit v1.2.3 From 2d48a237c8b61b457d146310d7e1e61224d0ca56 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Sat, 9 Sep 2017 06:02:46 +0200 Subject: ARC: reset: Only build on archs that have IOMEM This avoids the error: drivers/reset/reset-hsdk-v1.o: In function `hsdkv1_reset_probe': /home/thomas/git/linux/drivers/reset/reset-hsdk-v1.c:101: undefined reference to `devm_ioremap_resource' collect2: error: ld returned 1 exit status Signed-off-by: Thomas Meyer Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index e0c393214264..d063bd5373dd 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -36,6 +36,7 @@ config RESET_BERLIN config RESET_HSDK_V1 bool "HSDK v1 Reset Driver" + depends on HAS_IOMEM default n help This enables the reset controller driver for HSDK v1. -- cgit v1.2.3 From 70e743e4cec3733dc13559f6184b35d358b9ef3f Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Thu, 14 Sep 2017 16:52:59 +0200 Subject: uwb: ensure that endpoint is interrupt hwarc_neep_init() assumes that endpoint 0 is interrupt, but there's no check for that, which results in a WARNING in USB core code, when a bad USB descriptor is provided from a device: usb 1-1: BOGUS urb xfer, pipe 1 != type 3 ------------[ cut here ]------------ WARNING: CPU: 0 PID: 3 at drivers/usb/core/urb.c:449 usb_submit_urb+0xf8a/0x11d0 Modules linked in: CPU: 0 PID: 3 Comm: kworker/0:0 Not tainted 4.13.0+ #111 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Workqueue: usb_hub_wq hub_event task: ffff88006bdc1a00 task.stack: ffff88006bde8000 RIP: 0010:usb_submit_urb+0xf8a/0x11d0 drivers/usb/core/urb.c:448 RSP: 0018:ffff88006bdee3c0 EFLAGS: 00010282 RAX: 0000000000000029 RBX: ffff8800672a7200 RCX: 0000000000000000 RDX: 0000000000000029 RSI: ffff88006c815c78 RDI: ffffed000d7bdc6a RBP: ffff88006bdee4c0 R08: fffffbfff0fe00ff R09: fffffbfff0fe00ff R10: 0000000000000018 R11: fffffbfff0fe00fe R12: 1ffff1000d7bdc7f R13: 0000000000000003 R14: 0000000000000001 R15: ffff88006b02cc90 FS: 0000000000000000(0000) GS:ffff88006c800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fe4daddf000 CR3: 000000006add6000 CR4: 00000000000006f0 Call Trace: hwarc_neep_init+0x4ce/0x9c0 drivers/uwb/hwa-rc.c:710 uwb_rc_add+0x2fb/0x730 drivers/uwb/lc-rc.c:361 hwarc_probe+0x34e/0x9b0 drivers/uwb/hwa-rc.c:858 usb_probe_interface+0x351/0x8d0 drivers/usb/core/driver.c:361 really_probe drivers/base/dd.c:385 driver_probe_device+0x610/0xa00 drivers/base/dd.c:529 __device_attach_driver+0x230/0x290 drivers/base/dd.c:625 bus_for_each_drv+0x15e/0x210 drivers/base/bus.c:463 __device_attach+0x269/0x3c0 drivers/base/dd.c:682 device_initial_probe+0x1f/0x30 drivers/base/dd.c:729 bus_probe_device+0x1da/0x280 drivers/base/bus.c:523 device_add+0xcf9/0x1640 drivers/base/core.c:1703 usb_set_configuration+0x1064/0x1890 drivers/usb/core/message.c:1932 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266 really_probe drivers/base/dd.c:385 driver_probe_device+0x610/0xa00 drivers/base/dd.c:529 __device_attach_driver+0x230/0x290 drivers/base/dd.c:625 bus_for_each_drv+0x15e/0x210 drivers/base/bus.c:463 __device_attach+0x269/0x3c0 drivers/base/dd.c:682 device_initial_probe+0x1f/0x30 drivers/base/dd.c:729 bus_probe_device+0x1da/0x280 drivers/base/bus.c:523 device_add+0xcf9/0x1640 drivers/base/core.c:1703 usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457 hub_port_connect drivers/usb/core/hub.c:4890 hub_port_connect_change drivers/usb/core/hub.c:4996 port_event drivers/usb/core/hub.c:5102 hub_event+0x23c8/0x37c0 drivers/usb/core/hub.c:5182 process_one_work+0x9fb/0x1570 kernel/workqueue.c:2097 worker_thread+0x1e4/0x1350 kernel/workqueue.c:2231 kthread+0x324/0x3f0 kernel/kthread.c:231 ret_from_fork+0x25/0x30 arch/x86/entry/entry_64.S:425 Code: 48 8b 85 30 ff ff ff 48 8d b8 98 00 00 00 e8 8e 93 07 ff 45 89 e8 44 89 f1 4c 89 fa 48 89 c6 48 c7 c7 a0 e5 55 86 e8 20 08 8f fd <0f> ff e9 9b f7 ff ff e8 4a 04 d6 fd e9 80 f7 ff ff e8 60 11 a6 ---[ end trace 55d741234124cfc3 ]--- Check that endpoint is interrupt. Found by syzkaller. Signed-off-by: Andrey Konovalov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/hwa-rc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 35a1e777b449..9a53912bdfe9 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -825,6 +825,8 @@ static int hwarc_probe(struct usb_interface *iface, if (iface->cur_altsetting->desc.bNumEndpoints < 1) return -ENODEV; + if (!usb_endpoint_xfer_int(&iface->cur_altsetting->endpoint[0].desc)) + return -ENODEV; result = -ENOMEM; uwb_rc = uwb_rc_alloc(); -- cgit v1.2.3 From bbf26183b7a6236ba602f4d6a2f7cade35bba043 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Thu, 14 Sep 2017 14:30:55 +0200 Subject: uwb: properly check kthread_run return value uwbd_start() calls kthread_run() and checks that the return value is not NULL. But the return value is not NULL in case kthread_run() fails, it takes the form of ERR_PTR(-EINTR). Use IS_ERR() instead. Also add a check to uwbd_stop(). Signed-off-by: Andrey Konovalov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/uwbd.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 01c20a260a8b..39dd4ef53c77 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c @@ -302,18 +302,22 @@ static int uwbd(void *param) /** Start the UWB daemon */ void uwbd_start(struct uwb_rc *rc) { - rc->uwbd.task = kthread_run(uwbd, rc, "uwbd"); - if (rc->uwbd.task == NULL) + struct task_struct *task = kthread_run(uwbd, rc, "uwbd"); + if (IS_ERR(task)) { + rc->uwbd.task = NULL; printk(KERN_ERR "UWB: Cannot start management daemon; " "UWB won't work\n"); - else + } else { + rc->uwbd.task = task; rc->uwbd.pid = rc->uwbd.task->pid; + } } /* Stop the UWB daemon and free any unprocessed events */ void uwbd_stop(struct uwb_rc *rc) { - kthread_stop(rc->uwbd.task); + if (rc->uwbd.task) + kthread_stop(rc->uwbd.task); uwbd_flush(rc); } -- cgit v1.2.3 From b2a542bbb3081dbd64acc8929c140d196664c406 Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Tue, 5 Sep 2017 11:40:56 +0300 Subject: usb: Increase quirk delay for USB devices Commit e0429362ab15 ("usb: Add device quirk for Logitech HD Pro Webcams C920 and C930e") introduced quirk to workaround an issue with some Logitech webcams. The workaround is introducing delay for some USB operations. According to our testing, delay introduced by original commit is not long enough and in rare cases we still see issues described by the aforementioned commit. This patch increases delays introduced by original commit. Having this patch applied we do not see those problems anymore. Signed-off-by: Dmitry Fleytman Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 2 +- drivers/usb/core/hub.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 4be52c602e9b..854c8d66cfbe 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -852,7 +852,7 @@ int usb_get_configuration(struct usb_device *dev) } if (dev->quirks & USB_QUIRK_DELAY_INIT) - msleep(100); + msleep(200); result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 41eaf0b52518..b5c733613823 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4838,7 +4838,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, goto loop; if (udev->quirks & USB_QUIRK_DELAY_INIT) - msleep(1000); + msleep(2000); /* consecutive bus-powered hubs aren't reliable; they can * violate the voltage drop budget. if the new child has -- cgit v1.2.3 From 27a5f61b377bb62e4813af57fd91636f91ea5755 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 Sep 2017 18:31:00 +0100 Subject: drm/i915: Cancel all ready but queued requests when wedging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When wedging the hw, we want to mark all in-flight requests as -EIO. This is made slightly more complex by execlists who store the ready but not yet submitted-to-hw requests on a private queue (an rbtree priolist). Call into execlists to cancel not only the ELSP tracking for the submitted requests, but also the queue of unsubmitted requests. v2: Move the majority of engine_set_wedged to the backends (both legacy ringbuffer and execlists handling their own lists). Reported-by: Michał Winiarski Testcase: igt/gem_eio/in-flight-contexts Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Mika Kuoppala Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170915173100.26470-1-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski --- drivers/gpu/drm/i915/i915_gem.c | 38 +-------------------- drivers/gpu/drm/i915/intel_lrc.c | 60 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 20 +++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 8 +++++ 4 files changed, 89 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f445587c1a4b..b0bbf8729dae 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3022,9 +3022,6 @@ static void nop_submit_request(struct drm_i915_gem_request *request) static void engine_set_wedged(struct intel_engine_cs *engine) { - struct drm_i915_gem_request *request; - unsigned long flags; - /* We need to be sure that no thread is running the old callback as * we install the nop handler (otherwise we would submit a request * to hardware that will never complete). In order to prevent this @@ -3034,40 +3031,7 @@ static void engine_set_wedged(struct intel_engine_cs *engine) engine->submit_request = nop_submit_request; /* Mark all executing requests as skipped */ - spin_lock_irqsave(&engine->timeline->lock, flags); - list_for_each_entry(request, &engine->timeline->requests, link) - if (!i915_gem_request_completed(request)) - dma_fence_set_error(&request->fence, -EIO); - spin_unlock_irqrestore(&engine->timeline->lock, flags); - - /* - * Clear the execlists queue up before freeing the requests, as those - * are the ones that keep the context and ringbuffer backing objects - * pinned in place. - */ - - if (i915.enable_execlists) { - struct execlist_port *port = engine->execlist_port; - unsigned long flags; - unsigned int n; - - spin_lock_irqsave(&engine->timeline->lock, flags); - - for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) - i915_gem_request_put(port_request(&port[n])); - memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); - engine->execlist_queue = RB_ROOT; - engine->execlist_first = NULL; - - spin_unlock_irqrestore(&engine->timeline->lock, flags); - - /* The port is checked prior to scheduling a tasklet, but - * just in case we have suspended the tasklet to do the - * wedging make sure that when it wakes, it decides there - * is no work to do by clearing the irq_posted bit. - */ - clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - } + engine->cancel_requests(engine); /* Mark all pending requests as complete so that any concurrent * (lockless) lookup doesn't try and wait upon the request as we diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 1960ba5ff9e4..8e5caa5d3973 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -506,6 +506,65 @@ done: execlists_submit_ports(engine); } +static void execlists_cancel_requests(struct intel_engine_cs *engine) +{ + struct execlist_port *port = engine->execlist_port; + struct drm_i915_gem_request *rq, *rn; + struct rb_node *rb; + unsigned long flags; + unsigned long n; + + spin_lock_irqsave(&engine->timeline->lock, flags); + + /* Cancel the requests on the HW and clear the ELSP tracker. */ + for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) + i915_gem_request_put(port_request(&port[n])); + memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); + + /* Mark all executing requests as skipped. */ + list_for_each_entry(rq, &engine->timeline->requests, link) { + GEM_BUG_ON(!rq->global_seqno); + if (!i915_gem_request_completed(rq)) + dma_fence_set_error(&rq->fence, -EIO); + } + + /* Flush the queued requests to the timeline list (for retiring). */ + rb = engine->execlist_first; + while (rb) { + struct i915_priolist *p = rb_entry(rb, typeof(*p), node); + + list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { + INIT_LIST_HEAD(&rq->priotree.link); + rq->priotree.priority = INT_MAX; + + dma_fence_set_error(&rq->fence, -EIO); + __i915_gem_request_submit(rq); + } + + rb = rb_next(rb); + rb_erase(&p->node, &engine->execlist_queue); + INIT_LIST_HEAD(&p->requests); + if (p->priority != I915_PRIORITY_NORMAL) + kmem_cache_free(engine->i915->priorities, p); + } + + /* Remaining _unready_ requests will be nop'ed when submitted */ + + engine->execlist_queue = RB_ROOT; + engine->execlist_first = NULL; + GEM_BUG_ON(port_isset(&port[0])); + + /* + * The port is checked prior to scheduling a tasklet, but + * just in case we have suspended the tasklet to do the + * wedging make sure that when it wakes, it decides there + * is no work to do by clearing the irq_posted bit. + */ + clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); + + spin_unlock_irqrestore(&engine->timeline->lock, flags); +} + static bool execlists_elsp_ready(const struct intel_engine_cs *engine) { const struct execlist_port *port = engine->execlist_port; @@ -1704,6 +1763,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) static void execlists_set_default_submission(struct intel_engine_cs *engine) { engine->submit_request = execlists_submit_request; + engine->cancel_requests = execlists_cancel_requests; engine->schedule = execlists_schedule; engine->irq_tasklet.func = intel_lrc_irq_handler; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 22e5ea8516b6..85e64a45d0bf 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -782,6 +782,24 @@ static u32 *gen6_signal(struct drm_i915_gem_request *req, u32 *cs) return cs; } +static void cancel_requests(struct intel_engine_cs *engine) +{ + struct drm_i915_gem_request *request; + unsigned long flags; + + spin_lock_irqsave(&engine->timeline->lock, flags); + + /* Mark all submitted requests as skipped. */ + list_for_each_entry(request, &engine->timeline->requests, link) { + GEM_BUG_ON(!request->global_seqno); + if (!i915_gem_request_completed(request)) + dma_fence_set_error(&request->fence, -EIO); + } + /* Remaining _unready_ requests will be nop'ed when submitted */ + + spin_unlock_irqrestore(&engine->timeline->lock, flags); +} + static void i9xx_submit_request(struct drm_i915_gem_request *request) { struct drm_i915_private *dev_priv = request->i915; @@ -1996,11 +2014,13 @@ static void intel_ring_init_irq(struct drm_i915_private *dev_priv, static void i9xx_set_default_submission(struct intel_engine_cs *engine) { engine->submit_request = i9xx_submit_request; + engine->cancel_requests = cancel_requests; } static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine) { engine->submit_request = gen6_bsd_submit_request; + engine->cancel_requests = cancel_requests; } static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index abf171c3cb9c..138116a3b537 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -306,6 +306,14 @@ struct intel_engine_cs { void (*schedule)(struct drm_i915_gem_request *request, int priority); + /* + * Cancel all requests on the hardware, or queued for execution. + * This should only cancel the ready requests that have been + * submitted to the engine (via the engine->submit_request callback). + * This is called when marking the device as wedged. + */ + void (*cancel_requests)(struct intel_engine_cs *engine); + /* Some chipsets are not quite as coherent as advertised and need * an expensive kick to force a true read of the up-to-date seqno. * However, the up-to-date seqno is not always required and the last -- cgit v1.2.3 From 523e7c9278f0a2ca6174319e33f255161e74d16c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 16 Sep 2017 21:44:11 +0100 Subject: drm/i915/execlists: Kick start request processing after a reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During a reset, we may skip over completed requests and lost context-switch interrupts. Following the reset, we may then may end up with no active requests in the ELSP (and so do not resubmit to restart the engine), but have a queue of requests ready for execution. This is unlikely, it requires the last request to complete after the hang is detected, but not impossible. The outcome of this is that the engine stalls, possibly leading to full ring and indefinite wait under struct_mutex, eventually leading to a full driver hang. Alternatively, we can solve this by unsubmitting the incomplete requests and just kickstarting the tasklet. Michał has patches for that, which I initially disliked due to the extra complexity, but the complexity of this "simple" restart is growing... Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Mika Kuoppala Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170916204414.32762-1-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski --- drivers/gpu/drm/i915/intel_lrc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8e5caa5d3973..0f578f76f79f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1357,8 +1357,12 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) submit = true; } - if (submit && !i915.enable_guc_submission) - execlists_submit_ports(engine); + if (!i915.enable_guc_submission) { + if (submit) + execlists_submit_ports(engine); + else if (engine->execlist_first) + tasklet_schedule(&engine->irq_tasklet); + } return 0; } -- cgit v1.2.3 From 08dd3e1acc169100ee35df322e2146e39b43a827 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 16 Sep 2017 21:44:12 +0100 Subject: drm/i915/execlists: Move insert_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move insert_request() earlier to avoid a forward declaration in a later patch. Signed-off-by: Chris Wilson Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/20170916204414.32762-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 128 +++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 0f578f76f79f..7c709530b422 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -286,6 +286,70 @@ intel_lr_context_descriptor_update(struct i915_gem_context *ctx, ce->lrc_desc = desc; } +static bool +insert_request(struct intel_engine_cs *engine, + struct i915_priotree *pt, + int prio) +{ + struct i915_priolist *p; + struct rb_node **parent, *rb; + bool first = true; + + if (unlikely(engine->no_priolist)) + prio = I915_PRIORITY_NORMAL; + +find_priolist: + /* most positive priority is scheduled first, equal priorities fifo */ + rb = NULL; + parent = &engine->execlist_queue.rb_node; + while (*parent) { + rb = *parent; + p = rb_entry(rb, typeof(*p), node); + if (prio > p->priority) { + parent = &rb->rb_left; + } else if (prio < p->priority) { + parent = &rb->rb_right; + first = false; + } else { + list_add_tail(&pt->link, &p->requests); + return false; + } + } + + if (prio == I915_PRIORITY_NORMAL) { + p = &engine->default_priolist; + } else { + p = kmem_cache_alloc(engine->i915->priorities, GFP_ATOMIC); + /* Convert an allocation failure to a priority bump */ + if (unlikely(!p)) { + prio = I915_PRIORITY_NORMAL; /* recurses just once */ + + /* To maintain ordering with all rendering, after an + * allocation failure we have to disable all scheduling. + * Requests will then be executed in fifo, and schedule + * will ensure that dependencies are emitted in fifo. + * There will be still some reordering with existing + * requests, so if userspace lied about their + * dependencies that reordering may be visible. + */ + engine->no_priolist = true; + goto find_priolist; + } + } + + p->priority = prio; + rb_link_node(&p->node, rb, parent); + rb_insert_color(&p->node, &engine->execlist_queue); + + INIT_LIST_HEAD(&p->requests); + list_add_tail(&pt->link, &p->requests); + + if (first) + engine->execlist_first = &p->node; + + return first; +} + static inline void execlists_context_status_change(struct drm_i915_gem_request *rq, unsigned long status) @@ -700,70 +764,6 @@ static void intel_lrc_irq_handler(unsigned long data) intel_uncore_forcewake_put(dev_priv, engine->fw_domains); } -static bool -insert_request(struct intel_engine_cs *engine, - struct i915_priotree *pt, - int prio) -{ - struct i915_priolist *p; - struct rb_node **parent, *rb; - bool first = true; - - if (unlikely(engine->no_priolist)) - prio = I915_PRIORITY_NORMAL; - -find_priolist: - /* most positive priority is scheduled first, equal priorities fifo */ - rb = NULL; - parent = &engine->execlist_queue.rb_node; - while (*parent) { - rb = *parent; - p = rb_entry(rb, typeof(*p), node); - if (prio > p->priority) { - parent = &rb->rb_left; - } else if (prio < p->priority) { - parent = &rb->rb_right; - first = false; - } else { - list_add_tail(&pt->link, &p->requests); - return false; - } - } - - if (prio == I915_PRIORITY_NORMAL) { - p = &engine->default_priolist; - } else { - p = kmem_cache_alloc(engine->i915->priorities, GFP_ATOMIC); - /* Convert an allocation failure to a priority bump */ - if (unlikely(!p)) { - prio = I915_PRIORITY_NORMAL; /* recurses just once */ - - /* To maintain ordering with all rendering, after an - * allocation failure we have to disable all scheduling. - * Requests will then be executed in fifo, and schedule - * will ensure that dependencies are emitted in fifo. - * There will be still some reordering with existing - * requests, so if userspace lied about their - * dependencies that reordering may be visible. - */ - engine->no_priolist = true; - goto find_priolist; - } - } - - p->priority = prio; - rb_link_node(&p->node, rb, parent); - rb_insert_color(&p->node, &engine->execlist_queue); - - INIT_LIST_HEAD(&p->requests); - list_add_tail(&pt->link, &p->requests); - - if (first) - engine->execlist_first = &p->node; - - return first; -} - static void execlists_submit_request(struct drm_i915_gem_request *request) { struct intel_engine_cs *engine = request->engine; -- cgit v1.2.3 From 27606fd87895c3b45072a796caead8055a2f4b94 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 16 Sep 2017 21:44:13 +0100 Subject: drm/i915/execlists: Split insert_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the next patch we will want to reinsert a request not at the end of the priority queue, but at the front. Here we split insert_request() into two, the first function retrieves the priority list (for reuse for unsubmit later) and a wrapper function to insert at the end of that list and to schedule the tasklet if we were first. Signed-off-by: Chris Wilson Reviewed-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/20170916204414.32762-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7c709530b422..be2cba6b36d1 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -286,10 +286,10 @@ intel_lr_context_descriptor_update(struct i915_gem_context *ctx, ce->lrc_desc = desc; } -static bool -insert_request(struct intel_engine_cs *engine, - struct i915_priotree *pt, - int prio) +static struct i915_priolist * +lookup_priolist(struct intel_engine_cs *engine, + struct i915_priotree *pt, + int prio) { struct i915_priolist *p; struct rb_node **parent, *rb; @@ -311,8 +311,7 @@ find_priolist: parent = &rb->rb_right; first = false; } else { - list_add_tail(&pt->link, &p->requests); - return false; + return p; } } @@ -338,16 +337,14 @@ find_priolist: } p->priority = prio; + INIT_LIST_HEAD(&p->requests); rb_link_node(&p->node, rb, parent); rb_insert_color(&p->node, &engine->execlist_queue); - INIT_LIST_HEAD(&p->requests); - list_add_tail(&pt->link, &p->requests); - if (first) engine->execlist_first = &p->node; - return first; + return ptr_pack_bits(p, first, 1); } static inline void @@ -764,6 +761,17 @@ static void intel_lrc_irq_handler(unsigned long data) intel_uncore_forcewake_put(dev_priv, engine->fw_domains); } +static void insert_request(struct intel_engine_cs *engine, + struct i915_priotree *pt, + int prio) +{ + struct i915_priolist *p = lookup_priolist(engine, pt, prio); + + list_add_tail(&pt->link, &ptr_mask_bits(p, 1)->requests); + if (ptr_unmask_bits(p, 1) && execlists_elsp_ready(engine)) + tasklet_hi_schedule(&engine->irq_tasklet); +} + static void execlists_submit_request(struct drm_i915_gem_request *request) { struct intel_engine_cs *engine = request->engine; @@ -772,12 +780,7 @@ static void execlists_submit_request(struct drm_i915_gem_request *request) /* Will be called from irq-context when using foreign fences. */ spin_lock_irqsave(&engine->timeline->lock, flags); - if (insert_request(engine, - &request->priotree, - request->priotree.priority)) { - if (execlists_elsp_ready(engine)) - tasklet_hi_schedule(&engine->irq_tasklet); - } + insert_request(engine, &request->priotree, request->priotree.priority); GEM_BUG_ON(!engine->execlist_first); GEM_BUG_ON(list_empty(&request->priotree.link)); -- cgit v1.2.3 From 221ab9719bf33ad2984928d2afb20988d652a289 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 16 Sep 2017 21:44:14 +0100 Subject: drm/i915/execlists: Unwind incomplete requests on resets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given the mechanism to unwind and replay requests (designed to support preemption), we have an alternative to the current method of resubmitting the ELSP upon reset. Resubmitting ELSP turns out to be more complicated than expected, due to having to handle lost context-switch interrupts and so guessing what ELSP we need to resubmit later. Instead, by unwinding the requests and clearing the ELSP tracking entirely, we can then just dequeue the first pair of ready requests after resetting, using the normal submission procedure. Currently, the unwound requests have maximum priority and so are guaranteed to be resubmitted upon resume. If we are lucky, we may be able to coalesce a new request on top! Suggested-by: Michał Winiarski Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Mika Kuoppala Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170916204414.32762-4-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski --- drivers/gpu/drm/i915/intel_lrc.c | 61 +++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index be2cba6b36d1..94a89eff4dbd 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1308,9 +1308,6 @@ static u8 gtiir[] = { static int gen8_init_common_ring(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - struct execlist_port *port = engine->execlist_port; - unsigned int n; - bool submit; int ret; ret = intel_mocs_init_engine(engine); @@ -1346,26 +1343,8 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) engine->csb_head = -1; /* After a GPU reset, we may have requests to replay */ - submit = false; - for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) { - if (!port_isset(&port[n])) - break; - - DRM_DEBUG_DRIVER("Restarting %s:%d from 0x%x\n", - engine->name, n, - port_request(&port[n])->global_seqno); - - /* Discard the current inflight count */ - port_set(&port[n], port_request(&port[n])); - submit = true; - } - - if (!i915.enable_guc_submission) { - if (submit) - execlists_submit_ports(engine); - else if (engine->execlist_first) - tasklet_schedule(&engine->irq_tasklet); - } + if (!i915.enable_guc_submission && engine->execlist_first) + tasklet_schedule(&engine->irq_tasklet); return 0; } @@ -1407,9 +1386,13 @@ static void reset_common_ring(struct intel_engine_cs *engine, struct drm_i915_gem_request *request) { struct execlist_port *port = engine->execlist_port; + struct drm_i915_gem_request *rq, *rn; struct intel_context *ce; + unsigned long flags; unsigned int n; + spin_lock_irqsave(&engine->timeline->lock, flags); + /* * Catch up with any missed context-switch interrupts. * @@ -1419,20 +1402,28 @@ static void reset_common_ring(struct intel_engine_cs *engine, * guessing the missed context-switch events by looking at what * requests were completed. */ - if (!request) { - for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) - i915_gem_request_put(port_request(&port[n])); - memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); - return; - } + for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) + i915_gem_request_put(port_request(&port[n])); + memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); - if (request->ctx != port_request(port)->ctx) { - i915_gem_request_put(port_request(port)); - port[0] = port[1]; - memset(&port[1], 0, sizeof(port[1])); + /* Push back any incomplete requests for replay after the reset. */ + list_for_each_entry_safe_reverse(rq, rn, + &engine->timeline->requests, link) { + struct i915_priolist *p; + + if (i915_gem_request_completed(rq)) + break; + + __i915_gem_request_unsubmit(rq); + + p = lookup_priolist(engine, + &rq->priotree, + rq->priotree.priority); + list_add(&rq->priotree.link, + &ptr_mask_bits(p, 1)->requests); } - GEM_BUG_ON(request->ctx != port_request(port)->ctx); + spin_unlock_irqrestore(&engine->timeline->lock, flags); /* If the request was innocent, we leave the request in the ELSP * and will try to replay it on restarting. The context image may @@ -1444,7 +1435,7 @@ static void reset_common_ring(struct intel_engine_cs *engine, * and have to at least restore the RING register in the context * image back to the expected values to skip over the guilty request. */ - if (request->fence.error != -EIO) + if (!request || request->fence.error != -EIO) return; /* We want a simple context + ring to execute the breadcrumb update. -- cgit v1.2.3 From 45ec5bc8774b1a03213de072f240bad01c7ff09d Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Thu, 14 Sep 2017 10:32:12 +0200 Subject: drm/i915/guc: Remove obsolete comments and remove unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Originally removed in: c1adab970348 ("drm/i915/guc: Remove failed doorbell stat from debugfs") f1448a62a103 ("drm/i915/guc: Remove last submission result from debugfs") Were accidentally restored in: 925344ccc91d ("BackMerge tag 'v4.12-rc5' into drm-next") We can also remove unused variable and replace it with a WARN. Cc: Chris Wilson Cc: Michal Wajdeczko Signed-off-by: Michał Winiarski Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170914083216.10192-1-michal.winiarski@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_guc_submission.c | 3 +-- drivers/gpu/drm/i915/intel_uc.h | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index b28677e5a4f2..c180ff1423fd 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -601,7 +601,6 @@ static void __i915_guc_submit(struct drm_i915_gem_request *rq) struct intel_guc *guc = &rq->i915->guc; struct i915_guc_client *client = guc->execbuf_client; unsigned long flags; - int b_ret; /* WA to flush out the pending GMADR writes to ring buffer. */ if (i915_vma_is_map_and_fenceable(rq->ring->vma)) @@ -610,7 +609,7 @@ static void __i915_guc_submit(struct drm_i915_gem_request *rq) spin_lock_irqsave(&client->wq_lock, flags); guc_wq_item_append(client, rq); - b_ret = guc_ring_doorbell(client); + WARN_ON(guc_ring_doorbell(client)); client->submissions[engine_id] += 1; diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 22ae52b17b0f..69daf4c01cd0 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -59,10 +59,6 @@ struct drm_i915_gem_request; * available in the work queue (note, the queue is shared, * not per-engine). It is OK for this to be nonzero, but * it should not be huge! - * b_fail: failed to ring the doorbell. This should never happen, unless - * somehow the hardware misbehaves, or maybe if the GuC firmware - * crashes? We probably need to reset the GPU to recover. - * retcode: errno from last guc_submit() */ struct i915_guc_client { struct i915_vma *vma; -- cgit v1.2.3 From 85e2fe679e053326191f92b923f22a834f82cb53 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Thu, 14 Sep 2017 10:32:13 +0200 Subject: drm/i915/guc: Submit GuC workitems containing coalesced requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To create an upper bound on number of GuC workitems, we need to change the way that requests are being submitted. Rather than submitting each request as an individual workitem, we can do coalescing in a similar way we're handlig execlist submission ports. We also need to stop pretending that we're doing "lite-restore" in GuC submission (we would create a workitem each time we hit this condition). This allows us to completely remove the reservation, replacing it with a compile time check. v2: Also coalesce when replaying on reset (Daniele) v3: Consistent wq_resv - per-request (Daniele) v4: Squash removing wq_resv v5: Reflect i915_guc_submit argument changes in doc v6: Rebase on top of execlists reset/restart fix (Chris,Michał) References: https://bugs.freedesktop.org/show_bug.cgi?id=101873 Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Jeff McGee Cc: Michal Wajdeczko Cc: Oscar Mateo Signed-off-by: Michał Winiarski Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170914083216.10192-2-michal.winiarski@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 2 - drivers/gpu/drm/i915/i915_guc_submission.c | 182 ++++++++++------------------- drivers/gpu/drm/i915/intel_lrc.c | 25 +--- drivers/gpu/drm/i915/intel_uc.h | 11 -- 4 files changed, 63 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 12381045ed6a..a4c2d0718a70 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2450,8 +2450,6 @@ static void i915_guc_client_info(struct seq_file *m, seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n", client->wq_size, client->wq_offset, client->wq_tail); - seq_printf(m, "\tWork queue full: %u\n", client->no_wq_space); - for_each_engine(engine, dev_priv, id) { u64 submissions = client->submissions[id]; tot += submissions; diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index c180ff1423fd..a30cff294b30 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -406,63 +406,6 @@ static void guc_stage_desc_fini(struct intel_guc *guc, memset(desc, 0, sizeof(*desc)); } -/** - * i915_guc_wq_reserve() - reserve space in the GuC's workqueue - * @request: request associated with the commands - * - * Return: 0 if space is available - * -EAGAIN if space is not currently available - * - * This function must be called (and must return 0) before a request - * is submitted to the GuC via i915_guc_submit() below. Once a result - * of 0 has been returned, it must be balanced by a corresponding - * call to submit(). - * - * Reservation allows the caller to determine in advance that space - * will be available for the next submission before committing resources - * to it, and helps avoid late failures with complicated recovery paths. - */ -int i915_guc_wq_reserve(struct drm_i915_gem_request *request) -{ - const size_t wqi_size = sizeof(struct guc_wq_item); - struct i915_guc_client *client = request->i915->guc.execbuf_client; - struct guc_process_desc *desc = __get_process_desc(client); - u32 freespace; - int ret; - - spin_lock_irq(&client->wq_lock); - freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size); - freespace -= client->wq_rsvd; - if (likely(freespace >= wqi_size)) { - client->wq_rsvd += wqi_size; - ret = 0; - } else { - client->no_wq_space++; - ret = -EAGAIN; - } - spin_unlock_irq(&client->wq_lock); - - return ret; -} - -static void guc_client_update_wq_rsvd(struct i915_guc_client *client, int size) -{ - unsigned long flags; - - spin_lock_irqsave(&client->wq_lock, flags); - client->wq_rsvd += size; - spin_unlock_irqrestore(&client->wq_lock, flags); -} - -void i915_guc_wq_unreserve(struct drm_i915_gem_request *request) -{ - const int wqi_size = sizeof(struct guc_wq_item); - struct i915_guc_client *client = request->i915->guc.execbuf_client; - - GEM_BUG_ON(READ_ONCE(client->wq_rsvd) < wqi_size); - guc_client_update_wq_rsvd(client, -wqi_size); -} - /* Construct a Work Item and append it to the GuC's Work Queue */ static void guc_wq_item_append(struct i915_guc_client *client, struct drm_i915_gem_request *rq) @@ -476,7 +419,7 @@ static void guc_wq_item_append(struct i915_guc_client *client, struct guc_wq_item *wqi; u32 freespace, tail, wq_off; - /* Free space is guaranteed, see i915_guc_wq_reserve() above */ + /* Free space is guaranteed */ freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size); GEM_BUG_ON(freespace < wqi_size); @@ -491,14 +434,12 @@ static void guc_wq_item_append(struct i915_guc_client *client, * workqueue buffer dw by dw. */ BUILD_BUG_ON(wqi_size != 16); - GEM_BUG_ON(client->wq_rsvd < wqi_size); /* postincrement WQ tail for next time */ wq_off = client->wq_tail; GEM_BUG_ON(wq_off & (wqi_size - 1)); client->wq_tail += wqi_size; client->wq_tail &= client->wq_size - 1; - client->wq_rsvd -= wqi_size; /* WQ starts from the page after doorbell / process_desc */ wqi = client->vaddr + wq_off + GUC_DB_SIZE; @@ -579,47 +520,42 @@ static int guc_ring_doorbell(struct i915_guc_client *client) } /** - * __i915_guc_submit() - Submit commands through GuC - * @rq: request associated with the commands - * - * The caller must have already called i915_guc_wq_reserve() above with - * a result of 0 (success), guaranteeing that there is space in the work - * queue for the new request, so enqueuing the item cannot fail. - * - * Bad Things Will Happen if the caller violates this protocol e.g. calls - * submit() when _reserve() says there's no space, or calls _submit() - * a different number of times from (successful) calls to _reserve(). + * i915_guc_submit() - Submit commands through GuC + * @engine: engine associated with the commands * * The only error here arises if the doorbell hardware isn't functioning * as expected, which really shouln't happen. */ -static void __i915_guc_submit(struct drm_i915_gem_request *rq) +static void i915_guc_submit(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = rq->i915; - struct intel_engine_cs *engine = rq->engine; - unsigned int engine_id = engine->id; - struct intel_guc *guc = &rq->i915->guc; + struct drm_i915_private *dev_priv = engine->i915; + struct intel_guc *guc = &dev_priv->guc; struct i915_guc_client *client = guc->execbuf_client; - unsigned long flags; + struct execlist_port *port = engine->execlist_port; + unsigned int engine_id = engine->id; + unsigned int n; - /* WA to flush out the pending GMADR writes to ring buffer. */ - if (i915_vma_is_map_and_fenceable(rq->ring->vma)) - POSTING_READ_FW(GUC_STATUS); + for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) { + struct drm_i915_gem_request *rq; + unsigned int count; - spin_lock_irqsave(&client->wq_lock, flags); + rq = port_unpack(&port[n], &count); + if (rq && count == 0) { + port_set(&port[n], port_pack(rq, ++count)); - guc_wq_item_append(client, rq); - WARN_ON(guc_ring_doorbell(client)); + if (i915_vma_is_map_and_fenceable(rq->ring->vma)) + POSTING_READ_FW(GUC_STATUS); - client->submissions[engine_id] += 1; + spin_lock(&client->wq_lock); - spin_unlock_irqrestore(&client->wq_lock, flags); -} + guc_wq_item_append(client, rq); + WARN_ON(guc_ring_doorbell(client)); -static void i915_guc_submit(struct drm_i915_gem_request *rq) -{ - __i915_gem_request_submit(rq); - __i915_guc_submit(rq); + client->submissions[engine_id] += 1; + + spin_unlock(&client->wq_lock); + } + } } static void nested_enable_signaling(struct drm_i915_gem_request *rq) @@ -653,16 +589,19 @@ static void port_assign(struct execlist_port *port, if (port_isset(port)) i915_gem_request_put(port_request(port)); - port_set(port, i915_gem_request_get(rq)); + port_set(port, port_pack(i915_gem_request_get(rq), port_count(port))); nested_enable_signaling(rq); } -static bool i915_guc_dequeue(struct intel_engine_cs *engine) +static void i915_guc_dequeue(struct intel_engine_cs *engine) { struct execlist_port *port = engine->execlist_port; - struct drm_i915_gem_request *last = port_request(port); - struct rb_node *rb; + struct drm_i915_gem_request *last = NULL; bool submit = false; + struct rb_node *rb; + + if (port_isset(port)) + port++; spin_lock_irq(&engine->timeline->lock); rb = engine->execlist_first; @@ -687,7 +626,7 @@ static bool i915_guc_dequeue(struct intel_engine_cs *engine) INIT_LIST_HEAD(&rq->priotree.link); rq->priotree.priority = INT_MAX; - i915_guc_submit(rq); + __i915_gem_request_submit(rq); trace_i915_gem_request_in(rq, port_index(port, engine)); last = rq; submit = true; @@ -701,11 +640,11 @@ static bool i915_guc_dequeue(struct intel_engine_cs *engine) } done: engine->execlist_first = rb; - if (submit) + if (submit) { port_assign(port, last); + i915_guc_submit(engine); + } spin_unlock_irq(&engine->timeline->lock); - - return submit; } static void i915_guc_irq_handler(unsigned long data) @@ -713,24 +652,20 @@ static void i915_guc_irq_handler(unsigned long data) struct intel_engine_cs *engine = (struct intel_engine_cs *)data; struct execlist_port *port = engine->execlist_port; struct drm_i915_gem_request *rq; - bool submit; - do { - rq = port_request(&port[0]); - while (rq && i915_gem_request_completed(rq)) { - trace_i915_gem_request_out(rq); - i915_gem_request_put(rq); + rq = port_request(&port[0]); + while (rq && i915_gem_request_completed(rq)) { + trace_i915_gem_request_out(rq); + i915_gem_request_put(rq); - port[0] = port[1]; - memset(&port[1], 0, sizeof(port[1])); + port[0] = port[1]; + memset(&port[1], 0, sizeof(port[1])); - rq = port_request(&port[0]); - } + rq = port_request(&port[0]); + } - submit = false; - if (!port_count(&port[1])) - submit = i915_guc_dequeue(engine); - } while (submit); + if (!port_isset(&port[1])) + i915_guc_dequeue(engine); } /* @@ -1239,6 +1174,19 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) enum intel_engine_id id; int err; + /* + * We're using GuC work items for submitting work through GuC. Since + * we're coalescing multiple requests from a single context into a + * single work item prior to assigning it to execlist_port, we can + * never have more work items than the total number of ports (for all + * engines). The GuC firmware is controlling the HEAD of work queue, + * and it is guaranteed that it will remove the work item from the + * queue before our request is completed. + */ + BUILD_BUG_ON(ARRAY_SIZE(engine->execlist_port) * + sizeof(struct guc_wq_item) * + I915_NUM_ENGINES > GUC_WQ_SIZE); + if (!client) { client = guc_client_alloc(dev_priv, INTEL_INFO(dev_priv)->ring_mask, @@ -1266,9 +1214,6 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) guc_interrupts_capture(dev_priv); for_each_engine(engine, dev_priv, id) { - const int wqi_size = sizeof(struct guc_wq_item); - struct drm_i915_gem_request *rq; - /* The tasklet was initialised by execlists, and may be in * a state of flux (across a reset) and so we just want to * take over the callback without changing any other state @@ -1276,14 +1221,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) */ engine->irq_tasklet.func = i915_guc_irq_handler; clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - - /* Replay the current set of previously submitted requests */ - spin_lock_irq(&engine->timeline->lock); - list_for_each_entry(rq, &engine->timeline->requests, link) { - guc_client_update_wq_rsvd(client, wqi_size); - __i915_guc_submit(rq); - } - spin_unlock_irq(&engine->timeline->lock); + tasklet_schedule(&engine->irq_tasklet); } return 0; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 94a89eff4dbd..86fed9f1f1ae 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -988,27 +988,14 @@ static int execlists_request_alloc(struct drm_i915_gem_request *request) */ request->reserved_space += EXECLISTS_REQUEST_SIZE; - if (i915.enable_guc_submission) { - /* - * Check that the GuC has space for the request before - * going any further, as the i915_add_request() call - * later on mustn't fail ... - */ - ret = i915_guc_wq_reserve(request); - if (ret) - goto err; - } - cs = intel_ring_begin(request, 0); - if (IS_ERR(cs)) { - ret = PTR_ERR(cs); - goto err_unreserve; - } + if (IS_ERR(cs)) + return PTR_ERR(cs); if (!ce->initialised) { ret = engine->init_context(request); if (ret) - goto err_unreserve; + return ret; ce->initialised = true; } @@ -1022,12 +1009,6 @@ static int execlists_request_alloc(struct drm_i915_gem_request *request) request->reserved_space -= EXECLISTS_REQUEST_SIZE; return 0; - -err_unreserve: - if (i915.enable_guc_submission) - i915_guc_wq_unreserve(request); -err: - return ret; } /* diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 69daf4c01cd0..d41051688221 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -52,13 +52,6 @@ struct drm_i915_gem_request; * GuC). The subsequent pages of the client object constitute the work * queue (a circular array of work items), again described in the process * descriptor. Work queue pages are mapped momentarily as required. - * - * We also keep a few statistics on failures. Ideally, these should all - * be zero! - * no_wq_space: times that the submission pre-check found no space was - * available in the work queue (note, the queue is shared, - * not per-engine). It is OK for this to be nonzero, but - * it should not be huge! */ struct i915_guc_client { struct i915_vma *vma; @@ -79,8 +72,6 @@ struct i915_guc_client { uint32_t wq_offset; uint32_t wq_size; uint32_t wq_tail; - uint32_t wq_rsvd; - uint32_t no_wq_space; /* Per-engine counts of GuC submissions */ uint64_t submissions[I915_NUM_ENGINES]; @@ -246,8 +237,6 @@ u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv); /* i915_guc_submission.c */ int i915_guc_submission_init(struct drm_i915_private *dev_priv); int i915_guc_submission_enable(struct drm_i915_private *dev_priv); -int i915_guc_wq_reserve(struct drm_i915_gem_request *rq); -void i915_guc_wq_unreserve(struct drm_i915_gem_request *request); void i915_guc_submission_disable(struct drm_i915_private *dev_priv); void i915_guc_submission_fini(struct drm_i915_private *dev_priv); struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); -- cgit v1.2.3 From 59db36cf4d67b74f5b8cb001493847464240d136 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Thu, 14 Sep 2017 12:51:23 +0200 Subject: drm/i915/guc: Simplify GuC doorbell logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All we're really doing is incrementing a simple counter in a doorbell_info struct. We can do without extra variables and a separate counter kept in guc_client. Since it's gone, we're also removing its debugfs. The only functional change here, is that we're no longer treating 0 as a special value. GuC doesn't seem to care, why should we? v2: Restore desc->tail update. v3: Drop the retry loop, assert that doorbell cookie doesn't change behind our back. v4: WARN rather than BUG, use xchg. (Chris) Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Michal Wajdeczko Cc: Oscar Mateo Suggested-by: Chris Wilson Signed-off-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/20170914105125.3031-1-michal.winiarski@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_guc_submission.c | 60 +++++++----------------------- drivers/gpu/drm/i915/intel_uc.h | 1 - 3 files changed, 15 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a4c2d0718a70..46ac6091772e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2445,8 +2445,8 @@ static void i915_guc_client_info(struct seq_file *m, seq_printf(m, "\tPriority %d, GuC stage index: %u, PD offset 0x%x\n", client->priority, client->stage_id, client->proc_desc_offset); - seq_printf(m, "\tDoorbell id %d, offset: 0x%lx, cookie 0x%x\n", - client->doorbell_id, client->doorbell_offset, client->doorbell_cookie); + seq_printf(m, "\tDoorbell id %d, offset: 0x%lx\n", + client->doorbell_id, client->doorbell_offset); seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n", client->wq_size, client->wq_offset, client->wq_tail); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index a30cff294b30..2231214597b9 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -192,13 +192,12 @@ static int __create_doorbell(struct i915_guc_client *client) doorbell = __get_doorbell(client); doorbell->db_status = GUC_DOORBELL_ENABLED; - doorbell->cookie = client->doorbell_cookie; + doorbell->cookie = 0; err = __guc_allocate_doorbell(client->guc, client->stage_id); - if (err) { + if (err) doorbell->db_status = GUC_DOORBELL_DISABLED; - doorbell->cookie = 0; - } + return err; } @@ -466,57 +465,24 @@ static void guc_reset_wq(struct i915_guc_client *client) client->wq_tail = 0; } -static int guc_ring_doorbell(struct i915_guc_client *client) +static void guc_ring_doorbell(struct i915_guc_client *client) { struct guc_process_desc *desc = __get_process_desc(client); - union guc_doorbell_qw db_cmp, db_exc, db_ret; - union guc_doorbell_qw *db; - int attempt = 2, ret = -EAGAIN; + struct guc_doorbell_info *db; + u32 cookie; /* Update the tail so it is visible to GuC */ desc->tail = client->wq_tail; - /* current cookie */ - db_cmp.db_status = GUC_DOORBELL_ENABLED; - db_cmp.cookie = client->doorbell_cookie; - - /* cookie to be updated */ - db_exc.db_status = GUC_DOORBELL_ENABLED; - db_exc.cookie = client->doorbell_cookie + 1; - if (db_exc.cookie == 0) - db_exc.cookie = 1; - /* pointer of current doorbell cacheline */ - db = (union guc_doorbell_qw *)__get_doorbell(client); - - while (attempt--) { - /* lets ring the doorbell */ - db_ret.value_qw = atomic64_cmpxchg((atomic64_t *)db, - db_cmp.value_qw, db_exc.value_qw); - - /* if the exchange was successfully executed */ - if (db_ret.value_qw == db_cmp.value_qw) { - /* db was successfully rung */ - client->doorbell_cookie = db_exc.cookie; - ret = 0; - break; - } - - /* XXX: doorbell was lost and need to acquire it again */ - if (db_ret.db_status == GUC_DOORBELL_DISABLED) - break; + db = __get_doorbell(client); - DRM_WARN("Cookie mismatch. Expected %d, found %d\n", - db_cmp.cookie, db_ret.cookie); + /* we're not expecting the doorbell cookie to change behind our back */ + cookie = READ_ONCE(db->cookie); + WARN_ON_ONCE(xchg(&db->cookie, cookie + 1) != cookie); - /* update the cookie to newly read cookie from GuC */ - db_cmp.cookie = db_ret.cookie; - db_exc.cookie = db_ret.cookie + 1; - if (db_exc.cookie == 0) - db_exc.cookie = 1; - } - - return ret; + /* XXX: doorbell was lost and need to acquire it again */ + GEM_BUG_ON(db->db_status != GUC_DOORBELL_ENABLED); } /** @@ -549,7 +515,7 @@ static void i915_guc_submit(struct intel_engine_cs *engine) spin_lock(&client->wq_lock); guc_wq_item_append(client, rq); - WARN_ON(guc_ring_doorbell(client)); + guc_ring_doorbell(client); client->submissions[engine_id] += 1; diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index d41051688221..f505dcccd613 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -66,7 +66,6 @@ struct i915_guc_client { u16 doorbell_id; unsigned long doorbell_offset; - u32 doorbell_cookie; spinlock_t wq_lock; uint32_t wq_offset; -- cgit v1.2.3 From a529a1c9db931a5d4fd6683199d73a8363bc7e83 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Mon, 18 Sep 2017 11:25:35 +0200 Subject: drm/i915/guc: Cleanup adding GuC work items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can just operate on the wq_tail directly (in the process descriptor). This allows us to remove the duplicated tail from the client. While I'm here let's also remove the constants kept in the client and document our locking requirements. This causes a small change in one of GuC debugfs files. We're no longer reporting constant values (which I don't think is a problem), but we're also no longer reporting the tail (does anyone care?). v2: Update tail after wqi contents. (Chris) v3: Really update tail after wqi contents. Cc: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Michal Wajdeczko Cc: Oscar Mateo Signed-off-by: Michał Winiarski Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170918092536.12287-1-michal.winiarski@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 2 -- drivers/gpu/drm/i915/i915_guc_submission.c | 37 +++++++++++++----------------- drivers/gpu/drm/i915/intel_uc.h | 4 ---- 3 files changed, 16 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 46ac6091772e..2518bdf95eef 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2447,8 +2447,6 @@ static void i915_guc_client_info(struct seq_file *m, client->priority, client->stage_id, client->proc_desc_offset); seq_printf(m, "\tDoorbell id %d, offset: 0x%lx\n", client->doorbell_id, client->doorbell_offset); - seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n", - client->wq_size, client->wq_offset, client->wq_tail); for_each_engine(engine, dev_priv, id) { u64 submissions = client->submissions[id]; diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 2231214597b9..e191d56fc990 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -305,7 +305,7 @@ static void guc_proc_desc_init(struct intel_guc *guc, desc->db_base_addr = 0; desc->stage_id = client->stage_id; - desc->wq_size_bytes = client->wq_size; + desc->wq_size_bytes = GUC_WQ_SIZE; desc->wq_status = WQ_STATUS_ACTIVE; desc->priority = client->priority; } @@ -390,8 +390,8 @@ static void guc_stage_desc_init(struct intel_guc *guc, desc->db_trigger_cpu = (uintptr_t)__get_doorbell(client); desc->db_trigger_uk = gfx_addr + client->doorbell_offset; desc->process_desc = gfx_addr + client->proc_desc_offset; - desc->wq_addr = gfx_addr + client->wq_offset; - desc->wq_size = client->wq_size; + desc->wq_addr = gfx_addr + GUC_DB_SIZE; + desc->wq_size = GUC_WQ_SIZE; desc->desc_private = (uintptr_t)client; } @@ -416,14 +416,12 @@ static void guc_wq_item_append(struct i915_guc_client *client, struct i915_gem_context *ctx = rq->ctx; struct guc_process_desc *desc = __get_process_desc(client); struct guc_wq_item *wqi; - u32 freespace, tail, wq_off; + u32 ring_tail, wq_off; - /* Free space is guaranteed */ - freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size); - GEM_BUG_ON(freespace < wqi_size); + lockdep_assert_held(&client->wq_lock); - tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64); - GEM_BUG_ON(tail > WQ_RING_TAIL_MAX); + ring_tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64); + GEM_BUG_ON(ring_tail > WQ_RING_TAIL_MAX); /* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we * should not have the case where structure wqi is across page, neither @@ -434,11 +432,11 @@ static void guc_wq_item_append(struct i915_guc_client *client, */ BUILD_BUG_ON(wqi_size != 16); - /* postincrement WQ tail for next time */ - wq_off = client->wq_tail; + /* Free space is guaranteed. */ + wq_off = READ_ONCE(desc->tail); + GEM_BUG_ON(CIRC_SPACE(wq_off, READ_ONCE(desc->head), + GUC_WQ_SIZE) < wqi_size); GEM_BUG_ON(wq_off & (wqi_size - 1)); - client->wq_tail += wqi_size; - client->wq_tail &= client->wq_size - 1; /* WQ starts from the page after doorbell / process_desc */ wqi = client->vaddr + wq_off + GUC_DB_SIZE; @@ -451,8 +449,11 @@ static void guc_wq_item_append(struct i915_guc_client *client, wqi->context_desc = lower_32_bits(intel_lr_context_descriptor(ctx, engine)); - wqi->submit_element_info = tail << WQ_RING_TAIL_SHIFT; + wqi->submit_element_info = ring_tail << WQ_RING_TAIL_SHIFT; wqi->fence_id = rq->global_seqno; + + /* Postincrement WQ tail for next time. */ + WRITE_ONCE(desc->tail, (wq_off + wqi_size) & (GUC_WQ_SIZE - 1)); } static void guc_reset_wq(struct i915_guc_client *client) @@ -461,18 +462,14 @@ static void guc_reset_wq(struct i915_guc_client *client) desc->head = 0; desc->tail = 0; - - client->wq_tail = 0; } static void guc_ring_doorbell(struct i915_guc_client *client) { - struct guc_process_desc *desc = __get_process_desc(client); struct guc_doorbell_info *db; u32 cookie; - /* Update the tail so it is visible to GuC */ - desc->tail = client->wq_tail; + lockdep_assert_held(&client->wq_lock); /* pointer of current doorbell cacheline */ db = __get_doorbell(client); @@ -812,8 +809,6 @@ guc_client_alloc(struct drm_i915_private *dev_priv, client->engines = engines; client->priority = priority; client->doorbell_id = GUC_DOORBELL_INVALID; - client->wq_offset = GUC_DB_SIZE; - client->wq_size = GUC_WQ_SIZE; spin_lock_init(&client->wq_lock); ret = ida_simple_get(&guc->stage_ids, 0, GUC_MAX_STAGE_DESCRIPTORS, diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index f505dcccd613..7703c9ad6511 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -68,10 +68,6 @@ struct i915_guc_client { unsigned long doorbell_offset; spinlock_t wq_lock; - uint32_t wq_offset; - uint32_t wq_size; - uint32_t wq_tail; - /* Per-engine counts of GuC submissions */ uint64_t submissions[I915_NUM_ENGINES]; }; -- cgit v1.2.3 From 056e4fc2018364ba01a23a1ced0ccbbdfa4520b3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 15 Sep 2017 21:23:13 +0200 Subject: staging: unisys/visorbus: add __init/__exit annotations gcc-4.6 causes a harmless warning about the init function: WARNING: vmlinux.o(.text+0xed62c2): Section mismatch in reference from the function init_unisys() to the function .init.text:visorutil_spar_detect() The function init_unisys() references the function __init visorutil_spar_detect(). This is often because init_unisys lacks a __init annotation or the annotation of visorutil_spar_detect is wrong. It appears that newer versions inline visorutil_spar_detect(), end up with an empty __init section. This marks the module entry points as __init and __exit respectively, which avoids the warning and slightly reduces the runtime code size. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorchipset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 74cce4f1a7bd..27ecf6fb49fd 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1826,7 +1826,7 @@ static __init int visorutil_spar_detect(void) return 0; } -static int init_unisys(void) +static int __init init_unisys(void) { int result; @@ -1841,7 +1841,7 @@ static int init_unisys(void) return 0; }; -static void exit_unisys(void) +static void __exit exit_unisys(void) { acpi_bus_unregister_driver(&unisys_acpi_driver); } -- cgit v1.2.3 From a3563b09f132661d447f69224ef65fdec02f5c61 Mon Sep 17 00:00:00 2001 From: Arun Nagendran Date: Fri, 15 Sep 2017 12:30:32 -0400 Subject: staging: mt29f_spinand: Enable the read ECC before program the page Current program_page function did following operation: 1. read page (with ECC OFF) 2. modify the page 3. write the page (with ECC ON) For some case(buggy flash Chip), while read the page without ECC ON, we may read the page with bit flip error and modify that bad page without knowing the bit flip error on that page. also we re-calculate the hash for bad page and write it. This could bring potential in-consistency problem with Flash data. Verify this logic with GIGA DEVICE Part(GD5F2GQ4RCFIG): we see this in-conststency problem wit Giga Device and fix on this patch resovle that issue. Signed-off-by: Arun Nagendran Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mt29f_spinand/mt29f_spinand.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index 13eaf16ecd16..87595c594b12 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c @@ -496,8 +496,12 @@ static int spinand_program_page(struct spi_device *spi_nand, if (!wbuf) return -ENOMEM; - enable_read_hw_ecc = 0; - spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf); + enable_read_hw_ecc = 1; + retval = spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf); + if (retval < 0) { + dev_err(&spi_nand->dev, "ecc error on read page!!!\n"); + return retval; + } for (i = offset, j = 0; i < len; i++, j++) wbuf[i] &= buf[j]; -- cgit v1.2.3 From e1bf28868ab0bfd1fc73dd8d5e642d88456c30e9 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 8 Sep 2017 14:55:06 +0100 Subject: staging: r8822be: fix null pointer dereferences with a null driver_adapter The call to _rtl_dbg_trace via macro HALMAC_RT_TRACE will trigger a null pointer deference on a null driver_adapter. Fix this by assigning driver_adapter earlier to halmac_adapter->driver_adapter before the tracing call so that a non-null driver_adapter is passed instead. I should have spotted these with an earlier patch I sent, but I overlooked these in the rather large CoverityScan logs. Detected by CoverityScan, CID#1454550, CID#1454554, CID#1454565, CID#1454591, CID#1454598 ("Explicit null dereferenced") Fixes: 938a0447f094 ("staging: r8822be: Add code for halmac sub-driver") Signed-off-by: Colin Ian King Signed-off-by: Greg Kroah-Hartman --- .../staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c | 4 ++-- .../staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c index 5f84526cb5b5..edbf6af1c8b7 100644 --- a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c +++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_api_88xx.c @@ -2901,11 +2901,11 @@ halmac_update_datapack_88xx(struct halmac_adapter *halmac_adapter, if (halmac_adapter->fw_version.h2c_version < 4) return HALMAC_RET_FW_NO_SUPPORT; + driver_adapter = halmac_adapter->driver_adapter; + HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG, "[TRACE]%s ==========>\n", __func__); - driver_adapter = halmac_adapter->driver_adapter; - HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG, "[TRACE]%s <==========\n", __func__); diff --git a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c index f33024e4d853..544f638ed3ef 100644 --- a/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c +++ b/drivers/staging/rtlwifi/halmac/halmac_88xx/halmac_func_88xx.c @@ -1618,10 +1618,11 @@ halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter *halmac_adapter, void *driver_adapter = NULL; enum halmac_ret_status status = HALMAC_RET_SUCCESS; + driver_adapter = halmac_adapter->driver_adapter; + HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG, "%s!!\n", __func__); - driver_adapter = halmac_adapter->driver_adapter; h2c_header = h2c_buff; h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX; @@ -1713,10 +1714,11 @@ halmac_media_status_rpt_88xx(struct halmac_adapter *halmac_adapter, u8 op_mode, void *driver_adapter = NULL; enum halmac_ret_status status = HALMAC_RET_SUCCESS; + driver_adapter = halmac_adapter->driver_adapter; + HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG, "halmac_send_h2c_set_pwr_mode_88xx!!\n"); - driver_adapter = halmac_adapter->driver_adapter; h2c_header = H2c_buff; h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX; @@ -2143,10 +2145,11 @@ halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter, enum halmac_cmd_process_status *process_status = &halmac_adapter->halmac_state.scan_state_set.process_status; + driver_adapter = halmac_adapter->driver_adapter; + HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG, "halmac_ctrl_ch_switch!!\n"); - driver_adapter = halmac_adapter->driver_adapter; halmac_api = (struct halmac_api *)halmac_adapter->halmac_api; if (halmac_transition_scan_state_88xx( @@ -2276,15 +2279,13 @@ enum halmac_ret_status halmac_send_h2c_update_bcn_parse_info_88xx( { u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0}; u16 h2c_seq_mum = 0; - void *driver_adapter = NULL; + void *driver_adapter = halmac_adapter->driver_adapter; struct halmac_h2c_header_info h2c_header_info; enum halmac_ret_status status = HALMAC_RET_SUCCESS; HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG, "%s!!\n", __func__); - driver_adapter = halmac_adapter->driver_adapter; - UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(h2c_buff, bcn_ie_info->func_en); UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(h2c_buff, bcn_ie_info->size_th); UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(h2c_buff, bcn_ie_info->timeout); -- cgit v1.2.3 From b72703e26b9478da531144ce5c4552dd22f1103d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Sep 2017 17:40:25 +0200 Subject: staging: pi433: Move limit check to switch default to kill warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With gcc-4.1.2: drivers/staging/pi433/rf69.c: In function ‘rf69_set_dio_mapping’: drivers/staging/pi433/rf69.c:566: warning: ‘regaddr’ may be used uninitialized in this function drivers/staging/pi433/rf69.c:565: warning: ‘shift’ may be used uninitialized in this function drivers/staging/pi433/rf69.c:564: warning: ‘mask’ may be used uninitialized in this function While this is a false positive, it can easily be fixed by moving the limit check into the "default" case of the switch statement. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pi433/rf69.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c index c4b1b218ea38..290b419aa9dd 100644 --- a/drivers/staging/pi433/rf69.c +++ b/drivers/staging/pi433/rf69.c @@ -570,12 +570,6 @@ int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value) dev_dbg(&spi->dev, "set: DIO mapping"); #endif - // check DIO number - if (DIONumber > 5) { - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } - switch (DIONumber) { case 0: mask=MASK_DIO0; shift=SHIFT_DIO0; regaddr=REG_DIOMAPPING1; break; case 1: mask=MASK_DIO1; shift=SHIFT_DIO1; regaddr=REG_DIOMAPPING1; break; @@ -583,6 +577,9 @@ int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value) case 3: mask=MASK_DIO3; shift=SHIFT_DIO3; regaddr=REG_DIOMAPPING1; break; case 4: mask=MASK_DIO4; shift=SHIFT_DIO4; regaddr=REG_DIOMAPPING2; break; case 5: mask=MASK_DIO5; shift=SHIFT_DIO5; regaddr=REG_DIOMAPPING2; break; + default: + dev_dbg(&spi->dev, "set: illegal input param"); + return -EINVAL; } // read reg -- cgit v1.2.3 From e5f5d0e20b6cecc0ebe6fc8e7df6f8823ad2d594 Mon Sep 17 00:00:00 2001 From: Okash Khawaja Date: Tue, 5 Sep 2017 12:51:59 +0100 Subject: staging: speakup: fix speakup-r empty line lockup When cursor is at beginning of an empty or whitespace-only line and speakup-r typed, kernel locks up. This happens because deadlock of in input_event function over dev->event_lock, as demonstrated by lockdep logs. The reason for that is speakup simulates a down arrow - because cursor is at an empty line - while inside key press notifier handler which is ultimately triggered from input_event function. The simulated key press leads to input_event being called again, this time under its own context. So the spinlock is dev->event_lock is acquired while still being held. This patch ensures that key press is not simulated from inside key press notifier handler. Instead it delegates to cursor_timer. It starts the timer and passes RA_DOWN_ARROW as argument. When timer handler runs and sees RA_DOWN_ARROW, it will then call kbd_fakekey2(RA_DOWN_ARROW) which will correctly simulate the keypress inside timer context. When not inside key press notifier callback, the behaviour will remain the same as before this patch. Signed-off-by: Okash Khawaja Reviewed-by: Samuel Thibault Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 67956e24779c..56f7be6af1f6 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1376,6 +1376,8 @@ static void reset_highlight_buffers(struct vc_data *); static int read_all_key; +static int in_keyboard_notifier; + static void start_read_all_timer(struct vc_data *vc, int command); enum { @@ -1408,7 +1410,10 @@ static void read_all_doc(struct vc_data *vc) cursor_track = read_all_mode; spk_reset_index_count(0); if (get_sentence_buf(vc, 0) == -1) { - kbd_fakekey2(vc, RA_DOWN_ARROW); + del_timer(&cursor_timer); + if (!in_keyboard_notifier) + speakup_fake_down_arrow(); + start_read_all_timer(vc, RA_DOWN_ARROW); } else { say_sentence_num(0, 0); synth_insert_next_index(0); @@ -2212,8 +2217,10 @@ static int keyboard_notifier_call(struct notifier_block *nb, int ret = NOTIFY_OK; static int keycode; /* to hold the current keycode */ + in_keyboard_notifier = 1; + if (vc->vc_mode == KD_GRAPHICS) - return ret; + goto out; /* * First, determine whether we are handling a fake keypress on @@ -2225,7 +2232,7 @@ static int keyboard_notifier_call(struct notifier_block *nb, */ if (speakup_fake_key_pressed()) - return ret; + goto out; switch (code) { case KBD_KEYCODE: @@ -2266,6 +2273,8 @@ static int keyboard_notifier_call(struct notifier_block *nb, break; } } +out: + in_keyboard_notifier = 0; return ret; } -- cgit v1.2.3 From 974d4d03fc020af4fa4e9e72a86f0fefa37803c5 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 3 Sep 2017 19:06:31 +0200 Subject: staging: vchiq_2835_arm: Fix NULL ptr dereference in free_pagelist This fixes a NULL pointer dereference on RPi 2 with multi_v7_defconfig. The function page_address() could return NULL with enabled CONFIG_HIGHMEM. So fix this by using kmap() instead. Signed-off-by: Stefan Wahren Fixes: 71bad7f08641 ("staging: add bcm2708 vchiq driver") Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 0159ca4407d8..be08849175ea 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -612,18 +612,20 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, if (head_bytes > actual) head_bytes = actual; - memcpy((char *)page_address(pages[0]) + + memcpy((char *)kmap(pages[0]) + pagelist->offset, fragments, head_bytes); + kunmap(pages[0]); } if ((actual >= 0) && (head_bytes < actual) && (tail_bytes != 0)) { - memcpy((char *)page_address(pages[num_pages - 1]) + + memcpy((char *)kmap(pages[num_pages - 1]) + ((pagelist->offset + actual) & (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)), fragments + g_cache_line_size, tail_bytes); + kunmap(pages[num_pages - 1]); } down(&g_free_fragments_mutex); -- cgit v1.2.3 From 55168470835688e5da5828cdcf1b1498d7baadb1 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Sep 2017 10:45:12 +0300 Subject: usb: dwc3: ep0: fix DMA starvation by assigning req->trb on ep0 If we don't assign a TRB to ep0 requests, we won't be able to unmap the request later on resulting in starvation of DMA resources. Fixes: 4a71fcb8ac5f ("usb: dwc3: gadget: only unmap requests from DMA if mapped") Reported-by: Thinh Nguyen Tested-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 827e376bfa97..75e6cb044eb2 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -990,6 +990,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA, true); + req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; + /* Now prepare one extra TRB to align transfer size */ dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, maxpacket - rem, @@ -1015,6 +1017,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA, true); + req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; + /* Now prepare one extra TRB to align transfer size */ dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, 0, DWC3_TRBCTL_CONTROL_DATA, @@ -1029,6 +1033,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, dwc3_ep0_prepare_one_trb(dep, req->request.dma, req->request.length, DWC3_TRBCTL_CONTROL_DATA, false); + + req->trb = &dwc->ep0_trb[dep->trb_enqueue]; + ret = dwc3_ep0_start_trans(dep); } -- cgit v1.2.3 From 13541226dc056fa3f54417ce12f18ba711a1591c Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 31 Aug 2017 11:06:07 -0700 Subject: ARC: reset: remove the misleading v1 suffix all over There is no plan yet to do a v2 board. And even if we were to do it only some IPs would actually change, so it be best to add suffixes at that point, not now ! Signed-off-by: Vineet Gupta Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/snps,hsdk-reset.txt | 28 +++++ .../bindings/reset/snps,hsdk-v1-reset.txt | 28 ----- MAINTAINERS | 6 +- drivers/reset/Kconfig | 6 +- drivers/reset/Makefile | 2 +- drivers/reset/reset-hsdk-v1.c | 137 --------------------- drivers/reset/reset-hsdk.c | 137 +++++++++++++++++++++ include/dt-bindings/reset/snps,hsdk-reset.h | 17 +++ include/dt-bindings/reset/snps,hsdk-v1-reset.h | 17 --- 9 files changed, 189 insertions(+), 189 deletions(-) create mode 100644 Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt delete mode 100644 Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt delete mode 100644 drivers/reset/reset-hsdk-v1.c create mode 100644 drivers/reset/reset-hsdk.c create mode 100644 include/dt-bindings/reset/snps,hsdk-reset.h delete mode 100644 include/dt-bindings/reset/snps,hsdk-v1-reset.h (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt b/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt new file mode 100644 index 000000000000..830069b1c37c --- /dev/null +++ b/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt @@ -0,0 +1,28 @@ +Binding for the Synopsys HSDK reset controller + +This binding uses the common reset binding[1]. + +[1] Documentation/devicetree/bindings/reset/reset.txt + +Required properties: +- compatible: should be "snps,hsdk-reset". +- reg: should always contain 2 pairs address - length: first for reset + configuration register and second for corresponding SW reset and status bits + register. +- #reset-cells: from common reset binding; Should always be set to 1. + +Example: + reset: reset@880 { + compatible = "snps,hsdk-reset"; + #reset-cells = <1>; + reg = <0x8A0 0x4>, <0xFF0 0x4>; + }; + +Specifying reset lines connected to IP modules: + ethernet@.... { + .... + resets = <&reset HSDK_V1_ETH_RESET>; + .... + }; + +The index could be found in diff --git a/Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt b/Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt deleted file mode 100644 index 6a68146ee353..000000000000 --- a/Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt +++ /dev/null @@ -1,28 +0,0 @@ -Binding for the HSDK v1 reset controller - -This binding uses the common reset binding[1]. - -[1] Documentation/devicetree/bindings/reset/reset.txt - -Required properties: -- compatible: should be "snps,hsdk-v1.0-reset". -- reg: should always contain 2 pairs address - length: first for reset - configuration register and second for corresponding SW reset and status bits - register. -- #reset-cells: from common reset binding; Should always be set to 1. - -Example: - reset: reset@880 { - compatible = "snps,hsdk-v1.0-reset"; - #reset-cells = <1>; - reg = <0x8A0 0x4>, <0xFF0 0x4>; - }; - -Specifying reset lines connected to IP modules: - ethernet@.... { - .... - resets = <&reset HSDK_V1_ETH_RESET>; - .... - }; - -The index could be found in diff --git a/MAINTAINERS b/MAINTAINERS index 2281af4b41b6..3b9887b3644e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12915,9 +12915,9 @@ F: drivers/mmc/host/dw_mmc* SYNOPSYS HSDK RESET CONTROLLER DRIVER M: Eugeniy Paltsev S: Supported -F: drivers/reset/reset-hsdk-v1.c -F: include/dt-bindings/reset/snps,hsdk-v1-reset.h -F: Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt +F: drivers/reset/reset-hsdk.c +F: include/dt-bindings/reset/snps,hsdk-reset.h +F: Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt SYSTEM CONFIGURATION (SYSCON) M: Lee Jones diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index d063bd5373dd..a7c7d5a8c089 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -34,12 +34,12 @@ config RESET_BERLIN help This enables the reset controller driver for Marvell Berlin SoCs. -config RESET_HSDK_V1 - bool "HSDK v1 Reset Driver" +config RESET_HSDK + bool "Synopsys HSDK Reset Driver" depends on HAS_IOMEM default n help - This enables the reset controller driver for HSDK v1. + This enables the reset controller driver for HSDK board. config RESET_IMX7 bool "i.MX7 Reset Driver" if COMPILE_TEST diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index d368367110e5..af1c15c330b3 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o -obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o +obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o diff --git a/drivers/reset/reset-hsdk-v1.c b/drivers/reset/reset-hsdk-v1.c deleted file mode 100644 index bca13e4bf622..000000000000 --- a/drivers/reset/reset-hsdk-v1.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2017 Synopsys. - * - * Synopsys HSDKv1 SDP reset driver. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define to_hsdkv1_rst(p) container_of((p), struct hsdkv1_rst, rcdev) - -struct hsdkv1_rst { - void __iomem *regs_ctl; - void __iomem *regs_rst; - spinlock_t lock; - struct reset_controller_dev rcdev; -}; - -static const u32 rst_map[] = { - BIT(16), /* APB_RST */ - BIT(17), /* AXI_RST */ - BIT(18), /* ETH_RST */ - BIT(19), /* USB_RST */ - BIT(20), /* SDIO_RST */ - BIT(21), /* HDMI_RST */ - BIT(22), /* GFX_RST */ - BIT(25), /* DMAC_RST */ - BIT(31), /* EBI_RST */ -}; - -#define HSDK_MAX_RESETS ARRAY_SIZE(rst_map) - -#define CGU_SYS_RST_CTRL 0x0 -#define CGU_IP_SW_RESET 0x0 -#define CGU_IP_SW_RESET_DELAY_SHIFT 16 -#define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT) -#define CGU_IP_SW_RESET_DELAY 0 -#define CGU_IP_SW_RESET_RESET BIT(0) -#define SW_RESET_TIMEOUT 10000 - -static void hsdkv1_reset_config(struct hsdkv1_rst *rst, unsigned long id) -{ - writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL); -} - -static int hsdkv1_reset_do(struct hsdkv1_rst *rst) -{ - u32 reg; - - reg = readl(rst->regs_rst + CGU_IP_SW_RESET); - reg &= ~CGU_IP_SW_RESET_DELAY_MASK; - reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT; - reg |= CGU_IP_SW_RESET_RESET; - writel(reg, rst->regs_rst + CGU_IP_SW_RESET); - - /* wait till reset bit is back to 0 */ - return readl_poll_timeout_atomic(rst->regs_rst + CGU_IP_SW_RESET, reg, - !(reg & CGU_IP_SW_RESET_RESET), 5, SW_RESET_TIMEOUT); -} - -static int hsdkv1_reset_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct hsdkv1_rst *rst = to_hsdkv1_rst(rcdev); - unsigned long flags; - int ret; - - spin_lock_irqsave(&rst->lock, flags); - hsdkv1_reset_config(rst, id); - ret = hsdkv1_reset_do(rst); - spin_unlock_irqrestore(&rst->lock, flags); - - return ret; -} - -static const struct reset_control_ops hsdkv1_reset_ops = { - .reset = hsdkv1_reset_reset, -}; - -static int hsdkv1_reset_probe(struct platform_device *pdev) -{ - struct hsdkv1_rst *rst; - struct resource *mem; - - rst = devm_kzalloc(&pdev->dev, sizeof(*rst), GFP_KERNEL); - if (!rst) - return -ENOMEM; - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - rst->regs_ctl = devm_ioremap_resource(&pdev->dev, mem); - if (IS_ERR(rst->regs_ctl)) - return PTR_ERR(rst->regs_ctl); - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - rst->regs_rst = devm_ioremap_resource(&pdev->dev, mem); - if (IS_ERR(rst->regs_rst)) - return PTR_ERR(rst->regs_rst); - - spin_lock_init(&rst->lock); - - rst->rcdev.owner = THIS_MODULE; - rst->rcdev.ops = &hsdkv1_reset_ops; - rst->rcdev.of_node = pdev->dev.of_node; - rst->rcdev.nr_resets = HSDK_MAX_RESETS; - rst->rcdev.of_reset_n_cells = 1; - - return reset_controller_register(&rst->rcdev); -} - -static const struct of_device_id hsdkv1_reset_dt_match[] = { - { .compatible = "snps,hsdk-v1.0-reset" }, - { }, -}; - -static struct platform_driver hsdkv1_reset_driver = { - .probe = hsdkv1_reset_probe, - .driver = { - .name = "hsdk-v1.0-reset", - .of_match_table = hsdkv1_reset_dt_match, - }, -}; -builtin_platform_driver(hsdkv1_reset_driver); - -MODULE_AUTHOR("Eugeniy Paltsev "); -MODULE_DESCRIPTION("Synopsys HSDKv1 SDP reset driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/reset/reset-hsdk.c b/drivers/reset/reset-hsdk.c new file mode 100644 index 000000000000..8bce391c6943 --- /dev/null +++ b/drivers/reset/reset-hsdk.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2017 Synopsys. + * + * Synopsys HSDK Development platform reset driver. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define to_hsdk_rst(p) container_of((p), struct hsdk_rst, rcdev) + +struct hsdk_rst { + void __iomem *regs_ctl; + void __iomem *regs_rst; + spinlock_t lock; + struct reset_controller_dev rcdev; +}; + +static const u32 rst_map[] = { + BIT(16), /* APB_RST */ + BIT(17), /* AXI_RST */ + BIT(18), /* ETH_RST */ + BIT(19), /* USB_RST */ + BIT(20), /* SDIO_RST */ + BIT(21), /* HDMI_RST */ + BIT(22), /* GFX_RST */ + BIT(25), /* DMAC_RST */ + BIT(31), /* EBI_RST */ +}; + +#define HSDK_MAX_RESETS ARRAY_SIZE(rst_map) + +#define CGU_SYS_RST_CTRL 0x0 +#define CGU_IP_SW_RESET 0x0 +#define CGU_IP_SW_RESET_DELAY_SHIFT 16 +#define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT) +#define CGU_IP_SW_RESET_DELAY 0 +#define CGU_IP_SW_RESET_RESET BIT(0) +#define SW_RESET_TIMEOUT 10000 + +static void hsdk_reset_config(struct hsdk_rst *rst, unsigned long id) +{ + writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL); +} + +static int hsdk_reset_do(struct hsdk_rst *rst) +{ + u32 reg; + + reg = readl(rst->regs_rst + CGU_IP_SW_RESET); + reg &= ~CGU_IP_SW_RESET_DELAY_MASK; + reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT; + reg |= CGU_IP_SW_RESET_RESET; + writel(reg, rst->regs_rst + CGU_IP_SW_RESET); + + /* wait till reset bit is back to 0 */ + return readl_poll_timeout_atomic(rst->regs_rst + CGU_IP_SW_RESET, reg, + !(reg & CGU_IP_SW_RESET_RESET), 5, SW_RESET_TIMEOUT); +} + +static int hsdk_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct hsdk_rst *rst = to_hsdk_rst(rcdev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&rst->lock, flags); + hsdk_reset_config(rst, id); + ret = hsdk_reset_do(rst); + spin_unlock_irqrestore(&rst->lock, flags); + + return ret; +} + +static const struct reset_control_ops hsdk_reset_ops = { + .reset = hsdk_reset_reset, +}; + +static int hsdk_reset_probe(struct platform_device *pdev) +{ + struct hsdk_rst *rst; + struct resource *mem; + + rst = devm_kzalloc(&pdev->dev, sizeof(*rst), GFP_KERNEL); + if (!rst) + return -ENOMEM; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rst->regs_ctl = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(rst->regs_ctl)) + return PTR_ERR(rst->regs_ctl); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + rst->regs_rst = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(rst->regs_rst)) + return PTR_ERR(rst->regs_rst); + + spin_lock_init(&rst->lock); + + rst->rcdev.owner = THIS_MODULE; + rst->rcdev.ops = &hsdk_reset_ops; + rst->rcdev.of_node = pdev->dev.of_node; + rst->rcdev.nr_resets = HSDK_MAX_RESETS; + rst->rcdev.of_reset_n_cells = 1; + + return reset_controller_register(&rst->rcdev); +} + +static const struct of_device_id hsdk_reset_dt_match[] = { + { .compatible = "snps,hsdk-reset" }, + { }, +}; + +static struct platform_driver hsdk_reset_driver = { + .probe = hsdk_reset_probe, + .driver = { + .name = "hsdk-reset", + .of_match_table = hsdk_reset_dt_match, + }, +}; +builtin_platform_driver(hsdk_reset_driver); + +MODULE_AUTHOR("Eugeniy Paltsev "); +MODULE_DESCRIPTION("Synopsys HSDK SDP reset driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/reset/snps,hsdk-reset.h b/include/dt-bindings/reset/snps,hsdk-reset.h new file mode 100644 index 000000000000..e1a643e4bc91 --- /dev/null +++ b/include/dt-bindings/reset/snps,hsdk-reset.h @@ -0,0 +1,17 @@ +/** + * This header provides index for the HSDK reset controller. + */ +#ifndef _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK +#define _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK + +#define HSDK_APB_RESET 0 +#define HSDK_AXI_RESET 1 +#define HSDK_ETH_RESET 2 +#define HSDK_USB_RESET 3 +#define HSDK_SDIO_RESET 4 +#define HSDK_HDMI_RESET 5 +#define HSDK_GFX_RESET 6 +#define HSDK_DMAC_RESET 7 +#define HSDK_EBI_RESET 8 + +#endif /*_DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK*/ diff --git a/include/dt-bindings/reset/snps,hsdk-v1-reset.h b/include/dt-bindings/reset/snps,hsdk-v1-reset.h deleted file mode 100644 index d898c89b7123..000000000000 --- a/include/dt-bindings/reset/snps,hsdk-v1-reset.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * This header provides index for the HSDK v1 reset controller. - */ -#ifndef _DT_BINDINGS_RESET_CONTROLLER_HSDK_V1 -#define _DT_BINDINGS_RESET_CONTROLLER_HSDK_V1 - -#define HSDK_V1_APB_RESET 0 -#define HSDK_V1_AXI_RESET 1 -#define HSDK_V1_ETH_RESET 2 -#define HSDK_V1_USB_RESET 3 -#define HSDK_V1_SDIO_RESET 4 -#define HSDK_V1_HDMI_RESET 5 -#define HSDK_V1_GFX_RESET 6 -#define HSDK_V1_DMAC_RESET 7 -#define HSDK_V1_EBI_RESET 8 - -#endif /*_DT_BINDINGS_RESET_CONTROLLER_HSDK_V1*/ -- cgit v1.2.3 From 1c363eaece2752c5f8b1b874cb4ae435de06aa66 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 5 Sep 2017 10:56:13 +0200 Subject: android: binder: fix type mismatch warning Allowing binder to expose the 64-bit API on 32-bit kernels caused a build warning: drivers/android/binder.c: In function 'binder_transaction_buffer_release': drivers/android/binder.c:2220:15: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] fd_array = (u32 *)(parent_buffer + fda->parent_offset); ^ drivers/android/binder.c: In function 'binder_translate_fd_array': drivers/android/binder.c:2445:13: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] fd_array = (u32 *)(parent_buffer + fda->parent_offset); ^ drivers/android/binder.c: In function 'binder_fixup_parent': drivers/android/binder.c:2511:18: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] This adds extra type casts to avoid the warning. However, there is another problem with the Kconfig option: turning it on or off creates two incompatible ABI versions, a kernel that has this enabled cannot run user space that was built without it or vice versa. A better solution might be to leave the option hidden until the binder code is fixed to deal with both ABI versions. Fixes: e8d2ed7db7c3 ("Revert "staging: Fix build issues with new binder API"") Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index d055b3f2a207..72af95c9ea22 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2217,7 +2217,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, debug_id, (u64)fda->num_fds); continue; } - fd_array = (u32 *)(parent_buffer + fda->parent_offset); + fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset); for (fd_index = 0; fd_index < fda->num_fds; fd_index++) task_close_fd(proc, fd_array[fd_index]); } break; @@ -2442,7 +2442,7 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda, */ parent_buffer = parent->buffer - binder_alloc_get_user_buffer_offset(&target_proc->alloc); - fd_array = (u32 *)(parent_buffer + fda->parent_offset); + fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset); if (!IS_ALIGNED((unsigned long)fd_array, sizeof(u32))) { binder_user_error("%d:%d parent offset not aligned correctly.\n", proc->pid, thread->pid); @@ -2508,7 +2508,7 @@ static int binder_fixup_parent(struct binder_transaction *t, proc->pid, thread->pid); return -EINVAL; } - parent_buffer = (u8 *)(parent->buffer - + parent_buffer = (u8 *)((uintptr_t)parent->buffer - binder_alloc_get_user_buffer_offset( &target_proc->alloc)); *(binder_uintptr_t *)(parent_buffer + bp->parent_offset) = bp->buffer; -- cgit v1.2.3 From 52b81611f209da5f49019260522633e994e241b5 Mon Sep 17 00:00:00 2001 From: Xu YiPing Date: Tue, 5 Sep 2017 10:25:38 -0700 Subject: binder: fix an ret value override commit 372e3147df70 ("binder: guarantee txn complete / errors delivered in-order") incorrectly defined a local ret value. This ret value will be invalid when out of the if block Fixes: 372e3147df70 ("binder: refactor binder ref inc/dec for thread safety") Signed-off-by: Xu YiPing Signed-off-by: Todd Kjos Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 72af95c9ea22..b257bb0e2cfe 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2326,7 +2326,6 @@ static int binder_translate_handle(struct flat_binder_object *fp, (u64)node->ptr); binder_node_unlock(node); } else { - int ret; struct binder_ref_data dest_rdata; binder_node_unlock(node); -- cgit v1.2.3 From d53bebdf4d779497b29e1aad26e19cac1d446f42 Mon Sep 17 00:00:00 2001 From: Xu YiPing Date: Tue, 5 Sep 2017 10:21:52 -0700 Subject: binder: fix memory corruption in binder_transaction binder commit 7a4408c6bd3e ("binder: make sure accesses to proc/thread are safe") made a change to enqueue tcomplete to thread->todo before enqueuing the transaction. However, in err_dead_proc_or_thread case, the tcomplete is directly freed, without dequeued. It may cause the thread->todo list to be corrupted. So, dequeue it before freeing. Fixes: 7a4408c6bd3e ("binder: make sure accesses to proc/thread are safe") Signed-off-by: Xu YiPing Signed-off-by: Todd Kjos Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index b257bb0e2cfe..ab34239a76ee 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3082,6 +3082,7 @@ static void binder_transaction(struct binder_proc *proc, err_dead_proc_or_thread: return_error = BR_DEAD_REPLY; return_error_line = __LINE__; + binder_dequeue_work(proc, tcomplete); err_translate_failed: err_bad_object_type: err_bad_offset: -- cgit v1.2.3 From 93dc1774d2a4c7a298d5cdf78cc8acdcb7b1428d Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 7 Sep 2017 15:37:30 +0200 Subject: auxdisplay: charlcd: properly restore atomic counter on error path Commit f4757af ("staging: panel: Fix single-open policy race condition") introduced in 3.19-rc1 attempted to fix a race condition on the open, but failed to properly do it and used to exit without restoring the semaphore. This results in -EBUSY being returned after the first open error until the module is reloaded or the system restarted (ie: consecutive to a dual open resulting in -EBUSY or to a permission error). [ Note for stable maintainers: the code moved from drivers/misc/panel.c to drivers/auxdisplay/{charlcd,panel}.c during 4.12. The patch easily applies there (modulo the renamed atomic counter) but I can provide a tested backport if desired. ] Fixes: f4757af85 # 3.19-rc1 Cc: stable@vger.kernel.org Cc: Mariusz Gorski Cc: Geert Uytterhoeven Cc: Miguel Ojeda Sandonis Signed-off-by: Willy Tarreau Signed-off-by: Greg Kroah-Hartman --- drivers/auxdisplay/charlcd.c | 11 +++++++++-- drivers/auxdisplay/panel.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c index cfeb049a01ef..642afd88870b 100644 --- a/drivers/auxdisplay/charlcd.c +++ b/drivers/auxdisplay/charlcd.c @@ -647,18 +647,25 @@ static ssize_t charlcd_write(struct file *file, const char __user *buf, static int charlcd_open(struct inode *inode, struct file *file) { struct charlcd_priv *priv = to_priv(the_charlcd); + int ret; + ret = -EBUSY; if (!atomic_dec_and_test(&charlcd_available)) - return -EBUSY; /* open only once at a time */ + goto fail; /* open only once at a time */ + ret = -EPERM; if (file->f_mode & FMODE_READ) /* device is write-only */ - return -EPERM; + goto fail; if (priv->must_clear) { charlcd_clear_display(&priv->lcd); priv->must_clear = false; } return nonseekable_open(inode, file); + + fail: + atomic_inc(&charlcd_available); + return ret; } static int charlcd_release(struct inode *inode, struct file *file) diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c index df126dcdaf18..6911acd896d9 100644 --- a/drivers/auxdisplay/panel.c +++ b/drivers/auxdisplay/panel.c @@ -1105,14 +1105,21 @@ static ssize_t keypad_read(struct file *file, static int keypad_open(struct inode *inode, struct file *file) { + int ret; + + ret = -EBUSY; if (!atomic_dec_and_test(&keypad_available)) - return -EBUSY; /* open only once at a time */ + goto fail; /* open only once at a time */ + ret = -EPERM; if (file->f_mode & FMODE_WRITE) /* device is read-only */ - return -EPERM; + goto fail; keypad_buflen = 0; /* flush the buffer on opening */ return 0; + fail: + atomic_inc(&keypad_available); + return ret; } static int keypad_release(struct inode *inode, struct file *file) -- cgit v1.2.3 From 38b0774c0598c7a54b8499d18c2b764c35dc94ab Mon Sep 17 00:00:00 2001 From: Guy Shapiro Date: Mon, 11 Sep 2017 11:00:11 +0200 Subject: nvmem: core: return EFBIG on out-of-range write When writing data that exceeds the nvmem size to a nvmem sysfs file using the sh redirection operator >, the shell hangs, trying to write the out-of-range bytes endlessly. Fix the problem by returning EFBIG described in man 2 write. Similar change was done for binary sysfs files on commit 0936896056365349afa867c16e9f9100a6707cbf Signed-off-by: Guy Shapiro Cc: linux-api@vger.kernel.org Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index de54c7f5048a..3866117bc285 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -135,7 +135,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, /* Stop the user from writing */ if (pos >= nvmem->size) - return 0; + return -EFBIG; if (count < nvmem->word_size) return -EINVAL; -- cgit v1.2.3 From aad8d097c9224be264939fc6c02a5570ea094f60 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 11 Sep 2017 11:00:12 +0200 Subject: nvmem: add missing of_node_put() in of_nvmem_cell_get() of_get_next_parent() increments the refcount of the returned node. It should be put when done. Signed-off-by: Masahiro Yamada Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 3866117bc285..d12e5de78e70 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -789,6 +789,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, return ERR_PTR(-EINVAL); nvmem = __nvmem_device_get(nvmem_np, NULL, NULL); + of_node_put(nvmem_np); if (IS_ERR(nvmem)) return ERR_CAST(nvmem); -- cgit v1.2.3 From 1298d51c44fddcb609ea6c9fa37b76028593963b Mon Sep 17 00:00:00 2001 From: Zhi Wang Date: Mon, 18 Sep 2017 21:36:34 +0800 Subject: drm/i915: Return the correct score in i915_ppat_get() The cache attribute of the required entry has to be the same with the existing value. After this requirement is met, the futher comparison should be performed. After this fix, the refined test case can pass. v2: - Refine the tittle and comments. (Rodrigo) Fixes: 4395890a4855 ("drm/i915: Introduce private PAT management") Cc: Chris Wilson Cc: Ben Widawsky Cc: Rodrigo Vivi Cc: Joonas Lahtinen Signed-off-by: Zhi Wang Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1505741794-10593-1-git-send-email-zhi.a.wang@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 729ebaf29b71..37cd0860fc29 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2965,7 +2965,7 @@ static unsigned int bdw_private_pat_match(u8 src, u8 dst) }; /* Cache attribute has to be matched. */ - if (GEN8_PPAT_GET_CA(src) == GEN8_PPAT_GET_CA(dst)) + if (GEN8_PPAT_GET_CA(src) != GEN8_PPAT_GET_CA(dst)) return 0; score |= CA_MATCH; -- cgit v1.2.3 From 452562abb5b76c14449dead2a7113f641893e8bc Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 7 Sep 2017 15:16:05 +0100 Subject: base: arch_topology: fix section mismatch build warnings Commit 2ef7a2953c81 ("arm, arm64: factorize common cpu capacity default code") introduced init_cpu_capacity_callback and init_cpu_capacity_notifier which are referenced from initcall and are missing __init{,data} annotations resulting the below section mismatch build warnings. "WARNING: vmlinux.o(.text+0xbab790): Section mismatch in reference from the function init_cpu_capacity_callback() to the variable .init.text:$x The function init_cpu_capacity_callback() references the variable __init $x. This is often because init_cpu_capacity_callback lacks a __init annotation or the annotation of $x is wrong." This patch fixes the above build warnings by adding the required annotations. Fixes: 2ef7a2953c81 ("arm, arm64: factorize common cpu capacity default code") Cc: Juri Lelli Cc: stable Signed-off-by: Sudeep Holla Signed-off-by: Greg Kroah-Hartman --- drivers/base/arch_topology.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 41be9ff7d70a..6df7d6676a48 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -166,11 +166,11 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu) } #ifdef CONFIG_CPU_FREQ -static cpumask_var_t cpus_to_visit; -static void parsing_done_workfn(struct work_struct *work); -static DECLARE_WORK(parsing_done_work, parsing_done_workfn); +static cpumask_var_t cpus_to_visit __initdata; +static void __init parsing_done_workfn(struct work_struct *work); +static __initdata DECLARE_WORK(parsing_done_work, parsing_done_workfn); -static int +static int __init init_cpu_capacity_callback(struct notifier_block *nb, unsigned long val, void *data) @@ -206,7 +206,7 @@ init_cpu_capacity_callback(struct notifier_block *nb, return 0; } -static struct notifier_block init_cpu_capacity_notifier = { +static struct notifier_block init_cpu_capacity_notifier __initdata = { .notifier_call = init_cpu_capacity_callback, }; @@ -232,7 +232,7 @@ static int __init register_cpufreq_notifier(void) } core_initcall(register_cpufreq_notifier); -static void parsing_done_workfn(struct work_struct *work) +static void __init parsing_done_workfn(struct work_struct *work) { cpufreq_unregister_notifier(&init_cpu_capacity_notifier, CPUFREQ_POLICY_NOTIFIER); -- cgit v1.2.3 From 9821786d7c90eee2f6852261893d9703801aae47 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Mon, 18 Sep 2017 17:39:12 +0300 Subject: usb: xhci: Free the right ring in xhci_add_endpoint() In the xhci_add_endpoint(), a new ring was allocated and saved at xhci_virt_ep->new_ring. Hence, when error happens, we need to free the allocated ring before returning error. Current code frees xhci_virt_ep->ring instead of the new_ring. This patch fixes this. Cc: Signed-off-by: Lu Baolu Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b2ff1ff1a02f..ee198ea47f49 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1703,7 +1703,8 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, if (xhci->quirks & XHCI_MTK_HOST) { ret = xhci_mtk_add_ep_quirk(hcd, udev, ep); if (ret < 0) { - xhci_free_endpoint_ring(xhci, virt_dev, ep_index); + xhci_ring_free(xhci, virt_dev->eps[ep_index].new_ring); + virt_dev->eps[ep_index].new_ring = NULL; return ret; } } -- cgit v1.2.3 From 5a838a13c9b4e5dd188b7a6eaeb894e9358ead0c Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 18 Sep 2017 17:39:13 +0300 Subject: xhci: fix finding correct bus_state structure for USB 3.1 hosts xhci driver keeps a bus_state structure for each hcd (usb2 and usb3) The structure is picked based on hcd speed, but driver only compared for HCD_USB3 speed, returning the wrong bus_state for HCD_USB31 hosts. This caused null pointer dereference errors in bus_resume function. Cc: Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2abaa4d6d39d..e96e90d0fe9f 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1681,7 +1681,7 @@ struct xhci_bus_state { static inline unsigned int hcd_index(struct usb_hcd *hcd) { - if (hcd->speed == HCD_USB3) + if (hcd->speed >= HCD_USB3) return 0; else return 1; -- cgit v1.2.3 From 114ec3a6f9096d211a4aff4277793ba969a62c73 Mon Sep 17 00:00:00 2001 From: Jim Dickerson Date: Mon, 18 Sep 2017 17:39:14 +0300 Subject: usb: pci-quirks.c: Corrected timeout values used in handshake Servers were emitting failed handoff messages but were not waiting the full 1 second as designated in section 4.22.1 of the eXtensible Host Controller Interface specifications. The handshake was using wrong units so calls were made with milliseconds not microseconds. Comments referenced 5 seconds not 1 second as in specs. The wrong units were also corrected in a second handshake call. Cc: Signed-off-by: Jim Dickerson Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 658d9d1f9ea3..e02dbb1e1cdd 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -1022,7 +1022,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); * * Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS. * It signals to the BIOS that the OS wants control of the host controller, - * and then waits 5 seconds for the BIOS to hand over control. + * and then waits 1 second for the BIOS to hand over control. * If we timeout, assume the BIOS is broken and take control anyway. */ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) @@ -1069,9 +1069,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) if (val & XHCI_HC_BIOS_OWNED) { writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); - /* Wait for 5 seconds with 10 microsecond polling interval */ + /* Wait for 1 second with 10 microsecond polling interval */ timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, - 0, 5000, 10); + 0, 1000000, 10); /* Assume a buggy BIOS and take HC ownership anyway */ if (timeout) { @@ -1100,7 +1100,7 @@ hc_init: * operational or runtime registers. Wait 5 seconds and no more. */ timeout = handshake(op_reg_base + XHCI_STS_OFFSET, XHCI_STS_CNR, 0, - 5000, 10); + 5000000, 10); /* Assume a buggy HC and start HC initialization anyway */ if (timeout) { val = readl(op_reg_base + XHCI_STS_OFFSET); -- cgit v1.2.3 From 76a14d7bf92960aac2f5450bfd23783bfa618be9 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 18 Sep 2017 17:39:15 +0300 Subject: xhci: fix wrong endpoint ESIT value shown in tracing Read the endpiont ESIT from endpiont context using correct macro. Add a macro for reading the high bits of ESIT for Large ESIT Payload Capable hosts (LEC=1) Cc: # 4.12 Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e96e90d0fe9f..7c87189e8110 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -735,6 +735,8 @@ struct xhci_ep_ctx { #define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK) /* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */ #define EP_HAS_LSA (1 << 15) +/* hosts with LEC=1 use bits 31:24 as ESIT high bits. */ +#define CTX_TO_MAX_ESIT_PAYLOAD_HI(p) (((p) >> 24) & 0xff) /* ep_info2 bitmasks */ /* @@ -2540,8 +2542,8 @@ static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq, u8 lsa; u8 hid; - esit = EP_MAX_ESIT_PAYLOAD_HI(info) << 16 | - EP_MAX_ESIT_PAYLOAD_LO(tx_info); + esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 | + CTX_TO_MAX_ESIT_PAYLOAD(tx_info); ep_state = info & EP_STATE_MASK; max_pstr = info & EP_MAXPSTREAMS_MASK; -- cgit v1.2.3 From c6b8e79306f515b5483eb11076e0fbfc140434a8 Mon Sep 17 00:00:00 2001 From: Adam Wallis Date: Mon, 18 Sep 2017 17:39:16 +0300 Subject: usb: host: xhci-plat: allow sysdev to inherit from ACPI Commit 4c39d4b949d3 ("usb: xhci: use bus->sysdev for DMA configuration") updated the method determining DMA for XHCI from sysdev. However, this patch broke the ability to enumerate the FWNODE from parent ACPI devices from the child plat XHCI device. Currently, xhci_plat is not set up properly when the parent device is an ACPI node. The conditions that xhci_plat_probe should satisfy are 1. xhci_plat comes from firmware 2. xhci_plat is child of a device from firmware (dwc3-plat) 3. xhci_plat is grandchild of a pci device (dwc3-pci) Case 2 is covered when the child is an OF node (by checking sysdev->parent->of_node), however, an ACPI parent will return NULL in the of_node check and will thus not result in sysdev being set to sysdev->parent [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 This change adds a check for ACPI to completely allow for condition 2. This is done by first checking if the parent node is of type ACPI (e.g., dwc3-plat) and set sysdev to sysdev->parent if either of the two following conditions are met: 1: If fwnode is empty (in the case that platform_device_add_properties was not called on the allocated platform device) 2: fwnode exists but is not of type ACPI (this would happen if platform_device_add_properties was called on the allocated device. Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) Cc: stable@vger.kernel.org #4.12.x Cc: stable@vger.kernel.org #4.13.x Fixes: 4c39d4b949d3 ("usb: xhci: use bus->sysdev for DMA configuration") Tested-by: Thang Q. Nguyen Signed-off-by: Adam Wallis Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 163bafde709f..1cb6eaef4ae1 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -178,14 +178,18 @@ static int xhci_plat_probe(struct platform_device *pdev) * 2. xhci_plat is child of a device from firmware (dwc3-plat) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; #ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && - sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; + else if (sysdev->bus == &pci_bus_type) + break; #endif + } + + if (!sysdev) + sysdev = &pdev->dev; /* Try to set 64-bit DMA first */ if (WARN_ON(!sysdev->dma_mask)) -- cgit v1.2.3 From 4ec1cd3eeeee7ccc35681270da028dbc29ca7bbd Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 18 Sep 2017 17:39:17 +0300 Subject: xhci: Fix sleeping with spin_lock_irq() held in ASmedia 1042A workaround The flow control workaround for ASM1042A xHC hosts sleeps between register polling. The workaround gets called in several places, among them with spin_lock_irq() held when xHC host is resumed or hoplug removed. This was noticed as kernel panics at resume on a Dell XPS15 9550 with TB16 thunderbolt dock. Avoid sleeping with spin_lock_irq() held, use udelay() instead The original workaround was added to 4.9 and 4.12 stable releases, this patch needs to be applied to those as well. Fixes: 9da5a1092b13 ("xhci: Bad Ethernet performance plugged in ASM1042A host") Cc: #4.9+ Reported-by: Jose Marino Tested-by: Jose Marino Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index e02dbb1e1cdd..6dda3623a276 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -447,7 +447,7 @@ static int usb_asmedia_wait_write(struct pci_dev *pdev) if ((value & ASMT_CONTROL_WRITE_BIT) == 0) return 0; - usleep_range(40, 60); + udelay(50); } dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__); -- cgit v1.2.3 From 7bea22b124d77845c85a62eaa29a85ba6cc2f899 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 18 Sep 2017 17:39:18 +0300 Subject: xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor A SuperSpeedPlus roothub needs to have the Link Protocol (LP) bit set in the bmSublinkSpeedAttr[] entry of a SuperSpeedPlus descriptor. If the xhci controller has an optional Protocol Speed ID (PSI) table then that will be used as a base to create the roothub SuperSpeedPlus descriptor. The PSI table does not however necessary contain the LP bit so we need to set it manually. Check the psi speed and set LP bit if speed is 10Gbps or higher. We're not setting it for 5 to 10Gbps as USB 3.1 specification always mention SuperSpeedPlus for 10Gbps or higher, and some SSIC USB 3.0 speeds can be over 5Gbps, such as SSIC-G3B-L1 at 5830 Mbps Cc: # 4.6+ Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index ad89a6d4111b..4dba2cf73cbe 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -112,7 +112,7 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, /* If PSI table exists, add the custom speed attributes from it */ if (usb3_1 && xhci->usb3_rhub.psi_count) { - u32 ssp_cap_base, bm_attrib, psi; + u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp; int offset; ssp_cap_base = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE; @@ -139,6 +139,15 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, for (i = 0; i < xhci->usb3_rhub.psi_count; i++) { psi = xhci->usb3_rhub.psi[i]; psi &= ~USB_SSP_SUBLINK_SPEED_RSVD; + psi_exp = XHCI_EXT_PORT_PSIE(psi); + psi_mant = XHCI_EXT_PORT_PSIM(psi); + + /* Shift to Gbps and set SSP Link BIT(14) if 10Gpbs */ + for (; psi_exp < 3; psi_exp++) + psi_mant /= 1000; + if (psi_mant >= 10) + psi |= BIT(14); + if ((psi & PLT_MASK) == PLT_SYM) { /* Symmetric, create SSA RX and TX from one PSI entry */ put_unaligned_le32(psi, &buf[offset]); -- cgit v1.2.3 From bcd6a7aa13800afc1418e6b29d944d882214939a Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Mon, 18 Sep 2017 17:39:19 +0300 Subject: Revert "xhci: Limit USB2 port wake support for AMD Promontory hosts" This reverts commit dec08194ffeccfa1cf085906b53d301930eae18f. Commit dec08194ffec ("xhci: Limit USB2 port wake support for AMD Promontory hosts") makes all high speed USB ports on ASUS PRIME B350M-A cease to function after enabling runtime PM. All boards with this chipsets will be affected, so revert the commit. The original patch was added to stable 4.9, 4.11 and 4.12 and needs to reverted from there as well Cc: # 4.9+ Signed-off-by: Kai-Heng Feng Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 3 --- drivers/usb/host/xhci-pci.c | 12 ------------ drivers/usb/host/xhci.h | 2 +- 3 files changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 4dba2cf73cbe..da9158f171cb 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1515,9 +1515,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd) t2 |= PORT_WKOC_E | PORT_WKCONN_E; t2 &= ~PORT_WKDISC_E; } - if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && - (hcd->speed < HCD_USB3)) - t2 &= ~PORT_WAKE_BITS; } else t2 &= ~PORT_WAKE_BITS; diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 8071c8fdd15e..76f392954733 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -54,11 +54,6 @@ #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 -#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 -#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba -#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb -#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc - #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 static const char hcd_name[] = "xhci_hcd"; @@ -142,13 +137,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_AMD) xhci->quirks |= XHCI_TRUST_TX_LENGTH; - if ((pdev->vendor == PCI_VENDOR_ID_AMD) && - ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) - xhci->quirks |= XHCI_U2_DISABLE_WAKE; - if (pdev->vendor == PCI_VENDOR_ID_INTEL) { xhci->quirks |= XHCI_LPM_SUPPORT; xhci->quirks |= XHCI_INTEL_HOST; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 7c87189e8110..2b48aa4f6b76 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1828,7 +1828,7 @@ struct xhci_hcd { /* For controller with a broken Port Disable implementation */ #define XHCI_BROKEN_PORT_PED (1 << 25) #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) -#define XHCI_U2_DISABLE_WAKE (1 << 27) +/* Reserved. It was XHCI_U2_DISABLE_WAKE */ #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) unsigned int num_active_eps; -- cgit v1.2.3 From bf563b01c2895a4bfd1a29cc5abc67fe706ecffd Mon Sep 17 00:00:00 2001 From: Nicolai Stange Date: Mon, 11 Sep 2017 09:45:42 +0200 Subject: driver core: platform: Don't read past the end of "driver_override" buffer When printing the driver_override parameter when it is 4095 and 4094 bytes long, the printing code would access invalid memory because we need count+1 bytes for printing. Reject driver_override values of these lengths in driver_override_store(). This is in close analogy to commit 4efe874aace5 ("PCI: Don't read past the end of sysfs "driver_override" buffer") from Sasha Levin. Fixes: 3d713e0e382e ("driver core: platform: add device binding path 'driver_override'") Cc: stable@vger.kernel.org # v3.17+ Signed-off-by: Nicolai Stange Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index d1bd99271066..9045c5f3734e 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -868,7 +868,8 @@ static ssize_t driver_override_store(struct device *dev, struct platform_device *pdev = to_platform_device(dev); char *driver_override, *old, *cp; - if (count > PATH_MAX) + /* We need to keep extra room for a newline */ + if (count >= (PAGE_SIZE - 1)) return -EINVAL; driver_override = kstrndup(buf, count, GFP_KERNEL); -- cgit v1.2.3 From b5891fb520f742ce48b097c6b8a0b2db1e2bb979 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 14 Sep 2017 17:22:40 +0100 Subject: drm/i915/selftests: Disable iommu for the mock device On some machines, the iommu cannot allocate a domain for the mock device causing the dma_map_sg() to fail, and the selftest to fail with -ENOMEM. For the mock selftests, we are using a fake device and do not care about iommu; so convince intel_iommu to treat us as a dummy device with an identity mapping (and no iommu domain). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101080 Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170914162240.18310-1-chris@chris-wilson.co.uk Tested-by: Elizabeth De La Torre Mena Reviewed-by: Matthew Auld dev, "mock"); dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + /* hack to disable iommu for the fake device; force identity mapping */ + pdev->dev.archdata.iommu = (void *)-1; + dev_pm_domain_set(&pdev->dev, &pm_domain); pm_runtime_enable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); -- cgit v1.2.3 From 104583b504da8a3ad86d033b497cb6e58941a9a1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 12 Sep 2017 12:39:54 +0200 Subject: mxser: fix timeout calculation for low rates Paul reported, that low rates like B300 make the driver to hang in mxser_wait_until_sent. His debugging tackled the issue down to the info->timeout computation in mxser_set_baud. Obviously, ints are used there and they easily overflow with these low rates: B300 makes info->timeout to be -373. So switch all these types to unsigned as it ought to be. And use the u64 domain to perform the computation as in the worst case, we need 35 bits to store the computed value (before division). And use do_div not to break 32 bit kernels. [v2] make it actually build Signed-off-by: Jiri Slaby Cc: Paul Tested-by: Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 1c0c9553bc05..7dd38047ba23 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -246,11 +246,11 @@ struct mxser_port { unsigned char err_shadow; struct async_icount icount; /* kernel counters for 4 input interrupts */ - int timeout; + unsigned int timeout; int read_status_mask; int ignore_status_mask; - int xmit_fifo_size; + unsigned int xmit_fifo_size; int xmit_head; int xmit_tail; int xmit_cnt; @@ -572,8 +572,9 @@ static void mxser_dtr_rts(struct tty_port *port, int on) static int mxser_set_baud(struct tty_struct *tty, long newspd) { struct mxser_port *info = tty->driver_data; - int quot = 0, baud; + unsigned int quot = 0, baud; unsigned char cval; + u64 timeout; if (!info->ioaddr) return -1; @@ -594,8 +595,13 @@ static int mxser_set_baud(struct tty_struct *tty, long newspd) quot = 0; } - info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); - info->timeout += HZ / 50; /* Add .02 seconds of slop */ + /* + * worst case (128 * 1000 * 10 * 18432) needs 35 bits, so divide in the + * u64 domain + */ + timeout = (u64)info->xmit_fifo_size * HZ * 10 * quot; + do_div(timeout, info->baud_base); + info->timeout = timeout + HZ / 50; /* Add .02 seconds of slop */ if (quot) { info->MCR |= UART_MCR_DTR; -- cgit v1.2.3 From 0e5ec4140c4a8a38c4ff7293c018eb7da69a30db Mon Sep 17 00:00:00 2001 From: Russell Enderby Date: Tue, 5 Sep 2017 12:16:47 -0500 Subject: serial: bcm63xx: fix timing issue. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue where unprintable characters can occur or output is cut off over the serial uart / linux console depending on timing. Problem occurs when changing the serial baud rate when setting up the new console.The bcm63xx driver does a disable and flush of the uart tx fifo while there is data still in the tx fifo. If the tx fifo still has data it is trying to send out, we need to wait until it is empty before disabling and flushing the uart. When we now go to change the uart parameters including speed we check if there is data currently in the tx fifo.If there is was mdelay(10) and check again.If it tries 3 times and still has data in it we just continue and sacrifice the tx fifo buffer. A cleaner and more preferred approach would be to remove : - spin_lock_irqsave() - bcm_uart_disable() - bcm_uart_flush() However it is not clear if the author put those in to fix another underlying issue.As a result this solution is a safer approach. Output before the fix: [0.306000] 14e00520.serial: ttyS0 at MMIO 0x14e00520 (irq = 9, base_baud = 1687500) is a° 0.315000] console[ttyS0] enabled Output verified after the fix: [0.315000] 14e00520.serial: ttyS0 at MMIO 0x14e00520 (irq = 9, base_baud = 1687500) is a bcm63xx_uart [0.334000] console[ttyS0] enabled Signed-off-by: Russell Enderby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 583c9a0c7ecc..8c48c3784831 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -507,9 +507,14 @@ static void bcm_uart_set_termios(struct uart_port *port, { unsigned int ctl, baud, quot, ier; unsigned long flags; + int tries; spin_lock_irqsave(&port->lock, flags); + /* Drain the hot tub fully before we power it off for the winter. */ + for (tries = 3; !bcm_uart_tx_empty(port) && tries; tries--) + mdelay(10); + /* disable uart while changing speed */ bcm_uart_disable(port); bcm_uart_flush(port); -- cgit v1.2.3 From 9d7ee0e28da59b05647c3d2a7ad4076c16b1a6ef Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Mon, 4 Sep 2017 19:20:24 +0800 Subject: tty: serial: lpuart: avoid report NULL interrupt The current driver register irq in .startup() and free the irq in .shutdown(), then user will see the NULL interrupt output from 'cat /proc/interrupts' after the uart port test completed: ... 41: 515 0 0 0 GICv3 257 Level fsl-lpuart 42: 2 0 0 0 GICv3 258 Level ... It is better to register all the irqs during probe function via devm_request_irq() to avoid to call free_irq(). Signed-off-by: Fugang Duan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 849c1f9991ce..f0252184291e 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1276,7 +1276,6 @@ static void rx_dma_timer_init(struct lpuart_port *sport) static int lpuart_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - int ret; unsigned long flags; unsigned char temp; @@ -1291,11 +1290,6 @@ static int lpuart_startup(struct uart_port *port) sport->rxfifo_size = 0x1 << (((temp >> UARTPFIFO_RXSIZE_OFF) & UARTPFIFO_FIFOSIZE_MASK) + 1); - ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0, - DRIVER_NAME, sport); - if (ret) - return ret; - spin_lock_irqsave(&sport->port.lock, flags); lpuart_setup_watermark(sport); @@ -1333,7 +1327,6 @@ static int lpuart_startup(struct uart_port *port) static int lpuart32_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - int ret; unsigned long flags; unsigned long temp; @@ -1346,11 +1339,6 @@ static int lpuart32_startup(struct uart_port *port) sport->rxfifo_size = 0x1 << (((temp >> UARTFIFO_RXSIZE_OFF) & UARTFIFO_FIFOSIZE_MASK) - 1); - ret = devm_request_irq(port->dev, port->irq, lpuart32_int, 0, - DRIVER_NAME, sport); - if (ret) - return ret; - spin_lock_irqsave(&sport->port.lock, flags); lpuart32_setup_watermark(sport); @@ -1380,8 +1368,6 @@ static void lpuart_shutdown(struct uart_port *port) spin_unlock_irqrestore(&port->lock, flags); - devm_free_irq(port->dev, port->irq, sport); - if (sport->lpuart_dma_rx_use) { del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); @@ -1400,7 +1386,6 @@ static void lpuart_shutdown(struct uart_port *port) static void lpuart32_shutdown(struct uart_port *port) { - struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long temp; unsigned long flags; @@ -1413,8 +1398,6 @@ static void lpuart32_shutdown(struct uart_port *port) lpuart32_write(port, temp, UARTCTRL); spin_unlock_irqrestore(&port->lock, flags); - - devm_free_irq(port->dev, port->irq, sport); } static void @@ -2212,16 +2195,22 @@ static int lpuart_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &sport->port); - if (lpuart_is_32(sport)) + if (lpuart_is_32(sport)) { lpuart_reg.cons = LPUART32_CONSOLE; - else + ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0, + DRIVER_NAME, sport); + } else { lpuart_reg.cons = LPUART_CONSOLE; + ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0, + DRIVER_NAME, sport); + } + + if (ret) + goto failed_irq_request; ret = uart_add_one_port(&lpuart_reg, &sport->port); - if (ret) { - clk_disable_unprepare(sport->clk); - return ret; - } + if (ret) + goto failed_attach_port; sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx"); if (!sport->dma_tx_chan) @@ -2240,6 +2229,11 @@ static int lpuart_probe(struct platform_device *pdev) } return 0; + +failed_attach_port: +failed_irq_request: + clk_disable_unprepare(sport->clk); + return ret; } static int lpuart_remove(struct platform_device *pdev) -- cgit v1.2.3 From c91261437985d481c472639d4397931d77f5d4e9 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 2 Sep 2017 23:13:55 +0300 Subject: serial: sccnxp: Fix error handling in sccnxp_probe() sccnxp_probe() returns result of regulator_disable() that may lead to returning zero, while device is not properly initialized. Also the driver enables clocks, but it does not disable it. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sccnxp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index cdd2f942317c..b9c7a904c1ea 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -889,7 +889,16 @@ static int sccnxp_probe(struct platform_device *pdev) goto err_out; uartclk = 0; } else { - clk_prepare_enable(clk); + ret = clk_prepare_enable(clk); + if (ret) + goto err_out; + + ret = devm_add_action_or_reset(&pdev->dev, + (void(*)(void *))clk_disable_unprepare, + clk); + if (ret) + goto err_out; + uartclk = clk_get_rate(clk); } @@ -988,7 +997,7 @@ static int sccnxp_probe(struct platform_device *pdev) uart_unregister_driver(&s->uart); err_out: if (!IS_ERR(s->regulator)) - return regulator_disable(s->regulator); + regulator_disable(s->regulator); return ret; } -- cgit v1.2.3 From 342a2c840ed0cb99509e99e082b1f8aa784b5e59 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 18 Sep 2017 12:21:23 +0100 Subject: drm/i915/perf: disable clk ratio reports on gen9 We're doing this on all Gen9 based platforms, let's just check the gen rather than listing every single platforms. Signed-off-by: Lionel Landwerlin Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20170918112124.29541-2-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/i915/i915_perf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 94185d610673..1b40ac6d1400 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -1850,8 +1850,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv, * be read back from automatically triggered reports, as part of the * RPT_ID field. */ - if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) || - IS_KABYLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) { + if (IS_GEN9(dev_priv)) { I915_WRITE(GEN8_OA_DEBUG, _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS | GEN9_OA_DEBUG_INCLUDE_CLK_RATIO)); -- cgit v1.2.3 From 22ea4f3528efaa0523d1643264372d0bdfbd49bd Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 18 Sep 2017 12:21:24 +0100 Subject: drm/i915/perf: add support for Coffeelake GT2 Add the test configuration & timestamp frequency for Coffeelake GT2. Signed-off-by: Lionel Landwerlin Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20170918112124.29541-3-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_oa_cflgt2.c | 109 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_oa_cflgt2.h | 34 +++++++++++ drivers/gpu/drm/i915/i915_perf.c | 5 ++ 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/i915_oa_cflgt2.c create mode 100644 drivers/gpu/drm/i915/i915_oa_cflgt2.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 1cb8059a3a16..5182e3d5557d 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -139,7 +139,8 @@ i915-y += i915_perf.o \ i915_oa_bxt.o \ i915_oa_kblgt2.o \ i915_oa_kblgt3.o \ - i915_oa_glk.o + i915_oa_glk.o \ + i915_oa_cflgt2.o ifeq ($(CONFIG_DRM_I915_GVT),y) i915-y += intel_gvt.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a24659b5e6b5..08e3ae15b52e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2984,6 +2984,8 @@ intel_info(const struct drm_i915_private *dev_priv) (dev_priv)->info.gt == 3) #define IS_CFL_ULT(dev_priv) (IS_COFFEELAKE(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0x00F0) == 0x00A0) +#define IS_CFL_GT2(dev_priv) (IS_COFFEELAKE(dev_priv) && \ + (dev_priv)->info.gt == 2) #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support) diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt2.c b/drivers/gpu/drm/i915/i915_oa_cflgt2.c new file mode 100644 index 000000000000..368c87d7ee9a --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_cflgt2.c @@ -0,0 +1,109 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include + +#include "i915_drv.h" +#include "i915_oa_cflgt2.h" + +static const struct i915_oa_reg b_counter_config_test_oa[] = { + { _MMIO(0x2740), 0x00000000 }, + { _MMIO(0x2744), 0x00800000 }, + { _MMIO(0x2714), 0xf0800000 }, + { _MMIO(0x2710), 0x00000000 }, + { _MMIO(0x2724), 0xf0800000 }, + { _MMIO(0x2720), 0x00000000 }, + { _MMIO(0x2770), 0x00000004 }, + { _MMIO(0x2774), 0x00000000 }, + { _MMIO(0x2778), 0x00000003 }, + { _MMIO(0x277c), 0x00000000 }, + { _MMIO(0x2780), 0x00000007 }, + { _MMIO(0x2784), 0x00000000 }, + { _MMIO(0x2788), 0x00100002 }, + { _MMIO(0x278c), 0x0000fff7 }, + { _MMIO(0x2790), 0x00100002 }, + { _MMIO(0x2794), 0x0000ffcf }, + { _MMIO(0x2798), 0x00100082 }, + { _MMIO(0x279c), 0x0000ffef }, + { _MMIO(0x27a0), 0x001000c2 }, + { _MMIO(0x27a4), 0x0000ffe7 }, + { _MMIO(0x27a8), 0x00100001 }, + { _MMIO(0x27ac), 0x0000ffe7 }, +}; + +static const struct i915_oa_reg flex_eu_config_test_oa[] = { +}; + +static const struct i915_oa_reg mux_config_test_oa[] = { + { _MMIO(0x9840), 0x00000080 }, + { _MMIO(0x9888), 0x11810000 }, + { _MMIO(0x9888), 0x07810013 }, + { _MMIO(0x9888), 0x1f810000 }, + { _MMIO(0x9888), 0x1d810000 }, + { _MMIO(0x9888), 0x1b930040 }, + { _MMIO(0x9888), 0x07e54000 }, + { _MMIO(0x9888), 0x1f908000 }, + { _MMIO(0x9888), 0x11900000 }, + { _MMIO(0x9888), 0x37900000 }, + { _MMIO(0x9888), 0x53900000 }, + { _MMIO(0x9888), 0x45900000 }, + { _MMIO(0x9888), 0x33900000 }, +}; + +static ssize_t +show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "1\n"); +} + +void +i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv) +{ + strncpy(dev_priv->perf.oa.test_config.uuid, + "74fb4902-d3d3-4237-9e90-cbdc68d0a446", + UUID_STRING_LEN); + dev_priv->perf.oa.test_config.id = 1; + + dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; + dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa); + + dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa; + dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa); + + dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa; + dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa); + + dev_priv->perf.oa.test_config.sysfs_metric.name = "74fb4902-d3d3-4237-9e90-cbdc68d0a446"; + dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs; + + dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr; + + dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id"; + dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444; + dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id; +} diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt2.h b/drivers/gpu/drm/i915/i915_oa_cflgt2.h new file mode 100644 index 000000000000..1f3268ef2ea2 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_cflgt2.h @@ -0,0 +1,34 @@ +/* + * Autogenerated file by GPU Top : https://github.com/rib/gputop + * DO NOT EDIT manually! + * + * + * Copyright (c) 2015 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef __I915_OA_CFLGT2_H__ +#define __I915_OA_CFLGT2_H__ + +extern void i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 1b40ac6d1400..902722ab84c9 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -206,6 +206,7 @@ #include "i915_oa_kblgt2.h" #include "i915_oa_kblgt3.h" #include "i915_oa_glk.h" +#include "i915_oa_cflgt2.h" /* HW requires this to be a power of two, between 128k and 16M, though driver * is currently generally designed assuming the largest 16M size is used such @@ -2926,6 +2927,9 @@ void i915_perf_register(struct drm_i915_private *dev_priv) i915_perf_load_test_config_kblgt3(dev_priv); } else if (IS_GEMINILAKE(dev_priv)) { i915_perf_load_test_config_glk(dev_priv); + } else if (IS_COFFEELAKE(dev_priv)) { + if (IS_CFL_GT2(dev_priv)) + i915_perf_load_test_config_cflgt2(dev_priv); } if (dev_priv->perf.oa.test_config.id == 0) @@ -3452,6 +3456,7 @@ void i915_perf_init(struct drm_i915_private *dev_priv) break; case INTEL_SKYLAKE: case INTEL_KABYLAKE: + case INTEL_COFFEELAKE: dev_priv->perf.oa.timestamp_frequency = 12000000; break; default: -- cgit v1.2.3 From da83ef85f5356b4bdf534add20fb34dcc6b53fc1 Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Thu, 14 Sep 2017 11:16:41 -0700 Subject: drm/i915: Do not enable DRRS when PSR is enabled Some platforms do not support PSR and DRRS simultaneously. Visual artifacts and flickering were reported on BDW HP Spectre x360 Convertible. Deferring to PSR when both PSR and DRRS are supported by the panel. V2: Minor code-style changes suggested by Rodrigo V3: Add a WARN_ON during PSR init suggested by Dhinakaran Correct debug message,title suggested by Jani Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101111 Cc: Nicholas Stommel Cc: Dhinakaran Pandiyan Cc: Jani Nikula Cc: Clinton Taylor Cc: Rodrigo Vivi Signed-off-by: Radhakrishna Sripada Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20170914181641.24393-1-radhakrishna.sripada@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 10 +++++----- drivers/gpu/drm/i915/intel_psr.c | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 887953c0f495..8db6b11f103f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5467,11 +5467,6 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, return; } - /* - * FIXME: This needs proper synchronization with psr state for some - * platforms that cannot have PSR and DRRS enabled at the same time. - */ - dig_port = dp_to_dig_port(intel_dp); encoder = &dig_port->base; intel_crtc = to_intel_crtc(encoder->base.crtc); @@ -5555,6 +5550,11 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp, return; } + if (dev_priv->psr.enabled) { + DRM_DEBUG_KMS("PSR enabled. Not enabling DRRS.\n"); + return; + } + mutex_lock(&dev_priv->drrs.mutex); if (WARN_ON(dev_priv->drrs.dp)) { DRM_ERROR("DRRS already enabled\n"); diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 55b4002bbe53..acb50945bfa8 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -530,6 +530,7 @@ void intel_psr_enable(struct intel_dp *intel_dp, return; } + WARN_ON(dev_priv->drrs.dp); mutex_lock(&dev_priv->psr.lock); if (dev_priv->psr.enabled) { DRM_DEBUG_KMS("PSR already in use\n"); -- cgit v1.2.3 From 4cc6feb715c223d59c8cad0dc71bce1a574a2c67 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 8 Sep 2017 16:45:33 -0700 Subject: drm/i915/cnp: Don't touch other PCH clock gating bits. Don't touch other bits. My bad. I haven't seen any case where those other bits appeard to be set before we touch it, but it is safe to avoid touching other bits we weren't told to touch. Fixes: 0a46ddd57c9e ("drm/i915/cnp: Wa 1181: Fix Backlight issue") Cc: Dhinakaran Pandiyan Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170908234534.17986-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 94624ede3479..adfeb7bb8874 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -8369,7 +8369,8 @@ static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) return; /* Wa #1181 */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, CNP_PWM_CGE_GATING_DISABLE); + I915_WRITE(SOUTH_DSPCLK_GATE_D, I915_READ(SOUTH_DSPCLK_GATE_D) | + CNP_PWM_CGE_GATING_DISABLE); } static void cnl_init_clock_gating(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From 80a921e207cea3dd18038501187078669a218dab Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 18 Sep 2017 23:00:08 +0300 Subject: ata_piix: Add Fujitsu-Siemens Lifebook S6120 to short cable IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fujitsu-Siemens Lifebook S6120 misdetects the cable type for some drives. The problematic one in this case is an mSATA SSD hooked up via a mSATA->PATA bridge. With regular hard disks the detection seems to work correctly. Strangely an older Lifebook model (S6020) detects the cable as 80c with the mSATA SSD, even if using the exact same flex cable. Cc: Tejun Heo Signed-off-by: Ville Syrjälä Signed-off-by: Tejun Heo --- drivers/ata/ata_piix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 8401c3b5be92..b702c20fbc2b 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -492,6 +492,7 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x152D, 0x0778 }, /* ICH7 on unknown Intel */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ + { 0x24CA, 0x10CF, 0x11AB }, /* ICH4M on Fujitsu-Siemens Lifebook S6120 */ { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */ -- cgit v1.2.3 From 55e001aabb826c96f09e0a440bdcbce620189dbc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Sep 2017 12:17:36 +0200 Subject: fpga: altera-cvp: remove DRIVER_ATTR() usage It's better to be explicit and use the DRIVER_ATTR_RW() macro when defining a driver's sysfs file. This is part of a series to drop DRIVER_ATTR() from the tree entirely. Cc: linux-fpga@vger.kernel.org Reviewed-by: Moritz Fischer Acked-by: Alan Tull Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/altera-cvp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c index 08629ee69d11..00e73d28077c 100644 --- a/drivers/fpga/altera-cvp.c +++ b/drivers/fpga/altera-cvp.c @@ -361,12 +361,12 @@ static const struct fpga_manager_ops altera_cvp_ops = { .write_complete = altera_cvp_write_complete, }; -static ssize_t show_chkcfg(struct device_driver *dev, char *buf) +static ssize_t chkcfg_show(struct device_driver *dev, char *buf) { return snprintf(buf, 3, "%d\n", altera_cvp_chkcfg); } -static ssize_t store_chkcfg(struct device_driver *drv, const char *buf, +static ssize_t chkcfg_store(struct device_driver *drv, const char *buf, size_t count) { int ret; @@ -378,7 +378,7 @@ static ssize_t store_chkcfg(struct device_driver *drv, const char *buf, return count; } -static DRIVER_ATTR(chkcfg, 0600, show_chkcfg, store_chkcfg); +static DRIVER_ATTR_RW(chkcfg); static int altera_cvp_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id); -- cgit v1.2.3 From 7eac35ea29dc54cbc8399de84c9bf16553575b89 Mon Sep 17 00:00:00 2001 From: Sebastian Frei Date: Tue, 12 Sep 2017 09:50:59 +0200 Subject: USB: serial: cp210x: fix partnum regression When adding GPIO support for the cp2105, the mentioned commit by Martyn Welch introduced a query for the part number of the chip. Unfortunately the driver aborts probing when this query fails, so currently the driver can not be used with chips not supporting this query. I have a data cable for Siemens mobile phones (ID 10ab:10c5) where this is the case. With this patch the driver can be bound even if the part number can not be queried. Fixes: cf5276ce7867 ("USB: serial: cp210x: Adding GPIO support for CP2105") Signed-off-by: Sebastian Frei [ johan: amend commit message; shorten error message and demote to warning; drop unnecessary move of usb_set_serial_data() ] Cc: stable # 4.9 Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2d945c9f975c..8364b44f4c45 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -352,6 +352,7 @@ static struct usb_serial_driver * const serial_drivers[] = { #define CP210X_PARTNUM_CP2104 0x04 #define CP210X_PARTNUM_CP2105 0x05 #define CP210X_PARTNUM_CP2108 0x08 +#define CP210X_PARTNUM_UNKNOWN 0xFF /* CP210X_GET_COMM_STATUS returns these 0x13 bytes */ struct cp210x_comm_status { @@ -1491,8 +1492,11 @@ static int cp210x_attach(struct usb_serial *serial) result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, CP210X_GET_PARTNUM, &priv->partnum, sizeof(priv->partnum)); - if (result < 0) - goto err_free_priv; + if (result < 0) { + dev_warn(&serial->interface->dev, + "querying part number failed\n"); + priv->partnum = CP210X_PARTNUM_UNKNOWN; + } usb_set_serial_data(serial, priv); @@ -1505,10 +1509,6 @@ static int cp210x_attach(struct usb_serial *serial) } return 0; -err_free_priv: - kfree(priv); - - return result; } static void cp210x_disconnect(struct usb_serial *serial) -- cgit v1.2.3 From 311de3ce96f453a5a6edb3066eb6109cc07e81d2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 6 Sep 2017 10:40:52 +0900 Subject: gpio: thunderx: select IRQ_DOMAIN_HIERARCHY instead of depends on IRQ_DOMAIN_HIERARCHY is not user-configurable, but supposed to be selected by drivers that need IRQ domain hierarchy support. GPIO_THUNDERX is the only user of "depends on IRQ_DOMAIN_HIERARCHY". This means, we can not enable GPIO_THUNDERX unless other drivers select IRQ_DOMAIN_HIERARCHY elsewhere. This is odd. Flip the logic. Signed-off-by: Masahiro Yamada Acked-by: David Daney Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3388d54ba114..3f80f167ed56 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -453,7 +453,8 @@ config GPIO_TS4800 config GPIO_THUNDERX tristate "Cavium ThunderX/OCTEON-TX GPIO" depends on ARCH_THUNDER || (64BIT && COMPILE_TEST) - depends on PCI_MSI && IRQ_DOMAIN_HIERARCHY + depends on PCI_MSI + select IRQ_DOMAIN_HIERARCHY select IRQ_FASTEOI_HIERARCHY_HANDLERS help Say yes here to support the on-chip GPIO lines on the ThunderX -- cgit v1.2.3 From e40a3ae1f794a35c4af3746291ed6fedc1fa0f6f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 6 Sep 2017 17:47:45 +0200 Subject: gpio: acpi: work around false-positive -Wstring-overflow warning gcc-7 notices that the pin_table is an array of 16-bit numbers, but fails to take the following range check into account: drivers/gpio/gpiolib-acpi.c: In function 'acpi_gpiochip_request_interrupt': drivers/gpio/gpiolib-acpi.c:206:24: warning: '%02X' directive writing between 2 and 4 bytes into a region of size 3 [-Wformat-overflow=] sprintf(ev_name, "_%c%02X", ^~~~ drivers/gpio/gpiolib-acpi.c:206:20: note: directive argument in the range [0, 65535] sprintf(ev_name, "_%c%02X", ^~~~~~~~~ drivers/gpio/gpiolib-acpi.c:206:3: note: 'sprintf' output between 5 and 7 bytes into a destination of size 5 sprintf(ev_name, "_%c%02X", ^~~~~~~~~~~~~~~~~~~~~~~~~~~ agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L', ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pin); ~~~~ As suggested by Andy, this changes the format string to have a fixed length. Since modifying the range check did not help, I also opened a bug against gcc, see link below. Fixes: 0d1c28a449c6 ("gpiolib-acpi: Add ACPI5 event model support to gpio.") Cc: Andy Shevchenko Link: https://patchwork.kernel.org/patch/9840801/ Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82123 Signed-off-by: Arnd Bergmann Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 4d2113530735..eb4528c87c0b 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -203,7 +203,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, if (pin <= 255) { char ev_name[5]; - sprintf(ev_name, "_%c%02X", + sprintf(ev_name, "_%c%02hhX", agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L', pin); if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle))) -- cgit v1.2.3 From c496ad835c31ad639b6865714270b3003df031f6 Mon Sep 17 00:00:00 2001 From: Andreas Engel Date: Mon, 18 Sep 2017 21:11:57 +0200 Subject: USB: serial: cp210x: add support for ELV TFD500 Add the USB device id for the ELV TFD500 data logger. Signed-off-by: Andreas Engel Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 8364b44f4c45..412f812522ee 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ + { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ -- cgit v1.2.3 From f46f156ea7704a40577800c3df63b599121a87ec Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 18 Sep 2017 17:46:52 +0100 Subject: drm/i915/selftests: Only touch archdata.iommu when it exists archdata.iommu only exists when CONFIG_IOMMU_API is enabled (and only applies to intel-iommu in our case) so conditionally compile it out when it doesn't exist. Fixes: b5891fb520f7 ("drm/i915/selftests: Disable iommu for the mock device") Signed-off-by: Chris Wilson Cc: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20170918164652.14200-1-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 38ed006be5be..2388424a14da 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -146,8 +146,10 @@ struct drm_i915_private *mock_gem_device(void) dev_set_name(&pdev->dev, "mock"); dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +#if IS_ENABLED(CONFIG_IOMMU_API) /* hack to disable iommu for the fake device; force identity mapping */ pdev->dev.archdata.iommu = (void *)-1; +#endif dev_pm_domain_set(&pdev->dev, &pm_domain); pm_runtime_enable(&pdev->dev); -- cgit v1.2.3 From 81c0ed21aa91230ab6c0de945155aa5c0626d001 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 11 Sep 2017 09:41:26 +0100 Subject: drm/i915/fence: Avoid del_timer_sync() from inside a timer A fence may be signaled from any context, including from inside a timer. One example is timer_i915_sw_fence_wake() which is used to provide a safety-net when waiting on an external fence. If the external fence is not signaled within a timely fashion, we signal our fence on its behalf, and so we then may process subsequent fences in the chain from within that timer context. Given that dma_i915_sw_fence_wake() may be from inside a timer, we cannot then use del_timer_sync() as that requires the timer lock for itself. To circumvent this, while trying to keep the signal propagation as low latency as possible, move the completion into a worker and use a bit of atomic switheroo to serialise the timer-callback and the dma-callback. Testcase: igt/gem_eio/in-flight-external Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170911084135.22903-3-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/i915_sw_fence.c | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index e9e64e8e9765..dfd95889f4b7 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -12,6 +12,7 @@ config DRM_I915 select DRM_PANEL select DRM_MIPI_DSI select RELAY + select IRQ_WORK # i915 depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick select BACKLIGHT_LCD_SUPPORT if ACPI diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index f29540f922af..808ea4d5b962 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -9,6 +9,7 @@ #include #include +#include #include #include "i915_sw_fence.h" @@ -356,31 +357,44 @@ struct i915_sw_dma_fence_cb { struct i915_sw_fence *fence; struct dma_fence *dma; struct timer_list timer; + struct irq_work work; }; static void timer_i915_sw_fence_wake(unsigned long data) { struct i915_sw_dma_fence_cb *cb = (struct i915_sw_dma_fence_cb *)data; + struct i915_sw_fence *fence; + + fence = xchg(&cb->fence, NULL); + if (!fence) + return; pr_warn("asynchronous wait on fence %s:%s:%x timed out\n", cb->dma->ops->get_driver_name(cb->dma), cb->dma->ops->get_timeline_name(cb->dma), cb->dma->seqno); - dma_fence_put(cb->dma); - cb->dma = NULL; - i915_sw_fence_complete(cb->fence); - cb->timer.function = NULL; + i915_sw_fence_complete(fence); } static void dma_i915_sw_fence_wake(struct dma_fence *dma, struct dma_fence_cb *data) { struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base); + struct i915_sw_fence *fence; + + fence = xchg(&cb->fence, NULL); + if (fence) + i915_sw_fence_complete(fence); + + irq_work_queue(&cb->work); +} + +static void irq_i915_sw_fence_work(struct irq_work *wrk) +{ + struct i915_sw_dma_fence_cb *cb = container_of(wrk, typeof(*cb), work); del_timer_sync(&cb->timer); - if (cb->timer.function) - i915_sw_fence_complete(cb->fence); dma_fence_put(cb->dma); kfree(cb); @@ -414,6 +428,7 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, __setup_timer(&cb->timer, timer_i915_sw_fence_wake, (unsigned long)cb, TIMER_IRQSAFE); + init_irq_work(&cb->work, irq_i915_sw_fence_work); if (timeout) { cb->dma = dma_fence_get(dma); mod_timer(&cb->timer, round_jiffies_up(jiffies + timeout)); -- cgit v1.2.3 From bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 19 Sep 2017 15:07:17 +0200 Subject: USB: fix out-of-bounds in usb_set_configuration Andrey Konovalov reported a possible out-of-bounds problem for a USB interface association descriptor. He writes: It seems there's no proper size check of a USB_DT_INTERFACE_ASSOCIATION descriptor. It's only checked that the size is >= 2 in usb_parse_configuration(), so find_iad() might do out-of-bounds access to intf_assoc->bInterfaceCount. And he's right, we don't check for crazy descriptors of this type very well, so resolve this problem. Yet another issue found by syzkaller... Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 14 +++++++++++--- include/uapi/linux/usb/ch9.h | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 854c8d66cfbe..68b54bd88d1e 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -643,15 +643,23 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, } else if (header->bDescriptorType == USB_DT_INTERFACE_ASSOCIATION) { + struct usb_interface_assoc_descriptor *d; + + d = (struct usb_interface_assoc_descriptor *)header; + if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { + dev_warn(ddev, + "config %d has an invalid interface association descriptor of length %d, skipping\n", + cfgno, d->bLength); + continue; + } + if (iad_num == USB_MAXIADS) { dev_warn(ddev, "found more Interface " "Association Descriptors " "than allocated for in " "configuration %d\n", cfgno); } else { - config->intf_assoc[iad_num] = - (struct usb_interface_assoc_descriptor - *)header; + config->intf_assoc[iad_num] = d; iad_num++; } diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index ce1169af39d7..2a5d63040a0b 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h @@ -780,6 +780,7 @@ struct usb_interface_assoc_descriptor { __u8 iFunction; } __attribute__ ((packed)); +#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8 /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From 20303eb4e09e196f33e1a558c2ac8bb699df0a34 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 18 Sep 2017 21:25:36 +0300 Subject: drm/i915: Replace some spaces with tabs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some comments in intel_ddi.c are indented with spaces instead of tabs. Fix that up. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170918182604.9519-2-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 31d14587ad86..797008033089 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1939,7 +1939,7 @@ static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv, val |= RCOMP_SCALAR(0x98); I915_WRITE(CNL_PORT_TX_DW2_GRP(port), val); - /* Program PORT_TX_DW4 */ + /* Program PORT_TX_DW4 */ /* We cannot write to GRP. It would overrite individual loadgen */ for (ln = 0; ln < 4; ln++) { val = I915_READ(CNL_PORT_TX_DW4_LN(port, ln)); @@ -1951,7 +1951,7 @@ static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv, I915_WRITE(CNL_PORT_TX_DW4_LN(port, ln), val); } - /* Program PORT_TX_DW5 */ + /* Program PORT_TX_DW5 */ /* All DW5 values are fixed for every table entry */ val = I915_READ(CNL_PORT_TX_DW5_LN0(port)); val &= ~RTERM_SELECT_MASK; @@ -1959,7 +1959,7 @@ static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv, val |= TAP3_DISABLE; I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val); - /* Program PORT_TX_DW7 */ + /* Program PORT_TX_DW7 */ val = I915_READ(CNL_PORT_TX_DW7_LN0(port)); val &= ~N_SCALAR_MASK; val |= N_SCALAR(ddi_translations[level].dw7_n_scalar); -- cgit v1.2.3 From ac3ad6c66998ee90ff83e70e9eb9dbe08a402ff5 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 18 Sep 2017 21:25:37 +0300 Subject: drm/i915: Shrink bxt_ddi_buf_trans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the values we put into the BXT buf_trans tables fit into 8 bits. So switch over to u8 from the u32 we use currently. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170918182604.9519-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ddi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 797008033089..5c709985904e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -301,10 +301,10 @@ static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = { }; struct bxt_ddi_buf_trans { - u32 margin; /* swing value */ - u32 scale; /* scale value */ - u32 enable; /* scale enable */ - u32 deemphasis; + u8 margin; /* swing value */ + u8 scale; /* scale value */ + u8 enable; /* scale enable */ + u8 deemphasis; bool default_index; /* true if the entry represents default value */ }; -- cgit v1.2.3 From fb5f4e96fdf9cb7ec5e6a590e1c3fdc3b6fd1e01 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 18 Sep 2017 21:25:38 +0300 Subject: drm/i915: Shrink cnl_ddi_buf_trans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the values we put into the CNL buf_trans tables fit into 8 bits. So switch over to u8 from the u32 we use currently. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170918182604.9519-4-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson Acked-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5c709985904e..93cbbcbbc193 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -354,11 +354,11 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = { }; struct cnl_ddi_buf_trans { - u32 dw2_swing_sel; - u32 dw7_n_scalar; - u32 dw4_cursor_coeff; - u32 dw4_post_cursor_2; - u32 dw4_post_cursor_1; + u8 dw2_swing_sel; + u8 dw7_n_scalar; + u8 dw4_cursor_coeff; + u8 dw4_post_cursor_2; + u8 dw4_post_cursor_1; }; /* Voltage Swing Programming for VccIO 0.85V for DP */ -- cgit v1.2.3 From 3b92e263dd4a38fa168d12a55ea4c8193483b884 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 19 Sep 2017 14:57:03 -0700 Subject: drm/i915/cnp: Display Wa #1179: WaHardHangonHotPlug "CNL PCH chance of hang when software accesses south display registers after hotplug is enabled. Workaround: Program 0xC2000 bits 11:8 = 0xF before enabling south display hotplug detection." "Workaround only needs to be applied to pre-production steppings used in graphics capable SKUs, but it is easier to apply to everything, and does not hurt." v2: Moving from clock gating to right before enabling SHOTPLUG_CTL as it should be. v3: Align with SOUTH_CHICKEN1 (DK) and consequently use proper spaces on bits definition since other bits around already use new style. And now that checkpatch is not noise anymore I also fixed the reg read mask to avoid going over 80 chars. Suggested-by: Ben Widawsky Cc: Ben Widawsky Cc: Dhinakaran Pandiyan Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170919215703.25947-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 10 +++++++++- drivers/gpu/drm/i915/i915_reg.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4d0e8f76ed1a..c23efc4394ce 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3218,7 +3218,15 @@ static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) { - u32 hotplug; + u32 val, hotplug; + + /* Display WA #1179 WaHardHangonHotPlug: cnp */ + if (HAS_PCH_CNP(dev_priv)) { + val = I915_READ(SOUTH_CHICKEN1); + val &= ~CHASSIS_CLK_REQ_DURATION_MASK; + val |= CHASSIS_CLK_REQ_DURATION(0xf); + I915_WRITE(SOUTH_CHICKEN1, val); + } /* Enable digital hotplug on the PCH */ hotplug = I915_READ(PCH_PORT_HOTPLUG); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 94b40a469afd..82f36dd0cd94 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7471,6 +7471,8 @@ enum { #define FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 2))) #define FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2))) #define FDI_BC_BIFURCATION_SELECT (1 << 12) +#define CHASSIS_CLK_REQ_DURATION_MASK (0xf << 8) +#define CHASSIS_CLK_REQ_DURATION(x) ((x) << 8) #define SPT_PWM_GRANULARITY (1<<0) #define SOUTH_CHICKEN2 _MMIO(0xc2004) #define FDI_MPHY_IOSFSB_RESET_STATUS (1<<13) -- cgit v1.2.3 From e6b20bf1b77c24465393b5b1e12781110cedc12c Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Sep 2017 16:06:32 -0700 Subject: drm/i915/cfl: Remove alpha support protection. We now have Coffee Lake on our CI systems. Coffee Lake is at this point in same stage as Kaby Lake. And it seems that we don't have any risk of bad blank screens or anything like that. So let's remove the protection. Cc: Daniel Vetter Cc: Dhinakaran Pandiyan Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: https://patchwork.freedesktop.org/patch/msgid/20170907230632.25650-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_pci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 853002fb0371..ce2c08eb9890 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -520,7 +520,6 @@ static const struct intel_device_info intel_kabylake_gt3_info __initconst = { }; #define CFL_PLATFORM \ - .is_alpha_support = 1, \ BDW_FEATURES, \ .gen = 9, \ .platform = INTEL_COFFEELAKE, \ -- cgit v1.2.3 From 17df6453d4be17910456e99c5a85025aa1b7a246 Mon Sep 17 00:00:00 2001 From: Arend Van Spriel Date: Tue, 12 Sep 2017 10:47:53 +0200 Subject: brcmfmac: add length check in brcmf_cfg80211_escan_handler() Upon handling the firmware notification for scans the length was checked properly and may result in corrupting kernel heap memory due to buffer overruns. This fix addresses CVE-2017-0786. Cc: stable@vger.kernel.org # v4.0.x Cc: Kevin Cernekee Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo --- .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index aaed4ab503ad..26a0de371c26 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -3162,6 +3162,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 status; struct brcmf_escan_result_le *escan_result_le; + u32 escan_buflen; struct brcmf_bss_info_le *bss_info_le; struct brcmf_bss_info_le *bss = NULL; u32 bi_length; @@ -3181,11 +3182,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, if (status == BRCMF_E_STATUS_PARTIAL) { brcmf_dbg(SCAN, "ESCAN Partial result\n"); + if (e->datalen < sizeof(*escan_result_le)) { + brcmf_err("invalid event data length\n"); + goto exit; + } escan_result_le = (struct brcmf_escan_result_le *) data; if (!escan_result_le) { brcmf_err("Invalid escan result (NULL pointer)\n"); goto exit; } + escan_buflen = le32_to_cpu(escan_result_le->buflen); + if (escan_buflen > BRCMF_ESCAN_BUF_SIZE || + escan_buflen > e->datalen || + escan_buflen < sizeof(*escan_result_le)) { + brcmf_err("Invalid escan buffer length: %d\n", + escan_buflen); + goto exit; + } if (le16_to_cpu(escan_result_le->bss_count) != 1) { brcmf_err("Invalid bss_count %d: ignoring\n", escan_result_le->bss_count); @@ -3202,9 +3215,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, } bi_length = le32_to_cpu(bss_info_le->length); - if (bi_length != (le32_to_cpu(escan_result_le->buflen) - - WL_ESCAN_RESULTS_FIXED_SIZE)) { - brcmf_err("Invalid bss_info length %d: ignoring\n", + if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { + brcmf_err("Ignoring invalid bss_info length: %d\n", bi_length); goto exit; } -- cgit v1.2.3 From 35f62727df0ed8e5e4857e162d94fd46d861f1cf Mon Sep 17 00:00:00 2001 From: Arend Van Spriel Date: Tue, 12 Sep 2017 10:47:54 +0200 Subject: brcmfmac: setup passive scan if requested by user-space The driver was not properly configuring firmware with regard to the type of scan. It always performed an active scan even when user-space was requesting for passive scan, ie. the scan request was done without any SSIDs specified. Cc: stable@vger.kernel.org # v4.0.x Reported-by: Huang, Jiangyang Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo --- .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 19 ++++--------------- .../wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | 5 +++++ 2 files changed, 9 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 26a0de371c26..4157c90ad973 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -980,7 +980,7 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, eth_broadcast_addr(params_le->bssid); params_le->bss_type = DOT11_BSSTYPE_ANY; - params_le->scan_type = 0; + params_le->scan_type = BRCMF_SCANTYPE_ACTIVE; params_le->channel_num = 0; params_le->nprobes = cpu_to_le32(-1); params_le->active_time = cpu_to_le32(-1); @@ -988,12 +988,9 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, params_le->home_time = cpu_to_le32(-1); memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le)); - /* if request is null exit so it will be all channel broadcast scan */ - if (!request) - return; - n_ssids = request->n_ssids; n_channels = request->n_channels; + /* Copy channel array if applicable */ brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n", n_channels); @@ -1030,16 +1027,8 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, ptr += sizeof(ssid_le); } } else { - brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids); - if ((request->ssids) && request->ssids->ssid_len) { - brcmf_dbg(SCAN, "SSID %s len=%d\n", - params_le->ssid_le.SSID, - request->ssids->ssid_len); - params_le->ssid_le.SSID_len = - cpu_to_le32(request->ssids->ssid_len); - memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid, - request->ssids->ssid_len); - } + brcmf_dbg(SCAN, "Performing passive scan\n"); + params_le->scan_type = BRCMF_SCANTYPE_PASSIVE; } /* Adding mask to channel numbers */ params_le->channel_num = diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h index 8391989b1882..e0d22fedb2b4 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -45,6 +45,11 @@ #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 +/* scan type definitions */ +#define BRCMF_SCANTYPE_DEFAULT 0xFF +#define BRCMF_SCANTYPE_ACTIVE 0 +#define BRCMF_SCANTYPE_PASSIVE 1 + #define BRCMF_WSEC_MAX_PSK_LEN 32 #define BRCMF_WSEC_PASSPHRASE BIT(0) -- cgit v1.2.3 From d81fb7fd9436e81fda67e5bc8ed0713aa28d3db2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 19 Sep 2017 18:38:13 +0300 Subject: drm/i915: always update ELD connector type after get modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_edid_to_eld() initializes the connector ELD to zero, overwriting the ELD connector type initialized in intel_audio_codec_enable(). If userspace does getconnector and thus get_modes after modeset, a subsequent audio component i915_audio_component_get_eld() call will receive an ELD without the connector type properly set. It's fine for HDMI, but screws up audio for DP. Always set the ELD connector type at intel_connector_update_modes() based on the connector type. We can drop the connector type update from intel_audio_codec_enable(). Credits to Joseph Nuzman for figuring this out. Cc: Ville Syrjälä Cc: Joseph Nuzman Reported-by: Joseph Nuzman Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101583 Reviewed-by: Ville Syrjälä Tested-by: Joseph Nuzman Cc: stable@vger.kernel.org # v4.10+, maybe earlier Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170919153813.29808-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_audio.c | 5 ----- drivers/gpu/drm/i915/intel_modes.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index d805b6e6fe71..27743be5b768 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -606,11 +606,6 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, connector->encoder->base.id, connector->encoder->name); - /* ELD Conn_Type */ - connector->eld[5] &= ~(3 << 2); - if (intel_crtc_has_dp_encoder(crtc_state)) - connector->eld[5] |= (1 << 2); - connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; if (dev_priv->display.audio_codec_enable) diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 951e834dd274..28a778b785ac 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -30,6 +30,21 @@ #include "intel_drv.h" #include "i915_drv.h" +static void intel_connector_update_eld_conn_type(struct drm_connector *connector) +{ + u8 conn_type; + + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + conn_type = DRM_ELD_CONN_TYPE_DP; + } else { + conn_type = DRM_ELD_CONN_TYPE_HDMI; + } + + connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] &= ~DRM_ELD_CONN_TYPE_MASK; + connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= conn_type; +} + /** * intel_connector_update_modes - update connector from edid * @connector: DRM connector device to use @@ -44,6 +59,8 @@ int intel_connector_update_modes(struct drm_connector *connector, ret = drm_add_edid_modes(connector, edid); drm_edid_to_eld(connector, edid); + intel_connector_update_eld_conn_type(connector); + return ret; } -- cgit v1.2.3 From 87de8d5613a7221abcce0b680b0da3c98b0871c8 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 19 Sep 2017 17:41:28 +0300 Subject: drm/i915: Stop engines before reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On kbl evidence indicates that even if the hardware happily tells us to proceed with reset, it really isn't ready. Resetting a freely running batchbuffer after we have ack for readiness, still can cause a system hang. We also have similar experiences on older gens. So now attempt to stop engines before proceeding for reset, on all gens where we have a gpu reset. This has shown to improve reset reliability and reduce the risk of losing the machine. v2: Add fixme for wa (Joonas) Testcase: igt/prime_busy/hang-* # kbl Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Ville Syrjälä Signed-off-by: Mika Kuoppala Acked-by: Chris Wilson Acked-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170919144128.25506-1-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 75 +++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 97525de2cee4..fdd7f93acb4f 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1354,33 +1354,39 @@ int i915_reg_read_ioctl(struct drm_device *dev, return ret; } -static void gen3_stop_rings(struct drm_i915_private *dev_priv) +static void gen3_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + const u32 base = engine->mmio_base; + const i915_reg_t mode = RING_MI_MODE(base); + + I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); + if (intel_wait_for_register_fw(dev_priv, + mode, + MODE_IDLE, + MODE_IDLE, + 500)) + DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", + engine->name); + + I915_WRITE_FW(RING_CTL(base), 0); + I915_WRITE_FW(RING_HEAD(base), 0); + I915_WRITE_FW(RING_TAIL(base), 0); + + /* Check acts as a post */ + if (I915_READ_FW(RING_HEAD(base)) != 0) + DRM_DEBUG_DRIVER("%s: ring head not parked\n", + engine->name); +} + +static void i915_stop_engines(struct drm_i915_private *dev_priv, + unsigned engine_mask) { struct intel_engine_cs *engine; enum intel_engine_id id; - for_each_engine(engine, dev_priv, id) { - const u32 base = engine->mmio_base; - const i915_reg_t mode = RING_MI_MODE(base); - - I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); - if (intel_wait_for_register_fw(dev_priv, - mode, - MODE_IDLE, - MODE_IDLE, - 500)) - DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", - engine->name); - - I915_WRITE_FW(RING_CTL(base), 0); - I915_WRITE_FW(RING_HEAD(base), 0); - I915_WRITE_FW(RING_TAIL(base), 0); - - /* Check acts as a post */ - if (I915_READ_FW(RING_HEAD(base)) != 0) - DRM_DEBUG_DRIVER("%s: ring head not parked\n", - engine->name); - } + for_each_engine_masked(engine, dev_priv, engine_mask, id) + gen3_stop_engine(engine); } static bool i915_reset_complete(struct pci_dev *pdev) @@ -1415,9 +1421,6 @@ static int g33_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { struct pci_dev *pdev = dev_priv->drm.pdev; - /* Stop engines before we reset; see g4x_do_reset() below for why. */ - gen3_stop_rings(dev_priv); - pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE); return wait_for(g4x_reset_complete(pdev), 500); } @@ -1432,12 +1435,6 @@ static int g4x_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE); POSTING_READ(VDECCLK_GATE_D); - /* We stop engines, otherwise we might get failed reset and a - * dead gpu (on elk). - * WaMediaResetMainRingCleanup:ctg,elk (presumably) - */ - gen3_stop_rings(dev_priv); - pci_write_config_byte(pdev, I915_GDRST, GRDOM_MEDIA | GRDOM_RESET_ENABLE); ret = wait_for(g4x_reset_complete(pdev), 500); @@ -1742,6 +1739,20 @@ int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) */ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); for (retry = 0; retry < 3; retry++) { + + /* We stop engines, otherwise we might get failed reset and a + * dead gpu (on elk). Also as modern gpu as kbl can suffer + * from system hang if batchbuffer is progressing when + * the reset is issued, regardless of READY_TO_RESET ack. + * Thus assume it is best to stop engines on all gens + * where we have a gpu reset. + * + * WaMediaResetMainRingCleanup:ctg,elk (presumably) + * + * FIXME: Wa for more modern gens needs to be validated + */ + i915_stop_engines(dev_priv, engine_mask); + ret = reset(dev_priv, engine_mask); if (ret != -ETIMEDOUT) break; -- cgit v1.2.3 From 97e133d54c1ca8948b191e5721a145a76c4db33d Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 19 Sep 2017 11:46:16 +0300 Subject: usb: gadget: core: fix ->udc_set_speed() logic Consider the following case: udc controller supports SuperSpeed. If we first load a HighSpeed gadget followed by a SuperSpeed gadget, the SuperSpeed gadget will be limited to HighSpeed as UDC core driver doesn't call ->udc_set_speed() in the second case. Call ->udc_set_speed() unconditionally to fix this issue. This will also fix the case for dwc3 controller driver when SuperSpeed gadget is loaded first and works in HighSpeed only as udc_set_speed() was never being called. Fixes: 6099eca796ae ("usb: gadget: core: introduce ->udc_set_speed() method") Cc: [v4.13+] Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 75c51ca4ee0f..d41d07aae0ce 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1320,8 +1320,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri udc->dev.driver = &driver->driver; udc->gadget->dev.driver = &driver->driver; - if (driver->max_speed < udc->gadget->max_speed) - usb_gadget_udc_set_speed(udc, driver->max_speed); + usb_gadget_udc_set_speed(udc, driver->max_speed); ret = driver->bind(udc->gadget, driver); if (ret) -- cgit v1.2.3 From 9ada8c582088d32bd5c071c17213bc6edf37443a Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 13 Sep 2017 15:31:33 +0900 Subject: usb: gadget: function: printer: avoid spinlock recursion If usb_gadget_giveback_request() is called in usb_ep_queue(), this printer_write() is possible to cause spinlock recursion. So, this patch adds spin_unlock() before calls usb_ep_queue() to avoid it. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_printer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 8df244fc9d80..ea0da35a44e2 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -555,6 +555,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) size_t size; /* Amount of data in a TX request. */ size_t bytes_copied = 0; struct usb_request *req; + int value; DBG(dev, "printer_write trying to send %d bytes\n", (int)len); @@ -634,7 +635,11 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) return -EAGAIN; } - if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { + /* here, we unlock, and only unlock, to avoid deadlock. */ + spin_unlock(&dev->lock); + value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); + spin_lock(&dev->lock); + if (value) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); -- cgit v1.2.3 From 641663a19f6002ecc5c5af517a5184d4164cc749 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 11 Sep 2017 09:24:15 -0700 Subject: usb: gadget: udc: fix snps_udc_plat.c build errors Fix build errors that happen when CONFIG_EXTCON=m and CONFIG_USB_SNP_UDC_PLAT=y by preventing that combination in Kconfig. CONFIG_EXTCON can still be disabled or enabled for this driver since has stubs for the disabled case, but if CONFIG_EXTCON=m, USB_SNP_UDC_PLAT is restricted to m or n (cannot be builtin). drivers/built-in.o: In function `udc_plat_remove': snps_udc_plat.c:(.text+0x2c4060): undefined reference to `extcon_unregister_notifier' drivers/built-in.o: In function `udc_plat_probe': snps_udc_plat.c:(.text+0x2c438c): undefined reference to `extcon_get_edev_by_phandle' snps_udc_plat.c:(.text+0x2c43f2): undefined reference to `extcon_register_notifier' snps_udc_plat.c:(.text+0x2c4416): undefined reference to `extcon_get_state' snps_udc_plat.c:(.text+0x2c44f7): undefined reference to `extcon_unregister_notifier' Reported-by: kbuild test robot Signed-off-by: Randy Dunlap Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 7cd5c969fcbe..1e9567091d86 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -273,6 +273,7 @@ config USB_SNP_CORE config USB_SNP_UDC_PLAT tristate "Synopsys USB 2.0 Device controller" depends on USB_GADGET && OF && HAS_DMA + depends on EXTCON || EXTCON=n select USB_GADGET_DUALSPEED select USB_SNP_CORE default ARCH_BCM_IPROC -- cgit v1.2.3 From 7661ca09b2ff98f48693f431bb01fed62830e433 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 7 Sep 2017 16:14:31 +0200 Subject: usb: gadget: dummy: fix nonsensical comparisons gcc-8 points out two comparisons that are clearly bogus and almost certainly not what the author intended to write: drivers/usb/gadget/udc/dummy_hcd.c: In function 'set_link_state_by_speed': drivers/usb/gadget/udc/dummy_hcd.c:379:31: error: bitwise comparison always evaluates to false [-Werror=tautological-compare] USB_PORT_STAT_ENABLE) == 1 && ^~ drivers/usb/gadget/udc/dummy_hcd.c:381:25: error: bitwise comparison always evaluates to false [-Werror=tautological-compare] USB_SS_PORT_LS_U0) == 1 && ^~ I looked at the code for a bit and came up with a change that makes it look like what the author probably meant here. This makes it look reasonable to me and to gcc, shutting up the warning. It does of course change behavior as the two conditions are actually evaluated rather than being hardcoded to false, and I have made no attempt at verifying that the changed logic makes sense in the context of a USB HCD, so that part needs to be reviewed carefully. Fixes: 1cd8fd2887e1 ("usb: gadget: dummy_hcd: add SuperSpeed support") Cc: Tatyana Brokhman Cc: Felipe Balbi Acked-by: Alan Stern Signed-off-by: Arnd Bergmann Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index a030d7923d7d..b1e21b3be6e1 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -375,11 +375,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) USB_PORT_STAT_CONNECTION) == 0) dum_hcd->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); - if ((dum_hcd->port_status & - USB_PORT_STAT_ENABLE) == 1 && - (dum_hcd->port_status & - USB_SS_PORT_LS_U0) == 1 && - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) && + (dum_hcd->port_status & + USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) dum_hcd->active = 1; } } else { -- cgit v1.2.3 From 20da2ec06bfad2d4dfd40d77d3831f5e56365d20 Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Mon, 18 Sep 2017 15:29:49 +0300 Subject: qtnfmac: lock access to h/w in tx path Fix tx path regression. Lock should be held when queuing packets to h/w fifos in order to properly handle configurations with multiple enabled interfaces. Signed-off-by: Sergey Matyukevich Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c | 9 ++++++++- drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c index 502e72b7cdcc..69131965a298 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c @@ -661,14 +661,18 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); dma_addr_t txbd_paddr, skb_paddr; struct qtnf_tx_bd *txbd; + unsigned long flags; int len, i; u32 info; int ret = 0; + spin_lock_irqsave(&priv->tx0_lock, flags); + if (!qtnf_tx_queue_ready(priv)) { if (skb->dev) netif_stop_queue(skb->dev); + spin_unlock_irqrestore(&priv->tx0_lock, flags); return NETDEV_TX_BUSY; } @@ -717,8 +721,10 @@ tx_done: dev_kfree_skb_any(skb); } - qtnf_pcie_data_tx_reclaim(priv); priv->tx_done_count++; + spin_unlock_irqrestore(&priv->tx0_lock, flags); + + qtnf_pcie_data_tx_reclaim(priv); return NETDEV_TX_OK; } @@ -1247,6 +1253,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) strcpy(bus->fwname, QTN_PCI_PEARL_FW_NAME); init_completion(&bus->request_firmware_complete); mutex_init(&bus->bus_lock); + spin_lock_init(&pcie_priv->tx0_lock); spin_lock_init(&pcie_priv->irq_lock); spin_lock_init(&pcie_priv->tx_reclaim_lock); diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h index e76a23716ee0..86ac1ccedb52 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h @@ -34,6 +34,8 @@ struct qtnf_pcie_bus_priv { /* lock for tx reclaim operations */ spinlock_t tx_reclaim_lock; + /* lock for tx0 operations */ + spinlock_t tx0_lock; u8 msi_enabled; int mps; -- cgit v1.2.3 From a715b3a0efe76d36c3ef96a93894a13db9d3a72f Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Mon, 18 Sep 2017 15:29:50 +0300 Subject: qtnfmac: cancel scans on wireless interface changes Cancel active scans and deactivate firmware scan watchdog timer when wireless interface configuration is changed. The usecases include wireless interface mode change, interface down, AP stop, virtual interface removal. Signed-off-by: Sergey Matyukevich Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 9 ++++++--- drivers/net/wireless/quantenna/qtnfmac/cfg80211.h | 3 +++ drivers/net/wireless/quantenna/qtnfmac/event.c | 2 -- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index 856fa6e8327e..a450bc6bc774 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -115,6 +115,8 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) vif = qtnf_netdev_get_priv(wdev->netdev); + qtnf_scan_done(vif->mac, true); + if (qtnf_cmd_send_del_intf(vif)) pr_err("VIF%u.%u: failed to delete VIF\n", vif->mac->macid, vif->vifid); @@ -335,6 +337,8 @@ static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev) struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); int ret; + qtnf_scan_done(vif->mac, true); + ret = qtnf_cmd_send_stop_ap(vif); if (ret) { pr_err("VIF%u.%u: failed to stop AP operation in FW\n", @@ -570,8 +574,6 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device *dev, !qtnf_sta_list_lookup(&vif->sta_list, params->mac)) return 0; - qtnf_scan_done(vif->mac, true); - ret = qtnf_cmd_send_del_sta(vif, params); if (ret) pr_err("VIF%u.%u: failed to delete STA %pM\n", @@ -1134,8 +1136,9 @@ void qtnf_virtual_intf_cleanup(struct net_device *ndev) } vif->sta_state = QTNF_STA_DISCONNECTED; - qtnf_scan_done(mac, true); } + + qtnf_scan_done(mac, true); } void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif) diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h index 6a4af52522b8..66db26613b1f 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.h @@ -34,6 +34,9 @@ static inline void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted) .aborted = aborted, }; + if (timer_pending(&mac->scan_timeout)) + del_timer_sync(&mac->scan_timeout); + mutex_lock(&mac->mac_lock); if (mac->scan_req) { diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c index 0fc2814eafad..43d2e7fd6e02 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -345,8 +345,6 @@ qtnf_event_handle_scan_complete(struct qtnf_wmac *mac, return -EINVAL; } - if (timer_pending(&mac->scan_timeout)) - del_timer_sync(&mac->scan_timeout); qtnf_scan_done(mac, le32_to_cpu(status->flags) & QLINK_SCAN_ABORTED); return 0; -- cgit v1.2.3 From 76a4b41d654c0eaaf3b4ebc65fc0728d205f028a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 20 Sep 2017 18:12:36 +0300 Subject: drm/i915: Drop useless HAS_PSR() check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is safe to call intel_psr_disable() on a platform without PSR. We don't have such a check when calling intel_psr_enable() either. v2: Don't drop the HAS_DDI check quite yet (Rodrigo) Reviewed-by: Rodrigo Vivi Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170920151236.5864-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8db6b11f103f..e536f5942d7f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2697,7 +2697,7 @@ static void intel_disable_dp(struct intel_encoder *encoder, if (old_crtc_state->has_audio) intel_audio_codec_disable(encoder); - if (HAS_PSR(dev_priv) && !HAS_DDI(dev_priv)) + if (!HAS_DDI(dev_priv)) intel_psr_disable(intel_dp, old_crtc_state); /* Make sure the panel is off before trying to change the mode. But also -- cgit v1.2.3 From 1a8ff6076e8f3e197831455e4bba8fa2f5f1d0f1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 20 Sep 2017 18:12:51 +0300 Subject: drm/i915: Reorganize .disable hooks for pre-DDI DP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of our DP encoder hooks are split into per-platform variants. .disable() an exception, and thus it's a bit messy. Let's split it up as well. We'll leave the common parts in a helper called by each platform specific hook. Now each platform has mostly its own hooks. Some hooks are still shared between vlv and chv, and between g4x and ilk. None of the remaining shared hooks have any platform checks in them however so duplicating them doesn't seem particularly useful. There is a subtle change on VLV/CHV where we now disable PSR before audio, whereas before we disabled PSR after audio. That should be totally fine, and PSR is disabled by default anyway. Jani also pointed out to me that PSR + audio doesn't seem like a particularly realistic combination. v2: Drop the PSR HAS_DDI check here (Rodrigo) Pimp up the commit message a bit based on a chat with Jani Cc: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170920151251.5961-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 45 ++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e536f5942d7f..1e0bfbe6b4f3 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2692,24 +2692,46 @@ static void intel_disable_dp(struct intel_encoder *encoder, const struct drm_connector_state *old_conn_state) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); if (old_crtc_state->has_audio) intel_audio_codec_disable(encoder); - if (!HAS_DDI(dev_priv)) - intel_psr_disable(intel_dp, old_crtc_state); - /* Make sure the panel is off before trying to change the mode. But also * ensure that we have vdd while we switch off the panel. */ intel_edp_panel_vdd_on(intel_dp); intel_edp_backlight_off(old_conn_state); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_edp_panel_off(intel_dp); +} + +static void g4x_disable_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + + intel_disable_dp(encoder, old_crtc_state, old_conn_state); /* disable the port before the pipe on g4x */ - if (INTEL_GEN(dev_priv) < 5) - intel_dp_link_down(intel_dp); + intel_dp_link_down(intel_dp); +} + +static void ilk_disable_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + intel_disable_dp(encoder, old_crtc_state, old_conn_state); +} + +static void vlv_disable_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + + intel_psr_disable(intel_dp, old_crtc_state); + + intel_disable_dp(encoder, old_crtc_state, old_conn_state); } static void ilk_post_disable_dp(struct intel_encoder *encoder, @@ -6145,7 +6167,6 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, goto err_encoder_init; intel_encoder->compute_config = intel_dp_compute_config; - intel_encoder->disable = intel_disable_dp; intel_encoder->get_hw_state = intel_dp_get_hw_state; intel_encoder->get_config = intel_dp_get_config; intel_encoder->suspend = intel_dp_encoder_suspend; @@ -6153,18 +6174,24 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; intel_encoder->pre_enable = chv_pre_enable_dp; intel_encoder->enable = vlv_enable_dp; + intel_encoder->disable = vlv_disable_dp; intel_encoder->post_disable = chv_post_disable_dp; intel_encoder->post_pll_disable = chv_dp_post_pll_disable; } else if (IS_VALLEYVIEW(dev_priv)) { intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable; intel_encoder->pre_enable = vlv_pre_enable_dp; intel_encoder->enable = vlv_enable_dp; + intel_encoder->disable = vlv_disable_dp; intel_encoder->post_disable = vlv_post_disable_dp; + } else if (INTEL_GEN(dev_priv) >= 5) { + intel_encoder->pre_enable = g4x_pre_enable_dp; + intel_encoder->enable = g4x_enable_dp; + intel_encoder->disable = ilk_disable_dp; + intel_encoder->post_disable = ilk_post_disable_dp; } else { intel_encoder->pre_enable = g4x_pre_enable_dp; intel_encoder->enable = g4x_enable_dp; - if (INTEL_GEN(dev_priv) >= 5) - intel_encoder->post_disable = ilk_post_disable_dp; + intel_encoder->disable = g4x_disable_dp; } intel_dig_port->port = port; -- cgit v1.2.3 From 4babc5e27cfda59e2e257d28628b8d853aea5206 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 14 Sep 2017 17:21:54 +0100 Subject: drm/i915: remove redundant variable hw_check hw_check is being assigned and updated but is no longer being read, hence it is redundant and can be removed. Detected by clang scan-build: "warning: Value stored to 'hw_check' during its initialization is never read" Fixes: f6d1973db2d2 ("drm/i915: Move modeset state verifier calls") Signed-off-by: Colin Ian King Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20170914162154.11304-1-colin.king@canonical.com --- drivers/gpu/drm/i915/intel_display.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3bfcf187a0a1..2e407dc49c19 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12367,7 +12367,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) struct drm_crtc_state *old_crtc_state, *new_crtc_state; struct drm_crtc *crtc; struct intel_crtc_state *intel_cstate; - bool hw_check = intel_state->modeset; u64 put_domains[I915_MAX_PIPES] = {}; unsigned crtc_vblank_mask = 0; int i; @@ -12384,7 +12383,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) if (needs_modeset(new_crtc_state) || to_intel_crtc_state(new_crtc_state)->update_pipe) { - hw_check = true; put_domains[to_intel_crtc(crtc)->pipe] = modeset_get_crtc_power_domains(crtc, -- cgit v1.2.3 From b8935a7c4b4f2c487c639eb9071b4e8f0cbeac4a Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 20 Sep 2017 18:10:13 -0400 Subject: drm/amdkfd: Reorganize kfd resume code The idea is to let kfd init and resume function share the same code path as much as possible, rather than to have two copies of almost identical code. That way improves the code readability and maintainability. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 78 +++++++++++++++++---------------- 1 file changed, 40 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 5df12b287201..e5d1387c34ae 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -92,6 +92,8 @@ static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, unsigned int chunk_size); static void kfd_gtt_sa_fini(struct kfd_dev *kfd); +static int kfd_resume(struct kfd_dev *kfd); + static const struct kfd_device_info *lookup_device_info(unsigned short did) { size_t i; @@ -169,15 +171,8 @@ static bool device_iommu_pasid_init(struct kfd_dev *kfd) (unsigned int)(1 << kfd->device_info->max_pasid_bits), iommu_info.max_pasids); - err = amd_iommu_init_device(kfd->pdev, pasid_limit); - if (err < 0) { - dev_err(kfd_device, "error initializing iommu device\n"); - return false; - } - if (!kfd_set_pasid_limit(pasid_limit)) { dev_err(kfd_device, "error setting pasid limit\n"); - amd_iommu_free_device(kfd->pdev); return false; } @@ -273,29 +268,22 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_interrupt_error; } - if (!device_iommu_pasid_init(kfd)) { - dev_err(kfd_device, - "Error initializing iommuv2 for device %x:%x\n", - kfd->pdev->vendor, kfd->pdev->device); - goto device_iommu_pasid_error; - } - amd_iommu_set_invalidate_ctx_cb(kfd->pdev, - iommu_pasid_shutdown_callback); - amd_iommu_set_invalid_ppr_cb(kfd->pdev, iommu_invalid_ppr_cb); - kfd->dqm = device_queue_manager_init(kfd); if (!kfd->dqm) { dev_err(kfd_device, "Error initializing queue manager\n"); goto device_queue_manager_error; } - if (kfd->dqm->ops.start(kfd->dqm)) { + if (!device_iommu_pasid_init(kfd)) { dev_err(kfd_device, - "Error starting queue manager for device %x:%x\n", + "Error initializing iommuv2 for device %x:%x\n", kfd->pdev->vendor, kfd->pdev->device); - goto dqm_start_error; + goto device_iommu_pasid_error; } + if (kfd_resume(kfd)) + goto kfd_resume_error; + kfd->dbgmgr = NULL; kfd->init_complete = true; @@ -307,11 +295,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto out; -dqm_start_error: +kfd_resume_error: +device_iommu_pasid_error: device_queue_manager_uninit(kfd->dqm); device_queue_manager_error: - amd_iommu_free_device(kfd->pdev); -device_iommu_pasid_error: kfd_interrupt_exit(kfd); kfd_interrupt_error: kfd_topology_remove_device(kfd); @@ -331,8 +318,8 @@ out: void kgd2kfd_device_exit(struct kfd_dev *kfd) { if (kfd->init_complete) { + kgd2kfd_suspend(kfd); device_queue_manager_uninit(kfd->dqm); - amd_iommu_free_device(kfd->pdev); kfd_interrupt_exit(kfd); kfd_topology_remove_device(kfd); kfd_doorbell_fini(kfd); @@ -355,25 +342,40 @@ void kgd2kfd_suspend(struct kfd_dev *kfd) int kgd2kfd_resume(struct kfd_dev *kfd) { - unsigned int pasid_limit; - int err; + if (!kfd->init_complete) + return 0; - pasid_limit = kfd_get_pasid_limit(); + return kfd_resume(kfd); - if (kfd->init_complete) { - err = amd_iommu_init_device(kfd->pdev, pasid_limit); - if (err < 0) { - dev_err(kfd_device, "failed to initialize iommu\n"); - return -ENXIO; - } +} - amd_iommu_set_invalidate_ctx_cb(kfd->pdev, - iommu_pasid_shutdown_callback); - amd_iommu_set_invalid_ppr_cb(kfd->pdev, iommu_invalid_ppr_cb); - kfd->dqm->ops.start(kfd->dqm); +static int kfd_resume(struct kfd_dev *kfd) +{ + int err = 0; + unsigned int pasid_limit = kfd_get_pasid_limit(); + + err = amd_iommu_init_device(kfd->pdev, pasid_limit); + if (err) + return -ENXIO; + amd_iommu_set_invalidate_ctx_cb(kfd->pdev, + iommu_pasid_shutdown_callback); + amd_iommu_set_invalid_ppr_cb(kfd->pdev, + iommu_invalid_ppr_cb); + + err = kfd->dqm->ops.start(kfd->dqm); + if (err) { + dev_err(kfd_device, + "Error starting queue manager for device %x:%x\n", + kfd->pdev->vendor, kfd->pdev->device); + goto dqm_start_error; } - return 0; + return err; + +dqm_start_error: + amd_iommu_free_device(kfd->pdev); + + return err; } /* This is called directly from KGD at ISR. */ -- cgit v1.2.3 From 733fa1f7428c362b17b3de3a1c691e21fa803239 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 20 Sep 2017 18:10:14 -0400 Subject: drm/amdkfd: Fix suspend/resume issue on Carrizo v2 When we do suspend/resume through "sudo pm-suspend" while there is HSA activity running, upon resume we will encounter HWS hanging, which is caused by memory read/write failures. The root cause is that when suspend, we neglected to unbind pasid from kfd device. Another major change is that the bind/unbinding is changed to be performed on a per process basis, instead of whether there are queues in dqm. v2: - free IOMMU device if kfd_bind_processes_to_device fails in kfd_resume - add comments to kfd_bind/unbind_processes_to/from_device - minor cleanups Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 23 +++-- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 13 --- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 15 +++- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 97 ++++++++++++++++++---- 4 files changed, 109 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index e5d1387c34ae..80c90f3619b7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -184,7 +184,7 @@ static void iommu_pasid_shutdown_callback(struct pci_dev *pdev, int pasid) struct kfd_dev *dev = kfd_device_by_pci_dev(pdev); if (dev) - kfd_unbind_process_from_device(dev, pasid); + kfd_process_iommu_unbind_callback(dev, pasid); } /* @@ -332,12 +332,16 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) void kgd2kfd_suspend(struct kfd_dev *kfd) { - if (kfd->init_complete) { - kfd->dqm->ops.stop(kfd->dqm); - amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL); - amd_iommu_set_invalid_ppr_cb(kfd->pdev, NULL); - amd_iommu_free_device(kfd->pdev); - } + if (!kfd->init_complete) + return; + + kfd->dqm->ops.stop(kfd->dqm); + + kfd_unbind_processes_from_device(kfd); + + amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL); + amd_iommu_set_invalid_ppr_cb(kfd->pdev, NULL); + amd_iommu_free_device(kfd->pdev); } int kgd2kfd_resume(struct kfd_dev *kfd) @@ -362,6 +366,10 @@ static int kfd_resume(struct kfd_dev *kfd) amd_iommu_set_invalid_ppr_cb(kfd->pdev, iommu_invalid_ppr_cb); + err = kfd_bind_processes_to_device(kfd); + if (err) + goto processes_bind_error; + err = kfd->dqm->ops.start(kfd->dqm); if (err) { dev_err(kfd_device, @@ -373,6 +381,7 @@ static int kfd_resume(struct kfd_dev *kfd) return err; dqm_start_error: +processes_bind_error: amd_iommu_free_device(kfd->pdev); return err; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 53a66e821624..5db82b877deb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -670,7 +670,6 @@ static int initialize_cpsch(struct device_queue_manager *dqm) static int start_cpsch(struct device_queue_manager *dqm) { - struct device_process_node *node; int retval; retval = 0; @@ -697,11 +696,6 @@ static int start_cpsch(struct device_queue_manager *dqm) init_interrupts(dqm); - list_for_each_entry(node, &dqm->queues, list) - if (node->qpd->pqm->process && dqm->dev) - kfd_bind_process_to_device(dqm->dev, - node->qpd->pqm->process); - execute_queues_cpsch(dqm, true); return 0; @@ -714,15 +708,8 @@ fail_packet_manager_init: static int stop_cpsch(struct device_queue_manager *dqm) { - struct device_process_node *node; - struct kfd_process_device *pdd; - destroy_queues_cpsch(dqm, true, true); - list_for_each_entry(node, &dqm->queues, list) { - pdd = qpd_to_pdd(node->qpd); - pdd->bound = false; - } kfd_gtt_sa_free(dqm->dev, dqm->fence_mem); pm_uninit(&dqm->packets); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 634083e340d1..c71160422348 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -432,6 +432,13 @@ struct qcm_process_device { uint32_t sh_hidden_private_base; }; + +enum kfd_pdd_bound { + PDD_UNBOUND = 0, + PDD_BOUND, + PDD_BOUND_SUSPENDED, +}; + /* Data that is per-process-per device. */ struct kfd_process_device { /* @@ -456,7 +463,7 @@ struct kfd_process_device { uint64_t scratch_limit; /* Is this process/pasid bound to this device? (amd_iommu_bind_pasid) */ - bool bound; + enum kfd_pdd_bound bound; /* This flag tells if we should reset all * wavefronts on process termination @@ -547,8 +554,10 @@ struct kfd_process *kfd_get_process(const struct task_struct *); struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid); struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, - struct kfd_process *p); -void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid); + struct kfd_process *p); +int kfd_bind_processes_to_device(struct kfd_dev *dev); +void kfd_unbind_processes_from_device(struct kfd_dev *dev); +void kfd_process_iommu_unbind_callback(struct kfd_dev *dev, unsigned int pasid); struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, struct kfd_process *p); struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 9e65ce3c1967..1325f88591ae 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -174,9 +174,10 @@ static void kfd_process_wq_release(struct work_struct *work) if (pdd->reset_wavefronts) dbgdev_wave_reset_wavefronts(pdd->dev, p); - amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); - list_del(&pdd->per_device_list); + if (pdd->bound == PDD_BOUND) + amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); + list_del(&pdd->per_device_list); kfree(pdd); } @@ -351,9 +352,9 @@ struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, list_for_each_entry(pdd, &p->per_device_data, per_device_list) if (pdd->dev == dev) - break; + return pdd; - return pdd; + return NULL; } struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, @@ -368,6 +369,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, INIT_LIST_HEAD(&pdd->qpd.priv_queue_list); pdd->qpd.dqm = dev->dqm; pdd->reset_wavefronts = false; + pdd->bound = PDD_UNBOUND; list_add(&pdd->per_device_list, &p->per_device_data); } @@ -393,19 +395,91 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, return ERR_PTR(-ENOMEM); } - if (pdd->bound) + if (pdd->bound == PDD_BOUND) { return pdd; + } else if (unlikely(pdd->bound == PDD_BOUND_SUSPENDED)) { + pr_err("Binding PDD_BOUND_SUSPENDED pdd is unexpected!\n"); + return ERR_PTR(-EINVAL); + } err = amd_iommu_bind_pasid(dev->pdev, p->pasid, p->lead_thread); if (err < 0) return ERR_PTR(err); - pdd->bound = true; + pdd->bound = PDD_BOUND; return pdd; } -void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) +/* + * Bind processes do the device that have been temporarily unbound + * (PDD_BOUND_SUSPENDED) in kfd_unbind_processes_from_device. + */ +int kfd_bind_processes_to_device(struct kfd_dev *dev) +{ + struct kfd_process_device *pdd; + struct kfd_process *p; + unsigned int temp; + int err = 0; + + int idx = srcu_read_lock(&kfd_processes_srcu); + + hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) { + mutex_lock(&p->mutex); + pdd = kfd_get_process_device_data(dev, p); + if (pdd->bound != PDD_BOUND_SUSPENDED) { + mutex_unlock(&p->mutex); + continue; + } + + err = amd_iommu_bind_pasid(dev->pdev, p->pasid, + p->lead_thread); + if (err < 0) { + pr_err("unexpected pasid %d binding failure\n", + p->pasid); + mutex_unlock(&p->mutex); + break; + } + + pdd->bound = PDD_BOUND; + mutex_unlock(&p->mutex); + } + + srcu_read_unlock(&kfd_processes_srcu, idx); + + return err; +} + +/* + * Temporarily unbind currently bound processes from the device and + * mark them as PDD_BOUND_SUSPENDED. These processes will be restored + * to PDD_BOUND state in kfd_bind_processes_to_device. + */ +void kfd_unbind_processes_from_device(struct kfd_dev *dev) +{ + struct kfd_process_device *pdd; + struct kfd_process *p; + unsigned int temp, temp_bound, temp_pasid; + + int idx = srcu_read_lock(&kfd_processes_srcu); + + hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) { + mutex_lock(&p->mutex); + pdd = kfd_get_process_device_data(dev, p); + temp_bound = pdd->bound; + temp_pasid = p->pasid; + if (pdd->bound == PDD_BOUND) + pdd->bound = PDD_BOUND_SUSPENDED; + mutex_unlock(&p->mutex); + + if (temp_bound == PDD_BOUND) + amd_iommu_unbind_pasid(dev->pdev, temp_pasid); + } + + srcu_read_unlock(&kfd_processes_srcu, idx); +} + +void kfd_process_iommu_unbind_callback(struct kfd_dev *dev, unsigned int pasid) { struct kfd_process *p; struct kfd_process_device *pdd; @@ -438,15 +512,6 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) pdd->reset_wavefronts = false; } - /* - * Just mark pdd as unbound, because we still need it - * to call amd_iommu_unbind_pasid() in when the - * process exits. - * We don't call amd_iommu_unbind_pasid() here - * because the IOMMU called us. - */ - pdd->bound = false; - mutex_unlock(&p->mutex); } -- cgit v1.2.3 From 8c72c3d7dfa86f7e84c5397975eb9c803e4de7b6 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 20 Sep 2017 18:10:15 -0400 Subject: drm/amdkfd: Rectify the jiffies calculation error with milliseconds v2 The timeout in milliseconds should not be regarded as jiffies. This commit fixed that. v2: - use msecs_to_jiffies - change timeout_ms parameter to unsigned int to match msecs_to_jiffies Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 6 +++--- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 5db82b877deb..87961fe669e1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -835,12 +835,12 @@ out: int amdkfd_fence_wait_timeout(unsigned int *fence_addr, unsigned int fence_value, - unsigned long timeout) + unsigned int timeout_ms) { - timeout += jiffies; + unsigned long end_jiffies = msecs_to_jiffies(timeout_ms) + jiffies; while (*fence_addr != fence_value) { - if (time_after(jiffies, timeout)) { + if (time_after(jiffies, end_jiffies)) { pr_err("qcm fence wait loop timeout expired\n"); return -ETIME; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index c71160422348..f37fbfd0e917 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -672,7 +672,7 @@ struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm, int amdkfd_fence_wait_timeout(unsigned int *fence_addr, unsigned int fence_value, - unsigned long timeout); + unsigned int timeout_ms); /* Packet Manager */ -- cgit v1.2.3 From b90e3fbecc9030efb8a6aed1d54a79d0c3d0820a Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 20 Sep 2017 18:10:16 -0400 Subject: drm/amdkfd: Adjust dequeue latencies and timeouts Adjust latencies and timeouts for dequeueing with HWS and consolidate them in one place. Make them longer to allow long running waves to complete without causing a timeout. The timeout is twice as long as the latency plus some buffer to make sure we don't detect a timeout prematurely. Change timeouts for dequeueing HQDs without HWS. KFD_UNMAP_LATENCY is more consistent with what the HWS does for user queues. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 4 +++- drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 3 --- 5 files changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 87961fe669e1..dd60c6eec962 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -323,7 +323,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm, retval = mqd->destroy_mqd(mqd, q->mqd, KFD_PREEMPT_TYPE_WAVEFRONT_RESET, - QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS, + KFD_UNMAP_LATENCY_MS, q->pipe, q->queue); if (retval) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index faf820a06400..99e23053f59d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -29,7 +29,9 @@ #include "kfd_priv.h" #include "kfd_mqd_manager.h" -#define QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS (500) +#define KFD_UNMAP_LATENCY_MS (4000) +#define QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS (2 * KFD_UNMAP_LATENCY_MS + 1000) + #define CIK_VMID_NUM (8) #define KFD_VMID_START_OFFSET (8) #define VMID_PER_DEVICE CIK_VMID_NUM diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index ed71ad40e8f7..d53d32a91a16 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -185,7 +185,7 @@ static void uninitialize(struct kernel_queue *kq) kq->mqd->destroy_mqd(kq->mqd, kq->queue->mqd, KFD_PREEMPT_TYPE_WAVEFRONT_RESET, - QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS, + KFD_UNMAP_LATENCY_MS, kq->queue->pipe, kq->queue->queue); else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c index 1d312603de9f..9eda884d8d48 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c @@ -376,7 +376,7 @@ int pm_send_set_resources(struct packet_manager *pm, packet->bitfields2.queue_type = queue_type__mes_set_resources__hsa_interface_queue_hiq; packet->bitfields2.vmid_mask = res->vmid_mask; - packet->bitfields2.unmap_latency = KFD_UNMAP_LATENCY; + packet->bitfields2.unmap_latency = KFD_UNMAP_LATENCY_MS / 100; packet->bitfields7.oac_mask = res->oac_mask; packet->bitfields8.gds_heap_base = res->gds_heap_base; packet->bitfields8.gds_heap_size = res->gds_heap_size; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f37fbfd0e917..8883416634d3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -676,11 +676,8 @@ int amdkfd_fence_wait_timeout(unsigned int *fence_addr, /* Packet Manager */ -#define KFD_HIQ_TIMEOUT (500) - #define KFD_FENCE_COMPLETED (100) #define KFD_FENCE_INIT (10) -#define KFD_UNMAP_LATENCY (150) struct packet_manager { struct device_queue_manager *dqm; -- cgit v1.2.3 From 44008d7a871ce5a487cbcc4c412a5149145ea442 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 20 Sep 2017 18:10:18 -0400 Subject: drm/amdkfd: Use VMID bitmap from KGD v2 The hard-coded values related to VMID were removed in KFD, as those values can be calculated in the KFD initialization function. v2: remove unnecessary local variable Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c | 9 ++------- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 5 +++++ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 13 ++++++------- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 4 ---- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 7 +++++++ drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 2 +- 6 files changed, 21 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c index 0aa021aa0aa1..7d5635fdd6e7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -769,13 +769,8 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p) union GRBM_GFX_INDEX_BITS reg_gfx_index; struct kfd_process_device *pdd; struct dbg_wave_control_info wac_info; - int temp; - int first_vmid_to_scan = 8; - int last_vmid_to_scan = 15; - - first_vmid_to_scan = ffs(dev->shared_resources.compute_vmid_bitmap) - 1; - temp = dev->shared_resources.compute_vmid_bitmap >> first_vmid_to_scan; - last_vmid_to_scan = first_vmid_to_scan + ffz(temp); + int first_vmid_to_scan = dev->vm_info.first_vmid_kfd; + int last_vmid_to_scan = dev->vm_info.last_vmid_kfd; reg_sq_cmd.u32All = 0; status = 0; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 80c90f3619b7..46049f005b02 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -219,6 +219,11 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, kfd->shared_resources = *gpu_resources; + kfd->vm_info.first_vmid_kfd = ffs(gpu_resources->compute_vmid_bitmap)-1; + kfd->vm_info.last_vmid_kfd = fls(gpu_resources->compute_vmid_bitmap)-1; + kfd->vm_info.vmid_num_kfd = kfd->vm_info.last_vmid_kfd + - kfd->vm_info.first_vmid_kfd + 1; + /* calculate max size of mqds needed for queues */ size = max_num_of_queues_per_device * kfd->device_info->mqd_size_aligned; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index dd60c6eec962..87f8742dcd8c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -113,11 +113,11 @@ static int allocate_vmid(struct device_queue_manager *dqm, if (dqm->vmid_bitmap == 0) return -ENOMEM; - bit = find_first_bit((unsigned long *)&dqm->vmid_bitmap, CIK_VMID_NUM); + bit = find_first_bit((unsigned long *)&dqm->vmid_bitmap, + dqm->dev->vm_info.vmid_num_kfd); clear_bit(bit, (unsigned long *)&dqm->vmid_bitmap); - /* Kaveri kfd vmid's starts from vmid 8 */ - allocated_vmid = bit + KFD_VMID_START_OFFSET; + allocated_vmid = bit + dqm->dev->vm_info.first_vmid_kfd; pr_debug("vmid allocation %d\n", allocated_vmid); qpd->vmid = allocated_vmid; q->properties.vmid = allocated_vmid; @@ -132,7 +132,7 @@ static void deallocate_vmid(struct device_queue_manager *dqm, struct qcm_process_device *qpd, struct queue *q) { - int bit = qpd->vmid - KFD_VMID_START_OFFSET; + int bit = qpd->vmid - dqm->dev->vm_info.first_vmid_kfd; /* Release the vmid mapping */ set_pasid_vmid_mapping(dqm, 0, qpd->vmid); @@ -507,7 +507,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm) dqm->allocated_queues[pipe] |= 1 << queue; } - dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1; + dqm->vmid_bitmap = (1 << dqm->dev->vm_info.vmid_num_kfd) - 1; dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1; return 0; @@ -613,8 +613,7 @@ static int set_sched_resources(struct device_queue_manager *dqm) int i, mec; struct scheduling_resources res; - res.vmid_mask = (1 << VMID_PER_DEVICE) - 1; - res.vmid_mask <<= KFD_VMID_START_OFFSET; + res.vmid_mask = dqm->dev->shared_resources.compute_vmid_bitmap; res.queue_mask = 0; for (i = 0; i < KGD_MAX_QUEUES; ++i) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 99e23053f59d..60d46ce0b8a7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -32,10 +32,6 @@ #define KFD_UNMAP_LATENCY_MS (4000) #define QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS (2 * KFD_UNMAP_LATENCY_MS + 1000) -#define CIK_VMID_NUM (8) -#define KFD_VMID_START_OFFSET (8) -#define VMID_PER_DEVICE CIK_VMID_NUM -#define KFD_DQM_FIRST_PIPE (0) #define CIK_SDMA_QUEUES (4) #define CIK_SDMA_QUEUES_PER_ENGINE (2) #define CIK_SDMA_ENGINE_NUM (2) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 8883416634d3..f0ca60f27d9a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -141,6 +141,12 @@ struct kfd_mem_obj { uint32_t *cpu_ptr; }; +struct kfd_vmid_info { + uint32_t first_vmid_kfd; + uint32_t last_vmid_kfd; + uint32_t vmid_num_kfd; +}; + struct kfd_dev { struct kgd_dev *kgd; @@ -162,6 +168,7 @@ struct kfd_dev { */ struct kgd2kfd_shared_resources shared_resources; + struct kfd_vmid_info vm_info; const struct kfd2kgd_calls *kfd2kgd; struct mutex doorbell_mutex; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 03bec765b03d..68fe0d99f6c2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -187,7 +187,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, case KFD_QUEUE_TYPE_COMPUTE: /* check if there is over subscription */ if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) && - ((dev->dqm->processes_count >= VMID_PER_DEVICE) || + ((dev->dqm->processes_count >= dev->vm_info.vmid_num_kfd) || (dev->dqm->queue_count >= get_queues_num(dev->dqm)))) { pr_err("Over-subscription is not allowed in radeon_kfd.sched_policy == 1\n"); retval = -EPERM; -- cgit v1.2.3 From e596b90338126d08a8d90f08e79bb644b8c9f2b6 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 20 Sep 2017 18:10:19 -0400 Subject: drm/amdkfd: Reuse CHIP_* from amdgpu v2 There are already CHIP_* definitions under amd_shared.h file on amdgpu side, so KFD should reuse them rather than defining new ones. Using enum for asic type requires default cases on switch statements to prevent compiler warnings. WARN on unsupported ASICs. It should never get there because KFD should not be initialized on unsupported devices. v2: Replace BUG() with WARN and error return Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 4 ++++ drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 18 ++++++++++++------ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | 3 +++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 9 +++------ 4 files changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 87f8742dcd8c..fe0f0de0ef86 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1130,6 +1130,10 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) case CHIP_KAVERI: device_queue_manager_init_cik(&dqm->ops_asic_specific); break; + default: + WARN(1, "Unexpected ASIC family %u", + dev->device_info->asic_family); + goto out_free; } if (!dqm->ops.initialize(dqm)) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index d53d32a91a16..8b0c0645d7c0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -303,14 +303,20 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, case CHIP_KAVERI: kernel_queue_init_cik(&kq->ops_asic_specific); break; + default: + WARN(1, "Unexpected ASIC family %u", + dev->device_info->asic_family); + goto out_free; } - if (!kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE)) { - pr_err("Failed to init kernel queue\n"); - kfree(kq); - return NULL; - } - return kq; + if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE)) + return kq; + + pr_err("Failed to init kernel queue\n"); + +out_free: + kfree(kq); + return NULL; } void kernel_queue_uninit(struct kernel_queue *kq) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index b1ef1368c3bb..dfd260ef81ff 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -31,6 +31,9 @@ struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type, return mqd_manager_init_cik(type, dev); case CHIP_CARRIZO: return mqd_manager_init_vi(type, dev); + default: + WARN(1, "Unexpected ASIC family %u", + dev->device_info->asic_family); } return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f0ca60f27d9a..5ebe565fecb3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -33,6 +33,8 @@ #include #include +#include "amd_shared.h" + #define KFD_SYSFS_FILE_MODE 0444 #define KFD_MMAP_DOORBELL_MASK 0x8000000000000 @@ -112,11 +114,6 @@ enum cache_policy { cache_policy_noncoherent }; -enum asic_family_type { - CHIP_KAVERI = 0, - CHIP_CARRIZO -}; - struct kfd_event_interrupt_class { bool (*interrupt_isr)(struct kfd_dev *dev, const uint32_t *ih_ring_entry); @@ -125,7 +122,7 @@ struct kfd_event_interrupt_class { }; struct kfd_device_info { - unsigned int asic_family; + enum amd_asic_type asic_family; const struct kfd_event_interrupt_class *event_interrupt_class; unsigned int max_pasid_bits; unsigned int max_no_of_hqd; -- cgit v1.2.3 From 58dcd5bfcf99c9222a825ca67a0ecbd75516ec3f Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 20 Sep 2017 18:10:20 -0400 Subject: drm/amdkfd: Drop _nocpsch suffix from shared functions Several functions in DQM are shared between cpsch and nocpsch code. Remove the misleading _nocpsch suffix from their names. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index fe0f0de0ef86..471b34e58225 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -386,7 +386,7 @@ out_unlock: return retval; } -static struct mqd_manager *get_mqd_manager_nocpsch( +static struct mqd_manager *get_mqd_manager( struct device_queue_manager *dqm, enum KFD_MQD_TYPE type) { struct mqd_manager *mqd; @@ -407,7 +407,7 @@ static struct mqd_manager *get_mqd_manager_nocpsch( return mqd; } -static int register_process_nocpsch(struct device_queue_manager *dqm, +static int register_process(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { struct device_process_node *n; @@ -431,7 +431,7 @@ static int register_process_nocpsch(struct device_queue_manager *dqm, return retval; } -static int unregister_process_nocpsch(struct device_queue_manager *dqm, +static int unregister_process(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { int retval; @@ -513,7 +513,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm) return 0; } -static void uninitialize_nocpsch(struct device_queue_manager *dqm) +static void uninitialize(struct device_queue_manager *dqm) { int i; @@ -1095,10 +1095,10 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) dqm->ops.stop = stop_cpsch; dqm->ops.destroy_queue = destroy_queue_cpsch; dqm->ops.update_queue = update_queue; - dqm->ops.get_mqd_manager = get_mqd_manager_nocpsch; - dqm->ops.register_process = register_process_nocpsch; - dqm->ops.unregister_process = unregister_process_nocpsch; - dqm->ops.uninitialize = uninitialize_nocpsch; + dqm->ops.get_mqd_manager = get_mqd_manager; + dqm->ops.register_process = register_process; + dqm->ops.unregister_process = unregister_process; + dqm->ops.uninitialize = uninitialize; dqm->ops.create_kernel_queue = create_kernel_queue_cpsch; dqm->ops.destroy_kernel_queue = destroy_kernel_queue_cpsch; dqm->ops.set_cache_memory_policy = set_cache_memory_policy; @@ -1110,11 +1110,11 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) dqm->ops.create_queue = create_queue_nocpsch; dqm->ops.destroy_queue = destroy_queue_nocpsch; dqm->ops.update_queue = update_queue; - dqm->ops.get_mqd_manager = get_mqd_manager_nocpsch; - dqm->ops.register_process = register_process_nocpsch; - dqm->ops.unregister_process = unregister_process_nocpsch; + dqm->ops.get_mqd_manager = get_mqd_manager; + dqm->ops.register_process = register_process; + dqm->ops.unregister_process = unregister_process; dqm->ops.initialize = initialize_nocpsch; - dqm->ops.uninitialize = uninitialize_nocpsch; + dqm->ops.uninitialize = uninitialize; dqm->ops.set_cache_memory_policy = set_cache_memory_policy; break; default: -- cgit v1.2.3 From 544e3bf4f0e8278400f19ca7918a3cdf2548b4eb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 11 Sep 2017 14:22:08 +0200 Subject: reset: Restrict RESET_HSDK to ARC_SOC_HSDK or COMPILE_TEST The HSDK reset driver is only useful when building for an ARC HSDK platform. While at it, drop the "default n", as that is the default. Fixes: e0be864f14240cb1 ("ARC: reset: introduce HSDKv1 reset driver") Signed-off-by: Geert Uytterhoeven [p.zabel@pengutronix.de: rebased, renamed RESET_HSDK_V1 to RESET_HSDK] Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index a7c7d5a8c089..e2baecbb9dd3 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -37,7 +37,7 @@ config RESET_BERLIN config RESET_HSDK bool "Synopsys HSDK Reset Driver" depends on HAS_IOMEM - default n + depends on ARC_SOC_HSDK || COMPILE_TEST help This enables the reset controller driver for HSDK board. -- cgit v1.2.3 From e4b2ae7a8a11c5d4e0a6e21ba65d4b487a15d3d8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 16 Sep 2017 22:42:21 +0200 Subject: gpio: omap: omap_gpio_show_rev is not __init The probe function calls omap_gpio_show_rev(), which on most compilers is inlined, but on the old gcc-4.6 is not, causing a valid warning about the incorrect __init annotation: WARNING: vmlinux.o(.text+0x40f614): Section mismatch in reference from the function omap_gpio_probe() to the function .init.text:omap_gpio_show_rev() The function omap_gpio_probe() references the function __init omap_gpio_show_rev(). This is often because omap_gpio_probe lacks a __init annotation or the annotation of omap_gpio_show_rev is wrong. This removes the __init. Signed-off-by: Arnd Bergmann Acked-by: Santosh Shilimkar Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index dbf869fb63ce..22d7d4838265 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1010,7 +1010,7 @@ static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value) /*---------------------------------------------------------------------*/ -static void __init omap_gpio_show_rev(struct gpio_bank *bank) +static void omap_gpio_show_rev(struct gpio_bank *bank) { static bool called; u32 rev; -- cgit v1.2.3 From c84284e59d60514539cb06741972adf60b14a5a3 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Tue, 19 Sep 2017 21:04:56 +0200 Subject: pinctrl: bcm2835: fix build warning in bcm2835_gpio_irq_handle_bank This patch fix the following build warning: drivers/pinctrl/bcm/pinctrl-bcm2835.c:376:15: warning: variable 'type' set but not used [-Wunused-but-set-variable] Furthermore, it is unused for a long time, at least since commit 85ae9e512f43 ("pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP") where a "FIXME no clue why the code looks up the type here" was added. A year after, nobody answeered this question, so its time to remove it. Signed-off-by: Corentin Labbe Acked-by: Stefan Wahren Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 0944310225db..ff782445dfb7 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -373,16 +373,12 @@ static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc, unsigned long events; unsigned offset; unsigned gpio; - unsigned int type; events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4); events &= mask; events &= pc->enabled_irq_map[bank]; for_each_set_bit(offset, &events, 32) { gpio = (32 * bank) + offset; - /* FIXME: no clue why the code looks up the type here */ - type = pc->irq_type[gpio]; - generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irqdomain, gpio)); } -- cgit v1.2.3 From 6af1de2e4ec49635905aaed31d073a0d92c8d3bf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 6 Sep 2017 14:58:53 +0200 Subject: ath10k: mark PM functions as __maybe_unused When CONFIG_PM_SLEEP is disabled, we get a compile-time warning: drivers/net/wireless/ath/ath10k/pci.c:3417:12: error: 'ath10k_pci_pm_resume' defined but not used [-Werror=unused-function] static int ath10k_pci_pm_resume(struct device *dev) ^~~~~~~~~~~~~~~~~~~~ drivers/net/wireless/ath/ath10k/pci.c:3401:12: error: 'ath10k_pci_pm_suspend' defined but not used [-Werror=unused-function] static int ath10k_pci_pm_suspend(struct device *dev) Rather than fixing the #ifdef, this just marks both functions as __maybe_unused, which is a more robust way to do this. Fixes: 32faa3f0ee50 ("ath10k: add the PCI PM core suspend/resume ops") Signed-off-by: Arnd Bergmann Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index bc1633945a56..195dafb98131 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -3396,9 +3396,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); -#ifdef CONFIG_PM - -static int ath10k_pci_pm_suspend(struct device *dev) +static __maybe_unused int ath10k_pci_pm_suspend(struct device *dev) { struct ath10k *ar = dev_get_drvdata(dev); int ret; @@ -3414,7 +3412,7 @@ static int ath10k_pci_pm_suspend(struct device *dev) return ret; } -static int ath10k_pci_pm_resume(struct device *dev) +static __maybe_unused int ath10k_pci_pm_resume(struct device *dev) { struct ath10k *ar = dev_get_drvdata(dev); int ret; @@ -3433,7 +3431,6 @@ static int ath10k_pci_pm_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ath10k_pci_pm_ops, ath10k_pci_pm_suspend, ath10k_pci_pm_resume); -#endif static struct pci_driver ath10k_pci_driver = { .name = "ath10k_pci", -- cgit v1.2.3 From 2e1c42391ff2556387b3cb6308b24f6f65619feb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 21 Sep 2017 16:58:48 +0200 Subject: USB: core: harden cdc_parse_cdc_header Andrey Konovalov reported a possible out-of-bounds problem for the cdc_parse_cdc_header function. He writes: It looks like cdc_parse_cdc_header() doesn't validate buflen before accessing buffer[1], buffer[2] and so on. The only check present is while (buflen > 0). So fix this issue up by properly validating the buffer length matches what the descriptor says it is. Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 4c38ea41ae96..371a07d874a3 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -2069,6 +2069,10 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, elength = 1; goto next_desc; } + if ((buflen < elength) || (elength < 3)) { + dev_err(&intf->dev, "invalid descriptor buffer length\n"); + break; + } if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; -- cgit v1.2.3 From 74c1c694a2deab0561c1f502de9d32fdc7eb7b32 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 21 Sep 2017 12:01:35 +0100 Subject: drm/i915: Document the split in internal and public execbuf flags Since we reuse the same field for the user passing in their control flags, and for the kernel to track a couple of bits of state, document and check that those do not overlap. Suggested-by: Tvrtko Ursulin Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170921110135.15990-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 214a850b4b3c..61b9b079c8c8 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -58,6 +58,7 @@ enum { #define __EXEC_HAS_RELOC BIT(31) #define __EXEC_VALIDATED BIT(30) +#define __EXEC_INTERNAL_FLAGS (~0u << 30) #define UPDATE PIN_OFFSET_FIXED #define BATCH_OFFSET_BIAS (256*1024) @@ -2185,6 +2186,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, int out_fence_fd = -1; int err; + BUILD_BUG_ON(__EXEC_INTERNAL_FLAGS & ~__I915_EXEC_ILLEGAL_FLAGS); BUILD_BUG_ON(__EXEC_OBJECT_INTERNAL_FLAGS & ~__EXEC_OBJECT_UNKNOWN_FLAGS); -- cgit v1.2.3 From 87a2f622cc6446c7d09ac655b7b9b04886f16a4c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 18 Sep 2017 11:16:26 +0300 Subject: dmaengine: edma: Align the memcpy acnt array size with the transfer Memory to Memory transfers does not have any special alignment needs regarding to acnt array size, but if one of the areas are in memory mapped regions (like PCIe memory), we need to make sure that the acnt array size is aligned with the mem copy parameters. Before "dmaengine: edma: Optimize memcpy operation" change the memcpy was set up in a different way: acnt == number of bytes in a word based on __ffs((src | dest | len), bcnt and ccnt for looping the necessary number of words to comlete the trasnfer. Instead of reverting the commit we can fix it to make sure that the ACNT size is aligned to the traswnfer. Fixes: df6694f80365a (dmaengine: edma: Optimize memcpy operation) Signed-off-by: Peter Ujfalusi Cc: stable@vger.kernel.org Signed-off-by: Vinod Koul --- drivers/dma/edma.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 3879f80a4815..a7ea20e7b8e9 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -1143,11 +1143,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( struct edma_desc *edesc; struct device *dev = chan->device->dev; struct edma_chan *echan = to_edma_chan(chan); - unsigned int width, pset_len; + unsigned int width, pset_len, array_size; if (unlikely(!echan || !len)) return NULL; + /* Align the array size (acnt block) with the transfer properties */ + switch (__ffs((src | dest | len))) { + case 0: + array_size = SZ_32K - 1; + break; + case 1: + array_size = SZ_32K - 2; + break; + default: + array_size = SZ_32K - 4; + break; + } + if (len < SZ_64K) { /* * Transfer size less than 64K can be handled with one paRAM @@ -1169,7 +1182,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( * When the full_length is multibple of 32767 one slot can be * used to complete the transfer. */ - width = SZ_32K - 1; + width = array_size; pset_len = rounddown(len, width); /* One slot is enough for lengths multiple of (SZ_32K -1) */ if (unlikely(pset_len == len)) @@ -1217,7 +1230,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( } dest += pset_len; src += pset_len; - pset_len = width = len % (SZ_32K - 1); + pset_len = width = len % array_size; ret = edma_config_pset(chan, &edesc->pset[1], src, dest, 1, width, pset_len, DMA_MEM_TO_MEM); -- cgit v1.2.3 From 2ccb4837c938357233a0b8818e3ca3e58242c952 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 21 Sep 2017 14:35:32 +0300 Subject: dmaengine: ti-dma-crossbar: Fix possible race condition with dma_inuse When looking for unused xbar_out lane we should also protect the set_bit() call with the same mutex to protect against concurrent threads picking the same ID. Fixes: ec9bfa1e1a796 ("dmaengine: ti-dma-crossbar: dra7: Use bitops instead of idr") Signed-off-by: Peter Ujfalusi Cc: stable@vger.kernel.org Signed-off-by: Vinod Koul --- drivers/dma/ti-dma-crossbar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c index 2f65a8fde21d..f1d04b70ee67 100644 --- a/drivers/dma/ti-dma-crossbar.c +++ b/drivers/dma/ti-dma-crossbar.c @@ -262,13 +262,14 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec, mutex_lock(&xbar->mutex); map->xbar_out = find_first_zero_bit(xbar->dma_inuse, xbar->dma_requests); - mutex_unlock(&xbar->mutex); if (map->xbar_out == xbar->dma_requests) { + mutex_unlock(&xbar->mutex); dev_err(&pdev->dev, "Run out of free DMA requests\n"); kfree(map); return ERR_PTR(-ENOMEM); } set_bit(map->xbar_out, xbar->dma_inuse); + mutex_unlock(&xbar->mutex); map->xbar_in = (u16)dma_spec->args[0]; -- cgit v1.2.3 From a4fd4a724d6c30ad671046d83be2e9be2f11d275 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 21 Sep 2017 16:02:05 -0400 Subject: usb-storage: fix bogus hardware error messages for ATA pass-thru devices Ever since commit a621bac3044e ("scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands"), people have been getting bogus error messages for USB disk drives using ATA pass-thru. For example: [ 1344.880193] sd 6:0:0:0: [sdb] Attached SCSI disk [ 1345.069152] sd 6:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_ERROR driverbyte=DRIVER_SENSE [ 1345.069159] sd 6:0:0:0: [sdb] tag#0 Sense Key : Hardware Error [current] [descriptor] [ 1345.069162] sd 6:0:0:0: [sdb] tag#0 Add. Sense: No additional sense information [ 1345.069168] sd 6:0:0:0: [sdb] tag#0 CDB: ATA command pass through(16) 85 06 20 00 00 00 00 00 00 00 00 00 00 00 e5 00 [ 1345.172252] sd 6:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_ERROR driverbyte=DRIVER_SENSE [ 1345.172258] sd 6:0:0:0: [sdb] tag#0 Sense Key : Hardware Error [current] [descriptor] [ 1345.172261] sd 6:0:0:0: [sdb] tag#0 Add. Sense: No additional sense information [ 1345.172266] sd 6:0:0:0: [sdb] tag#0 CDB: ATA command pass through(12)/Blank a1 06 20 da 00 00 4f c2 00 b0 00 00 These messages can be quite annoying, because programs like udisks2 provoke them every 10 minutes or so. Other programs can also have this effect, such as those in smartmontools. I don't fully understand how that commit induced the SCSI core to log these error messages, but the underlying cause for them is code added to usb-storage by commit f1a0743bc0e7 ("USB: storage: When a device returns no sense data, call it a Hardware Error"). At the time it was necessary to do this, in order to prevent an infinite retry loop with some not-so-great mass storage devices. However, the ATA pass-thru protocol uses SCSI sense data to return command status values, and some devices always report Check Condition status for ATA pass-thru commands to ensure that the host retrieves the sense data, even if the command succeeded. This violates the USB mass-storage protocol (Check Condition status is supposed to mean the command failed), but we can't help that. This patch attempts to mitigate the problem of these bogus error reports by changing usb-storage. The HARDWARE ERROR sense key will be inserted only for commands that aren't ATA pass-thru. Thanks to Ewan Milne for pointing out that this mechanism was present in usb-storage. 8 years after writing it, I had completely forgotten its existence. Signed-off-by: Alan Stern Tested-by: Kris Lindgren Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1351305 CC: Ewan D. Milne CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/transport.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 1a59f335b063..a3ccb899df60 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -834,13 +834,25 @@ Retry_Sense: if (result == USB_STOR_TRANSPORT_GOOD) { srb->result = SAM_STAT_GOOD; srb->sense_buffer[0] = 0x0; + } + + /* + * ATA-passthru commands use sense data to report + * the command completion status, and often devices + * return Check Condition status when nothing is + * wrong. + */ + else if (srb->cmnd[0] == ATA_16 || + srb->cmnd[0] == ATA_12) { + /* leave the data alone */ + } /* * If there was a problem, report an unspecified * hardware error to prevent the higher layers from * entering an infinite retry loop. */ - } else { + else { srb->result = DID_ERROR << 16; if ((sshdr.response_code & 0x72) == 0x72) srb->sense_buffer[1] = HARDWARE_ERROR; -- cgit v1.2.3 From 113f6eb6d50cfa5e2a1cdcf1678b12661fa272ab Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 21 Sep 2017 15:59:30 -0400 Subject: usb-storage: unusual_devs entry to fix write-access regression for Seagate external drives Kris Lindgren reports that without the NO_WP_DETECT flag, his Seagate external disk drive fails all write accesses. This regresssion dates back approximately to the start of the 4.x kernel releases. Signed-off-by: Alan Stern Reported-by: Kris Lindgren CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 5a70c33ef0e0..eb06d88b41d6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1459,6 +1459,13 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Reported by Kris Lindgren */ +UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999, + "Seagate", + "External", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT ), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA", -- cgit v1.2.3 From fd085bb1766d6a598f53af2308374a546a49775a Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 19 Sep 2017 18:47:40 +0300 Subject: stm class: Fix a use-after-free For reasons unknown, the stm_source removal path uses device_destroy() to kill the underlying device object. Because device_destroy() uses devt to look for the device to destroy and the fact that stm_source devices don't have one (or all have the same one), it just picks the first device in the class, which may well be the wrong one. That is, loading stm_console and stm_heartbeat and then removing both will die in dereferencing a freed object. Since this should have been device_unregister() in the first place, use it instead of device_destroy(). Signed-off-by: Alexander Shishkin Fixes: 7bd1d4093c2 ("stm class: Introduce an abstraction for System Trace Module devices") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/stm/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index 9414900575d8..f129869e05a9 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -1119,7 +1119,7 @@ void stm_source_unregister_device(struct stm_source_data *data) stm_source_link_drop(src); - device_destroy(&stm_source_class, src->dev.devt); + device_unregister(&src->dev); } EXPORT_SYMBOL_GPL(stm_source_unregister_device); -- cgit v1.2.3 From 920ce7c33db25cf4acb4ade3ae8c93bd23dfd730 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 19 Sep 2017 18:47:41 +0300 Subject: intel_th: pci: Add Cedar Fork PCH support This adds Intel(R) Trace Hub PCI ID for Cedar Fork PCH. Signed-off-by: Alexander Shishkin Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index bc9cebc30526..00ee60d9789e 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -158,6 +158,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), .driver_data = (kernel_ulong_t)&intel_th_2x, }, + { + /* Cedar Fork PCH */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, { 0 }, }; -- cgit v1.2.3 From 24600840c74112ad04a9ddd99d7d7f731dcaa1cb Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 19 Sep 2017 18:47:42 +0300 Subject: intel_th: pci: Add Lewisburg PCH support This adds Intel(R) Trace Hub PCI ID for Lewisburg PCH. Signed-off-by: Alexander Shishkin Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 00ee60d9789e..c2a2ce8ee541 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -143,6 +143,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), .driver_data = (kernel_ulong_t)0, }, + { + /* Lewisburg PCH */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6), + .driver_data = (kernel_ulong_t)0, + }, { /* Gemini Lake */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), -- cgit v1.2.3 From 33c150c2ee4a65a59190a124b45d05b1abf9478e Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Thu, 21 Sep 2017 23:41:47 -0700 Subject: vmbus: don't acquire the mutex in vmbus_hvsock_device_unregister() Due to commit 54a66265d675 ("Drivers: hv: vmbus: Fix rescind handling"), we need this patch to resolve the below deadlock: after we get the mutex in vmbus_hvsock_device_unregister() and call vmbus_device_unregister() -> device_unregister() -> ... -> device_release() -> vmbus_device_release(), we'll get a deadlock, because vmbus_device_release() tries to get the same mutex. Signed-off-by: Dexuan Cui Cc: K. Y. Srinivasan Cc: Haiyang Zhang Cc: Stephen Hemminger Signed-off-by: K. Y. Srinivasan Cc: stable@vger.kernel.org (4.13 and above) Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 060df71c2e8b..bcbb031f7263 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -936,14 +936,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) void vmbus_hvsock_device_unregister(struct vmbus_channel *channel) { - mutex_lock(&vmbus_connection.channel_mutex); - BUG_ON(!is_hvsock_channel(channel)); channel->rescind = true; vmbus_device_unregister(channel->device_obj); - - mutex_unlock(&vmbus_connection.channel_mutex); } EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister); -- cgit v1.2.3 From 549e658a0919e355a2b2144dc380b3729bef7f3e Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 21 Sep 2017 23:41:48 -0700 Subject: Drivers: hv: fcopy: restore correct transfer length Till recently the expected length of bytes read by the daemon did depend on the context. It was either hv_start_fcopy or hv_do_fcopy. The daemon had a buffer size of two pages, which was much larger than needed. Now the expected length of bytes read by the daemon changed slightly. For START_FILE_COPY it is still the size of hv_start_fcopy. But for WRITE_TO_FILE and the other operations it is as large as the buffer that arrived via vmbus. In case of WRITE_TO_FILE that is slightly larger than a struct hv_do_fcopy. Since the buffer in the daemon was still larger everything was fine. Currently, the daemon reads only what is actually needed. The new buffer layout is as large as a struct hv_do_fcopy, for the WRITE_TO_FILE operation. Since the kernel expects a slightly larger size, hvt_op_read will return -EINVAL because the daemon will read slightly less than expected. Address this by restoring the expected buffer size in case of WRITE_TO_FILE. Fixes: 'c7e490fc23eb ("Drivers: hv: fcopy: convert to hv_utils_transport")' Fixes: '3f2baa8a7d2e ("Tools: hv: update buffer handling in hv_fcopy_daemon")' Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_fcopy.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c index daa75bd41f86..2364281d8593 100644 --- a/drivers/hv/hv_fcopy.c +++ b/drivers/hv/hv_fcopy.c @@ -170,6 +170,10 @@ static void fcopy_send_data(struct work_struct *dummy) out_src = smsg_out; break; + case WRITE_TO_FILE: + out_src = fcopy_transaction.fcopy_msg; + out_len = sizeof(struct hv_do_fcopy); + break; default: out_src = fcopy_transaction.fcopy_msg; out_len = fcopy_transaction.recv_len; -- cgit v1.2.3 From c51b46dd5b9950436b6b1f8189e93e1ad380cee1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 20 Sep 2017 22:19:57 +0100 Subject: staging: rtl8723bs: add missing range check on id The value of the u8 id needs to be upper bounds checked to ensure the cam_cache array on the adapter dvobj is not indexed outside of the allowed range of 0..TOTAL_CAM_ENTRY-1. This can currently occur if id is >= TOTAL_CAM_ENTRY when calling write_cam_from_cache. Fix this by adding an upper range check. Detected by CoverityScan, CID#1428464 ("Use of untrusted scalar value") Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver") Signed-off-by: Colin Ian King Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/os_dep/rtw_proc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/rtl8723bs/os_dep/rtw_proc.c b/drivers/staging/rtl8723bs/os_dep/rtw_proc.c index 92277457aba4..ce1dd6f9036f 100644 --- a/drivers/staging/rtl8723bs/os_dep/rtw_proc.c +++ b/drivers/staging/rtl8723bs/os_dep/rtw_proc.c @@ -311,6 +311,8 @@ static ssize_t proc_set_cam(struct file *file, const char __user *buffer, size_t if (num < 2) return count; + if (id >= TOTAL_CAM_ENTRY) + return -EINVAL; if (strcmp("c", cmd) == 0) { _clear_cam_entry(adapter, id); -- cgit v1.2.3 From ec14121931a24f8d3678b8a9c408adee3b21d465 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 20 Sep 2017 18:34:18 +0100 Subject: staging: rtl8723bs: avoid null pointer dereference on pmlmepriv There is a check to see if pmlmepriv is null before vfree'ing pmlmepriv->free_bss_buf hence implying pmlmepriv could potenially be null. However, a previous call to rtw_free_mlme_priv_ie_data can also dereference pmlmepriv, so move this call so that it is only called if pmlmepriv non-null. Detected by CoverityScan, CID#1077739 ("Dereference before null check") Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver") Signed-off-by: Colin Ian King Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723bs/core/rtw_mlme.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index 6b778206a1a3..cb8a95aabd6c 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -119,9 +119,8 @@ void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) { - rtw_free_mlme_priv_ie_data(pmlmepriv); - if (pmlmepriv) { + rtw_free_mlme_priv_ie_data(pmlmepriv); if (pmlmepriv->free_bss_buf) { vfree(pmlmepriv->free_bss_buf); } -- cgit v1.2.3 From 40784d72aeeb4d95cf74ea2243223a85193f0e84 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 25 Aug 2017 00:19:54 +0200 Subject: crypto: axis - hide an unused variable Without CONFIG_DEBUG_FS, we get a harmless warning: drivers/crypto/axis/artpec6_crypto.c:352:23: error: 'dbgfs_root' defined but not used [-Werror=unused-variable] This moves it into the #ifdef that hides the only user. Fixes: a21eb94fc4d3 ("crypto: axis - add ARTPEC-6/7 crypto accelerator driver") Signed-off-by: Arnd Bergmann Acked-by: Lars Persson Signed-off-by: Herbert Xu --- drivers/crypto/axis/artpec6_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/axis/artpec6_crypto.c b/drivers/crypto/axis/artpec6_crypto.c index d9fbbf01062b..0f9754e07719 100644 --- a/drivers/crypto/axis/artpec6_crypto.c +++ b/drivers/crypto/axis/artpec6_crypto.c @@ -349,8 +349,6 @@ struct artpec6_crypto_aead_req_ctx { /* The crypto framework makes it hard to avoid this global. */ static struct device *artpec6_crypto_dev; -static struct dentry *dbgfs_root; - #ifdef CONFIG_FAULT_INJECTION static DECLARE_FAULT_ATTR(artpec6_crypto_fail_status_read); static DECLARE_FAULT_ATTR(artpec6_crypto_fail_dma_array_full); @@ -2984,6 +2982,8 @@ struct dbgfs_u32 { char *desc; }; +static struct dentry *dbgfs_root; + static void artpec6_crypto_init_debugfs(void) { dbgfs_root = debugfs_create_dir("artpec6_crypto", NULL); -- cgit v1.2.3 From 17b51ad8e5c051032d8e1d698e7dfd01d9133a92 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 18 Sep 2017 17:27:33 +0100 Subject: drm/i915: Only wake the waiter from the interrupt if passed As we now check if the seqno is complete in order to signal the fence, we can also decide not to wake up the first_waiter until it is ready (since it is waiting on the same seqno). The only caveat is that if we need the engine->irq_seqno_barrier to enforce some coherency between an interrupt and the seqno read, we have to always wake the waiter in order to perform that heavyweight barrier. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170918162734.21294-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_irq.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c23efc4394ce..2190e42ba310 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1038,6 +1038,8 @@ static void notify_ring(struct intel_engine_cs *engine) spin_lock(&engine->breadcrumbs.irq_lock); wait = engine->breadcrumbs.irq_wait; if (wait) { + bool wakeup = engine->irq_seqno_barrier; + /* We use a callback from the dma-fence to submit * requests after waiting on our own requests. To * ensure minimum delay in queuing the next request to @@ -1050,12 +1052,15 @@ static void notify_ring(struct intel_engine_cs *engine) * and many waiters. */ if (i915_seqno_passed(intel_engine_get_seqno(engine), - wait->seqno) && - !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &wait->request->fence.flags)) - rq = i915_gem_request_get(wait->request); + wait->seqno)) { + wakeup = true; + if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, + &wait->request->fence.flags)) + rq = i915_gem_request_get(wait->request); + } - wake_up_process(wait->tsk); + if (wakeup) + wake_up_process(wait->tsk); } else { __intel_engine_disarm_breadcrumbs(engine); } -- cgit v1.2.3 From de4d2106f88ad7d98bf3adc602885d1d9071b644 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 18 Sep 2017 17:27:34 +0100 Subject: drm/i915: Check waiter->seqno carefully in case of preemption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If preemption occurs at precisely the right moment, we may decide that the wait is complete even though the wait's request is no longer executing (having been preempted). We handle this situation by double checking that request following deciding whether the wait is complete. Reported-by: Michał Winiarski Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170918162734.21294-2-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski --- drivers/gpu/drm/i915/i915_irq.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2190e42ba310..bd38c6983eec 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1053,10 +1053,13 @@ static void notify_ring(struct intel_engine_cs *engine) */ if (i915_seqno_passed(intel_engine_get_seqno(engine), wait->seqno)) { + struct drm_i915_gem_request *waiter = wait->request; + wakeup = true; if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &wait->request->fence.flags)) - rq = i915_gem_request_get(wait->request); + &waiter->fence.flags) && + intel_wait_check_request(wait, waiter)) + rq = i915_gem_request_get(waiter); } if (wakeup) -- cgit v1.2.3 From a3df2c857c103b1103c9d578d68193a6fbe63c61 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 21 Sep 2017 22:09:03 +0100 Subject: drm/i915: Confirm request->global_seqno after spin completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After we see our target seqno has been completed by the hw, we need to confirm that it still matches the request (as it may have been preempted before the spin completes). If the request no longer matches the target seqno, we need to restart the wait to reacquire that seqno. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Michal Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/20170921210903.18337-1-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski --- drivers/gpu/drm/i915/i915_gem_request.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 813a3b546d6e..289fb08acaf5 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -1040,12 +1040,9 @@ bool __i915_spin_request(const struct drm_i915_gem_request *req, irq = atomic_read(&engine->irq_count); timeout_us += local_clock_us(&cpu); do { - if (seqno != i915_gem_request_global_seqno(req)) - break; - if (i915_seqno_passed(intel_engine_get_seqno(req->engine), seqno)) - return true; + return seqno == i915_gem_request_global_seqno(req); /* Seqno are meant to be ordered *before* the interrupt. If * we see an interrupt without a corresponding seqno advance, -- cgit v1.2.3 From 4f044a88a86adb4c8cc6cb1a7303bb9c61ea2caa Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Tue, 19 Sep 2017 19:38:44 +0000 Subject: drm/i915: Rename global i915 to i915_modparams Our global struct with params is named exactly the same way as new preferred name for the drm_i915_private function parameter. To avoid such name reuse lets use different name for the global. v5: pure rename v6: fix Credits-to: Coccinelle @@ identifier n; @@ ( - i915.n + i915_modparams.n ) Signed-off-by: Michal Wajdeczko Cc: Jani Nikula Cc: Chris Wilson Cc: Tvrtko Ursulin Cc: Ville Syrjala Cc: Joonas Lahtinen Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170919193846.38060-1-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/gvt/render.c | 2 +- drivers/gpu/drm/i915/i915_debugfs.c | 14 ++++---- drivers/gpu/drm/i915/i915_drv.c | 34 ++++++++++-------- drivers/gpu/drm/i915/i915_drv.h | 10 +++--- drivers/gpu/drm/i915/i915_gem.c | 4 +-- drivers/gpu/drm/i915/i915_gem_context.c | 12 +++---- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++-- drivers/gpu/drm/i915/i915_gpu_error.c | 6 ++-- drivers/gpu/drm/i915/i915_guc_submission.c | 2 +- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/i915_params.c | 6 ++-- drivers/gpu/drm/i915/i915_params.h | 2 +- drivers/gpu/drm/i915/i915_pci.c | 6 ++-- drivers/gpu/drm/i915/i915_perf.c | 6 ++-- drivers/gpu/drm/i915/intel_bios.c | 7 ++-- drivers/gpu/drm/i915/intel_crt.c | 4 +-- drivers/gpu/drm/i915/intel_device_info.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 12 +++---- drivers/gpu/drm/i915/intel_dp.c | 4 +-- drivers/gpu/drm/i915/intel_dp_aux_backlight.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_engine_cs.c | 4 +-- drivers/gpu/drm/i915/intel_fbc.c | 11 +++--- drivers/gpu/drm/i915/intel_guc_loader.c | 13 +++---- drivers/gpu/drm/i915/intel_guc_log.c | 26 +++++++------- drivers/gpu/drm/i915/intel_gvt.c | 12 +++---- drivers/gpu/drm/i915/intel_hangcheck.c | 2 +- drivers/gpu/drm/i915/intel_huc.c | 4 +-- drivers/gpu/drm/i915/intel_lrc.c | 4 +-- drivers/gpu/drm/i915/intel_lvds.c | 4 +-- drivers/gpu/drm/i915/intel_opregion.c | 2 +- drivers/gpu/drm/i915/intel_panel.c | 8 ++--- drivers/gpu/drm/i915/intel_pm.c | 6 ++-- drivers/gpu/drm/i915/intel_psr.c | 10 +++--- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++--- drivers/gpu/drm/i915/intel_runtime_pm.c | 17 ++++----- drivers/gpu/drm/i915/intel_uc.c | 51 ++++++++++++++------------- drivers/gpu/drm/i915/intel_uncore.c | 22 ++++++------ 39 files changed, 182 insertions(+), 169 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c index 2ea542257f03..6d066cf35478 100644 --- a/drivers/gpu/drm/i915/gvt/render.c +++ b/drivers/gpu/drm/i915/gvt/render.c @@ -293,7 +293,7 @@ static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id) */ if (mmio->in_context && ((ctx_ctrl & inhibit_mask) != inhibit_mask) && - i915.enable_execlists) + i915_modparams.enable_execlists) continue; if (mmio->mask) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 2518bdf95eef..b08ebed4e700 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -66,7 +66,7 @@ static int i915_capabilities(struct seq_file *m, void *data) #undef PRINT_FLAG kernel_param_lock(THIS_MODULE); -#define PRINT_PARAM(T, x) seq_print_param(m, #x, #T, &i915.x); +#define PRINT_PARAM(T, x) seq_print_param(m, #x, #T, &i915_modparams.x); I915_PARAMS_FOR_EACH(PRINT_PARAM); #undef PRINT_PARAM kernel_param_unlock(THIS_MODULE); @@ -1266,7 +1266,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) if (waitqueue_active(&dev_priv->gpu_error.reset_queue)) seq_puts(m, "struct_mutex blocked for reset\n"); - if (!i915.enable_hangcheck) { + if (!i915_modparams.enable_hangcheck) { seq_puts(m, "Hangcheck disabled\n"); return 0; } @@ -1701,7 +1701,7 @@ static int i915_ips_status(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); seq_printf(m, "Enabled by kernel parameter: %s\n", - yesno(i915.enable_ips)); + yesno(i915_modparams.enable_ips)); if (INTEL_GEN(dev_priv) >= 8) { seq_puts(m, "Currently: unknown\n"); @@ -2016,7 +2016,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) enum intel_engine_id id; int ret; - if (!i915.enable_execlists) { + if (!i915_modparams.enable_execlists) { seq_printf(m, "Logical Ring Contexts are disabled\n"); return 0; } @@ -2592,7 +2592,7 @@ static int i915_guc_log_control_get(void *data, u64 *val) if (!dev_priv->guc.log.vma) return -EINVAL; - *val = i915.guc_log_level; + *val = i915_modparams.guc_log_level; return 0; } @@ -3310,7 +3310,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) seq_printf(m, "\tBBADDR: 0x%08x_%08x\n", upper_32_bits(addr), lower_32_bits(addr)); - if (i915.enable_execlists) { + if (i915_modparams.enable_execlists) { const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; u32 ptr, read, write; unsigned int idx; @@ -3406,7 +3406,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) enum intel_engine_id id; int j, ret; - if (!i915.semaphores) { + if (!i915_modparams.semaphores) { seq_puts(m, "Semaphores are disabled\n"); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5c111ea96e80..7056bb299dc6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -58,12 +58,12 @@ static unsigned int i915_load_fail_count; bool __i915_inject_load_failure(const char *func, int line) { - if (i915_load_fail_count >= i915.inject_load_failure) + if (i915_load_fail_count >= i915_modparams.inject_load_failure) return false; - if (++i915_load_fail_count == i915.inject_load_failure) { + if (++i915_load_fail_count == i915_modparams.inject_load_failure) { DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n", - i915.inject_load_failure, func, line); + i915_modparams.inject_load_failure, func, line); return true; } @@ -106,8 +106,8 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level, static bool i915_error_injected(struct drm_i915_private *dev_priv) { - return i915.inject_load_failure && - i915_load_fail_count == i915.inject_load_failure; + return i915_modparams.inject_load_failure && + i915_load_fail_count == i915_modparams.inject_load_failure; } #define i915_load_error(dev_priv, fmt, ...) \ @@ -321,7 +321,7 @@ static int i915_getparam(struct drm_device *dev, void *data, value = USES_PPGTT(dev_priv); break; case I915_PARAM_HAS_SEMAPHORES: - value = i915.semaphores; + value = i915_modparams.semaphores; break; case I915_PARAM_HAS_SECURE_BATCHES: value = capable(CAP_SYS_ADMIN); @@ -340,7 +340,8 @@ static int i915_getparam(struct drm_device *dev, void *data, return -ENODEV; break; case I915_PARAM_HAS_GPU_RESET: - value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv); + value = i915_modparams.enable_hangcheck && + intel_has_gpu_reset(dev_priv); if (value && intel_has_reset_engine(dev_priv)) value = 2; break; @@ -1031,9 +1032,9 @@ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) static void intel_sanitize_options(struct drm_i915_private *dev_priv) { - i915.enable_execlists = + i915_modparams.enable_execlists = intel_sanitize_enable_execlists(dev_priv, - i915.enable_execlists); + i915_modparams.enable_execlists); /* * i915.enable_ppgtt is read-only, so do an early pass to validate the @@ -1041,12 +1042,15 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv) * do this now so that we can print out any log messages once rather * than every time we check intel_enable_ppgtt(). */ - i915.enable_ppgtt = - intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt); - DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); + i915_modparams.enable_ppgtt = + intel_sanitize_enable_ppgtt(dev_priv, + i915_modparams.enable_ppgtt); + DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915_modparams.enable_ppgtt); - i915.semaphores = intel_sanitize_semaphores(dev_priv, i915.semaphores); - DRM_DEBUG_DRIVER("use GPU semaphores? %s\n", yesno(i915.semaphores)); + i915_modparams.semaphores = + intel_sanitize_semaphores(dev_priv, i915_modparams.semaphores); + DRM_DEBUG_DRIVER("use GPU semaphores? %s\n", + yesno(i915_modparams.semaphores)); intel_uc_sanitize_options(dev_priv); @@ -1277,7 +1281,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) int ret; /* Enable nuclear pageflip on ILK+ */ - if (!i915.nuclear_pageflip && match_info->gen < 5) + if (!i915_modparams.nuclear_pageflip && match_info->gen < 5) driver.driver_features &= ~DRIVER_ATOMIC; ret = -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 08e3ae15b52e..d6babe7d362d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -93,7 +93,7 @@ #define I915_STATE_WARN(condition, format...) ({ \ int __ret_warn_on = !!(condition); \ if (unlikely(__ret_warn_on)) \ - if (!WARN(i915.verbose_state_checks, format)) \ + if (!WARN(i915_modparams.verbose_state_checks, format)) \ DRM_ERROR(format); \ unlikely(__ret_warn_on); \ }) @@ -3076,9 +3076,9 @@ intel_info(const struct drm_i915_private *dev_priv) #define HAS_LOGICAL_RING_CONTEXTS(dev_priv) \ ((dev_priv)->info.has_logical_ring_contexts) -#define USES_PPGTT(dev_priv) (i915.enable_ppgtt) -#define USES_FULL_PPGTT(dev_priv) (i915.enable_ppgtt >= 2) -#define USES_FULL_48BIT_PPGTT(dev_priv) (i915.enable_ppgtt == 3) +#define USES_PPGTT(dev_priv) (i915_modparams.enable_ppgtt) +#define USES_FULL_PPGTT(dev_priv) (i915_modparams.enable_ppgtt >= 2) +#define USES_FULL_48BIT_PPGTT(dev_priv) (i915_modparams.enable_ppgtt == 3) #define HAS_OVERLAY(dev_priv) ((dev_priv)->info.has_overlay) #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \ @@ -3279,7 +3279,7 @@ static inline void i915_queue_hangcheck(struct drm_i915_private *dev_priv) { unsigned long delay; - if (unlikely(!i915.enable_hangcheck)) + if (unlikely(!i915_modparams.enable_hangcheck)) return; /* Don't continually defer the hangcheck so that it is always run at diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b0bbf8729dae..12ce97d47afb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4738,7 +4738,7 @@ bool intel_sanitize_semaphores(struct drm_i915_private *dev_priv, int value) return false; /* TODO: make semaphores and Execlists play nicely together */ - if (i915.enable_execlists) + if (i915_modparams.enable_execlists) return false; if (value >= 0) @@ -4759,7 +4759,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv) dev_priv->mm.unordered_timeline = dma_fence_context_alloc(1); - if (!i915.enable_execlists) { + if (!i915_modparams.enable_execlists) { dev_priv->gt.resume = intel_legacy_submission_resume; dev_priv->gt.cleanup_engine = intel_engine_cleanup; } else { diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 58a2a44f88bd..921ee369c74d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -314,7 +314,7 @@ __create_hw_context(struct drm_i915_private *dev_priv, * present or not in use we still need a small bias as ring wraparound * at offset 0 sometimes hangs. No idea why. */ - if (HAS_GUC(dev_priv) && i915.enable_guc_loading) + if (HAS_GUC(dev_priv) && i915_modparams.enable_guc_loading) ctx->ggtt_offset_bias = GUC_WOPCM_TOP; else ctx->ggtt_offset_bias = I915_GTT_PAGE_SIZE; @@ -407,7 +407,7 @@ i915_gem_context_create_gvt(struct drm_device *dev) i915_gem_context_set_closed(ctx); /* not user accessible */ i915_gem_context_clear_bannable(ctx); i915_gem_context_set_force_single_submission(ctx); - if (!i915.enable_guc_submission) + if (!i915_modparams.enable_guc_submission) ctx->ring_size = 512 * PAGE_SIZE; /* Max ring buffer size */ GEM_BUG_ON(i915_gem_context_is_kernel(ctx)); @@ -431,7 +431,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv) if (intel_vgpu_active(dev_priv) && HAS_LOGICAL_RING_CONTEXTS(dev_priv)) { - if (!i915.enable_execlists) { + if (!i915_modparams.enable_execlists) { DRM_INFO("Only EXECLIST mode is supported in vgpu.\n"); return -EINVAL; } @@ -483,7 +483,7 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv) } /* Force the GPU state to be restored on enabling */ - if (!i915.enable_execlists) { + if (!i915_modparams.enable_execlists) { struct i915_gem_context *ctx; list_for_each_entry(ctx, &dev_priv->contexts.list, link) { @@ -568,7 +568,7 @@ mi_set_context(struct drm_i915_gem_request *req, u32 flags) enum intel_engine_id id; const int num_rings = /* Use an extended w/a on gen7 if signalling from other rings */ - (i915.semaphores && INTEL_GEN(dev_priv) == 7) ? + (i915_modparams.semaphores && INTEL_GEN(dev_priv) == 7) ? INTEL_INFO(dev_priv)->num_rings - 1 : 0; int len; @@ -837,7 +837,7 @@ int i915_switch_context(struct drm_i915_gem_request *req) struct intel_engine_cs *engine = req->engine; lockdep_assert_held(&req->i915->drm.struct_mutex); - if (i915.enable_execlists) + if (i915_modparams.enable_execlists) return 0; if (!req->ctx->engine[engine->id].state) { diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 61b9b079c8c8..fa18677cdb54 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1585,7 +1585,7 @@ static int eb_prefault_relocations(const struct i915_execbuffer *eb) const unsigned int count = eb->buffer_count; unsigned int i; - if (unlikely(i915.prefault_disable)) + if (unlikely(i915_modparams.prefault_disable)) return 0; for (i = 0; i < count; i++) { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 37cd0860fc29..ecb5e8cd37ba 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -180,7 +180,7 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, return 0; } - if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists) { + if (INTEL_GEN(dev_priv) >= 8 && i915_modparams.enable_execlists) { if (has_full_48bit_ppgtt) return 3; @@ -1972,7 +1972,7 @@ int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv) /* In the case of execlists, PPGTT is enabled by the context descriptor * and the PDPs are contained within the context itself. We don't * need to do anything here. */ - if (i915.enable_execlists) + if (i915_modparams.enable_execlists) return 0; if (!USES_PPGTT(dev_priv)) @@ -3292,7 +3292,7 @@ int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv) * currently don't have any bits spare to pass in this upper * restriction! */ - if (HAS_GUC(dev_priv) && i915.enable_guc_loading) { + if (HAS_GUC(dev_priv) && i915_modparams.enable_guc_loading) { ggtt->base.total = min_t(u64, ggtt->base.total, GUC_GGTT_TOP); ggtt->mappable_end = min(ggtt->mappable_end, ggtt->base.total); } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index ed5a1eb839ad..6cd5eba643e8 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1554,7 +1554,7 @@ static void i915_gem_capture_guc_log_buffer(struct drm_i915_private *dev_priv, struct i915_gpu_state *error) { /* Capturing log buf contents won't be useful if logging was disabled */ - if (!dev_priv->guc.log.vma || (i915.guc_log_level < 0)) + if (!dev_priv->guc.log.vma || (i915_modparams.guc_log_level < 0)) return; error->guc_log = i915_error_object_create(dev_priv, @@ -1696,7 +1696,7 @@ static int capture(void *data) ktime_to_timeval(ktime_sub(ktime_get(), error->i915->gt.last_init_time)); - error->params = i915; + error->params = i915_modparams; #define DUP(T, x) dup_param(#T, &error->params.x); I915_PARAMS_FOR_EACH(DUP); #undef DUP @@ -1751,7 +1751,7 @@ void i915_capture_error_state(struct drm_i915_private *dev_priv, struct i915_gpu_state *error; unsigned long flags; - if (!i915.error_capture) + if (!i915_modparams.error_capture) return; if (READ_ONCE(dev_priv->gpu_error.first_error)) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index e191d56fc990..06a26c610806 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -1245,7 +1245,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv) if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) return 0; - if (i915.guc_log_level >= 0) + if (i915_modparams.guc_log_level >= 0) gen9_enable_guc_interrupts(dev_priv); ctx = dev_priv->kernel_context; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bd38c6983eec..b1bab7605db9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1357,7 +1357,7 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) { notify_ring(engine); - tasklet |= i915.enable_guc_submission; + tasklet |= i915_modparams.enable_guc_submission; } if (tasklet) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index ddda513cc7f4..ec6534180d54 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -26,13 +26,13 @@ #include "i915_drv.h" #define i915_param_named(name, T, perm, desc) \ - module_param_named(name, i915.name, T, perm); \ + module_param_named(name, i915_modparams.name, T, perm); \ MODULE_PARM_DESC(name, desc) #define i915_param_named_unsafe(name, T, perm, desc) \ - module_param_named_unsafe(name, i915.name, T, perm); \ + module_param_named_unsafe(name, i915_modparams.name, T, perm); \ MODULE_PARM_DESC(name, desc) -struct i915_params i915 __read_mostly = { +struct i915_params i915_modparams __read_mostly = { .modeset = -1, .panel_ignore_lid = 1, .semaphores = -1, diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index ac844709c97e..a2cbb4782fcd 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -76,7 +76,7 @@ struct i915_params { }; #undef MEMBER -extern struct i915_params i915 __read_mostly; +extern struct i915_params i915_modparams __read_mostly; #endif diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index ce2c08eb9890..da60866b6628 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -631,7 +631,7 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (struct intel_device_info *) ent->driver_data; int err; - if (IS_ALPHA_SUPPORT(intel_info) && !i915.alpha_support) { + if (IS_ALPHA_SUPPORT(intel_info) && !i915_modparams.alpha_support) { DRM_INFO("The driver support for your hardware in this kernel version is alpha quality\n" "See CONFIG_DRM_I915_ALPHA_SUPPORT or i915.alpha_support module parameter\n" "to enable support in this kernel version, or check for kernel updates.\n"); @@ -689,10 +689,10 @@ static int __init i915_init(void) * vga_text_mode_force boot option. */ - if (i915.modeset == 0) + if (i915_modparams.modeset == 0) use_kms = false; - if (vgacon_text_force() && i915.modeset == -1) + if (vgacon_text_force() && i915_modparams.modeset == -1) use_kms = false; if (!use_kms) { diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 902722ab84c9..1383a2995a69 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -1214,7 +1214,7 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream) { struct drm_i915_private *dev_priv = stream->dev_priv; - if (i915.enable_execlists) + if (i915_modparams.enable_execlists) dev_priv->perf.oa.specific_ctx_id = stream->ctx->hw_id; else { struct intel_engine_cs *engine = dev_priv->engine[RCS]; @@ -1260,7 +1260,7 @@ static void oa_put_render_ctx_id(struct i915_perf_stream *stream) { struct drm_i915_private *dev_priv = stream->dev_priv; - if (i915.enable_execlists) { + if (i915_modparams.enable_execlists) { dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID; } else { struct intel_engine_cs *engine = dev_priv->engine[RCS]; @@ -3408,7 +3408,7 @@ void i915_perf_init(struct drm_i915_private *dev_priv) dev_priv->perf.oa.timestamp_frequency = 12500000; dev_priv->perf.oa.oa_formats = hsw_oa_formats; - } else if (i915.enable_execlists) { + } else if (i915_modparams.enable_execlists) { /* Note: that although we could theoretically also support the * legacy ringbuffer mode on BDW (and earlier iterations of * this driver, before upstreaming did this) it didn't seem diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 5949750a35ee..8526da90168c 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -356,7 +356,7 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv, struct drm_display_mode *panel_fixed_mode; int index; - index = i915.vbt_sdvo_panel_type; + index = i915_modparams.vbt_sdvo_panel_type; if (index == -2) { DRM_DEBUG_KMS("Ignore SDVO panel mode from BIOS VBT tables.\n"); return; @@ -675,8 +675,9 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) uint8_t vswing; /* Don't read from VBT if module parameter has valid value*/ - if (i915.edp_vswing) { - dev_priv->vbt.edp.low_vswing = i915.edp_vswing == 1; + if (i915_modparams.edp_vswing) { + dev_priv->vbt.edp.low_vswing = + i915_modparams.edp_vswing == 1; } else { vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; dev_priv->vbt.edp.low_vswing = vswing == 0; diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index a77dd80a97f2..954070255b4d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -712,7 +712,7 @@ intel_crt_detect(struct drm_connector *connector, * broken monitor (without edid) to work behind a broken kvm (that fails * to have the right resistors for HP detection) needs to fix this up. * For now just bail out. */ - if (I915_HAS_HOTPLUG(dev_priv) && !i915.load_detect_test) { + if (I915_HAS_HOTPLUG(dev_priv) && !i915_modparams.load_detect_test) { status = connector_status_disconnected; goto out; } @@ -730,7 +730,7 @@ intel_crt_detect(struct drm_connector *connector, else if (INTEL_GEN(dev_priv) < 4) status = intel_crt_load_detect(crt, to_intel_crtc(connector->state->crtc)->pipe); - else if (i915.load_detect_test) + else if (i915_modparams.load_detect_test) status = connector_status_disconnected; else status = connector_status_unknown; diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 43831b09b47a..fdf9b54b71e9 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -343,7 +343,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) info->num_sprites[pipe] = 1; } - if (i915.disable_display) { + if (i915_modparams.disable_display) { DRM_INFO("Display disabled (module parameter)\n"); info->num_pipes = 0; } else if (info->num_pipes > 0 && diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2e407dc49c19..8a185971798b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3701,7 +3701,7 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv) /* reset doesn't touch the display */ - if (!i915.force_reset_modeset_test && + if (!i915_modparams.force_reset_modeset_test && !gpu_reset_clobbers_display(dev_priv)) return; @@ -3757,7 +3757,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) int ret; /* reset doesn't touch the display */ - if (!i915.force_reset_modeset_test && + if (!i915_modparams.force_reset_modeset_test && !gpu_reset_clobbers_display(dev_priv)) return; @@ -6313,7 +6313,7 @@ static void hsw_compute_ips_config(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - pipe_config->ips_enabled = i915.enable_ips && + pipe_config->ips_enabled = i915_modparams.enable_ips && hsw_crtc_supports_ips(crtc) && pipe_config_supports_ips(dev_priv, pipe_config); } @@ -6494,8 +6494,8 @@ intel_link_compute_m_n(int bits_per_pixel, int nlanes, static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) { - if (i915.panel_use_ssc >= 0) - return i915.panel_use_ssc != 0; + if (i915_modparams.panel_use_ssc >= 0) + return i915_modparams.panel_use_ssc != 0; return dev_priv->vbt.lvds_use_ssc && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); } @@ -12084,7 +12084,7 @@ static int intel_atomic_check(struct drm_device *dev, return ret; } - if (i915.fastboot && + if (i915_modparams.fastboot && intel_pipe_config_compare(dev_priv, to_intel_crtc_state(old_crtc_state), pipe_config, true)) { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1e0bfbe6b4f3..48ed6c1b5a76 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3848,7 +3848,7 @@ intel_dp_can_mst(struct intel_dp *intel_dp) { u8 mstm_cap; - if (!i915.enable_dp_mst) + if (!i915_modparams.enable_dp_mst) return false; if (!intel_dp->can_mst) @@ -3866,7 +3866,7 @@ intel_dp_can_mst(struct intel_dp *intel_dp) static void intel_dp_configure_mst(struct intel_dp *intel_dp) { - if (!i915.enable_dp_mst) + if (!i915_modparams.enable_dp_mst) return; if (!intel_dp->can_mst) diff --git a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c index d2830ba3162e..2bb2ceb9d463 100644 --- a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c @@ -264,7 +264,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector) { struct intel_panel *panel = &intel_connector->panel; - if (!i915.enable_dpcd_backlight) + if (!i915_modparams.enable_dpcd_backlight) return -ENODEV; if (!intel_dp_aux_display_control_capable(intel_connector)) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 307807672896..64358d2f2422 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1902,7 +1902,7 @@ void intel_init_ipc(struct drm_i915_private *dev_priv); void intel_enable_ipc(struct drm_i915_private *dev_priv); static inline int intel_enable_rc6(void) { - return i915.enable_rc6; + return i915_modparams.enable_rc6; } /* intel_sdvo.c */ diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 3d135c3cd380..d755a2ae4223 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -153,7 +153,7 @@ __intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class) case 9: return GEN9_LR_CONTEXT_RENDER_SIZE; case 8: - return i915.enable_execlists ? + return i915_modparams.enable_execlists ? GEN8_LR_CONTEXT_RENDER_SIZE : GEN8_CXT_TOTAL_SIZE; case 7: @@ -301,7 +301,7 @@ int intel_engines_init(struct drm_i915_private *dev_priv) &intel_engine_classes[engine->class]; int (*init)(struct intel_engine_cs *engine); - if (i915.enable_execlists) + if (i915_modparams.enable_execlists) init = class_info->init_execlists; else init = class_info->init_legacy; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 58a772de6672..8e3a05505f49 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -859,7 +859,7 @@ static bool intel_fbc_can_enable(struct drm_i915_private *dev_priv) return false; } - if (!i915.enable_fbc) { + if (!i915_modparams.enable_fbc) { fbc->no_fbc_reason = "disabled per module param or by default"; return false; } @@ -1310,8 +1310,8 @@ void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv) */ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) { - if (i915.enable_fbc >= 0) - return !!i915.enable_fbc; + if (i915_modparams.enable_fbc >= 0) + return !!i915_modparams.enable_fbc; if (!HAS_FBC(dev_priv)) return 0; @@ -1355,8 +1355,9 @@ void intel_fbc_init(struct drm_i915_private *dev_priv) if (need_fbc_vtd_wa(dev_priv)) mkwrite_device_info(dev_priv)->has_fbc = false; - i915.enable_fbc = intel_sanitize_fbc_option(dev_priv); - DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n", i915.enable_fbc); + i915_modparams.enable_fbc = intel_sanitize_fbc_option(dev_priv); + DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n", + i915_modparams.enable_fbc); if (!HAS_FBC(dev_priv)) { fbc->no_fbc_reason = "unsupported by this chipset"; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 8b0ae7fce7f2..c9e25be4db40 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -131,14 +131,14 @@ static void guc_params_init(struct drm_i915_private *dev_priv) params[GUC_CTL_LOG_PARAMS] = guc->log.flags; - if (i915.guc_log_level >= 0) { + if (i915_modparams.guc_log_level >= 0) { params[GUC_CTL_DEBUG] = - i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; + i915_modparams.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; } else params[GUC_CTL_DEBUG] = GUC_LOG_DISABLED; /* If GuC submission is enabled, set up additional parameters here */ - if (i915.enable_guc_submission) { + if (i915_modparams.enable_guc_submission) { u32 ads = guc_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT; u32 pgs = guc_ggtt_offset(dev_priv->guc.stage_desc_pool); u32 ctx_in_16 = GUC_MAX_STAGE_DESCRIPTORS / 16; @@ -368,7 +368,8 @@ int intel_guc_init_hw(struct intel_guc *guc) guc->fw.load_status = INTEL_UC_FIRMWARE_SUCCESS; DRM_INFO("GuC %s (firmware %s [version %u.%u])\n", - i915.enable_guc_submission ? "submission enabled" : "loaded", + i915_modparams.enable_guc_submission ? "submission enabled" : + "loaded", guc->fw.path, guc->fw.major_ver_found, guc->fw.minor_ver_found); @@ -390,8 +391,8 @@ int intel_guc_select_fw(struct intel_guc *guc) guc->fw.load_status = INTEL_UC_FIRMWARE_NONE; guc->fw.type = INTEL_UC_FW_TYPE_GUC; - if (i915.guc_firmware_path) { - guc->fw.path = i915.guc_firmware_path; + if (i915_modparams.guc_firmware_path) { + guc->fw.path = i915_modparams.guc_firmware_path; guc->fw.major_ver_wanted = 0; guc->fw.minor_ver_wanted = 0; } else if (IS_SKYLAKE(dev_priv)) { diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c index 16d3b8719cab..6571d96704ad 100644 --- a/drivers/gpu/drm/i915/intel_guc_log.c +++ b/drivers/gpu/drm/i915/intel_guc_log.c @@ -144,7 +144,7 @@ static int guc_log_relay_file_create(struct intel_guc *guc) struct dentry *log_dir; int ret; - if (i915.guc_log_level < 0) + if (i915_modparams.guc_log_level < 0) return 0; /* For now create the log file in /sys/kernel/debug/dri/0 dir */ @@ -480,7 +480,7 @@ err_runtime: guc_log_runtime_destroy(guc); err: /* logging will remain off */ - i915.guc_log_level = -1; + i915_modparams.guc_log_level = -1; return ret; } @@ -502,7 +502,8 @@ static void guc_flush_logs(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); - if (!i915.enable_guc_submission || (i915.guc_log_level < 0)) + if (!i915_modparams.enable_guc_submission || + (i915_modparams.guc_log_level < 0)) return; /* First disable the interrupts, will be renabled afterwards */ @@ -529,8 +530,8 @@ int intel_guc_log_create(struct intel_guc *guc) GEM_BUG_ON(guc->log.vma); - if (i915.guc_log_level > GUC_LOG_VERBOSITY_MAX) - i915.guc_log_level = GUC_LOG_VERBOSITY_MAX; + if (i915_modparams.guc_log_level > GUC_LOG_VERBOSITY_MAX) + i915_modparams.guc_log_level = GUC_LOG_VERBOSITY_MAX; /* The first page is to save log buffer state. Allocate one * extra page for others in case for overlap */ @@ -555,7 +556,7 @@ int intel_guc_log_create(struct intel_guc *guc) guc->log.vma = vma; - if (i915.guc_log_level >= 0) { + if (i915_modparams.guc_log_level >= 0) { ret = guc_log_runtime_create(guc); if (ret < 0) goto err_vma; @@ -576,7 +577,7 @@ err_vma: i915_vma_unpin_and_release(&guc->log.vma); err: /* logging will be off */ - i915.guc_log_level = -1; + i915_modparams.guc_log_level = -1; return ret; } @@ -600,7 +601,7 @@ int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val) return -EINVAL; /* This combination doesn't make sense & won't have any effect */ - if (!log_param.logging_enabled && (i915.guc_log_level < 0)) + if (!log_param.logging_enabled && (i915_modparams.guc_log_level < 0)) return 0; ret = guc_log_control(guc, log_param.value); @@ -610,7 +611,7 @@ int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val) } if (log_param.logging_enabled) { - i915.guc_log_level = log_param.verbosity; + i915_modparams.guc_log_level = log_param.verbosity; /* If log_level was set as -1 at boot time, then the relay channel file * wouldn't have been created by now and interrupts also would not have @@ -633,7 +634,7 @@ int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val) guc_flush_logs(guc); /* As logging is disabled, update log level to reflect that */ - i915.guc_log_level = -1; + i915_modparams.guc_log_level = -1; } return ret; @@ -641,7 +642,8 @@ int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val) void i915_guc_log_register(struct drm_i915_private *dev_priv) { - if (!i915.enable_guc_submission || i915.guc_log_level < 0) + if (!i915_modparams.enable_guc_submission || + (i915_modparams.guc_log_level < 0)) return; mutex_lock(&dev_priv->drm.struct_mutex); @@ -651,7 +653,7 @@ void i915_guc_log_register(struct drm_i915_private *dev_priv) void i915_guc_log_unregister(struct drm_i915_private *dev_priv) { - if (!i915.enable_guc_submission) + if (!i915_modparams.enable_guc_submission) return; mutex_lock(&dev_priv->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c index c17ed0e62b67..b4a7f31f0214 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c +++ b/drivers/gpu/drm/i915/intel_gvt.c @@ -58,7 +58,7 @@ static bool is_supported_device(struct drm_i915_private *dev_priv) */ void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv) { - if (!i915.enable_gvt) + if (!i915_modparams.enable_gvt) return; if (intel_vgpu_active(dev_priv)) { @@ -73,7 +73,7 @@ void intel_gvt_sanitize_options(struct drm_i915_private *dev_priv) return; bail: - i915.enable_gvt = 0; + i915_modparams.enable_gvt = 0; } /** @@ -90,17 +90,17 @@ int intel_gvt_init(struct drm_i915_private *dev_priv) { int ret; - if (!i915.enable_gvt) { + if (!i915_modparams.enable_gvt) { DRM_DEBUG_DRIVER("GVT-g is disabled by kernel params\n"); return 0; } - if (!i915.enable_execlists) { + if (!i915_modparams.enable_execlists) { DRM_ERROR("i915 GVT-g loading failed due to disabled execlists mode\n"); return -EIO; } - if (i915.enable_guc_submission) { + if (i915_modparams.enable_guc_submission) { DRM_ERROR("i915 GVT-g loading failed due to Graphics virtualization is not yet supported with GuC submission\n"); return -EIO; } @@ -123,7 +123,7 @@ int intel_gvt_init(struct drm_i915_private *dev_priv) return 0; bail: - i915.enable_gvt = 0; + i915_modparams.enable_gvt = 0; return 0; } diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c index d9d87d96fb69..12ac270a5f93 100644 --- a/drivers/gpu/drm/i915/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/intel_hangcheck.c @@ -428,7 +428,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) unsigned int hung = 0, stuck = 0; int busy_count = 0; - if (!i915.enable_hangcheck) + if (!i915_modparams.enable_hangcheck) return; if (!READ_ONCE(dev_priv->gt.awake)) diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index 6145fa0d6773..6e1779ba87a9 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c @@ -155,8 +155,8 @@ void intel_huc_select_fw(struct intel_huc *huc) huc->fw.load_status = INTEL_UC_FIRMWARE_NONE; huc->fw.type = INTEL_UC_FW_TYPE_HUC; - if (i915.huc_firmware_path) { - huc->fw.path = i915.huc_firmware_path; + if (i915_modparams.huc_firmware_path) { + huc->fw.path = i915_modparams.huc_firmware_path; huc->fw.major_ver_wanted = 0; huc->fw.minor_ver_wanted = 0; } else if (IS_SKYLAKE(dev_priv)) { diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 86fed9f1f1ae..955c87999280 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -244,7 +244,7 @@ int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, int enabl if (HAS_LOGICAL_RING_CONTEXTS(dev_priv) && USES_PPGTT(dev_priv) && - i915.use_mmio_flip >= 0) + i915_modparams.use_mmio_flip >= 0) return 1; return 0; @@ -1324,7 +1324,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) engine->csb_head = -1; /* After a GPU reset, we may have requests to replay */ - if (!i915.enable_guc_submission && engine->execlist_first) + if (!i915_modparams.enable_guc_submission && engine->execlist_first) tasklet_schedule(&engine->irq_tasklet); return 0; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a9813aea89d8..a55954a89148 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -880,8 +880,8 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) struct drm_i915_private *dev_priv = to_i915(dev); /* use the module option value if specified */ - if (i915.lvds_channel_mode > 0) - return i915.lvds_channel_mode == 2; + if (i915_modparams.lvds_channel_mode > 0) + return i915_modparams.lvds_channel_mode == 2; /* single channel LVDS is limited to 112 MHz */ if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 98154efcb2f4..1d946240e55f 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -921,7 +921,7 @@ static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv) { struct intel_opregion *opregion = &dev_priv->opregion; const struct firmware *fw = NULL; - const char *name = i915.vbt_firmware; + const char *name = i915_modparams.vbt_firmware; int ret; if (!name || !*name) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3b1c5d783ee7..adc51e452e3e 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -379,13 +379,13 @@ enum drm_connector_status intel_panel_detect(struct drm_i915_private *dev_priv) { /* Assume that the BIOS does not lie through the OpRegion... */ - if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) { + if (!i915_modparams.panel_ignore_lid && dev_priv->opregion.lid_state) { return *dev_priv->opregion.lid_state & 0x1 ? connector_status_connected : connector_status_disconnected; } - switch (i915.panel_ignore_lid) { + switch (i915_modparams.panel_ignore_lid) { case -2: return connector_status_connected; case -1: @@ -465,10 +465,10 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector, WARN_ON(panel->backlight.max == 0); - if (i915.invert_brightness < 0) + if (i915_modparams.invert_brightness < 0) return val; - if (i915.invert_brightness > 0 || + if (i915_modparams.invert_brightness > 0 || dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { return panel->backlight.max - val + panel->backlight.min; } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index adfeb7bb8874..c66af09e27a7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7825,7 +7825,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) * RPM depends on RC6 to save restore the GT HW context, so make RC6 a * requirement. */ - if (!i915.enable_rc6) { + if (!i915_modparams.enable_rc6) { DRM_INFO("RC6 disabled, disabling runtime PM support\n"); intel_runtime_pm_get(dev_priv); } @@ -7882,7 +7882,7 @@ void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) if (IS_VALLEYVIEW(dev_priv)) valleyview_cleanup_gt_powersave(dev_priv); - if (!i915.enable_rc6) + if (!i915_modparams.enable_rc6) intel_runtime_pm_put(dev_priv); } @@ -8004,7 +8004,7 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work) if (IS_ERR(req)) goto unlock; - if (!i915.enable_execlists && i915_switch_context(req) == 0) + if (!i915_modparams.enable_execlists && i915_switch_context(req) == 0) rcs->init_context(req); /* Mark the device busy, calling intel_enable_gt_powersave() */ diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index acb50945bfa8..0a17d1f3ca77 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -396,7 +396,7 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp) return false; } - if (!i915.enable_psr) { + if (!i915_modparams.enable_psr) { DRM_DEBUG_KMS("PSR disable by flag\n"); return false; } @@ -943,8 +943,8 @@ void intel_psr_init(struct drm_i915_private *dev_priv) HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE; /* Per platform default: all disabled. */ - if (i915.enable_psr == -1) - i915.enable_psr = 0; + if (i915_modparams.enable_psr == -1) + i915_modparams.enable_psr = 0; /* Set link_standby x link_off defaults */ if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) @@ -958,11 +958,11 @@ void intel_psr_init(struct drm_i915_private *dev_priv) dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link; /* Override link_standby x link_off defaults */ - if (i915.enable_psr == 2 && !dev_priv->psr.link_standby) { + if (i915_modparams.enable_psr == 2 && !dev_priv->psr.link_standby) { DRM_DEBUG_KMS("PSR: Forcing link standby\n"); dev_priv->psr.link_standby = true; } - if (i915.enable_psr == 3 && dev_priv->psr.link_standby) { + if (i915_modparams.enable_psr == 3 && dev_priv->psr.link_standby) { DRM_DEBUG_KMS("PSR: Forcing main link off\n"); dev_priv->psr.link_standby = false; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 85e64a45d0bf..05c08b0bc172 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1882,7 +1882,7 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, struct drm_i915_gem_object *obj; int ret, i; - if (!i915.semaphores) + if (!i915_modparams.semaphores) return; if (INTEL_GEN(dev_priv) >= 8 && !dev_priv->semaphore) { @@ -1982,7 +1982,7 @@ err_obj: i915_gem_object_put(obj); err: DRM_DEBUG_DRIVER("Failed to allocate space for semaphores, disabling\n"); - i915.semaphores = 0; + i915_modparams.semaphores = 0; } static void intel_ring_init_irq(struct drm_i915_private *dev_priv, @@ -2039,7 +2039,7 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, engine->emit_breadcrumb = i9xx_emit_breadcrumb; engine->emit_breadcrumb_sz = i9xx_emit_breadcrumb_sz; - if (i915.semaphores) { + if (i915_modparams.semaphores) { int num_rings; engine->emit_breadcrumb = gen6_sema_emit_breadcrumb; @@ -2083,7 +2083,7 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine) engine->emit_breadcrumb = gen8_render_emit_breadcrumb; engine->emit_breadcrumb_sz = gen8_render_emit_breadcrumb_sz; engine->emit_flush = gen8_render_ring_flush; - if (i915.semaphores) { + if (i915_modparams.semaphores) { int num_rings; engine->semaphore.signal = gen8_rcs_signal; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index a3bfb9f27e7a..7933d1bc6a1c 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -2413,7 +2413,7 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv, mask = 0; } - if (!i915.disable_power_well) + if (!i915_modparams.disable_power_well) max_dc = 0; if (enable_dc >= 0 && enable_dc <= max_dc) { @@ -2471,10 +2471,11 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) { struct i915_power_domains *power_domains = &dev_priv->power_domains; - i915.disable_power_well = sanitize_disable_power_well_option(dev_priv, - i915.disable_power_well); - dev_priv->csr.allowed_dc_mask = get_allowed_dc_mask(dev_priv, - i915.enable_dc); + i915_modparams.disable_power_well = + sanitize_disable_power_well_option(dev_priv, + i915_modparams.disable_power_well); + dev_priv->csr.allowed_dc_mask = + get_allowed_dc_mask(dev_priv, i915_modparams.enable_dc); BUILD_BUG_ON(POWER_DOMAIN_NUM > 64); @@ -2535,7 +2536,7 @@ void intel_power_domains_fini(struct drm_i915_private *dev_priv) intel_display_set_init_power(dev_priv, true); /* Remove the refcount we took to keep power well support disabled. */ - if (!i915.disable_power_well) + if (!i915_modparams.disable_power_well) intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); /* @@ -2995,7 +2996,7 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) /* For now, we need the power well to be always enabled. */ intel_display_set_init_power(dev_priv, true); /* Disable power support if the user asked so. */ - if (!i915.disable_power_well) + if (!i915_modparams.disable_power_well) intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); intel_power_domains_sync_hw(dev_priv); power_domains->initializing = false; @@ -3014,7 +3015,7 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv) * Even if power well support was disabled we still want to disable * power wells while we are system suspended. */ - if (!i915.disable_power_well) + if (!i915_modparams.disable_power_well) intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); if (IS_CANNONLAKE(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 0178ba42a0e5..901854007664 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -63,35 +63,35 @@ static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv) void intel_uc_sanitize_options(struct drm_i915_private *dev_priv) { if (!HAS_GUC(dev_priv)) { - if (i915.enable_guc_loading > 0 || - i915.enable_guc_submission > 0) + if (i915_modparams.enable_guc_loading > 0 || + i915_modparams.enable_guc_submission > 0) DRM_INFO("Ignoring GuC options, no hardware\n"); - i915.enable_guc_loading = 0; - i915.enable_guc_submission = 0; + i915_modparams.enable_guc_loading = 0; + i915_modparams.enable_guc_submission = 0; return; } /* A negative value means "use platform default" */ - if (i915.enable_guc_loading < 0) - i915.enable_guc_loading = HAS_GUC_UCODE(dev_priv); + if (i915_modparams.enable_guc_loading < 0) + i915_modparams.enable_guc_loading = HAS_GUC_UCODE(dev_priv); /* Verify firmware version */ - if (i915.enable_guc_loading) { + if (i915_modparams.enable_guc_loading) { if (HAS_HUC_UCODE(dev_priv)) intel_huc_select_fw(&dev_priv->huc); if (intel_guc_select_fw(&dev_priv->guc)) - i915.enable_guc_loading = 0; + i915_modparams.enable_guc_loading = 0; } /* Can't enable guc submission without guc loaded */ - if (!i915.enable_guc_loading) - i915.enable_guc_submission = 0; + if (!i915_modparams.enable_guc_loading) + i915_modparams.enable_guc_submission = 0; /* A negative value means "use platform default" */ - if (i915.enable_guc_submission < 0) - i915.enable_guc_submission = HAS_GUC_SCHED(dev_priv); + if (i915_modparams.enable_guc_submission < 0) + i915_modparams.enable_guc_submission = HAS_GUC_SCHED(dev_priv); } static void gen8_guc_raise_irq(struct intel_guc *guc) @@ -290,7 +290,7 @@ static void guc_init_send_regs(struct intel_guc *guc) static void guc_capture_load_err_log(struct intel_guc *guc) { - if (!guc->log.vma || i915.guc_log_level < 0) + if (!guc->log.vma || i915_modparams.guc_log_level < 0) return; if (!guc->load_err_log) @@ -333,7 +333,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) struct intel_guc *guc = &dev_priv->guc; int ret, attempts; - if (!i915.enable_guc_loading) + if (!i915_modparams.enable_guc_loading) return 0; guc_disable_communication(guc); @@ -342,7 +342,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) /* We need to notify the guc whenever we change the GGTT */ i915_ggtt_enable_guc(dev_priv); - if (i915.enable_guc_submission) { + if (i915_modparams.enable_guc_submission) { /* * This is stuff we need to have available at fw load time * if we are planning to enable submission later @@ -391,8 +391,8 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) goto err_log_capture; intel_guc_auth_huc(dev_priv); - if (i915.enable_guc_submission) { - if (i915.guc_log_level >= 0) + if (i915_modparams.enable_guc_submission) { + if (i915_modparams.guc_log_level >= 0) gen9_enable_guc_interrupts(dev_priv); ret = i915_guc_submission_enable(dev_priv); @@ -417,23 +417,24 @@ err_interrupts: err_log_capture: guc_capture_load_err_log(guc); err_submission: - if (i915.enable_guc_submission) + if (i915_modparams.enable_guc_submission) i915_guc_submission_fini(dev_priv); err_guc: i915_ggtt_disable_guc(dev_priv); DRM_ERROR("GuC init failed\n"); - if (i915.enable_guc_loading > 1 || i915.enable_guc_submission > 1) + if (i915_modparams.enable_guc_loading > 1 || + i915_modparams.enable_guc_submission > 1) ret = -EIO; else ret = 0; - if (i915.enable_guc_submission) { - i915.enable_guc_submission = 0; + if (i915_modparams.enable_guc_submission) { + i915_modparams.enable_guc_submission = 0; DRM_NOTE("Falling back from GuC submission to execlist mode\n"); } - i915.enable_guc_loading = 0; + i915_modparams.enable_guc_loading = 0; DRM_NOTE("GuC firmware loading disabled\n"); return ret; @@ -443,15 +444,15 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv) { guc_free_load_err_log(&dev_priv->guc); - if (!i915.enable_guc_loading) + if (!i915_modparams.enable_guc_loading) return; - if (i915.enable_guc_submission) + if (i915_modparams.enable_guc_submission) i915_guc_submission_disable(dev_priv); guc_disable_communication(&dev_priv->guc); - if (i915.enable_guc_submission) { + if (i915_modparams.enable_guc_submission) { gen9_disable_guc_interrupts(dev_priv); i915_guc_submission_fini(dev_priv); } diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index fdd7f93acb4f..b3c3f94fc7e4 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -436,7 +436,8 @@ void intel_uncore_resume_early(struct drm_i915_private *dev_priv) void intel_uncore_sanitize(struct drm_i915_private *dev_priv) { - i915.enable_rc6 = sanitize_rc6_option(dev_priv, i915.enable_rc6); + i915_modparams.enable_rc6 = + sanitize_rc6_option(dev_priv, i915_modparams.enable_rc6); /* BIOS often leaves RC6 enabled, but disable it for hw init */ intel_sanitize_gt_powersave(dev_priv); @@ -507,10 +508,10 @@ void intel_uncore_forcewake_user_get(struct drm_i915_private *dev_priv) dev_priv->uncore.user_forcewake.saved_mmio_check = dev_priv->uncore.unclaimed_mmio_check; dev_priv->uncore.user_forcewake.saved_mmio_debug = - i915.mmio_debug; + i915_modparams.mmio_debug; dev_priv->uncore.unclaimed_mmio_check = 0; - i915.mmio_debug = 0; + i915_modparams.mmio_debug = 0; } spin_unlock_irq(&dev_priv->uncore.lock); } @@ -532,7 +533,7 @@ void intel_uncore_forcewake_user_put(struct drm_i915_private *dev_priv) dev_priv->uncore.unclaimed_mmio_check = dev_priv->uncore.user_forcewake.saved_mmio_check; - i915.mmio_debug = + i915_modparams.mmio_debug = dev_priv->uncore.user_forcewake.saved_mmio_debug; intel_uncore_forcewake_put__locked(dev_priv, FORCEWAKE_ALL); @@ -841,7 +842,8 @@ __unclaimed_reg_debug(struct drm_i915_private *dev_priv, "Unclaimed %s register 0x%x\n", read ? "read from" : "write to", i915_mmio_reg_offset(reg))) - i915.mmio_debug--; /* Only report the first N failures */ + /* Only report the first N failures */ + i915_modparams.mmio_debug--; } static inline void @@ -850,7 +852,7 @@ unclaimed_reg_debug(struct drm_i915_private *dev_priv, const bool read, const bool before) { - if (likely(!i915.mmio_debug)) + if (likely(!i915_modparams.mmio_debug)) return; __unclaimed_reg_debug(dev_priv, reg, read, before); @@ -1703,7 +1705,7 @@ typedef int (*reset_func)(struct drm_i915_private *, unsigned engine_mask); static reset_func intel_get_gpu_reset(struct drm_i915_private *dev_priv) { - if (!i915.reset) + if (!i915_modparams.reset) return NULL; if (INTEL_INFO(dev_priv)->gen >= 8) @@ -1777,7 +1779,7 @@ bool intel_has_reset_engine(struct drm_i915_private *dev_priv) { return (dev_priv->info.has_reset_engine && !dev_priv->guc.execbuf_client && - i915.reset >= 2); + i915_modparams.reset >= 2); } int intel_guc_reset(struct drm_i915_private *dev_priv) @@ -1802,7 +1804,7 @@ bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv) bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv) { - if (unlikely(i915.mmio_debug || + if (unlikely(i915_modparams.mmio_debug || dev_priv->uncore.unclaimed_mmio_check <= 0)) return false; @@ -1810,7 +1812,7 @@ intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv) DRM_DEBUG("Unclaimed register detected, " "enabling oneshot unclaimed register reporting. " "Please use i915.mmio_debug=N for more information.\n"); - i915.mmio_debug++; + i915_modparams.mmio_debug++; dev_priv->uncore.unclaimed_mmio_check--; return true; } -- cgit v1.2.3 From 7fd0b1a2593647aba4538196dd80314fd134877b Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 21 Sep 2017 16:19:49 -0700 Subject: drm/i915/cnl: Add Gen10 LRC size The total size of the context has decreased with the removal of the URB_ATOMIC section. BSpec indicates 16750 DWORDs (17 pages), plus one page for PPHWSP, and I'm throwing an extra page for precaution. Signed-off-by: Oscar Mateo Cc: Rodrigo Vivi Cc: Daniele Ceraolo Spurio Cc: Ben Widawsky Acked-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/1506035989-14295-1-git-send-email-oscar.mateo@intel.com --- drivers/gpu/drm/i915/intel_engine_cs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index d755a2ae4223..020e4c6c0192 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -39,6 +39,7 @@ #define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE) #define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE) +#define GEN10_LR_CONTEXT_RENDER_SIZE (19 * PAGE_SIZE) #define GEN8_LR_CONTEXT_OTHER_SIZE ( 2 * PAGE_SIZE) @@ -150,6 +151,7 @@ __intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class) default: MISSING_CASE(INTEL_GEN(dev_priv)); case 10: + return GEN10_LR_CONTEXT_RENDER_SIZE; case 9: return GEN9_LR_CONTEXT_RENDER_SIZE; case 8: -- cgit v1.2.3 From 786de92b3cb26012d3d0f00ee37adf14527f35c4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 22 Sep 2017 11:56:49 -0400 Subject: USB: uas: fix bug in handling of alternate settings The uas driver has a subtle bug in the way it handles alternate settings. The uas_find_uas_alt_setting() routine returns an altsetting value (the bAlternateSetting number in the descriptor), but uas_use_uas_driver() then treats that value as an index to the intf->altsetting array, which it isn't. Normally this doesn't cause any problems because the various alternate settings have bAlternateSetting values 0, 1, 2, ..., so the value is equal to the index in the array. But this is not guaranteed, and Andrey Konovalov used the syzkaller fuzzer with KASAN to get a slab-out-of-bounds error by violating this assumption. This patch fixes the bug by making uas_find_uas_alt_setting() return a pointer to the altsetting entry rather than either the value or the index. Pointers are less subject to misinterpretation. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov CC: Oliver Neukum CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas-detect.h | 15 ++++++++------- drivers/usb/storage/uas.c | 10 +++++----- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index f58caa9e6a27..a155cd02bce2 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -9,7 +9,8 @@ static int uas_is_interface(struct usb_host_interface *intf) intf->desc.bInterfaceProtocol == USB_PR_UAS); } -static int uas_find_uas_alt_setting(struct usb_interface *intf) +static struct usb_host_interface *uas_find_uas_alt_setting( + struct usb_interface *intf) { int i; @@ -17,10 +18,10 @@ static int uas_find_uas_alt_setting(struct usb_interface *intf) struct usb_host_interface *alt = &intf->altsetting[i]; if (uas_is_interface(alt)) - return alt->desc.bAlternateSetting; + return alt; } - return -ENODEV; + return NULL; } static int uas_find_endpoints(struct usb_host_interface *alt, @@ -58,14 +59,14 @@ static int uas_use_uas_driver(struct usb_interface *intf, struct usb_device *udev = interface_to_usbdev(intf); struct usb_hcd *hcd = bus_to_hcd(udev->bus); unsigned long flags = id->driver_info; - int r, alt; - + struct usb_host_interface *alt; + int r; alt = uas_find_uas_alt_setting(intf); - if (alt < 0) + if (!alt) return 0; - r = uas_find_endpoints(&intf->altsetting[alt], eps); + r = uas_find_endpoints(alt, eps); if (r < 0) return 0; diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index cfb1e3bbd434..63cf981ed81c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -873,14 +873,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids); static int uas_switch_interface(struct usb_device *udev, struct usb_interface *intf) { - int alt; + struct usb_host_interface *alt; alt = uas_find_uas_alt_setting(intf); - if (alt < 0) - return alt; + if (!alt) + return -ENODEV; - return usb_set_interface(udev, - intf->altsetting[0].desc.bInterfaceNumber, alt); + return usb_set_interface(udev, alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); } static int uas_configure_endpoints(struct uas_dev_info *devinfo) -- cgit v1.2.3 From 6e76c01e71551cb221c1f3deacb9dcd9a7346784 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 21 Sep 2017 16:12:01 -0400 Subject: USB: gadgetfs: fix copy_to_user while holding spinlock The gadgetfs driver as a long-outstanding FIXME, regarding a call of copy_to_user() made while holding a spinlock. This patch fixes the issue by dropping the spinlock and using the dev->udc_usage mechanism introduced by another recent patch to guard against status changes while the lock isn't held. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov CC: Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/inode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 684900fcfe24..956b3dc7c3a4 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -983,11 +983,14 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) retval = -EIO; else { len = min (len, (size_t)dev->req->actual); -// FIXME don't call this with the spinlock held ... + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); if (copy_to_user (buf, dev->req->buf, len)) retval = -EFAULT; else retval = len; + spin_lock_irq(&dev->lock); + --dev->udc_usage; clean_req (dev->gadget->ep0, dev->req); /* NOTE userspace can't yet choose to stall */ } -- cgit v1.2.3 From 520b72fc64debf8a86c3853b8e486aa5982188f0 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 21 Sep 2017 13:23:58 -0400 Subject: USB: gadgetfs: Fix crash caused by inadequate synchronization The gadgetfs driver (drivers/usb/gadget/legacy/inode.c) was written before the UDC and composite frameworks were adopted; it is a legacy driver. As such, it expects that once bound to a UDC controller, it will not be unbound until it unregisters itself. However, the UDC framework does unbind function drivers while they are still registered. When this happens, it can cause the gadgetfs driver to misbehave or crash. For example, userspace can cause a crash by opening the device file and doing an ioctl call before setting up a configuration (found by Andrey Konovalov using the syzkaller fuzzer). This patch adds checks and synchronization to prevent these bad behaviors. It adds a udc_usage counter that the driver increments at times when it is using a gadget interface without holding the private spinlock. The unbind routine waits for this counter to go to 0 before returning, thereby ensuring that the UDC is no longer in use. The patch also adds a check in the dev_ioctl() routine to make sure the driver is bound to a UDC before dereferencing the gadget pointer, and it makes destroy_ep_files() synchronize with the endpoint I/O routines, to prevent the user from accessing an endpoint data structure after it has been removed. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov CC: Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/inode.c | 41 ++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 956b3dc7c3a4..5c28bee327e1 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -28,7 +28,7 @@ #include #include #include - +#include #include #include @@ -116,6 +116,7 @@ enum ep0_state { struct dev_data { spinlock_t lock; refcount_t count; + int udc_usage; enum ep0_state state; /* P: lock */ struct usb_gadgetfs_event event [N_EVENT]; unsigned ev_next; @@ -513,9 +514,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) INIT_WORK(&priv->work, ep_user_copy_worker); schedule_work(&priv->work); } - spin_unlock(&epdata->dev->lock); usb_ep_free_request(ep, req); + spin_unlock(&epdata->dev->lock); put_ep(epdata); } @@ -939,9 +940,11 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) struct usb_request *req = dev->req; if ((retval = setup_req (ep, req, 0)) == 0) { + ++dev->udc_usage; spin_unlock_irq (&dev->lock); retval = usb_ep_queue (ep, req, GFP_KERNEL); spin_lock_irq (&dev->lock); + --dev->udc_usage; } dev->state = STATE_DEV_CONNECTED; @@ -1134,6 +1137,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) retval = setup_req (dev->gadget->ep0, dev->req, len); if (retval == 0) { dev->state = STATE_DEV_CONNECTED; + ++dev->udc_usage; spin_unlock_irq (&dev->lock); if (copy_from_user (dev->req->buf, buf, len)) retval = -EFAULT; @@ -1145,6 +1149,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) GFP_KERNEL); } spin_lock_irq(&dev->lock); + --dev->udc_usage; if (retval < 0) { clean_req (dev->gadget->ep0, dev->req); } else @@ -1246,9 +1251,21 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) struct usb_gadget *gadget = dev->gadget; long ret = -ENOTTY; - if (gadget->ops->ioctl) + spin_lock_irq(&dev->lock); + if (dev->state == STATE_DEV_OPENED || + dev->state == STATE_DEV_UNBOUND) { + /* Not bound to a UDC */ + } else if (gadget->ops->ioctl) { + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); + ret = gadget->ops->ioctl (gadget, code, value); + spin_lock_irq(&dev->lock); + --dev->udc_usage; + } + spin_unlock_irq(&dev->lock); + return ret; } @@ -1466,10 +1483,12 @@ delegate: if (value < 0) break; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, dev->req, GFP_KERNEL); spin_lock (&dev->lock); + --dev->udc_usage; if (value < 0) { clean_req (gadget->ep0, dev->req); break; @@ -1493,8 +1512,12 @@ delegate: req->length = value; req->zero = value < w_length; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL); + spin_lock(&dev->lock); + --dev->udc_usage; + spin_unlock(&dev->lock); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); req->status = 0; @@ -1521,21 +1544,24 @@ static void destroy_ep_files (struct dev_data *dev) /* break link to FS */ ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles); list_del_init (&ep->epfiles); + spin_unlock_irq (&dev->lock); + dentry = ep->dentry; ep->dentry = NULL; parent = d_inode(dentry->d_parent); /* break link to controller */ + mutex_lock(&ep->lock); if (ep->state == STATE_EP_ENABLED) (void) usb_ep_disable (ep->ep); ep->state = STATE_EP_UNBOUND; usb_ep_free_request (ep->ep, ep->req); ep->ep = NULL; + mutex_unlock(&ep->lock); + wake_up (&ep->wait); put_ep (ep); - spin_unlock_irq (&dev->lock); - /* break link to dcache */ inode_lock(parent); d_delete (dentry); @@ -1606,6 +1632,11 @@ gadgetfs_unbind (struct usb_gadget *gadget) spin_lock_irq (&dev->lock); dev->state = STATE_DEV_UNBOUND; + while (dev->udc_usage > 0) { + spin_unlock_irq(&dev->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dev->lock); + } spin_unlock_irq (&dev->lock); destroy_ep_files (dev); -- cgit v1.2.3 From 1fbbb78f25d1291274f320462bf6908906f538db Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 21 Sep 2017 13:22:00 -0400 Subject: USB: g_mass_storage: Fix deadlock when driver is unbound As a holdover from the old g_file_storage gadget, the g_mass_storage legacy gadget driver attempts to unregister itself when its main operating thread terminates (if it hasn't been unregistered already). This is not strictly necessary; it was never more than an attempt to have the gadget fail cleanly if something went wrong and the main thread was killed. However, now that the UDC core manages gadget drivers independently of UDC drivers, this scheme doesn't work any more. A simple test: modprobe dummy-hcd modprobe g-mass-storage file=... rmmod dummy-hcd ends up in a deadlock with the following backtrace: sysrq: SysRq : Show Blocked State task PC stack pid father file-storage D 0 1130 2 0x00000000 Call Trace: __schedule+0x53e/0x58c schedule+0x6e/0x77 schedule_preempt_disabled+0xd/0xf __mutex_lock.isra.1+0x129/0x224 ? _raw_spin_unlock_irqrestore+0x12/0x14 __mutex_lock_slowpath+0x12/0x14 mutex_lock+0x28/0x2b usb_gadget_unregister_driver+0x29/0x9b [udc_core] usb_composite_unregister+0x10/0x12 [libcomposite] msg_cleanup+0x1d/0x20 [g_mass_storage] msg_thread_exits+0xd/0xdd7 [g_mass_storage] fsg_main_thread+0x1395/0x13d6 [usb_f_mass_storage] ? __schedule+0x573/0x58c kthread+0xd9/0xdb ? do_set_interface+0x25c/0x25c [usb_f_mass_storage] ? init_completion+0x1e/0x1e ret_from_fork+0x19/0x24 rmmod D 0 1155 683 0x00000000 Call Trace: __schedule+0x53e/0x58c schedule+0x6e/0x77 schedule_timeout+0x26/0xbc ? __schedule+0x573/0x58c do_wait_for_common+0xb3/0x128 ? usleep_range+0x81/0x81 ? wake_up_q+0x3f/0x3f wait_for_common+0x2e/0x45 wait_for_completion+0x17/0x19 fsg_common_put+0x34/0x81 [usb_f_mass_storage] fsg_free_inst+0x13/0x1e [usb_f_mass_storage] usb_put_function_instance+0x1a/0x25 [libcomposite] msg_unbind+0x2a/0x42 [g_mass_storage] __composite_unbind+0x4a/0x6f [libcomposite] composite_unbind+0x12/0x14 [libcomposite] usb_gadget_remove_driver+0x4f/0x77 [udc_core] usb_del_gadget_udc+0x52/0xcc [udc_core] dummy_udc_remove+0x27/0x2c [dummy_hcd] platform_drv_remove+0x1d/0x31 device_release_driver_internal+0xe9/0x16d device_release_driver+0x11/0x13 bus_remove_device+0xd2/0xe2 device_del+0x19f/0x221 ? selinux_capable+0x22/0x27 platform_device_del+0x21/0x63 platform_device_unregister+0x10/0x1a cleanup+0x20/0x817 [dummy_hcd] SyS_delete_module+0x10c/0x197 ? ____fput+0xd/0xf ? task_work_run+0x55/0x62 ? prepare_exit_to_usermode+0x65/0x75 do_fast_syscall_32+0x86/0xc3 entry_SYSENTER_32+0x4e/0x7c What happens is that removing the dummy-hcd driver causes the UDC core to unbind the gadget driver, which it does while holding the udc_lock mutex. The unbind routine in g_mass_storage tells the main thread to exit and waits for it to terminate. But as mentioned above, when the main thread exits it tries to unregister the mass-storage function driver. Via the composite framework this ends up calling usb_gadget_unregister_driver(), which tries to acquire the udc_lock mutex. The result is deadlock. The simplest way to fix the problem is not to be so clever: The main thread doesn't have to unregister the function driver. The side effects won't be so terrible; if the gadget is still attached to a USB host when the main thread is killed, it will appear to the host as though the gadget's firmware has crashed -- a reasonably accurate interpretation, and an all-too-common occurrence for USB mass-storage devices. In fact, the code to unregister the driver when the main thread exits is specific to g-mass-storage; it is not used when f-mass-storage is included as a function in a larger composite device. Therefore the entire mechanism responsible for this (the fsg_operations structure with its ->thread_exits method, the fsg_common_set_ops() routine, and the msg_thread_exits() callback routine) can all be eliminated. Even the msg_registered bitflag can be removed, because now the driver is unregistered in only one place rather than in two places. Signed-off-by: Alan Stern CC: Acked-by: Felipe Balbi Acked-by: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_mass_storage.c | 27 +++++++-------------------- drivers/usb/gadget/function/f_mass_storage.h | 14 -------------- drivers/usb/gadget/legacy/mass_storage.c | 26 +++----------------------- 3 files changed, 10 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index d6bd0244b008..5153e29870c3 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -307,8 +307,6 @@ struct fsg_common { struct completion thread_notifier; struct task_struct *thread_task; - /* Callback functions. */ - const struct fsg_operations *ops; /* Gadget's private data. */ void *private_data; @@ -2438,6 +2436,7 @@ static void handle_exception(struct fsg_common *common) static int fsg_main_thread(void *common_) { struct fsg_common *common = common_; + int i; /* * Allow the thread to be killed by a signal, but set the signal mask @@ -2476,21 +2475,16 @@ static int fsg_main_thread(void *common_) common->thread_task = NULL; spin_unlock_irq(&common->lock); - if (!common->ops || !common->ops->thread_exits - || common->ops->thread_exits(common) < 0) { - int i; + /* Eject media from all LUNs */ - down_write(&common->filesem); - for (i = 0; i < ARRAY_SIZE(common->luns); i++) { - struct fsg_lun *curlun = common->luns[i]; - if (!curlun || !fsg_lun_is_open(curlun)) - continue; + down_write(&common->filesem); + for (i = 0; i < ARRAY_SIZE(common->luns); i++) { + struct fsg_lun *curlun = common->luns[i]; + if (curlun && fsg_lun_is_open(curlun)) fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } - up_write(&common->filesem); } + up_write(&common->filesem); /* Let fsg_unbind() know the thread has exited */ complete_and_exit(&common->thread_notifier, 0); @@ -2681,13 +2675,6 @@ void fsg_common_remove_luns(struct fsg_common *common) } EXPORT_SYMBOL_GPL(fsg_common_remove_luns); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops) -{ - common->ops = ops; -} -EXPORT_SYMBOL_GPL(fsg_common_set_ops); - void fsg_common_free_buffers(struct fsg_common *common) { _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h index d3902313b8ac..dc05ca0c4359 100644 --- a/drivers/usb/gadget/function/f_mass_storage.h +++ b/drivers/usb/gadget/function/f_mass_storage.h @@ -60,17 +60,6 @@ struct fsg_module_parameters { struct fsg_common; /* FSF callback functions */ -struct fsg_operations { - /* - * Callback function to call when thread exits. If no - * callback is set or it returns value lower then zero MSF - * will force eject all LUNs it operates on (including those - * marked as non-removable or with prevent_medium_removal flag - * set). - */ - int (*thread_exits)(struct fsg_common *common); -}; - struct fsg_lun_opts { struct config_group group; struct fsg_lun *lun; @@ -142,9 +131,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun); void fsg_common_remove_luns(struct fsg_common *common); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops); - int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, unsigned int id, const char *name, const char **name_pfx); diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index e99ab57ee3e5..fcba59782f26 100644 --- a/drivers/usb/gadget/legacy/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c @@ -107,15 +107,6 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); -static unsigned long msg_registered; -static void msg_cleanup(void); - -static int msg_thread_exits(struct fsg_common *common) -{ - msg_cleanup(); - return 0; -} - static int msg_do_config(struct usb_configuration *c) { struct fsg_opts *opts; @@ -154,9 +145,6 @@ static struct usb_configuration msg_config_driver = { static int msg_bind(struct usb_composite_dev *cdev) { - static const struct fsg_operations ops = { - .thread_exits = msg_thread_exits, - }; struct fsg_opts *opts; struct fsg_config config; int status; @@ -173,8 +161,6 @@ static int msg_bind(struct usb_composite_dev *cdev) if (status) goto fail; - fsg_common_set_ops(opts->common, &ops); - status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); if (status) goto fail_set_cdev; @@ -256,18 +242,12 @@ MODULE_LICENSE("GPL"); static int __init msg_init(void) { - int ret; - - ret = usb_composite_probe(&msg_driver); - set_bit(0, &msg_registered); - - return ret; + return usb_composite_probe(&msg_driver); } module_init(msg_init); -static void msg_cleanup(void) +static void __exit msg_cleanup(void) { - if (test_and_clear_bit(0, &msg_registered)) - usb_composite_unregister(&msg_driver); + usb_composite_unregister(&msg_driver); } module_exit(msg_cleanup); -- cgit v1.2.3 From b2f2f0fc69056a495391cab792394965973aabf8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 22 Sep 2017 13:03:33 +0100 Subject: drm/i915: Make i915_spin_request() static No users now outside of i915_wait_request(), so we can make it private to i915_gem_request.c, and assume the caller knows the seqno. In the process, also remove i915_gem_request_started() as that was only ever used by i915_spin_request(). Signed-off-by: Chris Wilson Cc: Michal Winiarski Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170922120333.25535-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_request.c | 27 +++++++++++++++++++------ drivers/gpu/drm/i915/i915_gem_request.h | 35 --------------------------------- 2 files changed, 21 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 289fb08acaf5..4eb1a76731b2 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -1021,12 +1021,28 @@ static bool busywait_stop(unsigned long timeout, unsigned int cpu) return this_cpu != cpu; } -bool __i915_spin_request(const struct drm_i915_gem_request *req, - u32 seqno, int state, unsigned long timeout_us) +static bool __i915_spin_request(const struct drm_i915_gem_request *req, + u32 seqno, int state, unsigned long timeout_us) { struct intel_engine_cs *engine = req->engine; unsigned int irq, cpu; + GEM_BUG_ON(!seqno); + + /* + * Only wait for the request if we know it is likely to complete. + * + * We don't track the timestamps around requests, nor the average + * request length, so we do not have a good indicator that this + * request will complete within the timeout. What we do know is the + * order in which requests are executed by the engine and so we can + * tell if the request has started. If the request hasn't started yet, + * it is a fair assumption that it will not complete within our + * relatively short timeout. + */ + if (!i915_seqno_passed(intel_engine_get_seqno(engine), seqno - 1)) + return false; + /* When waiting for high frequency requests, e.g. during synchronous * rendering split between the CPU and GPU, the finite amount of time * required to set up the irq and wait upon it limits the response @@ -1040,8 +1056,7 @@ bool __i915_spin_request(const struct drm_i915_gem_request *req, irq = atomic_read(&engine->irq_count); timeout_us += local_clock_us(&cpu); do { - if (i915_seqno_passed(intel_engine_get_seqno(req->engine), - seqno)) + if (i915_seqno_passed(intel_engine_get_seqno(engine), seqno)) return seqno == i915_gem_request_global_seqno(req); /* Seqno are meant to be ordered *before* the interrupt. If @@ -1153,7 +1168,7 @@ restart: GEM_BUG_ON(!i915_sw_fence_signaled(&req->submit)); /* Optimistic short spin before touching IRQs */ - if (i915_spin_request(req, state, 5)) + if (__i915_spin_request(req, wait.seqno, state, 5)) goto complete; set_current_state(state); @@ -1210,7 +1225,7 @@ wakeup: continue; /* Only spin if we know the GPU is processing this request */ - if (i915_spin_request(req, state, 2)) + if (__i915_spin_request(req, wait.seqno, state, 2)) break; if (!intel_wait_check_request(&wait, req)) { diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h index 49a4c8994ff0..96eb52471dad 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.h +++ b/drivers/gpu/drm/i915/i915_gem_request.h @@ -312,26 +312,6 @@ static inline bool i915_seqno_passed(u32 seq1, u32 seq2) return (s32)(seq1 - seq2) >= 0; } -static inline bool -__i915_gem_request_started(const struct drm_i915_gem_request *req, u32 seqno) -{ - GEM_BUG_ON(!seqno); - return i915_seqno_passed(intel_engine_get_seqno(req->engine), - seqno - 1); -} - -static inline bool -i915_gem_request_started(const struct drm_i915_gem_request *req) -{ - u32 seqno; - - seqno = i915_gem_request_global_seqno(req); - if (!seqno) - return false; - - return __i915_gem_request_started(req, seqno); -} - static inline bool __i915_gem_request_completed(const struct drm_i915_gem_request *req, u32 seqno) { @@ -352,21 +332,6 @@ i915_gem_request_completed(const struct drm_i915_gem_request *req) return __i915_gem_request_completed(req, seqno); } -bool __i915_spin_request(const struct drm_i915_gem_request *request, - u32 seqno, int state, unsigned long timeout_us); -static inline bool i915_spin_request(const struct drm_i915_gem_request *request, - int state, unsigned long timeout_us) -{ - u32 seqno; - - seqno = i915_gem_request_global_seqno(request); - if (!seqno) - return 0; - - return (__i915_gem_request_started(request, seqno) && - __i915_spin_request(request, seqno, state, timeout_us)); -} - /* We treat requests as fences. This is not be to confused with our * "fence registers" but pipeline synchronisation objects ala GL_ARB_sync. * We use the fences to synchronize access from the CPU with activity on the -- cgit v1.2.3 From b4756707152700c96acdfe149cb1ca4cec306c7a Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 2 Sep 2017 07:42:42 -0400 Subject: media: dvb: i2c transfers over usb cannot be done from stack Since commit 29d2fef8be11 ("usb: catch attempts to submit urbs with a vmalloc'd transfer buffer"), the AverMedia AverTV DVB-T USB 2.0 (a800) fails to probe. Cc: stable@vger.kernel.org Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib3000mc.c | 50 ++++++++++++++++++++++------ drivers/media/dvb-frontends/dvb-pll.c | 22 +++++++++--- drivers/media/tuners/mt2060.c | 59 ++++++++++++++++++++++++++------- 3 files changed, 103 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c index 224283fe100a..4d086a7248e9 100644 --- a/drivers/media/dvb-frontends/dib3000mc.c +++ b/drivers/media/dvb-frontends/dib3000mc.c @@ -55,29 +55,57 @@ struct dib3000mc_state { static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) { - u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; - u8 rb[2]; struct i2c_msg msg[2] = { - { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, + { .addr = state->i2c_addr >> 1, .flags = 0, .len = 2 }, + { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .len = 2 }, }; + u16 word; + u8 *b; + + b = kmalloc(4, GFP_KERNEL); + if (!b) + return 0; + + b[0] = (reg >> 8) | 0x80; + b[1] = reg; + b[2] = 0; + b[3] = 0; + + msg[0].buf = b; + msg[1].buf = b + 2; if (i2c_transfer(state->i2c_adap, msg, 2) != 2) dprintk("i2c read error on %d\n",reg); - return (rb[0] << 8) | rb[1]; + word = (b[2] << 8) | b[3]; + kfree(b); + + return word; } static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val) { - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; struct i2c_msg msg = { - .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 + .addr = state->i2c_addr >> 1, .flags = 0, .len = 4 }; - return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; + int rc; + u8 *b; + + b = kmalloc(4, GFP_KERNEL); + if (!b) + return -ENOMEM; + + b[0] = reg >> 8; + b[1] = reg; + b[2] = val >> 8; + b[3] = val; + + msg.buf = b; + + rc = i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; + kfree(b); + + return rc; } static int dib3000mc_identify(struct dib3000mc_state *state) diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index 7bec3e028bee..5553b89b804e 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c @@ -753,13 +753,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, unsigned int pll_desc_id) { - u8 b1 [] = { 0 }; - struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, - .buf = b1, .len = 1 }; + u8 *b1; + struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .len = 1 }; struct dvb_pll_priv *priv = NULL; int ret; const struct dvb_pll_desc *desc; + b1 = kmalloc(1, GFP_KERNEL); + if (!b1) + return NULL; + + b1[0] = 0; + msg.buf = b1; + if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) && (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list))) pll_desc_id = id[dvb_pll_devcount]; @@ -773,15 +779,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, fe->ops.i2c_gate_ctrl(fe, 1); ret = i2c_transfer (i2c, &msg, 1); - if (ret != 1) + if (ret != 1) { + kfree(b1); return NULL; + } if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); - if (priv == NULL) + if (!priv) { + kfree(b1); return NULL; + } priv->pll_i2c_address = pll_addr; priv->i2c = i2c; @@ -811,6 +821,8 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, "insmod option" : "autodetected"); } + kfree(b1); + return fe; } EXPORT_SYMBOL(dvb_pll_attach); diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c index 2e487f9a2cc3..4983eeb39f36 100644 --- a/drivers/media/tuners/mt2060.c +++ b/drivers/media/tuners/mt2060.c @@ -38,41 +38,74 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val) { struct i2c_msg msg[2] = { - { .addr = priv->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 }, + { .addr = priv->cfg->i2c_address, .flags = 0, .len = 1 }, + { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .len = 1 }, }; + int rc = 0; + u8 *b; + + b = kmalloc(2, GFP_KERNEL); + if (!b) + return -ENOMEM; + + b[0] = reg; + b[1] = 0; + + msg[0].buf = b; + msg[1].buf = b + 1; if (i2c_transfer(priv->i2c, msg, 2) != 2) { printk(KERN_WARNING "mt2060 I2C read failed\n"); - return -EREMOTEIO; + rc = -EREMOTEIO; } - return 0; + *val = b[1]; + kfree(b); + + return rc; } // Writes a single register static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val) { - u8 buf[2] = { reg, val }; struct i2c_msg msg = { - .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2 + .addr = priv->cfg->i2c_address, .flags = 0, .len = 2 }; + u8 *buf; + int rc = 0; + + buf = kmalloc(2, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf[0] = reg; + buf[1] = val; + + msg.buf = buf; if (i2c_transfer(priv->i2c, &msg, 1) != 1) { printk(KERN_WARNING "mt2060 I2C write failed\n"); - return -EREMOTEIO; + rc = -EREMOTEIO; } - return 0; + kfree(buf); + return rc; } // Writes a set of consecutive registers static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len) { int rem, val_len; - u8 xfer_buf[16]; + u8 *xfer_buf; + int rc = 0; struct i2c_msg msg = { - .addr = priv->cfg->i2c_address, .flags = 0, .buf = xfer_buf + .addr = priv->cfg->i2c_address, .flags = 0 }; + xfer_buf = kmalloc(16, GFP_KERNEL); + if (!xfer_buf) + return -ENOMEM; + + msg.buf = xfer_buf; + for (rem = len - 1; rem > 0; rem -= priv->i2c_max_regs) { val_len = min_t(int, rem, priv->i2c_max_regs); msg.len = 1 + val_len; @@ -81,11 +114,13 @@ static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len) if (i2c_transfer(priv->i2c, &msg, 1) != 1) { printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n", val_len); - return -EREMOTEIO; + rc = -EREMOTEIO; + break; } } - return 0; + kfree(xfer_buf); + return rc; } // Initialisation sequences -- cgit v1.2.3 From bbd770aee018c8f46d8f43263928440d5ac04b36 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Tue, 29 Aug 2017 04:19:43 -0400 Subject: media: venus: init registered list on streamoff Add missing init_list_head for the registered buffer list. Absence of the init could lead to a unhandled kernel paging request as below, when streamon/streamoff are called in row. [338046.571321] Unable to handle kernel paging request at virtual address fffffffffffffe00 [338046.574849] pgd = ffff800034820000 [338046.582381] [fffffffffffffe00] *pgd=00000000b60f5003[338046.582545] , *pud=00000000b1f31003 , *pmd=0000000000000000[338046.592082] [338046.597754] Internal error: Oops: 96000004 [#1] PREEMPT SMP [338046.601671] Modules linked in: venus_enc venus_dec venus_core usb_f_ecm g_ether usb_f_rndis u_ether libcomposite ipt_MASQUERADE nf_nat_masquerade_ipv4 arc4 wcn36xx mac80211 btqcomsmd btqca iptable_nat nf_co] [338046.662408] CPU: 0 PID: 5433 Comm: irq/160-venus Tainted: G W 4.9.39+ #232 [338046.668024] Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT) [338046.675268] task: ffff80003541cb00 task.stack: ffff800026e20000 [338046.682097] PC is at venus_helper_release_buf_ref+0x28/0x88 [venus_core] [338046.688282] LR is at vdec_event_notify+0xe8/0x150 [venus_dec] [338046.695029] pc : [] lr : [] pstate: a0000145 [338046.701256] sp : ffff800026e23bc0 [338046.708494] x29: ffff800026e23bc0 x28: 0000000000000000 [338046.718853] x27: ffff000000afd4f8 x26: ffff800031faa700 [338046.729253] x25: ffff000000afd790 x24: ffff800031faa618 [338046.739664] x23: ffff800003e18138 x22: ffff800002fc9810 [338046.750109] x21: ffff800026e23c28 x20: 0000000000000001 [338046.760592] x19: ffff80002a13b800 x18: 0000000000000010 [338046.771099] x17: 0000ffffa3d01600 x16: ffff000008100428 [338046.781654] x15: 0000000000000006 x14: ffff000089045ba7 [338046.792250] x13: ffff000009045bb6 x12: 00000000004f37c8 [338046.802894] x11: 0000000000267211 x10: 0000000000000000 [338046.813574] x9 : 0000000000032000 x8 : 00000000dc400000 [338046.824274] x7 : 0000000000000000 x6 : ffff800031faa728 [338046.835005] x5 : ffff80002a13b850 x4 : 0000000000000000 [338046.845793] x3 : fffffffffffffdf8 x2 : 0000000000000000 [338046.856602] x1 : 0000000000000003 x0 : ffff80002a13b800 Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/helpers.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 68933d208063..9b2a401a4891 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -682,6 +682,7 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q) hfi_session_abort(inst); load_scale_clocks(core); + INIT_LIST_HEAD(&inst->registeredbufs); } venus_helper_buffers_done(inst, VB2_BUF_STATE_ERROR); -- cgit v1.2.3 From 9b62ccdbc797ae42342bd6ca15719362d2543d24 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 29 Aug 2017 06:21:10 -0400 Subject: media: qcom: camss: Make function vfe_set_selection static The function vfe_set_selection is local to the source and does not need to be in global scope, so make it static. Cleans up sparse warning: warning: symbol 'vfe_set_selection' was not declared. Should it be static? Signed-off-by: Colin Ian King Acked-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index b21b3c2dc77f..b22d2dfcd3c2 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -2660,7 +2660,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd, * * Return -EINVAL or zero on success */ -int vfe_set_selection(struct v4l2_subdev *sd, +static int vfe_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { -- cgit v1.2.3 From 81b79c71e546fc15e95e804de2497a448cc51a47 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 30 Aug 2017 13:14:36 -0400 Subject: media: staging/imx: Fix uninitialized variable warning The ret variable can be returned uninitialized in the imx_media_create_pad_vdev_lists() function is imxmd->num_vdevs is zero. Fix it. Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-media-dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c index d96f4512224f..b55e5ebba8b4 100644 --- a/drivers/staging/media/imx/imx-media-dev.c +++ b/drivers/staging/media/imx/imx-media-dev.c @@ -400,10 +400,10 @@ static int imx_media_create_pad_vdev_lists(struct imx_media_dev *imxmd) struct media_link, list); ret = imx_media_add_vdev_to_pad(imxmd, vdev, link->source); if (ret) - break; + return ret; } - return ret; + return 0; } /* async subdev complete notifier */ -- cgit v1.2.3 From e949f61461ab83b094cad564c89a8d2b078b4508 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 31 Aug 2017 12:56:10 -0400 Subject: media: s5p-cec: add NACK detection support The s5p-cec driver returned CEC_TX_STATUS_ERROR for the NACK condition. Some digging into the datasheet uncovered the S5P_CEC_TX_STAT1 register where bit 0 indicates if the transmit was nacked or not. Use this to return the correct CEC_TX_STATUS_NACK status to userspace. This was the only driver that couldn't tell a NACK from another error, and that was very unusual. And a potential problem for applications as well. Tested with my Odroid-U3. Signed-off-by: Hans Verkuil Acked-by: Sylwester Nawrocki Cc: # for v4.12 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c | 3 ++- drivers/media/platform/s5p-cec/s5p_cec.c | 11 ++++++++++- drivers/media/platform/s5p-cec/s5p_cec.h | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c index 1edf667d562a..146ae6f25cdb 100644 --- a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c +++ b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c @@ -172,7 +172,8 @@ u32 s5p_cec_get_status(struct s5p_cec_dev *cec) { u32 status = 0; - status = readb(cec->reg + S5P_CEC_STATUS_0); + status = readb(cec->reg + S5P_CEC_STATUS_0) & 0xf; + status |= (readb(cec->reg + S5P_CEC_TX_STAT1) & 0xf) << 4; status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8; status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16; status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24; diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c index 58d200e7c838..8837e2678bde 100644 --- a/drivers/media/platform/s5p-cec/s5p_cec.c +++ b/drivers/media/platform/s5p-cec/s5p_cec.c @@ -92,7 +92,10 @@ static irqreturn_t s5p_cec_irq_handler(int irq, void *priv) dev_dbg(cec->dev, "irq received\n"); if (status & CEC_STATUS_TX_DONE) { - if (status & CEC_STATUS_TX_ERROR) { + if (status & CEC_STATUS_TX_NACK) { + dev_dbg(cec->dev, "CEC_STATUS_TX_NACK set\n"); + cec->tx = STATE_NACK; + } else if (status & CEC_STATUS_TX_ERROR) { dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n"); cec->tx = STATE_ERROR; } else { @@ -135,6 +138,12 @@ static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv) cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); cec->tx = STATE_IDLE; break; + case STATE_NACK: + cec_transmit_done(cec->adap, + CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK, + 0, 1, 0, 0); + cec->tx = STATE_IDLE; + break; case STATE_ERROR: cec_transmit_done(cec->adap, CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR, diff --git a/drivers/media/platform/s5p-cec/s5p_cec.h b/drivers/media/platform/s5p-cec/s5p_cec.h index 8bcd8dc1aeb9..86ded522ef27 100644 --- a/drivers/media/platform/s5p-cec/s5p_cec.h +++ b/drivers/media/platform/s5p-cec/s5p_cec.h @@ -35,6 +35,7 @@ #define CEC_STATUS_TX_TRANSFERRING (1 << 1) #define CEC_STATUS_TX_DONE (1 << 2) #define CEC_STATUS_TX_ERROR (1 << 3) +#define CEC_STATUS_TX_NACK (1 << 4) #define CEC_STATUS_TX_BYTES (0xFF << 8) #define CEC_STATUS_RX_RUNNING (1 << 16) #define CEC_STATUS_RX_RECEIVING (1 << 17) @@ -55,6 +56,7 @@ enum cec_state { STATE_IDLE, STATE_BUSY, STATE_DONE, + STATE_NACK, STATE_ERROR }; -- cgit v1.2.3 From 845d6524d69b40bd6abd61dc1264a8657159aa55 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Thu, 14 Sep 2017 11:23:38 -0400 Subject: media: cec: Respond to unregistered initiators, when applicable Running CEC 1.4 compliance test we get the following error on test 11.1.6.2: "ERROR: The DUT did not broadcast a message to the unregistered device." Fix this by letting GIVE_PHYSICAL_ADDR message respond to unregistered device. Also, GIVE_DEVICE_VENDOR_ID and GIVE_FEATURES fall in the same category so, respond also to these messages. With this fix we pass CEC 1.4 official compliance. Signed-off-by: Jose Abreu Cc: Joao Pinto Signed-off-by: Hans Verkuil Cc: # for v4.10 and up Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index dd769e40416f..84d1b67f850c 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -1794,12 +1794,19 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, */ switch (msg->msg[1]) { case CEC_MSG_GET_CEC_VERSION: - case CEC_MSG_GIVE_DEVICE_VENDOR_ID: case CEC_MSG_ABORT: case CEC_MSG_GIVE_DEVICE_POWER_STATUS: - case CEC_MSG_GIVE_PHYSICAL_ADDR: case CEC_MSG_GIVE_OSD_NAME: + /* + * These messages reply with a directed message, so ignore if + * the initiator is Unregistered. + */ + if (!adap->passthrough && from_unregistered) + return 0; + /* Fall through */ + case CEC_MSG_GIVE_DEVICE_VENDOR_ID: case CEC_MSG_GIVE_FEATURES: + case CEC_MSG_GIVE_PHYSICAL_ADDR: /* * Skip processing these messages if the passthrough mode * is on. @@ -1807,7 +1814,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, if (adap->passthrough) goto skip_processing; /* Ignore if addressing is wrong */ - if (is_broadcast || from_unregistered) + if (is_broadcast) return 0; break; -- cgit v1.2.3 From db6321a1af8432df983048d2dd8529525589f71d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 11 Sep 2017 08:35:36 -0400 Subject: media: platform: VIDEO_QCOM_CAMSS should depend on HAS_DMA If NO_DMA=y: warning: (TOUCHSCREEN_SUR40 && VIDEO_TW68 && VIDEO_CX23885 && VIDEO_CX25821 && VIDEO_CX88 && VIDEO_SAA7134 && VIDEO_COBALT && VIDEO_QCOM_CAMSS) selects VIDEOBUF2_DMA_SG which has unmet direct dependencies (MEDIA_SUPPORT && HAS_DMA) and ERROR: "bad_dma_ops" [drivers/media/v4l2-core/videobuf2-dma-sg.ko] undefined! ERROR: "bad_dma_ops" [drivers/media/platform/qcom/camss-8x16/qcom-camss.ko] undefined! VIDEO_QCOM_CAMSS selects VIDEOBUF2_DMA_SG, which bypasses its dependency on HAS_DMA. Make VIDEO_QCOM_CAMSS depend on HAS_DMA to fix this. Fixes: f5c074947f56533c ("media: camss: Enable building") Signed-off-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil --- drivers/media/platform/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 7e7cc49b8674..3c4f7fa7b9d8 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -112,7 +112,7 @@ config VIDEO_PXA27x config VIDEO_QCOM_CAMSS tristate "Qualcomm 8x16 V4L2 Camera Subsystem driver" - depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST select VIDEOBUF2_DMA_SG select V4L2_FWNODE -- cgit v1.2.3 From 05cf97e7a619fc7ede81ee6bb8ebfa7531b633f5 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 22 Sep 2017 01:01:11 +0200 Subject: cnic: Fix an error handling path in 'cnic_alloc_bnx2x_resc()' All the error handling paths 'goto error', except this one. We should also go to error in this case, or some resources will be leaking. Signed-off-by: Christophe JAILLET Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index cec94bbb2ea5..8bc126a156e8 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -1278,7 +1278,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) ret = cnic_alloc_dma(dev, kwq_16_dma, pages, 0); if (ret) - return -ENOMEM; + goto error; n = CNIC_PAGE_SIZE / CNIC_KWQ16_DATA_SIZE; for (i = 0, j = 0; i < cp->max_cid_space; i++) { -- cgit v1.2.3 From 5c346525d3591cb032eca86d0f904cc01f1069ff Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Thu, 21 Sep 2017 18:00:36 -0600 Subject: net: qualcomm: rmnet: Fix rcu splat in rmnet_is_real_dev_registered Xiaolong reported a suspicious rcu_dereference_check in the device unregister notifier callback. Since we do not dereference the rx_handler_data, it's ok to just check for the value of the pointer. Note that this section is already protected by rtnl_lock. [ 101.364846] WARNING: suspicious RCU usage [ 101.365654] 4.13.0-rc6-01701-gceed73a #1 Not tainted [ 101.370873] ----------------------------- [ 101.372472] drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c:57 suspicious rcu_dereference_check() usage! [ 101.374427] [ 101.374427] other info that might help us debug this: [ 101.374427] [ 101.387491] [ 101.387491] rcu_scheduler_active = 2, debug_locks = 1 [ 101.389368] 1 lock held by trinity-main/2809: [ 101.390736] #0: (rtnl_mutex){+.+.+.}, at: [<8146085b>] rtnl_lock+0xf/0x11 [ 101.395482] [ 101.395482] stack backtrace: [ 101.396948] CPU: 0 PID: 2809 Comm: trinity-main Not tainted 4.13.0-rc6-01701-gceed73a #1 [ 101.398857] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-20161025_171302-gandalf 04/01/2014 [ 101.401079] Call Trace: [ 101.401656] dump_stack+0xa1/0xeb [ 101.402871] lockdep_rcu_suspicious+0xc7/0xd0 [ 101.403665] rmnet_is_real_dev_registered+0x40/0x4e [ 101.405199] rmnet_config_notify_cb+0x2c/0x142 [ 101.406344] ? wireless_nlevent_flush+0x47/0x71 [ 101.407385] notifier_call_chain+0x2d/0x47 [ 101.408645] raw_notifier_call_chain+0xc/0xe [ 101.409882] call_netdevice_notifiers_info+0x41/0x49 [ 101.411402] call_netdevice_notifiers+0xc/0xe [ 101.412713] rollback_registered_many+0x268/0x36e [ 101.413702] rollback_registered+0x39/0x56 [ 101.414965] unregister_netdevice_queue+0x79/0x88 [ 101.415908] unregister_netdev+0x16/0x1d Fixes: ceed73a2cf4a ("drivers: net: ethernet: qualcomm: rmnet: Initial implementation") Signed-off-by: Subash Abhinov Kasiviswanathan Reported-by: kernel test robot Signed-off-by: David S. Miller --- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index 98f22551eb45..1e33aea59f50 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -51,10 +51,7 @@ struct rmnet_walk_data { static int rmnet_is_real_dev_registered(const struct net_device *real_dev) { - rx_handler_func_t *rx_handler; - - rx_handler = rcu_dereference(real_dev->rx_handler); - return (rx_handler == rmnet_rx_handler); + return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler; } /* Needs rtnl lock */ -- cgit v1.2.3 From 245a396a9b1a67ac5c3228737c261b3e48708a2a Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 23 Sep 2017 08:06:18 +0200 Subject: iio: adc: twl4030: Fix an error handling path in 'twl4030_madc_probe()' If 'devm_regulator_get()' fails, we should go through the existing error handling path instead of returning directly, as done is all the other error handling paths in this function. Fixes: 7cc97d77ee8a ("iio: adc: twl4030: Fix ADC[3:6] readings") Signed-off-by: Christophe JAILLET Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/twl4030-madc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c index bd3d37fc2144..252f5890311e 100644 --- a/drivers/iio/adc/twl4030-madc.c +++ b/drivers/iio/adc/twl4030-madc.c @@ -887,8 +887,10 @@ static int twl4030_madc_probe(struct platform_device *pdev) /* Enable 3v1 bias regulator for MADC[3:6] */ madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1"); - if (IS_ERR(madc->usb3v1)) - return -ENODEV; + if (IS_ERR(madc->usb3v1)) { + ret = -ENODEV; + goto err_i2c; + } ret = regulator_enable(madc->usb3v1); if (ret) -- cgit v1.2.3 From 7f70be6e4025db0551e6863e7eb9cca07122695c Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 23 Sep 2017 08:06:19 +0200 Subject: iio: adc: twl4030: Disable the vusb3v1 rugulator in the error handling path of 'twl4030_madc_probe()' Commit 7cc97d77ee8a has introduced a call to 'regulator_disable()' in the .remove function. So we should also have such a call in the .probe function in case of error after a successful 'regulator_enable()' call. Add a new label for that and use it. Fixes: 7cc97d77ee8a ("iio: adc: twl4030: Fix ADC[3:6] readings") Signed-off-by: Christophe JAILLET Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/twl4030-madc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c index 252f5890311e..0c86fbb3033e 100644 --- a/drivers/iio/adc/twl4030-madc.c +++ b/drivers/iio/adc/twl4030-madc.c @@ -899,11 +899,13 @@ static int twl4030_madc_probe(struct platform_device *pdev) ret = iio_device_register(iio_dev); if (ret) { dev_err(&pdev->dev, "could not register iio device\n"); - goto err_i2c; + goto err_usb3v1; } return 0; +err_usb3v1: + regulator_disable(madc->usb3v1); err_i2c: twl4030_madc_set_current_generator(madc, 0, 0); err_current_generator: -- cgit v1.2.3 From 53063846affd27def6f96e13a9fb80b9a3c2d126 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 23 Sep 2017 08:06:20 +0200 Subject: iio: adc: twl4030: Return an error if we can not enable the vusb3v1 regulator in 'twl4030_madc_probe()' If we can not enable the regulator, go through the error handling path instead of silently continuing. Fixes: 7cc97d77ee8a ("iio: adc: twl4030: Fix ADC[3:6] readings") Signed-off-by: Christophe JAILLET Signed-off-by: Jonathan Cameron --- drivers/iio/adc/twl4030-madc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c index 0c86fbb3033e..28df096e84ec 100644 --- a/drivers/iio/adc/twl4030-madc.c +++ b/drivers/iio/adc/twl4030-madc.c @@ -893,8 +893,10 @@ static int twl4030_madc_probe(struct platform_device *pdev) } ret = regulator_enable(madc->usb3v1); - if (ret) + if (ret) { dev_err(madc->dev, "could not enable 3v1 bias regulator\n"); + goto err_i2c; + } ret = iio_device_register(iio_dev); if (ret) { -- cgit v1.2.3 From 0a56eabc4e3f730782e4a9f3af4f60aa03a8a849 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Mon, 18 Sep 2017 12:05:30 +0200 Subject: iio: trigger: stm32-timer: preset shouldn't be buffered Currently, setting preset value (ARR) will update directly 'Auto reload value' only on 1st write access. But then, ARPE is set. This makes ARR a shadow register. Preset value should be updated upon each write request: ensure ARPE is 0. This fixes successive writes to preset attribute. Fixes: 4adec7da0536 ("iio: stm32 trigger: Add quadrature encoder device") Signed-off-by: Fabrice Gasnier Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/trigger/stm32-timer-trigger.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index a9bc5b603b86..4cec28af3ecf 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c @@ -681,8 +681,9 @@ static ssize_t stm32_count_set_preset(struct iio_dev *indio_dev, if (ret) return ret; + /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); regmap_write(priv->regmap, TIM_ARR, preset); - regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); return len; } -- cgit v1.2.3 From b7a9776c1f9443326632486fcbd82dca82f8511e Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Mon, 18 Sep 2017 12:05:31 +0200 Subject: iio: trigger: stm32-timer: fix a corner case to write preset Balance timer start routine that sets ARPE: clear it in stop routine. This fixes a corner case, when timer is used successively as trigger (with sampling_frequency start/stop routines), then as a counter (with preset). Fixes: 93fbe91b5521 ("iio: Add STM32 timer trigger driver") Signed-off-by: Fabrice Gasnier Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/trigger/stm32-timer-trigger.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index 4cec28af3ecf..a30ba6e1dfec 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c @@ -174,6 +174,7 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv) clk_disable(priv->clk); /* Stop timer */ + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); regmap_write(priv->regmap, TIM_PSC, 0); regmap_write(priv->regmap, TIM_ARR, 0); -- cgit v1.2.3 From 4fb840c95f82652cece7352be9080884cafb92a0 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Mon, 18 Sep 2017 18:24:15 +0200 Subject: iio: adc: stm32: fix bad error check on max_channels Fix a bad error check when counting 'st,adc-channels' array elements. This is seen when all channels are in use simultaneously. Fixes: 64ad7f643 ("iio: adc: stm32: introduce compatible data cfg") Signed-off-by: Fabrice Gasnier Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/stm32-adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 6bc602891f2f..e93244bc3edd 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -1656,7 +1656,7 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev) num_channels = of_property_count_u32_elems(node, "st,adc-channels"); if (num_channels < 0 || - num_channels >= adc_info->max_channels) { + num_channels > adc_info->max_channels) { dev_err(&indio_dev->dev, "Bad st,adc-channels?\n"); return num_channels < 0 ? num_channels : -EINVAL; } -- cgit v1.2.3 From 0964e40947a630a2a6f724e968246992f97bcf1c Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Tue, 22 Aug 2017 15:33:00 +0200 Subject: iio: adc: mcp320x: Fix oops on module unload The driver calls spi_get_drvdata() in its ->remove hook even though it has never called spi_set_drvdata(). Stack trace for posterity: Unable to handle kernel NULL pointer dereference at virtual address 00000220 Internal error: Oops: 5 [#1] SMP ARM [<8072f564>] (mutex_lock) from [<7f1400d0>] (iio_device_unregister+0x24/0x7c [industrialio]) [<7f1400d0>] (iio_device_unregister [industrialio]) from [<7f15e020>] (mcp320x_remove+0x20/0x30 [mcp320x]) [<7f15e020>] (mcp320x_remove [mcp320x]) from [<8055a8cc>] (spi_drv_remove+0x2c/0x44) [<8055a8cc>] (spi_drv_remove) from [<805087bc>] (__device_release_driver+0x98/0x134) [<805087bc>] (__device_release_driver) from [<80509180>] (driver_detach+0xdc/0xe0) [<80509180>] (driver_detach) from [<8050823c>] (bus_remove_driver+0x5c/0xb0) [<8050823c>] (bus_remove_driver) from [<80509ab0>] (driver_unregister+0x38/0x58) [<80509ab0>] (driver_unregister) from [<7f15e69c>] (mcp320x_driver_exit+0x14/0x1c [mcp320x]) [<7f15e69c>] (mcp320x_driver_exit [mcp320x]) from [<801a78d0>] (SyS_delete_module+0x184/0x1d0) [<801a78d0>] (SyS_delete_module) from [<80108100>] (ret_fast_syscall+0x0/0x1c) Fixes: f5ce4a7a9291 ("iio: adc: add driver for MCP3204/08 12-bit ADC") Cc: Oskar Andero Signed-off-by: Lukas Wunner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp320x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 634717ae12f3..45d043c9a888 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -312,6 +312,7 @@ static int mcp320x_probe(struct spi_device *spi) indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &mcp320x_info; + spi_set_drvdata(spi, indio_dev); chip_info = &mcp320x_chip_infos[spi_get_device_id(spi)->driver_data]; indio_dev->channels = chip_info->channels; -- cgit v1.2.3 From e6f4794371ee7cce1339e7ca9542f1e703c5f84a Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Tue, 22 Aug 2017 15:33:00 +0200 Subject: iio: adc: mcp320x: Fix readout of negative voltages Commit f686a36b4b79 ("iio: adc: mcp320x: Add support for mcp3301") returns a signed voltage from mcp320x_adc_conversion() but neglects that the caller interprets a negative return value as failure. Only mcp3301 (and the upcoming mcp3550/1/3) is affected as the other chips are incapable of measuring negative voltages. Fix and while at it, add mcp3301 to the list of supported chips at the top of the file. Fixes: f686a36b4b79 ("iio: adc: mcp320x: Add support for mcp3301") Cc: Andrea Galbusera Signed-off-by: Lukas Wunner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp320x.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 45d043c9a888..071dd23a33d9 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -17,6 +17,8 @@ * MCP3204 * MCP3208 * ------------ + * 13 bit converter + * MCP3301 * * Datasheet can be found here: * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001 @@ -96,7 +98,7 @@ static int mcp320x_channel_to_tx_data(int device_index, } static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, - bool differential, int device_index) + bool differential, int device_index, int *val) { int ret; @@ -117,19 +119,25 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, switch (device_index) { case mcp3001: - return (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); + *val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); + return 0; case mcp3002: case mcp3004: case mcp3008: - return (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); + *val = (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); + return 0; case mcp3201: - return (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); + *val = (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); + return 0; case mcp3202: case mcp3204: case mcp3208: - return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); + *val = (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); + return 0; case mcp3301: - return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12); + *val = sign_extend32((adc->rx_buf[0] & 0x1f) << 8 + | adc->rx_buf[1], 12); + return 0; default: return -EINVAL; } @@ -150,12 +158,10 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: ret = mcp320x_adc_conversion(adc, channel->address, - channel->differential, device_index); - + channel->differential, device_index, val); if (ret < 0) goto out; - *val = ret; ret = IIO_VAL_INT; break; -- cgit v1.2.3 From 4b1f0c31f96c45e8521dd84aae50f2aa4aecfb7b Mon Sep 17 00:00:00 2001 From: Colin Parker Date: Mon, 28 Aug 2017 16:21:39 -0700 Subject: IIO: BME280: Updates to Humidity readings need ctrl_reg write! The ctrl_reg register needs to be written after any write to the humidity registers. The value written to the ctrl_reg register does not necessarily need to change, but a write operation must occur. The regmap_update_bits functions will not write to a register if the register value matches the value to be written. This saves unnecessary bus operations. The change in this patch forces a bus write during the chip_config operation by switching to regmap_write_bits. This will fix issues where the Humidity Sensor Oversampling bits are not updated after initialization. Signed-off-by: Colin Parker Acked-by: Andreas Klinger Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/bmp280-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index d82b788374b6..e442c5248427 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -558,7 +558,7 @@ static int bmp280_chip_config(struct bmp280_data *data) u8 osrs = BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) | BMP280_OSRS_PRESS_X(data->oversampling_press + 1); - ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS, + ret = regmap_write_bits(data->regmap, BMP280_REG_CTRL_MEAS, BMP280_OSRS_TEMP_MASK | BMP280_OSRS_PRESS_MASK | BMP280_MODE_MASK, -- cgit v1.2.3 From 7fc10de8d49a748c476532c9d8e8fe19e548dd67 Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Tue, 5 Sep 2017 15:14:45 +0300 Subject: iio: ad_sigma_delta: Implement a dedicated reset function Since most of the SD ADCs have the option of reseting the serial interface by sending a number of SCLKs with CS = 0 and DIN = 1, a dedicated function that can do this is usefull. Needed for the patch: iio: ad7793: Fix the serial interface reset Signed-off-by: Dragos Bogdan Acked-by: Lars-Peter Clausen Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad_sigma_delta.c | 28 ++++++++++++++++++++++++++++ include/linux/iio/adc/ad_sigma_delta.h | 3 +++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index d10bd0c97233..22c4c17cd996 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -177,6 +177,34 @@ out: } EXPORT_SYMBOL_GPL(ad_sd_read_reg); +/** + * ad_sd_reset() - Reset the serial interface + * + * @sigma_delta: The sigma delta device + * @reset_length: Number of SCLKs with DIN = 1 + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_reset(struct ad_sigma_delta *sigma_delta, + unsigned int reset_length) +{ + uint8_t *buf; + unsigned int size; + int ret; + + size = DIV_ROUND_UP(reset_length, 8); + buf = kcalloc(size, sizeof(*buf), GFP_KERNEL); + if (!buf) + return -ENOMEM; + + memset(buf, 0xff, size); + ret = spi_write(sigma_delta->spi, buf, size); + kfree(buf); + + return ret; +} +EXPORT_SYMBOL_GPL(ad_sd_reset); + static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, unsigned int mode, unsigned int channel) { diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index 5ba430cc9a87..1fc7abd28b0b 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -111,6 +111,9 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, unsigned int size, unsigned int *val); +int ad_sd_reset(struct ad_sigma_delta *sigma_delta, + unsigned int reset_length); + int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, int *val); int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, -- cgit v1.2.3 From 7ee3b7ebcb74714df6d94c8f500f307e1ee5dda5 Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Tue, 5 Sep 2017 15:16:13 +0300 Subject: iio: ad7793: Fix the serial interface reset The serial interface can be reset by writing 32 consecutive 1s to the device. 'ret' was initialized correctly but its value was overwritten when ad7793_check_platform_data() was called. Since a dedicated reset function is present now, it should be used instead. Fixes: 2edb769d246e ("iio:ad7793: Add support for the ad7798 and ad7799") Signed-off-by: Dragos Bogdan Acked-by: Lars-Peter Clausen Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7793.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index e6706a09e100..47c3d7f32900 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -257,7 +257,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, unsigned int vref_mv) { struct ad7793_state *st = iio_priv(indio_dev); - int i, ret = -1; + int i, ret; unsigned long long scale_uv; u32 id; @@ -266,7 +266,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, return ret; /* reset the serial interface */ - ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); + ret = ad_sd_reset(&st->sd, 32); if (ret < 0) goto out; usleep_range(500, 2000); /* Wait for at least 500us */ -- cgit v1.2.3 From 3d62c78a6eb9a7d67bace9622b66ad51e81c5f9b Mon Sep 17 00:00:00 2001 From: Matt Fornero Date: Tue, 5 Sep 2017 16:34:10 +0200 Subject: iio: core: Return error for failed read_reg If an IIO device returns an error code for a read access via debugfs, it is currently ignored by the IIO core (other than emitting an error message). Instead, return this error code to user space, so upper layers can detect it correctly. Signed-off-by: Matt Fornero Signed-off-by: Lars-Peter Clausen Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 17ec4cee51dc..a47428b4d31b 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -310,8 +310,10 @@ static ssize_t iio_debugfs_read_reg(struct file *file, char __user *userbuf, ret = indio_dev->info->debugfs_reg_access(indio_dev, indio_dev->cached_reg_addr, 0, &val); - if (ret) + if (ret) { dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__); + return ret; + } len = snprintf(buf, sizeof(buf), "0x%X\n", val); -- cgit v1.2.3 From f790923f146140a261ad211e5baf75d169f16fb2 Mon Sep 17 00:00:00 2001 From: Stefan Popa Date: Thu, 14 Sep 2017 16:50:28 +0300 Subject: staging: iio: ad7192: Fix - use the dedicated reset function avoiding dma from stack. Depends on: 691c4b95d1 ("iio: ad_sigma_delta: Implement a dedicated reset function") SPI host drivers can use DMA to transfer data, so the buffer should be properly allocated. Keeping it on the stack could cause an undefined behavior. The dedicated reset function solves this issue. Signed-off-by: Stefan Popa Acked-by: Lars-Peter Clausen Acked-by: Michael Hennerich Cc: Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7192.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index d11c6de9c777..6150d2780e22 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -223,11 +223,9 @@ static int ad7192_setup(struct ad7192_state *st, struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); unsigned long long scale_uv; int i, ret, id; - u8 ones[6]; /* reset the serial interface */ - memset(&ones, 0xFF, 6); - ret = spi_write(st->sd.spi, &ones, 6); + ret = ad_sd_reset(&st->sd, 48); if (ret < 0) goto out; usleep_range(500, 1000); /* Wait for at least 500us */ -- cgit v1.2.3 From d27ffc1d00327c29b3aa97f941b42f0949f9e99f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 21 Sep 2017 17:19:20 +0300 Subject: drm/i915/bios: ignore HDMI on port A MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hardware state readout oopses after several warnings when trying to use HDMI on port A, if such a combination is configured in VBT. Filter the combo out already at the VBT parsing phase. v2: also ignore DVI (Ville) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102889 Cc: stable@vger.kernel.org Cc: Imre Deak Reviewed-by: Ville Syrjälä Tested-by: Daniel Drake Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170921141920.18172-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 8526da90168c..b881ce8596ee 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1163,6 +1163,13 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, is_hdmi = is_dvi && (child->device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0; is_edp = is_dp && (child->device_type & DEVICE_TYPE_INTERNAL_CONNECTOR); + if (port == PORT_A && is_dvi) { + DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n", + is_hdmi ? "/HDMI" : ""); + is_dvi = false; + is_hdmi = false; + } + info->supports_dvi = is_dvi; info->supports_hdmi = is_hdmi; info->supports_dp = is_dp; -- cgit v1.2.3 From b620e870218ebe75b8221c7596b46e36d8329c85 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 22 Sep 2017 15:43:03 +0300 Subject: drm/i915: Make own struct for execlist items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Engine's execlist related items have been increasing to a point where a separate struct is warranted. Carve execlist specific items to a dedicated struct to add clarity. v2: add kerneldoc and fix whitespace (Joonas, Chris) v3: csb_mmio changes, rebase v4: s/\b(el|execlist)\b/execlists/ (Joonas) Suggested-by: Chris Wilson Cc: Chris Wilson Cc: Joonas Lahtinen Signed-off-by: Mika Kuoppala Acked-by: Joonas Lahtinen Reviewed-by: Michał Winiarski (v3) Reviewed-by: Chris Wilson (v3) Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170922124307.10914-1-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 8 +-- drivers/gpu/drm/i915/i915_gem.c | 6 +- drivers/gpu/drm/i915/i915_gpu_error.c | 4 +- drivers/gpu/drm/i915/i915_guc_submission.c | 31 +++++---- drivers/gpu/drm/i915/i915_irq.c | 5 +- drivers/gpu/drm/i915/intel_engine_cs.c | 12 ++-- drivers/gpu/drm/i915/intel_lrc.c | 100 +++++++++++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 100 +++++++++++++++++++++++------ 8 files changed, 167 insertions(+), 99 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b08ebed4e700..87e06da55a69 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3323,7 +3323,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) read = GEN8_CSB_READ_PTR(ptr); write = GEN8_CSB_WRITE_PTR(ptr); seq_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s\n", - read, engine->csb_head, + read, engine->execlists.csb_head, write, intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)), yesno(test_bit(ENGINE_IRQ_EXECLIST, @@ -3345,10 +3345,10 @@ static int i915_engine_info(struct seq_file *m, void *unused) } rcu_read_lock(); - for (idx = 0; idx < ARRAY_SIZE(engine->execlist_port); idx++) { + for (idx = 0; idx < ARRAY_SIZE(engine->execlists.port); idx++) { unsigned int count; - rq = port_unpack(&engine->execlist_port[idx], + rq = port_unpack(&engine->execlists.port[idx], &count); if (rq) { seq_printf(m, "\t\tELSP[%d] count=%d, ", @@ -3362,7 +3362,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) rcu_read_unlock(); spin_lock_irq(&engine->timeline->lock); - for (rb = engine->execlist_first; rb; rb = rb_next(rb)){ + for (rb = engine->execlists.first; rb; rb = rb_next(rb)) { struct i915_priolist *p = rb_entry(rb, typeof(*p), node); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 12ce97d47afb..49bf5ddfa7fd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2815,8 +2815,8 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) * Turning off the engine->irq_tasklet until the reset is over * prevents the race. */ - tasklet_kill(&engine->irq_tasklet); - tasklet_disable(&engine->irq_tasklet); + tasklet_kill(&engine->execlists.irq_tasklet); + tasklet_disable(&engine->execlists.irq_tasklet); if (engine->irq_seqno_barrier) engine->irq_seqno_barrier(engine); @@ -2995,7 +2995,7 @@ void i915_gem_reset(struct drm_i915_private *dev_priv) void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { - tasklet_enable(&engine->irq_tasklet); + tasklet_enable(&engine->execlists.irq_tasklet); kthread_unpark(engine->breadcrumbs.signaler); } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 6cd5eba643e8..20a1f034bf95 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1327,10 +1327,10 @@ static void engine_record_requests(struct intel_engine_cs *engine, static void error_record_engine_execlists(struct intel_engine_cs *engine, struct drm_i915_error_engine *ee) { - const struct execlist_port *port = engine->execlist_port; + const struct execlist_port *port = engine->execlists.port; unsigned int n; - for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) { + for (n = 0; n < ARRAY_SIZE(engine->execlists.port); n++) { struct drm_i915_gem_request *rq = port_request(&port[n]); if (!rq) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 06a26c610806..bce3f1b5892b 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -494,11 +494,12 @@ static void i915_guc_submit(struct intel_engine_cs *engine) struct drm_i915_private *dev_priv = engine->i915; struct intel_guc *guc = &dev_priv->guc; struct i915_guc_client *client = guc->execbuf_client; - struct execlist_port *port = engine->execlist_port; - unsigned int engine_id = engine->id; + struct intel_engine_execlists * const execlists = &engine->execlists; + struct execlist_port *port = execlists->port; + const unsigned int engine_id = engine->id; unsigned int n; - for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) { + for (n = 0; n < ARRAY_SIZE(execlists->port); n++) { struct drm_i915_gem_request *rq; unsigned int count; @@ -558,7 +559,8 @@ static void port_assign(struct execlist_port *port, static void i915_guc_dequeue(struct intel_engine_cs *engine) { - struct execlist_port *port = engine->execlist_port; + struct intel_engine_execlists * const execlists = &engine->execlists; + struct execlist_port *port = execlists->port; struct drm_i915_gem_request *last = NULL; bool submit = false; struct rb_node *rb; @@ -567,15 +569,15 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) port++; spin_lock_irq(&engine->timeline->lock); - rb = engine->execlist_first; - GEM_BUG_ON(rb_first(&engine->execlist_queue) != rb); + rb = execlists->first; + GEM_BUG_ON(rb_first(&execlists->queue) != rb); while (rb) { struct i915_priolist *p = rb_entry(rb, typeof(*p), node); struct drm_i915_gem_request *rq, *rn; list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { if (last && rq->ctx != last->ctx) { - if (port != engine->execlist_port) { + if (port != execlists->port) { __list_del_many(&p->requests, &rq->priotree.link); goto done; @@ -596,13 +598,13 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) } rb = rb_next(rb); - rb_erase(&p->node, &engine->execlist_queue); + rb_erase(&p->node, &execlists->queue); INIT_LIST_HEAD(&p->requests); if (p->priority != I915_PRIORITY_NORMAL) kmem_cache_free(engine->i915->priorities, p); } done: - engine->execlist_first = rb; + execlists->first = rb; if (submit) { port_assign(port, last); i915_guc_submit(engine); @@ -612,8 +614,8 @@ done: static void i915_guc_irq_handler(unsigned long data) { - struct intel_engine_cs *engine = (struct intel_engine_cs *)data; - struct execlist_port *port = engine->execlist_port; + struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; + struct execlist_port *port = engine->execlists.port; struct drm_i915_gem_request *rq; rq = port_request(&port[0]); @@ -1144,7 +1146,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) * and it is guaranteed that it will remove the work item from the * queue before our request is completed. */ - BUILD_BUG_ON(ARRAY_SIZE(engine->execlist_port) * + BUILD_BUG_ON(ARRAY_SIZE(engine->execlists.port) * sizeof(struct guc_wq_item) * I915_NUM_ENGINES > GUC_WQ_SIZE); @@ -1175,14 +1177,15 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) guc_interrupts_capture(dev_priv); for_each_engine(engine, dev_priv, id) { + struct intel_engine_execlists * const execlists = &engine->execlists; /* The tasklet was initialised by execlists, and may be in * a state of flux (across a reset) and so we just want to * take over the callback without changing any other state * in the tasklet. */ - engine->irq_tasklet.func = i915_guc_irq_handler; + execlists->irq_tasklet.func = i915_guc_irq_handler; clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - tasklet_schedule(&engine->irq_tasklet); + tasklet_schedule(&execlists->irq_tasklet); } return 0; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b1bab7605db9..af82bd721dbc 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1346,10 +1346,11 @@ static void snb_gt_irq_handler(struct drm_i915_private *dev_priv, static void gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) { + struct intel_engine_execlists * const execlists = &engine->execlists; bool tasklet = false; if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) { - if (port_count(&engine->execlist_port[0])) { + if (port_count(&execlists->port[0])) { __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); tasklet = true; } @@ -1361,7 +1362,7 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) } if (tasklet) - tasklet_hi_schedule(&engine->irq_tasklet); + tasklet_hi_schedule(&execlists->irq_tasklet); } static irqreturn_t gen8_gt_irq_ack(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 020e4c6c0192..bf132266a007 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -393,8 +393,8 @@ static void intel_engine_init_timeline(struct intel_engine_cs *engine) */ void intel_engine_setup_common(struct intel_engine_cs *engine) { - engine->execlist_queue = RB_ROOT; - engine->execlist_first = NULL; + engine->execlists.queue = RB_ROOT; + engine->execlists.first = NULL; intel_engine_init_timeline(engine); intel_engine_init_hangcheck(engine); @@ -1475,11 +1475,11 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine) return false; /* Both ports drained, no more ELSP submission? */ - if (port_request(&engine->execlist_port[0])) + if (port_request(&engine->execlists.port[0])) return false; /* ELSP is empty, but there are ready requests? */ - if (READ_ONCE(engine->execlist_first)) + if (READ_ONCE(engine->execlists.first)) return false; /* Ring stopped? */ @@ -1528,8 +1528,8 @@ void intel_engines_mark_idle(struct drm_i915_private *i915) for_each_engine(engine, i915, id) { intel_engine_disarm_breadcrumbs(engine); i915_gem_batch_pool_fini(&engine->batch_pool); - tasklet_kill(&engine->irq_tasklet); - engine->no_priolist = false; + tasklet_kill(&engine->execlists.irq_tasklet); + engine->execlists.no_priolist = false; } } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 955c87999280..4f202b840e3d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -291,17 +291,18 @@ lookup_priolist(struct intel_engine_cs *engine, struct i915_priotree *pt, int prio) { + struct intel_engine_execlists * const execlists = &engine->execlists; struct i915_priolist *p; struct rb_node **parent, *rb; bool first = true; - if (unlikely(engine->no_priolist)) + if (unlikely(execlists->no_priolist)) prio = I915_PRIORITY_NORMAL; find_priolist: /* most positive priority is scheduled first, equal priorities fifo */ rb = NULL; - parent = &engine->execlist_queue.rb_node; + parent = &execlists->queue.rb_node; while (*parent) { rb = *parent; p = rb_entry(rb, typeof(*p), node); @@ -316,7 +317,7 @@ find_priolist: } if (prio == I915_PRIORITY_NORMAL) { - p = &engine->default_priolist; + p = &execlists->default_priolist; } else { p = kmem_cache_alloc(engine->i915->priorities, GFP_ATOMIC); /* Convert an allocation failure to a priority bump */ @@ -331,7 +332,7 @@ find_priolist: * requests, so if userspace lied about their * dependencies that reordering may be visible. */ - engine->no_priolist = true; + execlists->no_priolist = true; goto find_priolist; } } @@ -339,10 +340,10 @@ find_priolist: p->priority = prio; INIT_LIST_HEAD(&p->requests); rb_link_node(&p->node, rb, parent); - rb_insert_color(&p->node, &engine->execlist_queue); + rb_insert_color(&p->node, &execlists->queue); if (first) - engine->execlist_first = &p->node; + execlists->first = &p->node; return ptr_pack_bits(p, first, 1); } @@ -393,12 +394,12 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq) static void execlists_submit_ports(struct intel_engine_cs *engine) { - struct execlist_port *port = engine->execlist_port; + struct execlist_port *port = engine->execlists.port; u32 __iomem *elsp = engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine)); unsigned int n; - for (n = ARRAY_SIZE(engine->execlist_port); n--; ) { + for (n = ARRAY_SIZE(engine->execlists.port); n--; ) { struct drm_i915_gem_request *rq; unsigned int count; u64 desc; @@ -453,7 +454,7 @@ static void port_assign(struct execlist_port *port, static void execlists_dequeue(struct intel_engine_cs *engine) { struct drm_i915_gem_request *last; - struct execlist_port *port = engine->execlist_port; + struct execlist_port *port = engine->execlists.port; struct rb_node *rb; bool submit = false; @@ -491,8 +492,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) */ spin_lock_irq(&engine->timeline->lock); - rb = engine->execlist_first; - GEM_BUG_ON(rb_first(&engine->execlist_queue) != rb); + rb = engine->execlists.first; + GEM_BUG_ON(rb_first(&engine->execlists.queue) != rb); while (rb) { struct i915_priolist *p = rb_entry(rb, typeof(*p), node); struct drm_i915_gem_request *rq, *rn; @@ -515,7 +516,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) * combine this request with the last, then we * are done. */ - if (port != engine->execlist_port) { + if (port != engine->execlists.port) { __list_del_many(&p->requests, &rq->priotree.link); goto done; @@ -552,13 +553,13 @@ static void execlists_dequeue(struct intel_engine_cs *engine) } rb = rb_next(rb); - rb_erase(&p->node, &engine->execlist_queue); + rb_erase(&p->node, &engine->execlists.queue); INIT_LIST_HEAD(&p->requests); if (p->priority != I915_PRIORITY_NORMAL) kmem_cache_free(engine->i915->priorities, p); } done: - engine->execlist_first = rb; + engine->execlists.first = rb; if (submit) port_assign(port, last); spin_unlock_irq(&engine->timeline->lock); @@ -569,7 +570,8 @@ done: static void execlists_cancel_requests(struct intel_engine_cs *engine) { - struct execlist_port *port = engine->execlist_port; + struct intel_engine_execlists * const execlists = &engine->execlists; + struct execlist_port *port = execlists->port; struct drm_i915_gem_request *rq, *rn; struct rb_node *rb; unsigned long flags; @@ -578,9 +580,9 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) spin_lock_irqsave(&engine->timeline->lock, flags); /* Cancel the requests on the HW and clear the ELSP tracker. */ - for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) + for (n = 0; n < ARRAY_SIZE(execlists->port); n++) i915_gem_request_put(port_request(&port[n])); - memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); + memset(execlists->port, 0, sizeof(execlists->port)); /* Mark all executing requests as skipped. */ list_for_each_entry(rq, &engine->timeline->requests, link) { @@ -590,7 +592,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) } /* Flush the queued requests to the timeline list (for retiring). */ - rb = engine->execlist_first; + rb = execlists->first; while (rb) { struct i915_priolist *p = rb_entry(rb, typeof(*p), node); @@ -603,7 +605,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) } rb = rb_next(rb); - rb_erase(&p->node, &engine->execlist_queue); + rb_erase(&p->node, &execlists->queue); INIT_LIST_HEAD(&p->requests); if (p->priority != I915_PRIORITY_NORMAL) kmem_cache_free(engine->i915->priorities, p); @@ -611,8 +613,8 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) /* Remaining _unready_ requests will be nop'ed when submitted */ - engine->execlist_queue = RB_ROOT; - engine->execlist_first = NULL; + execlists->queue = RB_ROOT; + execlists->first = NULL; GEM_BUG_ON(port_isset(&port[0])); /* @@ -628,7 +630,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) static bool execlists_elsp_ready(const struct intel_engine_cs *engine) { - const struct execlist_port *port = engine->execlist_port; + const struct execlist_port *port = engine->execlists.port; return port_count(&port[0]) + port_count(&port[1]) < 2; } @@ -639,8 +641,9 @@ static bool execlists_elsp_ready(const struct intel_engine_cs *engine) */ static void intel_lrc_irq_handler(unsigned long data) { - struct intel_engine_cs *engine = (struct intel_engine_cs *)data; - struct execlist_port *port = engine->execlist_port; + struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; + struct intel_engine_execlists * const execlists = &engine->execlists; + struct execlist_port *port = execlists->port; struct drm_i915_private *dev_priv = engine->i915; /* We can skip acquiring intel_runtime_pm_get() here as it was taken @@ -652,7 +655,7 @@ static void intel_lrc_irq_handler(unsigned long data) */ GEM_BUG_ON(!dev_priv->gt.awake); - intel_uncore_forcewake_get(dev_priv, engine->fw_domains); + intel_uncore_forcewake_get(dev_priv, execlists->fw_domains); /* Prefer doing test_and_clear_bit() as a two stage operation to avoid * imposing the cost of a locked atomic transaction when submitting a @@ -665,10 +668,10 @@ static void intel_lrc_irq_handler(unsigned long data) unsigned int head, tail; /* However GVT emulation depends upon intercepting CSB mmio */ - if (unlikely(engine->csb_use_mmio)) { + if (unlikely(execlists->csb_use_mmio)) { buf = (u32 * __force) (dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); - engine->csb_head = -1; /* force mmio read of CSB ptrs */ + execlists->csb_head = -1; /* force mmio read of CSB ptrs */ } /* The write will be ordered by the uncached read (itself @@ -682,19 +685,20 @@ static void intel_lrc_irq_handler(unsigned long data) * is set and we do a new loop. */ __clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - if (unlikely(engine->csb_head == -1)) { /* following a reset */ + if (unlikely(execlists->csb_head == -1)) { /* following a reset */ head = readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); tail = GEN8_CSB_WRITE_PTR(head); head = GEN8_CSB_READ_PTR(head); - engine->csb_head = head; + execlists->csb_head = head; } else { const int write_idx = intel_hws_csb_write_index(dev_priv) - I915_HWS_CSB_BUF0_INDEX; - head = engine->csb_head; + head = execlists->csb_head; tail = READ_ONCE(buf[write_idx]); } + while (head != tail) { struct drm_i915_gem_request *rq; unsigned int status; @@ -748,8 +752,8 @@ static void intel_lrc_irq_handler(unsigned long data) !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); } - if (head != engine->csb_head) { - engine->csb_head = head; + if (head != execlists->csb_head) { + execlists->csb_head = head; writel(_MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, head << 8), dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); } @@ -758,7 +762,7 @@ static void intel_lrc_irq_handler(unsigned long data) if (execlists_elsp_ready(engine)) execlists_dequeue(engine); - intel_uncore_forcewake_put(dev_priv, engine->fw_domains); + intel_uncore_forcewake_put(dev_priv, execlists->fw_domains); } static void insert_request(struct intel_engine_cs *engine, @@ -769,7 +773,7 @@ static void insert_request(struct intel_engine_cs *engine, list_add_tail(&pt->link, &ptr_mask_bits(p, 1)->requests); if (ptr_unmask_bits(p, 1) && execlists_elsp_ready(engine)) - tasklet_hi_schedule(&engine->irq_tasklet); + tasklet_hi_schedule(&engine->execlists.irq_tasklet); } static void execlists_submit_request(struct drm_i915_gem_request *request) @@ -782,7 +786,7 @@ static void execlists_submit_request(struct drm_i915_gem_request *request) insert_request(engine, &request->priotree, request->priotree.priority); - GEM_BUG_ON(!engine->execlist_first); + GEM_BUG_ON(!engine->execlists.first); GEM_BUG_ON(list_empty(&request->priotree.link)); spin_unlock_irqrestore(&engine->timeline->lock, flags); @@ -1289,6 +1293,7 @@ static u8 gtiir[] = { static int gen8_init_common_ring(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; + struct intel_engine_execlists * const execlists = &engine->execlists; int ret; ret = intel_mocs_init_engine(engine); @@ -1321,11 +1326,11 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]), GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift); clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - engine->csb_head = -1; + execlists->csb_head = -1; /* After a GPU reset, we may have requests to replay */ - if (!i915_modparams.enable_guc_submission && engine->execlist_first) - tasklet_schedule(&engine->irq_tasklet); + if (!i915_modparams.enable_guc_submission && execlists->first) + tasklet_schedule(&execlists->irq_tasklet); return 0; } @@ -1366,7 +1371,8 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine) static void reset_common_ring(struct intel_engine_cs *engine, struct drm_i915_gem_request *request) { - struct execlist_port *port = engine->execlist_port; + struct intel_engine_execlists * const execlists = &engine->execlists; + struct execlist_port *port = execlists->port; struct drm_i915_gem_request *rq, *rn; struct intel_context *ce; unsigned long flags; @@ -1383,9 +1389,9 @@ static void reset_common_ring(struct intel_engine_cs *engine, * guessing the missed context-switch events by looking at what * requests were completed. */ - for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) + for (n = 0; n < ARRAY_SIZE(execlists->port); n++) i915_gem_request_put(port_request(&port[n])); - memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); + memset(execlists->port, 0, sizeof(execlists->port)); /* Push back any incomplete requests for replay after the reset. */ list_for_each_entry_safe_reverse(rq, rn, @@ -1719,8 +1725,8 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) * Tasklet cannot be active at this point due intel_mark_active/idle * so this is just for documentation. */ - if (WARN_ON(test_bit(TASKLET_STATE_SCHED, &engine->irq_tasklet.state))) - tasklet_kill(&engine->irq_tasklet); + if (WARN_ON(test_bit(TASKLET_STATE_SCHED, &engine->execlists.irq_tasklet.state))) + tasklet_kill(&engine->execlists.irq_tasklet); dev_priv = engine->i915; @@ -1744,7 +1750,7 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine) engine->submit_request = execlists_submit_request; engine->cancel_requests = execlists_cancel_requests; engine->schedule = execlists_schedule; - engine->irq_tasklet.func = intel_lrc_irq_handler; + engine->execlists.irq_tasklet.func = intel_lrc_irq_handler; } static void @@ -1806,7 +1812,7 @@ logical_ring_setup(struct intel_engine_cs *engine) /* Intentionally left blank. */ engine->buffer = NULL; - engine->csb_use_mmio = irq_handler_force_mmio(dev_priv); + engine->execlists.csb_use_mmio = irq_handler_force_mmio(dev_priv); fw_domains = intel_uncore_forcewake_for_reg(dev_priv, RING_ELSP(engine), @@ -1820,9 +1826,9 @@ logical_ring_setup(struct intel_engine_cs *engine) RING_CONTEXT_STATUS_BUF_BASE(engine), FW_REG_READ); - engine->fw_domains = fw_domains; + engine->execlists.fw_domains = fw_domains; - tasklet_init(&engine->irq_tasklet, + tasklet_init(&engine->execlists.irq_tasklet, intel_lrc_irq_handler, (unsigned long)engine); logical_ring_default_vfuncs(engine); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 138116a3b537..421e769adb79 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -184,6 +184,84 @@ struct i915_priolist { int priority; }; +/** + * struct intel_engine_execlists - execlist submission queue and port state + * + * The struct intel_engine_execlists represents the combined logical state of + * driver and the hardware state for execlist mode of submission. + */ +struct intel_engine_execlists { + /** + * @irq_tasklet: softirq tasklet for bottom handler + */ + struct tasklet_struct irq_tasklet; + + /** + * @default_priolist: priority list for I915_PRIORITY_NORMAL + */ + struct i915_priolist default_priolist; + + /** + * @no_priolist: priority lists disabled + */ + bool no_priolist; + + /** + * @port: execlist port states + * + * For each hardware ELSP (ExecList Submission Port) we keep + * track of the last request and the number of times we submitted + * that port to hw. We then count the number of times the hw reports + * a context completion or preemption. As only one context can + * be active on hw, we limit resubmission of context to port[0]. This + * is called Lite Restore, of the context. + */ + struct execlist_port { + /** + * @request_count: combined request and submission count + */ + struct drm_i915_gem_request *request_count; +#define EXECLIST_COUNT_BITS 2 +#define port_request(p) ptr_mask_bits((p)->request_count, EXECLIST_COUNT_BITS) +#define port_count(p) ptr_unmask_bits((p)->request_count, EXECLIST_COUNT_BITS) +#define port_pack(rq, count) ptr_pack_bits(rq, count, EXECLIST_COUNT_BITS) +#define port_unpack(p, count) ptr_unpack_bits((p)->request_count, count, EXECLIST_COUNT_BITS) +#define port_set(p, packed) ((p)->request_count = (packed)) +#define port_isset(p) ((p)->request_count) +#define port_index(p, e) ((p) - (e)->execlists.port) + + /** + * @context_id: context ID for port + */ + GEM_DEBUG_DECL(u32 context_id); + } port[2]; + + /** + * @queue: queue of requests, in priority lists + */ + struct rb_root queue; + + /** + * @first: leftmost level in priority @queue + */ + struct rb_node *first; + + /** + * @fw_domains: forcewake domains for irq tasklet + */ + unsigned int fw_domains; + + /** + * @csb_head: context status buffer head + */ + unsigned int csb_head; + + /** + * @csb_use_mmio: access csb through mmio, instead of hwsp + */ + bool csb_use_mmio; +}; + #define INTEL_ENGINE_CS_MAX_NAME 8 struct intel_engine_cs { @@ -380,27 +458,7 @@ struct intel_engine_cs { u32 *(*signal)(struct drm_i915_gem_request *req, u32 *cs); } semaphore; - /* Execlists */ - struct tasklet_struct irq_tasklet; - struct i915_priolist default_priolist; - bool no_priolist; - struct execlist_port { - struct drm_i915_gem_request *request_count; -#define EXECLIST_COUNT_BITS 2 -#define port_request(p) ptr_mask_bits((p)->request_count, EXECLIST_COUNT_BITS) -#define port_count(p) ptr_unmask_bits((p)->request_count, EXECLIST_COUNT_BITS) -#define port_pack(rq, count) ptr_pack_bits(rq, count, EXECLIST_COUNT_BITS) -#define port_unpack(p, count) ptr_unpack_bits((p)->request_count, count, EXECLIST_COUNT_BITS) -#define port_set(p, packed) ((p)->request_count = (packed)) -#define port_isset(p) ((p)->request_count) -#define port_index(p, e) ((p) - (e)->execlist_port) - GEM_DEBUG_DECL(u32 context_id); - } execlist_port[2]; - struct rb_root execlist_queue; - struct rb_node *execlist_first; - unsigned int fw_domains; - unsigned int csb_head; - bool csb_use_mmio; + struct intel_engine_execlists execlists; /* Contexts are pinned whilst they are active on the GPU. The last * context executed remains active whilst the GPU is idle - the -- cgit v1.2.3 From 19df9a5782f51c900a730dae11e4abf85a0e5ebc Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 22 Sep 2017 15:43:04 +0300 Subject: drm/i915: Move execlist initialization into intel_engine_cs.c Move execlist init into a common engine setup. As it is common to both guc and hw execlists. v2: rebase with csb changes v3: rebase Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170922124307.10914-2-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_engine_cs.c | 30 ++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_lrc.c | 19 ------------------- 2 files changed, 28 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index bf132266a007..30035e59a784 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -382,6 +382,33 @@ static void intel_engine_init_timeline(struct intel_engine_cs *engine) engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id]; } +static bool csb_force_mmio(struct drm_i915_private *i915) +{ + /* GVT emulation depends upon intercepting CSB mmio */ + if (intel_vgpu_active(i915)) + return true; + + /* + * IOMMU adds unpredictable latency causing the CSB write (from the + * GPU into the HWSP) to only be visible some time after the interrupt + * (missed breadcrumb syndrome). + */ + if (intel_vtd_active()) + return true; + + return false; +} + +static void intel_engine_init_execlist(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + execlists->csb_use_mmio = csb_force_mmio(engine->i915); + + execlists->queue = RB_ROOT; + execlists->first = NULL; +} + /** * intel_engines_setup_common - setup engine state not requiring hw access * @engine: Engine to setup. @@ -393,8 +420,7 @@ static void intel_engine_init_timeline(struct intel_engine_cs *engine) */ void intel_engine_setup_common(struct intel_engine_cs *engine) { - engine->execlists.queue = RB_ROOT; - engine->execlists.first = NULL; + intel_engine_init_execlist(engine); intel_engine_init_timeline(engine); intel_engine_init_hangcheck(engine); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 4f202b840e3d..3186be54bbd8 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1784,23 +1784,6 @@ logical_ring_default_irqs(struct intel_engine_cs *engine) engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; } -static bool irq_handler_force_mmio(struct drm_i915_private *i915) -{ - /* GVT emulation depends upon intercepting CSB mmio */ - if (intel_vgpu_active(i915)) - return true; - - /* - * IOMMU adds unpredictable latency causing the CSB write (from the - * GPU into the HWSP) to only be visible some time after the interrupt - * (missed breadcrumb syndrome). - */ - if (intel_vtd_active()) - return true; - - return false; -} - static void logical_ring_setup(struct intel_engine_cs *engine) { @@ -1812,8 +1795,6 @@ logical_ring_setup(struct intel_engine_cs *engine) /* Intentionally left blank. */ engine->buffer = NULL; - engine->execlists.csb_use_mmio = irq_handler_force_mmio(dev_priv); - fw_domains = intel_uncore_forcewake_for_reg(dev_priv, RING_ELSP(engine), FW_REG_WRITE); -- cgit v1.2.3 From cf4591d1ce1c85d589a3e8e7e5a0bbc7aa9b0027 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 22 Sep 2017 15:43:05 +0300 Subject: drm/i915: Wrap port cancellation into a function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On reset and wedged path, we want to release the requests that are tied to ports and then mark the ports to be unset. Introduce a function for this. v2: rebase v3: drop local, keep GEM_BUG_ON (Michał, Chris) v4: rebase Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Michał Winiarski Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170922124307.10914-3-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3186be54bbd8..4f625371b5fe 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -568,21 +568,27 @@ done: execlists_submit_ports(engine); } +static void execlist_cancel_port_requests(struct intel_engine_execlists *execlists) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(execlists->port); i++) + i915_gem_request_put(port_request(&execlists->port[i])); + + memset(execlists->port, 0, sizeof(execlists->port)); +} + static void execlists_cancel_requests(struct intel_engine_cs *engine) { struct intel_engine_execlists * const execlists = &engine->execlists; - struct execlist_port *port = execlists->port; struct drm_i915_gem_request *rq, *rn; struct rb_node *rb; unsigned long flags; - unsigned long n; spin_lock_irqsave(&engine->timeline->lock, flags); /* Cancel the requests on the HW and clear the ELSP tracker. */ - for (n = 0; n < ARRAY_SIZE(execlists->port); n++) - i915_gem_request_put(port_request(&port[n])); - memset(execlists->port, 0, sizeof(execlists->port)); + execlist_cancel_port_requests(execlists); /* Mark all executing requests as skipped. */ list_for_each_entry(rq, &engine->timeline->requests, link) { @@ -613,9 +619,10 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) /* Remaining _unready_ requests will be nop'ed when submitted */ + execlists->queue = RB_ROOT; execlists->first = NULL; - GEM_BUG_ON(port_isset(&port[0])); + GEM_BUG_ON(port_isset(&execlists->port[0])); /* * The port is checked prior to scheduling a tasklet, but @@ -1372,11 +1379,9 @@ static void reset_common_ring(struct intel_engine_cs *engine, struct drm_i915_gem_request *request) { struct intel_engine_execlists * const execlists = &engine->execlists; - struct execlist_port *port = execlists->port; struct drm_i915_gem_request *rq, *rn; struct intel_context *ce; unsigned long flags; - unsigned int n; spin_lock_irqsave(&engine->timeline->lock, flags); @@ -1389,9 +1394,7 @@ static void reset_common_ring(struct intel_engine_cs *engine, * guessing the missed context-switch events by looking at what * requests were completed. */ - for (n = 0; n < ARRAY_SIZE(execlists->port); n++) - i915_gem_request_put(port_request(&port[n])); - memset(execlists->port, 0, sizeof(execlists->port)); + execlist_cancel_port_requests(execlists); /* Push back any incomplete requests for replay after the reset. */ list_for_each_entry_safe_reverse(rq, rn, -- cgit v1.2.3 From 7a62cc6107f31e119a0df6f79fa9fae566b1a22e Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 22 Sep 2017 15:43:06 +0300 Subject: drm/i915: Add execlist_port_complete When first execlist entry is processed, we move the port (contents). Introduce function for this as execlist and guc use this common operation. v2: rebase. s/GEM_DEBUG_BUG/GEM_BUG (Chris) v3: rebase Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170922124307.10914-4-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_guc_submission.c | 8 ++++---- drivers/gpu/drm/i915/intel_lrc.c | 22 +++++++++++----------- drivers/gpu/drm/i915/intel_ringbuffer.h | 14 +++++++++++++- 3 files changed, 28 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index bce3f1b5892b..55e15a57c3d9 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -592,7 +592,7 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) rq->priotree.priority = INT_MAX; __i915_gem_request_submit(rq); - trace_i915_gem_request_in(rq, port_index(port, engine)); + trace_i915_gem_request_in(rq, port_index(port, execlists)); last = rq; submit = true; } @@ -615,7 +615,8 @@ done: static void i915_guc_irq_handler(unsigned long data) { struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; - struct execlist_port *port = engine->execlists.port; + struct intel_engine_execlists * const execlists = &engine->execlists; + struct execlist_port *port = execlists->port; struct drm_i915_gem_request *rq; rq = port_request(&port[0]); @@ -623,8 +624,7 @@ static void i915_guc_irq_handler(unsigned long data) trace_i915_gem_request_out(rq); i915_gem_request_put(rq); - port[0] = port[1]; - memset(&port[1], 0, sizeof(port[1])); + execlists_port_complete(execlists, port); rq = port_request(&port[0]); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 4f625371b5fe..3b03f19f1395 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -454,7 +454,8 @@ static void port_assign(struct execlist_port *port, static void execlists_dequeue(struct intel_engine_cs *engine) { struct drm_i915_gem_request *last; - struct execlist_port *port = engine->execlists.port; + struct intel_engine_execlists * const execlists = &engine->execlists; + struct execlist_port *port = execlists->port; struct rb_node *rb; bool submit = false; @@ -468,8 +469,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine) */ last->tail = last->wa_tail; - GEM_BUG_ON(port_isset(&port[1])); - /* Hardware submission is through 2 ports. Conceptually each port * has a (RING_START, RING_HEAD, RING_TAIL) tuple. RING_START is * static for a context, and unique to each, so we only execute @@ -492,8 +491,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) */ spin_lock_irq(&engine->timeline->lock); - rb = engine->execlists.first; - GEM_BUG_ON(rb_first(&engine->execlists.queue) != rb); + rb = execlists->first; + GEM_BUG_ON(rb_first(&execlists->queue) != rb); while (rb) { struct i915_priolist *p = rb_entry(rb, typeof(*p), node); struct drm_i915_gem_request *rq, *rn; @@ -516,7 +515,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) * combine this request with the last, then we * are done. */ - if (port != engine->execlists.port) { + if (port != execlists->port) { __list_del_many(&p->requests, &rq->priotree.link); goto done; @@ -541,25 +540,27 @@ static void execlists_dequeue(struct intel_engine_cs *engine) if (submit) port_assign(port, last); port++; + + GEM_BUG_ON(port_isset(port)); } INIT_LIST_HEAD(&rq->priotree.link); rq->priotree.priority = INT_MAX; __i915_gem_request_submit(rq); - trace_i915_gem_request_in(rq, port_index(port, engine)); + trace_i915_gem_request_in(rq, port_index(port, execlists)); last = rq; submit = true; } rb = rb_next(rb); - rb_erase(&p->node, &engine->execlists.queue); + rb_erase(&p->node, &execlists->queue); INIT_LIST_HEAD(&p->requests); if (p->priority != I915_PRIORITY_NORMAL) kmem_cache_free(engine->i915->priorities, p); } done: - engine->execlists.first = rb; + execlists->first = rb; if (submit) port_assign(port, last); spin_unlock_irq(&engine->timeline->lock); @@ -748,8 +749,7 @@ static void intel_lrc_irq_handler(unsigned long data) trace_i915_gem_request_out(rq); i915_gem_request_put(rq); - port[0] = port[1]; - memset(&port[1], 0, sizeof(port[1])); + execlists_port_complete(execlists, port); } else { port_set(port, port_pack(rq, count)); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 421e769adb79..0eae5936bc3c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -228,7 +228,7 @@ struct intel_engine_execlists { #define port_unpack(p, count) ptr_unpack_bits((p)->request_count, count, EXECLIST_COUNT_BITS) #define port_set(p, packed) ((p)->request_count = (packed)) #define port_isset(p) ((p)->request_count) -#define port_index(p, e) ((p) - (e)->execlists.port) +#define port_index(p, execlists) ((p) - (execlists)->port) /** * @context_id: context ID for port @@ -511,6 +511,18 @@ struct intel_engine_cs { u32 (*get_cmd_length_mask)(u32 cmd_header); }; +static inline void +execlists_port_complete(struct intel_engine_execlists * const execlists, + struct execlist_port * const port) +{ + struct execlist_port * const port1 = &execlists->port[1]; + + GEM_BUG_ON(port_index(port, execlists) != 0); + + *port = *port1; + memset(port1, 0, sizeof(struct execlist_port)); +} + static inline unsigned int intel_engine_flag(const struct intel_engine_cs *engine) { -- cgit v1.2.3 From 76e70087d360fdbe97f24c205d585ada04126e5f Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 22 Sep 2017 15:43:07 +0300 Subject: drm/i915: Make execlist port count variable As we emulate execlists on top of the GuC workqueue, it is not restricted to just 2 ports and we can increase that number arbitrarily to trade-off queue depth (i.e. scheduling latency) against pipeline bubbles. v2: rebase. better commit msg (Chris) v3: rebase Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170922124307.10914-5-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 10 +++++----- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/i915_gpu_error.c | 17 ++++++++++++----- drivers/gpu/drm/i915/i915_guc_submission.c | 8 ++++++-- drivers/gpu/drm/i915/intel_engine_cs.c | 4 ++++ drivers/gpu/drm/i915/intel_lrc.c | 6 ++++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 21 +++++++++++++++++---- 7 files changed, 50 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 87e06da55a69..d10d71aa4b0e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3312,6 +3312,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) if (i915_modparams.enable_execlists) { const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; + struct intel_engine_execlists * const execlists = &engine->execlists; u32 ptr, read, write; unsigned int idx; @@ -3323,7 +3324,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) read = GEN8_CSB_READ_PTR(ptr); write = GEN8_CSB_WRITE_PTR(ptr); seq_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s\n", - read, engine->execlists.csb_head, + read, execlists->csb_head, write, intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)), yesno(test_bit(ENGINE_IRQ_EXECLIST, @@ -3345,11 +3346,10 @@ static int i915_engine_info(struct seq_file *m, void *unused) } rcu_read_lock(); - for (idx = 0; idx < ARRAY_SIZE(engine->execlists.port); idx++) { + for (idx = 0; idx < execlists_num_ports(execlists); idx++) { unsigned int count; - rq = port_unpack(&engine->execlists.port[idx], - &count); + rq = port_unpack(&execlists->port[idx], &count); if (rq) { seq_printf(m, "\t\tELSP[%d] count=%d, ", idx, count); @@ -3362,7 +3362,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) rcu_read_unlock(); spin_lock_irq(&engine->timeline->lock); - for (rb = engine->execlists.first; rb; rb = rb_next(rb)) { + for (rb = execlists->first; rb; rb = rb_next(rb)) { struct i915_priolist *p = rb_entry(rb, typeof(*p), node); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d6babe7d362d..0f26aa57a922 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1001,7 +1001,8 @@ struct i915_gpu_state { u32 seqno; u32 head; u32 tail; - } *requests, execlist[2]; + } *requests, execlist[EXECLIST_MAX_PORTS]; + unsigned int num_ports; struct drm_i915_error_waiter { char comm[TASK_COMM_LEN]; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 20a1f034bf95..881fbe8d179b 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -396,6 +396,8 @@ static void error_print_context(struct drm_i915_error_state_buf *m, static void error_print_engine(struct drm_i915_error_state_buf *m, const struct drm_i915_error_engine *ee) { + int n; + err_printf(m, "%s command stream:\n", engine_str(ee->engine_id)); err_printf(m, " START: 0x%08x\n", ee->start); err_printf(m, " HEAD: 0x%08x [0x%08x]\n", ee->head, ee->rq_head); @@ -465,8 +467,11 @@ static void error_print_engine(struct drm_i915_error_state_buf *m, jiffies_to_msecs(jiffies - ee->hangcheck_timestamp)); err_printf(m, " engine reset count: %u\n", ee->reset_count); - error_print_request(m, " ELSP[0]: ", &ee->execlist[0]); - error_print_request(m, " ELSP[1]: ", &ee->execlist[1]); + for (n = 0; n < ee->num_ports; n++) { + err_printf(m, " ELSP[%d]:", n); + error_print_request(m, " ", &ee->execlist[n]); + } + error_print_context(m, " Active context: ", &ee->context); } @@ -1327,17 +1332,19 @@ static void engine_record_requests(struct intel_engine_cs *engine, static void error_record_engine_execlists(struct intel_engine_cs *engine, struct drm_i915_error_engine *ee) { - const struct execlist_port *port = engine->execlists.port; + const struct intel_engine_execlists * const execlists = &engine->execlists; unsigned int n; - for (n = 0; n < ARRAY_SIZE(engine->execlists.port); n++) { - struct drm_i915_gem_request *rq = port_request(&port[n]); + for (n = 0; n < execlists_num_ports(execlists); n++) { + struct drm_i915_gem_request *rq = port_request(&execlists->port[n]); if (!rq) break; record_request(rq, &ee->execlist[n]); } + + ee->num_ports = n; } static void record_context(struct drm_i915_error_context *e, diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 55e15a57c3d9..04f1281d81a5 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -562,6 +562,8 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port *port = execlists->port; struct drm_i915_gem_request *last = NULL; + const struct execlist_port * const last_port = + &execlists->port[execlists->port_mask]; bool submit = false; struct rb_node *rb; @@ -577,7 +579,7 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { if (last && rq->ctx != last->ctx) { - if (port != execlists->port) { + if (port == last_port) { __list_del_many(&p->requests, &rq->priotree.link); goto done; @@ -617,6 +619,8 @@ static void i915_guc_irq_handler(unsigned long data) struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port *port = execlists->port; + const struct execlist_port * const last_port = + &execlists->port[execlists->port_mask]; struct drm_i915_gem_request *rq; rq = port_request(&port[0]); @@ -629,7 +633,7 @@ static void i915_guc_irq_handler(unsigned long data) rq = port_request(&port[0]); } - if (!port_isset(&port[1])) + if (!port_isset(last_port)) i915_guc_dequeue(engine); } diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 30035e59a784..a28e2a864cf1 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -405,6 +405,10 @@ static void intel_engine_init_execlist(struct intel_engine_cs *engine) execlists->csb_use_mmio = csb_force_mmio(engine->i915); + execlists->port_mask = 1; + BUILD_BUG_ON_NOT_POWER_OF_2(execlists_num_ports(execlists)); + GEM_BUG_ON(execlists_num_ports(execlists) > EXECLIST_MAX_PORTS); + execlists->queue = RB_ROOT; execlists->first = NULL; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3b03f19f1395..f91e126a7f97 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -399,7 +399,7 @@ static void execlists_submit_ports(struct intel_engine_cs *engine) engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine)); unsigned int n; - for (n = ARRAY_SIZE(engine->execlists.port); n--; ) { + for (n = execlists_num_ports(&engine->execlists); n--; ) { struct drm_i915_gem_request *rq; unsigned int count; u64 desc; @@ -456,6 +456,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) struct drm_i915_gem_request *last; struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port *port = execlists->port; + const struct execlist_port * const last_port = + &execlists->port[execlists->port_mask]; struct rb_node *rb; bool submit = false; @@ -515,7 +517,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) * combine this request with the last, then we * are done. */ - if (port != execlists->port) { + if (port == last_port) { __list_del_many(&p->requests, &rq->priotree.link); goto done; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 0eae5936bc3c..56d7ae9f298b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -234,7 +234,14 @@ struct intel_engine_execlists { * @context_id: context ID for port */ GEM_DEBUG_DECL(u32 context_id); - } port[2]; + +#define EXECLIST_MAX_PORTS 2 + } port[EXECLIST_MAX_PORTS]; + + /** + * @port_mask: number of execlist ports - 1 + */ + unsigned int port_mask; /** * @queue: queue of requests, in priority lists @@ -511,16 +518,22 @@ struct intel_engine_cs { u32 (*get_cmd_length_mask)(u32 cmd_header); }; +static inline unsigned int +execlists_num_ports(const struct intel_engine_execlists * const execlists) +{ + return execlists->port_mask + 1; +} + static inline void execlists_port_complete(struct intel_engine_execlists * const execlists, struct execlist_port * const port) { - struct execlist_port * const port1 = &execlists->port[1]; + const unsigned int m = execlists->port_mask; GEM_BUG_ON(port_index(port, execlists) != 0); - *port = *port1; - memset(port1, 0, sizeof(struct execlist_port)); + memmove(port, port + 1, m * sizeof(struct execlist_port)); + memset(port + m, 0, sizeof(struct execlist_port)); } static inline unsigned int -- cgit v1.2.3 From 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 22 Sep 2017 23:43:25 +0300 Subject: USB: devio: Prevent integer overflow in proc_do_submiturb() There used to be an integer overflow check in proc_do_submiturb() but we removed it. It turns out that it's still required. The uurb->buffer_length variable is a signed integer and it's controlled by the user. It can lead to an integer overflow when we do: num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); If we strip away the macro then that line looks like this: num_sgs = (uurb->buffer_length + USB_SG_SIZE - 1) / USB_SG_SIZE; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It's the first addition which can overflow. Fixes: 1129d270cbfb ("USB: Increase usbfs transfer limit") Cc: stable Signed-off-by: Dan Carpenter Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 318bb3b96687..e9326f31db8d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -140,6 +140,9 @@ module_param(usbfs_memory_mb, uint, 0644); MODULE_PARM_DESC(usbfs_memory_mb, "maximum MB allowed for usbfs buffers (0 = no limit)"); +/* Hard limit, necessary to avoid arithmetic overflow */ +#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000) + static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */ /* Check whether it's okay to allocate more memory for a transfer */ @@ -1460,6 +1463,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb USBDEVFS_URB_ZERO_PACKET | USBDEVFS_URB_NO_INTERRUPT)) return -EINVAL; + if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX) + return -EINVAL; if (uurb->buffer_length > 0 && !uurb->buffer) return -EINVAL; if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && -- cgit v1.2.3 From fa1ed74eb1c233be6131ec92df21ab46499a15b6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 22 Sep 2017 23:43:46 +0300 Subject: USB: devio: Don't corrupt user memory The user buffer has "uurb->buffer_length" bytes. If the kernel has more information than that, we should truncate it instead of writing past the end of the user's buffer. I added a WARN_ONCE() to help the user debug the issue. Reported-by: Alan Stern Cc: stable Signed-off-by: Dan Carpenter Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e9326f31db8d..4664e543cf2f 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1576,7 +1576,11 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb totlen += isopkt[u].length; } u *= sizeof(struct usb_iso_packet_descriptor); - uurb->buffer_length = totlen; + if (totlen <= uurb->buffer_length) + uurb->buffer_length = totlen; + else + WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d", + totlen, uurb->buffer_length); break; default: -- cgit v1.2.3 From 8fec9355a968ad240f3a2e9ad55b823cf1cc52ff Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 22 Sep 2017 22:18:18 +0200 Subject: USB: cdc-wdm: ignore -EPIPE from GetEncapsulatedResponse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver will forward errors to userspace after turning most of them into -EIO. But all status codes are not equal. The -EPIPE (stall) in particular can be seen more as a result of normal USB signaling than an actual error. The state is automatically cleared by the USB core without intervention from either driver or userspace. And most devices and firmwares will never trigger a stall as a result of GetEncapsulatedResponse. This is in fact a requirement for CDC WDM devices. Quoting from section 7.1 of the CDC WMC spec revision 1.1: The function shall not return STALL in response to GetEncapsulatedResponse. But this driver is also handling GetEncapsulatedResponse on behalf of the qmi_wwan and cdc_mbim drivers. Unfortunately the relevant specs are not as clear wrt stall. So some QMI and MBIM devices *will* occasionally stall, causing the GetEncapsulatedResponse to return an -EPIPE status. Translating this into -EIO for userspace has proven to be harmful. Treating it as an empty read is safer, making the driver behave as if the device was conforming to the CDC WDM spec. There have been numerous reports of issues related to -EPIPE errors from some newer CDC MBIM devices in particular, like for example the Fibocom L831-EAU. Testing on this device has shown that the issues go away if we simply ignore the -EPIPE status. Similar handling of -EPIPE is already known from e.g. usb_get_string() The -EPIPE log message is still kept to let us track devices with this unexpected behaviour, hoping that it attracts attention from firmware developers. Cc: Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100938 Reported-and-tested-by: Christian Ehrig Reported-and-tested-by: Patrick Chilton Reported-and-tested-by: Andreas Böhler Signed-off-by: Bjørn Mork Acked-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 5aacea1978a5..3e865dbf878c 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -190,8 +190,10 @@ static void wdm_in_callback(struct urb *urb) /* * only set a new error if there is no previous error. * Errors are only cleared during read/open + * Avoid propagating -EPIPE (stall) to userspace since it is + * better handled as an empty read */ - if (desc->rerr == 0) + if (desc->rerr == 0 && status != -EPIPE) desc->rerr = status; if (length + desc->length > desc->wMaxCommand) { -- cgit v1.2.3 From 604a8f6f1e33ed53529a117baec92d28e746a601 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 21 Sep 2017 14:54:43 +0100 Subject: drm/i915/lrc: Only enable per-context and per-bb buffers if set The per-context and per-batch workaround buffers are optional, yet we tell the GPU to execute them even if they contain no instructions. Doing so incurs the dispatch latency, which we can avoid if we don't ask the GPU to execute the no-op buffers. Allow ourselves to skip setup of empty buffer, and then to only enable non-empty buffers in the context image. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170921135444.27330-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_lrc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f91e126a7f97..8d158deda328 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1278,7 +1278,8 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine) ret = -EINVAL; break; } - batch_ptr = wa_bb_fn[i](engine, batch_ptr); + if (wa_bb_fn[i]) + batch_ptr = wa_bb_fn[i](engine, batch_ptr); wa_bb[i]->size = batch_ptr - (batch + wa_bb[i]->offset); } @@ -1986,13 +1987,12 @@ static void execlists_init_reg_state(u32 *regs, CTX_REG(regs, CTX_SECOND_BB_HEAD_L, RING_SBBADDR(base), 0); CTX_REG(regs, CTX_SECOND_BB_STATE, RING_SBBSTATE(base), 0); if (rcs) { - CTX_REG(regs, CTX_BB_PER_CTX_PTR, RING_BB_PER_CTX_PTR(base), 0); + struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx; + CTX_REG(regs, CTX_RCS_INDIRECT_CTX, RING_INDIRECT_CTX(base), 0); CTX_REG(regs, CTX_RCS_INDIRECT_CTX_OFFSET, RING_INDIRECT_CTX_OFFSET(base), 0); - - if (engine->wa_ctx.vma) { - struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx; + if (wa_ctx->indirect_ctx.size) { u32 ggtt_offset = i915_ggtt_offset(wa_ctx->vma); regs[CTX_RCS_INDIRECT_CTX + 1] = @@ -2001,6 +2001,11 @@ static void execlists_init_reg_state(u32 *regs, regs[CTX_RCS_INDIRECT_CTX_OFFSET + 1] = intel_lr_indirect_ctx_offset(engine) << 6; + } + + CTX_REG(regs, CTX_BB_PER_CTX_PTR, RING_BB_PER_CTX_PTR(base), 0); + if (wa_ctx->per_ctx.size) { + u32 ggtt_offset = i915_ggtt_offset(wa_ctx->vma); regs[CTX_BB_PER_CTX_PTR + 1] = (ggtt_offset + wa_ctx->per_ctx.offset) | 0x01; -- cgit v1.2.3 From b8aa223341a9bfc68285c47474f5150225504584 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 21 Sep 2017 14:54:44 +0100 Subject: drm/i915/lrc: Skip no-op per-bb buffer on gen9 Since we inherited the context image setup from gen8 which needed a per-bb workaround (for GPGPU), we are submitting an empty per-bb buffer on gen9. Now that we can skip adding the buffer to the context image, remove the dangling per-bb. This slightly improves execution latency, most notably on an idle engine. References: https://bugs.freedesktop.org/show_bug.cgi?id=87725 Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170921135444.27330-2-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_lrc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8d158deda328..3623403a4f2d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1184,13 +1184,6 @@ static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) return batch; } -static u32 *gen9_init_perctx_bb(struct intel_engine_cs *engine, u32 *batch) -{ - *batch++ = MI_BATCH_BUFFER_END; - - return batch; -} - #define CTX_WA_BB_OBJ_SIZE (PAGE_SIZE) static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) @@ -1247,7 +1240,7 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine) return 0; case 9: wa_bb_fn[0] = gen9_init_indirectctx_bb; - wa_bb_fn[1] = gen9_init_perctx_bb; + wa_bb_fn[1] = NULL; break; case 8: wa_bb_fn[0] = gen8_init_indirectctx_bb; -- cgit v1.2.3 From dd59a9ba952752abecf4eb95287fb8c64fdb4499 Mon Sep 17 00:00:00 2001 From: "Pandiyan, Dhinakaran" Date: Mon, 18 Sep 2017 15:21:37 -0700 Subject: drm/i915/mst: Debug log connector name in destroy_connector() Print connector name in destroy_connect() and this doesn't add any extra lines to dmesg. The debug macro has been moved before the unregister call so that we don't lose the connector name and id. Signed-off-by: Dhinakaran Pandiyan Reviewed-by: James Ausmus Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170918222141.4674-1-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp_mst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 8e3aad0ea60b..88d1d2b9ac56 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -494,6 +494,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_i915_private *dev_priv = to_i915(connector->dev); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); drm_connector_unregister(connector); if (dev_priv->fbdev) @@ -505,7 +506,6 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, drm_modeset_unlock(&connector->dev->mode_config.connection_mutex); drm_connector_unreference(connector); - DRM_DEBUG_KMS("\n"); } static void intel_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) -- cgit v1.2.3 From 9b1c581885c985b84d36a9ffa519a9b2e68708e1 Mon Sep 17 00:00:00 2001 From: "Pandiyan, Dhinakaran" Date: Mon, 18 Sep 2017 15:21:38 -0700 Subject: drm/i915/mst: Print active mst links after update Both mst_disable_dp and mst_post_disable_dp print number of active links before the variable has been updated. Move the print statement in mst_disable_dp after the decrement so that the printed values indicate the disabing of a mst connector. Also, add some text to clarify what we are printing. Signed-off-by: Dhinakaran Pandiyan Reviewed-by: James Ausmus Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170918222141.4674-2-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp_mst.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 88d1d2b9ac56..9a396f483f8b 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -133,7 +133,7 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder, to_intel_connector(old_conn_state->connector); int ret; - DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); + DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port); @@ -155,8 +155,6 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); - /* this can fail */ drm_dp_check_act_status(&intel_dp->mst_mgr); /* and this can also fail */ @@ -173,6 +171,7 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); } + DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); } static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, @@ -195,7 +194,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, connector->encoder = encoder; intel_mst->connector = connector; - DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); + DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); if (intel_dp->active_mst_links == 0) intel_dig_port->base.pre_enable(&intel_dig_port->base, @@ -229,7 +228,7 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder, enum port port = intel_dig_port->port; int ret; - DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); + DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); if (intel_wait_for_register(dev_priv, DP_TP_STATUS(port), -- cgit v1.2.3 From e8b2577c5e312d175ed11a35a12346b19059277d Mon Sep 17 00:00:00 2001 From: "Pandiyan, Dhinakaran" Date: Mon, 18 Sep 2017 15:21:39 -0700 Subject: drm/i915/dp: Fix buffer size for sink_irq_esi read The buffer size defined is 16 bytes whereas only 14 bytes are read. Add a macro to avoid this discrepancy. Signed-off-by: Dhinakaran Pandiyan Reviewed-by: James Ausmus Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170918222141.4674-3-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 48ed6c1b5a76..ff04b3616f95 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -42,6 +42,7 @@ #include "i915_drv.h" #define DP_LINK_CHECK_TIMEOUT (10 * 1000) +#define DP_DPRX_ESI_LEN 14 /* Compliance test status bits */ #define INTEL_DP_RESOLUTION_SHIFT_MASK 0 @@ -4013,15 +4014,9 @@ intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector) static bool intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector) { - int ret; - - ret = drm_dp_dpcd_read(&intel_dp->aux, - DP_SINK_COUNT_ESI, - sink_irq_vector, 14); - if (ret != 14) - return false; - - return true; + return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, + sink_irq_vector, DP_DPRX_ESI_LEN) == + DP_DPRX_ESI_LEN; } static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp) @@ -4221,7 +4216,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) bool bret; if (intel_dp->is_mst) { - u8 esi[16] = { 0 }; + u8 esi[DP_DPRX_ESI_LEN] = { 0 }; int ret = 0; int retry; bool handled; -- cgit v1.2.3 From 3bc31a7f4d376083b972acdc1a580e05c3a6dc12 Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Mon, 18 Sep 2017 15:21:41 -0700 Subject: drm/i915/dp: Remove useless debug about TPS3 support We already print training pattern used during link training and also print if the source or sink does not support TPS3 for HBR2 link rates, see intel_dp_training_pattern(). Signed-off-by: Dhinakaran Pandiyan Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170918222141.4674-5-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ff04b3616f95..90e756c76f10 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4753,10 +4753,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) if (intel_encoder->type != INTEL_OUTPUT_EDP) intel_encoder->type = INTEL_OUTPUT_DP; - DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n", - yesno(intel_dp_source_supports_hbr2(intel_dp)), - yesno(drm_dp_tps3_supported(intel_dp->dpcd))); - if (intel_dp->reset_link_params) { /* Initial max link lane count */ intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); -- cgit v1.2.3 From dff457d74e7eaf8c5280967467597ebfc3e2e44a Mon Sep 17 00:00:00 2001 From: David Weinehall Date: Tue, 5 Sep 2017 16:10:50 +0300 Subject: drm/i915: Speed up DMC firmware loading Currently we're doing: 1. acquire lock 2. write word to hardware 3. release lock 4. repeat from 1 to load the DMC firmware. Due to the cost of acquiring/releasing a lock, and the size of the DMC firmware, this slows down DMC loading a lot. This patch simply acquires the lock, writes the entire firmware, then releases the lock. Testing shows resume speedups in the order of 10ms on platforms with DMC firmware (GEN9+). v2: Per feedback from Chris & Ville there's no need to do the whole forcewake dance, so lose that bit (Chris, Ville) v3: Actually send the new version of the patch... v4: Don't acquire the uncore lock. Disable preempt. (Chris) Signed-off-by: David Weinehall Link: https://patchwork.freedesktop.org/patch/msgid/20170905131050.11655-1-david.weinehall@linux.intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_csr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 965988f79a55..cdfb624eb82d 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -252,8 +252,14 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv) } fw_size = dev_priv->csr.dmc_fw_size; + assert_rpm_wakelock_held(dev_priv); + + preempt_disable(); + for (i = 0; i < fw_size; i++) - I915_WRITE(CSR_PROGRAM(i), payload[i]); + I915_WRITE_FW(CSR_PROGRAM(i), payload[i]); + + preempt_enable(); for (i = 0; i < dev_priv->csr.mmio_count; i++) { I915_WRITE(dev_priv->csr.mmioaddr[i], -- cgit v1.2.3 From 6b12ca569bb2f864892c41dbbb0f88f3f9952bf3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 14 Sep 2017 18:17:31 +0300 Subject: drm/i915: Don't rmw PIPESTAT enable bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i830 seems to occasionally forget the PIPESTAT enable bits when we read the register. These aren't the only registers on i830 that have problems with RMW, as reading the double buffered plane registers returns the latched value rather than the last written value. So something similar is perhaps going on with PIPESTAT. This corruption results on vblank interrupts occasionally turning off on their own, which leads to vblank timeouts and generally a stuck display subsystem. So let's not RMW the pipestat enable bits, and instead use the cached copy we have around. Cc: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170914151731.5034-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_irq.c | 135 ++++++++++++----------------- drivers/gpu/drm/i915/intel_fifo_underrun.c | 14 +-- 3 files changed, 66 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0f26aa57a922..44f5569ed995 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3313,6 +3313,8 @@ static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv) return dev_priv->vgpu.active; } +u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, + enum pipe pipe); void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 status_mask); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index af82bd721dbc..6a07ef38fb47 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -567,62 +567,16 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, POSTING_READ(SDEIMR); } -static void -__i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, - u32 enable_mask, u32 status_mask) +u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, + enum pipe pipe) { - i915_reg_t reg = PIPESTAT(pipe); - u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; - - lockdep_assert_held(&dev_priv->irq_lock); - WARN_ON(!intel_irqs_enabled(dev_priv)); - - if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || - status_mask & ~PIPESTAT_INT_STATUS_MASK, - "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", - pipe_name(pipe), enable_mask, status_mask)) - return; - - if ((pipestat & enable_mask) == enable_mask) - return; - - dev_priv->pipestat_irq_mask[pipe] |= status_mask; - - /* Enable the interrupt, clear any pending status */ - pipestat |= enable_mask | status_mask; - I915_WRITE(reg, pipestat); - POSTING_READ(reg); -} - -static void -__i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, - u32 enable_mask, u32 status_mask) -{ - i915_reg_t reg = PIPESTAT(pipe); - u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; + u32 status_mask = dev_priv->pipestat_irq_mask[pipe]; + u32 enable_mask = status_mask << 16; lockdep_assert_held(&dev_priv->irq_lock); - WARN_ON(!intel_irqs_enabled(dev_priv)); - - if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || - status_mask & ~PIPESTAT_INT_STATUS_MASK, - "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", - pipe_name(pipe), enable_mask, status_mask)) - return; - - if ((pipestat & enable_mask) == 0) - return; - - dev_priv->pipestat_irq_mask[pipe] &= ~status_mask; - - pipestat &= ~enable_mask; - I915_WRITE(reg, pipestat); - POSTING_READ(reg); -} -static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask) -{ - u32 enable_mask = status_mask << 16; + if (INTEL_GEN(dev_priv) < 5) + goto out; /* * On pipe A we don't support the PSR interrupt yet, @@ -645,35 +599,59 @@ static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask) if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV) enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV; +out: + WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || + status_mask & ~PIPESTAT_INT_STATUS_MASK, + "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", + pipe_name(pipe), enable_mask, status_mask); + return enable_mask; } -void -i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, - u32 status_mask) +void i915_enable_pipestat(struct drm_i915_private *dev_priv, + enum pipe pipe, u32 status_mask) { + i915_reg_t reg = PIPESTAT(pipe); u32 enable_mask; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, - status_mask); - else - enable_mask = status_mask << 16; - __i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask); + WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK, + "pipe %c: status_mask=0x%x\n", + pipe_name(pipe), status_mask); + + lockdep_assert_held(&dev_priv->irq_lock); + WARN_ON(!intel_irqs_enabled(dev_priv)); + + if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == status_mask) + return; + + dev_priv->pipestat_irq_mask[pipe] |= status_mask; + enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); + + I915_WRITE(reg, enable_mask | status_mask); + POSTING_READ(reg); } -void -i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, - u32 status_mask) +void i915_disable_pipestat(struct drm_i915_private *dev_priv, + enum pipe pipe, u32 status_mask) { + i915_reg_t reg = PIPESTAT(pipe); u32 enable_mask; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, - status_mask); - else - enable_mask = status_mask << 16; - __i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask); + WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK, + "pipe %c: status_mask=0x%x\n", + pipe_name(pipe), status_mask); + + lockdep_assert_held(&dev_priv->irq_lock); + WARN_ON(!intel_irqs_enabled(dev_priv)); + + if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == 0) + return; + + dev_priv->pipestat_irq_mask[pipe] &= ~status_mask; + enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); + + I915_WRITE(reg, enable_mask | status_mask); + POSTING_READ(reg); } /** @@ -1775,7 +1753,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, for_each_pipe(dev_priv, pipe) { i915_reg_t reg; - u32 mask, iir_bit = 0; + u32 status_mask, enable_mask, iir_bit = 0; /* * PIPESTAT bits get signalled even when the interrupt is @@ -1786,7 +1764,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, */ /* fifo underruns are filterered in the underrun handler. */ - mask = PIPE_FIFO_UNDERRUN_STATUS; + status_mask = PIPE_FIFO_UNDERRUN_STATUS; switch (pipe) { case PIPE_A: @@ -1800,21 +1778,20 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, break; } if (iir & iir_bit) - mask |= dev_priv->pipestat_irq_mask[pipe]; + status_mask |= dev_priv->pipestat_irq_mask[pipe]; - if (!mask) + if (!status_mask) continue; reg = PIPESTAT(pipe); - mask |= PIPESTAT_INT_ENABLE_MASK; - pipe_stats[pipe] = I915_READ(reg) & mask; + pipe_stats[pipe] = I915_READ(reg) & status_mask; + enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); /* * Clear the PIPE*STAT regs before the IIR */ - if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS | - PIPESTAT_INT_STATUS_MASK)) - I915_WRITE(reg, pipe_stats[pipe]); + if (pipe_stats[pipe]) + I915_WRITE(reg, enable_mask | pipe_stats[pipe]); } spin_unlock(&dev_priv->irq_lock); } diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 04689600e337..77c123cc8817 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -88,14 +88,15 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); i915_reg_t reg = PIPESTAT(crtc->pipe); - u32 pipestat = I915_READ(reg) & 0xffff0000; + u32 enable_mask; lockdep_assert_held(&dev_priv->irq_lock); - if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0) + if ((I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0) return; - I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); + enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe); + I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); POSTING_READ(reg); trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe); @@ -108,15 +109,16 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, { struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t reg = PIPESTAT(pipe); - u32 pipestat = I915_READ(reg) & 0xffff0000; lockdep_assert_held(&dev_priv->irq_lock); if (enable) { - I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); + u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); + + I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); POSTING_READ(reg); } else { - if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS) + if (old && I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); } } -- cgit v1.2.3 From 62e082430ea4bb5b28909ca4375bb683931e22aa Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 20 Sep 2017 07:29:49 -0400 Subject: dm ioctl: fix alignment of event number in the device list The size of struct dm_name_list is different on 32-bit and 64-bit kernels (so "(nl + 1)" differs between 32-bit and 64-bit kernels). This mismatch caused some harmless difference in padding when using 32-bit or 64-bit kernel. Commit 23d70c5e52dd ("dm ioctl: report event number in DM_LIST_DEVICES") added reporting event number in the output of DM_LIST_DEVICES_CMD. This difference in padding makes it impossible for userspace to determine the location of the event number (the location would be different when running on 32-bit and 64-bit kernels). Fix the padding by using offsetof(struct dm_name_list, name) instead of sizeof(struct dm_name_list) to determine the location of entries. Also, the ioctl version number is incremented to 37 so that userspace can use the version number to determine that the event number is present and correctly located. In addition, a global event is now raised when a DM device is created, removed, renamed or when table is swapped, so that the user can monitor for device changes. Reported-by: Eugene Syromiatnikov Fixes: 23d70c5e52dd ("dm ioctl: report event number in DM_LIST_DEVICES") Cc: stable@vger.kernel.org # 4.13 Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/dm-core.h | 1 + drivers/md/dm-ioctl.c | 37 ++++++++++++++++++++++++------------- drivers/md/dm.c | 10 ++++++++-- include/uapi/linux/dm-ioctl.h | 4 ++-- 4 files changed, 35 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h index 24eddbdf2ab4..203144762f36 100644 --- a/drivers/md/dm-core.h +++ b/drivers/md/dm-core.h @@ -149,5 +149,6 @@ static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen extern atomic_t dm_global_event_nr; extern wait_queue_head_t dm_global_eventq; +void dm_issue_global_event(void); #endif diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 8756a6850431..e52676fa9832 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -477,9 +477,13 @@ static int remove_all(struct file *filp, struct dm_ioctl *param, size_t param_si * Round up the ptr to an 8-byte boundary. */ #define ALIGN_MASK 7 +static inline size_t align_val(size_t val) +{ + return (val + ALIGN_MASK) & ~ALIGN_MASK; +} static inline void *align_ptr(void *ptr) { - return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK); + return (void *)align_val((size_t)ptr); } /* @@ -505,7 +509,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ struct hash_cell *hc; size_t len, needed = 0; struct gendisk *disk; - struct dm_name_list *nl, *old_nl = NULL; + struct dm_name_list *orig_nl, *nl, *old_nl = NULL; uint32_t *event_nr; down_write(&_hash_lock); @@ -516,17 +520,15 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ */ for (i = 0; i < NUM_BUCKETS; i++) { list_for_each_entry (hc, _name_buckets + i, name_list) { - needed += sizeof(struct dm_name_list); - needed += strlen(hc->name) + 1; - needed += ALIGN_MASK; - needed += (sizeof(uint32_t) + ALIGN_MASK) & ~ALIGN_MASK; + needed += align_val(offsetof(struct dm_name_list, name) + strlen(hc->name) + 1); + needed += align_val(sizeof(uint32_t)); } } /* * Grab our output buffer. */ - nl = get_result_buffer(param, param_size, &len); + nl = orig_nl = get_result_buffer(param, param_size, &len); if (len < needed) { param->flags |= DM_BUFFER_FULL_FLAG; goto out; @@ -549,11 +551,16 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_ strcpy(nl->name, hc->name); old_nl = nl; - event_nr = align_ptr(((void *) (nl + 1)) + strlen(hc->name) + 1); + event_nr = align_ptr(nl->name + strlen(hc->name) + 1); *event_nr = dm_get_event_nr(hc->md); nl = align_ptr(event_nr + 1); } } + /* + * If mismatch happens, security may be compromised due to buffer + * overflow, so it's better to crash. + */ + BUG_ON((char *)nl - (char *)orig_nl != needed); out: up_write(&_hash_lock); @@ -1621,7 +1628,8 @@ static int target_message(struct file *filp, struct dm_ioctl *param, size_t para * which has a variable size, is not used by the function processing * the ioctl. */ -#define IOCTL_FLAGS_NO_PARAMS 1 +#define IOCTL_FLAGS_NO_PARAMS 1 +#define IOCTL_FLAGS_ISSUE_GLOBAL_EVENT 2 /*----------------------------------------------------------------- * Implementation of open/close/ioctl on the special char @@ -1635,12 +1643,12 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags) ioctl_fn fn; } _ioctls[] = { {DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */ - {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all}, + {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, remove_all}, {DM_LIST_DEVICES_CMD, 0, list_devices}, - {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create}, - {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove}, - {DM_DEV_RENAME_CMD, 0, dev_rename}, + {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_create}, + {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_remove}, + {DM_DEV_RENAME_CMD, IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_rename}, {DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend}, {DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status}, {DM_DEV_WAIT_CMD, 0, dev_wait}, @@ -1869,6 +1877,9 @@ static int ctl_ioctl(struct file *file, uint command, struct dm_ioctl __user *us unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS)) DMERR("ioctl %d tried to output some data but has IOCTL_FLAGS_NO_PARAMS set", cmd); + if (!r && ioctl_flags & IOCTL_FLAGS_ISSUE_GLOBAL_EVENT) + dm_issue_global_event(); + /* * Copy the results back to userland. */ diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 6e54145969c5..4be85324f44d 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -52,6 +52,12 @@ static struct workqueue_struct *deferred_remove_workqueue; atomic_t dm_global_event_nr = ATOMIC_INIT(0); DECLARE_WAIT_QUEUE_HEAD(dm_global_eventq); +void dm_issue_global_event(void) +{ + atomic_inc(&dm_global_event_nr); + wake_up(&dm_global_eventq); +} + /* * One of these is allocated per bio. */ @@ -1865,9 +1871,8 @@ static void event_callback(void *context) dm_send_uevents(&uevents, &disk_to_dev(md->disk)->kobj); atomic_inc(&md->event_nr); - atomic_inc(&dm_global_event_nr); wake_up(&md->eventq); - wake_up(&dm_global_eventq); + dm_issue_global_event(); } /* @@ -2283,6 +2288,7 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table) } map = __bind(md, table, &limits); + dm_issue_global_event(); out: mutex_unlock(&md->suspend_lock); diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h index 412c06a624c8..ccaea525340b 100644 --- a/include/uapi/linux/dm-ioctl.h +++ b/include/uapi/linux/dm-ioctl.h @@ -269,9 +269,9 @@ enum { #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 36 +#define DM_VERSION_MINOR 37 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2017-06-09)" +#define DM_VERSION_EXTRA "-ioctl (2017-09-20)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ -- cgit v1.2.3 From eb35279dd7c7834d6320edf24e1b9786d31e4899 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Wed, 24 May 2017 22:52:29 -0700 Subject: iio: proximity: as3935: noise detection + threshold changes Most applications are too noisy to allow the default noise and watchdog settings, and thus need to be configurable via DT properties. Also default settings to POR defaults on a reset, and register distuber interrupts as noise since it prevents proper usage. Cc: devicetree@vger.kernel.org Signed-off-by: Matt Ranostay Acked-by: Rob Herring Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-proximity-as3935 | 8 ++++ .../devicetree/bindings/iio/proximity/as3935.txt | 5 +++ drivers/iio/proximity/as3935.c | 43 ++++++++++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 index 33e96f740639..147d4e8a1403 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 +++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 @@ -14,3 +14,11 @@ Description: Show or set the gain boost of the amp, from 0-31 range. 18 = indoors (default) 14 = outdoors + +What /sys/bus/iio/devices/iio:deviceX/noise_level_tripped +Date: May 2017 +KernelVersion: 4.13 +Contact: Matt Ranostay +Description: + When 1 the noise level is over the trip level and not reporting + valid data diff --git a/Documentation/devicetree/bindings/iio/proximity/as3935.txt b/Documentation/devicetree/bindings/iio/proximity/as3935.txt index 38d74314b7ab..b6c1afa6f02d 100644 --- a/Documentation/devicetree/bindings/iio/proximity/as3935.txt +++ b/Documentation/devicetree/bindings/iio/proximity/as3935.txt @@ -16,6 +16,10 @@ Optional properties: - ams,tuning-capacitor-pf: Calibration tuning capacitor stepping value 0 - 120pF. This will require using the calibration data from the manufacturer. + - ams,nflwdth: Set the noise and watchdog threshold register on + startup. This will need to set according to the noise from the + MCU board, and possibly the local environment. Refer to the + datasheet for the threshold settings. Example: @@ -27,4 +31,5 @@ as3935@0 { interrupt-parent = <&gpio1>; interrupts = <16 1>; ams,tuning-capacitor-pf = <80>; + ams,nflwdth = <0x44>; }; diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index 0eeff29b61be..4a48b7ba3a1c 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -39,8 +39,12 @@ #define AS3935_AFE_GAIN_MAX 0x1F #define AS3935_AFE_PWR_BIT BIT(0) +#define AS3935_NFLWDTH 0x01 +#define AS3935_NFLWDTH_MASK 0x7f + #define AS3935_INT 0x03 #define AS3935_INT_MASK 0x0f +#define AS3935_DISTURB_INT BIT(2) #define AS3935_EVENT_INT BIT(3) #define AS3935_NOISE_INT BIT(0) @@ -48,6 +52,7 @@ #define AS3935_DATA_MASK 0x3F #define AS3935_TUNE_CAP 0x08 +#define AS3935_DEFAULTS 0x3C #define AS3935_CALIBRATE 0x3D #define AS3935_READ_DATA BIT(14) @@ -62,7 +67,9 @@ struct as3935_state { struct mutex lock; struct delayed_work work; + unsigned long noise_tripped; u32 tune_cap; + u32 nflwdth_reg; u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */ u8 buf[2] ____cacheline_aligned; }; @@ -145,12 +152,29 @@ static ssize_t as3935_sensor_sensitivity_store(struct device *dev, return len; } +static ssize_t as3935_noise_level_tripped_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct as3935_state *st = iio_priv(dev_to_iio_dev(dev)); + int ret; + + mutex_lock(&st->lock); + ret = sprintf(buf, "%d\n", !time_after(jiffies, st->noise_tripped + HZ)); + mutex_unlock(&st->lock); + + return ret; +} + static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR, as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0); +static IIO_DEVICE_ATTR(noise_level_tripped, S_IRUGO, + as3935_noise_level_tripped_show, NULL, 0); static struct attribute *as3935_attributes[] = { &iio_dev_attr_sensor_sensitivity.dev_attr.attr, + &iio_dev_attr_noise_level_tripped.dev_attr.attr, NULL, }; @@ -246,7 +270,11 @@ static void as3935_event_work(struct work_struct *work) case AS3935_EVENT_INT: iio_trigger_poll_chained(st->trig); break; + case AS3935_DISTURB_INT: case AS3935_NOISE_INT: + mutex_lock(&st->lock); + st->noise_tripped = jiffies; + mutex_unlock(&st->lock); dev_warn(&st->spi->dev, "noise level is too high\n"); break; } @@ -269,15 +297,14 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private) static void calibrate_as3935(struct as3935_state *st) { - /* mask disturber interrupt bit */ - as3935_write(st, AS3935_INT, BIT(5)); - + as3935_write(st, AS3935_DEFAULTS, 0x96); as3935_write(st, AS3935_CALIBRATE, 0x96); as3935_write(st, AS3935_TUNE_CAP, BIT(5) | (st->tune_cap / TUNE_CAP_DIV)); mdelay(2); as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV)); + as3935_write(st, AS3935_NFLWDTH, st->nflwdth_reg); } #ifdef CONFIG_PM_SLEEP @@ -370,6 +397,15 @@ static int as3935_probe(struct spi_device *spi) return -EINVAL; } + ret = of_property_read_u32(np, + "ams,nflwdth", &st->nflwdth_reg); + if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) { + dev_err(&spi->dev, + "invalid nflwdth setting of %d\n", + st->nflwdth_reg); + return -EINVAL; + } + indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->channels = as3935_channels; @@ -384,6 +420,7 @@ static int as3935_probe(struct spi_device *spi) return -ENOMEM; st->trig = trig; + st->noise_tripped = jiffies - HZ; trig->dev.parent = indio_dev->dev.parent; iio_trigger_set_drvdata(trig, indio_dev); trig->ops = &iio_interrupt_trigger_ops; -- cgit v1.2.3 From 3f9e6cd8230a413fdf462aba35ea6b6166fa3631 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 Sep 2017 13:49:27 +0100 Subject: drm/i915/execlists: Microoptimise execlists_cancel_port_request() Just rearrange the code slightly to trim the number of iterations required. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170925124929.16974-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/intel_lrc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3623403a4f2d..2c07f3c08bd3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -571,14 +571,17 @@ done: execlists_submit_ports(engine); } -static void execlist_cancel_port_requests(struct intel_engine_execlists *execlists) +static void +execlist_cancel_port_requests(struct intel_engine_execlists *execlists) { - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(execlists->port); i++) - i915_gem_request_put(port_request(&execlists->port[i])); + struct execlist_port *port = execlists->port; + unsigned int num_ports = ARRAY_SIZE(execlists->port); - memset(execlists->port, 0, sizeof(execlists->port)); + while (num_ports-- && port_isset(port)) { + i915_gem_request_put(port_request(port)); + memset(port, 0, sizeof(*port)); + port++; + } } static void execlists_cancel_requests(struct intel_engine_cs *engine) @@ -625,7 +628,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) execlists->queue = RB_ROOT; execlists->first = NULL; - GEM_BUG_ON(port_isset(&execlists->port[0])); + GEM_BUG_ON(port_isset(execlists->port)); /* * The port is checked prior to scheduling a tasklet, but -- cgit v1.2.3 From f61dfff2f5b9fcb087bf5c444bc44b444709588f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 5 Jul 2017 10:14:59 +0200 Subject: iio: pressure: zpa2326: Remove always-true check which confuses gcc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With gcc 4.1.2: drivers/iio/pressure/zpa2326.c: In function ‘zpa2326_wait_oneshot_completion’: drivers/iio/pressure/zpa2326.c:868: warning: ‘ret’ may be used uninitialized in this function When testing for "timeout < 0", timeout is already guaranteed to be strict negative, so the branch is always taken, and ret is thus always initialized. But (some version of) gcc is not smart enough to notice. Remove the check to fix this. As there is no other code in between assigning the error codes and returning them, the error codes can be returned immediately, and the intermediate variable can be dropped. Drop the "else" to please checkpatch. Fixes: e7215fe4d51e69c9 ("iio: pressure: zpa2326: report interrupted case as failure") Signed-off-by: Geert Uytterhoeven Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/zpa2326.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index ebfb1de7377f..91431454eb85 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -865,7 +865,6 @@ complete: static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, struct zpa2326_private *private) { - int ret; unsigned int val; long timeout; @@ -887,14 +886,11 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, /* Timed out. */ zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)", timeout); - ret = -ETIME; - } else if (timeout < 0) { - zpa2326_warn(indio_dev, - "wait for one shot interrupt cancelled"); - ret = -ERESTARTSYS; + return -ETIME; } - return ret; + zpa2326_warn(indio_dev, "wait for one shot interrupt cancelled"); + return -ERESTARTSYS; } static int zpa2326_init_managed_irq(struct device *parent, -- cgit v1.2.3 From a93ad944f4ff9a797abff17c73fc4b1e4a1d9141 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Fri, 22 Sep 2017 15:32:44 -0500 Subject: net: qcom/emac: specify the correct size when mapping a DMA buffer When mapping the RX DMA buffers, the driver was accidentally specifying zero for the buffer length. Under normal circumstances, SWIOTLB does not need to allocate a bounce buffer, so the address is just mapped without checking the size field. This is why the error was not detected earlier. Fixes: b9b17debc69d ("net: emac: emac gigabit ethernet controller driver") Cc: stable@vger.kernel.org Signed-off-by: Timur Tabi Signed-off-by: David S. Miller --- drivers/net/ethernet/qualcomm/emac/emac-mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qualcomm/emac/emac-mac.c b/drivers/net/ethernet/qualcomm/emac/emac-mac.c index 0ea3ca09c689..3ed9033e56db 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac-mac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac-mac.c @@ -898,7 +898,8 @@ static void emac_mac_rx_descs_refill(struct emac_adapter *adpt, curr_rxbuf->dma_addr = dma_map_single(adpt->netdev->dev.parent, skb->data, - curr_rxbuf->length, DMA_FROM_DEVICE); + adpt->rxbuf_size, DMA_FROM_DEVICE); + ret = dma_mapping_error(adpt->netdev->dev.parent, curr_rxbuf->dma_addr); if (ret) { -- cgit v1.2.3 From 6098d7ddd62f532f80ee2a4b01aca500a8e4e9e4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 22 Sep 2017 23:29:18 +0200 Subject: rocker: fix rocker_tlv_put_* functions for KASAN Inlining these functions creates lots of stack variables that each take 64 bytes when KASAN is enabled, leading to this warning about potential stack overflow: drivers/net/ethernet/rocker/rocker_ofdpa.c: In function 'ofdpa_cmd_flow_tbl_add': drivers/net/ethernet/rocker/rocker_ofdpa.c:621:1: error: the frame size of 2752 bytes is larger than 1536 bytes [-Werror=frame-larger-than=] gcc-8 can now consolidate the stack slots itself, but on older versions we get the same behavior by using a temporary variable that holds a copy of the inline function argument. Cc: stable@vger.kernel.org Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/ethernet/rocker/rocker_tlv.h | 48 ++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/rocker/rocker_tlv.h b/drivers/net/ethernet/rocker/rocker_tlv.h index a63ef82e7c72..dfae3c9d57c6 100644 --- a/drivers/net/ethernet/rocker/rocker_tlv.h +++ b/drivers/net/ethernet/rocker/rocker_tlv.h @@ -139,40 +139,52 @@ rocker_tlv_start(struct rocker_desc_info *desc_info) int rocker_tlv_put(struct rocker_desc_info *desc_info, int attrtype, int attrlen, const void *data); -static inline int rocker_tlv_put_u8(struct rocker_desc_info *desc_info, - int attrtype, u8 value) +static inline int +rocker_tlv_put_u8(struct rocker_desc_info *desc_info, int attrtype, u8 value) { - return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &value); + u8 tmp = value; /* work around GCC PR81715 */ + + return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &tmp); } -static inline int rocker_tlv_put_u16(struct rocker_desc_info *desc_info, - int attrtype, u16 value) +static inline int +rocker_tlv_put_u16(struct rocker_desc_info *desc_info, int attrtype, u16 value) { - return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &value); + u16 tmp = value; + + return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &tmp); } -static inline int rocker_tlv_put_be16(struct rocker_desc_info *desc_info, - int attrtype, __be16 value) +static inline int +rocker_tlv_put_be16(struct rocker_desc_info *desc_info, int attrtype, __be16 value) { - return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &value); + __be16 tmp = value; + + return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &tmp); } -static inline int rocker_tlv_put_u32(struct rocker_desc_info *desc_info, - int attrtype, u32 value) +static inline int +rocker_tlv_put_u32(struct rocker_desc_info *desc_info, int attrtype, u32 value) { - return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &value); + u32 tmp = value; + + return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &tmp); } -static inline int rocker_tlv_put_be32(struct rocker_desc_info *desc_info, - int attrtype, __be32 value) +static inline int +rocker_tlv_put_be32(struct rocker_desc_info *desc_info, int attrtype, __be32 value) { - return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &value); + __be32 tmp = value; + + return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &tmp); } -static inline int rocker_tlv_put_u64(struct rocker_desc_info *desc_info, - int attrtype, u64 value) +static inline int +rocker_tlv_put_u64(struct rocker_desc_info *desc_info, int attrtype, u64 value) { - return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &value); + u64 tmp = value; + + return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &tmp); } static inline struct rocker_tlv * -- cgit v1.2.3 From aec0246f3e3882065b5c29916a84b539afe4e4af Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Mon, 25 Sep 2017 19:26:01 +0530 Subject: drm/i915: Enable scanline read based on frame timestamps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For certain platforms on certain encoders, timings are driven from port instead of pipe. Thus, we can't rely on pipe scanline registers to get the timing information. Some cases scanline register read will not be functional. This is causing vblank evasion logic to fail since it relies on scanline, causing atomic update failure warnings. This patch uses pipe framestamp and current timestamp registers to calculate scanline. This is an indirect way to get the scanline. It helps resolve atomic update failure for gen9 dsi platforms. v2: Addressed Ville and Daniel's review comments. Updated the register MACROs, handled race condition for register reads, extracted timings from the hwmode. Removed the dependency on crtc->config to get the encoder type. v3: Made get scanline function generic v4: Addressed Ville's review comments. Added a flag to decide timestamp based scanline reporting. Changed 64bit variables to u32 v5: Adressed Ville's review comments. Put the scanline compute function at the place of caller. Removed hwmode flags from uapi and used a local i915 data structure instead. v6: Used vblank hwmode to get the timings. v7: Fixed sparse warnings, indentation and minor review comments. v8: Limited this only for Gen9 DSI. Credits-to: Ville Syrjälä Signed-off-by: Uma Shankar Signed-off-by: Chandra Konduru Signed-off-by: Vidya Srinivas Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1506347761-4201-1-git-send-email-vidya.srinivas@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 54 ++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 9 +++++++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_dsi.c | 8 ++++++ 4 files changed, 73 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6a07ef38fb47..0b7562135d1c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -783,6 +783,57 @@ static u32 g4x_get_vblank_counter(struct drm_device *dev, unsigned int pipe) return I915_READ(PIPE_FRMCOUNT_G4X(pipe)); } +/* + * On certain encoders on certain platforms, pipe + * scanline register will not work to get the scanline, + * since the timings are driven from the PORT or issues + * with scanline register updates. + * This function will use Framestamp and current + * timestamp registers to calculate the scanline. + */ +static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct drm_vblank_crtc *vblank = + &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)]; + const struct drm_display_mode *mode = &vblank->hwmode; + u32 vblank_start = mode->crtc_vblank_start; + u32 vtotal = mode->crtc_vtotal; + u32 htotal = mode->crtc_htotal; + u32 clock = mode->crtc_clock; + u32 scanline, scan_prev_time, scan_curr_time, scan_post_time; + + /* + * To avoid the race condition where we might cross into the + * next vblank just between the PIPE_FRMTMSTMP and TIMESTAMP_CTR + * reads. We make sure we read PIPE_FRMTMSTMP and TIMESTAMP_CTR + * during the same frame. + */ + do { + /* + * This field provides read back of the display + * pipe frame time stamp. The time stamp value + * is sampled at every start of vertical blank. + */ + scan_prev_time = I915_READ_FW(PIPE_FRMTMSTMP(crtc->pipe)); + + /* + * The TIMESTAMP_CTR register has the current + * time stamp value. + */ + scan_curr_time = I915_READ_FW(IVB_TIMESTAMP_CTR); + + scan_post_time = I915_READ_FW(PIPE_FRMTMSTMP(crtc->pipe)); + } while (scan_post_time != scan_prev_time); + + scanline = div_u64(mul_u32_u32(scan_curr_time - scan_prev_time, + clock), 1000 * htotal); + scanline = min(scanline, vtotal - 1); + scanline = (scanline + vblank_start) % vtotal; + + return scanline; +} + /* I915_READ_FW, only for fast reads of display block, no need for forcewake etc. */ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) { @@ -799,6 +850,9 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)]; mode = &vblank->hwmode; + if (mode->private_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP) + return __intel_get_crtc_scanline_from_timestamp(crtc); + vtotal = mode->crtc_vtotal; if (mode->flags & DRM_MODE_FLAG_INTERLACE) vtotal /= 2; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 82f36dd0cd94..76fd8fda46d2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8808,6 +8808,15 @@ enum skl_power_gate { #define MIPIO_TXESC_CLK_DIV2 _MMIO(0x160008) #define GLK_TX_ESC_CLK_DIV2_MASK 0x3FF +/* Gen4+ Timestamp and Pipe Frame time stamp registers */ +#define GEN4_TIMESTAMP _MMIO(0x2358) +#define ILK_TIMESTAMP_HI _MMIO(0x70070) +#define IVB_TIMESTAMP_CTR _MMIO(0x44070) + +#define _PIPE_FRMTMSTMP_A 0x70048 +#define PIPE_FRMTMSTMP(pipe) \ + _MMIO_PIPE2(pipe, _PIPE_FRMTMSTMP_A) + /* BXT MIPI clock controls */ #define BXT_MAX_VAR_OUTPUT_KHZ 39500 diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 64358d2f2422..0cab667fff57 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -494,6 +494,8 @@ struct intel_crtc_scaler_state { /* drm_mode->private_flags */ #define I915_MODE_FLAG_INHERITED 1 +/* Flag to get scanline using frame time stamps */ +#define I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP (1<<1) struct intel_pipe_wm { struct intel_wm_level wm[5]; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 578254ac799c..20a7b004ffd7 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -330,6 +330,10 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, adjusted_mode->flags = 0; if (IS_GEN9_LP(dev_priv)) { + /* Enable Frame time stamp based scanline reporting */ + adjusted_mode->private_flags |= + I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; + /* Dual link goes to DSI transcoder A. */ if (intel_dsi->ports == BIT(PORT_C)) pipe_config->cpu_transcoder = TRANSCODER_DSI_C; @@ -1102,6 +1106,10 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, pixel_format_from_register_bits(fmt)); bpp = pipe_config->pipe_bpp; + /* Enable Frame time stamo based scanline reporting */ + adjusted_mode->private_flags |= + I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; + /* In terms of pixels */ adjusted_mode->crtc_hdisplay = I915_READ(BXT_MIPI_TRANS_HACTIVE(port)); -- cgit v1.2.3 From 54fea2b974a076799e427e50644de7c6ca662be5 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 25 Sep 2017 10:50:06 +0000 Subject: drm/i915: Make I915_PARAMS_FOR_EACH macro more flexible We should not add trailing ; after each member to allow other than statements-style uses of this helper macro. While here s/func/param for clarity. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Jani Nikula Reviewed-by: Chris Wilson Acked-by: Jani Nikula Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170925105008.46060-1-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_params.h | 84 +++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index a2cbb4782fcd..0116bb9713e3 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -27,50 +27,50 @@ #include /* for __read_mostly */ -#define I915_PARAMS_FOR_EACH(func) \ - func(char *, vbt_firmware); \ - func(int, modeset); \ - func(int, panel_ignore_lid); \ - func(int, semaphores); \ - func(int, lvds_channel_mode); \ - func(int, panel_use_ssc); \ - func(int, vbt_sdvo_panel_type); \ - func(int, enable_rc6); \ - func(int, enable_dc); \ - func(int, enable_fbc); \ - func(int, enable_ppgtt); \ - func(int, enable_execlists); \ - func(int, enable_psr); \ - func(int, disable_power_well); \ - func(int, enable_ips); \ - func(int, invert_brightness); \ - func(int, enable_guc_loading); \ - func(int, enable_guc_submission); \ - func(int, guc_log_level); \ - func(char *, guc_firmware_path); \ - func(char *, huc_firmware_path); \ - func(int, use_mmio_flip); \ - func(int, mmio_debug); \ - func(int, edp_vswing); \ - func(int, reset); \ - func(unsigned int, inject_load_failure); \ +#define I915_PARAMS_FOR_EACH(param) \ + param(char *, vbt_firmware) \ + param(int, modeset) \ + param(int, panel_ignore_lid) \ + param(int, semaphores) \ + param(int, lvds_channel_mode) \ + param(int, panel_use_ssc) \ + param(int, vbt_sdvo_panel_type) \ + param(int, enable_rc6) \ + param(int, enable_dc) \ + param(int, enable_fbc) \ + param(int, enable_ppgtt) \ + param(int, enable_execlists) \ + param(int, enable_psr) \ + param(int, disable_power_well) \ + param(int, enable_ips) \ + param(int, invert_brightness) \ + param(int, enable_guc_loading) \ + param(int, enable_guc_submission) \ + param(int, guc_log_level) \ + param(char *, guc_firmware_path) \ + param(char *, huc_firmware_path) \ + param(int, use_mmio_flip) \ + param(int, mmio_debug) \ + param(int, edp_vswing) \ + param(int, reset) \ + param(unsigned int, inject_load_failure) \ /* leave bools at the end to not create holes */ \ - func(bool, alpha_support); \ - func(bool, enable_cmd_parser); \ - func(bool, enable_hangcheck); \ - func(bool, fastboot); \ - func(bool, prefault_disable); \ - func(bool, load_detect_test); \ - func(bool, force_reset_modeset_test); \ - func(bool, error_capture); \ - func(bool, disable_display); \ - func(bool, verbose_state_checks); \ - func(bool, nuclear_pageflip); \ - func(bool, enable_dp_mst); \ - func(bool, enable_dpcd_backlight); \ - func(bool, enable_gvt) + param(bool, alpha_support) \ + param(bool, enable_cmd_parser) \ + param(bool, enable_hangcheck) \ + param(bool, fastboot) \ + param(bool, prefault_disable) \ + param(bool, load_detect_test) \ + param(bool, force_reset_modeset_test) \ + param(bool, error_capture) \ + param(bool, disable_display) \ + param(bool, verbose_state_checks) \ + param(bool, nuclear_pageflip) \ + param(bool, enable_dp_mst) \ + param(bool, enable_dpcd_backlight) \ + param(bool, enable_gvt) -#define MEMBER(T, member) T member +#define MEMBER(T, member) T member; struct i915_params { I915_PARAMS_FOR_EACH(MEMBER); }; -- cgit v1.2.3 From 7075cb855d493487805ecf113874c04218d16014 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 25 Sep 2017 10:50:07 +0000 Subject: drm/i915: Extend I915_PARAMS_FOR_EACH with default member value By combining default value into helper macro we can initialize modparams struct in the same automatic way as it was declared. This will initialize members in the same order as declared and additionally will disallow declaring new member without proper default value for it. v2: make MEMBER macro more robust (Joonas) Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Jani Nikula Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Acked-by: Jani Nikula Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170925105008.46060-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_gpu_error.c | 6 +-- drivers/gpu/drm/i915/i915_params.c | 42 ++---------------- drivers/gpu/drm/i915/i915_params.h | 82 +++++++++++++++++------------------ 4 files changed, 48 insertions(+), 84 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d10d71aa4b0e..86c799ac4b85 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -66,7 +66,7 @@ static int i915_capabilities(struct seq_file *m, void *data) #undef PRINT_FLAG kernel_param_lock(THIS_MODULE); -#define PRINT_PARAM(T, x) seq_print_param(m, #x, #T, &i915_modparams.x); +#define PRINT_PARAM(T, x, ...) seq_print_param(m, #x, #T, &i915_modparams.x); I915_PARAMS_FOR_EACH(PRINT_PARAM); #undef PRINT_PARAM kernel_param_unlock(THIS_MODULE); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 881fbe8d179b..9f7b351621f3 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -572,7 +572,7 @@ static __always_inline void err_print_param(struct drm_i915_error_state_buf *m, static void err_print_params(struct drm_i915_error_state_buf *m, const struct i915_params *p) { -#define PRINT(T, x) err_print_param(m, #x, #T, &p->x); +#define PRINT(T, x, ...) err_print_param(m, #x, #T, &p->x); I915_PARAMS_FOR_EACH(PRINT); #undef PRINT } @@ -866,7 +866,7 @@ void __i915_gpu_state_free(struct kref *error_ref) kfree(error->overlay); kfree(error->display); -#define FREE(T, x) free_param(#T, &error->params.x); +#define FREE(T, x, ...) free_param(#T, &error->params.x); I915_PARAMS_FOR_EACH(FREE); #undef FREE @@ -1704,7 +1704,7 @@ static int capture(void *data) error->i915->gt.last_init_time)); error->params = i915_modparams; -#define DUP(T, x) dup_param(#T, &error->params.x); +#define DUP(T, x, ...) dup_param(#T, &error->params.x); I915_PARAMS_FOR_EACH(DUP); #undef DUP diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index ec6534180d54..9dff323a83d3 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -33,45 +33,9 @@ MODULE_PARM_DESC(name, desc) struct i915_params i915_modparams __read_mostly = { - .modeset = -1, - .panel_ignore_lid = 1, - .semaphores = -1, - .lvds_channel_mode = 0, - .panel_use_ssc = -1, - .vbt_sdvo_panel_type = -1, - .enable_rc6 = -1, - .enable_dc = -1, - .enable_fbc = -1, - .enable_execlists = -1, - .enable_hangcheck = true, - .enable_ppgtt = -1, - .enable_psr = -1, - .alpha_support = IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT), - .disable_power_well = -1, - .enable_ips = 1, - .fastboot = 0, - .prefault_disable = 0, - .load_detect_test = 0, - .force_reset_modeset_test = 0, - .reset = 2, - .error_capture = true, - .invert_brightness = 0, - .disable_display = 0, - .enable_cmd_parser = true, - .use_mmio_flip = 0, - .mmio_debug = 0, - .verbose_state_checks = 1, - .nuclear_pageflip = 0, - .edp_vswing = 0, - .enable_guc_loading = 0, - .enable_guc_submission = 0, - .guc_log_level = -1, - .guc_firmware_path = NULL, - .huc_firmware_path = NULL, - .enable_dp_mst = true, - .inject_load_failure = 0, - .enable_dpcd_backlight = false, - .enable_gvt = false, +#define MEMBER(T, member, value) .member = (value), + I915_PARAMS_FOR_EACH(MEMBER) +#undef MEMBER }; i915_param_named(modeset, int, 0400, diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 0116bb9713e3..da599395f2ba 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -28,49 +28,49 @@ #include /* for __read_mostly */ #define I915_PARAMS_FOR_EACH(param) \ - param(char *, vbt_firmware) \ - param(int, modeset) \ - param(int, panel_ignore_lid) \ - param(int, semaphores) \ - param(int, lvds_channel_mode) \ - param(int, panel_use_ssc) \ - param(int, vbt_sdvo_panel_type) \ - param(int, enable_rc6) \ - param(int, enable_dc) \ - param(int, enable_fbc) \ - param(int, enable_ppgtt) \ - param(int, enable_execlists) \ - param(int, enable_psr) \ - param(int, disable_power_well) \ - param(int, enable_ips) \ - param(int, invert_brightness) \ - param(int, enable_guc_loading) \ - param(int, enable_guc_submission) \ - param(int, guc_log_level) \ - param(char *, guc_firmware_path) \ - param(char *, huc_firmware_path) \ - param(int, use_mmio_flip) \ - param(int, mmio_debug) \ - param(int, edp_vswing) \ - param(int, reset) \ - param(unsigned int, inject_load_failure) \ + param(char *, vbt_firmware, NULL) \ + param(int, modeset, -1) \ + param(int, panel_ignore_lid, 1) \ + param(int, semaphores, -1) \ + param(int, lvds_channel_mode, 0) \ + param(int, panel_use_ssc, -1) \ + param(int, vbt_sdvo_panel_type, -1) \ + param(int, enable_rc6, -1) \ + param(int, enable_dc, -1) \ + param(int, enable_fbc, -1) \ + param(int, enable_ppgtt, -1) \ + param(int, enable_execlists, -1) \ + param(int, enable_psr, -1) \ + param(int, disable_power_well, -1) \ + param(int, enable_ips, 1) \ + param(int, invert_brightness, 0) \ + param(int, enable_guc_loading, 0) \ + param(int, enable_guc_submission, 0) \ + param(int, guc_log_level, -1) \ + param(char *, guc_firmware_path, NULL) \ + param(char *, huc_firmware_path, NULL) \ + param(int, use_mmio_flip, 0) \ + param(int, mmio_debug, 0) \ + param(int, edp_vswing, 0) \ + param(int, reset, 2) \ + param(unsigned int, inject_load_failure, 0) \ /* leave bools at the end to not create holes */ \ - param(bool, alpha_support) \ - param(bool, enable_cmd_parser) \ - param(bool, enable_hangcheck) \ - param(bool, fastboot) \ - param(bool, prefault_disable) \ - param(bool, load_detect_test) \ - param(bool, force_reset_modeset_test) \ - param(bool, error_capture) \ - param(bool, disable_display) \ - param(bool, verbose_state_checks) \ - param(bool, nuclear_pageflip) \ - param(bool, enable_dp_mst) \ - param(bool, enable_dpcd_backlight) \ - param(bool, enable_gvt) + param(bool, alpha_support, IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT)) \ + param(bool, enable_cmd_parser, true) \ + param(bool, enable_hangcheck, true) \ + param(bool, fastboot, 0) \ + param(bool, prefault_disable, 0) \ + param(bool, load_detect_test, 0) \ + param(bool, force_reset_modeset_test, 0) \ + param(bool, error_capture, true) \ + param(bool, disable_display, 0) \ + param(bool, verbose_state_checks, 1) \ + param(bool, nuclear_pageflip, 0) \ + param(bool, enable_dp_mst, true) \ + param(bool, enable_dpcd_backlight, false) \ + param(bool, enable_gvt, false) -#define MEMBER(T, member) T member; +#define MEMBER(T, member, ...) T member; struct i915_params { I915_PARAMS_FOR_EACH(MEMBER); }; -- cgit v1.2.3 From ad0c167252e90531b398bc5f637580733d1789e4 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 25 Sep 2017 10:50:08 +0000 Subject: drm/i915: Fix default values of some modparams Members should be initialized with values of matching types. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Jani Nikula Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Acked-by: Jani Nikula Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170925105008.46060-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_params.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index da599395f2ba..4f3f8d650194 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -58,14 +58,14 @@ param(bool, alpha_support, IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT)) \ param(bool, enable_cmd_parser, true) \ param(bool, enable_hangcheck, true) \ - param(bool, fastboot, 0) \ - param(bool, prefault_disable, 0) \ - param(bool, load_detect_test, 0) \ - param(bool, force_reset_modeset_test, 0) \ + param(bool, fastboot, false) \ + param(bool, prefault_disable, false) \ + param(bool, load_detect_test, false) \ + param(bool, force_reset_modeset_test, false) \ param(bool, error_capture, true) \ - param(bool, disable_display, 0) \ - param(bool, verbose_state_checks, 1) \ - param(bool, nuclear_pageflip, 0) \ + param(bool, disable_display, false) \ + param(bool, verbose_state_checks, true) \ + param(bool, nuclear_pageflip, false) \ param(bool, enable_dp_mst, true) \ param(bool, enable_dpcd_backlight, false) \ param(bool, enable_gvt, false) -- cgit v1.2.3 From 9a2cbf2d7b94660e4c4920cfae4a5eecc83ee485 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 26 Sep 2017 12:47:16 +0530 Subject: drm/i915/huc: Reorganize HuC authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepared intel_auth_huc to separate HuC specific functionality from GuC send action. Created new header intel_huc.h to group HuC specific declarations. v2: Changed argument preparation for AUTHENTICATE_HUC. s/intel_auth_huc/intel_huc_auth. Deferred creation of intel_huc.h to later patch. v3: Rebase as intel_guc.h is removed. Added param description to intel_huc_auth. (Michal) v4: Rebase as intel_guc.h is added again. :) v5: Rebase w.r.t removal of GuC code restructuring. v6-v7: Rebase. v8: Tagged subject as drm/i915/huc. (Michal Wajdeczko) Added kernel-doc description to intel_huc_auth and intel_guc_auth_huc. s/dev_priv/i915 and removed unnecessary variable offset. (Joonas) v9: Rebase. Had conflict with i915_modparams change. Signed-off-by: Sagar Arun Kamble Cc: Joonas Lahtinen Cc: Michal Wajdeczko Cc: Michał Winiarski Reviewed-by: Michal Wajdeczko Reviewed-by: Joonas Lahtinen Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1506410236-17926-1-git-send-email-sagar.a.kamble@intel.com --- drivers/gpu/drm/i915/intel_huc.c | 38 ++++++++++++++++++-------------------- drivers/gpu/drm/i915/intel_uc.c | 23 ++++++++++++++++++++++- drivers/gpu/drm/i915/intel_uc.h | 3 ++- 3 files changed, 42 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index 6e1779ba87a9..8b4b53525422 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c @@ -225,19 +225,22 @@ void intel_huc_init_hw(struct intel_huc *huc) } /** - * intel_guc_auth_huc() - authenticate ucode - * @dev_priv: the drm_i915_device + * intel_huc_auth() - Authenticate HuC uCode + * @huc: intel_huc structure + * + * Called after HuC and GuC firmware loading during intel_uc_init_hw(). * - * Triggers a HuC fw authentication request to the GuC via intel_guc_action_ - * authenticate_huc interface. + * This function pins HuC firmware image object into GGTT. + * Then it invokes GuC action to authenticate passing the offset to RSA + * signature through intel_guc_auth_huc(). It then waits for 50ms for + * firmware verification ACK and unpins the object. */ -void intel_guc_auth_huc(struct drm_i915_private *dev_priv) +void intel_huc_auth(struct intel_huc *huc) { - struct intel_guc *guc = &dev_priv->guc; - struct intel_huc *huc = &dev_priv->huc; + struct drm_i915_private *i915 = huc_to_i915(huc); + struct intel_guc *guc = &i915->guc; struct i915_vma *vma; int ret; - u32 data[2]; if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) return; @@ -250,23 +253,19 @@ void intel_guc_auth_huc(struct drm_i915_private *dev_priv) return; } - /* Specify auth action and where public signature is. */ - data[0] = INTEL_GUC_ACTION_AUTHENTICATE_HUC; - data[1] = guc_ggtt_offset(vma) + huc->fw.rsa_offset; - - ret = intel_guc_send(guc, data, ARRAY_SIZE(data)); + ret = intel_guc_auth_huc(guc, + guc_ggtt_offset(vma) + huc->fw.rsa_offset); if (ret) { DRM_ERROR("HuC: GuC did not ack Auth request %d\n", ret); goto out; } /* Check authentication status, it should be done by now */ - ret = intel_wait_for_register(dev_priv, - HUC_STATUS2, - HUC_FW_VERIFIED, - HUC_FW_VERIFIED, - 50); - + ret = intel_wait_for_register(i915, + HUC_STATUS2, + HUC_FW_VERIFIED, + HUC_FW_VERIFIED, + 50); if (ret) { DRM_ERROR("HuC: Authentication failed %d\n", ret); goto out; @@ -275,4 +274,3 @@ void intel_guc_auth_huc(struct drm_i915_private *dev_priv) out: i915_vma_unpin(vma); } - diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 901854007664..277477890240 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -328,6 +328,27 @@ static void guc_disable_communication(struct intel_guc *guc) guc->send = intel_guc_send_nop; } +/** + * intel_guc_auth_huc() - Send action to GuC to authenticate HuC ucode + * @guc: intel_guc structure + * @rsa_offset: rsa offset w.r.t ggtt base of huc vma + * + * Triggers a HuC firmware authentication request to the GuC via intel_guc_send + * INTEL_GUC_ACTION_AUTHENTICATE_HUC interface. This function is invoked by + * intel_huc_auth(). + * + * Return: non-zero code on error + */ +int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset) +{ + u32 action[] = { + INTEL_GUC_ACTION_AUTHENTICATE_HUC, + rsa_offset + }; + + return intel_guc_send(guc, action, ARRAY_SIZE(action)); +} + int intel_uc_init_hw(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; @@ -390,7 +411,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) if (ret) goto err_log_capture; - intel_guc_auth_huc(dev_priv); + intel_huc_auth(&dev_priv->huc); if (i915_modparams.enable_guc_submission) { if (i915_modparams.guc_log_level >= 0) gen9_enable_guc_interrupts(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 7703c9ad6511..6966349ed737 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -211,6 +211,7 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv); int intel_guc_sample_forcewake(struct intel_guc *guc); int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len); int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len); +int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset); static inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len) { @@ -254,6 +255,6 @@ static inline u32 guc_ggtt_offset(struct i915_vma *vma) /* intel_huc.c */ void intel_huc_select_fw(struct intel_huc *huc); void intel_huc_init_hw(struct intel_huc *huc); -void intel_guc_auth_huc(struct drm_i915_private *dev_priv); +void intel_huc_auth(struct intel_huc *huc); #endif -- cgit v1.2.3 From 1df79cb3bae754e4a42240f9851ed82549a44f1a Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 20 Sep 2017 12:35:57 +0530 Subject: phy: tegra: Handle return value of kasprintf kasprintf() can fail and it's return value must be checked. Signed-off-by: Arvind Yadav Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/tegra/xusb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 3cbcb2537657..4307bf0013e1 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -454,6 +454,8 @@ tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type, char *name; name = kasprintf(GFP_KERNEL, "%s-%u", type, index); + if (!name) + return ERR_PTR(-ENOMEM); np = of_find_node_by_name(np, name); kfree(name); } -- cgit v1.2.3 From 554a56fc83f679c73b4f851a330045d0ec7ec1a5 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Thu, 21 Sep 2017 18:31:48 +0800 Subject: phy: phy-mtk-tphy: fix NULL point of chip bank Chip bank of version-1 is initialized as NULL, but it's used by pcie_phy_instance_power_on/off(), so assign it a right address. Signed-off-by: Chunfeng Yun Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/mediatek/phy-mtk-tphy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index e3baad78521f..721a2a1c97ef 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -27,6 +27,7 @@ /* banks shared by multiple phys */ #define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */ #define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */ +#define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */ /* u2 phy bank */ #define SSUSB_SIFSLV_V1_U2PHY_COM 0x000 /* u3/pcie/sata phy banks */ @@ -762,7 +763,7 @@ static void phy_v1_banks_init(struct mtk_tphy *tphy, case PHY_TYPE_USB3: case PHY_TYPE_PCIE: u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC; - u3_banks->chip = NULL; + u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP; u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA; break; -- cgit v1.2.3 From caef3e0b657d091a540232e07e5e5b4648110a52 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 18 Sep 2017 10:04:20 +0200 Subject: phy: mvebu-cp110-comphy: fix mux error check The mux value is retrieved from the mvebu_comphy_get_mux() function which returns an int. In mvebu_comphy_power_on() this int is stored to a u32 and a check is made to ensure it's not negative. Which is wrong. This fixes it. Fixes: d0438bd6aa09 ("phy: add the mvebu cp110 comphy driver") Signed-off-by: Antoine Tenart Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 73ebad6634a7..514a1a47e1fd 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -468,8 +468,8 @@ static int mvebu_comphy_power_on(struct phy *phy) { struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); struct mvebu_comphy_priv *priv = lane->priv; - int ret; - u32 mux, val; + int ret, mux; + u32 val; mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode); if (mux < 0) -- cgit v1.2.3 From 17fb745d4acfe52f9ebb1ba2b10f2fcd796fb5ce Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 18 Sep 2017 10:04:22 +0200 Subject: phy: mvebu-cp110-comphy: explicitly set the pipe selector The pipe selector is used to select some modes (such as USB or PCIe). Otherwise it must be set to 0 (or "unconnected"). This patch does this to ensure it is not set to an incompatible value when using the supported modes (SGMII, 10GKR). Signed-off-by: Antoine Tenart Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 514a1a47e1fd..e8ed7e3e6e23 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -111,6 +111,8 @@ #define MVEBU_COMPHY_CONF6_40B BIT(18) #define MVEBU_COMPHY_SELECTOR 0x1140 #define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4) +#define MVEBU_COMPHY_PIPE_SELECTOR 0x1144 +#define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4) #define MVEBU_COMPHY_LANES 6 #define MVEBU_COMPHY_PORTS 3 @@ -475,6 +477,10 @@ static int mvebu_comphy_power_on(struct phy *phy) if (mux < 0) return -ENOTSUPP; + regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val); + val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id)); + regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val); + regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val); val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id); @@ -526,6 +532,10 @@ static int mvebu_comphy_power_off(struct phy *phy) val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val); + regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val); + val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id)); + regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val); + return 0; } -- cgit v1.2.3 From c1c7acac0998ffcc9cd81e016a7d1b58b1afbb51 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Sep 2017 13:31:37 +0300 Subject: phy: mvebu-cp110: checking for NULL instead of IS_ERR() devm_ioremap_resource() never returns NULL, it only returns error pointers so this test needs to be changed. Fixes: d0438bd6aa09 ("phy: add the mvebu cp110 comphy driver") Signed-off-by: Dan Carpenter Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index e8ed7e3e6e23..89c887ea5557 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -586,8 +586,8 @@ static int mvebu_comphy_probe(struct platform_device *pdev) return PTR_ERR(priv->regmap); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); - if (!priv->base) - return -ENOMEM; + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); for_each_available_child_of_node(pdev->dev.of_node, child) { struct mvebu_comphy_lane *lane; -- cgit v1.2.3 From f98b74387551f6d266c044d90e87e4919b25b970 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 22 Sep 2017 09:44:03 -0700 Subject: phy: rockchip-typec: Set the AUX channel flip state earlier On some DP monitors we found that setting the wrong flip state on the AUX channel could cause the monitor to stop asserting HotPlug Detect (HPD). Setting the right flip state caused these monitors to start asserting HotPlug Detect again. Here's what we believe was happening: * We'd plug in the monitor and we'd see HPD assert * We'd quickly see HPD deassert * The kernel would try to init the type C PHY but would init it in USB mode (because there was a peripheral there but no HPD) * Because the kernel never set the flip mode properly we'd never see the HPD come back. With this change, we'll still see HPD disappear (we don't think there's anything we can do about that), but then it will come back. Overall we can say that it's sane to set the AUX channel flip state even when HPD is not asserted. NOTE: to make this change possible, I needed to do a bit of cleanup to the tcphy_dp_aux_calibration() function so that it doesn't ever clobber the FLIP state. This made it very obvious that a line of code documented as "setting bit 12" also did a bunch of other magic, undocumented stuff. For now I'll just break out the bits and add a comment that this is black magic and we'll try to document tcphy_dp_aux_calibration() better in a future CL. ALSO NOTE: the old function used to write a bunch of hardcoded values in _some_ cases instead of doing a read-modify-write. One could possibly assert that these could have had (beneficial) side effects and thus with this new code (which always does read-modify-write) we could have a bug. We shouldn't need to worry, though, since in the old code tcphy_dp_aux_calibration() was always called following the de-assertion of "reset" the the type C PHY. ...so the type C PHY was always in default state. TX_ANA_CTRL_REG_1 is documented to be 0x0 after reset. This was also confirmed by printk. Suggested-by: Shawn Nematbakhsh Reviewed-by: Chris Zhong Signed-off-by: Douglas Anderson Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/rockchip/phy-rockchip-typec.c | 62 +++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index 4d2c57f21d76..342a77733207 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -443,14 +443,34 @@ static inline int property_enable(struct rockchip_typec_phy *tcphy, return regmap_write(tcphy->grf_regs, reg->offset, val | mask); } +static void tcphy_dp_aux_set_flip(struct rockchip_typec_phy *tcphy) +{ + u16 tx_ana_ctrl_reg_1; + + /* + * Select the polarity of the xcvr: + * 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull + * down aux_m) + * 0, Normal polarity (if TYPEC, pulls up aux_m and pulls down + * aux_p) + */ + tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1); + if (!tcphy->flip) + tx_ana_ctrl_reg_1 |= BIT(12); + else + tx_ana_ctrl_reg_1 &= ~BIT(12); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); +} + static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) { + u16 tx_ana_ctrl_reg_1; u16 rdata, rdata2, val; /* disable txda_cal_latch_en for rewrite the calibration values */ - rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1); - val = rdata & 0xdfff; - writel(val, tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 &= ~BIT(13); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); /* * read a resistor calibration code from CMN_TXPUCAL_CTRL[6:0] and @@ -472,9 +492,8 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) * Activate this signal for 1 clock cycle to sample new calibration * values. */ - rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1); - val = rdata | 0x2000; - writel(val, tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 |= BIT(13); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); usleep_range(150, 200); /* set TX Voltage Level and TX Deemphasis to 0 */ @@ -482,8 +501,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) /* re-enable decap */ writel(0x100, tcphy->base + TX_ANA_CTRL_REG_2); writel(0x300, tcphy->base + TX_ANA_CTRL_REG_2); - writel(0x2008, tcphy->base + TX_ANA_CTRL_REG_1); - writel(0x2018, tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 |= BIT(3); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 |= BIT(4); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); writel(0, tcphy->base + TX_ANA_CTRL_REG_5); @@ -494,8 +515,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4); /* re-enables Bandgap reference for LDO */ - writel(0x2098, tcphy->base + TX_ANA_CTRL_REG_1); - writel(0x2198, tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 |= BIT(7); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 |= BIT(8); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); /* * re-enables the transmitter pre-driver, driver data selection MUX, @@ -505,17 +528,15 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) writel(0x303, tcphy->base + TX_ANA_CTRL_REG_2); /* - * BIT 12: Controls auxda_polarity, which selects the polarity of the - * xcvr: - * 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull - * down aux_m) - * 0, Normal polarity (if TYPE_C, pulls up aux_m and pulls down - * aux_p) + * Do some magic undocumented stuff, some of which appears to + * undo the "re-enables Bandgap reference for LDO" above. */ - val = 0xa078; - if (!tcphy->flip) - val |= BIT(12); - writel(val, tcphy->base + TX_ANA_CTRL_REG_1); + tx_ana_ctrl_reg_1 |= BIT(15); + tx_ana_ctrl_reg_1 &= ~BIT(8); + tx_ana_ctrl_reg_1 &= ~BIT(7); + tx_ana_ctrl_reg_1 |= BIT(6); + tx_ana_ctrl_reg_1 |= BIT(5); + writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1); writel(0, tcphy->base + TX_ANA_CTRL_REG_3); writel(0, tcphy->base + TX_ANA_CTRL_REG_4); @@ -555,6 +576,7 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode) reset_control_deassert(tcphy->tcphy_rst); property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip); + tcphy_dp_aux_set_flip(tcphy); tcphy_cfg_24m(tcphy); -- cgit v1.2.3 From 26e03d803c8191e906360a0320c05b12d45a37ae Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 22 Sep 2017 09:44:04 -0700 Subject: phy: rockchip-typec: Don't set the aux voltage swing to 400 mV On rk3399-gru-kevin there are some cases where we're seeing AUX CH failures when trying to do DisplayPort over type C. Problems are intermittent and don't reproduce all the time. Problems are often bursty and failures persist for several seconds before going away. The failure case I focused on is: * A particular type C to HDMI adapter. * One orientation (flip mode) of that adapter. * Easier to see failures when something is plugged into the _other type C port at the same time. * Problems reproduce on both type C ports (left and right side). Ironically problems also stop reproducing when I solder wires onto the AUX CH signals on a port (even if no scope is connected to the signals). In this case, problems only stop reproducing on the port with the wires connected. From the above it appears that something about the signaling on the aux channel is marginal and any slight differences can bring us over the edge to failure. It turns out that we can fix our problems by just increasing the voltage swing of the AUX CH, giving us a bunch of extra margin. In DP up to version 1.2 the voltage swing on the aux channel was specced as .29 V to 1.38 V. In DP version 1.3 the aux channel voltage was tightened to be between .29 V and .40 V, but it clarifies that it really only needs the lower voltage when operating at the highest speed (HBR3 mode). So right now we are trying to use a voltage that technically should be valid for all versions of the spec (including version 1.3 when transmitting at HBR3). That would be great to do if it worked reliably. ...but it doesn't seem to. It turns out that if you continue to read through the DP part of the rk3399 TRM and other parts of the type C PHY spec you'll find out that while the rk3399 does support DP 1.3, it doesn't support HBR3. The docs specifically say "RBR, HBR and HBR2 data rates only". Thus there is actually no requirement to support an AUX CH swing of .4 V. Even if there is no actual requirement to support the tighter voltage swing, one could possibly argue that we should support it anyway. The DP spec clarifies that the lower voltage on the AUX CH will reduce cross talk in some cases and that seems like it could be beneficial even at the lower bit rates. At the moment, though, we are seeing problems with the AUX CH and not on the other lines. Also, checking another known working and similar laptop shows that the other laptop runs the AUX channel at a higher voltage. Other notes: * Looking at measurements done on the AUX CH we weren't actually compliant with the DP 1.3 spec anyway. AUX CH peek-to-peek voltage was measured on rk3399-gru-kevin as .466 V which is > .4 V. * With this new patch the AUX channel isn't actually 1.0 V, but it has been confirmed that the signal is better and has more margin. Eye diagram passes. * If someone were truly an expert in the Type C PHY and in DisplayPort signaling they might be able to make things work and keep the voltage at < .4 V. The Type C PHY seems to have a plethora of tuning knobs that could almost certainly improve the signal integrity. Some of these things (like enabling tx_fcm_full_margin) even seem to fix my problems. However, lacking expertise I can't say whether this is a better or worse solution. Tightening signals to give cleaner waveforms can often have adverse affects, like increasing EMI or adding noise to other signals. I'd rather not tune things like this without a healthy application of expertise that I don't have. Signed-off-by: Douglas Anderson Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/rockchip/phy-rockchip-typec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index 342a77733207..b25c00432f9b 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -543,10 +543,11 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) writel(0, tcphy->base + TX_ANA_CTRL_REG_5); /* - * Controls low_power_swing_en, set the voltage swing of the driver - * to 400mv. The values below are peak to peak (differential) values. + * Controls low_power_swing_en, don't set the voltage swing of the + * driver to 400mv. The values below are peak to peak (differential) + * values. */ - writel(4, tcphy->base + TXDA_COEFF_CALC_CTRL); + writel(0, tcphy->base + TXDA_COEFF_CALC_CTRL); writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA); /* Controls tx_high_z_tm_en */ -- cgit v1.2.3 From 87dc03ad268f285065cdd2e2ac75701a1f04d0b8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 Sep 2017 14:09:29 +0100 Subject: drm/i915/selftests: Try to recover from a wedged GPU during reset tests If we see the seqno stop progressing, we abandon the test for fear that the GPU died following the reset. However, during test teardown we still wait for the GPU to idle before continuing, but we have already confirmed that the GPU is dead. Furthermore, since we are inside a reset test, we have disabled the hangchecker, and so there is no safety net and we wait indefinitely. Detect the stuck GPU and declare it wedged as a state of emergency so we can escape. Signed-off-by: Chris Wilson Cc: Jari Tahvanainen Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20170915130929.18892-1-chris@chris-wilson.co.uk Tested-by: Jari Tahvanainen Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index 02e52a146ed8..377c1de766ce 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -621,7 +621,12 @@ static int igt_wait_reset(void *arg) __i915_add_request(rq, true); if (!wait_for_hang(&h, rq)) { - pr_err("Failed to start request %x\n", rq->fence.seqno); + pr_err("Failed to start request %x, at %x\n", + rq->fence.seqno, hws_seqno(&h, rq)); + + i915_reset(i915, 0); + i915_gem_set_wedged(i915); + err = -EIO; goto out_rq; } @@ -708,10 +713,14 @@ static int igt_reset_queue(void *arg) __i915_add_request(rq, true); if (!wait_for_hang(&h, prev)) { - pr_err("Failed to start request %x\n", - prev->fence.seqno); + pr_err("Failed to start request %x, at %x\n", + prev->fence.seqno, hws_seqno(&h, prev)); i915_gem_request_put(rq); i915_gem_request_put(prev); + + i915_reset(i915, 0); + i915_gem_set_wedged(i915); + err = -EIO; goto fini; } @@ -806,7 +815,12 @@ static int igt_handle_error(void *arg) __i915_add_request(rq, true); if (!wait_for_hang(&h, rq)) { - pr_err("Failed to start request %x\n", rq->fence.seqno); + pr_err("Failed to start request %x, at %x\n", + rq->fence.seqno, hws_seqno(&h, rq)); + + i915_reset(i915, 0); + i915_gem_set_wedged(i915); + err = -EIO; goto err_request; } @@ -843,8 +857,8 @@ err_unlock: int intel_hangcheck_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { + SUBTEST(igt_global_reset), /* attempt to recover GPU first */ SUBTEST(igt_hang_sanitycheck), - SUBTEST(igt_global_reset), SUBTEST(igt_reset_engine), SUBTEST(igt_reset_active_engines), SUBTEST(igt_wait_reset), -- cgit v1.2.3 From 5a127a8c4aaf6ea06752ee6404cd7eaea7154a6c Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 20 Sep 2017 10:26:59 +0100 Subject: drm/i915: Add IS_PLATFORM macro This will allow some code re-organization in a following patch. Signed-off-by: Tvrtko Ursulin Cc: Jani Nikula Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170920092701.17963-2-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 52 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 44f5569ed995..b5d65d07432d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2907,37 +2907,39 @@ intel_info(const struct drm_i915_private *dev_priv) #define IS_REVID(p, since, until) \ (INTEL_REVID(p) >= (since) && INTEL_REVID(p) <= (until)) -#define IS_I830(dev_priv) ((dev_priv)->info.platform == INTEL_I830) -#define IS_I845G(dev_priv) ((dev_priv)->info.platform == INTEL_I845G) -#define IS_I85X(dev_priv) ((dev_priv)->info.platform == INTEL_I85X) -#define IS_I865G(dev_priv) ((dev_priv)->info.platform == INTEL_I865G) -#define IS_I915G(dev_priv) ((dev_priv)->info.platform == INTEL_I915G) -#define IS_I915GM(dev_priv) ((dev_priv)->info.platform == INTEL_I915GM) -#define IS_I945G(dev_priv) ((dev_priv)->info.platform == INTEL_I945G) -#define IS_I945GM(dev_priv) ((dev_priv)->info.platform == INTEL_I945GM) -#define IS_I965G(dev_priv) ((dev_priv)->info.platform == INTEL_I965G) -#define IS_I965GM(dev_priv) ((dev_priv)->info.platform == INTEL_I965GM) -#define IS_G45(dev_priv) ((dev_priv)->info.platform == INTEL_G45) -#define IS_GM45(dev_priv) ((dev_priv)->info.platform == INTEL_GM45) +#define IS_PLATFORM(dev_priv, p) ((dev_priv)->info.platform == (p)) + +#define IS_I830(dev_priv) IS_PLATFORM(dev_priv, INTEL_I830) +#define IS_I845G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I845G) +#define IS_I85X(dev_priv) IS_PLATFORM(dev_priv, INTEL_I85X) +#define IS_I865G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I865G) +#define IS_I915G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I915G) +#define IS_I915GM(dev_priv) IS_PLATFORM(dev_priv, INTEL_I915GM) +#define IS_I945G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I945G) +#define IS_I945GM(dev_priv) IS_PLATFORM(dev_priv, INTEL_I945GM) +#define IS_I965G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I965G) +#define IS_I965GM(dev_priv) IS_PLATFORM(dev_priv, INTEL_I965GM) +#define IS_G45(dev_priv) IS_PLATFORM(dev_priv, INTEL_G45) +#define IS_GM45(dev_priv) IS_PLATFORM(dev_priv, INTEL_GM45) #define IS_G4X(dev_priv) (IS_G45(dev_priv) || IS_GM45(dev_priv)) #define IS_PINEVIEW_G(dev_priv) (INTEL_DEVID(dev_priv) == 0xa001) #define IS_PINEVIEW_M(dev_priv) (INTEL_DEVID(dev_priv) == 0xa011) -#define IS_PINEVIEW(dev_priv) ((dev_priv)->info.platform == INTEL_PINEVIEW) -#define IS_G33(dev_priv) ((dev_priv)->info.platform == INTEL_G33) +#define IS_PINEVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_PINEVIEW) +#define IS_G33(dev_priv) IS_PLATFORM(dev_priv, INTEL_G33) #define IS_IRONLAKE_M(dev_priv) (INTEL_DEVID(dev_priv) == 0x0046) -#define IS_IVYBRIDGE(dev_priv) ((dev_priv)->info.platform == INTEL_IVYBRIDGE) +#define IS_IVYBRIDGE(dev_priv) IS_PLATFORM(dev_priv, INTEL_IVYBRIDGE) #define IS_IVB_GT1(dev_priv) (IS_IVYBRIDGE(dev_priv) && \ (dev_priv)->info.gt == 1) -#define IS_VALLEYVIEW(dev_priv) ((dev_priv)->info.platform == INTEL_VALLEYVIEW) -#define IS_CHERRYVIEW(dev_priv) ((dev_priv)->info.platform == INTEL_CHERRYVIEW) -#define IS_HASWELL(dev_priv) ((dev_priv)->info.platform == INTEL_HASWELL) -#define IS_BROADWELL(dev_priv) ((dev_priv)->info.platform == INTEL_BROADWELL) -#define IS_SKYLAKE(dev_priv) ((dev_priv)->info.platform == INTEL_SKYLAKE) -#define IS_BROXTON(dev_priv) ((dev_priv)->info.platform == INTEL_BROXTON) -#define IS_KABYLAKE(dev_priv) ((dev_priv)->info.platform == INTEL_KABYLAKE) -#define IS_GEMINILAKE(dev_priv) ((dev_priv)->info.platform == INTEL_GEMINILAKE) -#define IS_COFFEELAKE(dev_priv) ((dev_priv)->info.platform == INTEL_COFFEELAKE) -#define IS_CANNONLAKE(dev_priv) ((dev_priv)->info.platform == INTEL_CANNONLAKE) +#define IS_VALLEYVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) +#define IS_CHERRYVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW) +#define IS_HASWELL(dev_priv) IS_PLATFORM(dev_priv, INTEL_HASWELL) +#define IS_BROADWELL(dev_priv) IS_PLATFORM(dev_priv, INTEL_BROADWELL) +#define IS_SKYLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_SKYLAKE) +#define IS_BROXTON(dev_priv) IS_PLATFORM(dev_priv, INTEL_BROXTON) +#define IS_KABYLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_KABYLAKE) +#define IS_GEMINILAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_GEMINILAKE) +#define IS_COFFEELAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_COFFEELAKE) +#define IS_CANNONLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_CANNONLAKE) #define IS_MOBILE(dev_priv) ((dev_priv)->info.is_mobile) #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) -- cgit v1.2.3 From 4d34b11e46184bb5762491d32566fade188c6c01 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 20 Sep 2017 10:27:00 +0100 Subject: drm/i915: Compact device info access by a small re-ordering More effort to align members on 4-byte boundary helps with code size a tiny bit: text data bss dec hex filename -1460454 60014 3656 1524124 17419c drivers/gpu/drm/i915/i915.ko +1460254 60014 3656 1523924 1740d4 drivers/gpu/drm/i915/i915.ko Signed-off-by: Tvrtko Ursulin Cc: Jani Nikula Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170920092701.17963-3-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b5d65d07432d..4e2fcdd4ce9e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -852,21 +852,27 @@ enum intel_platform { }; struct intel_device_info { - u32 display_mmio_offset; u16 device_id; - u8 num_pipes; - u8 num_sprites[I915_MAX_PIPES]; - u8 num_scalers[I915_MAX_PIPES]; - u8 gen; u16 gen_mask; - enum intel_platform platform; + + u8 gen; u8 gt; /* GT number, 0 if undefined */ - u8 ring_mask; /* Rings supported by the HW */ u8 num_rings; + u8 ring_mask; /* Rings supported by the HW */ + + enum intel_platform platform; + + u32 display_mmio_offset; + + u8 num_pipes; + u8 num_sprites[I915_MAX_PIPES]; + u8 num_scalers[I915_MAX_PIPES]; + #define DEFINE_FLAG(name) u8 name:1 DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG); #undef DEFINE_FLAG u16 ddb_size; /* in blocks */ + /* Register offsets for the various display pipes and transcoders */ int pipe_offsets[I915_MAX_TRANSCODERS]; int trans_offsets[I915_MAX_TRANSCODERS]; -- cgit v1.2.3 From 2d8f63297b9f0b430c96329893667c0bfdcbd47e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 19 Sep 2017 18:38:13 +0300 Subject: drm/i915: always update ELD connector type after get modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_edid_to_eld() initializes the connector ELD to zero, overwriting the ELD connector type initialized in intel_audio_codec_enable(). If userspace does getconnector and thus get_modes after modeset, a subsequent audio component i915_audio_component_get_eld() call will receive an ELD without the connector type properly set. It's fine for HDMI, but screws up audio for DP. Always set the ELD connector type at intel_connector_update_modes() based on the connector type. We can drop the connector type update from intel_audio_codec_enable(). Credits to Joseph Nuzman for figuring this out. Cc: Ville Syrjälä Cc: Joseph Nuzman Reported-by: Joseph Nuzman Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101583 Reviewed-by: Ville Syrjälä Tested-by: Joseph Nuzman Cc: stable@vger.kernel.org # v4.10+, maybe earlier Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170919153813.29808-1-jani.nikula@intel.com (cherry picked from commit d81fb7fd9436e81fda67e5bc8ed0713aa28d3db2) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_audio.c | 5 ----- drivers/gpu/drm/i915/intel_modes.c | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index d805b6e6fe71..27743be5b768 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -606,11 +606,6 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, connector->encoder->base.id, connector->encoder->name); - /* ELD Conn_Type */ - connector->eld[5] &= ~(3 << 2); - if (intel_crtc_has_dp_encoder(crtc_state)) - connector->eld[5] |= (1 << 2); - connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; if (dev_priv->display.audio_codec_enable) diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 951e834dd274..28a778b785ac 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -30,6 +30,21 @@ #include "intel_drv.h" #include "i915_drv.h" +static void intel_connector_update_eld_conn_type(struct drm_connector *connector) +{ + u8 conn_type; + + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + conn_type = DRM_ELD_CONN_TYPE_DP; + } else { + conn_type = DRM_ELD_CONN_TYPE_HDMI; + } + + connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] &= ~DRM_ELD_CONN_TYPE_MASK; + connector->eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= conn_type; +} + /** * intel_connector_update_modes - update connector from edid * @connector: DRM connector device to use @@ -44,6 +59,8 @@ int intel_connector_update_modes(struct drm_connector *connector, ret = drm_add_edid_modes(connector, edid); drm_edid_to_eld(connector, edid); + intel_connector_update_eld_conn_type(connector); + return ret; } -- cgit v1.2.3 From bf5d10dcae3549b779490672c705c6ac79cf68a3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 14 Sep 2017 17:21:54 +0100 Subject: drm/i915: remove redundant variable hw_check hw_check is being assigned and updated but is no longer being read, hence it is redundant and can be removed. Detected by clang scan-build: "warning: Value stored to 'hw_check' during its initialization is never read" Fixes: f6d1973db2d2 ("drm/i915: Move modeset state verifier calls") Signed-off-by: Colin Ian King Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20170914162154.11304-1-colin.king@canonical.com (cherry picked from commit 4babc5e27cfda59e2e257d28628b8d853aea5206) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_display.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 00cd17c76fdc..64f7b51ed97c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12359,7 +12359,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) struct drm_crtc_state *old_crtc_state, *new_crtc_state; struct drm_crtc *crtc; struct intel_crtc_state *intel_cstate; - bool hw_check = intel_state->modeset; u64 put_domains[I915_MAX_PIPES] = {}; unsigned crtc_vblank_mask = 0; int i; @@ -12376,7 +12375,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) if (needs_modeset(new_crtc_state) || to_intel_crtc_state(new_crtc_state)->update_pipe) { - hw_check = true; put_domains[to_intel_crtc(crtc)->pipe] = modeset_get_crtc_power_domains(crtc, -- cgit v1.2.3 From 2ba7d7e0437127314864238f8bfcb8369d81075c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 21 Sep 2017 17:19:20 +0300 Subject: drm/i915/bios: ignore HDMI on port A MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hardware state readout oopses after several warnings when trying to use HDMI on port A, if such a combination is configured in VBT. Filter the combo out already at the VBT parsing phase. v2: also ignore DVI (Ville) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102889 Cc: stable@vger.kernel.org Cc: Imre Deak Reviewed-by: Ville Syrjälä Tested-by: Daniel Drake Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170921141920.18172-1-jani.nikula@intel.com (cherry picked from commit d27ffc1d00327c29b3aa97f941b42f0949f9e99f) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_bios.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 183e87e8ea31..00c6aee0a9a1 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1163,6 +1163,13 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0; is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR); + if (port == PORT_A && is_dvi) { + DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n", + is_hdmi ? "/HDMI" : ""); + is_dvi = false; + is_hdmi = false; + } + info->supports_dvi = is_dvi; info->supports_hdmi = is_hdmi; info->supports_dp = is_dp; -- cgit v1.2.3 From 4e9767bc28e93139442847f023ff2fc0c2a21d34 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 20 Sep 2017 11:35:24 -0700 Subject: drm/i915/cnl: Add support slice/subslice/eu configs Cannonlake Slice and Subslice information has changed. This patch initially provided by Ben adds the proper sseu initialization. v2: This v2 done by Rodrigo includes: - Fix on Total slices count by avoiding [1][2] and [2][2]. - Inclusion of EU Per Subslice. - Commit message. v3: This v3 done by Rodrigo includes: - Handle all possible bits and extra fuse register. - Use INTEL_GEN macro. - Fully assume uniform distribution so remove union with eu_per_subslice and add proper the comment. v4: This v4 done by Rodrigo includes: - Consider all bits available: 6 bits for slices [27:22] and 4 for subslices [21:18]. v5: This v5 done by Rodrigo includes: - sseu->subslice_mask = (1 << 4) - 1 - missed on previous versions and noticed by Oscar. Cc: Oscar Mateo Signed-off-by: Ben Widawsky Signed-off-by: Rodrigo Vivi Reviewed-by: Oscar Mateo Link: https://patchwork.freedesktop.org/patch/msgid/20170920183525.20530-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 8 +++++++ drivers/gpu/drm/i915/intel_device_info.c | 37 +++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 76fd8fda46d2..e4c424ba5905 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2730,6 +2730,11 @@ enum i915_power_well_id { #define GEN9_F2_SS_DIS_SHIFT 20 #define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT) +#define GEN10_F2_S_ENA_SHIFT 22 +#define GEN10_F2_S_ENA_MASK (0x3f << GEN10_F2_S_ENA_SHIFT) +#define GEN10_F2_SS_DIS_SHIFT 18 +#define GEN10_F2_SS_DIS_MASK (0xf << GEN10_F2_SS_DIS_SHIFT) + #define GEN8_EU_DISABLE0 _MMIO(0x9134) #define GEN8_EU_DIS0_S0_MASK 0xffffff #define GEN8_EU_DIS0_S1_SHIFT 24 @@ -2745,6 +2750,9 @@ enum i915_power_well_id { #define GEN9_EU_DISABLE(slice) _MMIO(0x9134 + (slice)*0x4) +#define GEN10_EU_DISABLE3 _MMIO(0x9140) +#define GEN10_EU_DIS_SS_MASK 0xff + #define GEN6_BSD_SLEEP_PSMI_CONTROL _MMIO(0x12050) #define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) #define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index fdf9b54b71e9..875d428ea75f 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -82,6 +82,39 @@ void intel_device_info_dump(struct drm_i915_private *dev_priv) #undef PRINT_FLAG } +static void gen10_sseu_info_init(struct drm_i915_private *dev_priv) +{ + struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; + const u32 fuse2 = I915_READ(GEN8_FUSE2); + + sseu->slice_mask = (fuse2 & GEN10_F2_S_ENA_MASK) >> + GEN10_F2_S_ENA_SHIFT; + sseu->subslice_mask = (1 << 4) - 1; + sseu->subslice_mask &= ~((fuse2 & GEN10_F2_SS_DIS_MASK) >> + GEN10_F2_SS_DIS_SHIFT); + + sseu->eu_total = hweight32(~I915_READ(GEN8_EU_DISABLE0)); + sseu->eu_total += hweight32(~I915_READ(GEN8_EU_DISABLE1)); + sseu->eu_total += hweight32(~I915_READ(GEN8_EU_DISABLE2)); + sseu->eu_total += hweight8(~(I915_READ(GEN10_EU_DISABLE3) & + GEN10_EU_DIS_SS_MASK)); + + /* + * CNL is expected to always have a uniform distribution + * of EU across subslices with the exception that any one + * EU in any one subslice may be fused off for die + * recovery. + */ + sseu->eu_per_subslice = sseu_subslice_total(sseu) ? + DIV_ROUND_UP(sseu->eu_total, + sseu_subslice_total(sseu)) : 0; + + /* No restrictions on Power Gating */ + sseu->has_slice_pg = 1; + sseu->has_subslice_pg = 1; + sseu->has_eu_pg = 1; +} + static void cherryview_sseu_info_init(struct drm_i915_private *dev_priv) { struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; @@ -409,8 +442,10 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) cherryview_sseu_info_init(dev_priv); else if (IS_BROADWELL(dev_priv)) broadwell_sseu_info_init(dev_priv); - else if (INTEL_INFO(dev_priv)->gen >= 9) + else if (INTEL_GEN(dev_priv) == 9) gen9_sseu_info_init(dev_priv); + else if (INTEL_GEN(dev_priv) >= 10) + gen10_sseu_info_init(dev_priv); DRM_DEBUG_DRIVER("slice mask: %04x\n", info->sseu.slice_mask); DRM_DEBUG_DRIVER("slice total: %u\n", hweight8(info->sseu.slice_mask)); -- cgit v1.2.3 From d85fc17beeb06f9979d63fe4d9fbffbb1a00bba4 Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Mon, 25 Sep 2017 10:48:47 +0300 Subject: aquantia: Setup max_mtu in ndev to enable jumbo frames Although hardware is capable for almost 16K MTU, without max_mtu field correctly set it only allows standard MTU to be used. This patch enables max MTU, calculating it from hardware maximum frame size of 16352 octets (including FCS). Fixes: 5513e16421cb ("net: ethernet: aquantia: Fixes for aq_ndev_change_mtu") Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 11 ++--------- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 6ac9e2602d6d..bf26a59a9d8e 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -214,7 +214,6 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops, SET_NETDEV_DEV(ndev, dev); ndev->if_port = port; - ndev->min_mtu = ETH_MIN_MTU; self->ndev = ndev; self->aq_pci_func = aq_pci_func; @@ -283,6 +282,7 @@ int aq_nic_ndev_init(struct aq_nic_s *self) self->ndev->features = aq_hw_caps->hw_features; self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN; + self->ndev->max_mtu = self->aq_hw_caps.mtu - ETH_FCS_LEN - ETH_HLEN; return 0; } @@ -693,16 +693,9 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu) { - int err = 0; - - if (new_mtu > self->aq_hw_caps.mtu) { - err = -EINVAL; - goto err_exit; - } self->aq_nic_cfg.mtu = new_mtu; -err_exit: - return err; + return 0; } int aq_nic_set_mac(struct aq_nic_s *self, struct net_device *ndev) diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h index f3957e930340..fcf89e25a773 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h @@ -16,7 +16,7 @@ #include "../aq_common.h" -#define HW_ATL_B0_MTU_JUMBO (16000U) +#define HW_ATL_B0_MTU_JUMBO 16352U #define HW_ATL_B0_MTU 1514U #define HW_ATL_B0_TX_RINGS 4U -- cgit v1.2.3 From 3aec6412e007b294d4c135f5c7ed5e5ecf37dd2e Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Mon, 25 Sep 2017 10:48:48 +0300 Subject: aquantia: Fix Tx queue hangups Driver did a poor job in managing its Tx queues: Sometimes it could stop tx queues due to link down condition in aq_nic_xmit - but never waked up them. That led to Tx path total suspend. This patch fixes this and improves generic queue management: - introduces queue restart counter - uses generic netif_ interface to disable and enable tx path - refactors link up/down condition and introduces dmesg log event when link changes. - introduces new constant for minimum descriptors count required for queue wakeup Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_cfg.h | 4 ++ drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 91 +++++++++++------------- drivers/net/ethernet/aquantia/atlantic/aq_nic.h | 2 - drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 26 +++++++ drivers/net/ethernet/aquantia/atlantic/aq_ring.h | 4 ++ drivers/net/ethernet/aquantia/atlantic/aq_vec.c | 8 +-- 6 files changed, 76 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h index 214986436ece..0fdaaa643073 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h @@ -51,6 +51,10 @@ #define AQ_CFG_SKB_FRAGS_MAX 32U +/* Number of descriptors available in one ring to resume this ring queue + */ +#define AQ_CFG_RESTART_DESC_THRES (AQ_CFG_SKB_FRAGS_MAX * 2) + #define AQ_CFG_NAPI_WEIGHT 64U #define AQ_CFG_MULTICAST_ADDRESS_MAX 32U diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index bf26a59a9d8e..072a55029f04 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -119,6 +119,35 @@ int aq_nic_cfg_start(struct aq_nic_s *self) return 0; } +static int aq_nic_update_link_status(struct aq_nic_s *self) +{ + int err = self->aq_hw_ops.hw_get_link_status(self->aq_hw); + + if (err) + return err; + + if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) + pr_info("%s: link change old %d new %d\n", + AQ_CFG_DRV_NAME, self->link_status.mbps, + self->aq_hw->aq_link_status.mbps); + + self->link_status = self->aq_hw->aq_link_status; + if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) { + aq_utils_obj_set(&self->header.flags, + AQ_NIC_FLAG_STARTED); + aq_utils_obj_clear(&self->header.flags, + AQ_NIC_LINK_DOWN); + netif_carrier_on(self->ndev); + netif_tx_wake_all_queues(self->ndev); + } + if (netif_carrier_ok(self->ndev) && !self->link_status.mbps) { + netif_carrier_off(self->ndev); + netif_tx_disable(self->ndev); + aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN); + } + return 0; +} + static void aq_nic_service_timer_cb(unsigned long param) { struct aq_nic_s *self = (struct aq_nic_s *)param; @@ -131,26 +160,13 @@ static void aq_nic_service_timer_cb(unsigned long param) if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY)) goto err_exit; - err = self->aq_hw_ops.hw_get_link_status(self->aq_hw); - if (err < 0) + err = aq_nic_update_link_status(self); + if (err) goto err_exit; - self->link_status = self->aq_hw->aq_link_status; - self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, self->aq_nic_cfg.is_interrupt_moderation); - if (self->link_status.mbps) { - aq_utils_obj_set(&self->header.flags, - AQ_NIC_FLAG_STARTED); - aq_utils_obj_clear(&self->header.flags, - AQ_NIC_LINK_DOWN); - netif_carrier_on(self->ndev); - } else { - netif_carrier_off(self->ndev); - aq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN); - } - memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); for (i = AQ_DIMOF(self->aq_vec); i--;) { @@ -240,7 +256,6 @@ err_exit: int aq_nic_ndev_register(struct aq_nic_s *self) { int err = 0; - unsigned int i = 0U; if (!self->ndev) { err = -EINVAL; @@ -262,8 +277,7 @@ int aq_nic_ndev_register(struct aq_nic_s *self) netif_carrier_off(self->ndev); - for (i = AQ_CFG_VECS_MAX; i--;) - aq_nic_ndev_queue_stop(self, i); + netif_tx_disable(self->ndev); err = register_netdev(self->ndev); if (err < 0) @@ -318,12 +332,8 @@ struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev) err = -EINVAL; goto err_exit; } - if (netif_running(ndev)) { - unsigned int i; - - for (i = AQ_CFG_VECS_MAX; i--;) - netif_stop_subqueue(ndev, i); - } + if (netif_running(ndev)) + netif_tx_disable(ndev); for (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs; self->aq_vecs++) { @@ -383,16 +393,6 @@ err_exit: return err; } -void aq_nic_ndev_queue_start(struct aq_nic_s *self, unsigned int idx) -{ - netif_start_subqueue(self->ndev, idx); -} - -void aq_nic_ndev_queue_stop(struct aq_nic_s *self, unsigned int idx) -{ - netif_stop_subqueue(self->ndev, idx); -} - int aq_nic_start(struct aq_nic_s *self) { struct aq_vec_s *aq_vec = NULL; @@ -451,10 +451,6 @@ int aq_nic_start(struct aq_nic_s *self) goto err_exit; } - for (i = 0U, aq_vec = self->aq_vec[0]; - self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) - aq_nic_ndev_queue_start(self, i); - err = netif_set_real_num_tx_queues(self->ndev, self->aq_vecs); if (err < 0) goto err_exit; @@ -463,6 +459,8 @@ int aq_nic_start(struct aq_nic_s *self) if (err < 0) goto err_exit; + netif_tx_start_all_queues(self->ndev); + err_exit: return err; } @@ -602,7 +600,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs; unsigned int tc = 0U; int err = NETDEV_TX_OK; - bool is_nic_in_bad_state; frags = skb_shinfo(skb)->nr_frags + 1; @@ -613,13 +610,10 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) goto err_exit; } - is_nic_in_bad_state = aq_utils_obj_test(&self->header.flags, - AQ_NIC_FLAGS_IS_NOT_TX_READY) || - (aq_ring_avail_dx(ring) < - AQ_CFG_SKB_FRAGS_MAX); + aq_ring_update_queue_state(ring); - if (is_nic_in_bad_state) { - aq_nic_ndev_queue_stop(self, ring->idx); + /* Above status update may stop the queue. Check this. */ + if (__netif_subqueue_stopped(self->ndev, ring->idx)) { err = NETDEV_TX_BUSY; goto err_exit; } @@ -631,9 +625,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) ring, frags); if (err >= 0) { - if (aq_ring_avail_dx(ring) < AQ_CFG_SKB_FRAGS_MAX + 1) - aq_nic_ndev_queue_stop(self, ring->idx); - ++ring->stats.tx.packets; ring->stats.tx.bytes += skb->len; } @@ -898,9 +889,7 @@ int aq_nic_stop(struct aq_nic_s *self) struct aq_vec_s *aq_vec = NULL; unsigned int i = 0U; - for (i = 0U, aq_vec = self->aq_vec[0]; - self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) - aq_nic_ndev_queue_stop(self, i); + netif_tx_disable(self->ndev); del_timer_sync(&self->service_timer); diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h index 7fc2a5ecb2b7..0ddd556ff901 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h @@ -83,8 +83,6 @@ struct net_device *aq_nic_get_ndev(struct aq_nic_s *self); int aq_nic_init(struct aq_nic_s *self); int aq_nic_cfg_start(struct aq_nic_s *self); int aq_nic_ndev_register(struct aq_nic_s *self); -void aq_nic_ndev_queue_start(struct aq_nic_s *self, unsigned int idx); -void aq_nic_ndev_queue_stop(struct aq_nic_s *self, unsigned int idx); void aq_nic_ndev_free(struct aq_nic_s *self); int aq_nic_start(struct aq_nic_s *self); int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb); diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 4eee1996a825..02f79b0640ba 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -104,6 +104,32 @@ int aq_ring_init(struct aq_ring_s *self) return 0; } +void aq_ring_update_queue_state(struct aq_ring_s *ring) +{ + if (aq_ring_avail_dx(ring) <= AQ_CFG_SKB_FRAGS_MAX) + aq_ring_queue_stop(ring); + else if (aq_ring_avail_dx(ring) > AQ_CFG_RESTART_DESC_THRES) + aq_ring_queue_wake(ring); +} + +void aq_ring_queue_wake(struct aq_ring_s *ring) +{ + struct net_device *ndev = aq_nic_get_ndev(ring->aq_nic); + + if (__netif_subqueue_stopped(ndev, ring->idx)) { + netif_wake_subqueue(ndev, ring->idx); + ring->stats.tx.queue_restarts++; + } +} + +void aq_ring_queue_stop(struct aq_ring_s *ring) +{ + struct net_device *ndev = aq_nic_get_ndev(ring->aq_nic); + + if (!__netif_subqueue_stopped(ndev, ring->idx)) + netif_stop_subqueue(ndev, ring->idx); +} + void aq_ring_tx_clean(struct aq_ring_s *self) { struct device *dev = aq_nic_get_dev(self->aq_nic); diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h index 782176c5f4f8..24523b5ac68c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h @@ -94,6 +94,7 @@ struct aq_ring_stats_tx_s { u64 errors; u64 packets; u64 bytes; + u64 queue_restarts; }; union aq_ring_stats_s { @@ -147,6 +148,9 @@ struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, int aq_ring_init(struct aq_ring_s *self); void aq_ring_rx_deinit(struct aq_ring_s *self); void aq_ring_free(struct aq_ring_s *self); +void aq_ring_update_queue_state(struct aq_ring_s *ring); +void aq_ring_queue_wake(struct aq_ring_s *ring); +void aq_ring_queue_stop(struct aq_ring_s *ring); void aq_ring_tx_clean(struct aq_ring_s *self); int aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi, diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c index ebf588004c46..305ff8ffac2c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c @@ -59,12 +59,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget) if (ring[AQ_VEC_TX_ID].sw_head != ring[AQ_VEC_TX_ID].hw_head) { aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); - - if (aq_ring_avail_dx(&ring[AQ_VEC_TX_ID]) > - AQ_CFG_SKB_FRAGS_MAX) { - aq_nic_ndev_queue_start(self->aq_nic, - ring[AQ_VEC_TX_ID].idx); - } + aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]); was_tx_cleaned = true; } @@ -364,6 +359,7 @@ void aq_vec_add_stats(struct aq_vec_s *self, stats_tx->packets += tx->packets; stats_tx->bytes += tx->bytes; stats_tx->errors += tx->errors; + stats_tx->queue_restarts += tx->queue_restarts; } } -- cgit v1.2.3 From a7bb1bea3a296549ebfc28afa76276ef392f9afa Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Mon, 25 Sep 2017 10:48:49 +0300 Subject: aquantia: Fix transient invalid link down/up indications Due to a bug in aquantia atlantic card firmware, it sometimes reports invalid link speed bits. That caused driver to report link down events, although link itself is totally fine. This patch ignores such out of blue readings. Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c index 4f5ec9a0fbfb..bf734b32e44b 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c @@ -351,8 +351,7 @@ int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self) break; default: - link_status->mbps = 0U; - break; + return -EBUSY; } } -- cgit v1.2.3 From c7545689244b50c562b1fbbc71905fba224c8a05 Mon Sep 17 00:00:00 2001 From: Pavel Belous Date: Mon, 25 Sep 2017 10:48:50 +0300 Subject: atlantic: fix iommu errors Call skb_frag_dma_map multiple times if tx length is greater than device max and avoid processing tx ring until entire packet has been sent. Signed-off-by: Igor Russkikh Signed-off-by: Pavel Belous Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 43 ++++++++++++++---------- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 27 ++++++++++----- drivers/net/ethernet/aquantia/atlantic/aq_ring.h | 6 ++-- 3 files changed, 49 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 072a55029f04..0a5bb4114eb4 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -473,6 +473,7 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int frag_count = 0U; unsigned int dx = ring->sw_tail; + struct aq_ring_buff_s *first = NULL; struct aq_ring_buff_s *dx_buff = &ring->buff_ring[dx]; if (unlikely(skb_is_gso(skb))) { @@ -483,6 +484,7 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, dx_buff->len_l4 = tcp_hdrlen(skb); dx_buff->mss = skb_shinfo(skb)->gso_size; dx_buff->is_txc = 1U; + dx_buff->eop_index = 0xffffU; dx_buff->is_ipv6 = (ip_hdr(skb)->version == 6) ? 1U : 0U; @@ -502,6 +504,7 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) goto exit; + first = dx_buff; dx_buff->len_pkt = skb->len; dx_buff->is_sop = 1U; dx_buff->is_mapped = 1U; @@ -530,40 +533,46 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, for (; nr_frags--; ++frag_count) { unsigned int frag_len = 0U; + unsigned int buff_offset = 0U; + unsigned int buff_size = 0U; dma_addr_t frag_pa; skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_count]; frag_len = skb_frag_size(frag); - frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), frag, 0, - frag_len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(aq_nic_get_dev(self), frag_pa))) - goto mapping_error; + while (frag_len) { + if (frag_len > AQ_CFG_TX_FRAME_MAX) + buff_size = AQ_CFG_TX_FRAME_MAX; + else + buff_size = frag_len; + + frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), + frag, + buff_offset, + buff_size, + DMA_TO_DEVICE); + + if (unlikely(dma_mapping_error(aq_nic_get_dev(self), + frag_pa))) + goto mapping_error; - while (frag_len > AQ_CFG_TX_FRAME_MAX) { dx = aq_ring_next_dx(ring, dx); dx_buff = &ring->buff_ring[dx]; dx_buff->flags = 0U; - dx_buff->len = AQ_CFG_TX_FRAME_MAX; + dx_buff->len = buff_size; dx_buff->pa = frag_pa; dx_buff->is_mapped = 1U; + dx_buff->eop_index = 0xffffU; + + frag_len -= buff_size; + buff_offset += buff_size; - frag_len -= AQ_CFG_TX_FRAME_MAX; - frag_pa += AQ_CFG_TX_FRAME_MAX; ++ret; } - - dx = aq_ring_next_dx(ring, dx); - dx_buff = &ring->buff_ring[dx]; - - dx_buff->flags = 0U; - dx_buff->len = frag_len; - dx_buff->pa = frag_pa; - dx_buff->is_mapped = 1U; - ++ret; } + first->eop_index = dx; dx_buff->is_eop = 1U; dx_buff->skb = skb; goto exit; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 02f79b0640ba..0654e0c76bc2 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -104,6 +104,12 @@ int aq_ring_init(struct aq_ring_s *self) return 0; } +static inline bool aq_ring_dx_in_range(unsigned int h, unsigned int i, + unsigned int t) +{ + return (h < t) ? ((h < i) && (i < t)) : ((h < i) || (i < t)); +} + void aq_ring_update_queue_state(struct aq_ring_s *ring) { if (aq_ring_avail_dx(ring) <= AQ_CFG_SKB_FRAGS_MAX) @@ -139,23 +145,28 @@ void aq_ring_tx_clean(struct aq_ring_s *self) struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; if (likely(buff->is_mapped)) { - if (unlikely(buff->is_sop)) + if (unlikely(buff->is_sop)) { + if (!buff->is_eop && + buff->eop_index != 0xffffU && + (!aq_ring_dx_in_range(self->sw_head, + buff->eop_index, + self->hw_head))) + break; + dma_unmap_single(dev, buff->pa, buff->len, DMA_TO_DEVICE); - else + } else { dma_unmap_page(dev, buff->pa, buff->len, DMA_TO_DEVICE); + } } if (unlikely(buff->is_eop)) dev_kfree_skb_any(buff->skb); - } -} -static inline unsigned int aq_ring_dx_in_range(unsigned int h, unsigned int i, - unsigned int t) -{ - return (h < t) ? ((h < i) && (i < t)) : ((h < i) || (i < t)); + buff->pa = 0U; + buff->eop_index = 0xffffU; + } } #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h index 24523b5ac68c..5844078764bd 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h @@ -65,7 +65,7 @@ struct __packed aq_ring_buff_s { }; union { struct { - u32 len:16; + u16 len; u32 is_ip_cso:1; u32 is_udp_cso:1; u32 is_tcp_cso:1; @@ -77,8 +77,10 @@ struct __packed aq_ring_buff_s { u32 is_cleaned:1; u32 is_error:1; u32 rsvd3:6; + u16 eop_index; + u16 rsvd4; }; - u32 flags; + u64 flags; }; }; -- cgit v1.2.3 From 7da2bcf87617fb00386ce61024e1c84d045b4e4f Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 27 Sep 2017 00:09:48 -0400 Subject: drm/amdkfd: Avoid name confusion involved in queue unmapping When unmapping the queues from HW scheduler, there are two actions: reset and preempt. So naming the variables with only preempt is inapproriate. For functions such as destroy_queues_cpsch, what they do actually is to unmap the queues on HW scheduler rather than to destroy them. Change the name to reflect that fact. On the other hand, there is already a function called destroy_queue_cpsch() which exactly destroys a queue, and the name is very close to destroy_queues_cpsch(), resulting in confusion. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 32 +++++++++++----------- drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c | 18 ++++++------ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 20 +++++++------- 3 files changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 471b34e58225..1995e0aa7fa3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -45,8 +45,8 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, struct qcm_process_device *qpd); static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock); -static int destroy_queues_cpsch(struct device_queue_manager *dqm, - bool preempt_static_queues, bool lock); +static int unmap_queues_cpsch(struct device_queue_manager *dqm, + bool static_queues_included, bool lock); static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, struct queue *q, @@ -707,7 +707,7 @@ fail_packet_manager_init: static int stop_cpsch(struct device_queue_manager *dqm) { - destroy_queues_cpsch(dqm, true, true); + unmap_queues_cpsch(dqm, true, true); kfd_gtt_sa_free(dqm->dev, dqm->fence_mem); pm_uninit(&dqm->packets); @@ -750,7 +750,7 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, { mutex_lock(&dqm->lock); /* here we actually preempt the DIQ */ - destroy_queues_cpsch(dqm, true, false); + unmap_queues_cpsch(dqm, true, false); list_del(&kq->list); dqm->queue_count--; qpd->is_debug = false; @@ -849,19 +849,19 @@ int amdkfd_fence_wait_timeout(unsigned int *fence_addr, return 0; } -static int destroy_sdma_queues(struct device_queue_manager *dqm, +static int unmap_sdma_queues(struct device_queue_manager *dqm, unsigned int sdma_engine) { return pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA, - KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES, 0, false, + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0, false, sdma_engine); } -static int destroy_queues_cpsch(struct device_queue_manager *dqm, - bool preempt_static_queues, bool lock) +static int unmap_queues_cpsch(struct device_queue_manager *dqm, + bool static_queues_included, bool lock) { int retval; - enum kfd_preempt_type_filter preempt_type; + enum kfd_unmap_queues_filter filter; struct kfd_process_device *pdd; retval = 0; @@ -875,16 +875,16 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, dqm->sdma_queue_count); if (dqm->sdma_queue_count > 0) { - destroy_sdma_queues(dqm, 0); - destroy_sdma_queues(dqm, 1); + unmap_sdma_queues(dqm, 0); + unmap_sdma_queues(dqm, 1); } - preempt_type = preempt_static_queues ? - KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES : - KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES; + filter = static_queues_included ? + KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES : + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES; retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, - preempt_type, 0, false, 0); + filter, 0, false, 0); if (retval) goto out; @@ -916,7 +916,7 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock) if (lock) mutex_lock(&dqm->lock); - retval = destroy_queues_cpsch(dqm, false, false); + retval = unmap_queues_cpsch(dqm, false, false); if (retval) { pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption"); goto out; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c index 9eda884d8d48..e5a15babb4f3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c @@ -476,7 +476,7 @@ fail_acquire_packet_buffer: } int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, - enum kfd_preempt_type_filter mode, + enum kfd_unmap_queues_filter filter, uint32_t filter_param, bool reset, unsigned int sdma_engine) { @@ -494,8 +494,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, packet = (struct pm4_mes_unmap_queues *)buffer; memset(buffer, 0, sizeof(struct pm4_mes_unmap_queues)); - pr_debug("static_queue: unmapping queues: mode is %d , reset is %d , type is %d\n", - mode, reset, type); + pr_debug("static_queue: unmapping queues: filter is %d , reset is %d , type is %d\n", + filter, reset, type); packet->header.u32All = build_pm4_header(IT_UNMAP_QUEUES, sizeof(struct pm4_mes_unmap_queues)); switch (type) { @@ -521,29 +521,29 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, packet->bitfields2.action = action__mes_unmap_queues__preempt_queues; - switch (mode) { - case KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE: + switch (filter) { + case KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE: packet->bitfields2.queue_sel = queue_sel__mes_unmap_queues__perform_request_on_specified_queues; packet->bitfields2.num_queues = 1; packet->bitfields3b.doorbell_offset0 = filter_param; break; - case KFD_PREEMPT_TYPE_FILTER_BY_PASID: + case KFD_UNMAP_QUEUES_FILTER_BY_PASID: packet->bitfields2.queue_sel = queue_sel__mes_unmap_queues__perform_request_on_pasid_queues; packet->bitfields3a.pasid = filter_param; break; - case KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES: + case KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES: packet->bitfields2.queue_sel = queue_sel__mes_unmap_queues__unmap_all_queues; break; - case KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES: + case KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES: /* in this case, we do not preempt static queues */ packet->bitfields2.queue_sel = queue_sel__mes_unmap_queues__unmap_all_non_static_queues; break; default: - WARN(1, "filter %d", mode); + WARN(1, "filter %d", filter); retval = -EINVAL; goto err_invalid; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 5ebe565fecb3..8af0d6fe257a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -222,22 +222,22 @@ void kfd_chardev_exit(void); struct device *kfd_chardev(void); /** - * enum kfd_preempt_type_filter + * enum kfd_unmap_queues_filter * - * @KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE: Preempts single queue. + * @KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE: Preempts single queue. * - * @KFD_PRERMPT_TYPE_FILTER_ALL_QUEUES: Preempts all queues in the + * @KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES: Preempts all queues in the * running queues list. * - * @KFD_PRERMPT_TYPE_FILTER_BY_PASID: Preempts queues that belongs to + * @KFD_UNMAP_QUEUES_FILTER_BY_PASID: Preempts queues that belongs to * specific process. * */ -enum kfd_preempt_type_filter { - KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE, - KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, - KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES, - KFD_PREEMPT_TYPE_FILTER_BY_PASID +enum kfd_unmap_queues_filter { + KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE, + KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, + KFD_UNMAP_QUEUES_FILTER_BY_PASID }; /** @@ -700,7 +700,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, uint32_t fence_value); int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, - enum kfd_preempt_type_filter mode, + enum kfd_unmap_queues_filter mode, uint32_t filter_param, bool reset, unsigned int sdma_engine); -- cgit v1.2.3 From ac30c78384885b209324dacc7b65bd8e9cc69fbf Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Sun, 8 Oct 2017 14:57:18 +0300 Subject: drm/amdkfd: move locking outside of unmap_queues_cpsch Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 65 ++++++++++------------ 1 file changed, 28 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 1995e0aa7fa3..0f9c39ba548a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -44,9 +44,9 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, struct queue *q, struct qcm_process_device *qpd); -static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock); +static int execute_queues_cpsch(struct device_queue_manager *dqm); static int unmap_queues_cpsch(struct device_queue_manager *dqm, - bool static_queues_included, bool lock); + bool static_queues_included); static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, struct queue *q, @@ -379,7 +379,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) dqm->queue_count--; if (sched_policy != KFD_SCHED_POLICY_NO_HWS) - retval = execute_queues_cpsch(dqm, false); + retval = execute_queues_cpsch(dqm); out_unlock: mutex_unlock(&dqm->lock); @@ -695,7 +695,9 @@ static int start_cpsch(struct device_queue_manager *dqm) init_interrupts(dqm); - execute_queues_cpsch(dqm, true); + mutex_lock(&dqm->lock); + execute_queues_cpsch(dqm); + mutex_unlock(&dqm->lock); return 0; fail_allocate_vidmem: @@ -707,7 +709,9 @@ fail_packet_manager_init: static int stop_cpsch(struct device_queue_manager *dqm) { - unmap_queues_cpsch(dqm, true, true); + mutex_lock(&dqm->lock); + unmap_queues_cpsch(dqm, true); + mutex_unlock(&dqm->lock); kfd_gtt_sa_free(dqm->dev, dqm->fence_mem); pm_uninit(&dqm->packets); @@ -738,7 +742,7 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm, list_add(&kq->list, &qpd->priv_queue_list); dqm->queue_count++; qpd->is_debug = true; - execute_queues_cpsch(dqm, false); + execute_queues_cpsch(dqm); mutex_unlock(&dqm->lock); return 0; @@ -750,11 +754,11 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, { mutex_lock(&dqm->lock); /* here we actually preempt the DIQ */ - unmap_queues_cpsch(dqm, true, false); + unmap_queues_cpsch(dqm, true); list_del(&kq->list); dqm->queue_count--; qpd->is_debug = false; - execute_queues_cpsch(dqm, false); + execute_queues_cpsch(dqm); /* * Unconditionally decrement this counter, regardless of the queue's * type. @@ -813,7 +817,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, list_add(&q->list, &qpd->queues_list); if (q->properties.is_active) { dqm->queue_count++; - retval = execute_queues_cpsch(dqm, false); + retval = execute_queues_cpsch(dqm); } if (q->properties.type == KFD_QUEUE_TYPE_SDMA) @@ -857,8 +861,9 @@ static int unmap_sdma_queues(struct device_queue_manager *dqm, sdma_engine); } +/* dqm->lock mutex has to be locked before calling this function */ static int unmap_queues_cpsch(struct device_queue_manager *dqm, - bool static_queues_included, bool lock) + bool static_queues_included) { int retval; enum kfd_unmap_queues_filter filter; @@ -866,10 +871,8 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, retval = 0; - if (lock) - mutex_lock(&dqm->lock); if (!dqm->active_runlist) - goto out; + return retval; pr_debug("Before destroying queues, sdma queue count is : %u\n", dqm->sdma_queue_count); @@ -886,7 +889,7 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, filter, 0, false, 0); if (retval) - goto out; + return retval; *dqm->fence_addr = KFD_FENCE_INIT; pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr, @@ -898,50 +901,38 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, pdd = kfd_get_process_device_data(dqm->dev, kfd_get_process(current)); pdd->reset_wavefronts = true; - goto out; + return retval; } pm_release_ib(&dqm->packets); dqm->active_runlist = false; -out: - if (lock) - mutex_unlock(&dqm->lock); return retval; } -static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock) +/* dqm->lock mutex has to be locked before calling this function */ +static int execute_queues_cpsch(struct device_queue_manager *dqm) { int retval; - if (lock) - mutex_lock(&dqm->lock); - - retval = unmap_queues_cpsch(dqm, false, false); + retval = unmap_queues_cpsch(dqm, false); if (retval) { pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption"); - goto out; + return retval; } - if (dqm->queue_count <= 0 || dqm->processes_count <= 0) { - retval = 0; - goto out; - } + if (dqm->queue_count <= 0 || dqm->processes_count <= 0) + return 0; - if (dqm->active_runlist) { - retval = 0; - goto out; - } + if (dqm->active_runlist) + return 0; retval = pm_send_runlist(&dqm->packets, &dqm->queues); if (retval) { pr_err("failed to execute runlist"); - goto out; + return retval; } dqm->active_runlist = true; -out: - if (lock) - mutex_unlock(&dqm->lock); return retval; } @@ -984,7 +975,7 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, if (q->properties.is_active) dqm->queue_count--; - execute_queues_cpsch(dqm, false); + execute_queues_cpsch(dqm); mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); -- cgit v1.2.3 From 4465f466c76774d3b5866929524cce6dd2d4dfb1 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Sun, 8 Oct 2017 14:57:52 +0300 Subject: drm/amdkfd: Pass filter params to unmap_queues_cpsch Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 0f9c39ba548a..be925a49dd10 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -46,7 +46,8 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, static int execute_queues_cpsch(struct device_queue_manager *dqm); static int unmap_queues_cpsch(struct device_queue_manager *dqm, - bool static_queues_included); + enum kfd_unmap_queues_filter filter, + uint32_t filter_param); static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, struct queue *q, @@ -710,7 +711,7 @@ fail_packet_manager_init: static int stop_cpsch(struct device_queue_manager *dqm) { mutex_lock(&dqm->lock); - unmap_queues_cpsch(dqm, true); + unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); mutex_unlock(&dqm->lock); kfd_gtt_sa_free(dqm->dev, dqm->fence_mem); @@ -754,7 +755,7 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, { mutex_lock(&dqm->lock); /* here we actually preempt the DIQ */ - unmap_queues_cpsch(dqm, true); + unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); list_del(&kq->list); dqm->queue_count--; qpd->is_debug = false; @@ -863,10 +864,10 @@ static int unmap_sdma_queues(struct device_queue_manager *dqm, /* dqm->lock mutex has to be locked before calling this function */ static int unmap_queues_cpsch(struct device_queue_manager *dqm, - bool static_queues_included) + enum kfd_unmap_queues_filter filter, + uint32_t filter_param) { int retval; - enum kfd_unmap_queues_filter filter; struct kfd_process_device *pdd; retval = 0; @@ -882,12 +883,8 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, unmap_sdma_queues(dqm, 1); } - filter = static_queues_included ? - KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES : - KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES; - retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, - filter, 0, false, 0); + filter, filter_param, false, 0); if (retval) return retval; @@ -914,7 +911,8 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm) { int retval; - retval = unmap_queues_cpsch(dqm, false); + retval = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, + 0); if (retval) { pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption"); return retval; -- cgit v1.2.3 From 60a00956577cdc70c85260df89f336f15a2f054c Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 27 Sep 2017 00:09:50 -0400 Subject: drm/amdkfd: Fix MQD updates When a queue is mapped, the MQD is owned by the FW. The FW overwrites the MQD on the next unmap operation. Therefore the queue must be unmapped before updating the MQD. For the non-HWS case, also fix disabling of queues and creation of queues in disabled state. Signed-off-by: Oak Zeng Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 84 ++++++++++++++++------ 1 file changed, 62 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index be925a49dd10..dccb4932bcac 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -49,6 +49,8 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, enum kfd_unmap_queues_filter filter, uint32_t filter_param); +static int map_queues_cpsch(struct device_queue_manager *dqm); + static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, struct queue *q, struct qcm_process_device *qpd); @@ -274,6 +276,9 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, dqm->dev->kfd2kgd->set_scratch_backing_va( dqm->dev->kgd, qpd->sh_hidden_private_base, qpd->vmid); + if (!q->properties.is_active) + return 0; + retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue, &q->properties, q->process->mm); if (retval) @@ -365,23 +370,50 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) goto out_unlock; } - if (q->properties.is_active) - prev_active = true; + /* Save previous activity state for counters */ + prev_active = q->properties.is_active; + + /* Make sure the queue is unmapped before updating the MQD */ + if (sched_policy != KFD_SCHED_POLICY_NO_HWS) { + retval = unmap_queues_cpsch(dqm, + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); + if (retval != 0) { + pr_err("unmap queue failed\n"); + goto out_unlock; + } + } else if (sched_policy == KFD_SCHED_POLICY_NO_HWS && + prev_active && + (q->properties.type == KFD_QUEUE_TYPE_COMPUTE || + q->properties.type == KFD_QUEUE_TYPE_SDMA)) { + retval = mqd->destroy_mqd(mqd, q->mqd, + KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN, + KFD_UNMAP_LATENCY_MS, q->pipe, q->queue); + if (retval) { + pr_err("destroy mqd failed\n"); + goto out_unlock; + } + } + + retval = mqd->update_mqd(mqd, q->mqd, &q->properties); + + if (sched_policy != KFD_SCHED_POLICY_NO_HWS) + retval = map_queues_cpsch(dqm); + else if (sched_policy == KFD_SCHED_POLICY_NO_HWS && + q->properties.is_active && + (q->properties.type == KFD_QUEUE_TYPE_COMPUTE || + q->properties.type == KFD_QUEUE_TYPE_SDMA)) + retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue, + &q->properties, q->process->mm); /* - * * check active state vs. the previous state * and modify counter accordingly */ - retval = mqd->update_mqd(mqd, q->mqd, &q->properties); - if ((q->properties.is_active) && (!prev_active)) + if (q->properties.is_active && !prev_active) dqm->queue_count++; else if (!q->properties.is_active && prev_active) dqm->queue_count--; - if (sched_policy != KFD_SCHED_POLICY_NO_HWS) - retval = execute_queues_cpsch(dqm); - out_unlock: mutex_unlock(&dqm->lock); return retval; @@ -862,6 +894,27 @@ static int unmap_sdma_queues(struct device_queue_manager *dqm, sdma_engine); } +/* dqm->lock mutex has to be locked before calling this function */ +static int map_queues_cpsch(struct device_queue_manager *dqm) +{ + int retval; + + if (dqm->queue_count <= 0 || dqm->processes_count <= 0) + return 0; + + if (dqm->active_runlist) + return 0; + + retval = pm_send_runlist(&dqm->packets, &dqm->queues); + if (retval) { + pr_err("failed to execute runlist\n"); + return retval; + } + dqm->active_runlist = true; + + return retval; +} + /* dqm->lock mutex has to be locked before calling this function */ static int unmap_queues_cpsch(struct device_queue_manager *dqm, enum kfd_unmap_queues_filter filter, @@ -918,20 +971,7 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm) return retval; } - if (dqm->queue_count <= 0 || dqm->processes_count <= 0) - return 0; - - if (dqm->active_runlist) - return 0; - - retval = pm_send_runlist(&dqm->packets, &dqm->queues); - if (retval) { - pr_err("failed to execute runlist"); - return retval; - } - dqm->active_runlist = true; - - return retval; + return map_queues_cpsch(dqm); } static int destroy_queue_cpsch(struct device_queue_manager *dqm, -- cgit v1.2.3 From c4744e243c346b9e96857c6d11c716d31d475165 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 27 Sep 2017 00:09:51 -0400 Subject: drm/amdkfd: Avoid submitting an unnecessary packet to HWS v2: Make queue mapping interfaces more consistent by passing unmap filter parameters directly to execute_queues_cpsch, same as unmap_queues_cpsch. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index dccb4932bcac..f5a5988257c8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -44,7 +44,9 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, struct queue *q, struct qcm_process_device *qpd); -static int execute_queues_cpsch(struct device_queue_manager *dqm); +static int execute_queues_cpsch(struct device_queue_manager *dqm, + enum kfd_unmap_queues_filter filter, + uint32_t filter_param); static int unmap_queues_cpsch(struct device_queue_manager *dqm, enum kfd_unmap_queues_filter filter, uint32_t filter_param); @@ -729,7 +731,7 @@ static int start_cpsch(struct device_queue_manager *dqm) init_interrupts(dqm); mutex_lock(&dqm->lock); - execute_queues_cpsch(dqm); + execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); mutex_unlock(&dqm->lock); return 0; @@ -775,7 +777,7 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm, list_add(&kq->list, &qpd->priv_queue_list); dqm->queue_count++; qpd->is_debug = true; - execute_queues_cpsch(dqm); + execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); mutex_unlock(&dqm->lock); return 0; @@ -786,12 +788,10 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { mutex_lock(&dqm->lock); - /* here we actually preempt the DIQ */ - unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); list_del(&kq->list); dqm->queue_count--; qpd->is_debug = false; - execute_queues_cpsch(dqm); + execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); /* * Unconditionally decrement this counter, regardless of the queue's * type. @@ -850,7 +850,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, list_add(&q->list, &qpd->queues_list); if (q->properties.is_active) { dqm->queue_count++; - retval = execute_queues_cpsch(dqm); + retval = execute_queues_cpsch(dqm, + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); } if (q->properties.type == KFD_QUEUE_TYPE_SDMA) @@ -960,14 +961,15 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, } /* dqm->lock mutex has to be locked before calling this function */ -static int execute_queues_cpsch(struct device_queue_manager *dqm) +static int execute_queues_cpsch(struct device_queue_manager *dqm, + enum kfd_unmap_queues_filter filter, + uint32_t filter_param) { int retval; - retval = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, - 0); + retval = unmap_queues_cpsch(dqm, filter, filter_param); if (retval) { - pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption"); + pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption\n"); return retval; } @@ -1013,7 +1015,7 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, if (q->properties.is_active) dqm->queue_count--; - execute_queues_cpsch(dqm); + execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); -- cgit v1.2.3 From 9fd3f1bfae6c6c75f0c8aedb5d499d74cdb52eb9 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 27 Sep 2017 00:09:52 -0400 Subject: drm/amdkfd: Improve process termination handling Separate device queue termination from process queue manager termination. Unmap all queues at once instead of one at a time. Unmap device queues before the PASID is unbound, in the kfd_process_iommu_unbind_callback. When resetting wavefronts in non-HWS mode, do it before the VMID is released. Signed-off-by: Ben Goz Signed-off-by: shaoyun liu Signed-off-by: Amber Lin Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 185 ++++++++++++++++----- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 5 + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 18 +- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 36 ++-- .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 37 +++-- 5 files changed, 200 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index f5a5988257c8..dd7e44593cfe 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -296,65 +296,73 @@ out_deallocate_hqd: return retval; } -static int destroy_queue_nocpsch(struct device_queue_manager *dqm, +/* Access to DQM has to be locked before calling destroy_queue_nocpsch_locked + * to avoid asynchronized access + */ +static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm, struct qcm_process_device *qpd, struct queue *q) { int retval; struct mqd_manager *mqd; - retval = 0; - - mutex_lock(&dqm->lock); + mqd = dqm->ops.get_mqd_manager(dqm, + get_mqd_type_from_queue_type(q->properties.type)); + if (!mqd) + return -ENOMEM; if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE) { - mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE); - if (mqd == NULL) { - retval = -ENOMEM; - goto out; - } deallocate_hqd(dqm, q); } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { - mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_SDMA); - if (mqd == NULL) { - retval = -ENOMEM; - goto out; - } dqm->sdma_queue_count--; deallocate_sdma_queue(dqm, q->sdma_id); } else { pr_debug("q->properties.type %d is invalid\n", q->properties.type); - retval = -EINVAL; - goto out; + return -EINVAL; } + dqm->total_queue_count--; retval = mqd->destroy_mqd(mqd, q->mqd, KFD_PREEMPT_TYPE_WAVEFRONT_RESET, KFD_UNMAP_LATENCY_MS, q->pipe, q->queue); - - if (retval) - goto out; + if (retval == -ETIME) + qpd->reset_wavefronts = true; mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); list_del(&q->list); - if (list_empty(&qpd->queues_list)) + if (list_empty(&qpd->queues_list)) { + if (qpd->reset_wavefronts) { + pr_warn("Resetting wave fronts (nocpsch) on dev %p\n", + dqm->dev); + /* dbgdev_wave_reset_wavefronts has to be called before + * deallocate_vmid(), i.e. when vmid is still in use. + */ + dbgdev_wave_reset_wavefronts(dqm->dev, + qpd->pqm->process); + qpd->reset_wavefronts = false; + } + deallocate_vmid(dqm, qpd, q); + } if (q->properties.is_active) dqm->queue_count--; - /* - * Unconditionally decrement this counter, regardless of the queue's - * type - */ - dqm->total_queue_count--; - pr_debug("Total of %d queues are accountable so far\n", - dqm->total_queue_count); + return retval; +} -out: +static int destroy_queue_nocpsch(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + struct queue *q) +{ + int retval; + + mutex_lock(&dqm->lock); + retval = destroy_queue_nocpsch_locked(dqm, qpd, q); mutex_unlock(&dqm->lock); + return retval; } @@ -921,10 +929,7 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, enum kfd_unmap_queues_filter filter, uint32_t filter_param) { - int retval; - struct kfd_process_device *pdd; - - retval = 0; + int retval = 0; if (!dqm->active_runlist) return retval; @@ -948,12 +953,9 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, /* should be timed out */ retval = amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED, QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS); - if (retval) { - pdd = kfd_get_process_device_data(dqm->dev, - kfd_get_process(current)); - pdd->reset_wavefronts = true; + if (retval) return retval; - } + pm_release_ib(&dqm->packets); dqm->active_runlist = false; @@ -1015,7 +1017,10 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, if (q->properties.is_active) dqm->queue_count--; - execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); + retval = execute_queues_cpsch(dqm, + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); + if (retval == -ETIME) + qpd->reset_wavefronts = true; mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); @@ -1105,6 +1110,108 @@ out: return retval; } +static int process_termination_nocpsch(struct device_queue_manager *dqm, + struct qcm_process_device *qpd) +{ + struct queue *q, *next; + struct device_process_node *cur, *next_dpn; + int retval = 0; + + mutex_lock(&dqm->lock); + + /* Clear all user mode queues */ + list_for_each_entry_safe(q, next, &qpd->queues_list, list) { + int ret; + + ret = destroy_queue_nocpsch_locked(dqm, qpd, q); + if (ret) + retval = ret; + } + + /* Unregister process */ + list_for_each_entry_safe(cur, next_dpn, &dqm->queues, list) { + if (qpd == cur->qpd) { + list_del(&cur->list); + kfree(cur); + dqm->processes_count--; + break; + } + } + + mutex_unlock(&dqm->lock); + return retval; +} + + +static int process_termination_cpsch(struct device_queue_manager *dqm, + struct qcm_process_device *qpd) +{ + int retval; + struct queue *q, *next; + struct kernel_queue *kq, *kq_next; + struct mqd_manager *mqd; + struct device_process_node *cur, *next_dpn; + enum kfd_unmap_queues_filter filter = + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES; + + retval = 0; + + mutex_lock(&dqm->lock); + + /* Clean all kernel queues */ + list_for_each_entry_safe(kq, kq_next, &qpd->priv_queue_list, list) { + list_del(&kq->list); + dqm->queue_count--; + qpd->is_debug = false; + dqm->total_queue_count--; + filter = KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES; + } + + /* Clear all user mode queues */ + list_for_each_entry(q, &qpd->queues_list, list) { + if (q->properties.type == KFD_QUEUE_TYPE_SDMA) + dqm->sdma_queue_count--; + + if (q->properties.is_active) + dqm->queue_count--; + + dqm->total_queue_count--; + } + + /* Unregister process */ + list_for_each_entry_safe(cur, next_dpn, &dqm->queues, list) { + if (qpd == cur->qpd) { + list_del(&cur->list); + kfree(cur); + dqm->processes_count--; + break; + } + } + + retval = execute_queues_cpsch(dqm, filter, 0); + if (retval || qpd->reset_wavefronts) { + pr_warn("Resetting wave fronts (cpsch) on dev %p\n", dqm->dev); + dbgdev_wave_reset_wavefronts(dqm->dev, qpd->pqm->process); + qpd->reset_wavefronts = false; + } + + /* lastly, free mqd resources */ + list_for_each_entry_safe(q, next, &qpd->queues_list, list) { + mqd = dqm->ops.get_mqd_manager(dqm, + get_mqd_type_from_queue_type(q->properties.type)); + if (!mqd) { + retval = -ENOMEM; + goto out; + } + list_del(&q->list); + mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); + } + +out: + mutex_unlock(&dqm->lock); + return retval; +} + struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) { struct device_queue_manager *dqm; @@ -1133,6 +1240,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) dqm->ops.create_kernel_queue = create_kernel_queue_cpsch; dqm->ops.destroy_kernel_queue = destroy_kernel_queue_cpsch; dqm->ops.set_cache_memory_policy = set_cache_memory_policy; + dqm->ops.process_termination = process_termination_cpsch; break; case KFD_SCHED_POLICY_NO_HWS: /* initialize dqm for no cp scheduling */ @@ -1147,6 +1255,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) dqm->ops.initialize = initialize_nocpsch; dqm->ops.uninitialize = uninitialize; dqm->ops.set_cache_memory_policy = set_cache_memory_policy; + dqm->ops.process_termination = process_termination_nocpsch; break; default: pr_err("Invalid scheduling policy %d\n", sched_policy); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 60d46ce0b8a7..31c2b1f9d320 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -77,6 +77,8 @@ struct device_process_node { * @set_cache_memory_policy: Sets memory policy (cached/ non cached) for the * memory apertures. * + * @process_termination: Clears all process queues belongs to that device. + * */ struct device_queue_manager_ops { @@ -120,6 +122,9 @@ struct device_queue_manager_ops { enum cache_policy alternate_policy, void __user *alternate_aperture_base, uint64_t alternate_aperture_size); + + int (*process_termination)(struct device_queue_manager *dqm, + struct qcm_process_device *qpd); }; struct device_queue_manager_asic_ops { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 8af0d6fe257a..2e13f5d46d25 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -421,6 +421,12 @@ struct qcm_process_device { unsigned int queue_count; unsigned int vmid; bool is_debug; + + /* This flag tells if we should reset all wavefronts on + * process termination + */ + bool reset_wavefronts; + /* * All the memory management data should be here too */ @@ -454,6 +460,8 @@ struct kfd_process_device { /* The device that owns this data. */ struct kfd_dev *dev; + /* The process that owns this kfd_process_device. */ + struct kfd_process *process; /* per-process-per device QCM data structure */ struct qcm_process_device qpd; @@ -469,10 +477,12 @@ struct kfd_process_device { /* Is this process/pasid bound to this device? (amd_iommu_bind_pasid) */ enum kfd_pdd_bound bound; - /* This flag tells if we should reset all - * wavefronts on process termination + /* Flag used to tell the pdd has dequeued from the dqm. + * This is used to prevent dev->dqm->ops.process_termination() from + * being called twice when it is already called in IOMMU callback + * function. */ - bool reset_wavefronts; + bool already_dequeued; }; #define qpd_to_pdd(x) container_of(x, struct kfd_process_device, qpd) @@ -659,6 +669,8 @@ struct process_queue_node { struct list_head process_queue_list; }; +void kfd_process_dequeue_from_device(struct kfd_process_device *pdd); +void kfd_process_dequeue_from_all_devices(struct kfd_process *p); int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p); void pqm_uninit(struct process_queue_manager *pqm); int pqm_create_queue(struct process_queue_manager *pqm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 1325f88591ae..3ccb3b53216e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -171,9 +171,6 @@ static void kfd_process_wq_release(struct work_struct *work) pr_debug("Releasing pdd (topology id %d) for process (pasid %d) in workqueue\n", pdd->dev->id, p->pasid); - if (pdd->reset_wavefronts) - dbgdev_wave_reset_wavefronts(pdd->dev, p); - if (pdd->bound == PDD_BOUND) amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); @@ -237,24 +234,17 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, mutex_lock(&p->mutex); - /* In case our notifier is called before IOMMU notifier */ + kfd_process_dequeue_from_all_devices(p); pqm_uninit(&p->pqm); /* Iterate over all process device data structure and check - * if we should delete debug managers and reset all wavefronts + * if we should delete debug managers */ - list_for_each_entry(pdd, &p->per_device_data, per_device_list) { + list_for_each_entry(pdd, &p->per_device_data, per_device_list) if ((pdd->dev->dbgmgr) && (pdd->dev->dbgmgr->pasid == p->pasid)) kfd_dbgmgr_destroy(pdd->dev->dbgmgr); - if (pdd->reset_wavefronts) { - pr_warn("Resetting all wave fronts\n"); - dbgdev_wave_reset_wavefronts(pdd->dev, p); - pdd->reset_wavefronts = false; - } - } - mutex_unlock(&p->mutex); /* @@ -368,8 +358,9 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, INIT_LIST_HEAD(&pdd->qpd.queues_list); INIT_LIST_HEAD(&pdd->qpd.priv_queue_list); pdd->qpd.dqm = dev->dqm; - pdd->reset_wavefronts = false; + pdd->process = p; pdd->bound = PDD_UNBOUND; + pdd->already_dequeued = false; list_add(&pdd->per_device_list, &p->per_device_data); } @@ -498,19 +489,12 @@ void kfd_process_iommu_unbind_callback(struct kfd_dev *dev, unsigned int pasid) if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) kfd_dbgmgr_destroy(dev->dbgmgr); - pqm_uninit(&p->pqm); - pdd = kfd_get_process_device_data(dev, p); - - if (!pdd) { - mutex_unlock(&p->mutex); - return; - } - - if (pdd->reset_wavefronts) { - dbgdev_wave_reset_wavefronts(pdd->dev, p); - pdd->reset_wavefronts = false; - } + if (pdd) + /* For GPU relying on IOMMU, we need to dequeue here + * when PASID is still bound. + */ + kfd_process_dequeue_from_device(pdd); mutex_unlock(&p->mutex); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 68fe0d99f6c2..31ec3ca9d46d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -63,6 +63,25 @@ static int find_available_queue_slot(struct process_queue_manager *pqm, return 0; } +void kfd_process_dequeue_from_device(struct kfd_process_device *pdd) +{ + struct kfd_dev *dev = pdd->dev; + + if (pdd->already_dequeued) + return; + + dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd); + pdd->already_dequeued = true; +} + +void kfd_process_dequeue_from_all_devices(struct kfd_process *p) +{ + struct kfd_process_device *pdd; + + list_for_each_entry(pdd, &p->per_device_data, per_device_list) + kfd_process_dequeue_from_device(pdd); +} + int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p) { INIT_LIST_HEAD(&pqm->queues); @@ -78,21 +97,14 @@ int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p) void pqm_uninit(struct process_queue_manager *pqm) { - int retval; struct process_queue_node *pqn, *next; list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) { - retval = pqm_destroy_queue( - pqm, - (pqn->q != NULL) ? - pqn->q->properties.queue_id : - pqn->kq->queue->properties.queue_id); - - if (retval != 0) { - pr_err("failed to destroy queue\n"); - return; - } + uninit_queue(pqn->q); + list_del(&pqn->process_queue_list); + kfree(pqn); } + kfree(pqm->queue_slot_bitmap); pqm->queue_slot_bitmap = NULL; } @@ -290,9 +302,6 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid) if (pqn->q) { dqm = pqn->q->device->dqm; retval = dqm->ops.destroy_queue(dqm, &pdd->qpd, pqn->q); - if (retval != 0) - return retval; - uninit_queue(pqn->q); } -- cgit v1.2.3 From e6f791b1b068b168c6f5203f29040b972d7fbc20 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 27 Sep 2017 00:09:53 -0400 Subject: drm/amdkfd: Compress unnecessary function parameters Signed-off-by: Yong Zhao Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 3 +-- drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c | 5 +++-- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 -- drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 10 +++------- 4 files changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 660b3fbade41..0ef82b229754 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -282,8 +282,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, p->pasid, dev->id); - err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, - 0, q_properties.type, &queue_id); + err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, &queue_id); if (err != 0) goto err_create_queue; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c index 7d5635fdd6e7..c407f6bd9956 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -184,9 +184,10 @@ static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev) struct kernel_queue *kq = NULL; int status; + properties.type = KFD_QUEUE_TYPE_DIQ; + status = pqm_create_queue(dbgdev->pqm, dbgdev->dev, NULL, - &properties, 0, KFD_QUEUE_TYPE_DIQ, - &qid); + &properties, &qid); if (status) { pr_err("Failed to create DIQ\n"); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 2e13f5d46d25..7f141730de41 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -677,8 +677,6 @@ int pqm_create_queue(struct process_queue_manager *pqm, struct kfd_dev *dev, struct file *f, struct queue_properties *properties, - unsigned int flags, - enum kfd_queue_type type, unsigned int *qid); int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid); int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 31ec3ca9d46d..63c569b62cee 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -142,20 +142,17 @@ int pqm_create_queue(struct process_queue_manager *pqm, struct kfd_dev *dev, struct file *f, struct queue_properties *properties, - unsigned int flags, - enum kfd_queue_type type, unsigned int *qid) { int retval; struct kfd_process_device *pdd; - struct queue_properties q_properties; struct queue *q; struct process_queue_node *pqn; struct kernel_queue *kq; int num_queues = 0; struct queue *cur; + enum kfd_queue_type type = properties->type; - memcpy(&q_properties, properties, sizeof(struct queue_properties)); q = NULL; kq = NULL; @@ -206,7 +203,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, goto err_create_queue; } - retval = create_cp_queue(pqm, dev, &q, &q_properties, f, *qid); + retval = create_cp_queue(pqm, dev, &q, properties, f, *qid); if (retval != 0) goto err_create_queue; pqn->q = q; @@ -243,9 +240,8 @@ int pqm_create_queue(struct process_queue_manager *pqm, list_add(&pqn->process_queue_list, &pqm->queues); if (q) { - *properties = q->properties; pr_debug("PQM done creating queue\n"); - print_queue_properties(properties); + print_queue_properties(&q->properties); } return retval; -- cgit v1.2.3 From bc920fd4f4350a2e3094c165a77798d721f39e7b Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 27 Sep 2017 00:09:54 -0400 Subject: drm/amdkfd: Clean up process queue management Removed unused num_concurrent_processes. Implemented counting of queues in QPD. This makes counting the queue list repeatedly in several places unnecessary. Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 5 +++++ drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c | 7 +------ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 - drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 9 ++------- 4 files changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index dd7e44593cfe..c0685cd64d12 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -189,6 +189,7 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, } list_add(&q->list, &qpd->queues_list); + qpd->queue_count++; if (q->properties.is_active) dqm->queue_count++; @@ -347,6 +348,7 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm, deallocate_vmid(dqm, qpd, q); } + qpd->queue_count--; if (q->properties.is_active) dqm->queue_count--; @@ -856,6 +858,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, goto out; list_add(&q->list, &qpd->queues_list); + qpd->queue_count++; if (q->properties.is_active) { dqm->queue_count++; retval = execute_queues_cpsch(dqm, @@ -1014,6 +1017,7 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, dqm->sdma_queue_count--; list_del(&q->list); + qpd->queue_count--; if (q->properties.is_active) dqm->queue_count--; @@ -1204,6 +1208,7 @@ static int process_termination_cpsch(struct device_queue_manager *dqm, goto out; } list_del(&q->list); + qpd->queue_count--; mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c index e5a15babb4f3..5d1770e577e9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c @@ -140,8 +140,6 @@ static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer, struct qcm_process_device *qpd) { struct pm4_mes_map_process *packet; - struct queue *cur; - uint32_t num_queues; packet = (struct pm4_mes_map_process *)buffer; @@ -156,10 +154,7 @@ static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer, packet->bitfields10.gds_size = qpd->gds_size; packet->bitfields10.num_gws = qpd->num_gws; packet->bitfields10.num_oac = qpd->num_oac; - num_queues = 0; - list_for_each_entry(cur, &qpd->queues_list, list) - num_queues++; - packet->bitfields10.num_queues = (qpd->is_debug) ? 0 : num_queues; + packet->bitfields10.num_queues = (qpd->is_debug) ? 0 : qpd->queue_count; packet->sh_mem_config = qpd->sh_mem_config; packet->sh_mem_bases = qpd->sh_mem_bases; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 7f141730de41..7d86ec9790d3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -405,7 +405,6 @@ struct scheduling_resources { struct process_queue_manager { /* data */ struct kfd_process *process; - unsigned int num_concurrent_processes; struct list_head queues; unsigned long *queue_slot_bitmap; }; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 63c569b62cee..88ad178bffb6 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -149,8 +149,6 @@ int pqm_create_queue(struct process_queue_manager *pqm, struct queue *q; struct process_queue_node *pqn; struct kernel_queue *kq; - int num_queues = 0; - struct queue *cur; enum kfd_queue_type type = properties->type; q = NULL; @@ -168,11 +166,8 @@ int pqm_create_queue(struct process_queue_manager *pqm, * If we are just about to create DIQ, the is_debug flag is not set yet * Hence we also check the type as well */ - if ((pdd->qpd.is_debug) || - (type == KFD_QUEUE_TYPE_DIQ)) { - list_for_each_entry(cur, &pdd->qpd.queues_list, list) - num_queues++; - if (num_queues >= dev->device_info->max_no_of_hqd/2) + if ((pdd->qpd.is_debug) || (type == KFD_QUEUE_TYPE_DIQ)) { + if (pdd->qpd.queue_count >= dev->device_info->max_no_of_hqd/2) return -ENOSPC; } -- cgit v1.2.3 From 36c2d7eb5e99a4d765b1ec241823d563c71b1125 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 27 Sep 2017 00:09:55 -0400 Subject: drm/amdkfd: Limit queue number per process and device to 127 HWS uses bit 7 in the queue number of the map process packet for an undocumented feature. Therefore the queue number per process and device must be 127 or less. Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 88ad178bffb6..5129dc139219 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -150,6 +150,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, struct process_queue_node *pqn; struct kernel_queue *kq; enum kfd_queue_type type = properties->type; + unsigned int max_queues = 127; /* HWS limit */ q = NULL; kq = NULL; @@ -166,10 +167,11 @@ int pqm_create_queue(struct process_queue_manager *pqm, * If we are just about to create DIQ, the is_debug flag is not set yet * Hence we also check the type as well */ - if ((pdd->qpd.is_debug) || (type == KFD_QUEUE_TYPE_DIQ)) { - if (pdd->qpd.queue_count >= dev->device_info->max_no_of_hqd/2) - return -ENOSPC; - } + if ((pdd->qpd.is_debug) || (type == KFD_QUEUE_TYPE_DIQ)) + max_queues = dev->device_info->max_no_of_hqd/2; + + if (pdd->qpd.queue_count >= max_queues) + return -ENOSPC; retval = find_available_queue_slot(pqm, qid); if (retval != 0) -- cgit v1.2.3 From e139cd2a2ff842bd4a5d089b9d251ca62f58ecac Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Wed, 27 Sep 2017 00:09:56 -0400 Subject: drm/amdkfd: Improve multiple SDMA queues support per process HWS does not support over-subscription and the scheduler can not internally modify the engine. Driver needs to program the correct engine ID. Fix the queue and engine selection to create queues on alternating SDMA engines. This allows concurrent bi-directional DMA transfers in a process that creates two SDMA queues. Signed-off-by: shaoyun liu Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 29 +++++++++++----------- drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index c0685cd64d12..da3b74315acf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -622,8 +622,8 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, if (retval) return retval; - q->properties.sdma_queue_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE; - q->properties.sdma_engine_id = q->sdma_id / CIK_SDMA_ENGINE_NUM; + q->properties.sdma_queue_id = q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE; + q->properties.sdma_engine_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE; pr_debug("SDMA id is: %d\n", q->sdma_id); pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id); @@ -705,6 +705,7 @@ static int initialize_cpsch(struct device_queue_manager *dqm) dqm->queue_count = dqm->processes_count = 0; dqm->sdma_queue_count = 0; dqm->active_runlist = false; + dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1; retval = dqm->ops_asic_specific.initialize(dqm); if (retval) mutex_destroy(&dqm->lock); @@ -812,14 +813,6 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, mutex_unlock(&dqm->lock); } -static void select_sdma_engine_id(struct queue *q) -{ - static int sdma_id; - - q->sdma_id = sdma_id; - sdma_id = (sdma_id + 1) % 2; -} - static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, struct qcm_process_device *qpd, int *allocate_vmid) { @@ -840,9 +833,15 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, goto out; } - if (q->properties.type == KFD_QUEUE_TYPE_SDMA) - select_sdma_engine_id(q); - + if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { + retval = allocate_sdma_queue(dqm, &q->sdma_id); + if (retval != 0) + goto out; + q->properties.sdma_queue_id = + q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE; + q->properties.sdma_engine_id = + q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE; + } mqd = dqm->ops.get_mqd_manager(dqm, get_mqd_type_from_queue_type(q->properties.type)); @@ -1013,8 +1012,10 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, goto failed; } - if (q->properties.type == KFD_QUEUE_TYPE_SDMA) + if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { dqm->sdma_queue_count--; + deallocate_sdma_queue(dqm, q->sdma_id); + } list_del(&q->list); qpd->queue_count--; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c index 5d1770e577e9..16da8ad02d8b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c @@ -203,7 +203,7 @@ static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer, queue_type__mes_map_queues__debug_interface_queue_vi; break; case KFD_QUEUE_TYPE_SDMA: - packet->bitfields2.engine_sel = + packet->bitfields2.engine_sel = q->properties.sdma_engine_id + engine_sel__mes_map_queues__sdma0_vi; use_static = false; /* no static queues under SDMA */ break; -- cgit v1.2.3 From 7e44fc289d54aa3f1f37d6c9e5157f79011c6476 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 26 Sep 2017 11:17:19 +0100 Subject: drm/i915/execlists: Notify context-out for lost requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When cancelling requests, also send the notification to any listeners (gvt) that the request is no longer scheduled on hw. They may require to keep the in/out exactly balanced, and so the reuse after the reset may confuse the listener. Fixes: 221ab9719bf3 ("drm/i915/execlists: Unwind incomplete requests on resets") Signed-off-by: Chris Wilson Cc: "Zhenyu Wang" Cc: "Wang, Zhi A" Cc: Michał Winiarski Cc: Mika Kuoppala Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20170926101720.9479-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/intel_lrc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2c07f3c08bd3..61cac26a8b05 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -578,7 +578,11 @@ execlist_cancel_port_requests(struct intel_engine_execlists *execlists) unsigned int num_ports = ARRAY_SIZE(execlists->port); while (num_ports-- && port_isset(port)) { - i915_gem_request_put(port_request(port)); + struct drm_i915_gem_request *rq = port_request(port); + + execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); + i915_gem_request_put(rq); + memset(port, 0, sizeof(*port)); port++; } -- cgit v1.2.3 From 516726d46d84096b006e2648d8700d1a04d021cc Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 6 Sep 2017 22:27:52 +0200 Subject: i915: Use %pS printk format for direct addresses Use the %pS printk format for printing symbols from direct addresses. This is important for the ia64, ppc64 and parisc64 architectures, while on other architectures there is no difference between %pS and %pF. Fix it for consistency across the kernel. Signed-off-by: Helge Deller Cc: Jani Nikula Cc: David Airlie Cc: intel-gfx@lists.freedesktop.org Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1504729681-3504-6-git-send-email-deller@gmx.de --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 4e00e5cb9fa1..29c62d481cef 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -64,7 +64,7 @@ static unsigned long wait_timeout(void) static noinline void missed_breadcrumb(struct intel_engine_cs *engine) { - DRM_DEBUG_DRIVER("%s missed breadcrumb at %pF, irq posted? %s, current seqno=%x, last=%x\n", + DRM_DEBUG_DRIVER("%s missed breadcrumb at %pS, irq posted? %s, current seqno=%x, last=%x\n", engine->name, __builtin_return_address(0), yesno(test_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted)), -- cgit v1.2.3 From 83b31c2a5fdd4fb3a4ec84c59a962e816d0bc9de Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Tue, 26 Sep 2017 15:51:28 +0200 Subject: pinctrl/amd: Fix build dependency on pinmux code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume") caused the following compilation errors: drivers/pinctrl/pinctrl-amd.c: In function ‘amd_gpio_should_save’: drivers/pinctrl/pinctrl-amd.c:741:8: error: ‘const struct pin_desc’ has no member named ‘mux_owner’ if (pd->mux_owner || pd->gpio_owner || ^ drivers/pinctrl/pinctrl-amd.c:741:25: error: ‘const struct pin_desc’ has no member named ‘gpio_owner’ if (pd->mux_owner || pd->gpio_owner || We need to enable CONFIG_PINMUX for this driver as well. Cc: stable@vger.kernel.org Fixes: 79d2c8bede2c93f943 ("pinctrl/amd: save pin registers over suspend/resume") Signed-off-by: Petr Mladek Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 1778cf4f81c7..82cd8b08d71f 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -100,6 +100,7 @@ config PINCTRL_AMD tristate "AMD GPIO pin control" depends on GPIOLIB select GPIOLIB_IRQCHIP + select PINMUX select PINCONF select GENERIC_PINCONF help -- cgit v1.2.3 From bd30ca2d1a98fb9bd1f6ba63438068788b9e396b Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 26 Sep 2017 14:13:46 -0700 Subject: drm/i915: Avoid using dev_priv->info.gen directly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's stop this usage before it spreads so much. 1. This check is not part of usual searches happening when adding new platform. 2. There is already a duplication here with INTEL_INFO(dev_priv)->gen and INTEL_GEN(dev_priv). So let's please avoid yet another way. Cc: Lyude Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Radhakrishna Sripada Cc: Hans de Goede Cc: Matt Roper Cc: Maarten Lankhorst Cc: Paulo Zanoni Cc: Ville Syrjala Cc: Imre Deak Cc: Shashank Sharma Cc: Jani Nikula Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20170926211346.12009-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8a185971798b..aa9ccc3ecff9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9310,11 +9310,11 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, pipe_config->gamma_mode = I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK; - if (IS_BROADWELL(dev_priv) || dev_priv->info.gen >= 9) { + if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) { u32 tmp = I915_READ(PIPEMISC(crtc->pipe)); bool clrspace_yuv = tmp & PIPEMISC_OUTPUT_COLORSPACE_YUV; - if (IS_GEMINILAKE(dev_priv) || dev_priv->info.gen >= 10) { + if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10) { bool blend_mode_420 = tmp & PIPEMISC_YUV420_MODE_FULL_BLEND; @@ -14280,7 +14280,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) dev_priv->display.fdi_link_train = hsw_fdi_link_train; } - if (dev_priv->info.gen >= 9) + if (INTEL_GEN(dev_priv) >= 9) dev_priv->display.update_crtcs = skl_update_crtcs; else dev_priv->display.update_crtcs = intel_update_crtcs; -- cgit v1.2.3 From a5f3d8a5eaaf917878f07998e6f1ea46024e6bab Mon Sep 17 00:00:00 2001 From: Coly Li Date: Tue, 26 Sep 2017 17:54:12 +0800 Subject: bcache: use llist_for_each_entry_safe() in __closure_wake_up() Commit 09b3efec ("bcache: Don't reinvent the wheel but use existing llist API") replaces the following while loop by llist_for_each_entry(), - - while (reverse) { - cl = container_of(reverse, struct closure, list); - reverse = llist_next(reverse); - + llist_for_each_entry(cl, reverse, list) { closure_set_waiting(cl, 0); closure_sub(cl, CLOSURE_WAITING + 1); } This modification introduces a potential race by iterating a corrupted list. Here is how it happens. In the above modification, closure_sub() may wake up a process which is waiting on reverse list. If this process decides to wait again by calling closure_wait(), its cl->list will be added to another wait list. Then when llist_for_each_entry() continues to iterate next node, it will travel on another new wait list which is added in closure_wait(), not the original reverse list in __closure_wake_up(). It is more probably to happen on UP machine because the waked up process may preempt the process which wakes up it. Use llist_for_each_entry_safe() will fix the issue, the safe version fetch next node before waking up a process. Then the copy of next node will make sure list iteration stays on original reverse list. Fixes: 09b3efec81de ("bcache: Don't reinvent the wheel but use existing llist API") Signed-off-by: Coly Li Reported-by: Michael Lyle Reviewed-by: Byungchul Park Signed-off-by: Jens Axboe --- drivers/md/bcache/closure.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/bcache/closure.c b/drivers/md/bcache/closure.c index 7d5286b05036..1841d0359bac 100644 --- a/drivers/md/bcache/closure.c +++ b/drivers/md/bcache/closure.c @@ -64,7 +64,7 @@ EXPORT_SYMBOL(closure_put); void __closure_wake_up(struct closure_waitlist *wait_list) { struct llist_node *list; - struct closure *cl; + struct closure *cl, *t; struct llist_node *reverse = NULL; list = llist_del_all(&wait_list->list); @@ -73,7 +73,7 @@ void __closure_wake_up(struct closure_waitlist *wait_list) reverse = llist_reverse_order(list); /* Then do the wakeups */ - llist_for_each_entry(cl, reverse, list) { + llist_for_each_entry_safe(cl, t, reverse, list) { closure_set_waiting(cl, 0); closure_sub(cl, CLOSURE_WAITING + 1); } -- cgit v1.2.3 From 38e8a5c040d3ec99a8351c688dcdf0f549611565 Mon Sep 17 00:00:00 2001 From: Roi Dayan Date: Mon, 21 Aug 2017 12:04:50 +0300 Subject: net/mlx5e: IPoIB, Fix access to invalid memory address When cleaning rdma netdevice we need to save the mdev pointer because priv is released when we release netdev. This bug was found using the kernel address sanitizer (KASAN). use-after-free in mlx5_rdma_netdev_free+0xe3/0x100 [mlx5_core] Fixes: 48935bbb7ae8 ("net/mlx5e: IPoIB, Add netdevice profile skeleton") Signed-off-by: Roi Dayan Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index 85298051a3e4..145e392ab849 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c @@ -572,12 +572,13 @@ void mlx5_rdma_netdev_free(struct net_device *netdev) { struct mlx5e_priv *priv = mlx5i_epriv(netdev); const struct mlx5e_profile *profile = priv->profile; + struct mlx5_core_dev *mdev = priv->mdev; mlx5e_detach_netdev(priv); profile->cleanup(priv); destroy_workqueue(priv->wq); free_netdev(netdev); - mlx5e_destroy_mdev_resources(priv->mdev); + mlx5e_destroy_mdev_resources(mdev); } EXPORT_SYMBOL(mlx5_rdma_netdev_free); -- cgit v1.2.3 From 99d3cd27f755d63fd6cf85169eaa873d90769aa5 Mon Sep 17 00:00:00 2001 From: Inbar Karmy Date: Thu, 24 Aug 2017 17:21:44 +0300 Subject: net/mlx5: Fix FPGA capability location Currently, FPGA capability is located in (mdev)->caps.hca_cur, change the location to be (mdev)->caps.fpga, since hca_cur is reserved for HCA device capabilities. Fixes: e29341fb3a5b ("net/mlx5: FPGA, Add basic support for Innova") Signed-off-by: Inbar Karmy Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.h | 2 +- drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c | 3 +-- include/linux/mlx5/device.h | 5 ++--- include/linux/mlx5/driver.h | 1 + 5 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.c index e37453d838db..c0fd2212e890 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.c @@ -71,11 +71,11 @@ int mlx5_fpga_access_reg(struct mlx5_core_dev *dev, u8 size, u64 addr, return 0; } -int mlx5_fpga_caps(struct mlx5_core_dev *dev, u32 *caps) +int mlx5_fpga_caps(struct mlx5_core_dev *dev) { u32 in[MLX5_ST_SZ_DW(fpga_cap)] = {0}; - return mlx5_core_access_reg(dev, in, sizeof(in), caps, + return mlx5_core_access_reg(dev, in, sizeof(in), dev->caps.fpga, MLX5_ST_SZ_BYTES(fpga_cap), MLX5_REG_FPGA_CAP, 0, 0); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.h b/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.h index 94bdfd47c3f0..d05233c9b4f6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/cmd.h @@ -65,7 +65,7 @@ struct mlx5_fpga_qp_counters { u64 rx_total_drop; }; -int mlx5_fpga_caps(struct mlx5_core_dev *dev, u32 *caps); +int mlx5_fpga_caps(struct mlx5_core_dev *dev); int mlx5_fpga_query(struct mlx5_core_dev *dev, struct mlx5_fpga_query *query); int mlx5_fpga_ctrl_op(struct mlx5_core_dev *dev, u8 op); int mlx5_fpga_access_reg(struct mlx5_core_dev *dev, u8 size, u64 addr, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c index 9034e9960a76..dc8970346521 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c @@ -139,8 +139,7 @@ int mlx5_fpga_device_start(struct mlx5_core_dev *mdev) if (err) goto out; - err = mlx5_fpga_caps(fdev->mdev, - fdev->mdev->caps.hca_cur[MLX5_CAP_FPGA]); + err = mlx5_fpga_caps(fdev->mdev); if (err) goto out; diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index eaf4ad209c8f..e32dbc4934db 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -980,7 +980,6 @@ enum mlx5_cap_type { MLX5_CAP_RESERVED, MLX5_CAP_VECTOR_CALC, MLX5_CAP_QOS, - MLX5_CAP_FPGA, /* NUM OF CAP Types */ MLX5_CAP_NUM }; @@ -1110,10 +1109,10 @@ enum mlx5_mcam_feature_groups { MLX5_GET(mcam_reg, (mdev)->caps.mcam, mng_feature_cap_mask.enhanced_features.fld) #define MLX5_CAP_FPGA(mdev, cap) \ - MLX5_GET(fpga_cap, (mdev)->caps.hca_cur[MLX5_CAP_FPGA], cap) + MLX5_GET(fpga_cap, (mdev)->caps.fpga, cap) #define MLX5_CAP64_FPGA(mdev, cap) \ - MLX5_GET64(fpga_cap, (mdev)->caps.hca_cur[MLX5_CAP_FPGA], cap) + MLX5_GET64(fpga_cap, (mdev)->caps.fpga, cap) enum { MLX5_CMD_STAT_OK = 0x0, diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 02ff700e4f30..401c8972cc3a 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -774,6 +774,7 @@ struct mlx5_core_dev { u32 hca_max[MLX5_CAP_NUM][MLX5_UN_SZ_DW(hca_cap_union)]; u32 pcam[MLX5_ST_SZ_DW(pcam_reg)]; u32 mcam[MLX5_ST_SZ_DW(mcam_reg)]; + u32 fpga[MLX5_ST_SZ_DW(fpga_cap)]; } caps; phys_addr_t iseg_base; struct mlx5_init_seg __iomem *iseg; -- cgit v1.2.3 From 16f1c5bb3ed75b3cf3ced537db40f7e1a244debe Mon Sep 17 00:00:00 2001 From: Raed Salem Date: Sun, 30 Jul 2017 11:02:51 +0300 Subject: net/mlx5: Check device capability for maximum flow counters Added check for the maximal number of flow counters attached to rule (FTE). Fixes: bd5251dbf156b ('net/mlx5_core: Introduce flow steering destination of type counter') Signed-off-by: Raed Salem Reviewed-by: Maor Gottlieb Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c | 8 ++++++++ drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | 11 +++++++++++ include/linux/mlx5/mlx5_ifc.h | 3 ++- 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c index e0d0efd903bc..36ecc2b2e187 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c @@ -293,6 +293,9 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, } if (fte->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { + int max_list_size = BIT(MLX5_CAP_FLOWTABLE_TYPE(dev, + log_max_flow_counter, + ft->type)); int list_size = 0; list_for_each_entry(dst, &fte->node.children, node.list) { @@ -305,12 +308,17 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, in_dests += MLX5_ST_SZ_BYTES(dest_format_struct); list_size++; } + if (list_size > max_list_size) { + err = -EINVAL; + goto err_out; + } MLX5_SET(flow_context, in_flow_context, flow_counter_list_size, list_size); } err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); +err_out: kvfree(in); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h index 5509a752f98e..48dd78975062 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h @@ -52,6 +52,7 @@ enum fs_flow_table_type { FS_FT_FDB = 0X4, FS_FT_SNIFFER_RX = 0X5, FS_FT_SNIFFER_TX = 0X6, + FS_FT_MAX_TYPE = FS_FT_SNIFFER_TX, }; enum fs_flow_table_op_mod { @@ -260,4 +261,14 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev); #define fs_for_each_dst(pos, fte) \ fs_list_for_each_entry(pos, &(fte)->node.children) +#define MLX5_CAP_FLOWTABLE_TYPE(mdev, cap, type) ( \ + (type == FS_FT_NIC_RX) ? MLX5_CAP_FLOWTABLE_NIC_RX(mdev, cap) : \ + (type == FS_FT_ESW_EGRESS_ACL) ? MLX5_CAP_ESW_EGRESS_ACL(mdev, cap) : \ + (type == FS_FT_ESW_INGRESS_ACL) ? MLX5_CAP_ESW_INGRESS_ACL(mdev, cap) : \ + (type == FS_FT_FDB) ? MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, cap) : \ + (type == FS_FT_SNIFFER_RX) ? MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) : \ + (type == FS_FT_SNIFFER_TX) ? MLX5_CAP_FLOWTABLE_SNIFFER_TX(mdev, cap) : \ + (BUILD_BUG_ON_ZERO(FS_FT_SNIFFER_TX != FS_FT_MAX_TYPE))\ + ) + #endif diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index a528b35a022e..69772347f866 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -327,7 +327,8 @@ struct mlx5_ifc_flow_table_prop_layout_bits { u8 reserved_at_80[0x18]; u8 log_max_destination[0x8]; - u8 reserved_at_a0[0x18]; + u8 log_max_flow_counter[0x8]; + u8 reserved_at_a8[0x10]; u8 log_max_flow[0x8]; u8 reserved_at_c0[0x40]; -- cgit v1.2.3 From ace743214ea205c7d433562c5fa24e33bdfda7ab Mon Sep 17 00:00:00 2001 From: Paul Blakey Date: Tue, 5 Sep 2017 15:05:51 +0300 Subject: net/mlx5e: Fix erroneous freeing of encap header buffer In case the neighbour for the tunnel destination isn't valid, we send a neighbour update request but we free the encap header buffer. This is wrong, because we still need it for allocating a HW encap entry once the neighbour is available. Fix that by skipping freeing it if we wait for neighbour. Fixes: 232c001398ae ('net/mlx5e: Add support to neighbour update flow') Signed-off-by: Paul Blakey Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index da503e6411da..4e2fc016bdd6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1564,7 +1564,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, break; default: err = -EOPNOTSUPP; - goto out; + goto free_encap; } fl4.flowi4_tos = tun_key->tos; fl4.daddr = tun_key->u.ipv4.dst; @@ -1573,7 +1573,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, err = mlx5e_route_lookup_ipv4(priv, mirred_dev, &out_dev, &fl4, &n, &ttl); if (err) - goto out; + goto free_encap; /* used by mlx5e_detach_encap to lookup a neigh hash table * entry in the neigh hash table when a user deletes a rule @@ -1590,7 +1590,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, */ err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); if (err) - goto out; + goto free_encap; read_lock_bh(&n->lock); nud_state = n->nud_state; @@ -1630,8 +1630,9 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, destroy_neigh_entry: mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); -out: +free_encap: kfree(encap_header); +out: if (n) neigh_release(n); return err; @@ -1668,7 +1669,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, break; default: err = -EOPNOTSUPP; - goto out; + goto free_encap; } fl6.flowlabel = ip6_make_flowinfo(RT_TOS(tun_key->tos), tun_key->label); @@ -1678,7 +1679,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, err = mlx5e_route_lookup_ipv6(priv, mirred_dev, &out_dev, &fl6, &n, &ttl); if (err) - goto out; + goto free_encap; /* used by mlx5e_detach_encap to lookup a neigh hash table * entry in the neigh hash table when a user deletes a rule @@ -1695,7 +1696,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, */ err = mlx5e_rep_encap_entry_attach(netdev_priv(out_dev), e); if (err) - goto out; + goto free_encap; read_lock_bh(&n->lock); nud_state = n->nud_state; @@ -1736,8 +1737,9 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv, destroy_neigh_entry: mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e); -out: +free_encap: kfree(encap_header); +out: if (n) neigh_release(n); return err; -- cgit v1.2.3 From bdd66ac0aeed971d1cb42b3aa0d11b0ea3842e09 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Sun, 11 Jun 2017 21:13:25 +0300 Subject: net/mlx5e: Disallow TC offloading of unsupported match/action combinations When offloading header re-write, the HW may need to adjust checksums along the packet. For IP traffic, and a case where we are asked to modify fields in the IP header, current HW supports that only for TCP and UDP. Enforce it, in this case fail the offloading attempt for non TCP/UDP packets. Fixes: d7e75a325cb2 ('net/mlx5e: Add offloading of E-Switch TC pedit (header re-write) actions') Fixes: 2f4fe4cab073 ('net/mlx5e: Add offloading of NIC TC pedit (header re-write) actions') Signed-off-by: Or Gerlitz Reviewed-by: Paul Blakey Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 4e2fc016bdd6..d3786005fba7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1317,6 +1317,69 @@ static bool csum_offload_supported(struct mlx5e_priv *priv, u32 action, u32 upda return true; } +static bool modify_header_match_supported(struct mlx5_flow_spec *spec, + struct tcf_exts *exts) +{ + const struct tc_action *a; + bool modify_ip_header; + LIST_HEAD(actions); + u8 htype, ip_proto; + void *headers_v; + u16 ethertype; + int nkeys, i; + + headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers); + ethertype = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ethertype); + + /* for non-IP we only re-write MACs, so we're okay */ + if (ethertype != ETH_P_IP && ethertype != ETH_P_IPV6) + goto out_ok; + + modify_ip_header = false; + tcf_exts_to_list(exts, &actions); + list_for_each_entry(a, &actions, list) { + if (!is_tcf_pedit(a)) + continue; + + nkeys = tcf_pedit_nkeys(a); + for (i = 0; i < nkeys; i++) { + htype = tcf_pedit_htype(a, i); + if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 || + htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP6) { + modify_ip_header = true; + break; + } + } + } + + ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); + if (modify_ip_header && ip_proto != IPPROTO_TCP && ip_proto != IPPROTO_UDP) { + pr_info("can't offload re-write of ip proto %d\n", ip_proto); + return false; + } + +out_ok: + return true; +} + +static bool actions_match_supported(struct mlx5e_priv *priv, + struct tcf_exts *exts, + struct mlx5e_tc_flow_parse_attr *parse_attr, + struct mlx5e_tc_flow *flow) +{ + u32 actions; + + if (flow->flags & MLX5E_TC_FLOW_ESWITCH) + actions = flow->esw_attr->action; + else + actions = flow->nic_attr->action; + + if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) + return modify_header_match_supported(&parse_attr->spec, exts); + + return true; +} + static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, struct mlx5e_tc_flow_parse_attr *parse_attr, struct mlx5e_tc_flow *flow) @@ -1378,6 +1441,9 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, return -EINVAL; } + if (!actions_match_supported(priv, exts, parse_attr, flow)) + return -EOPNOTSUPP; + return 0; } @@ -1936,6 +2002,10 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, return -EINVAL; } + + if (!actions_match_supported(priv, exts, parse_attr, flow)) + return -EOPNOTSUPP; + return err; } -- cgit v1.2.3 From b281208911a549e391d92ee6cb680dcd3d71783b Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Tue, 8 Aug 2017 11:45:28 +0300 Subject: net/mlx5e: Check encap entry state when offloading tunneled flows Encap entries cached by the driver could be invalidated due to tunnel destination neighbour state changes. When attempting to offload a flow that uses a cached encap entry, we must check the entry validity and defer the offloading if the entry exists but not valid. When EAGAIN is returned, the flow offloading to hardware takes place by the neigh update code when the tunnel destination neighbour becomes connected. Fixes: 232c001398ae ("net/mlx5e: Add support to neighbour update flow") Signed-off-by: Vlad Buslov Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index d3786005fba7..1aa2028ed995 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1859,6 +1859,7 @@ vxlan_encap_offload_err: } } + /* must verify if encap is valid or not */ if (found) goto attach_flow; @@ -1885,6 +1886,8 @@ attach_flow: *encap_dev = e->out_dev; if (e->flags & MLX5_ENCAP_ENTRY_VALID) attr->encap_id = e->encap_id; + else + err = -EAGAIN; return err; -- cgit v1.2.3 From b20eab15a1d5091e45022401e75b49948e8be33f Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Tue, 12 Sep 2017 17:51:12 +0300 Subject: net/mlx5e: Print netdev features correctly in error message Use the correct formatting for netdev features. Fixes: 0e405443e803 ("net/mlx5e: Improve set features ndo resiliency") Signed-off-by: Gal Pressman Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index dfc29720ab77..84b013dc62e9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3333,8 +3333,8 @@ static int mlx5e_handle_feature(struct net_device *netdev, err = feature_handler(netdev, enable); if (err) { - netdev_err(netdev, "%s feature 0x%llx failed err %d\n", - enable ? "Enable" : "Disable", feature, err); + netdev_err(netdev, "%s feature %pNF failed, err %d\n", + enable ? "Enable" : "Disable", &feature, err); return err; } -- cgit v1.2.3 From 1456f69ff5fbba48ed5bc86e858e945e693ba0b7 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Sun, 10 Sep 2017 10:36:06 +0300 Subject: net/mlx5e: Don't add/remove 802.1ad rules when changing 802.1Q VLAN filter Toggling of C-tag VLAN filter should not affect the "any S-tag" steering rule. Fixes: 8a271746a264 ("net/mlx5e: Receive s-tagged packets in promiscuous mode") Signed-off-by: Gal Pressman Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c index f11fd07ac4dd..850cdc980ab5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c @@ -291,7 +291,7 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv) priv->fs.vlan.filter_disabled = false; if (priv->netdev->flags & IFF_PROMISC) return; - mlx5e_del_any_vid_rules(priv); + mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); } void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv) @@ -302,7 +302,7 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv) priv->fs.vlan.filter_disabled = true; if (priv->netdev->flags & IFF_PROMISC) return; - mlx5e_add_any_vid_rules(priv); + mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); } int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto, -- cgit v1.2.3 From 603e1f5bd3ca76f16688e10040545594d2e91ba4 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Wed, 13 Sep 2017 15:37:50 +0300 Subject: net/mlx5e: Fix calculated checksum offloads counters Instead of calculating the offloads counters, count them explicitly. The calculations done for these counters would result in bugs in some cases, for example: When running TCP traffic over a VXLAN tunnel with TSO enabled the following counters would increase: tx_csum_partial: 1,333,284 tx_csum_partial_inner: 29,286 tx4_csum_partial_inner: 384 tx7_csum_partial_inner: 8 tx9_csum_partial_inner: 34 tx10_csum_partial_inner: 26,807 tx11_csum_partial_inner: 287 tx12_csum_partial_inner: 27 tx16_csum_partial_inner: 6 tx25_csum_partial_inner: 1,733 Seems like tx_csum_partial increased out of nowhere. The issue is in the following calculation in mlx5e_update_sw_counters: s->tx_csum_partial = s->tx_packets - tx_offload_none - s->tx_csum_partial_inner; While tx_packets increases by the number of GSO segments for each SKB, tx_csum_partial_inner will only increase by one, resulting in wrong tx_csum_partial counter. Fixes: bfe6d8d1d433 ("net/mlx5e: Reorganize ethtool statistics") Signed-off-by: Gal Pressman Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 9 +++------ drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 3 +++ drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | 6 ++++++ drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 1 + 4 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 84b013dc62e9..cc11bbbd0309 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -184,7 +184,6 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv) struct mlx5e_sw_stats temp, *s = &temp; struct mlx5e_rq_stats *rq_stats; struct mlx5e_sq_stats *sq_stats; - u64 tx_offload_none = 0; int i, j; memset(s, 0, sizeof(*s)); @@ -199,6 +198,7 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv) s->rx_lro_bytes += rq_stats->lro_bytes; s->rx_csum_none += rq_stats->csum_none; s->rx_csum_complete += rq_stats->csum_complete; + s->rx_csum_unnecessary += rq_stats->csum_unnecessary; s->rx_csum_unnecessary_inner += rq_stats->csum_unnecessary_inner; s->rx_xdp_drop += rq_stats->xdp_drop; s->rx_xdp_tx += rq_stats->xdp_tx; @@ -229,14 +229,11 @@ static void mlx5e_update_sw_counters(struct mlx5e_priv *priv) s->tx_queue_dropped += sq_stats->dropped; s->tx_xmit_more += sq_stats->xmit_more; s->tx_csum_partial_inner += sq_stats->csum_partial_inner; - tx_offload_none += sq_stats->csum_none; + s->tx_csum_none += sq_stats->csum_none; + s->tx_csum_partial += sq_stats->csum_partial; } } - /* Update calculated offload counters */ - s->tx_csum_partial = s->tx_packets - tx_offload_none - s->tx_csum_partial_inner; - s->rx_csum_unnecessary = s->rx_packets - s->rx_csum_none - s->rx_csum_complete; - s->link_down_events_phy = MLX5_GET(ppcnt_reg, priv->stats.pport.phy_counters, counter_set.phys_layer_cntrs.link_down_events); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index f1dd638384d3..15a1687483cc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -627,6 +627,7 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, if (lro) { skb->ip_summed = CHECKSUM_UNNECESSARY; + rq->stats.csum_unnecessary++; return; } @@ -644,7 +645,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, skb->csum_level = 1; skb->encapsulation = 1; rq->stats.csum_unnecessary_inner++; + return; } + rq->stats.csum_unnecessary++; return; } csum_none: diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h index 6d199ffb1c0b..f8637213afc0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h @@ -68,6 +68,7 @@ struct mlx5e_sw_stats { u64 rx_xdp_drop; u64 rx_xdp_tx; u64 rx_xdp_tx_full; + u64 tx_csum_none; u64 tx_csum_partial; u64 tx_csum_partial_inner; u64 tx_queue_stopped; @@ -108,6 +109,7 @@ static const struct counter_desc sw_stats_desc[] = { { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_drop) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_full) }, + { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_none) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial_inner) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_stopped) }, @@ -339,6 +341,7 @@ struct mlx5e_rq_stats { u64 packets; u64 bytes; u64 csum_complete; + u64 csum_unnecessary; u64 csum_unnecessary_inner; u64 csum_none; u64 lro_packets; @@ -363,6 +366,7 @@ static const struct counter_desc rq_stats_desc[] = { { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, packets) }, { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, bytes) }, { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete) }, + { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary) }, { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary_inner) }, { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_none) }, { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, xdp_drop) }, @@ -392,6 +396,7 @@ struct mlx5e_sq_stats { u64 tso_bytes; u64 tso_inner_packets; u64 tso_inner_bytes; + u64 csum_partial; u64 csum_partial_inner; u64 nop; /* less likely accessed in data path */ @@ -408,6 +413,7 @@ static const struct counter_desc sq_stats_desc[] = { { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_bytes) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_packets) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_bytes) }, + { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, nop) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_none) }, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index fee43e40fa16..1d6925d4369a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -193,6 +193,7 @@ mlx5e_txwqe_build_eseg_csum(struct mlx5e_txqsq *sq, struct sk_buff *skb, struct sq->stats.csum_partial_inner++; } else { eseg->cs_flags |= MLX5_ETH_WQE_L4_CSUM; + sq->stats.csum_partial++; } } else sq->stats.csum_none++; -- cgit v1.2.3 From 480df991b869eff02a004e8fe7707900437cfcd4 Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 31 Aug 2017 18:52:14 +0300 Subject: net/mlx5: Fix static checker warning on steering tracepoints code Fix this sparse complaint: drivers/net/ethernet/mellanox/mlx5/core/./diag/fs_tracepoint.h:172:1: warning: odd constant _Bool cast (ffffffffffffffff becomes 1) Fixes: d9fea79171ee ('net/mlx5: Add tracepoints') Signed-off-by: Matan Barak Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h index 1e3a6c3e4132..80eef4163f52 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h @@ -139,7 +139,7 @@ TRACE_EVENT(mlx5_fs_del_fg, {MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO, "NEXT_PRIO"} TRACE_EVENT(mlx5_fs_set_fte, - TP_PROTO(const struct fs_fte *fte, bool new_fte), + TP_PROTO(const struct fs_fte *fte, int new_fte), TP_ARGS(fte, new_fte), TP_STRUCT__entry( __field(const struct fs_fte *, fte) @@ -149,7 +149,7 @@ TRACE_EVENT(mlx5_fs_set_fte, __field(u32, action) __field(u32, flow_tag) __field(u8, mask_enable) - __field(bool, new_fte) + __field(int, new_fte) __array(u32, mask_outer, MLX5_ST_SZ_DW(fte_match_set_lyr_2_4)) __array(u32, mask_inner, MLX5_ST_SZ_DW(fte_match_set_lyr_2_4)) __array(u32, mask_misc, MLX5_ST_SZ_DW(fte_match_set_misc)) -- cgit v1.2.3 From 353f59f4d41e9c5798a15c5c52958f25b579a3d5 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Sun, 24 Sep 2017 09:54:00 +0200 Subject: net/mlx5: Fix wrong indentation in enable SRIOV code Smatch is screaming: drivers/net/ethernet/mellanox/mlx5/core/sriov.c:112 mlx5_device_enable_sriov() warn: inconsistent indenting fix that. Fixes: 7ecf6d8ff154 ('IB/mlx5: Restore IB guid/policy for virtual functions') Signed-off-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/sriov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c index 6c48e9959b65..2a8b529ce6dd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c @@ -109,7 +109,7 @@ static int mlx5_device_enable_sriov(struct mlx5_core_dev *dev, int num_vfs) mlx5_core_warn(dev, "failed to restore VF %d settings, err %d\n", vf, err); - continue; + continue; } } mlx5_core_dbg(dev, "successfully enabled VF* %d\n", vf); -- cgit v1.2.3 From d9ec46416de5ef83220f1c7010ee0f5d1be1d753 Mon Sep 17 00:00:00 2001 From: Sylvain Lesne Date: Mon, 18 Sep 2017 13:08:00 +0200 Subject: dmaengine: altera: fix response FIFO emptying Commit 6084fc2ec478 ("dmaengine: altera: Use macros instead of structs to describe the registers") introduced a minus sign before a register offset. This leads to soft-locks of the DMA controller, since reading the last status byte is required to pop the response from the FIFO. Failing to do so will lead to a full FIFO, which means that the DMA controller will stop processing descriptors. Signed-off-by: Sylvain Lesne Reviewed-by: Stefan Roese Signed-off-by: Vinod Koul --- drivers/dma/altera-msgdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c index 32905d5606ac..35cbf2365f68 100644 --- a/drivers/dma/altera-msgdma.c +++ b/drivers/dma/altera-msgdma.c @@ -698,7 +698,7 @@ static void msgdma_tasklet(unsigned long data) * bits. So we need to just drop these values. */ size = ioread32(mdev->resp + MSGDMA_RESP_BYTES_TRANSFERRED); - status = ioread32(mdev->resp - MSGDMA_RESP_STATUS); + status = ioread32(mdev->resp + MSGDMA_RESP_STATUS); msgdma_complete_descriptor(mdev); msgdma_chan_desc_cleanup(mdev); -- cgit v1.2.3 From edf10919e5fc8dfd10e57ed72f651204559bc6ba Mon Sep 17 00:00:00 2001 From: Sylvain Lesne Date: Mon, 18 Sep 2017 13:08:01 +0200 Subject: dmaengine: altera: fix spinlock usage Since this lock is acquired in both process and IRQ context, failing to to disable IRQs when trying to acquire the lock in process context can lead to deadlocks. Signed-off-by: Sylvain Lesne Reviewed-by: Stefan Roese Signed-off-by: Vinod Koul --- drivers/dma/altera-msgdma.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c index 35cbf2365f68..339186f25a2a 100644 --- a/drivers/dma/altera-msgdma.c +++ b/drivers/dma/altera-msgdma.c @@ -212,11 +212,12 @@ struct msgdma_device { static struct msgdma_sw_desc *msgdma_get_descriptor(struct msgdma_device *mdev) { struct msgdma_sw_desc *desc; + unsigned long flags; - spin_lock_bh(&mdev->lock); + spin_lock_irqsave(&mdev->lock, flags); desc = list_first_entry(&mdev->free_list, struct msgdma_sw_desc, node); list_del(&desc->node); - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, flags); INIT_LIST_HEAD(&desc->tx_list); @@ -306,13 +307,14 @@ static dma_cookie_t msgdma_tx_submit(struct dma_async_tx_descriptor *tx) struct msgdma_device *mdev = to_mdev(tx->chan); struct msgdma_sw_desc *new; dma_cookie_t cookie; + unsigned long flags; new = tx_to_desc(tx); - spin_lock_bh(&mdev->lock); + spin_lock_irqsave(&mdev->lock, flags); cookie = dma_cookie_assign(tx); list_add_tail(&new->node, &mdev->pending_list); - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, flags); return cookie; } @@ -336,17 +338,18 @@ msgdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst, struct msgdma_extended_desc *desc; size_t copy; u32 desc_cnt; + unsigned long irqflags; desc_cnt = DIV_ROUND_UP(len, MSGDMA_MAX_TRANS_LEN); - spin_lock_bh(&mdev->lock); + spin_lock_irqsave(&mdev->lock, irqflags); if (desc_cnt > mdev->desc_free_cnt) { spin_unlock_bh(&mdev->lock); dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev); return NULL; } mdev->desc_free_cnt -= desc_cnt; - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, irqflags); do { /* Allocate and populate the descriptor */ @@ -397,18 +400,19 @@ msgdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, u32 desc_cnt = 0, i; struct scatterlist *sg; u32 stride; + unsigned long irqflags; for_each_sg(sgl, sg, sg_len, i) desc_cnt += DIV_ROUND_UP(sg_dma_len(sg), MSGDMA_MAX_TRANS_LEN); - spin_lock_bh(&mdev->lock); + spin_lock_irqsave(&mdev->lock, irqflags); if (desc_cnt > mdev->desc_free_cnt) { spin_unlock_bh(&mdev->lock); dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev); return NULL; } mdev->desc_free_cnt -= desc_cnt; - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, irqflags); avail = sg_dma_len(sgl); @@ -566,10 +570,11 @@ static void msgdma_start_transfer(struct msgdma_device *mdev) static void msgdma_issue_pending(struct dma_chan *chan) { struct msgdma_device *mdev = to_mdev(chan); + unsigned long flags; - spin_lock_bh(&mdev->lock); + spin_lock_irqsave(&mdev->lock, flags); msgdma_start_transfer(mdev); - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, flags); } /** @@ -634,10 +639,11 @@ static void msgdma_free_descriptors(struct msgdma_device *mdev) static void msgdma_free_chan_resources(struct dma_chan *dchan) { struct msgdma_device *mdev = to_mdev(dchan); + unsigned long flags; - spin_lock_bh(&mdev->lock); + spin_lock_irqsave(&mdev->lock, flags); msgdma_free_descriptors(mdev); - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, flags); kfree(mdev->sw_desq); } @@ -682,8 +688,9 @@ static void msgdma_tasklet(unsigned long data) u32 count; u32 __maybe_unused size; u32 __maybe_unused status; + unsigned long flags; - spin_lock(&mdev->lock); + spin_lock_irqsave(&mdev->lock, flags); /* Read number of responses that are available */ count = ioread32(mdev->csr + MSGDMA_CSR_RESP_FILL_LEVEL); @@ -704,7 +711,7 @@ static void msgdma_tasklet(unsigned long data) msgdma_chan_desc_cleanup(mdev); } - spin_unlock(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, flags); } /** -- cgit v1.2.3 From fe659bcc9b173bcfdd958ce2aec75e47651e74e1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 26 Sep 2017 15:15:22 -0400 Subject: USB: dummy-hcd: fix connection failures (wrong speed) The dummy-hcd UDC driver is not careful about the way it handles connection speeds. It ignores the module parameter that is supposed to govern the maximum connection speed and it doesn't set the HCD flags properly for the case where it ends up running at full speed. The result is that in many cases, gadget enumeration over dummy-hcd fails because the bMaxPacketSize byte in the device descriptor is set incorrectly. For example, the default settings call for a high-speed connection, but the maxpacket value for ep0 ends up being set for a Super-Speed connection. This patch fixes the problem by initializing the gadget's max_speed and the HCD flags correctly. Signed-off-by: Alan Stern CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index b1e21b3be6e1..d515ec31afe4 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -1036,7 +1036,12 @@ static int dummy_udc_probe(struct platform_device *pdev) memzero_explicit(&dum->gadget, sizeof(struct usb_gadget)); dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.max_speed = USB_SPEED_SUPER; + if (mod_data.is_super_speed) + dum->gadget.max_speed = USB_SPEED_SUPER; + else if (mod_data.is_high_speed) + dum->gadget.max_speed = USB_SPEED_HIGH; + else + dum->gadget.max_speed = USB_SPEED_FULL; dum->gadget.dev.parent = &pdev->dev; init_dummy_udc_hw(dum); @@ -2560,8 +2565,6 @@ static struct hc_driver dummy_hcd = { .product_desc = "Dummy host controller", .hcd_priv_size = sizeof(struct dummy_hcd), - .flags = HCD_USB3 | HCD_SHARED, - .reset = dummy_setup, .start = dummy_start, .stop = dummy_stop, @@ -2590,8 +2593,12 @@ static int dummy_hcd_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); dum = *((void **)dev_get_platdata(&pdev->dev)); - if (!mod_data.is_super_speed) + if (mod_data.is_super_speed) + dummy_hcd.flags = HCD_USB3 | HCD_SHARED; + else if (mod_data.is_high_speed) dummy_hcd.flags = HCD_USB2; + else + dummy_hcd.flags = HCD_USB11; hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); if (!hs_hcd) return -ENOMEM; -- cgit v1.2.3 From 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 26 Sep 2017 15:15:40 -0400 Subject: USB: dummy-hcd: fix infinite-loop resubmission bug The dummy-hcd HCD/UDC emulator tries not to do too much work during each timer interrupt. But it doesn't try very hard; currently all it does is limit the total amount of bulk data transferred. Other transfer types aren't limited, and URBs that transfer no data (because of an error, perhaps) don't count toward the limit, even though on a real USB bus they would consume at least a minimum overhead. This means it's possible to get the driver stuck in an infinite loop, for example, if the host class driver resubmits an URB every time it completes (which is common for interrupt URBs). Each time the URB is resubmitted it gets added to the end of the pending-URBs list, and dummy-hcd doesn't stop until that list is empty. Andrey Konovalov was able to trigger this failure mode using the syzkaller fuzzer. This patch fixes the infinite-loop problem by restricting the URBs handled during each timer interrupt to those that were already on the pending list when the interrupt routine started. Newly added URBs won't be processed until the next timer interrupt. The problem of properly accounting for non-bulk bandwidth (as well as packet and transaction overhead) is not addressed here. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index d515ec31afe4..b2ab9cc33fec 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -237,6 +237,8 @@ struct dummy_hcd { struct usb_device *udev; struct list_head urbp_list; + struct urbp *next_frame_urbp; + u32 stream_en_ep; u8 num_stream[30 / 2]; @@ -1250,6 +1252,8 @@ static int dummy_urb_enqueue( list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); urb->hcpriv = urbp; + if (!dum_hcd->next_frame_urbp) + dum_hcd->next_frame_urbp = urbp; if (usb_pipetype(urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ @@ -1766,6 +1770,7 @@ static void dummy_timer(unsigned long _dum_hcd) spin_unlock_irqrestore(&dum->lock, flags); return; } + dum_hcd->next_frame_urbp = NULL; for (i = 0; i < DUMMY_ENDPOINTS; i++) { if (!ep_info[i].name) @@ -1782,6 +1787,10 @@ restart: int type; int status = -EINPROGRESS; + /* stop when we reach URBs queued after the timer interrupt */ + if (urbp == dum_hcd->next_frame_urbp) + break; + urb = urbp->urb; if (urb->unlinked) goto return_urb; -- cgit v1.2.3 From 7dbd8f4cabd96db5a50513de9d83a8105a5ffc81 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 26 Sep 2017 15:15:49 -0400 Subject: USB: dummy-hcd: Fix erroneous synchronization change A recent change to the synchronization in dummy-hcd was incorrect. The issue was that dummy_udc_stop() contained no locking and therefore could race with various gadget driver callbacks, and the fix was to add locking and issue the callbacks with the private spinlock held. UDC drivers aren't supposed to do this. Gadget driver callback routines are allowed to invoke functions in the UDC driver, and these functions will generally try to acquire the private spinlock. This would deadlock the driver. The correct solution is to drop the spinlock before issuing callbacks, and avoid races by emulating the synchronize_irq() call that all real UDC drivers must perform in their ->udc_stop() routines after disabling interrupts. This involves adding a flag to dummy-hcd's private structure to keep track of whether interrupts are supposed to be enabled, and adding a counter to keep track of ongoing callbacks so that dummy_udc_stop() can wait for them all to finish. A real UDC driver won't receive disconnect, reset, suspend, resume, or setup events once it has disabled interrupts. dummy-hcd will receive them but won't try to issue any gadget driver callbacks, which should be just as good. Signed-off-by: Alan Stern Fixes: f16443a034c7 ("USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks") CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index b2ab9cc33fec..b17618a55f1b 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -255,11 +255,13 @@ struct dummy { */ struct dummy_ep ep[DUMMY_ENDPOINTS]; int address; + int callback_usage; struct usb_gadget gadget; struct usb_gadget_driver *driver; struct dummy_request fifo_req; u8 fifo_buf[FIFO_SIZE]; u16 devstatus; + unsigned ints_enabled:1; unsigned udc_suspended:1; unsigned pullup:1; @@ -441,18 +443,27 @@ static void set_link_state(struct dummy_hcd *dum_hcd) (~dum_hcd->old_status) & dum_hcd->port_status; /* Report reset and disconnect events to the driver */ - if (dum->driver && (disconnect || reset)) { + if (dum->ints_enabled && (disconnect || reset)) { stop_activity(dum); + ++dum->callback_usage; + spin_unlock(&dum->lock); if (reset) usb_gadget_udc_reset(&dum->gadget, dum->driver); else dum->driver->disconnect(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } - } else if (dum_hcd->active != dum_hcd->old_active) { + } else if (dum_hcd->active != dum_hcd->old_active && + dum->ints_enabled) { + ++dum->callback_usage; + spin_unlock(&dum->lock); if (dum_hcd->old_active && dum->driver->suspend) dum->driver->suspend(&dum->gadget); else if (!dum_hcd->old_active && dum->driver->resume) dum->driver->resume(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } dum_hcd->old_status = dum_hcd->port_status; @@ -973,8 +984,11 @@ static int dummy_udc_start(struct usb_gadget *g, * can't enumerate without help from the driver we're binding. */ + spin_lock_irq(&dum->lock); dum->devstatus = 0; dum->driver = driver; + dum->ints_enabled = 1; + spin_unlock_irq(&dum->lock); return 0; } @@ -985,6 +999,16 @@ static int dummy_udc_stop(struct usb_gadget *g) struct dummy *dum = dum_hcd->dum; spin_lock_irq(&dum->lock); + dum->ints_enabled = 0; + stop_activity(dum); + + /* emulate synchronize_irq(): wait for callbacks to finish */ + while (dum->callback_usage > 0) { + spin_unlock_irq(&dum->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dum->lock); + } + dum->driver = NULL; spin_unlock_irq(&dum->lock); @@ -1529,6 +1553,8 @@ static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address) if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ? dum->ss_hcd : dum->hs_hcd))) return NULL; + if (!dum->ints_enabled) + return NULL; if ((address & ~USB_DIR_IN) == 0) return &dum->ep[0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { @@ -1870,10 +1896,12 @@ restart: * until setup() returns; no reentrancy issues etc. */ if (value > 0) { + ++dum->callback_usage; spin_unlock(&dum->lock); value = dum->driver->setup(&dum->gadget, &setup); spin_lock(&dum->lock); + --dum->callback_usage; if (value >= 0) { /* no delays (max 64KB data stage) */ -- cgit v1.2.3 From 4dcf4bab4a409e81284b8202137e4a85b96b34de Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 25 Sep 2017 17:01:23 +0900 Subject: usb: gadget: udc: renesas_usb3: fix for no-data control transfer When bRequestType & USB_DIR_IN is false and req.length is 0 in control transfer, since it means non-data, this driver should not set the mode as control write. So, this patch fixes it. Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") Cc: # v4.5+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/renesas_usb3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index df37c1e6e9d5..555c105e82df 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -1150,7 +1150,8 @@ static void usb3_start_pipe0(struct renesas_usb3_ep *usb3_ep, usb3_set_p0_con_for_ctrl_read_data(usb3); } else { usb3_clear_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); - usb3_set_p0_con_for_ctrl_write_data(usb3); + if (usb3_req->req.length) + usb3_set_p0_con_for_ctrl_write_data(usb3); } usb3_p0_xfer(usb3_ep, usb3_req); -- cgit v1.2.3 From 73f2f5745f18b4ccfe9484deac4e84a1378d19fd Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 25 Sep 2017 17:01:24 +0900 Subject: usb: gadget: udc: renesas_usb3: fix Pn_RAMMAP.Pn_MPKT value According to the datasheet of R-Car Gen3, the Pn_RAMMAP.Pn_MPKT should be set to one of 8, 16, 32, 64, 512 and 1024. Otherwise, when a gadget driver uses an interrupt endpoint, unexpected behavior happens. So, this patch fixes it. Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") Cc: # v4.5+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/renesas_usb3.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 555c105e82df..7e0c53492356 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2054,7 +2054,16 @@ static u32 usb3_calc_ramarea(int ram_size) static u32 usb3_calc_rammap_val(struct renesas_usb3_ep *usb3_ep, const struct usb_endpoint_descriptor *desc) { - return usb3_ep->rammap_val | PN_RAMMAP_MPKT(usb_endpoint_maxp(desc)); + int i; + const u32 max_packet_array[] = {8, 16, 32, 64, 512}; + u32 mpkt = PN_RAMMAP_MPKT(1024); + + for (i = 0; i < ARRAY_SIZE(max_packet_array); i++) { + if (usb_endpoint_maxp(desc) <= max_packet_array[i]) + mpkt = PN_RAMMAP_MPKT(max_packet_array[i]); + } + + return usb3_ep->rammap_val | mpkt; } static int usb3_enable_pipe_n(struct renesas_usb3_ep *usb3_ep, -- cgit v1.2.3 From 447b8a01b84f048d93d43bfe1fcaa4fcc56595cc Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 25 Sep 2017 17:01:25 +0900 Subject: usb: gadget: udc: renesas_usb3: Fix return value of usb3_write_pipe() This patch fixes an issue that this driver cannot go status stage in control read when the req.zero is set to 1 and the len in usb3_write_pipe() is set to 0. Otherwise, if we use g_ncm driver, usb enumeration takes long time (5 seconds or more). Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") Cc: # v4.5+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/renesas_usb3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 7e0c53492356..63a206122058 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -1038,7 +1038,7 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_ep->ep.maxpacket); u8 *buf = usb3_req->req.buf + usb3_req->req.actual; u32 tmp = 0; - bool is_last; + bool is_last = !len ? true : false; if (usb3_wait_pipe_status(usb3_ep, PX_STA_BUFSTS) < 0) return -EBUSY; @@ -1059,7 +1059,8 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_write(usb3, tmp, fifo_reg); } - is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); + if (!is_last) + is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); /* Send the data */ usb3_set_px_con_send(usb3_ep, len, is_last); -- cgit v1.2.3 From 6124607acc88fffeaadf3aacfeb3cc1304c87387 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 27 Sep 2017 18:47:12 +0900 Subject: usb: renesas_usbhs: fix the BCLR setting condition for non-DCP pipe This patch fixes an issue that the driver sets the BCLR bit of {C,Dn}FIFOCTR register to 1 even when it's non-DCP pipe and the FRDY bit of {C,Dn}FIFOCTR register is set to 1. Fixes: e8d548d54968 ("usb: renesas_usbhs: fifo became independent from pipe.") Cc: # v3.1+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index d1af831f43eb..03cac07f57b5 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -282,11 +282,17 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) { struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + int ret = 0; if (!usbhs_pipe_is_dcp(pipe)) - usbhsf_fifo_barrier(priv, fifo); + ret = usbhsf_fifo_barrier(priv, fifo); - usbhs_write(priv, fifo->ctr, BCLR); + /* + * if non-DCP pipe, this driver should set BCLR when + * usbhsf_fifo_barrier() returns 0. + */ + if (!ret) + usbhs_write(priv, fifo->ctr, BCLR); } static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv, -- cgit v1.2.3 From 0a2ce62b61f2c76d0213edf4e37aaf54a8ddf295 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 27 Sep 2017 18:47:13 +0900 Subject: usb: renesas_usbhs: fix usbhsf_fifo_clear() for RX direction This patch fixes an issue that the usbhsf_fifo_clear() is possible to cause 10 msec delay if the pipe is RX direction and empty because the FRDY bit will never be set to 1 in such case. Fixes: e8d548d54968 ("usb: renesas_usbhs: fifo became independent from pipe.") Cc: # v3.1+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 03cac07f57b5..68f26904c316 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -284,8 +284,17 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); int ret = 0; - if (!usbhs_pipe_is_dcp(pipe)) - ret = usbhsf_fifo_barrier(priv, fifo); + if (!usbhs_pipe_is_dcp(pipe)) { + /* + * This driver checks the pipe condition first to avoid -EBUSY + * from usbhsf_fifo_barrier() with about 10 msec delay in + * the interrupt handler if the pipe is RX direction and empty. + */ + if (usbhs_pipe_is_dir_in(pipe)) + ret = usbhs_pipe_is_accessible(pipe); + if (!ret) + ret = usbhsf_fifo_barrier(priv, fifo); + } /* * if non-DCP pipe, this driver should set BCLR when -- cgit v1.2.3 From addfc5823dbf3e6ed400e98e49c7e64b10e191d6 Mon Sep 17 00:00:00 2001 From: John Keeping Date: Tue, 12 Sep 2017 10:24:40 +0100 Subject: usb: gadget: ffs: handle I/O completion in-order By submitting completed transfers to the system workqueue there is no guarantee that completion events will be queued up in the correct order, as in multi-processor systems there is a thread running for each processor and the work items are not bound to a particular core. This means that several completions are in the queue at the same time, they may be processed in parallel and complete out of order, resulting in data appearing corrupt when read by userspace. Create a single-threaded workqueue for FunctionFS so that data completed requests is passed to userspace in the order in which they complete. Acked-by: Michal Nazarewicz Signed-off-by: John Keeping Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_fs.c | 17 +++++++++++++---- drivers/usb/gadget/function/u_fs.h | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 9990944a7245..8b342587f8ad 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -46,7 +46,8 @@ static void ffs_data_get(struct ffs_data *ffs); static void ffs_data_put(struct ffs_data *ffs); /* Creates new ffs_data object. */ -static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc)); +static struct ffs_data *__must_check ffs_data_new(const char *dev_name) + __attribute__((malloc)); /* Opened counter handling. */ static void ffs_data_opened(struct ffs_data *ffs); @@ -780,11 +781,12 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, struct usb_request *req) { struct ffs_io_data *io_data = req->context; + struct ffs_data *ffs = io_data->ffs; ENTER(); INIT_WORK(&io_data->work, ffs_user_copy_worker); - schedule_work(&io_data->work); + queue_work(ffs->io_completion_wq, &io_data->work); } static void __ffs_epfile_read_buffer_free(struct ffs_epfile *epfile) @@ -1500,7 +1502,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, if (unlikely(ret < 0)) return ERR_PTR(ret); - ffs = ffs_data_new(); + ffs = ffs_data_new(dev_name); if (unlikely(!ffs)) return ERR_PTR(-ENOMEM); ffs->file_perms = data.perms; @@ -1610,6 +1612,7 @@ static void ffs_data_put(struct ffs_data *ffs) BUG_ON(waitqueue_active(&ffs->ev.waitq) || waitqueue_active(&ffs->ep0req_completion.wait) || waitqueue_active(&ffs->wait)); + destroy_workqueue(ffs->io_completion_wq); kfree(ffs->dev_name); kfree(ffs); } @@ -1642,7 +1645,7 @@ static void ffs_data_closed(struct ffs_data *ffs) ffs_data_put(ffs); } -static struct ffs_data *ffs_data_new(void) +static struct ffs_data *ffs_data_new(const char *dev_name) { struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); if (unlikely(!ffs)) @@ -1650,6 +1653,12 @@ static struct ffs_data *ffs_data_new(void) ENTER(); + ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name); + if (!ffs->io_completion_wq) { + kfree(ffs); + return NULL; + } + refcount_set(&ffs->ref, 1); atomic_set(&ffs->opened, 0); ffs->state = FFS_READ_DESCRIPTORS; diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h index 540f1c48c1a8..79f70ebf85dc 100644 --- a/drivers/usb/gadget/function/u_fs.h +++ b/drivers/usb/gadget/function/u_fs.h @@ -279,6 +279,7 @@ struct ffs_data { } file_perms; struct eventfd_ctx *ffs_eventfd; + struct workqueue_struct *io_completion_wq; bool no_disconnect; struct work_struct reset_work; -- cgit v1.2.3 From 6baeda120d90aa637b08f7604de104ab00ce9126 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Thu, 31 Aug 2017 14:51:40 +0200 Subject: usb: gadget: udc: atmel: set vbus irqflags explicitly The driver triggers actions on both edges of the vbus signal. The former PIO controller was triggering IRQs on both falling and rising edges by default. Newer PIO controller don't, so it's better to set it explicitly to IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING. Without this patch we may trigger the connection with host but only on some bouncing signal conditions and thus lose connecting events. Acked-by: Ludovic Desroches Signed-off-by: Nicolas Ferre Cc: stable # v4.4+ Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/atmel_usba_udc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 98d71400f8a1..a884c022df7a 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -29,6 +29,8 @@ #include #include "atmel_usba_udc.h" +#define USBA_VBUS_IRQFLAGS (IRQF_ONESHOT \ + | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING) #ifdef CONFIG_USB_GADGET_DEBUG_FS #include @@ -2361,7 +2363,7 @@ static int usba_udc_probe(struct platform_device *pdev) IRQ_NOAUTOEN); ret = devm_request_threaded_irq(&pdev->dev, gpio_to_irq(udc->vbus_pin), NULL, - usba_vbus_irq_thread, IRQF_ONESHOT, + usba_vbus_irq_thread, USBA_VBUS_IRQFLAGS, "atmel_usba_udc", udc); if (ret) { udc->vbus_pin = -ENODEV; -- cgit v1.2.3 From c3cdce45f8d3dfa5c3467894aa89798314920328 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Wed, 30 Aug 2017 19:03:52 +0800 Subject: usb: dwc3: of-simple: Add compatible for Spreadtrum SC9860 platform Add compatible string to use this generic glue layer to support Spreadtrum SC9860 platform's dwc3 controller. Signed-off-by: Baolin Wang Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-of-simple.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 4cef7d4f9cd0..a26d1fde0f5e 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -177,6 +177,7 @@ static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, + { .compatible = "sprd,sc9860-dwc3" }, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); -- cgit v1.2.3 From ae7617f0ef1820be033eef93859a6bb6174a843f Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 27 Sep 2017 17:41:38 +0100 Subject: drm/i915: Allow optimized platform checks If we store the platform as a bitmask, and convert the IS_PLATFORM macro to use it, we allow the compiler to merge the IS_PLATFORM(a) || IS_PLATFORM(b) || ... checks into a single conditional. As a secondary benefit this saves almost 1k of text: text data bss dec hex filename -1460254 60014 3656 1523924 1740d4 drivers/gpu/drm/i915/i915.ko +1459260 60026 3656 1522942 173cfe drivers/gpu/drm/i915/i915.ko v2: Removed the infamous -1. Signed-off-by: Tvrtko Ursulin Cc: Jani Nikula Reviewed-by: Chris Wilson Acked-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20170927164138.15474-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.c | 4 ++++ drivers/gpu/drm/i915/i915_drv.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7056bb299dc6..59ac9199b35d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -870,6 +870,10 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, memcpy(device_info, match_info, sizeof(*device_info)); device_info->device_id = dev_priv->drm.pdev->device; + BUILD_BUG_ON(INTEL_MAX_PLATFORMS > + sizeof(device_info->platform_mask) * BITS_PER_BYTE); + device_info->platform_mask = BIT(device_info->platform); + BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE); device_info->gen_mask = BIT(device_info->gen - 1); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4e2fcdd4ce9e..59fd4bceec7b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -861,6 +861,7 @@ struct intel_device_info { u8 ring_mask; /* Rings supported by the HW */ enum intel_platform platform; + u32 platform_mask; u32 display_mmio_offset; @@ -2913,7 +2914,7 @@ intel_info(const struct drm_i915_private *dev_priv) #define IS_REVID(p, since, until) \ (INTEL_REVID(p) >= (since) && INTEL_REVID(p) <= (until)) -#define IS_PLATFORM(dev_priv, p) ((dev_priv)->info.platform == (p)) +#define IS_PLATFORM(dev_priv, p) ((dev_priv)->info.platform_mask & BIT(p)) #define IS_I830(dev_priv) IS_PLATFORM(dev_priv, INTEL_I830) #define IS_I845G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I845G) -- cgit v1.2.3 From 2580c4c17aee3ad58e9751012bad278dd074ccae Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Thu, 28 Sep 2017 11:32:37 +0200 Subject: tun: bail out from tun_get_user() if the skb is empty KMSAN (https://github.com/google/kmsan) reported accessing uninitialized skb->data[0] in the case the skb is empty (i.e. skb->len is 0): ================================================ BUG: KMSAN: use of uninitialized memory in tun_get_user+0x19ba/0x3770 CPU: 0 PID: 3051 Comm: probe Not tainted 4.13.0+ #3140 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: ... __msan_warning_32+0x66/0xb0 mm/kmsan/kmsan_instr.c:477 tun_get_user+0x19ba/0x3770 drivers/net/tun.c:1301 tun_chr_write_iter+0x19f/0x300 drivers/net/tun.c:1365 call_write_iter ./include/linux/fs.h:1743 new_sync_write fs/read_write.c:457 __vfs_write+0x6c3/0x7f0 fs/read_write.c:470 vfs_write+0x3e4/0x770 fs/read_write.c:518 SYSC_write+0x12f/0x2b0 fs/read_write.c:565 SyS_write+0x55/0x80 fs/read_write.c:557 do_syscall_64+0x242/0x330 arch/x86/entry/common.c:284 entry_SYSCALL64_slow_path+0x25/0x25 arch/x86/entry/entry_64.S:245 ... origin: ... kmsan_poison_shadow+0x6e/0xc0 mm/kmsan/kmsan.c:211 slab_alloc_node mm/slub.c:2732 __kmalloc_node_track_caller+0x351/0x370 mm/slub.c:4351 __kmalloc_reserve net/core/skbuff.c:138 __alloc_skb+0x26a/0x810 net/core/skbuff.c:231 alloc_skb ./include/linux/skbuff.h:903 alloc_skb_with_frags+0x1d7/0xc80 net/core/skbuff.c:4756 sock_alloc_send_pskb+0xabf/0xfe0 net/core/sock.c:2037 tun_alloc_skb drivers/net/tun.c:1144 tun_get_user+0x9a8/0x3770 drivers/net/tun.c:1274 tun_chr_write_iter+0x19f/0x300 drivers/net/tun.c:1365 call_write_iter ./include/linux/fs.h:1743 new_sync_write fs/read_write.c:457 __vfs_write+0x6c3/0x7f0 fs/read_write.c:470 vfs_write+0x3e4/0x770 fs/read_write.c:518 SYSC_write+0x12f/0x2b0 fs/read_write.c:565 SyS_write+0x55/0x80 fs/read_write.c:557 do_syscall_64+0x242/0x330 arch/x86/entry/common.c:284 return_from_SYSCALL_64+0x0/0x6a arch/x86/entry/entry_64.S:245 ================================================ Make sure tun_get_user() doesn't touch skb->data[0] unless there is actual data. C reproducer below: ========================== // autogenerated by syzkaller (http://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include int main() { int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); int tun_fd = open("/dev/net/tun", O_RDWR); struct ifreq req; memset(&req, 0, sizeof(struct ifreq)); strcpy((char*)&req.ifr_name, "gre0"); req.ifr_flags = IFF_UP | IFF_MULTICAST; ioctl(tun_fd, TUNSETIFF, &req); ioctl(sock, SIOCSIFFLAGS, "gre0"); write(tun_fd, "hi", 0); return 0; } ========================== Signed-off-by: Alexander Potapenko Signed-off-by: David S. Miller --- drivers/net/tun.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 3c9985f29950..5ce580f413b9 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1496,11 +1496,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, switch (tun->flags & TUN_TYPE_MASK) { case IFF_TUN: if (tun->flags & IFF_NO_PI) { - switch (skb->data[0] & 0xf0) { - case 0x40: + u8 ip_version = skb->len ? (skb->data[0] >> 4) : 0; + + switch (ip_version) { + case 4: pi.proto = htons(ETH_P_IP); break; - case 0x60: + case 6: pi.proto = htons(ETH_P_IPV6); break; default: -- cgit v1.2.3 From bd86e32059526e2d0d13ca1e4447dfbbddb6e5cc Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Wed, 27 Sep 2017 20:28:57 +0800 Subject: dm crypt: fix memory leak in crypt_ctr_cipher_old() Fix memory leak of cipher_api. Fixes: 33d2f09fcb35 (dm crypt: introduce new format of cipher with "capi:" prefix) Cc: stable@vger.kernel.org # 4.12+ Signed-off-by: Jeffy Chen Signed-off-by: Mike Snitzer --- drivers/md/dm-crypt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index a55ffd4f5933..75341fdca4b6 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -2466,6 +2466,7 @@ static int crypt_ctr_cipher_old(struct dm_target *ti, char *cipher_in, char *key kfree(cipher_api); return ret; } + kfree(cipher_api); return 0; bad_mem: -- cgit v1.2.3 From aff3da39211105a42b2108b8af79bf8e16f670fd Mon Sep 17 00:00:00 2001 From: Stefan Chulski Date: Mon, 25 Sep 2017 14:59:46 +0200 Subject: net: mvpp2: fix parsing fragmentation detection Parsing fragmentation detection failed due to wrong configured parser TCAM entry's. Some traffic was marked as fragmented in RX descriptor, even it wasn't IP fragmented. The hardware also failed to calculate checksums which lead to use software checksum and caused performance degradation. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart Signed-off-by: Stefan Chulski Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index dd0ee2691c86..da04939a2748 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -676,6 +676,7 @@ enum mvpp2_tag_type { #define MVPP2_PRS_RI_L3_MCAST BIT(15) #define MVPP2_PRS_RI_L3_BCAST (BIT(15) | BIT(16)) #define MVPP2_PRS_RI_IP_FRAG_MASK 0x20000 +#define MVPP2_PRS_RI_IP_FRAG_TRUE BIT(17) #define MVPP2_PRS_RI_UDF3_MASK 0x300000 #define MVPP2_PRS_RI_UDF3_RX_SPECIAL BIT(21) #define MVPP2_PRS_RI_L4_PROTO_MASK 0x1c00000 @@ -2315,7 +2316,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, (proto != IPPROTO_IGMP)) return -EINVAL; - /* Fragmented packet */ + /* Not fragmented packet */ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID); if (tid < 0) @@ -2334,8 +2335,12 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT, MVPP2_PRS_IPV4_DIP_AI_BIT); - mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_MASK, - ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); + mvpp2_prs_sram_ri_update(&pe, ri, ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); + + mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, + MVPP2_PRS_TCAM_PROTO_MASK_L); + mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, + MVPP2_PRS_TCAM_PROTO_MASK); mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK); mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT); @@ -2346,7 +2351,7 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4); mvpp2_prs_hw_write(priv, &pe); - /* Not fragmented packet */ + /* Fragmented packet */ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID); if (tid < 0) @@ -2358,8 +2363,11 @@ static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto, pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0; mvpp2_prs_sram_ri_update(&pe, ri, ri_mask); - mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L); - mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK); + mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_TRUE, + ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); + + mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, 0x0); + mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, 0x0); /* Update shadow table and hw entry */ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4); -- cgit v1.2.3 From 6bf69a1d6334bed776875c5ca852594ab4e5b209 Mon Sep 17 00:00:00 2001 From: Yan Markman Date: Mon, 25 Sep 2017 14:59:47 +0200 Subject: net: mvpp2: fix port list indexing The private port_list array has a list of pointers to mvpp2_port instances. This list is allocated given the number of ports enabled in the device tree, but the pointers are set using the port-id property. If on a single port is enabled, the port_list array will be of size 1, but when registering the port, if its id is not 0 the driver will crash. Other crashes were encountered in various situations. This fixes the issue by using an index not equal to the value of the port-id property. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart Signed-off-by: Yan Markman Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index da04939a2748..b2f99df81e9c 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -7504,7 +7504,7 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv, /* Ports initialization */ static int mvpp2_port_probe(struct platform_device *pdev, struct device_node *port_node, - struct mvpp2 *priv) + struct mvpp2 *priv, int index) { struct device_node *phy_node; struct phy *comphy; @@ -7678,7 +7678,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, } netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr); - priv->port_list[id] = port; + priv->port_list[index] = port; return 0; err_free_port_pcpu: @@ -8013,10 +8013,12 @@ static int mvpp2_probe(struct platform_device *pdev) } /* Initialize ports */ + i = 0; for_each_available_child_of_node(dn, port_node) { - err = mvpp2_port_probe(pdev, port_node, priv); + err = mvpp2_port_probe(pdev, port_node, priv, i); if (err < 0) goto err_mg_clk; + i++; } platform_set_drvdata(pdev, priv); -- cgit v1.2.3 From c7dfc8c848a48f176096f66a14879fb3333a460f Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 25 Sep 2017 14:59:48 +0200 Subject: net: mvpp2: do not select the internal source clock This patch stops the internal MAC Tx clock from being enabled as the internal clock isn't used. The definition used for the bit controlling this behaviour is renamed as well as it was wrongly named (bit 4 of GMAC_CTRL_2_REG). Fixes: 3919357fb0bb ("net: mvpp2: initialize the GMAC when using a port") Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index b2f99df81e9c..161055564720 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -333,7 +333,7 @@ #define MVPP2_GMAC_INBAND_AN_MASK BIT(0) #define MVPP2_GMAC_FLOW_CTRL_MASK GENMASK(2, 1) #define MVPP2_GMAC_PCS_ENABLE_MASK BIT(3) -#define MVPP2_GMAC_PORT_RGMII_MASK BIT(4) +#define MVPP2_GMAC_INTERNAL_CLK_MASK BIT(4) #define MVPP2_GMAC_DISABLE_PADDING BIT(5) #define MVPP2_GMAC_PORT_RESET_MASK BIT(6) #define MVPP2_GMAC_AUTONEG_CONFIG 0xc @@ -4599,7 +4599,6 @@ static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port) val |= MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK; } else if (phy_interface_mode_is_rgmii(port->phy_interface)) { val &= ~MVPP2_GMAC_PCS_ENABLE_MASK; - val |= MVPP2_GMAC_PORT_RGMII_MASK; } writel(val, port->base + MVPP2_GMAC_CTRL_2_REG); -- cgit v1.2.3 From 977da084cc3c1791ecd6faed55e0ab41e7231660 Mon Sep 17 00:00:00 2001 From: vathsala nagaraju Date: Tue, 26 Sep 2017 15:29:13 +0530 Subject: drm/i915/psr: Set frames before SU entry for psr2 Set frames before SU entry value for max resync frame count of dpcd register 2009, bit field 0:3. v2 : - add macro EDP_PSR2_FRAME_BEFORE_SU (Rodrigo) - remove EDP_FRAMES_BEFORE_SU_ENTRY (Rodrigo) - add check ==1 for dpcd_read call (ville) v3 : (Rodrigo) - move macro EDP_PSR2_FRAME_BEFORE_SU after EDP_PSR2_FRAME_BEFORE_SU - replace with &= v4 : - change the macro to shift value (jani) - updated register names Cc: Rodrigo Vivi CC: Puthikorn Voravootivat Reviewed-by: Rodrigo Vivi Signed-off-by: Vathsala Nagaraju Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/1506419953-32605-2-git-send-email-vathsala.nagaraju@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 2 +- drivers/gpu/drm/i915/intel_psr.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e4c424ba5905..ee0d4f14ac98 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4055,7 +4055,7 @@ enum { #define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 #define EDP_PSR2_FRAME_BEFORE_SU_MASK (0xf<<4) #define EDP_PSR2_IDLE_MASK 0xf -#define EDP_FRAMES_BEFORE_SU_ENTRY (1<<4) +#define EDP_PSR2_FRAME_BEFORE_SU(a) ((a)<<4) #define EDP_PSR2_STATUS_CTL _MMIO(0x6f940) #define EDP_PSR2_STATUS_STATE_MASK (0xf<<28) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 0a17d1f3ca77..5419cda83ba8 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -327,6 +327,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) */ uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames); uint32_t val; + uint8_t sink_latency; val = idle_frames << EDP_PSR_IDLE_FRAME_SHIFT; @@ -334,8 +335,16 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) * mesh at all with our frontbuffer tracking. And the hw alone isn't * good enough. */ val |= EDP_PSR2_ENABLE | - EDP_SU_TRACK_ENABLE | - EDP_FRAMES_BEFORE_SU_ENTRY; + EDP_SU_TRACK_ENABLE; + + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_SYNCHRONIZATION_LATENCY_IN_SINK, + &sink_latency) == 1) { + sink_latency &= DP_MAX_RESYNC_FRAME_COUNT_MASK; + } else { + sink_latency = 0; + } + val |= EDP_PSR2_FRAME_BEFORE_SU(sink_latency + 1); if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5) val |= EDP_PSR2_TP2_TIME_2500; -- cgit v1.2.3 From 163e8aecd13e4442fb996ffe031acb8f951dd55f Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 27 Sep 2017 17:20:40 -0700 Subject: drm/i915: Also discard second CRC on gen8+ platforms. One of the differences I spotted for GEN8+ platforms when compared to older platforms is that spec for BDW+ includes this sentence: "The first CRC done indication after CRC is first enabled is from only a partial frame, so it will not have the expected CRC result." This is an indication that on BDW+ platforms, by the time we receive the interrupt the CRC is not accurate yet for the full frame. That would be ok, because we are already skipping the first CRC for all platforms. However the comment on the code state that it is for some unknown reason. Also, on CHV (gen8 lp) we were already discarding the second CRC as well to make sure we have a reliable CRC on hand. So based on all ou tests and bugs it seems that it is not on CHV that needs to discard 2 first CRCs, but all BDW+ platforms. Starting on SKL we have this CRC done bit (24), but the experiments around the use of this bit wasn't that stable as just discarding the second CRC. So, let's for now just move with CHV solution for all gen8+ platforms and make our CI a bit more stable. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102374 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101309 Cc: Mika Kahola Signed-off-by: Rodrigo Vivi Tested-by: Mika Kahola Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20170928002040.7917-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0b7562135d1c..efd7827ff181 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1647,11 +1647,11 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, * bonkers. So let's just wait for the next vblank and read * out the buggy result. * - * On CHV sometimes the second CRC is bonkers as well, so + * On GEN8+ sometimes the second CRC is bonkers as well, so * don't trust that one either. */ if (pipe_crc->skipped == 0 || - (IS_CHERRYVIEW(dev_priv) && pipe_crc->skipped == 1)) { + (INTEL_GEN(dev_priv) >= 8 && pipe_crc->skipped == 1)) { pipe_crc->skipped++; spin_unlock(&pipe_crc->lock); return; -- cgit v1.2.3 From db06ae41945b14feb7f696dcafe8048cc37e8a20 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Mon, 25 Sep 2017 23:32:20 +0200 Subject: net: dsa: mv88e6xxx: Allow dsa and cpu ports in multiple vlans Ports with the same VLAN must all be in the same bridge. However the CPU and DSA ports need to be in multiple VLANs spread over multiple bridges. So exclude them when performing this test. Fixes: b2f81d304cee ("net: dsa: add CPU and DSA ports as VLAN members") Signed-off-by: Andrew Lunn Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index c6678aa9b4ef..674dab71d71c 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -1100,6 +1100,10 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, }; int i, err; + /* DSA and CPU ports have to be members of multiple vlans */ + if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) + return 0; + if (!vid_begin) return -EOPNOTSUPP; -- cgit v1.2.3 From 06d7a1b932c26afe2c0a1f4520ddd417d8eeda79 Mon Sep 17 00:00:00 2001 From: Ed Blake Date: Tue, 26 Sep 2017 11:43:46 +0100 Subject: net: stmmac: dwc-qos: Add suspend / resume support Add hook to stmmac_pltfr_pm_ops for suspend / resume handling. Signed-off-by: Ed Blake Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c index dd6a2f9791cc..5efef8001edf 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c @@ -511,6 +511,7 @@ static struct platform_driver dwc_eth_dwmac_driver = { .remove = dwc_eth_dwmac_remove, .driver = { .name = "dwc-eth-dwmac", + .pm = &stmmac_pltfr_pm_ops, .of_match_table = dwc_eth_dwmac_match, }, }; -- cgit v1.2.3 From 1579f678fb4397f9e439d2e373d4ade036c673b4 Mon Sep 17 00:00:00 2001 From: Ed Blake Date: Tue, 26 Sep 2017 11:44:53 +0100 Subject: net: stmmac: dwmac4: Re-enable MAC Rx before powering down Re-enable the MAC receiver by setting CONFIG_RE before powering down, as instructed in section 6.3.5.1 of [1]. Without this the MAC fails to receive WoL packets and never wakes up. [1] DWC Ethernet QoS Databook 4.10a October 2014 Signed-off-by: Ed Blake Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index c4407e8e39a3..2f7d7ec59962 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -296,6 +296,7 @@ static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode) { void __iomem *ioaddr = hw->pcsr; unsigned int pmt = 0; + u32 config; if (mode & WAKE_MAGIC) { pr_debug("GMAC: WOL Magic frame\n"); @@ -306,6 +307,12 @@ static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode) pmt |= power_down | global_unicast | wake_up_frame_en; } + if (pmt) { + /* The receiver must be enabled for WOL before powering down */ + config = readl(ioaddr + GMAC_CONFIG); + config |= GMAC_CONFIG_RE; + writel(config, ioaddr + GMAC_CONFIG); + } writel(pmt, ioaddr + GMAC_PMT); } -- cgit v1.2.3 From b32ca44a88def4bf92626d8777494c6f14638c42 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 26 Sep 2017 14:57:21 -0400 Subject: net: dsa: mv88e6xxx: lock mutex when freeing IRQs mv88e6xxx_g2_irq_free locks the registers mutex, but not mv88e6xxx_g1_irq_free, which results in a stack trace from assert_reg_lock when unloading the mv88e6xxx module. Fix this. Fixes: 3460a5770ce9 ("net: dsa: mv88e6xxx: Mask g1 interrupts and free interrupt") Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 674dab71d71c..d74c7335c512 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3951,7 +3951,9 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev) if (chip->irq > 0) { if (chip->info->g2_irqs > 0) mv88e6xxx_g2_irq_free(chip); + mutex_lock(&chip->reg_lock); mv88e6xxx_g1_irq_free(chip); + mutex_unlock(&chip->reg_lock); } } -- cgit v1.2.3 From 4dd504f7d98a6719eb2fc1a400257ca1f13d344b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 26 Sep 2017 10:53:53 +0100 Subject: drm/i915: Use memset64() to prefill the GTT page Take advantage of optimised memset64() instead of open coding it to prefill the GTT pages. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170926095353.11036-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem_gtt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 64d785262d14..4c82ceb8d318 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -481,10 +481,8 @@ static void fill_page_dma(struct i915_address_space *vm, const u64 val) { u64 * const vaddr = kmap_atomic(p->page); - int i; - for (i = 0; i < 512; i++) - vaddr[i] = val; + memset64(vaddr, val, PAGE_SIZE / sizeof(val)); kunmap_atomic(vaddr); } -- cgit v1.2.3 From e23b74aab5dc48d3e508a2bc171ccd152fb03803 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Sep 2017 09:47:32 -0400 Subject: drm/amdgpu: fix vf error handling The error handling for virtual functions assumed a single vf per VM and didn't properly account for bare metal. Make the error arrays per device and add locking. Reviewed-by: Gavin Wan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 23 ++++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c | 54 +++++++++++++--------------- drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h | 5 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 13 +++++++ 4 files changed, 54 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 3e84ddf9e3b5..fc0c1cde69ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2040,6 +2040,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->srbm_mutex); mutex_init(&adev->grbm_idx_mutex); mutex_init(&adev->mn_lock); + mutex_init(&adev->virt.vf_errors.lock); hash_init(adev->mn_hash); amdgpu_check_arguments(adev); @@ -2125,7 +2126,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_atombios_init(adev); if (r) { dev_err(adev->dev, "amdgpu_atombios_init failed\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0); goto failed; } @@ -2136,7 +2137,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (amdgpu_vpost_needed(adev)) { if (!adev->bios) { dev_err(adev->dev, "no vBIOS found\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_NO_VBIOS, 0, 0); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_NO_VBIOS, 0, 0); r = -EINVAL; goto failed; } @@ -2144,7 +2145,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_atom_asic_init(adev->mode_info.atom_context); if (r) { dev_err(adev->dev, "gpu post error!\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_POST_ERROR, 0, 0); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_GPU_POST_ERROR, 0, 0); goto failed; } } else { @@ -2156,7 +2157,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_atomfirmware_get_clock_info(adev); if (r) { dev_err(adev->dev, "amdgpu_atomfirmware_get_clock_info failed\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); goto failed; } } else { @@ -2164,7 +2165,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_atombios_get_clock_info(adev); if (r) { dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); goto failed; } /* init i2c buses */ @@ -2175,7 +2176,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_fence_driver_init(adev); if (r) { dev_err(adev->dev, "amdgpu_fence_driver_init failed\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0); goto failed; } @@ -2185,7 +2186,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_init(adev); if (r) { dev_err(adev->dev, "amdgpu_init failed\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0); amdgpu_fini(adev); goto failed; } @@ -2205,7 +2206,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_ib_pool_init(adev); if (r) { dev_err(adev->dev, "IB initialization failed (%d).\n", r); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r); goto failed; } @@ -2254,7 +2255,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_late_init(adev); if (r) { dev_err(adev->dev, "amdgpu_late_init failed\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r); goto failed; } @@ -2936,7 +2937,7 @@ out: } } else { dev_err(adev->dev, "asic resume failed (%d).\n", r); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_ASIC_RESUME_FAIL, 0, r); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ASIC_RESUME_FAIL, 0, r); for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { if (adev->rings[i] && adev->rings[i]->sched.thread) { kthread_unpark(adev->rings[i]->sched.thread); @@ -2950,7 +2951,7 @@ out: if (r) { /* bad news, how to tell it to userspace ? */ dev_info(adev->dev, "GPU reset failed\n"); - amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r); + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r); } else { dev_info(adev->dev, "GPU reset successed!\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c index 45ac91861965..746b81339835 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c @@ -25,30 +25,21 @@ #include "amdgpu_vf_error.h" #include "mxgpu_ai.h" -#define AMDGPU_VF_ERROR_ENTRY_SIZE 16 - -/* struct error_entry - amdgpu VF error information. */ -struct amdgpu_vf_error_buffer { - int read_count; - int write_count; - uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE]; - uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE]; - uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; -}; - -struct amdgpu_vf_error_buffer admgpu_vf_errors; - - -void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data) +void amdgpu_vf_error_put(struct amdgpu_device *adev, + uint16_t sub_error_code, + uint16_t error_flags, + uint64_t error_data) { int index; uint16_t error_code = AMDGIM_ERROR_CODE(AMDGIM_ERROR_CATEGORY_VF, sub_error_code); - index = admgpu_vf_errors.write_count % AMDGPU_VF_ERROR_ENTRY_SIZE; - admgpu_vf_errors.code [index] = error_code; - admgpu_vf_errors.flags [index] = error_flags; - admgpu_vf_errors.data [index] = error_data; - admgpu_vf_errors.write_count ++; + mutex_lock(&adev->virt.vf_errors.lock); + index = adev->virt.vf_errors.write_count % AMDGPU_VF_ERROR_ENTRY_SIZE; + adev->virt.vf_errors.code [index] = error_code; + adev->virt.vf_errors.flags [index] = error_flags; + adev->virt.vf_errors.data [index] = error_data; + adev->virt.vf_errors.write_count ++; + mutex_unlock(&adev->virt.vf_errors.lock); } @@ -58,7 +49,8 @@ void amdgpu_vf_error_trans_all(struct amdgpu_device *adev) u32 data1, data2, data3; int index; - if ((NULL == adev) || (!amdgpu_sriov_vf(adev)) || (!adev->virt.ops) || (!adev->virt.ops->trans_msg)) { + if ((NULL == adev) || (!amdgpu_sriov_vf(adev)) || + (!adev->virt.ops) || (!adev->virt.ops->trans_msg)) { return; } /* @@ -68,18 +60,22 @@ void amdgpu_vf_error_trans_all(struct amdgpu_device *adev) return; } */ + + mutex_lock(&adev->virt.vf_errors.lock); /* The errors are overlay of array, correct read_count as full. */ - if (admgpu_vf_errors.write_count - admgpu_vf_errors.read_count > AMDGPU_VF_ERROR_ENTRY_SIZE) { - admgpu_vf_errors.read_count = admgpu_vf_errors.write_count - AMDGPU_VF_ERROR_ENTRY_SIZE; + if (adev->virt.vf_errors.write_count - adev->virt.vf_errors.read_count > AMDGPU_VF_ERROR_ENTRY_SIZE) { + adev->virt.vf_errors.read_count = adev->virt.vf_errors.write_count - AMDGPU_VF_ERROR_ENTRY_SIZE; } - while (admgpu_vf_errors.read_count < admgpu_vf_errors.write_count) { - index =admgpu_vf_errors.read_count % AMDGPU_VF_ERROR_ENTRY_SIZE; - data1 = AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX (admgpu_vf_errors.code[index], admgpu_vf_errors.flags[index]); - data2 = admgpu_vf_errors.data[index] & 0xFFFFFFFF; - data3 = (admgpu_vf_errors.data[index] >> 32) & 0xFFFFFFFF; + while (adev->virt.vf_errors.read_count < adev->virt.vf_errors.write_count) { + index =adev->virt.vf_errors.read_count % AMDGPU_VF_ERROR_ENTRY_SIZE; + data1 = AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX(adev->virt.vf_errors.code[index], + adev->virt.vf_errors.flags[index]); + data2 = adev->virt.vf_errors.data[index] & 0xFFFFFFFF; + data3 = (adev->virt.vf_errors.data[index] >> 32) & 0xFFFFFFFF; adev->virt.ops->trans_msg(adev, IDH_LOG_VF_ERROR, data1, data2, data3); - admgpu_vf_errors.read_count ++; + adev->virt.vf_errors.read_count ++; } + mutex_unlock(&adev->virt.vf_errors.lock); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h index 2a3278ec76ba..6436bd053325 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h @@ -56,7 +56,10 @@ enum AMDGIM_ERROR_CATEGORY { AMDGIM_ERROR_CATEGORY_MAX }; -void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data); +void amdgpu_vf_error_put(struct amdgpu_device *adev, + uint16_t sub_error_code, + uint16_t error_flags, + uint64_t error_data); void amdgpu_vf_error_trans_all (struct amdgpu_device *adev); #endif /* __VF_ERROR_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index afcfb8bcfb65..e5fd0ff6b29d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h @@ -36,6 +36,18 @@ struct amdgpu_mm_table { uint64_t gpu_addr; }; +#define AMDGPU_VF_ERROR_ENTRY_SIZE 16 + +/* struct error_entry - amdgpu VF error information. */ +struct amdgpu_vf_error_buffer { + struct mutex lock; + int read_count; + int write_count; + uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE]; + uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE]; + uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; +}; + /** * struct amdgpu_virt_ops - amdgpu device virt operations */ @@ -59,6 +71,7 @@ struct amdgpu_virt { struct work_struct flr_work; struct amdgpu_mm_table mm_table; const struct amdgpu_virt_ops *ops; + struct amdgpu_vf_error_buffer vf_errors; }; #define AMDGPU_CSA_SIZE (8 * 1024) -- cgit v1.2.3 From 0f7607d484f57c31a3e0b5b4e75ff1366cc90b6b Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Tue, 26 Sep 2017 12:22:45 -0400 Subject: drm/amdgpu: use multipipe compute policy on non PL11 asics A performance regression for OpenCL tests on Polaris11 had this feature disabled for all asics. Instead, disable it selectively on the affected asics. Acked-by: Felix Kuehling Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 4fcd98e65998..3930fcc3e344 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -109,9 +109,20 @@ void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_s } } +static bool amdgpu_gfx_is_multipipe_capable(struct amdgpu_device *adev) +{ + /* FIXME: spreading the queues across pipes causes perf regressions + * on POLARIS11 compute workloads */ + if (adev->asic_type == CHIP_POLARIS11) + return false; + + return adev->gfx.mec.num_mec > 1; +} + void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev) { int i, queue, pipe, mec; + bool multipipe_policy = amdgpu_gfx_is_multipipe_capable(adev); /* policy for amdgpu compute queue ownership */ for (i = 0; i < AMDGPU_MAX_COMPUTE_QUEUES; ++i) { @@ -125,8 +136,7 @@ void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev) if (mec >= adev->gfx.mec.num_mec) break; - /* FIXME: spreading the queues across pipes causes perf regressions */ - if (0) { + if (multipipe_policy) { /* policy: amdgpu owns the first two queues of the first MEC */ if (mec == 0 && queue < 2) set_bit(i, adev->gfx.mec.queue_bitmap); -- cgit v1.2.3 From 4a75aefe3feb99ff87c1ea594b4db377b98f50e8 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Tue, 26 Sep 2017 12:22:46 -0400 Subject: drm/amdgpu: add option for force enable multipipe policy for compute Useful for testing the effects of multipipe compute without recompiling. Acked-by: Felix Kuehling Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 6 ++++++ 3 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index ebfc267467ee..005b9823e468 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -121,6 +121,7 @@ extern int amdgpu_cntl_sb_buf_per_se; extern int amdgpu_param_buf_per_se; extern int amdgpu_job_hang_limit; extern int amdgpu_lbpw; +extern int amdgpu_compute_multipipe; #ifdef CONFIG_DRM_AMDGPU_SI extern int amdgpu_si_support; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 4f98960e47f9..9816f50a7498 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -122,6 +122,7 @@ int amdgpu_cntl_sb_buf_per_se = 0; int amdgpu_param_buf_per_se = 0; int amdgpu_job_hang_limit = 0; int amdgpu_lbpw = -1; +int amdgpu_compute_multipipe = -1; MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); @@ -265,6 +266,9 @@ module_param_named(job_hang_limit, amdgpu_job_hang_limit, int ,0444); MODULE_PARM_DESC(lbpw, "Load Balancing Per Watt (LBPW) support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(lbpw, amdgpu_lbpw, int, 0444); +MODULE_PARM_DESC(compute_multipipe, "Force compute queues to be spread across pipes (1 = enable, 0 = disable, -1 = auto)"); +module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444); + #ifdef CONFIG_DRM_AMDGPU_SI #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 3930fcc3e344..83435ccbad44 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -111,6 +111,12 @@ void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_s static bool amdgpu_gfx_is_multipipe_capable(struct amdgpu_device *adev) { + if (amdgpu_compute_multipipe != -1) { + DRM_INFO("amdgpu: forcing compute pipe policy %d\n", + amdgpu_compute_multipipe); + return amdgpu_compute_multipipe == 1; + } + /* FIXME: spreading the queues across pipes causes perf regressions * on POLARIS11 compute workloads */ if (adev->asic_type == CHIP_POLARIS11) -- cgit v1.2.3 From 35161bbc135a748dd0a3c822030b3341cdefbd33 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Tue, 26 Sep 2017 17:43:14 -0400 Subject: drm/amdgpu: map compute rings by least recently used pipe This patch provides a guarantee that the first n queues allocated by an application will be on different pipes. Where n is the number of pipes available from the hardware. This helps avoid ring aliasing which can result in work executing in time-sliced mode instead of truly parallel mode. Reviewed-by: Alex Deucher Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | 8 +++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 25 ++++++++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 5 +++-- 3 files changed, 28 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c index befc09b68543..190e28cb827e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c @@ -121,7 +121,7 @@ static enum amdgpu_ring_type amdgpu_hw_ip_to_ring_type(int hw_ip) static int amdgpu_lru_map(struct amdgpu_device *adev, struct amdgpu_queue_mapper *mapper, - int user_ring, + int user_ring, bool lru_pipe_order, struct amdgpu_ring **out_ring) { int r, i, j; @@ -139,7 +139,7 @@ static int amdgpu_lru_map(struct amdgpu_device *adev, } r = amdgpu_ring_lru_get(adev, ring_type, ring_blacklist, - j, out_ring); + j, lru_pipe_order, out_ring); if (r) return r; @@ -284,8 +284,10 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev, r = amdgpu_identity_map(adev, mapper, ring, out_ring); break; case AMDGPU_HW_IP_DMA: + r = amdgpu_lru_map(adev, mapper, ring, false, out_ring); + break; case AMDGPU_HW_IP_COMPUTE: - r = amdgpu_lru_map(adev, mapper, ring, out_ring); + r = amdgpu_lru_map(adev, mapper, ring, true, out_ring); break; default: *out_ring = NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 5ce65280b396..019932a7ea3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -315,14 +315,16 @@ static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring, * @type: amdgpu_ring_type enum * @blacklist: blacklisted ring ids array * @num_blacklist: number of entries in @blacklist + * @lru_pipe_order: find a ring from the least recently used pipe * @ring: output ring * * Retrieve the amdgpu_ring structure for the least recently used ring of * a specific IP block (all asics). * Returns 0 on success, error on failure. */ -int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist, - int num_blacklist, struct amdgpu_ring **ring) +int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, + int *blacklist, int num_blacklist, + bool lru_pipe_order, struct amdgpu_ring **ring) { struct amdgpu_ring *entry; @@ -337,10 +339,23 @@ int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist, if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist)) continue; - *ring = entry; - amdgpu_ring_lru_touch_locked(adev, *ring); - break; + if (!*ring) { + *ring = entry; + + /* We are done for ring LRU */ + if (!lru_pipe_order) + break; + } + + /* Move all rings on the same pipe to the end of the list */ + if (entry->pipe == (*ring)->pipe) + amdgpu_ring_lru_touch_locked(adev, entry); } + + /* Move the ring we found to the end of the list */ + if (*ring) + amdgpu_ring_lru_touch_locked(adev, *ring); + spin_unlock(&adev->ring_lru_list_lock); if (!*ring) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 322d25299a00..491bd5512dcc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -201,8 +201,9 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned ring_size, struct amdgpu_irq_src *irq_src, unsigned irq_type); void amdgpu_ring_fini(struct amdgpu_ring *ring); -int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist, - int num_blacklist, struct amdgpu_ring **ring); +int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, + int *blacklist, int num_blacklist, + bool lru_pipe_order, struct amdgpu_ring **ring); void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring); static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) { -- cgit v1.2.3 From fdd495c57b87078dbcbbc07fa6bf93b5605a95ff Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 08:37:34 +1000 Subject: amdgpu: don't ask about CHASH just default it for now. If we bump this up a level, we can ask about it, for now, just default to what amdgpu does. Reviewed-by: Felix Kuehling Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/lib/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/lib/Kconfig b/drivers/gpu/drm/amd/lib/Kconfig index 03ee7ad21ac3..776ef3434c10 100644 --- a/drivers/gpu/drm/amd/lib/Kconfig +++ b/drivers/gpu/drm/amd/lib/Kconfig @@ -4,7 +4,8 @@ menu "AMD Library routines" # Closed hash table # config CHASH - tristate "Closed hash table" + tristate + default DRM_AMDGPU help Statically sized closed hash table implementation with low memory and CPU overhead. -- cgit v1.2.3 From ba3b6c4273d5cefbed598e639ebb4a224f2f2dde Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 06:44:36 +1000 Subject: amdgpu/powerplay: constify large struct This moves this from being global data to global rodata, I'm sure it would be easy to move it to being local data. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c | 4 ++-- drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c index d09f25485844..34fdf1a2e2df 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c @@ -1,7 +1,7 @@ #include "pp_overdriver.h" #include -struct phm_fuses_default vega10_fuses_default[] = { +const struct phm_fuses_default vega10_fuses_default[] = { {"0000001000010011111010101001010011011110000011100100100101100100",0x00003C96,0xFFFFE226,0x00000656,0x00002203,0xFFFFF201,0x000003FF,0x00002203,0xFFFFF201,0x000003FF}, {"0000001000010011111010101001010011011110000010100001100010000100",0x00003CC5,0xFFFFE23A,0x0000064E,0x00002258,0xFFFFF1F7,0x000003FC,0x00002258,0xFFFFF1F7,0x000003FC}, {"0000001000010011111010101001010011011110000011100011000110100100",0x00003CAF,0xFFFFE36E,0x00000602,0x00001E98,0xFFFFF569,0x00000357,0x00001E98,0xFFFFF569,0x00000357}, @@ -1240,7 +1240,7 @@ struct phm_fuses_default vega10_fuses_default[] = { }; int pp_override_get_default_fuse_value(uint64_t key, - struct phm_fuses_default list[], + const struct phm_fuses_default list[], struct phm_fuses_default *result) { uint32_t i; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h index 6e8f7a2119c1..133745fe4570 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h @@ -40,9 +40,9 @@ struct phm_fuses_default { uint32_t VFT0_b; }; -extern struct phm_fuses_default vega10_fuses_default[]; +extern const struct phm_fuses_default vega10_fuses_default[]; extern int pp_override_get_default_fuse_value(uint64_t key, - struct phm_fuses_default list[], + const struct phm_fuses_default list[], struct phm_fuses_default *result); #endif \ No newline at end of file -- cgit v1.2.3 From 706e25f241a138d5fa14cd48a0de652283b7a3cd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 06:50:54 +1000 Subject: drm/amdgpu/pp: constify some powerplay tables Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c index 9186b0788fac..6f0b2e5b68c7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c @@ -312,37 +312,37 @@ static int rv_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, } /* temporary hardcoded clock voltage breakdown tables */ -DpmClock_t VddDcfClk[]= { +static const DpmClock_t VddDcfClk[]= { { 300, 2600}, { 600, 3200}, { 600, 3600}, }; -DpmClock_t VddSocClk[]= { +static const DpmClock_t VddSocClk[]= { { 478, 2600}, { 722, 3200}, { 722, 3600}, }; -DpmClock_t VddFClk[]= { +static const DpmClock_t VddFClk[]= { { 400, 2600}, {1200, 3200}, {1200, 3600}, }; -DpmClock_t VddDispClk[]= { +static const DpmClock_t VddDispClk[]= { { 435, 2600}, { 661, 3200}, {1086, 3600}, }; -DpmClock_t VddDppClk[]= { +static const DpmClock_t VddDppClk[]= { { 435, 2600}, { 661, 3200}, { 661, 3600}, }; -DpmClock_t VddPhyClk[]= { +static const DpmClock_t VddPhyClk[]= { { 540, 2600}, { 810, 3200}, { 810, 3600}, @@ -350,7 +350,7 @@ DpmClock_t VddPhyClk[]= { static int rv_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr, struct rv_voltage_dependency_table **pptable, - uint32_t num_entry, DpmClock_t *pclk_dependency_table) + uint32_t num_entry, const DpmClock_t *pclk_dependency_table) { uint32_t table_size, i; struct rv_voltage_dependency_table *ptable; -- cgit v1.2.3 From 30b58a248aed8a6e93f9004b5d0f983f2bec30a6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 06:51:21 +1000 Subject: drm/amdgpu/vega10: static constify channel_number Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index a59d282797f5..80e41be3bf7b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -56,7 +56,7 @@ #define HBM_MEMORY_CHANNEL_WIDTH 128 -uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2}; +static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2}; #define MEM_FREQ_LOW_LATENCY 25000 #define MEM_FREQ_HIGH_LATENCY 80000 -- cgit v1.2.3 From 19048dc65a73ea644077514c240bd01abe9c6c08 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 09:01:47 +1000 Subject: amdgpu/pp: remove ci_smc/smumgr split. This split serves no purpose, and we can make a bunch of functions static now. There are lots of cases of this sort of split in the powerplay code, please start cleaning them up. Ideally the function table is in the same file as all the implementations used in it. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/Makefile | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c | 85 ++++++++++++++++++----- drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.h | 52 -------------- drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c | 86 ------------------------ 4 files changed, 71 insertions(+), 154 deletions(-) delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.h delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile index a423c0a85129..4e2988825ff6 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile @@ -4,7 +4,7 @@ SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o fiji_smc.o \ polaris10_smumgr.o iceland_smumgr.o polaris10_smc.o tonga_smc.o \ - smu7_smumgr.o iceland_smc.o vega10_smumgr.o rv_smumgr.o ci_smc.o ci_smumgr.o + smu7_smumgr.o iceland_smc.o vega10_smumgr.o rv_smumgr.o ci_smc.o AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c index 9ee14315dce7..8fb0aa027b54 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c @@ -28,7 +28,6 @@ #include "smumgr.h" #include "pp_debug.h" -#include "ci_smc.h" #include "ci_smumgr.h" #include "ppsmc.h" #include "smu7_hwmgr.h" @@ -208,7 +207,7 @@ static int ci_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, return 0; } -int ci_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) +static int ci_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) { int ret; @@ -227,7 +226,7 @@ int ci_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) return 0; } -int ci_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, +static int ci_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter) { cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter); @@ -476,7 +475,7 @@ static int ci_populate_single_graphic_level(struct pp_hwmgr *hwmgr, return result; } -int ci_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) +static int ci_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); @@ -1297,7 +1296,7 @@ static int ci_populate_single_memory_level( return result; } -int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr) +static int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); @@ -1944,7 +1943,7 @@ static int ci_start_smc(struct pp_hwmgr *hwmgr) return 0; } -int ci_init_smc_table(struct pp_hwmgr *hwmgr) +static int ci_init_smc_table(struct pp_hwmgr *hwmgr) { int result; struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); @@ -2125,7 +2124,7 @@ int ci_init_smc_table(struct pp_hwmgr *hwmgr) return 0; } -int ci_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) +static int ci_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) { struct ci_smumgr *ci_data = (struct ci_smumgr *)(hwmgr->smu_backend); SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; @@ -2211,7 +2210,7 @@ static int ci_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) return 0; } -int ci_update_sclk_threshold(struct pp_hwmgr *hwmgr) +static int ci_update_sclk_threshold(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); @@ -2252,7 +2251,7 @@ int ci_update_sclk_threshold(struct pp_hwmgr *hwmgr) return result; } -uint32_t ci_get_offsetof(uint32_t type, uint32_t member) +static uint32_t ci_get_offsetof(uint32_t type, uint32_t member) { switch (type) { case SMU_SoftRegisters: @@ -2278,7 +2277,7 @@ uint32_t ci_get_offsetof(uint32_t type, uint32_t member) return 0; } -uint32_t ci_get_mac_definition(uint32_t value) +static uint32_t ci_get_mac_definition(uint32_t value) { switch (value) { case SMU_MAX_LEVELS_GRAPHICS: @@ -2355,7 +2354,7 @@ static int ci_upload_firmware(struct pp_hwmgr *hwmgr) return ci_load_smc_ucode(hwmgr); } -int ci_process_firmware_header(struct pp_hwmgr *hwmgr) +static int ci_process_firmware_header(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); struct ci_smumgr *ci_data = (struct ci_smumgr *)(hwmgr->smu_backend); @@ -2667,7 +2666,7 @@ static int ci_set_valid_flag(struct ci_mc_reg_table *table) return 0; } -int ci_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) +static int ci_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) { int result; struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); @@ -2722,13 +2721,13 @@ int ci_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) return result; } -bool ci_is_dpm_running(struct pp_hwmgr *hwmgr) +static bool ci_is_dpm_running(struct pp_hwmgr *hwmgr) { return ci_is_smc_ram_running(hwmgr); } -int ci_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request) +static int ci_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, + struct amd_pp_profile *request) { struct ci_smumgr *smu_data = (struct ci_smumgr *) (hwmgr->smu_backend); @@ -2751,3 +2750,59 @@ int ci_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, return ci_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, array_size, SMC_RAM_END); } + + +static int ci_smu_init(struct pp_hwmgr *hwmgr) +{ + int i; + struct ci_smumgr *ci_priv = NULL; + + ci_priv = kzalloc(sizeof(struct ci_smumgr), GFP_KERNEL); + + if (ci_priv == NULL) + return -ENOMEM; + + for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) + ci_priv->activity_target[i] = 30; + + hwmgr->smu_backend = ci_priv; + + return 0; +} + +static int ci_smu_fini(struct pp_hwmgr *hwmgr) +{ + kfree(hwmgr->smu_backend); + hwmgr->smu_backend = NULL; + cgs_rel_firmware(hwmgr->device, CGS_UCODE_ID_SMU); + return 0; +} + +static int ci_start_smu(struct pp_hwmgr *hwmgr) +{ + return 0; +} + +const struct pp_smumgr_func ci_smu_funcs = { + .smu_init = ci_smu_init, + .smu_fini = ci_smu_fini, + .start_smu = ci_start_smu, + .check_fw_load_finish = NULL, + .request_smu_load_fw = NULL, + .request_smu_load_specific_fw = NULL, + .send_msg_to_smc = ci_send_msg_to_smc, + .send_msg_to_smc_with_parameter = ci_send_msg_to_smc_with_parameter, + .download_pptable_settings = NULL, + .upload_pptable_settings = NULL, + .get_offsetof = ci_get_offsetof, + .process_firmware_header = ci_process_firmware_header, + .init_smc_table = ci_init_smc_table, + .update_sclk_threshold = ci_update_sclk_threshold, + .thermal_setup_fan_table = ci_thermal_setup_fan_table, + .populate_all_graphic_levels = ci_populate_all_graphic_levels, + .populate_all_memory_levels = ci_populate_all_memory_levels, + .get_mac_definition = ci_get_mac_definition, + .initialize_mc_reg_table = ci_initialize_mc_reg_table, + .is_dpm_running = ci_is_dpm_running, + .populate_requested_graphic_levels = ci_populate_requested_graphic_levels, +}; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.h b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.h deleted file mode 100644 index cc4176d2d25f..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - */ -#ifndef CI_SMC_H -#define CI_SMC_H - -#include - - -struct pp_smumgr; -struct pp_hwmgr; -struct amd_pp_profile; - -int ci_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, - uint16_t msg, uint32_t parameter); -int ci_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg); -int ci_populate_all_graphic_levels(struct pp_hwmgr *hwmgr); -int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr); -int ci_init_smc_table(struct pp_hwmgr *hwmgr); -int ci_thermal_setup_fan_table(struct pp_hwmgr *hwmgr); -int ci_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type); -int ci_update_sclk_threshold(struct pp_hwmgr *hwmgr); -uint32_t ci_get_offsetof(uint32_t type, uint32_t member); -uint32_t ci_get_mac_definition(uint32_t value); -int ci_process_firmware_header(struct pp_hwmgr *hwmgr); -int ci_initialize_mc_reg_table(struct pp_hwmgr *hwmgr); -bool ci_is_dpm_running(struct pp_hwmgr *hwmgr); -int ci_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request); - - -#endif - diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c deleted file mode 100644 index f265f42a7ed3..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include -#include -#include -#include "linux/delay.h" - -#include "smumgr.h" -#include "ci_smumgr.h" -#include "cgs_common.h" -#include "ci_smc.h" - -static int ci_smu_init(struct pp_hwmgr *hwmgr) -{ - int i; - struct ci_smumgr *ci_priv = NULL; - - ci_priv = kzalloc(sizeof(struct ci_smumgr), GFP_KERNEL); - - if (ci_priv == NULL) - return -ENOMEM; - - for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) - ci_priv->activity_target[i] = 30; - - hwmgr->smu_backend = ci_priv; - - return 0; -} - -static int ci_smu_fini(struct pp_hwmgr *hwmgr) -{ - kfree(hwmgr->smu_backend); - hwmgr->smu_backend = NULL; - cgs_rel_firmware(hwmgr->device, CGS_UCODE_ID_SMU); - return 0; -} - -static int ci_start_smu(struct pp_hwmgr *hwmgr) -{ - return 0; -} - -const struct pp_smumgr_func ci_smu_funcs = { - .smu_init = ci_smu_init, - .smu_fini = ci_smu_fini, - .start_smu = ci_start_smu, - .check_fw_load_finish = NULL, - .request_smu_load_fw = NULL, - .request_smu_load_specific_fw = NULL, - .send_msg_to_smc = ci_send_msg_to_smc, - .send_msg_to_smc_with_parameter = ci_send_msg_to_smc_with_parameter, - .download_pptable_settings = NULL, - .upload_pptable_settings = NULL, - .get_offsetof = ci_get_offsetof, - .process_firmware_header = ci_process_firmware_header, - .init_smc_table = ci_init_smc_table, - .update_sclk_threshold = ci_update_sclk_threshold, - .thermal_setup_fan_table = ci_thermal_setup_fan_table, - .populate_all_graphic_levels = ci_populate_all_graphic_levels, - .populate_all_memory_levels = ci_populate_all_memory_levels, - .get_mac_definition = ci_get_mac_definition, - .initialize_mc_reg_table = ci_initialize_mc_reg_table, - .is_dpm_running = ci_is_dpm_running, - .populate_requested_graphic_levels = ci_populate_requested_graphic_levels, -}; -- cgit v1.2.3 From f87c379ee073bec8451fbee9ea6922db1e6ac897 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 09:32:49 +1000 Subject: amdgpu/pp: move PhwVega10_Magic to static const. This isn't used outside this file. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 80e41be3bf7b..71b94241ea7a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -81,7 +81,7 @@ static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2}; static int vega10_force_clock_level(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); -const ULONG PhwVega10_Magic = (ULONG)(PHM_VIslands_Magic); +static const ULONG PhwVega10_Magic = (ULONG)(PHM_VIslands_Magic); struct vega10_power_state *cast_phw_vega10_power_state( struct pp_hw_power_state *hw_ps) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h index 676cd7735883..b4b461c3b8ee 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h @@ -31,7 +31,6 @@ #include "vega10_ppsmc.h" #include "vega10_powertune.h" -extern const uint32_t PhwVega10_Magic; #define VEGA10_MAX_HARDWARE_POWERLEVELS 2 #define WaterMarksExist 1 -- cgit v1.2.3 From 819c4b949d3af009f0111e4a9ddfe3de5f2c2fe1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 09:36:55 +1000 Subject: amdgpu/pp: move amdgpu_fuses_default into static const. There is no reason that this gets passed back into the function from outside the file, just reference the table directly. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c | 4 ++-- drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h | 2 -- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c index 34fdf1a2e2df..2b08371102be 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c @@ -1,7 +1,7 @@ #include "pp_overdriver.h" #include -const struct phm_fuses_default vega10_fuses_default[] = { +static const struct phm_fuses_default vega10_fuses_default[] = { {"0000001000010011111010101001010011011110000011100100100101100100",0x00003C96,0xFFFFE226,0x00000656,0x00002203,0xFFFFF201,0x000003FF,0x00002203,0xFFFFF201,0x000003FF}, {"0000001000010011111010101001010011011110000010100001100010000100",0x00003CC5,0xFFFFE23A,0x0000064E,0x00002258,0xFFFFF1F7,0x000003FC,0x00002258,0xFFFFF1F7,0x000003FC}, {"0000001000010011111010101001010011011110000011100011000110100100",0x00003CAF,0xFFFFE36E,0x00000602,0x00001E98,0xFFFFF569,0x00000357,0x00001E98,0xFFFFF569,0x00000357}, @@ -1240,9 +1240,9 @@ const struct phm_fuses_default vega10_fuses_default[] = { }; int pp_override_get_default_fuse_value(uint64_t key, - const struct phm_fuses_default list[], struct phm_fuses_default *result) { + const struct phm_fuses_default *list = vega10_fuses_default; uint32_t i; uint64_t temp_serial_numer; uint32_t bit; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h index 133745fe4570..22e2dd0b49b4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h @@ -40,9 +40,7 @@ struct phm_fuses_default { uint32_t VFT0_b; }; -extern const struct phm_fuses_default vega10_fuses_default[]; extern int pp_override_get_default_fuse_value(uint64_t key, - const struct phm_fuses_default list[], struct phm_fuses_default *result); #endif \ No newline at end of file diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 71b94241ea7a..6a859542382b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -2393,7 +2393,7 @@ static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr) serial_number = ((uint64_t)bottom32 << 32) | top32; - if (pp_override_get_default_fuse_value(serial_number, vega10_fuses_default, &fuse) == 0) { + if (pp_override_get_default_fuse_value(serial_number, &fuse) == 0) { avfs_fuse_table->VFT0_b = fuse.VFT0_b; avfs_fuse_table->VFT0_m1 = fuse.VFT0_m1; avfs_fuse_table->VFT0_m2 = fuse.VFT0_m2; -- cgit v1.2.3 From bf3486fd0ea9c36c6764583d763be7658ae5b3bf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 14:48:38 +1000 Subject: amdgpu/pp: slim down the pwr virus tables. This is what I'd call slightly overengineered, we waste 40k on storing a value that is write or end, when we could just use the register value to denote end. Remove the virus command parameter, and save text data bss dec hex filename 1412724 17982 1008 1431714 15d8a2 ../drm-next-build/drivers/gpu/drm/amd/amdgpu/amdgpu.o 1331332 17982 1008 1350322 149ab2 ../drm-next-build/drivers/gpu/drm/amd/amdgpu/amdgpu.o Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h | 20500 +++++++++---------- .../gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h | 20072 +++++++++--------- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 18 +- .../drm/amd/powerplay/smumgr/polaris10_smumgr.c | 18 +- 4 files changed, 20284 insertions(+), 20324 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h b/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h index 8a31665321a8..243de293a3ef 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h +++ b/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h @@ -28,10272 +28,10262 @@ #define mmCP_HYP_MEC2_UCODE_ADDR 0xf81c #define mmCP_HYP_MEC2_UCODE_DATA 0xf81d -enum PWR_Command -{ - PwrCmdNull = 0, - PwrCmdWrite, - PwrCmdEnd, - PwrCmdMax -}; -typedef enum PWR_Command PWR_Command; - struct PWR_Command_Table { - PWR_Command command; - ULONG data; - ULONG reg; + uint32_t data; + uint32_t reg; }; typedef struct PWR_Command_Table PWR_Command_Table; #define PWR_VIRUS_TABLE_SIZE 10243 static const PWR_Command_Table PwrVirusTable[PWR_VIRUS_TABLE_SIZE] = { - { PwrCmdWrite, 0x100100b6, mmPCIE_INDEX }, - { PwrCmdWrite, 0x00000000, mmPCIE_DATA }, - { PwrCmdWrite, 0x100100b6, mmPCIE_INDEX }, - { PwrCmdWrite, 0x0300078c, mmPCIE_DATA }, - { PwrCmdWrite, 0x00000000, mmBIF_CLK_CTRL }, - { PwrCmdWrite, 0x00000001, mmBIF_CLK_CTRL }, - { PwrCmdWrite, 0x00000000, mmBIF_CLK_CTRL }, - { PwrCmdWrite, 0x00000003, mmBIF_FB_EN }, - { PwrCmdWrite, 0x00000000, mmBIF_FB_EN }, - { PwrCmdWrite, 0x00000001, mmBIF_DOORBELL_APER_EN }, - { PwrCmdWrite, 0x00000000, mmBIF_DOORBELL_APER_EN }, - { PwrCmdWrite, 0x014000c0, mmPCIE_INDEX }, - { PwrCmdWrite, 0x00000000, mmPCIE_DATA }, - { PwrCmdWrite, 0x014000c0, mmPCIE_INDEX }, - { PwrCmdWrite, 0x22000000, mmPCIE_DATA }, - { PwrCmdWrite, 0x014000c0, mmPCIE_INDEX }, - { PwrCmdWrite, 0x00000000, mmPCIE_DATA }, + { 0x100100b6, mmPCIE_INDEX }, + { 0x00000000, mmPCIE_DATA }, + { 0x100100b6, mmPCIE_INDEX }, + { 0x0300078c, mmPCIE_DATA }, + { 0x00000000, mmBIF_CLK_CTRL }, + { 0x00000001, mmBIF_CLK_CTRL }, + { 0x00000000, mmBIF_CLK_CTRL }, + { 0x00000003, mmBIF_FB_EN }, + { 0x00000000, mmBIF_FB_EN }, + { 0x00000001, mmBIF_DOORBELL_APER_EN }, + { 0x00000000, mmBIF_DOORBELL_APER_EN }, + { 0x014000c0, mmPCIE_INDEX }, + { 0x00000000, mmPCIE_DATA }, + { 0x014000c0, mmPCIE_INDEX }, + { 0x22000000, mmPCIE_DATA }, + { 0x014000c0, mmPCIE_INDEX }, + { 0x00000000, mmPCIE_DATA }, /* - { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION }, - { PwrCmdWrite, 0x00000000, mmMC_CITF_CNTL }, - { PwrCmdWrite, 0x00000000, mmMC_VM_FB_LOCATION }, - { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION }, - { PwrCmdWrite, 0x00000000, mmMC_VM_FB_LOCATION }, - { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION }, - { PwrCmdWrite, 0x00000000, mmMC_VM_FB_OFFSET },*/ - { PwrCmdWrite, 0x00000000, mmRLC_CSIB_ADDR_LO }, - { PwrCmdWrite, 0x00000000, mmRLC_CSIB_ADDR_HI }, - { PwrCmdWrite, 0x00000000, mmRLC_CSIB_LENGTH }, + { 0x009f0090, mmMC_VM_FB_LOCATION }, + { 0x00000000, mmMC_CITF_CNTL }, + { 0x00000000, mmMC_VM_FB_LOCATION }, + { 0x009f0090, mmMC_VM_FB_LOCATION }, + { 0x00000000, mmMC_VM_FB_LOCATION }, + { 0x009f0090, mmMC_VM_FB_LOCATION }, + { 0x00000000, mmMC_VM_FB_OFFSET },*/ + { 0x00000000, mmRLC_CSIB_ADDR_LO }, + { 0x00000000, mmRLC_CSIB_ADDR_HI }, + { 0x00000000, mmRLC_CSIB_LENGTH }, /* - { PwrCmdWrite, 0x00000000, mmMC_VM_MX_L1_TLB_CNTL }, - { PwrCmdWrite, 0x00000001, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR }, - { PwrCmdWrite, 0x00000000, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR }, - { PwrCmdWrite, 0x00000000, mmMC_VM_FB_LOCATION }, - { PwrCmdWrite, 0x009f0090, mmMC_VM_FB_LOCATION },*/ - { PwrCmdWrite, 0x00000000, mmVM_CONTEXT0_CNTL }, - { PwrCmdWrite, 0x00000000, mmVM_CONTEXT1_CNTL }, + { 0x00000000, mmMC_VM_MX_L1_TLB_CNTL }, + { 0x00000001, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR }, + { 0x00000000, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR }, + { 0x00000000, mmMC_VM_FB_LOCATION }, + { 0x009f0090, mmMC_VM_FB_LOCATION },*/ + { 0x00000000, mmVM_CONTEXT0_CNTL }, + { 0x00000000, mmVM_CONTEXT1_CNTL }, /* - { PwrCmdWrite, 0x00000000, mmMC_VM_AGP_BASE }, - { PwrCmdWrite, 0x00000002, mmMC_VM_AGP_BOT }, - { PwrCmdWrite, 0x00000000, mmMC_VM_AGP_TOP },*/ - { PwrCmdWrite, 0x04000000, mmATC_VM_APERTURE0_LOW_ADDR }, - { PwrCmdWrite, 0x0400ff20, mmATC_VM_APERTURE0_HIGH_ADDR }, - { PwrCmdWrite, 0x00000002, mmATC_VM_APERTURE0_CNTL }, - { PwrCmdWrite, 0x0000ffff, mmATC_VM_APERTURE0_CNTL2 }, - { PwrCmdWrite, 0x00000001, mmATC_VM_APERTURE1_LOW_ADDR }, - { PwrCmdWrite, 0x00000000, mmATC_VM_APERTURE1_HIGH_ADDR }, - { PwrCmdWrite, 0x00000000, mmATC_VM_APERTURE1_CNTL }, - { PwrCmdWrite, 0x00000000, mmATC_VM_APERTURE1_CNTL2 }, - //{ PwrCmdWrite, 0x00000000, mmMC_ARB_RAMCFG }, - { PwrCmdWrite, 0x12011003, mmGB_ADDR_CONFIG }, - { PwrCmdWrite, 0x00800010, mmGB_TILE_MODE0 }, - { PwrCmdWrite, 0x00800810, mmGB_TILE_MODE1 }, - { PwrCmdWrite, 0x00801010, mmGB_TILE_MODE2 }, - { PwrCmdWrite, 0x00801810, mmGB_TILE_MODE3 }, - { PwrCmdWrite, 0x00802810, mmGB_TILE_MODE4 }, - { PwrCmdWrite, 0x00802808, mmGB_TILE_MODE5 }, - { PwrCmdWrite, 0x00802814, mmGB_TILE_MODE6 }, - { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE7 }, - { PwrCmdWrite, 0x00000004, mmGB_TILE_MODE8 }, - { PwrCmdWrite, 0x02000008, mmGB_TILE_MODE9 }, - { PwrCmdWrite, 0x02000010, mmGB_TILE_MODE10 }, - { PwrCmdWrite, 0x06000014, mmGB_TILE_MODE11 }, - { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE12 }, - { PwrCmdWrite, 0x02400008, mmGB_TILE_MODE13 }, - { PwrCmdWrite, 0x02400010, mmGB_TILE_MODE14 }, - { PwrCmdWrite, 0x02400030, mmGB_TILE_MODE15 }, - { PwrCmdWrite, 0x06400014, mmGB_TILE_MODE16 }, - { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE17 }, - { PwrCmdWrite, 0x0040000c, mmGB_TILE_MODE18 }, - { PwrCmdWrite, 0x0100000c, mmGB_TILE_MODE19 }, - { PwrCmdWrite, 0x0100001c, mmGB_TILE_MODE20 }, - { PwrCmdWrite, 0x01000034, mmGB_TILE_MODE21 }, - { PwrCmdWrite, 0x01000024, mmGB_TILE_MODE22 }, - { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE23 }, - { PwrCmdWrite, 0x0040001c, mmGB_TILE_MODE24 }, - { PwrCmdWrite, 0x01000020, mmGB_TILE_MODE25 }, - { PwrCmdWrite, 0x01000038, mmGB_TILE_MODE26 }, - { PwrCmdWrite, 0x02c00008, mmGB_TILE_MODE27 }, - { PwrCmdWrite, 0x02c00010, mmGB_TILE_MODE28 }, - { PwrCmdWrite, 0x06c00014, mmGB_TILE_MODE29 }, - { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE30 }, - { PwrCmdWrite, 0x00000000, mmGB_TILE_MODE31 }, - { PwrCmdWrite, 0x000000a8, mmGB_MACROTILE_MODE0 }, - { PwrCmdWrite, 0x000000a4, mmGB_MACROTILE_MODE1 }, - { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE2 }, - { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE3 }, - { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE4 }, - { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE5 }, - { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE6 }, - { PwrCmdWrite, 0x00000000, mmGB_MACROTILE_MODE7 }, - { PwrCmdWrite, 0x000000ee, mmGB_MACROTILE_MODE8 }, - { PwrCmdWrite, 0x000000ea, mmGB_MACROTILE_MODE9 }, - { PwrCmdWrite, 0x000000e9, mmGB_MACROTILE_MODE10 }, - { PwrCmdWrite, 0x000000e5, mmGB_MACROTILE_MODE11 }, - { PwrCmdWrite, 0x000000e4, mmGB_MACROTILE_MODE12 }, - { PwrCmdWrite, 0x000000e0, mmGB_MACROTILE_MODE13 }, - { PwrCmdWrite, 0x00000090, mmGB_MACROTILE_MODE14 }, - { PwrCmdWrite, 0x00000000, mmGB_MACROTILE_MODE15 }, - { PwrCmdWrite, 0x00900000, mmHDP_NONSURFACE_BASE }, - { PwrCmdWrite, 0x00008000, mmHDP_NONSURFACE_INFO }, - { PwrCmdWrite, 0x3fffffff, mmHDP_NONSURFACE_SIZE }, - { PwrCmdWrite, 0x00000003, mmBIF_FB_EN }, - //{ PwrCmdWrite, 0x00000000, mmMC_VM_FB_OFFSET }, - { PwrCmdWrite, 0x00000000, mmSRBM_CNTL }, - { PwrCmdWrite, 0x00020000, mmSRBM_CNTL }, - { PwrCmdWrite, 0x80000000, mmATC_VMID0_PASID_MAPPING }, - { PwrCmdWrite, 0x00000000, mmATC_VMID_PASID_MAPPING_UPDATE_STATUS }, - { PwrCmdWrite, 0x00000000, mmRLC_CNTL }, - { PwrCmdWrite, 0x00000000, mmRLC_CNTL }, - { PwrCmdWrite, 0x00000000, mmRLC_CNTL }, - { PwrCmdWrite, 0xe0000000, mmGRBM_GFX_INDEX }, - { PwrCmdWrite, 0x00000000, mmCGTS_TCC_DISABLE }, - { PwrCmdWrite, 0x00000000, mmTCP_ADDR_CONFIG }, - { PwrCmdWrite, 0x000000ff, mmTCP_ADDR_CONFIG }, - { PwrCmdWrite, 0x76543210, mmTCP_CHAN_STEER_LO }, - { PwrCmdWrite, 0xfedcba98, mmTCP_CHAN_STEER_HI }, - { PwrCmdWrite, 0x00000000, mmDB_DEBUG2 }, - { PwrCmdWrite, 0x00000000, mmDB_DEBUG }, - { PwrCmdWrite, 0x00002b16, mmCP_QUEUE_THRESHOLDS }, - { PwrCmdWrite, 0x00006030, mmCP_MEQ_THRESHOLDS }, - { PwrCmdWrite, 0x01000104, mmSPI_CONFIG_CNTL_1 }, - { PwrCmdWrite, 0x98184020, mmPA_SC_FIFO_SIZE }, - { PwrCmdWrite, 0x00000001, mmVGT_NUM_INSTANCES }, - { PwrCmdWrite, 0x00000000, mmCP_PERFMON_CNTL }, - { PwrCmdWrite, 0x01180000, mmSQ_CONFIG }, - { PwrCmdWrite, 0x00000000, mmVGT_CACHE_INVALIDATION }, - { PwrCmdWrite, 0x00000000, mmSQ_THREAD_TRACE_BASE }, - { PwrCmdWrite, 0x0000df80, mmSQ_THREAD_TRACE_MASK }, - { PwrCmdWrite, 0x02249249, mmSQ_THREAD_TRACE_MODE }, - { PwrCmdWrite, 0x00000000, mmPA_SC_LINE_STIPPLE_STATE }, - { PwrCmdWrite, 0x00000000, mmCB_PERFCOUNTER0_SELECT1 }, - { PwrCmdWrite, 0x06000100, mmCGTT_VGT_CLK_CTRL }, - { PwrCmdWrite, 0x00000007, mmPA_CL_ENHANCE }, - { PwrCmdWrite, 0x00000001, mmPA_SC_ENHANCE }, - { PwrCmdWrite, 0x00ffffff, mmPA_SC_FORCE_EOV_MAX_CNTS }, - { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000010, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000020, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000030, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000040, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000050, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000060, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000070, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000080, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000090, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x000000a0, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x000000b0, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x000000c0, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x000000d0, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x000000e0, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x000000f0, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmRLC_PG_CNTL }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS2 }, - { PwrCmdWrite, 0x15000000, mmCP_ME_CNTL }, - { PwrCmdWrite, 0x50000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x0000000e, mmSH_MEM_APE1_BASE }, - { PwrCmdWrite, 0x0000020d, mmSH_MEM_APE1_LIMIT }, - { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000320, mmSH_MEM_CONFIG }, - { PwrCmdWrite, 0x00000000, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_RB_VMID }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmRLC_CNTL }, - { PwrCmdWrite, 0x00000000, mmRLC_CNTL }, - { PwrCmdWrite, 0x00000000, mmRLC_SRM_CNTL }, - { PwrCmdWrite, 0x00000002, mmRLC_SRM_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_ME_CNTL }, - { PwrCmdWrite, 0x15000000, mmCP_ME_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x50000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x0840800a, mmCP_RB0_CNTL }, - { PwrCmdWrite, 0xf30fff0f, mmTCC_CTRL }, - { PwrCmdWrite, 0x00000002, mmTCC_EXE_DISABLE }, - { PwrCmdWrite, 0x000000ff, mmTCP_ADDR_CONFIG }, - { PwrCmdWrite, 0x540ff000, mmCP_CPC_IC_BASE_LO }, - { PwrCmdWrite, 0x000000b4, mmCP_CPC_IC_BASE_HI }, - { PwrCmdWrite, 0x00010000, mmCP_HYP_MEC1_UCODE_ADDR }, - { PwrCmdWrite, 0x00041b75, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000710e8, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000910dd, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000a1081, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000b016f, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000c0e3c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000d10ec, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000e0188, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00101b5d, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00150a6c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00170c5e, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x001d0c8c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x001e0cfe, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00221408, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00370d7b, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00390dcb, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x003c142f, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x003f0b27, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00400e63, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00500f62, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00460fa7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00490fa7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x005811d4, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00680ad6, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00760b00, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00780b0c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00790af7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x007d1aba, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x007e1abe, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00591260, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x005a12fb, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00861ac7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x008c1b01, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x008d1b34, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a014b9, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a1152e, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a216fb, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a41890, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a31906, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a50b14, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00621387, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x005c0b27, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00160a75, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00010000, mmCP_HYP_MEC2_UCODE_ADDR }, - { PwrCmdWrite, 0x00041b75, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000710e8, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000910dd, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000a1081, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000b016f, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000c0e3c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000d10ec, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000e0188, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00101b5d, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00150a6c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00170c5e, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x001d0c8c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x001e0cfe, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00221408, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00370d7b, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00390dcb, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x003c142f, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x003f0b27, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00400e63, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00500f62, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00460fa7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00490fa7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x005811d4, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00680ad6, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00760b00, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00780b0c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00790af7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x007d1aba, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x007e1abe, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00591260, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x005a12fb, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00861ac7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x008c1b01, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x008d1b34, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a014b9, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a1152e, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a216fb, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a41890, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a31906, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a50b14, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00621387, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x005c0b27, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00160a75, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x540fe800, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0x7e000200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e020201, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e040204, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e060205, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54106f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000400b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00004000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00804fac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x540fef00, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0xc0031502, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00001e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x540ff000, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000145, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdcc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080061, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ccffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3cd08000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1cd0ffcf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x050c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x84c00000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000067, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000006a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000008f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000099, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800000a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800000af, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x388c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08880002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d808001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc0700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10c017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0d000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01b10, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x280c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x280c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x280c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca88004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc00006f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10c017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd4c0380, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdcc0388, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdcc038c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0c0390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0c0394, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4c0398, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4c039c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8c03a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8c03a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcecc03a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcecc03ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0c03b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0c03b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4c03b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4c03bc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8c03c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57b80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8c03c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfcc03c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57fc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfcc03cc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05dc002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc12009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d200a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc012009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25e01c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25e40300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25e800c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25ec003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e25c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de5c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xddc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31100006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4df0388, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d7038c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d5dc01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4e30390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d70394, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d62001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4e70398, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d7039c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d66401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4eb03a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d6a801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ef03a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d6ec01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4f303b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d73001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4f703b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703bc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d77401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4fb03c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7b801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ff03c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703cc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7fc01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d70380, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1c88001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc01e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3cd00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0085, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc006a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc01e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3cd00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1c88001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400051, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aac0027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04080002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000367, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9880fff3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04080010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80c0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80c0319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9880fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d4001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x155c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e80180, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900091a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280196, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d4fe04, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800001b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000032b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000352, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000035f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000047c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000019f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d98001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0044, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9400036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11540015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a4003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1998003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af0007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15dc000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d65400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a38003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd5c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800045, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411326a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415326b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000056, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40005a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29988000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000073, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001b6d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00005f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000075, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26f00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d190004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af07fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0434001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04343000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf413267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd1c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0160, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc810001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b4c0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f4f400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55180020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x248dfffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc12e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af4007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33740003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ae8003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26680001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253348, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413348, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253348, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x958000d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000315, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04303000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26680001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1714000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d77400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c01e2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e5c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1334e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01334f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813351, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd881334d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3271, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50cc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cdcc011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05900008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00006a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0006b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3272, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d594002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc12e23, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd012e24, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc12e25, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b340057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b280213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980198, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e40020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20cc003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01e0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2d540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x078c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07d40000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001239, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04f80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x057c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd5c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840007c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c018a6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e22, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800007c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c018a2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800002e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800002e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540188f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc013cfff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x38d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdcc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01882, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000304, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x49980198, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e40020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000329, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc812e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16ec001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1998003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a18003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4093249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1888003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419324c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1598001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d80011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24dc00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31e00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31dc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95801827, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14dc0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a0000ad, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af4003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca88005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f4b4009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d33400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a4004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1eecffdd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800003c3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa80030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a8004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3272, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e80042, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e8e800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de9c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3271, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50cc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce8c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd30011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11e80007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd300001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1660001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e320009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0328000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e72400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0430000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ac000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d310002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa87600, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280222, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22ec003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8380018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57b00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04343108, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2374007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32a80003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e40213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc0199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cecc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800003e7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980104, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x49980104, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800003f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000448, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf41326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x254c0700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a641fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0726, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a640200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1237b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01755, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde830000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0174c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bb80040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100044, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19180024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x551c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000043d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840006c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000043f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282000f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2555fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0360001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5e124dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e624001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fff9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2555fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980158, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x49980158, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980170, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1154000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e80488, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0006c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f807f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e40077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000048e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000494, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000685, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000686, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800006ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ccc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d79400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e7a400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52a8001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d69401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec0028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004cc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419324e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26e8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12f4000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d324d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d75401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d290004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f8f4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f52800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50e00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004d1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0dc002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x6665fc00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a644000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f534002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x6665fc00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004d7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12f4000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d75401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a644000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e804e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004e7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000505, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x277401ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf41325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84131db, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26edf000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05a80507, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000050c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000528, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000057d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800005c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800005f3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00063b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000624, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1be00fe4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000066, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400067, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00063b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000624, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ed6c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113271, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193272, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d51401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253276, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400061, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2730000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7db1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00062, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000063, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400065, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec0188, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26e01000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c131fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x191807e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192007ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x69dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de20014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x561c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013344, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13345, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425334d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419334e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d334f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253351, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec01b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2010007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1910003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2010003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x191807e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013344, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013345, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280042, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400067, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07d40000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00124f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x057c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec0190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2154003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd800e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f598004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1be800e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801327a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800005f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000075, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a4004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x277401ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf41325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xda000068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425334d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419334e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d334f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253351, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec01b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1be000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0360001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc63124dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fff9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fc14001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c1c03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000697, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27301fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31100005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900008e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000075e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a9feff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d30b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00ac006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28880700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0006de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30d4000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41530b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19980028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800006c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8380023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa38011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c2002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202400d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27301fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000712, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c1c03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e80714, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000071c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000720, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000747, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000071d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800007c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000732, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000745, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000744, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000072e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a64008c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000075e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0fff1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000723, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41f02f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000743, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8813247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffde, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000072e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84131db, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195800e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dd7fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1a001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46200200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04283247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af80057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af40213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6f400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6990000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x329c325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x329c3269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x329c3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01defff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d8009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000078a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fff2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03e7ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3f0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1f30001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03e4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d30b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000b80, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x203c003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31dc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e40213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc0199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cecc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000448, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19580066, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0120001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da18001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d24db, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580137b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19080070, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x190c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2518000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05a80809, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000080e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000080f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000898, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000946, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009e1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a80811, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000815, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000834, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3045, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c091, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31300021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000241, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000084a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02f0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4252087, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5668001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000084a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431ecaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31300021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00021d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001a41, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43b02f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56f00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8813247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x950001fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aec0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a40006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de6000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10e40008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2110003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10ff9e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0245301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0121fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29108eff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0127ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0131fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd2400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0180003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd1c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a8089a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000089e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800008fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000945, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000945, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31300022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2738000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc79d3300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc7a13301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8393300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce793301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x964012a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c028009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800008d2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x242c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02620c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2f0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800008d2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdf93300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce393301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000903, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31240022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ec30011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32f80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x67180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bfc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd981325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000915, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c1325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fff6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f818001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001606, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d838001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16240014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a2801f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2a000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00075e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f40014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33e80010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680ffec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a80948, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000094c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000099b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2738000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc79d3300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc7a13301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8393300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce793301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x964011fe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c028009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000978, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x242c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2f0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000978, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdf93300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce393301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dda801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e838011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001802, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x469c0390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0014df, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31280014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8802ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800062, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31280034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a809e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a45, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a59, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a59, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a70250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e72401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04383000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b38007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33b40003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4598001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002eb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002ed, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04382000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001715, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04382000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffbc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431ecaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a55, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x233c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49302ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5198001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53b8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7db9801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01106, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e02, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c010fd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce4c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x58e801fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc01e2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e5c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x44cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55900020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x44cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd812e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd012e02, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd412e03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1e64001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ab1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a0010ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd880003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc010ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d403f7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0cc009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41b0367, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d958004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d85800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280adc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000af1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000adf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ae7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000ace, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8d2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d803f7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc010ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0cc009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11940014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29544001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29544003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000af4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd44d2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd44dc000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000ace, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8d2c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000b0a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd44d2c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28148004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4593240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0105e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef3400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14e80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a8000af, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a01fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3620005c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2464003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6290ce7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16ac001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ee6c00d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000367, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640102e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a00035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16f8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc035f0ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e764009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19b401f8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ae4003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000b7c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a4003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc01e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dbd800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d98ff15, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x592c00fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12e00016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x592c007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12e00015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1620000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12e4001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5924007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a4003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00fdb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780f5ca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001b6d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d324e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431324d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x269c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e4004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f67000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f674002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab42010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab8c006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a8000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000bec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000b47, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b34060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a8004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18580037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x262001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d54001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd280200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd680208, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcda80210, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6930200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6970208, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc69b0210, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd900003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd940003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14fc0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24f800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d83c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4093249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1888003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419324c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1598001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d80011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x321c0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580ffee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c30, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9480000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800f29, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800f23, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800f1a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600f502, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0f500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000f05, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1f30001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16e4001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640f4f4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40f4f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00ac005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28884900, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ff3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400ee1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c40a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c40c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c40d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d0007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15580010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x255400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c411, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c40f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c40e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c410, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c414, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c415, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c413, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c412, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c030011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c038011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431c417, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435c416, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c419, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc418, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf413261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13263, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813264, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc0030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d77000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000cd6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51b80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f97801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000cd6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ca7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc0031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435c40b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000cf4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc032800b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d42011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800e6c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x596001fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce0c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x505c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50600020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x122c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d1f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x566c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x566c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d57, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0328009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04143000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e51001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d2d0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19640057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19580213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19600199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da6400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04142000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d80034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280d83, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c424001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d8a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d95, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000db1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d95, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000dbc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11540010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e010001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d75400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4610000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x526c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2ec01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5ae0073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea2800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3c6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc3a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fff5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01c405, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd441c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3b1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c409, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11540010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4610000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3a5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00da7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5aac007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12d80017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e82400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e58c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19d4003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28182002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc011000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c908009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20880188, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20240090, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1624001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0001a2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1910003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2220003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2a000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e8000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80e71, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000edd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e91, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e91, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ea1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000eaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e7c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e7f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e7f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e87, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e8f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9e001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213264, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253263, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e82005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x59a001fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea2800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421c401, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c401, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2580, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac260c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0828, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2440, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0093, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ede, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac7c06, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db07c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc337, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc335, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c336, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acec70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5a10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5a50000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280eea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ef1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000efe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f11, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f2e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000efe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f1f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f26f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7daec01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5af8073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eba800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f25c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c405, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f24e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c409, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40f247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2580, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac260c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0828, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2440, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0093, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ef2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac7c06, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db07c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc337, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc335, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c336, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acec70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ef1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c1325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c034001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c038001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e0007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f88, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e52401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ac0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26f0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af000fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1334000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e02000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f63400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f9d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51e40020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ac0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26f0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af000fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13380016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e0007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1220001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31140005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31140006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280fb7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28140002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fc2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fd1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ff2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ff2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52a8003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d69401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140004b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d958004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x159c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31a00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31a40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e25800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0fff5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc011000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33b40003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0340008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c908009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c2002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x208801a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20240030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x507c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7d401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x557c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28342002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000102f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1cccfe08, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00b33, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da2400f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da28002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1ac002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d2ac002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3ef40010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40f11d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdcc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xddc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c024001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100086, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5510003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001075, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d520002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cde0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e20001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001071, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00b01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc40003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a400e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12500009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x248c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x200c006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x200c0228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18881fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d4072c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc00d1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3094000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x38d80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x311c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30940007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1620001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a00030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010cb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010cb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000aac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434002e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2020002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07a810d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000104c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x200c007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192400fd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06681110, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19180070, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19100078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f40058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5978073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001117, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001118, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000112d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001130, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001133, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ec0f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32ec0600, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ec0f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32ec0600, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e8e8009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22a8003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22a80074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2774001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eb6800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25ecffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55700020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15f40010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x275c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc1c01e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e40008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc2001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e40008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e62000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da58001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001165, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc2001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e0d000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e02401e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05d80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc2401e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da58001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da2000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600ffe6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22640435, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0528117e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x312c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001185, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001182, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001182, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a0400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1198001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d81c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de2c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011a3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d654001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c020001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2730003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3b380006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3f38000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0430000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb10004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e57000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e578002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d67c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0be40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d3a4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e640010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434002e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07a811cf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00feb8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x954009a7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f0012f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f40612, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc00c1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39600004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0140004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11600001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a6c003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab00030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aac0fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001205, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11600001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a2800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03ae000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03ae000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30d00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640090f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1514001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19180038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d324e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431324d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab0c006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000127f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab0c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e624004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f67800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab42010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a8000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1514001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0012e1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x964008d7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9800036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012aa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b34060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a8002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7edec00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1858003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0cc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0006c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d407f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d190004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d5d4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d52000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d514002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d958001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd5c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ccc001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd980003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9800040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33f80003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800051, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b74003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50700020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04e81324, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50600020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30e40004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d71401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x596401fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b74008d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a640000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000132c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000133b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001344, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42530b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a68003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2024003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d19000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de6800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de6800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffe0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28182002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20240030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x507c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30e40004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7d401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x557c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28342002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c007eb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0d001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x591c01fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45140210, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x595801fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1624001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a307fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x23304076, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4514020c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a2001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a204001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a64003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15dc000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dcdc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5dc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0434001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x248dfffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc12e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc812e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45140248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0434000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdb000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0337fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f220009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d01c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f01c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd240001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19682011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5a6c01fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eeac00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aec0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf830000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfa0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540073d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18c80066, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd910000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4220000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e80007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ec0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5310000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001465, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f02011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5aec01fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aec0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a8146a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1f0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001478, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001478, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f334002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e024001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000144a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fbfc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd910000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800014a9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0328007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b380057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b340213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c424001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c428001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c42c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c430001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a0800fd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x109c000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce080228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9880000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ec75, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52a80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80288, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf080290, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0802a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4802a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc802b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80802b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x178c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf8c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8802c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc802c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8802d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8802d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25b8ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd2800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5230309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e3a400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001539, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd08034b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd880353, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b0353, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd14005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000154f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd08034b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd900309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8100319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340801, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd910ce7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4190ce6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d918005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d918004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd810ce6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdd1054f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000156e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x090c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdcd050e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x110c0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc480329, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc48032a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc4802e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f02e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09940001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x44100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x69100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000157f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970290, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b0288, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f0298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dcdc002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d924019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d26400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001579, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d010021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d914019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd480298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8802a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10d40010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12180016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc51f0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d95800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d62000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdd00309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce113320, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f02e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc01e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015aa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a302b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab02a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4c0319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d8002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea14005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015bc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e624004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d25000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0d3330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0802b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8802b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab02e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa807f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f02d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49702d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f02c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d4e000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d964002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d694001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cde4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de94001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd64002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d694001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015cd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d698002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd4802d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x129c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc50f0319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a0000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1198000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd953300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e0e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a8000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce953301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce100319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b70280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x536c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780eb68, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001609, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30b40000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b70258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53780020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb3801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7faf8019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x67b40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bb0260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fab8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf880260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66f40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7f4009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fff7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x269c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a00018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a00060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x269c0018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a40060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de5c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b70228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f514005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001644, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f130005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001688, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340801, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f130004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01051e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d051f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ed2c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01051f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5170309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195c07f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x196007f6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x6b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001665, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a702a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab0298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f634014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56680020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8113320, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8802a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5170319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b702b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x255c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f5f4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8113330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4802b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195c07e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x196007ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8353300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8353301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4802d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8100309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8100319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x64d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580005c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc24001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd2000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df5c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800016f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a700064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800016df, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800016f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff9c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc0064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00042, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b380057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b340213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f4001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192807fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf0258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a70250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53fc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e7e401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x667c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eebc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x43300007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7db30011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03ec005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfca200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192807fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1d0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2110007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x203c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0017f5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc01e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00185b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffd5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ea24, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d4001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d52400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f0258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a30250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d534002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dae4005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32e0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000174f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00178a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40fff3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab0268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7daa4005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32a0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001765, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1d0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2110007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0017f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b3034b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f13000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001855, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32a4001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd080260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ffc0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ec28001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32e0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e72400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680fff7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa4003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32680003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa400e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017e2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc027ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2e6400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a4009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e403e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26680003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e40064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a40005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce412082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a40005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce412082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea64002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4292083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2024007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a70280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab0278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae8014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56680020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017fe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017fe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43b02eb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42302ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x47b8020c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1220000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a206032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x513c001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e3e001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000180f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b3c0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd200000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc30001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc413248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33fc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bfc0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd441326a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x173c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3f0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001842, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x23fc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf830000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd441326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1fb8ffc6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xddc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001852, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001878, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001878, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41f02ed, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42302ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2a0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x313c0bcc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x393c051f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d3c050e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x393c0560, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d3c054f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x393c1538, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d3c1537, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e8007c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c42c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a8189a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800018c5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800018f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09240002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a24002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2020002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1198001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd8c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5978073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bb80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600e8a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640e8a5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800018a9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc55b0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d5c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dad800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffd2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x442c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df9c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c13260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940fff1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26240007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940fff7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc023007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e4003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dee000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c13260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x261c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06281911, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f4001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001915, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800019af, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a2b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc48032b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc480333, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc48033b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc480343, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98800011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46640400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04203000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b3c0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b200213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e3e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a1c003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00065, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800062, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x43bc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fcbc001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc7df032b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1fc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0101, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001994, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001982, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffcb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001995, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x41bc0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53fc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e7fc011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x653c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dbd8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff8f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc55b0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d5c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200101, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc24001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df9c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a70003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a21, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f270009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x266400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16700005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a0f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16700005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e730002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4252083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x267000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a22, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff9f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001a31, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46640400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04203000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b180057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b200213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1a000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200101, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30f00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800056, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001aa2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a90, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001aa3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4664001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff9c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x244c00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc4c0200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc44f0200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d158010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x059cc000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccdd0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500e69a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0120840, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c0040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001ae8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0121841, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940e66b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00047, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d003ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d47fea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d87ff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40004e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c405, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x295c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c1325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4110000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0160800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0164010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400048, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c40a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901c40d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c410, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c40e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c40f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140096, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411c401, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c40c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0180034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c411, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841c414, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c412, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2468000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419c416, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x41980003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dda0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c40c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901c411, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c412, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce292e40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e02, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc120000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31144000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc3c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33f80003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780e601, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x188cfff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04e40002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b74, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x54106500, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0x7e000200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e020204, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00a0505, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf8c007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8900904, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8911a04, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8920304, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8930b44, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921c0d0c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921c1c13, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921d0c12, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x811c1d1c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x811c111c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921cff1c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921dff10, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x81181d1c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e040218, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x54106900, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0x7e080200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e100204, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbefc00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24200087, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x262200ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000001f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20222282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28182111, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x54116f00, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54116f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb454105e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54117300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4541065, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54117700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4541069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000444, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000008a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54117b00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54116f00, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000005, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54117300, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000006, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54117700, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000007, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54117b00, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000104, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000204, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000304, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000404, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000504, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000604, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000704, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000005, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000105, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000205, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000305, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000405, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000505, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000605, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000705, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000006, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000106, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000206, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000306, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000406, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000506, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000606, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000706, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000007, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000107, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000207, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000307, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000407, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000507, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000607, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000707, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000008, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000108, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000208, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000308, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000408, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000508, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000608, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000708, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000009, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000109, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000209, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000309, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000409, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000509, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000609, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000709, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x01010101, mmCP_PQ_WPTR_POLL_CNTL1 }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdEnd, 0x00000000, 0x00000000 }, + { 0x00000000, mmMC_VM_AGP_BASE }, + { 0x00000002, mmMC_VM_AGP_BOT }, + { 0x00000000, mmMC_VM_AGP_TOP },*/ + { 0x04000000, mmATC_VM_APERTURE0_LOW_ADDR }, + { 0x0400ff20, mmATC_VM_APERTURE0_HIGH_ADDR }, + { 0x00000002, mmATC_VM_APERTURE0_CNTL }, + { 0x0000ffff, mmATC_VM_APERTURE0_CNTL2 }, + { 0x00000001, mmATC_VM_APERTURE1_LOW_ADDR }, + { 0x00000000, mmATC_VM_APERTURE1_HIGH_ADDR }, + { 0x00000000, mmATC_VM_APERTURE1_CNTL }, + { 0x00000000, mmATC_VM_APERTURE1_CNTL2 }, + //{ 0x00000000, mmMC_ARB_RAMCFG }, + { 0x12011003, mmGB_ADDR_CONFIG }, + { 0x00800010, mmGB_TILE_MODE0 }, + { 0x00800810, mmGB_TILE_MODE1 }, + { 0x00801010, mmGB_TILE_MODE2 }, + { 0x00801810, mmGB_TILE_MODE3 }, + { 0x00802810, mmGB_TILE_MODE4 }, + { 0x00802808, mmGB_TILE_MODE5 }, + { 0x00802814, mmGB_TILE_MODE6 }, + { 0x00000000, mmGB_TILE_MODE7 }, + { 0x00000004, mmGB_TILE_MODE8 }, + { 0x02000008, mmGB_TILE_MODE9 }, + { 0x02000010, mmGB_TILE_MODE10 }, + { 0x06000014, mmGB_TILE_MODE11 }, + { 0x00000000, mmGB_TILE_MODE12 }, + { 0x02400008, mmGB_TILE_MODE13 }, + { 0x02400010, mmGB_TILE_MODE14 }, + { 0x02400030, mmGB_TILE_MODE15 }, + { 0x06400014, mmGB_TILE_MODE16 }, + { 0x00000000, mmGB_TILE_MODE17 }, + { 0x0040000c, mmGB_TILE_MODE18 }, + { 0x0100000c, mmGB_TILE_MODE19 }, + { 0x0100001c, mmGB_TILE_MODE20 }, + { 0x01000034, mmGB_TILE_MODE21 }, + { 0x01000024, mmGB_TILE_MODE22 }, + { 0x00000000, mmGB_TILE_MODE23 }, + { 0x0040001c, mmGB_TILE_MODE24 }, + { 0x01000020, mmGB_TILE_MODE25 }, + { 0x01000038, mmGB_TILE_MODE26 }, + { 0x02c00008, mmGB_TILE_MODE27 }, + { 0x02c00010, mmGB_TILE_MODE28 }, + { 0x06c00014, mmGB_TILE_MODE29 }, + { 0x00000000, mmGB_TILE_MODE30 }, + { 0x00000000, mmGB_TILE_MODE31 }, + { 0x000000a8, mmGB_MACROTILE_MODE0 }, + { 0x000000a4, mmGB_MACROTILE_MODE1 }, + { 0x00000090, mmGB_MACROTILE_MODE2 }, + { 0x00000090, mmGB_MACROTILE_MODE3 }, + { 0x00000090, mmGB_MACROTILE_MODE4 }, + { 0x00000090, mmGB_MACROTILE_MODE5 }, + { 0x00000090, mmGB_MACROTILE_MODE6 }, + { 0x00000000, mmGB_MACROTILE_MODE7 }, + { 0x000000ee, mmGB_MACROTILE_MODE8 }, + { 0x000000ea, mmGB_MACROTILE_MODE9 }, + { 0x000000e9, mmGB_MACROTILE_MODE10 }, + { 0x000000e5, mmGB_MACROTILE_MODE11 }, + { 0x000000e4, mmGB_MACROTILE_MODE12 }, + { 0x000000e0, mmGB_MACROTILE_MODE13 }, + { 0x00000090, mmGB_MACROTILE_MODE14 }, + { 0x00000000, mmGB_MACROTILE_MODE15 }, + { 0x00900000, mmHDP_NONSURFACE_BASE }, + { 0x00008000, mmHDP_NONSURFACE_INFO }, + { 0x3fffffff, mmHDP_NONSURFACE_SIZE }, + { 0x00000003, mmBIF_FB_EN }, + //{ 0x00000000, mmMC_VM_FB_OFFSET }, + { 0x00000000, mmSRBM_CNTL }, + { 0x00020000, mmSRBM_CNTL }, + { 0x80000000, mmATC_VMID0_PASID_MAPPING }, + { 0x00000000, mmATC_VMID_PASID_MAPPING_UPDATE_STATUS }, + { 0x00000000, mmRLC_CNTL }, + { 0x00000000, mmRLC_CNTL }, + { 0x00000000, mmRLC_CNTL }, + { 0xe0000000, mmGRBM_GFX_INDEX }, + { 0x00000000, mmCGTS_TCC_DISABLE }, + { 0x00000000, mmTCP_ADDR_CONFIG }, + { 0x000000ff, mmTCP_ADDR_CONFIG }, + { 0x76543210, mmTCP_CHAN_STEER_LO }, + { 0xfedcba98, mmTCP_CHAN_STEER_HI }, + { 0x00000000, mmDB_DEBUG2 }, + { 0x00000000, mmDB_DEBUG }, + { 0x00002b16, mmCP_QUEUE_THRESHOLDS }, + { 0x00006030, mmCP_MEQ_THRESHOLDS }, + { 0x01000104, mmSPI_CONFIG_CNTL_1 }, + { 0x98184020, mmPA_SC_FIFO_SIZE }, + { 0x00000001, mmVGT_NUM_INSTANCES }, + { 0x00000000, mmCP_PERFMON_CNTL }, + { 0x01180000, mmSQ_CONFIG }, + { 0x00000000, mmVGT_CACHE_INVALIDATION }, + { 0x00000000, mmSQ_THREAD_TRACE_BASE }, + { 0x0000df80, mmSQ_THREAD_TRACE_MASK }, + { 0x02249249, mmSQ_THREAD_TRACE_MODE }, + { 0x00000000, mmPA_SC_LINE_STIPPLE_STATE }, + { 0x00000000, mmCB_PERFCOUNTER0_SELECT1 }, + { 0x06000100, mmCGTT_VGT_CLK_CTRL }, + { 0x00000007, mmPA_CL_ENHANCE }, + { 0x00000001, mmPA_SC_ENHANCE }, + { 0x00ffffff, mmPA_SC_FORCE_EOV_MAX_CNTS }, + { 0x00000000, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000010, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000020, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000030, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000040, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000050, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000060, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000070, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000080, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000090, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x000000a0, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x000000b0, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x000000c0, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x000000d0, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x000000e0, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x000000f0, mmSRBM_GFX_CNTL }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000000, mmSRBM_GFX_CNTL }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmRLC_PG_CNTL }, + { 0x00000000, mmGRBM_STATUS2 }, + { 0x15000000, mmCP_ME_CNTL }, + { 0x50000000, mmCP_MEC_CNTL }, + { 0x00000000, mmSRBM_GFX_CNTL }, + { 0x0000000e, mmSH_MEM_APE1_BASE }, + { 0x0000020d, mmSH_MEM_APE1_LIMIT }, + { 0x00000000, mmSRBM_GFX_CNTL }, + { 0x00000000, mmSRBM_GFX_CNTL }, + { 0x00000000, mmSH_MEM_CONFIG }, + { 0x00000320, mmSH_MEM_CONFIG }, + { 0x00000000, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_RB_VMID }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmRLC_CNTL }, + { 0x00000000, mmRLC_CNTL }, + { 0x00000000, mmRLC_SRM_CNTL }, + { 0x00000002, mmRLC_SRM_CNTL }, + { 0x00000000, mmCP_ME_CNTL }, + { 0x15000000, mmCP_ME_CNTL }, + { 0x00000000, mmCP_MEC_CNTL }, + { 0x50000000, mmCP_MEC_CNTL }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x0840800a, mmCP_RB0_CNTL }, + { 0xf30fff0f, mmTCC_CTRL }, + { 0x00000002, mmTCC_EXE_DISABLE }, + { 0x000000ff, mmTCP_ADDR_CONFIG }, + { 0x540ff000, mmCP_CPC_IC_BASE_LO }, + { 0x000000b4, mmCP_CPC_IC_BASE_HI }, + { 0x00010000, mmCP_HYP_MEC1_UCODE_ADDR }, + { 0x00041b75, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000710e8, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000910dd, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000a1081, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000b016f, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000c0e3c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000d10ec, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000e0188, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00101b5d, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00150a6c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00170c5e, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x001d0c8c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x001e0cfe, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00221408, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00370d7b, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00390dcb, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x003c142f, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x003f0b27, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00400e63, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00500f62, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00460fa7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00490fa7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x005811d4, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00680ad6, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00760b00, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00780b0c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00790af7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x007d1aba, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x007e1abe, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00591260, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x005a12fb, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00861ac7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x008c1b01, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x008d1b34, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a014b9, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a1152e, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a216fb, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a41890, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a31906, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a50b14, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00621387, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x005c0b27, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00160a75, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00010000, mmCP_HYP_MEC2_UCODE_ADDR }, + { 0x00041b75, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000710e8, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000910dd, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000a1081, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000b016f, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000c0e3c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000d10ec, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000e0188, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00101b5d, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00150a6c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00170c5e, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x001d0c8c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x001e0cfe, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00221408, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00370d7b, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00390dcb, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x003c142f, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x003f0b27, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00400e63, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00500f62, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00460fa7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00490fa7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x005811d4, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00680ad6, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00760b00, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00780b0c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00790af7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x007d1aba, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x007e1abe, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00591260, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x005a12fb, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00861ac7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x008c1b01, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x008d1b34, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a014b9, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a1152e, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a216fb, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a41890, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a31906, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a50b14, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00621387, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x005c0b27, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00160a75, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x540fe800, mmCP_DFY_ADDR_LO }, + { 0x7e000200, mmCP_DFY_DATA_0 }, + { 0x7e020201, mmCP_DFY_DATA_0 }, + { 0x7e040204, mmCP_DFY_DATA_0 }, + { 0x7e060205, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000005, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54106f00, mmCP_DFY_DATA_0 }, + { 0x000400b4, mmCP_DFY_DATA_0 }, + { 0x00004000, mmCP_DFY_DATA_0 }, + { 0x00804fac, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x540fef00, mmCP_DFY_ADDR_LO }, + { 0xc0031502, mmCP_DFY_DATA_0 }, + { 0x00001e00, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x540ff000, mmCP_DFY_ADDR_LO }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x80000145, mmCP_DFY_DATA_0 }, + { 0x94800001, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0x95400001, mmCP_DFY_DATA_0 }, + { 0x95800001, mmCP_DFY_DATA_0 }, + { 0xdc810000, mmCP_DFY_DATA_0 }, + { 0xdcc10000, mmCP_DFY_DATA_0 }, + { 0xdd010000, mmCP_DFY_DATA_0 }, + { 0xdd410000, mmCP_DFY_DATA_0 }, + { 0xdd810000, mmCP_DFY_DATA_0 }, + { 0xc4080061, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8000003, mmCP_DFY_DATA_0 }, + { 0xc40c0001, mmCP_DFY_DATA_0 }, + { 0x24ccffff, mmCP_DFY_DATA_0 }, + { 0x3cd08000, mmCP_DFY_DATA_0 }, + { 0x9500fffd, mmCP_DFY_DATA_0 }, + { 0x1cd0ffcf, mmCP_DFY_DATA_0 }, + { 0x7d018001, mmCP_DFY_DATA_0 }, + { 0xc4140004, mmCP_DFY_DATA_0 }, + { 0x050c0019, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x84c00000, mmCP_DFY_DATA_0 }, + { 0x80000023, mmCP_DFY_DATA_0 }, + { 0x80000067, mmCP_DFY_DATA_0 }, + { 0x8000006a, mmCP_DFY_DATA_0 }, + { 0x8000006d, mmCP_DFY_DATA_0 }, + { 0x80000079, mmCP_DFY_DATA_0 }, + { 0x80000084, mmCP_DFY_DATA_0 }, + { 0x8000008f, mmCP_DFY_DATA_0 }, + { 0x80000099, mmCP_DFY_DATA_0 }, + { 0x800000a0, mmCP_DFY_DATA_0 }, + { 0x800000af, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0xc4080007, mmCP_DFY_DATA_0 }, + { 0x388c0001, mmCP_DFY_DATA_0 }, + { 0x08880002, mmCP_DFY_DATA_0 }, + { 0x04100003, mmCP_DFY_DATA_0 }, + { 0x94c00005, mmCP_DFY_DATA_0 }, + { 0x98800003, mmCP_DFY_DATA_0 }, + { 0x04100004, mmCP_DFY_DATA_0 }, + { 0x8000002d, mmCP_DFY_DATA_0 }, + { 0x04100005, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0000, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x28080001, mmCP_DFY_DATA_0 }, + { 0xcc000004, mmCP_DFY_DATA_0 }, + { 0x7d808001, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0xcc800005, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcd013278, mmCP_DFY_DATA_0 }, + { 0xc4113278, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0x24cc0700, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc4113255, mmCP_DFY_DATA_0 }, + { 0xcd01324f, mmCP_DFY_DATA_0 }, + { 0xc4113254, mmCP_DFY_DATA_0 }, + { 0x1d10ffdf, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0x10cc0014, mmCP_DFY_DATA_0 }, + { 0x1d10c017, mmCP_DFY_DATA_0 }, + { 0x7d0d000a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd0130b7, mmCP_DFY_DATA_0 }, + { 0x14cc0010, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0x8000005d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14d00011, mmCP_DFY_DATA_0 }, + { 0x9500fffe, mmCP_DFY_DATA_0 }, + { 0xdc030000, mmCP_DFY_DATA_0 }, + { 0xd800000c, mmCP_DFY_DATA_0 }, + { 0xd800000d, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01b10, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc00e0080, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0xc00e0800, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0x04100006, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0000, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x280c0008, mmCP_DFY_DATA_0 }, + { 0xccc00052, mmCP_DFY_DATA_0 }, + { 0xd8000021, mmCP_DFY_DATA_0 }, + { 0x28180039, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0x04100007, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0001, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x280c0010, mmCP_DFY_DATA_0 }, + { 0xccc00052, mmCP_DFY_DATA_0 }, + { 0x28180039, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0x04100008, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0003, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x280c0020, mmCP_DFY_DATA_0 }, + { 0xccc00052, mmCP_DFY_DATA_0 }, + { 0x28180039, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0xdc030000, mmCP_DFY_DATA_0 }, + { 0xd8000069, mmCP_DFY_DATA_0 }, + { 0x28080001, mmCP_DFY_DATA_0 }, + { 0xc428000d, mmCP_DFY_DATA_0 }, + { 0x7ca88004, mmCP_DFY_DATA_0 }, + { 0xcc800079, mmCP_DFY_DATA_0 }, + { 0x04280001, mmCP_DFY_DATA_0 }, + { 0xcc00006f, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0x04100010, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0xccc00078, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x28180080, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xcd013278, mmCP_DFY_DATA_0 }, + { 0xc4113278, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0xc4113254, mmCP_DFY_DATA_0 }, + { 0x1d10c017, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0xcd0130b7, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0x95c00001, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0x96400001, mmCP_DFY_DATA_0 }, + { 0x96800001, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x97400001, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x97c00001, mmCP_DFY_DATA_0 }, + { 0xdc810000, mmCP_DFY_DATA_0 }, + { 0xc40c000c, mmCP_DFY_DATA_0 }, + { 0xcd4c0380, mmCP_DFY_DATA_0 }, + { 0xcdcc0388, mmCP_DFY_DATA_0 }, + { 0x55dc0020, mmCP_DFY_DATA_0 }, + { 0xcdcc038c, mmCP_DFY_DATA_0 }, + { 0xce0c0390, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce0c0394, mmCP_DFY_DATA_0 }, + { 0xce4c0398, mmCP_DFY_DATA_0 }, + { 0x56640020, mmCP_DFY_DATA_0 }, + { 0xce4c039c, mmCP_DFY_DATA_0 }, + { 0xce8c03a0, mmCP_DFY_DATA_0 }, + { 0x56a80020, mmCP_DFY_DATA_0 }, + { 0xce8c03a4, mmCP_DFY_DATA_0 }, + { 0xcecc03a8, mmCP_DFY_DATA_0 }, + { 0x56ec0020, mmCP_DFY_DATA_0 }, + { 0xcecc03ac, mmCP_DFY_DATA_0 }, + { 0xcf0c03b0, mmCP_DFY_DATA_0 }, + { 0x57300020, mmCP_DFY_DATA_0 }, + { 0xcf0c03b4, mmCP_DFY_DATA_0 }, + { 0xcf4c03b8, mmCP_DFY_DATA_0 }, + { 0x57740020, mmCP_DFY_DATA_0 }, + { 0xcf4c03bc, mmCP_DFY_DATA_0 }, + { 0xcf8c03c0, mmCP_DFY_DATA_0 }, + { 0x57b80020, mmCP_DFY_DATA_0 }, + { 0xcf8c03c4, mmCP_DFY_DATA_0 }, + { 0xcfcc03c8, mmCP_DFY_DATA_0 }, + { 0x57fc0020, mmCP_DFY_DATA_0 }, + { 0xcfcc03cc, mmCP_DFY_DATA_0 }, + { 0xd9000033, mmCP_DFY_DATA_0 }, + { 0xc41c0009, mmCP_DFY_DATA_0 }, + { 0x25dc0010, mmCP_DFY_DATA_0 }, + { 0x95c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc41c000c, mmCP_DFY_DATA_0 }, + { 0x05dc002f, mmCP_DFY_DATA_0 }, + { 0xcdc12009, mmCP_DFY_DATA_0 }, + { 0xc41d200a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc012009, mmCP_DFY_DATA_0 }, + { 0xd9000034, mmCP_DFY_DATA_0 }, + { 0x25e01c00, mmCP_DFY_DATA_0 }, + { 0x12200013, mmCP_DFY_DATA_0 }, + { 0x25e40300, mmCP_DFY_DATA_0 }, + { 0x12640008, mmCP_DFY_DATA_0 }, + { 0x25e800c0, mmCP_DFY_DATA_0 }, + { 0x12a80002, mmCP_DFY_DATA_0 }, + { 0x25ec003f, mmCP_DFY_DATA_0 }, + { 0x7e25c00a, mmCP_DFY_DATA_0 }, + { 0x7eae400a, mmCP_DFY_DATA_0 }, + { 0x7de5c00a, mmCP_DFY_DATA_0 }, + { 0xddc10000, mmCP_DFY_DATA_0 }, + { 0xc02ee000, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0xc40c005f, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x24d000ff, mmCP_DFY_DATA_0 }, + { 0x31100006, mmCP_DFY_DATA_0 }, + { 0x9500007b, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xdc1c0000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1c200, mmCP_DFY_DATA_0 }, + { 0xc40c000c, mmCP_DFY_DATA_0 }, + { 0xc4df0388, mmCP_DFY_DATA_0 }, + { 0xc4d7038c, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d5dc01a, mmCP_DFY_DATA_0 }, + { 0xc4e30390, mmCP_DFY_DATA_0 }, + { 0xc4d70394, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d62001a, mmCP_DFY_DATA_0 }, + { 0xc4e70398, mmCP_DFY_DATA_0 }, + { 0xc4d7039c, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d66401a, mmCP_DFY_DATA_0 }, + { 0xc4eb03a0, mmCP_DFY_DATA_0 }, + { 0xc4d703a4, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d6a801a, mmCP_DFY_DATA_0 }, + { 0xc4ef03a8, mmCP_DFY_DATA_0 }, + { 0xc4d703ac, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d6ec01a, mmCP_DFY_DATA_0 }, + { 0xc4f303b0, mmCP_DFY_DATA_0 }, + { 0xc4d703b4, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d73001a, mmCP_DFY_DATA_0 }, + { 0xc4f703b8, mmCP_DFY_DATA_0 }, + { 0xc4d703bc, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d77401a, mmCP_DFY_DATA_0 }, + { 0xc4fb03c0, mmCP_DFY_DATA_0 }, + { 0xc4d703c4, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d7b801a, mmCP_DFY_DATA_0 }, + { 0xc4ff03c8, mmCP_DFY_DATA_0 }, + { 0xc4d703cc, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d7fc01a, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0xcc800013, mmCP_DFY_DATA_0 }, + { 0xc4d70380, mmCP_DFY_DATA_0 }, + { 0xc4080001, mmCP_DFY_DATA_0 }, + { 0x1c88001c, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0xc40c0083, mmCP_DFY_DATA_0 }, + { 0x94c00010, mmCP_DFY_DATA_0 }, + { 0xdc0e0000, mmCP_DFY_DATA_0 }, + { 0x94c0000e, mmCP_DFY_DATA_0 }, + { 0xc40c0082, mmCP_DFY_DATA_0 }, + { 0x24d00001, mmCP_DFY_DATA_0 }, + { 0x9900000b, mmCP_DFY_DATA_0 }, + { 0x18cc01e3, mmCP_DFY_DATA_0 }, + { 0x3cd00004, mmCP_DFY_DATA_0 }, + { 0x95000008, mmCP_DFY_DATA_0 }, + { 0xc40c0085, mmCP_DFY_DATA_0 }, + { 0x18cc006a, mmCP_DFY_DATA_0 }, + { 0x98c00005, mmCP_DFY_DATA_0 }, + { 0xc40c0082, mmCP_DFY_DATA_0 }, + { 0x18cc01e3, mmCP_DFY_DATA_0 }, + { 0x3cd00004, mmCP_DFY_DATA_0 }, + { 0x9900fffa, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0xcc800004, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4080001, mmCP_DFY_DATA_0 }, + { 0x1c88001c, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0xcc800004, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400051, mmCP_DFY_DATA_0 }, + { 0xc428000c, mmCP_DFY_DATA_0 }, + { 0x04180018, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a80001f, mmCP_DFY_DATA_0 }, + { 0x9a40001e, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4293265, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x1aac0027, mmCP_DFY_DATA_0 }, + { 0x2aa80080, mmCP_DFY_DATA_0 }, + { 0xce813265, mmCP_DFY_DATA_0 }, + { 0x9ac00017, mmCP_DFY_DATA_0 }, + { 0xd80002f1, mmCP_DFY_DATA_0 }, + { 0x04080002, mmCP_DFY_DATA_0 }, + { 0x08880001, mmCP_DFY_DATA_0 }, + { 0xd8080250, mmCP_DFY_DATA_0 }, + { 0xd8080258, mmCP_DFY_DATA_0 }, + { 0xd8080230, mmCP_DFY_DATA_0 }, + { 0xd8080238, mmCP_DFY_DATA_0 }, + { 0xd8080240, mmCP_DFY_DATA_0 }, + { 0xd8080248, mmCP_DFY_DATA_0 }, + { 0xd8080268, mmCP_DFY_DATA_0 }, + { 0xd8080270, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0xd8080228, mmCP_DFY_DATA_0 }, + { 0xd8000367, mmCP_DFY_DATA_0 }, + { 0x9880fff3, mmCP_DFY_DATA_0 }, + { 0x04080010, mmCP_DFY_DATA_0 }, + { 0x08880001, mmCP_DFY_DATA_0 }, + { 0xd80c0309, mmCP_DFY_DATA_0 }, + { 0xd80c0319, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x9880fffc, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc00e0100, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8000016e, mmCP_DFY_DATA_0 }, + { 0xc4180032, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x95800001, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d0003f, mmCP_DFY_DATA_0 }, + { 0x24d4001f, mmCP_DFY_DATA_0 }, + { 0x24d80001, mmCP_DFY_DATA_0 }, + { 0x155c0001, mmCP_DFY_DATA_0 }, + { 0x05e80180, mmCP_DFY_DATA_0 }, + { 0x9900000b, mmCP_DFY_DATA_0 }, + { 0x202c003d, mmCP_DFY_DATA_0 }, + { 0xcd800010, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0xc42d325b, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0x80000bfc, mmCP_DFY_DATA_0 }, + { 0x800012e9, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xc410001b, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0xd8000031, mmCP_DFY_DATA_0 }, + { 0x9900091a, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x24d000ff, mmCP_DFY_DATA_0 }, + { 0x05280196, mmCP_DFY_DATA_0 }, + { 0x18d4fe04, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x800001b4, mmCP_DFY_DATA_0 }, + { 0x8000032b, mmCP_DFY_DATA_0 }, + { 0x80000350, mmCP_DFY_DATA_0 }, + { 0x80000352, mmCP_DFY_DATA_0 }, + { 0x8000035f, mmCP_DFY_DATA_0 }, + { 0x80000701, mmCP_DFY_DATA_0 }, + { 0x8000047c, mmCP_DFY_DATA_0 }, + { 0x8000019f, mmCP_DFY_DATA_0 }, + { 0x80000800, mmCP_DFY_DATA_0 }, + { 0xc419325b, mmCP_DFY_DATA_0 }, + { 0x1d98001f, mmCP_DFY_DATA_0 }, + { 0xcd81325b, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0xc4140004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04100002, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0002, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0xc43c0044, mmCP_DFY_DATA_0 }, + { 0x27fc0003, mmCP_DFY_DATA_0 }, + { 0x9bc00002, mmCP_DFY_DATA_0 }, + { 0x97c00006, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x7d40c001, mmCP_DFY_DATA_0 }, + { 0xd8400028, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xd9400036, mmCP_DFY_DATA_0 }, + { 0xc4193256, mmCP_DFY_DATA_0 }, + { 0xc41d3254, mmCP_DFY_DATA_0 }, + { 0x15540008, mmCP_DFY_DATA_0 }, + { 0xcd400009, mmCP_DFY_DATA_0 }, + { 0xcd40005b, mmCP_DFY_DATA_0 }, + { 0xcd40005e, mmCP_DFY_DATA_0 }, + { 0xcd40005d, mmCP_DFY_DATA_0 }, + { 0xd840006d, mmCP_DFY_DATA_0 }, + { 0xc421325a, mmCP_DFY_DATA_0 }, + { 0xc42d3249, mmCP_DFY_DATA_0 }, + { 0x11540015, mmCP_DFY_DATA_0 }, + { 0x19a4003c, mmCP_DFY_DATA_0 }, + { 0x1998003f, mmCP_DFY_DATA_0 }, + { 0x1af0007d, mmCP_DFY_DATA_0 }, + { 0x11dc000b, mmCP_DFY_DATA_0 }, + { 0x1264001f, mmCP_DFY_DATA_0 }, + { 0x15dc000d, mmCP_DFY_DATA_0 }, + { 0x7d65400a, mmCP_DFY_DATA_0 }, + { 0x13300018, mmCP_DFY_DATA_0 }, + { 0x1a38003f, mmCP_DFY_DATA_0 }, + { 0x7dd5c00a, mmCP_DFY_DATA_0 }, + { 0x7df1c00a, mmCP_DFY_DATA_0 }, + { 0xcd800045, mmCP_DFY_DATA_0 }, + { 0xcdc00100, mmCP_DFY_DATA_0 }, + { 0xc411326a, mmCP_DFY_DATA_0 }, + { 0xc415326b, mmCP_DFY_DATA_0 }, + { 0xc419326c, mmCP_DFY_DATA_0 }, + { 0xc41d326d, mmCP_DFY_DATA_0 }, + { 0xc425326e, mmCP_DFY_DATA_0 }, + { 0xc4293279, mmCP_DFY_DATA_0 }, + { 0xce800077, mmCP_DFY_DATA_0 }, + { 0xcd000056, mmCP_DFY_DATA_0 }, + { 0xcd400057, mmCP_DFY_DATA_0 }, + { 0xcd800058, mmCP_DFY_DATA_0 }, + { 0xcdc00059, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x259c8000, mmCP_DFY_DATA_0 }, + { 0x99c00004, mmCP_DFY_DATA_0 }, + { 0xce40005a, mmCP_DFY_DATA_0 }, + { 0x29988000, mmCP_DFY_DATA_0 }, + { 0xcd813265, mmCP_DFY_DATA_0 }, + { 0xc4113248, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0xcd000073, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0xc411326f, mmCP_DFY_DATA_0 }, + { 0x17300019, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x25140fff, mmCP_DFY_DATA_0 }, + { 0x95400007, mmCP_DFY_DATA_0 }, + { 0xd800003a, mmCP_DFY_DATA_0 }, + { 0x8c001b6d, mmCP_DFY_DATA_0 }, + { 0xc4153279, mmCP_DFY_DATA_0 }, + { 0xcd400077, mmCP_DFY_DATA_0 }, + { 0xcd00005f, mmCP_DFY_DATA_0 }, + { 0xd8000075, mmCP_DFY_DATA_0 }, + { 0x26f00001, mmCP_DFY_DATA_0 }, + { 0x15100010, mmCP_DFY_DATA_0 }, + { 0x7d190004, mmCP_DFY_DATA_0 }, + { 0xcd000035, mmCP_DFY_DATA_0 }, + { 0x97000035, mmCP_DFY_DATA_0 }, + { 0x1af07fe8, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcf00000d, mmCP_DFY_DATA_0 }, + { 0xcf00000a, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x04340022, mmCP_DFY_DATA_0 }, + { 0x07740001, mmCP_DFY_DATA_0 }, + { 0x04300010, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0xd4412e01, mmCP_DFY_DATA_0 }, + { 0x0434001e, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xdf030000, mmCP_DFY_DATA_0 }, + { 0xd4412e40, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc41c030, mmCP_DFY_DATA_0 }, + { 0xcc41c031, mmCP_DFY_DATA_0 }, + { 0xc43dc031, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x04343000, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0xcf413267, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7dd1c01a, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0x45dc0160, mmCP_DFY_DATA_0 }, + { 0xc810001f, mmCP_DFY_DATA_0 }, + { 0x1b4c0057, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x7f4f400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x55180020, mmCP_DFY_DATA_0 }, + { 0x2198003f, mmCP_DFY_DATA_0 }, + { 0xd1c00025, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xcd000026, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9bc00001, mmCP_DFY_DATA_0 }, + { 0x248dfffe, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xccc12e00, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x1af4007d, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0x33740003, mmCP_DFY_DATA_0 }, + { 0x26d80001, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x1ae8003e, mmCP_DFY_DATA_0 }, + { 0x9680000c, mmCP_DFY_DATA_0 }, + { 0xc4253277, mmCP_DFY_DATA_0 }, + { 0x26680001, mmCP_DFY_DATA_0 }, + { 0x96800009, mmCP_DFY_DATA_0 }, + { 0x2a640002, mmCP_DFY_DATA_0 }, + { 0xce413277, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc4253348, mmCP_DFY_DATA_0 }, + { 0xce413348, mmCP_DFY_DATA_0 }, + { 0xc4253348, mmCP_DFY_DATA_0 }, + { 0x96400001, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9b400003, mmCP_DFY_DATA_0 }, + { 0x958000d8, mmCP_DFY_DATA_0 }, + { 0x80000315, mmCP_DFY_DATA_0 }, + { 0xc4253277, mmCP_DFY_DATA_0 }, + { 0x04303000, mmCP_DFY_DATA_0 }, + { 0x26680001, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x96800041, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x1714000c, mmCP_DFY_DATA_0 }, + { 0x25540800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x459801b0, mmCP_DFY_DATA_0 }, + { 0x7d77400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x04240010, mmCP_DFY_DATA_0 }, + { 0x199c01e2, mmCP_DFY_DATA_0 }, + { 0x7e5e4002, mmCP_DFY_DATA_0 }, + { 0x3e5c0004, mmCP_DFY_DATA_0 }, + { 0x3e540002, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0x95c00006, mmCP_DFY_DATA_0 }, + { 0xc80c0011, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x54d00020, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0x80000282, mmCP_DFY_DATA_0 }, + { 0x95400015, mmCP_DFY_DATA_0 }, + { 0xc80c0011, mmCP_DFY_DATA_0 }, + { 0x0a640002, mmCP_DFY_DATA_0 }, + { 0x041c0001, mmCP_DFY_DATA_0 }, + { 0x45980008, mmCP_DFY_DATA_0 }, + { 0x54d00020, mmCP_DFY_DATA_0 }, + { 0x96400004, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0x041c0000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0x99c00003, mmCP_DFY_DATA_0 }, + { 0xc8180011, mmCP_DFY_DATA_0 }, + { 0x80000282, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0x80000282, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xc80c0011, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1334e, mmCP_DFY_DATA_0 }, + { 0xcd01334f, mmCP_DFY_DATA_0 }, + { 0xcd413350, mmCP_DFY_DATA_0 }, + { 0xcd813351, mmCP_DFY_DATA_0 }, + { 0xd881334d, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4193273, mmCP_DFY_DATA_0 }, + { 0xc41d3275, mmCP_DFY_DATA_0 }, + { 0xc40d3271, mmCP_DFY_DATA_0 }, + { 0xc4113270, mmCP_DFY_DATA_0 }, + { 0xc4153274, mmCP_DFY_DATA_0 }, + { 0x50cc0020, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0x7cdcc011, mmCP_DFY_DATA_0 }, + { 0x05900008, mmCP_DFY_DATA_0 }, + { 0xcd00006a, mmCP_DFY_DATA_0 }, + { 0xcdc0006b, mmCP_DFY_DATA_0 }, + { 0xc41d3272, mmCP_DFY_DATA_0 }, + { 0x7d594002, mmCP_DFY_DATA_0 }, + { 0x54d00020, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xccc12e23, mmCP_DFY_DATA_0 }, + { 0xcd012e24, mmCP_DFY_DATA_0 }, + { 0xcdc12e25, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x15540002, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x1b340057, mmCP_DFY_DATA_0 }, + { 0x1b280213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x45980198, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x7f2b000a, mmCP_DFY_DATA_0 }, + { 0x55e40020, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcd40000d, mmCP_DFY_DATA_0 }, + { 0xcd40000a, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x20cc003c, mmCP_DFY_DATA_0 }, + { 0xccc13249, mmCP_DFY_DATA_0 }, + { 0xc4113274, mmCP_DFY_DATA_0 }, + { 0xdd430000, mmCP_DFY_DATA_0 }, + { 0xc01e0001, mmCP_DFY_DATA_0 }, + { 0x29dc0002, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0xd8000036, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0x2d540002, mmCP_DFY_DATA_0 }, + { 0x95400022, mmCP_DFY_DATA_0 }, + { 0x078c0000, mmCP_DFY_DATA_0 }, + { 0x07d40000, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001239, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x04f80000, mmCP_DFY_DATA_0 }, + { 0x057c0000, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc414000d, mmCP_DFY_DATA_0 }, + { 0xc41c0019, mmCP_DFY_DATA_0 }, + { 0x7dd5c005, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0xd840007c, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0xd8400069, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c018a6, mmCP_DFY_DATA_0 }, + { 0xd4412e22, mmCP_DFY_DATA_0 }, + { 0xd800007c, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c018a2, mmCP_DFY_DATA_0 }, + { 0x95c00007, mmCP_DFY_DATA_0 }, + { 0xc40c0019, mmCP_DFY_DATA_0 }, + { 0x7cd4c005, mmCP_DFY_DATA_0 }, + { 0x24cc0001, mmCP_DFY_DATA_0 }, + { 0x94c00008, mmCP_DFY_DATA_0 }, + { 0x9680fffc, mmCP_DFY_DATA_0 }, + { 0x800002e3, mmCP_DFY_DATA_0 }, + { 0xc40c0057, mmCP_DFY_DATA_0 }, + { 0x7cd0c002, mmCP_DFY_DATA_0 }, + { 0x94c00003, mmCP_DFY_DATA_0 }, + { 0x9680fffd, mmCP_DFY_DATA_0 }, + { 0x800002e3, mmCP_DFY_DATA_0 }, + { 0xd8000069, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcd013273, mmCP_DFY_DATA_0 }, + { 0xcd013275, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc414005e, mmCP_DFY_DATA_0 }, + { 0x9540188f, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0xc013cfff, mmCP_DFY_DATA_0 }, + { 0x7cd0c009, mmCP_DFY_DATA_0 }, + { 0xccc13249, mmCP_DFY_DATA_0 }, + { 0x9680000b, mmCP_DFY_DATA_0 }, + { 0xc40c0077, mmCP_DFY_DATA_0 }, + { 0x38d00001, mmCP_DFY_DATA_0 }, + { 0x99000006, mmCP_DFY_DATA_0 }, + { 0x04cc0002, mmCP_DFY_DATA_0 }, + { 0xdcc30000, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01882, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd800000d, mmCP_DFY_DATA_0 }, + { 0x80000304, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0xd840002f, mmCP_DFY_DATA_0 }, + { 0xc41c0015, mmCP_DFY_DATA_0 }, + { 0x95c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400030, mmCP_DFY_DATA_0 }, + { 0xc41c0016, mmCP_DFY_DATA_0 }, + { 0x95c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8000030, mmCP_DFY_DATA_0 }, + { 0xc41c0016, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xd800002f, mmCP_DFY_DATA_0 }, + { 0xc41c0015, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x49980198, mmCP_DFY_DATA_0 }, + { 0x55e40020, mmCP_DFY_DATA_0 }, + { 0x459801a0, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x04302000, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x96800004, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0xd8000036, mmCP_DFY_DATA_0 }, + { 0x80000329, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcc812e00, mmCP_DFY_DATA_0 }, + { 0x04302000, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0xc4193256, mmCP_DFY_DATA_0 }, + { 0xc42d3249, mmCP_DFY_DATA_0 }, + { 0x16ec001f, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x1998003e, mmCP_DFY_DATA_0 }, + { 0xcec00031, mmCP_DFY_DATA_0 }, + { 0xd8000036, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0x97800004, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xce00000a, mmCP_DFY_DATA_0 }, + { 0x1a18003e, mmCP_DFY_DATA_0 }, + { 0xcd800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0x7d43c001, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4093249, mmCP_DFY_DATA_0 }, + { 0x1888003e, mmCP_DFY_DATA_0 }, + { 0x94800015, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0xc419324c, mmCP_DFY_DATA_0 }, + { 0x259c0001, mmCP_DFY_DATA_0 }, + { 0x1598001f, mmCP_DFY_DATA_0 }, + { 0x95c0000d, mmCP_DFY_DATA_0 }, + { 0x9580000c, mmCP_DFY_DATA_0 }, + { 0x99000003, mmCP_DFY_DATA_0 }, + { 0xd8400036, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14d80011, mmCP_DFY_DATA_0 }, + { 0x24dc00ff, mmCP_DFY_DATA_0 }, + { 0x31e00002, mmCP_DFY_DATA_0 }, + { 0x31dc0003, mmCP_DFY_DATA_0 }, + { 0x9580fff0, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0x99c00002, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0x94800004, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95801827, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8800036, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8c00036, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xc4180014, mmCP_DFY_DATA_0 }, + { 0x9580ffff, mmCP_DFY_DATA_0 }, + { 0xd840002f, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14dc0011, mmCP_DFY_DATA_0 }, + { 0x95c0fffe, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd800006d, mmCP_DFY_DATA_0 }, + { 0xc41d3246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51dc0020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0xd8400028, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc420000b, mmCP_DFY_DATA_0 }, + { 0x32200002, mmCP_DFY_DATA_0 }, + { 0x9a0000ad, mmCP_DFY_DATA_0 }, + { 0x04200032, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0xde030000, mmCP_DFY_DATA_0 }, + { 0xd8400033, mmCP_DFY_DATA_0 }, + { 0x04080000, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0002, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xc42c0015, mmCP_DFY_DATA_0 }, + { 0x96c0ffff, mmCP_DFY_DATA_0 }, + { 0xd800002e, mmCP_DFY_DATA_0 }, + { 0xc42d3249, mmCP_DFY_DATA_0 }, + { 0x1af4003e, mmCP_DFY_DATA_0 }, + { 0x9740004d, mmCP_DFY_DATA_0 }, + { 0xc428000d, mmCP_DFY_DATA_0 }, + { 0xc4080060, mmCP_DFY_DATA_0 }, + { 0x7ca88005, mmCP_DFY_DATA_0 }, + { 0x24880001, mmCP_DFY_DATA_0 }, + { 0x7f4b4009, mmCP_DFY_DATA_0 }, + { 0x97400046, mmCP_DFY_DATA_0 }, + { 0xc4313274, mmCP_DFY_DATA_0 }, + { 0xc4100057, mmCP_DFY_DATA_0 }, + { 0x7d33400c, mmCP_DFY_DATA_0 }, + { 0x97400009, mmCP_DFY_DATA_0 }, + { 0x28240100, mmCP_DFY_DATA_0 }, + { 0x7e6a4004, mmCP_DFY_DATA_0 }, + { 0xce400079, mmCP_DFY_DATA_0 }, + { 0x1eecffdd, mmCP_DFY_DATA_0 }, + { 0xcec13249, mmCP_DFY_DATA_0 }, + { 0xcf013273, mmCP_DFY_DATA_0 }, + { 0xcf013275, mmCP_DFY_DATA_0 }, + { 0x800003c3, mmCP_DFY_DATA_0 }, + { 0xc429326f, mmCP_DFY_DATA_0 }, + { 0x1aa80030, mmCP_DFY_DATA_0 }, + { 0x96800006, mmCP_DFY_DATA_0 }, + { 0x28240001, mmCP_DFY_DATA_0 }, + { 0xc428000d, mmCP_DFY_DATA_0 }, + { 0x06a80008, mmCP_DFY_DATA_0 }, + { 0x7e6a8004, mmCP_DFY_DATA_0 }, + { 0xce800035, mmCP_DFY_DATA_0 }, + { 0xc41d3272, mmCP_DFY_DATA_0 }, + { 0x25cc0001, mmCP_DFY_DATA_0 }, + { 0x10cc0004, mmCP_DFY_DATA_0 }, + { 0x19e80042, mmCP_DFY_DATA_0 }, + { 0x25dc0006, mmCP_DFY_DATA_0 }, + { 0x11dc0001, mmCP_DFY_DATA_0 }, + { 0x7e8e800a, mmCP_DFY_DATA_0 }, + { 0x7de9c00a, mmCP_DFY_DATA_0 }, + { 0xc40d3271, mmCP_DFY_DATA_0 }, + { 0xc4293270, mmCP_DFY_DATA_0 }, + { 0x50cc0020, mmCP_DFY_DATA_0 }, + { 0x7ce8c01a, mmCP_DFY_DATA_0 }, + { 0x7cd30011, mmCP_DFY_DATA_0 }, + { 0x11e80007, mmCP_DFY_DATA_0 }, + { 0x2aa80000, mmCP_DFY_DATA_0 }, + { 0xce80001c, mmCP_DFY_DATA_0 }, + { 0xd300001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x1b30003f, mmCP_DFY_DATA_0 }, + { 0x33300000, mmCP_DFY_DATA_0 }, + { 0xc4240059, mmCP_DFY_DATA_0 }, + { 0x1660001f, mmCP_DFY_DATA_0 }, + { 0x7e320009, mmCP_DFY_DATA_0 }, + { 0xc0328000, mmCP_DFY_DATA_0 }, + { 0x7e72400a, mmCP_DFY_DATA_0 }, + { 0x0430000c, mmCP_DFY_DATA_0 }, + { 0x9a000002, mmCP_DFY_DATA_0 }, + { 0x04300008, mmCP_DFY_DATA_0 }, + { 0xc02ac000, mmCP_DFY_DATA_0 }, + { 0x7d310002, mmCP_DFY_DATA_0 }, + { 0x17300002, mmCP_DFY_DATA_0 }, + { 0x2aa87600, mmCP_DFY_DATA_0 }, + { 0x7cd0c011, mmCP_DFY_DATA_0 }, + { 0xcdc00024, mmCP_DFY_DATA_0 }, + { 0xd0c00025, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0x04280222, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc4280058, mmCP_DFY_DATA_0 }, + { 0x22ec003d, mmCP_DFY_DATA_0 }, + { 0xcec13249, mmCP_DFY_DATA_0 }, + { 0xcd013273, mmCP_DFY_DATA_0 }, + { 0xce813275, mmCP_DFY_DATA_0 }, + { 0xd800007b, mmCP_DFY_DATA_0 }, + { 0xc8380018, mmCP_DFY_DATA_0 }, + { 0x57b00020, mmCP_DFY_DATA_0 }, + { 0x04343108, mmCP_DFY_DATA_0 }, + { 0xc429325d, mmCP_DFY_DATA_0 }, + { 0x040c3000, mmCP_DFY_DATA_0 }, + { 0x13740008, mmCP_DFY_DATA_0 }, + { 0x2374007e, mmCP_DFY_DATA_0 }, + { 0x32a80003, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x18ec0057, mmCP_DFY_DATA_0 }, + { 0x18e40213, mmCP_DFY_DATA_0 }, + { 0x18cc0199, mmCP_DFY_DATA_0 }, + { 0x7cecc00a, mmCP_DFY_DATA_0 }, + { 0x7ce4c00a, mmCP_DFY_DATA_0 }, + { 0x94800003, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x800003e7, mmCP_DFY_DATA_0 }, + { 0x04200022, mmCP_DFY_DATA_0 }, + { 0xde030000, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x04200010, mmCP_DFY_DATA_0 }, + { 0xde030000, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0x45980104, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xcf800026, mmCP_DFY_DATA_0 }, + { 0xcf000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x49980104, mmCP_DFY_DATA_0 }, + { 0x9a80000a, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x45980168, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x800003f2, mmCP_DFY_DATA_0 }, + { 0x8c000448, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x040c2000, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0xd8400030, mmCP_DFY_DATA_0 }, + { 0xc42c0016, mmCP_DFY_DATA_0 }, + { 0x96c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8000030, mmCP_DFY_DATA_0 }, + { 0xc42c0016, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xd800002f, mmCP_DFY_DATA_0 }, + { 0xc42c0015, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400034, mmCP_DFY_DATA_0 }, + { 0xc4300025, mmCP_DFY_DATA_0 }, + { 0xc4340024, mmCP_DFY_DATA_0 }, + { 0xc4380081, mmCP_DFY_DATA_0 }, + { 0xcf813279, mmCP_DFY_DATA_0 }, + { 0xcf41326e, mmCP_DFY_DATA_0 }, + { 0xcf01326d, mmCP_DFY_DATA_0 }, + { 0x94c0000d, mmCP_DFY_DATA_0 }, + { 0x254c0700, mmCP_DFY_DATA_0 }, + { 0xc424001e, mmCP_DFY_DATA_0 }, + { 0x10cc0010, mmCP_DFY_DATA_0 }, + { 0x1a641fe8, mmCP_DFY_DATA_0 }, + { 0x28cc0726, mmCP_DFY_DATA_0 }, + { 0x2a640200, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1237b, mmCP_DFY_DATA_0 }, + { 0x2264003f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8813260, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0xc4240033, mmCP_DFY_DATA_0 }, + { 0xc4280034, mmCP_DFY_DATA_0 }, + { 0xd9000036, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x96400006, mmCP_DFY_DATA_0 }, + { 0xde430000, mmCP_DFY_DATA_0 }, + { 0xce40000c, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01755, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x9680000a, mmCP_DFY_DATA_0 }, + { 0xce80000a, mmCP_DFY_DATA_0 }, + { 0x06a80002, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xde830000, mmCP_DFY_DATA_0 }, + { 0xce80000d, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c0174c, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xc4393265, mmCP_DFY_DATA_0 }, + { 0x2bb80040, mmCP_DFY_DATA_0 }, + { 0xd8400032, mmCP_DFY_DATA_0 }, + { 0xcf813265, mmCP_DFY_DATA_0 }, + { 0xc4200012, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xc4100044, mmCP_DFY_DATA_0 }, + { 0x19180024, mmCP_DFY_DATA_0 }, + { 0xc8100072, mmCP_DFY_DATA_0 }, + { 0x551c003f, mmCP_DFY_DATA_0 }, + { 0x99c00003, mmCP_DFY_DATA_0 }, + { 0x95800010, mmCP_DFY_DATA_0 }, + { 0x8000043d, mmCP_DFY_DATA_0 }, + { 0xc00c8000, mmCP_DFY_DATA_0 }, + { 0xd840006c, mmCP_DFY_DATA_0 }, + { 0x28200000, mmCP_DFY_DATA_0 }, + { 0x8000043f, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0x282000f0, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc4113255, mmCP_DFY_DATA_0 }, + { 0xcd01324f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0xce000053, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x195c00e8, mmCP_DFY_DATA_0 }, + { 0xc4100004, mmCP_DFY_DATA_0 }, + { 0x2555fff0, mmCP_DFY_DATA_0 }, + { 0xc0360001, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0x29540001, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0x04280004, mmCP_DFY_DATA_0 }, + { 0xc420000b, mmCP_DFY_DATA_0 }, + { 0x32200002, mmCP_DFY_DATA_0 }, + { 0x9a000009, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0xc5e124dc, mmCP_DFY_DATA_0 }, + { 0x0aa80001, mmCP_DFY_DATA_0 }, + { 0x7ef6c001, mmCP_DFY_DATA_0 }, + { 0x7e624001, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0x9a80fff9, mmCP_DFY_DATA_0 }, + { 0xc02ee000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x2555fff0, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0xc42d3255, mmCP_DFY_DATA_0 }, + { 0xc4353259, mmCP_DFY_DATA_0 }, + { 0xd8013260, mmCP_DFY_DATA_0 }, + { 0x45980158, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x49980158, mmCP_DFY_DATA_0 }, + { 0x45980170, mmCP_DFY_DATA_0 }, + { 0xc4200012, mmCP_DFY_DATA_0 }, + { 0x16200010, mmCP_DFY_DATA_0 }, + { 0x9a00fffe, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xc429324f, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcd000008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x7d43c001, mmCP_DFY_DATA_0 }, + { 0x195400e8, mmCP_DFY_DATA_0 }, + { 0x1154000a, mmCP_DFY_DATA_0 }, + { 0x18dc00e8, mmCP_DFY_DATA_0 }, + { 0x05e80488, mmCP_DFY_DATA_0 }, + { 0x18d0006c, mmCP_DFY_DATA_0 }, + { 0x18f807f0, mmCP_DFY_DATA_0 }, + { 0x18e40077, mmCP_DFY_DATA_0 }, + { 0x18ec0199, mmCP_DFY_DATA_0 }, + { 0x7e6e400a, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000048e, mmCP_DFY_DATA_0 }, + { 0x80000494, mmCP_DFY_DATA_0 }, + { 0x800004de, mmCP_DFY_DATA_0 }, + { 0x80000685, mmCP_DFY_DATA_0 }, + { 0x80000686, mmCP_DFY_DATA_0 }, + { 0x800006ac, mmCP_DFY_DATA_0 }, + { 0x1ccc001f, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4293254, mmCP_DFY_DATA_0 }, + { 0x1264000a, mmCP_DFY_DATA_0 }, + { 0xc4300004, mmCP_DFY_DATA_0 }, + { 0x7d79400a, mmCP_DFY_DATA_0 }, + { 0x7e7a400a, mmCP_DFY_DATA_0 }, + { 0x52a8001e, mmCP_DFY_DATA_0 }, + { 0x15180001, mmCP_DFY_DATA_0 }, + { 0x7d69401a, mmCP_DFY_DATA_0 }, + { 0x202c007d, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x95000008, mmCP_DFY_DATA_0 }, + { 0x95800028, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x1aec0028, mmCP_DFY_DATA_0 }, + { 0xc40d325c, mmCP_DFY_DATA_0 }, + { 0x800004cc, mmCP_DFY_DATA_0 }, + { 0xc42d3256, mmCP_DFY_DATA_0 }, + { 0xc419324e, mmCP_DFY_DATA_0 }, + { 0x26e8003f, mmCP_DFY_DATA_0 }, + { 0x1aec003e, mmCP_DFY_DATA_0 }, + { 0x12f4000e, mmCP_DFY_DATA_0 }, + { 0xc41d324d, mmCP_DFY_DATA_0 }, + { 0xc40d324f, mmCP_DFY_DATA_0 }, + { 0x7d75401a, mmCP_DFY_DATA_0 }, + { 0x04100002, mmCP_DFY_DATA_0 }, + { 0x7d290004, mmCP_DFY_DATA_0 }, + { 0x7f8f4001, mmCP_DFY_DATA_0 }, + { 0x7f52800f, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x50e00002, mmCP_DFY_DATA_0 }, + { 0x51980008, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x800004d1, mmCP_DFY_DATA_0 }, + { 0x7d0dc002, mmCP_DFY_DATA_0 }, + { 0x6665fc00, mmCP_DFY_DATA_0 }, + { 0x7e5e401a, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x7da1c011, mmCP_DFY_DATA_0 }, + { 0xd140000b, mmCP_DFY_DATA_0 }, + { 0xd1c00002, mmCP_DFY_DATA_0 }, + { 0x2a644000, mmCP_DFY_DATA_0 }, + { 0xce400002, mmCP_DFY_DATA_0 }, + { 0x7f534002, mmCP_DFY_DATA_0 }, + { 0x6665fc00, mmCP_DFY_DATA_0 }, + { 0x7e76401a, mmCP_DFY_DATA_0 }, + { 0xd1800002, mmCP_DFY_DATA_0 }, + { 0xce400002, mmCP_DFY_DATA_0 }, + { 0x800004d7, mmCP_DFY_DATA_0 }, + { 0xc42d325a, mmCP_DFY_DATA_0 }, + { 0xc4193258, mmCP_DFY_DATA_0 }, + { 0x1aec003e, mmCP_DFY_DATA_0 }, + { 0xc41d3257, mmCP_DFY_DATA_0 }, + { 0xc4213259, mmCP_DFY_DATA_0 }, + { 0x12f4000e, mmCP_DFY_DATA_0 }, + { 0x7d75401a, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x52200002, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x7da1c011, mmCP_DFY_DATA_0 }, + { 0xd140000b, mmCP_DFY_DATA_0 }, + { 0xd1c00002, mmCP_DFY_DATA_0 }, + { 0x2a644000, mmCP_DFY_DATA_0 }, + { 0xce400002, mmCP_DFY_DATA_0 }, + { 0x202c003d, mmCP_DFY_DATA_0 }, + { 0xcf000008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0xc42d325b, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4193260, mmCP_DFY_DATA_0 }, + { 0x259c0007, mmCP_DFY_DATA_0 }, + { 0x15980004, mmCP_DFY_DATA_0 }, + { 0x05e804e3, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x800004e7, mmCP_DFY_DATA_0 }, + { 0x800004f0, mmCP_DFY_DATA_0 }, + { 0x80000505, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc435325d, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0x277401ef, mmCP_DFY_DATA_0 }, + { 0xcf41325d, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0x9640fff4, mmCP_DFY_DATA_0 }, + { 0x17e00008, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xd84131db, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xcd800009, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc42d325b, mmCP_DFY_DATA_0 }, + { 0x1b301ff8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0x26edf000, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0xd8413260, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x05a80507, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000050c, mmCP_DFY_DATA_0 }, + { 0x80000528, mmCP_DFY_DATA_0 }, + { 0x8000057d, mmCP_DFY_DATA_0 }, + { 0x800005c2, mmCP_DFY_DATA_0 }, + { 0x800005f3, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9a400012, mmCP_DFY_DATA_0 }, + { 0x1bd400e8, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xcd40005e, mmCP_DFY_DATA_0 }, + { 0xc41c004d, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x99c0000c, mmCP_DFY_DATA_0 }, + { 0xc4100019, mmCP_DFY_DATA_0 }, + { 0x7d150005, mmCP_DFY_DATA_0 }, + { 0x25100001, mmCP_DFY_DATA_0 }, + { 0x99000008, mmCP_DFY_DATA_0 }, + { 0x8c00063b, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0x2511fffd, mmCP_DFY_DATA_0 }, + { 0xcd013277, mmCP_DFY_DATA_0 }, + { 0xd801326f, mmCP_DFY_DATA_0 }, + { 0x80000624, mmCP_DFY_DATA_0 }, + { 0x04240012, mmCP_DFY_DATA_0 }, + { 0x1be00fe4, mmCP_DFY_DATA_0 }, + { 0xce413260, mmCP_DFY_DATA_0 }, + { 0xce000066, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400068, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9a400013, mmCP_DFY_DATA_0 }, + { 0x1bd400e8, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xcd40005e, mmCP_DFY_DATA_0 }, + { 0xc41c004d, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x99c0000d, mmCP_DFY_DATA_0 }, + { 0xc4100019, mmCP_DFY_DATA_0 }, + { 0x7d150005, mmCP_DFY_DATA_0 }, + { 0x25100001, mmCP_DFY_DATA_0 }, + { 0x99000009, mmCP_DFY_DATA_0 }, + { 0xd8400067, mmCP_DFY_DATA_0 }, + { 0x8c00063b, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0x2511fffd, mmCP_DFY_DATA_0 }, + { 0xcd013277, mmCP_DFY_DATA_0 }, + { 0xd801326f, mmCP_DFY_DATA_0 }, + { 0x80000624, mmCP_DFY_DATA_0 }, + { 0x1bd400e8, mmCP_DFY_DATA_0 }, + { 0xc42c0060, mmCP_DFY_DATA_0 }, + { 0x7ed6c005, mmCP_DFY_DATA_0 }, + { 0x26ec0001, mmCP_DFY_DATA_0 }, + { 0xc4113271, mmCP_DFY_DATA_0 }, + { 0xc4153270, mmCP_DFY_DATA_0 }, + { 0xc4193272, mmCP_DFY_DATA_0 }, + { 0xc41d3273, mmCP_DFY_DATA_0 }, + { 0x04280022, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d51401a, mmCP_DFY_DATA_0 }, + { 0xc4113274, mmCP_DFY_DATA_0 }, + { 0xc4213275, mmCP_DFY_DATA_0 }, + { 0xc4253276, mmCP_DFY_DATA_0 }, + { 0xc4313248, mmCP_DFY_DATA_0 }, + { 0xd1400061, mmCP_DFY_DATA_0 }, + { 0x2730000f, mmCP_DFY_DATA_0 }, + { 0x13300010, mmCP_DFY_DATA_0 }, + { 0x7db1800a, mmCP_DFY_DATA_0 }, + { 0xcd800060, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0x05dc0008, mmCP_DFY_DATA_0 }, + { 0xcdc00062, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xcd000063, mmCP_DFY_DATA_0 }, + { 0xce000064, mmCP_DFY_DATA_0 }, + { 0xce400065, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0xce813260, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc820001f, mmCP_DFY_DATA_0 }, + { 0x1b700057, mmCP_DFY_DATA_0 }, + { 0x1b680213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x46ec0188, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0x17e00008, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x26e01000, mmCP_DFY_DATA_0 }, + { 0x9a00fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd9c131fc, mmCP_DFY_DATA_0 }, + { 0xcd800009, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0x29dc0001, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0x191807e4, mmCP_DFY_DATA_0 }, + { 0x192007ec, mmCP_DFY_DATA_0 }, + { 0x95400004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9580000e, mmCP_DFY_DATA_0 }, + { 0x09980001, mmCP_DFY_DATA_0 }, + { 0x041c0001, mmCP_DFY_DATA_0 }, + { 0x95800005, mmCP_DFY_DATA_0 }, + { 0x09980001, mmCP_DFY_DATA_0 }, + { 0x51dc0001, mmCP_DFY_DATA_0 }, + { 0x69dc0001, mmCP_DFY_DATA_0 }, + { 0x9980fffd, mmCP_DFY_DATA_0 }, + { 0x7de20014, mmCP_DFY_DATA_0 }, + { 0x561c0020, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xce013344, mmCP_DFY_DATA_0 }, + { 0xcdc13345, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x95400022, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425334d, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9640fffe, mmCP_DFY_DATA_0 }, + { 0xc419334e, mmCP_DFY_DATA_0 }, + { 0xc41d334f, mmCP_DFY_DATA_0 }, + { 0xc4213350, mmCP_DFY_DATA_0 }, + { 0xc4253351, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x1b680057, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x46ec01b0, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x04280032, mmCP_DFY_DATA_0 }, + { 0xce813260, mmCP_DFY_DATA_0 }, + { 0xd8800068, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x2010007d, mmCP_DFY_DATA_0 }, + { 0xcd01325b, mmCP_DFY_DATA_0 }, + { 0xc411325b, mmCP_DFY_DATA_0 }, + { 0x1910003e, mmCP_DFY_DATA_0 }, + { 0x9500fffe, mmCP_DFY_DATA_0 }, + { 0x04100040, mmCP_DFY_DATA_0 }, + { 0xcd00001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc410000f, mmCP_DFY_DATA_0 }, + { 0x9900ffff, mmCP_DFY_DATA_0 }, + { 0x04100060, mmCP_DFY_DATA_0 }, + { 0xcd00001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc410000f, mmCP_DFY_DATA_0 }, + { 0x9900ffff, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x2010003d, mmCP_DFY_DATA_0 }, + { 0xcd01325b, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0x191807e4, mmCP_DFY_DATA_0 }, + { 0x9540000b, mmCP_DFY_DATA_0 }, + { 0x2511fffd, mmCP_DFY_DATA_0 }, + { 0xcd013277, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x95800005, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8013344, mmCP_DFY_DATA_0 }, + { 0xd8013345, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4180050, mmCP_DFY_DATA_0 }, + { 0xc41c0052, mmCP_DFY_DATA_0 }, + { 0x04280042, mmCP_DFY_DATA_0 }, + { 0xcd813273, mmCP_DFY_DATA_0 }, + { 0xcdc13275, mmCP_DFY_DATA_0 }, + { 0xce813260, mmCP_DFY_DATA_0 }, + { 0xd9000068, mmCP_DFY_DATA_0 }, + { 0xd8400067, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x07d40000, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c00124f, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x057c0000, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x1b680057, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0xc820001f, mmCP_DFY_DATA_0 }, + { 0x46ec0190, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc4153249, mmCP_DFY_DATA_0 }, + { 0x2154003d, mmCP_DFY_DATA_0 }, + { 0xc41c0019, mmCP_DFY_DATA_0 }, + { 0x1bd800e8, mmCP_DFY_DATA_0 }, + { 0x7dd9c005, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xcd80005e, mmCP_DFY_DATA_0 }, + { 0xc420004d, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x11dc0010, mmCP_DFY_DATA_0 }, + { 0x7e1e000a, mmCP_DFY_DATA_0 }, + { 0xcd413249, mmCP_DFY_DATA_0 }, + { 0xce01326f, mmCP_DFY_DATA_0 }, + { 0x28340001, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7f598004, mmCP_DFY_DATA_0 }, + { 0xcd800035, mmCP_DFY_DATA_0 }, + { 0x1be800e8, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xce80005e, mmCP_DFY_DATA_0 }, + { 0xd801327a, mmCP_DFY_DATA_0 }, + { 0xd800005f, mmCP_DFY_DATA_0 }, + { 0xd8000075, mmCP_DFY_DATA_0 }, + { 0xd800007f, mmCP_DFY_DATA_0 }, + { 0xc424004c, mmCP_DFY_DATA_0 }, + { 0xce41326e, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x28240100, mmCP_DFY_DATA_0 }, + { 0x7e6a4004, mmCP_DFY_DATA_0 }, + { 0xce400079, mmCP_DFY_DATA_0 }, + { 0xc435325d, mmCP_DFY_DATA_0 }, + { 0x277401ef, mmCP_DFY_DATA_0 }, + { 0x04240020, mmCP_DFY_DATA_0 }, + { 0xce41325e, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xd8013260, mmCP_DFY_DATA_0 }, + { 0xcf41325d, mmCP_DFY_DATA_0 }, + { 0xda000068, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0x29dc0001, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0x9540002d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425334d, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9640fffe, mmCP_DFY_DATA_0 }, + { 0xc419334e, mmCP_DFY_DATA_0 }, + { 0xc41d334f, mmCP_DFY_DATA_0 }, + { 0xc4213350, mmCP_DFY_DATA_0 }, + { 0xc4253351, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x1b680057, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x46ec01b0, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc430000b, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0x9b000010, mmCP_DFY_DATA_0 }, + { 0x1be000e8, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0xc0360001, mmCP_DFY_DATA_0 }, + { 0x04280004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0xc63124dc, mmCP_DFY_DATA_0 }, + { 0x0aa80001, mmCP_DFY_DATA_0 }, + { 0x7ef6c001, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x9a80fff9, mmCP_DFY_DATA_0 }, + { 0xc02ee000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4253260, mmCP_DFY_DATA_0 }, + { 0x7fc14001, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x98c00005, mmCP_DFY_DATA_0 }, + { 0x194c1c03, mmCP_DFY_DATA_0 }, + { 0xccc0003b, mmCP_DFY_DATA_0 }, + { 0xc40c002d, mmCP_DFY_DATA_0 }, + { 0x80000697, mmCP_DFY_DATA_0 }, + { 0xc420004a, mmCP_DFY_DATA_0 }, + { 0x194c00e8, mmCP_DFY_DATA_0 }, + { 0xccc0005e, mmCP_DFY_DATA_0 }, + { 0xc40c004c, mmCP_DFY_DATA_0 }, + { 0xc431326d, mmCP_DFY_DATA_0 }, + { 0x27301fff, mmCP_DFY_DATA_0 }, + { 0xce00005e, mmCP_DFY_DATA_0 }, + { 0x7cf0c00d, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c00008, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0x1b301ff8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x25100007, mmCP_DFY_DATA_0 }, + { 0x31100005, mmCP_DFY_DATA_0 }, + { 0x9900008e, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x8000075e, mmCP_DFY_DATA_0 }, + { 0x202c007d, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0xc4293265, mmCP_DFY_DATA_0 }, + { 0xc4353254, mmCP_DFY_DATA_0 }, + { 0x26a9feff, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x1374000b, mmCP_DFY_DATA_0 }, + { 0xc40c000d, mmCP_DFY_DATA_0 }, + { 0xd8000009, mmCP_DFY_DATA_0 }, + { 0x1774000d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc41d30b8, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x95c00008, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xccc00009, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xce813265, mmCP_DFY_DATA_0 }, + { 0xcf400100, mmCP_DFY_DATA_0 }, + { 0xc00ac006, mmCP_DFY_DATA_0 }, + { 0xc00e0000, mmCP_DFY_DATA_0 }, + { 0x28880700, mmCP_DFY_DATA_0 }, + { 0x28cc0014, mmCP_DFY_DATA_0 }, + { 0x8c0006de, mmCP_DFY_DATA_0 }, + { 0x14cc0010, mmCP_DFY_DATA_0 }, + { 0x30d4000f, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x10cc0010, mmCP_DFY_DATA_0 }, + { 0x28cc0014, mmCP_DFY_DATA_0 }, + { 0x99400009, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc41530b8, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x19980028, mmCP_DFY_DATA_0 }, + { 0x99400003, mmCP_DFY_DATA_0 }, + { 0x99800002, mmCP_DFY_DATA_0 }, + { 0x800006c8, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x15600008, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xc8380023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x7fa38011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x282c2002, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0xcec00013, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x042c0008, mmCP_DFY_DATA_0 }, + { 0xd3800025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x202400d0, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0x28240006, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x9a800004, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x24d8003f, mmCP_DFY_DATA_0 }, + { 0xd840003c, mmCP_DFY_DATA_0 }, + { 0xcec0003a, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcd81a2a4, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc41d325d, mmCP_DFY_DATA_0 }, + { 0x25dc0007, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x94c0000a, mmCP_DFY_DATA_0 }, + { 0xc420004a, mmCP_DFY_DATA_0 }, + { 0x194c00e8, mmCP_DFY_DATA_0 }, + { 0xccc0005e, mmCP_DFY_DATA_0 }, + { 0xc40c004c, mmCP_DFY_DATA_0 }, + { 0xc431326d, mmCP_DFY_DATA_0 }, + { 0x27301fff, mmCP_DFY_DATA_0 }, + { 0xce00005e, mmCP_DFY_DATA_0 }, + { 0x7cf0c00d, mmCP_DFY_DATA_0 }, + { 0x80000712, mmCP_DFY_DATA_0 }, + { 0x194c1c03, mmCP_DFY_DATA_0 }, + { 0xccc0003b, mmCP_DFY_DATA_0 }, + { 0xc40c002d, mmCP_DFY_DATA_0 }, + { 0x05e80714, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000071c, mmCP_DFY_DATA_0 }, + { 0x80000720, mmCP_DFY_DATA_0 }, + { 0x80000747, mmCP_DFY_DATA_0 }, + { 0x8000071d, mmCP_DFY_DATA_0 }, + { 0x800007c4, mmCP_DFY_DATA_0 }, + { 0x80000732, mmCP_DFY_DATA_0 }, + { 0x80000745, mmCP_DFY_DATA_0 }, + { 0x80000744, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x98c00006, mmCP_DFY_DATA_0 }, + { 0x8000072e, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c0000c, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4253265, mmCP_DFY_DATA_0 }, + { 0x2a64008c, mmCP_DFY_DATA_0 }, + { 0xce413265, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0x1b301fe8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0xd8013260, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0x8000075e, mmCP_DFY_DATA_0 }, + { 0x98c0fff1, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c00002, mmCP_DFY_DATA_0 }, + { 0x80000723, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc41f02f1, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0xd8013247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0x80000743, mmCP_DFY_DATA_0 }, + { 0xd8813247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0xc4100004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcd000008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0x98c0ffde, mmCP_DFY_DATA_0 }, + { 0x8000072e, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c00012, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x15600008, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd84131db, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0xcd800009, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0x1b301ff8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8413260, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x041c3000, mmCP_DFY_DATA_0 }, + { 0xcdc13267, mmCP_DFY_DATA_0 }, + { 0xc41d3267, mmCP_DFY_DATA_0 }, + { 0xc41d3265, mmCP_DFY_DATA_0 }, + { 0x25dc8000, mmCP_DFY_DATA_0 }, + { 0x95c00007, mmCP_DFY_DATA_0 }, + { 0xc41c004a, mmCP_DFY_DATA_0 }, + { 0x195800e8, mmCP_DFY_DATA_0 }, + { 0xcd80005e, mmCP_DFY_DATA_0 }, + { 0xc418004c, mmCP_DFY_DATA_0 }, + { 0xcd81326e, mmCP_DFY_DATA_0 }, + { 0xcdc0005e, mmCP_DFY_DATA_0 }, + { 0xc41d3265, mmCP_DFY_DATA_0 }, + { 0x25dd7fff, mmCP_DFY_DATA_0 }, + { 0xcdc13265, mmCP_DFY_DATA_0 }, + { 0xc41d3246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x51e00020, mmCP_DFY_DATA_0 }, + { 0x7e1a001a, mmCP_DFY_DATA_0 }, + { 0x46200200, mmCP_DFY_DATA_0 }, + { 0x04283247, mmCP_DFY_DATA_0 }, + { 0x04300033, mmCP_DFY_DATA_0 }, + { 0x1af80057, mmCP_DFY_DATA_0 }, + { 0x1af40213, mmCP_DFY_DATA_0 }, + { 0x042c000c, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f6f400a, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2000025, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xc6990000, mmCP_DFY_DATA_0 }, + { 0x329c325d, mmCP_DFY_DATA_0 }, + { 0x99c00008, mmCP_DFY_DATA_0 }, + { 0x329c3269, mmCP_DFY_DATA_0 }, + { 0x99c00006, mmCP_DFY_DATA_0 }, + { 0x329c3267, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0xc01defff, mmCP_DFY_DATA_0 }, + { 0x7d9d8009, mmCP_DFY_DATA_0 }, + { 0x8000078a, mmCP_DFY_DATA_0 }, + { 0x25980000, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0x9b00fff2, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc43c0012, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0xc03e7ff0, mmCP_DFY_DATA_0 }, + { 0x7f3f0009, mmCP_DFY_DATA_0 }, + { 0xcf01325a, mmCP_DFY_DATA_0 }, + { 0xc4313249, mmCP_DFY_DATA_0 }, + { 0x1f30001f, mmCP_DFY_DATA_0 }, + { 0xcf013249, mmCP_DFY_DATA_0 }, + { 0xc03e4000, mmCP_DFY_DATA_0 }, + { 0xcfc13254, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8013254, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0xd801324f, mmCP_DFY_DATA_0 }, + { 0xd8013255, mmCP_DFY_DATA_0 }, + { 0xd8013247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0x1b300028, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001219, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x9900000d, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0x9700000b, mmCP_DFY_DATA_0 }, + { 0xc43d30b5, mmCP_DFY_DATA_0 }, + { 0x1bf0003a, mmCP_DFY_DATA_0 }, + { 0x9b000b80, mmCP_DFY_DATA_0 }, + { 0x203c003a, mmCP_DFY_DATA_0 }, + { 0xc430000e, mmCP_DFY_DATA_0 }, + { 0x27300700, mmCP_DFY_DATA_0 }, + { 0x13300014, mmCP_DFY_DATA_0 }, + { 0x2b300001, mmCP_DFY_DATA_0 }, + { 0xcf0130b7, mmCP_DFY_DATA_0 }, + { 0xcfc130b5, mmCP_DFY_DATA_0 }, + { 0x46200008, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2000025, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0x9bc00001, mmCP_DFY_DATA_0 }, + { 0xccc00010, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4080007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0xc4193260, mmCP_DFY_DATA_0 }, + { 0x259c0003, mmCP_DFY_DATA_0 }, + { 0x31dc0003, mmCP_DFY_DATA_0 }, + { 0x95c00014, mmCP_DFY_DATA_0 }, + { 0x040c3000, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x18ec0057, mmCP_DFY_DATA_0 }, + { 0x18e40213, mmCP_DFY_DATA_0 }, + { 0x18cc0199, mmCP_DFY_DATA_0 }, + { 0x7cecc00a, mmCP_DFY_DATA_0 }, + { 0x7ce4c00a, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x8c000448, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x040c2000, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0xcc800010, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc418000b, mmCP_DFY_DATA_0 }, + { 0x31980002, mmCP_DFY_DATA_0 }, + { 0x041c0000, mmCP_DFY_DATA_0 }, + { 0x9980001c, mmCP_DFY_DATA_0 }, + { 0x19580066, mmCP_DFY_DATA_0 }, + { 0x15600008, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0xc0120001, mmCP_DFY_DATA_0 }, + { 0x11980003, mmCP_DFY_DATA_0 }, + { 0x04240004, mmCP_DFY_DATA_0 }, + { 0x7da18001, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1c200, mmCP_DFY_DATA_0 }, + { 0xc41d24db, mmCP_DFY_DATA_0 }, + { 0x7cd0c001, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0x7dd9c005, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0x99c00002, mmCP_DFY_DATA_0 }, + { 0x9a40fff8, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x9580137b, mmCP_DFY_DATA_0 }, + { 0xc00ee000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1c200, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd840004f, mmCP_DFY_DATA_0 }, + { 0xc4113269, mmCP_DFY_DATA_0 }, + { 0x19080070, mmCP_DFY_DATA_0 }, + { 0x190c00e8, mmCP_DFY_DATA_0 }, + { 0x2510003f, mmCP_DFY_DATA_0 }, + { 0x2518000f, mmCP_DFY_DATA_0 }, + { 0xcd813268, mmCP_DFY_DATA_0 }, + { 0x05a80809, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000080e, mmCP_DFY_DATA_0 }, + { 0x8000080f, mmCP_DFY_DATA_0 }, + { 0x80000898, mmCP_DFY_DATA_0 }, + { 0x80000946, mmCP_DFY_DATA_0 }, + { 0x800009e1, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x04a80811, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000815, mmCP_DFY_DATA_0 }, + { 0x80000834, mmCP_DFY_DATA_0 }, + { 0x8000085e, mmCP_DFY_DATA_0 }, + { 0x8000085e, mmCP_DFY_DATA_0 }, + { 0x04341001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc42d3045, mmCP_DFY_DATA_0 }, + { 0xcec1c091, mmCP_DFY_DATA_0 }, + { 0x31300021, mmCP_DFY_DATA_0 }, + { 0x9700000b, mmCP_DFY_DATA_0 }, + { 0xd84002f1, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xc4293059, mmCP_DFY_DATA_0 }, + { 0x56a8001f, mmCP_DFY_DATA_0 }, + { 0x7f2b000a, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x9b000241, mmCP_DFY_DATA_0 }, + { 0x8000084a, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc43130b6, mmCP_DFY_DATA_0 }, + { 0x9b000003, mmCP_DFY_DATA_0 }, + { 0xc02f0001, mmCP_DFY_DATA_0 }, + { 0xcec130b6, mmCP_DFY_DATA_0 }, + { 0xc4252087, mmCP_DFY_DATA_0 }, + { 0x5668001a, mmCP_DFY_DATA_0 }, + { 0x26a80005, mmCP_DFY_DATA_0 }, + { 0x9a80fffd, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd80130b6, mmCP_DFY_DATA_0 }, + { 0x8000084a, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04341001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc431ecaa, mmCP_DFY_DATA_0 }, + { 0x27300080, mmCP_DFY_DATA_0 }, + { 0x9b000010, mmCP_DFY_DATA_0 }, + { 0xc02e0001, mmCP_DFY_DATA_0 }, + { 0xcec130b6, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd80130b6, mmCP_DFY_DATA_0 }, + { 0x31300021, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xd84002f1, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xc4293059, mmCP_DFY_DATA_0 }, + { 0x56a8001f, mmCP_DFY_DATA_0 }, + { 0x7f2b000a, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x9b00021d, mmCP_DFY_DATA_0 }, + { 0xdd410000, mmCP_DFY_DATA_0 }, + { 0x040c0005, mmCP_DFY_DATA_0 }, + { 0xd84802e9, mmCP_DFY_DATA_0 }, + { 0x8c001a41, mmCP_DFY_DATA_0 }, + { 0xc43b02f1, mmCP_DFY_DATA_0 }, + { 0x9b800006, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xcec80278, mmCP_DFY_DATA_0 }, + { 0x56f00020, mmCP_DFY_DATA_0 }, + { 0xcf080280, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8813247, mmCP_DFY_DATA_0 }, + { 0xd80802e9, mmCP_DFY_DATA_0 }, + { 0x8000085e, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x31100011, mmCP_DFY_DATA_0 }, + { 0x950001fa, mmCP_DFY_DATA_0 }, + { 0xc02e0001, mmCP_DFY_DATA_0 }, + { 0x2aec0008, mmCP_DFY_DATA_0 }, + { 0xc01c0020, mmCP_DFY_DATA_0 }, + { 0xc0180001, mmCP_DFY_DATA_0 }, + { 0xc00c0007, mmCP_DFY_DATA_0 }, + { 0x11a40006, mmCP_DFY_DATA_0 }, + { 0x7de6000a, mmCP_DFY_DATA_0 }, + { 0x10e40008, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x7e2e000a, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0xc4113254, mmCP_DFY_DATA_0 }, + { 0x1d10ffdf, mmCP_DFY_DATA_0 }, + { 0x2110003e, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0xd801324f, mmCP_DFY_DATA_0 }, + { 0xd8013255, mmCP_DFY_DATA_0 }, + { 0x1d10ff9e, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0xd8013247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0xd801325e, mmCP_DFY_DATA_0 }, + { 0xc0245301, mmCP_DFY_DATA_0 }, + { 0xce413249, mmCP_DFY_DATA_0 }, + { 0xd801325f, mmCP_DFY_DATA_0 }, + { 0xc425326c, mmCP_DFY_DATA_0 }, + { 0xc0121fff, mmCP_DFY_DATA_0 }, + { 0x29108eff, mmCP_DFY_DATA_0 }, + { 0x7e524009, mmCP_DFY_DATA_0 }, + { 0xce41326c, mmCP_DFY_DATA_0 }, + { 0xc425325a, mmCP_DFY_DATA_0 }, + { 0xc0127ff0, mmCP_DFY_DATA_0 }, + { 0x7e524009, mmCP_DFY_DATA_0 }, + { 0xce41325a, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0xc0131fff, mmCP_DFY_DATA_0 }, + { 0x7e524009, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0xd801326d, mmCP_DFY_DATA_0 }, + { 0xd801326e, mmCP_DFY_DATA_0 }, + { 0xd8013279, mmCP_DFY_DATA_0 }, + { 0x94c00003, mmCP_DFY_DATA_0 }, + { 0x08cc0001, mmCP_DFY_DATA_0 }, + { 0x80000866, mmCP_DFY_DATA_0 }, + { 0xc00c0007, mmCP_DFY_DATA_0 }, + { 0x95800003, mmCP_DFY_DATA_0 }, + { 0x09980001, mmCP_DFY_DATA_0 }, + { 0x80000866, mmCP_DFY_DATA_0 }, + { 0xc0100010, mmCP_DFY_DATA_0 }, + { 0x7dd2400c, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xc0180003, mmCP_DFY_DATA_0 }, + { 0x7dd1c002, mmCP_DFY_DATA_0 }, + { 0x80000866, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x04a8089a, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000089e, mmCP_DFY_DATA_0 }, + { 0x800008fa, mmCP_DFY_DATA_0 }, + { 0x80000945, mmCP_DFY_DATA_0 }, + { 0x80000945, mmCP_DFY_DATA_0 }, + { 0x31300022, mmCP_DFY_DATA_0 }, + { 0x97000007, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d91801a, mmCP_DFY_DATA_0 }, + { 0x459801e0, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x2738000f, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8300011, mmCP_DFY_DATA_0 }, + { 0x97000036, mmCP_DFY_DATA_0 }, + { 0x45980008, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8340011, mmCP_DFY_DATA_0 }, + { 0x9740002f, mmCP_DFY_DATA_0 }, + { 0xc43c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x13b80001, mmCP_DFY_DATA_0 }, + { 0xc79d3300, mmCP_DFY_DATA_0 }, + { 0xc7a13301, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xd8393300, mmCP_DFY_DATA_0 }, + { 0xc0260001, mmCP_DFY_DATA_0 }, + { 0xce793301, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x964012a4, mmCP_DFY_DATA_0 }, + { 0x7c028009, mmCP_DFY_DATA_0 }, + { 0x9740001c, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x99800004, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x06a80400, mmCP_DFY_DATA_0 }, + { 0x800008d2, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0x29640001, mmCP_DFY_DATA_0 }, + { 0xce40001a, mmCP_DFY_DATA_0 }, + { 0x242c0000, mmCP_DFY_DATA_0 }, + { 0x06ec0400, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x9980fffd, mmCP_DFY_DATA_0 }, + { 0xc02620c0, mmCP_DFY_DATA_0 }, + { 0xce41c078, mmCP_DFY_DATA_0 }, + { 0xce81c080, mmCP_DFY_DATA_0 }, + { 0xcc01c081, mmCP_DFY_DATA_0 }, + { 0xcf01c082, mmCP_DFY_DATA_0 }, + { 0x57240020, mmCP_DFY_DATA_0 }, + { 0xce41c083, mmCP_DFY_DATA_0 }, + { 0xc0260400, mmCP_DFY_DATA_0 }, + { 0x7e6e400a, mmCP_DFY_DATA_0 }, + { 0xce41c084, mmCP_DFY_DATA_0 }, + { 0x7eae8001, mmCP_DFY_DATA_0 }, + { 0x7f2f0011, mmCP_DFY_DATA_0 }, + { 0x800008d2, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xcdf93300, mmCP_DFY_DATA_0 }, + { 0xce393301, mmCP_DFY_DATA_0 }, + { 0xcfc00008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc43c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xcfc00008, mmCP_DFY_DATA_0 }, + { 0x80000903, mmCP_DFY_DATA_0 }, + { 0x31240022, mmCP_DFY_DATA_0 }, + { 0x96400008, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x7ec30011, mmCP_DFY_DATA_0 }, + { 0x32f80000, mmCP_DFY_DATA_0 }, + { 0x9b800011, mmCP_DFY_DATA_0 }, + { 0x043c0020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x67180001, mmCP_DFY_DATA_0 }, + { 0x0bfc0001, mmCP_DFY_DATA_0 }, + { 0x57300001, mmCP_DFY_DATA_0 }, + { 0x95800006, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x9a400003, mmCP_DFY_DATA_0 }, + { 0xd981325d, mmCP_DFY_DATA_0 }, + { 0x80000915, mmCP_DFY_DATA_0 }, + { 0xd9c1325d, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9bc0fff6, mmCP_DFY_DATA_0 }, + { 0x7f818001, mmCP_DFY_DATA_0 }, + { 0x8c001606, mmCP_DFY_DATA_0 }, + { 0x7d838001, mmCP_DFY_DATA_0 }, + { 0x94800010, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc41d3259, mmCP_DFY_DATA_0 }, + { 0xc421325a, mmCP_DFY_DATA_0 }, + { 0x16240014, mmCP_DFY_DATA_0 }, + { 0x12640014, mmCP_DFY_DATA_0 }, + { 0x1a2801f0, mmCP_DFY_DATA_0 }, + { 0x12a80010, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0x7e2a000a, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x7e5e400a, mmCP_DFY_DATA_0 }, + { 0x9b800002, mmCP_DFY_DATA_0 }, + { 0x2264003f, mmCP_DFY_DATA_0 }, + { 0xce41325a, mmCP_DFY_DATA_0 }, + { 0xd8013259, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x8c00075e, mmCP_DFY_DATA_0 }, + { 0xc4af0228, mmCP_DFY_DATA_0 }, + { 0x043c0000, mmCP_DFY_DATA_0 }, + { 0x66d80001, mmCP_DFY_DATA_0 }, + { 0x95800010, mmCP_DFY_DATA_0 }, + { 0x04300002, mmCP_DFY_DATA_0 }, + { 0x1330000d, mmCP_DFY_DATA_0 }, + { 0x13f40014, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x04380040, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380060, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x07fc0001, mmCP_DFY_DATA_0 }, + { 0x56ec0001, mmCP_DFY_DATA_0 }, + { 0x33e80010, mmCP_DFY_DATA_0 }, + { 0x9680ffec, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x04a80948, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000094c, mmCP_DFY_DATA_0 }, + { 0x8000099b, mmCP_DFY_DATA_0 }, + { 0x800009e0, mmCP_DFY_DATA_0 }, + { 0x800009e0, mmCP_DFY_DATA_0 }, + { 0xc43c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d91801a, mmCP_DFY_DATA_0 }, + { 0x459801e0, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x2738000f, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8300011, mmCP_DFY_DATA_0 }, + { 0x97000033, mmCP_DFY_DATA_0 }, + { 0x45980008, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8340011, mmCP_DFY_DATA_0 }, + { 0x9740002c, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x13b80001, mmCP_DFY_DATA_0 }, + { 0xc79d3300, mmCP_DFY_DATA_0 }, + { 0xc7a13301, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xd8393300, mmCP_DFY_DATA_0 }, + { 0xc0260001, mmCP_DFY_DATA_0 }, + { 0xce793301, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x964011fe, mmCP_DFY_DATA_0 }, + { 0x7c028009, mmCP_DFY_DATA_0 }, + { 0x9740001c, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x99800004, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x06a80400, mmCP_DFY_DATA_0 }, + { 0x80000978, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0x29640001, mmCP_DFY_DATA_0 }, + { 0xce40001a, mmCP_DFY_DATA_0 }, + { 0x242c0000, mmCP_DFY_DATA_0 }, + { 0x06ec0400, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x9980fffd, mmCP_DFY_DATA_0 }, + { 0xc0260010, mmCP_DFY_DATA_0 }, + { 0xce41c078, mmCP_DFY_DATA_0 }, + { 0xcf01c080, mmCP_DFY_DATA_0 }, + { 0x57240020, mmCP_DFY_DATA_0 }, + { 0xce41c081, mmCP_DFY_DATA_0 }, + { 0xce81c082, mmCP_DFY_DATA_0 }, + { 0xcc01c083, mmCP_DFY_DATA_0 }, + { 0xc0260800, mmCP_DFY_DATA_0 }, + { 0x7e6e400a, mmCP_DFY_DATA_0 }, + { 0xce41c084, mmCP_DFY_DATA_0 }, + { 0x7eae8001, mmCP_DFY_DATA_0 }, + { 0x7f2f0011, mmCP_DFY_DATA_0 }, + { 0x80000978, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xcdf93300, mmCP_DFY_DATA_0 }, + { 0xce393301, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xcfc00008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7dda801a, mmCP_DFY_DATA_0 }, + { 0x7d41c001, mmCP_DFY_DATA_0 }, + { 0x7e838011, mmCP_DFY_DATA_0 }, + { 0xd84802e9, mmCP_DFY_DATA_0 }, + { 0x8c001802, mmCP_DFY_DATA_0 }, + { 0x469c0390, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4200011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4240011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4280011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc42c0011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4380011, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x8c0014df, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x31280014, mmCP_DFY_DATA_0 }, + { 0xce8802ef, mmCP_DFY_DATA_0 }, + { 0x9a800062, mmCP_DFY_DATA_0 }, + { 0x31280034, mmCP_DFY_DATA_0 }, + { 0x9a800060, mmCP_DFY_DATA_0 }, + { 0x04a809e8, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x800009ec, mmCP_DFY_DATA_0 }, + { 0x80000a45, mmCP_DFY_DATA_0 }, + { 0x80000a59, mmCP_DFY_DATA_0 }, + { 0x80000a59, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d91801a, mmCP_DFY_DATA_0 }, + { 0x45980400, mmCP_DFY_DATA_0 }, + { 0xc4b30258, mmCP_DFY_DATA_0 }, + { 0xc4a70250, mmCP_DFY_DATA_0 }, + { 0x53300020, mmCP_DFY_DATA_0 }, + { 0x7e72401a, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0x042c0020, mmCP_DFY_DATA_0 }, + { 0x66740001, mmCP_DFY_DATA_0 }, + { 0x97400041, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04383000, mmCP_DFY_DATA_0 }, + { 0xcf813267, mmCP_DFY_DATA_0 }, + { 0xc4393267, mmCP_DFY_DATA_0 }, + { 0x9b800001, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x1b38007e, mmCP_DFY_DATA_0 }, + { 0x33b40003, mmCP_DFY_DATA_0 }, + { 0x9b400003, mmCP_DFY_DATA_0 }, + { 0x4598001c, mmCP_DFY_DATA_0 }, + { 0x9740002f, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc40c0011, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4100011, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002eb, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002ec, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002ed, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002ee, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04382000, mmCP_DFY_DATA_0 }, + { 0xcf813267, mmCP_DFY_DATA_0 }, + { 0xd84802e9, mmCP_DFY_DATA_0 }, + { 0x8c001715, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04382000, mmCP_DFY_DATA_0 }, + { 0xcf813267, mmCP_DFY_DATA_0 }, + { 0x56640001, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x9ac0ffbc, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04341001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x94800005, mmCP_DFY_DATA_0 }, + { 0xc431ecaa, mmCP_DFY_DATA_0 }, + { 0x27300080, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000a55, mmCP_DFY_DATA_0 }, + { 0xc43130b6, mmCP_DFY_DATA_0 }, + { 0x233c0032, mmCP_DFY_DATA_0 }, + { 0xcfc130b6, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcf0130b6, mmCP_DFY_DATA_0 }, + { 0xc49302ef, mmCP_DFY_DATA_0 }, + { 0x99000003, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8413247, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04180001, mmCP_DFY_DATA_0 }, + { 0x5198001f, mmCP_DFY_DATA_0 }, + { 0xcd813268, mmCP_DFY_DATA_0 }, + { 0xc4193269, mmCP_DFY_DATA_0 }, + { 0x2598000f, mmCP_DFY_DATA_0 }, + { 0x9980fffe, mmCP_DFY_DATA_0 }, + { 0xd80002f1, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8013268, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04380001, mmCP_DFY_DATA_0 }, + { 0x53b8001f, mmCP_DFY_DATA_0 }, + { 0x7db9801a, mmCP_DFY_DATA_0 }, + { 0xcd813268, mmCP_DFY_DATA_0 }, + { 0x80000a5e, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01106, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcc412e01, mmCP_DFY_DATA_0 }, + { 0xcc412e02, mmCP_DFY_DATA_0 }, + { 0xcc412e03, mmCP_DFY_DATA_0 }, + { 0xcc412e00, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c010fd, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50640020, mmCP_DFY_DATA_0 }, + { 0x7ce4c01a, mmCP_DFY_DATA_0 }, + { 0xd0c00072, mmCP_DFY_DATA_0 }, + { 0xc80c0072, mmCP_DFY_DATA_0 }, + { 0x58e801fc, mmCP_DFY_DATA_0 }, + { 0x12a80009, mmCP_DFY_DATA_0 }, + { 0x2aa80000, mmCP_DFY_DATA_0 }, + { 0xd0c0001e, mmCP_DFY_DATA_0 }, + { 0xce80001c, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc424000f, mmCP_DFY_DATA_0 }, + { 0x9a40ffff, mmCP_DFY_DATA_0 }, + { 0x04240010, mmCP_DFY_DATA_0 }, + { 0x18dc01e2, mmCP_DFY_DATA_0 }, + { 0x7e5e4002, mmCP_DFY_DATA_0 }, + { 0x3e5c0003, mmCP_DFY_DATA_0 }, + { 0x3e540002, mmCP_DFY_DATA_0 }, + { 0x95c00006, mmCP_DFY_DATA_0 }, + { 0xc8180011, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0x55140020, mmCP_DFY_DATA_0 }, + { 0x80000aa2, mmCP_DFY_DATA_0 }, + { 0x9540000a, mmCP_DFY_DATA_0 }, + { 0xc8180011, mmCP_DFY_DATA_0 }, + { 0x44cc0008, mmCP_DFY_DATA_0 }, + { 0x55900020, mmCP_DFY_DATA_0 }, + { 0xd0c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc424000f, mmCP_DFY_DATA_0 }, + { 0x9a40ffff, mmCP_DFY_DATA_0 }, + { 0xc4140011, mmCP_DFY_DATA_0 }, + { 0x80000aa2, mmCP_DFY_DATA_0 }, + { 0x44cc0004, mmCP_DFY_DATA_0 }, + { 0xc4180011, mmCP_DFY_DATA_0 }, + { 0xd0c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc424000f, mmCP_DFY_DATA_0 }, + { 0x9a40ffff, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0x55140020, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcd812e01, mmCP_DFY_DATA_0 }, + { 0xcd012e02, mmCP_DFY_DATA_0 }, + { 0xcd412e03, mmCP_DFY_DATA_0 }, + { 0xcc412e00, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc4253249, mmCP_DFY_DATA_0 }, + { 0x2264003f, mmCP_DFY_DATA_0 }, + { 0xce413249, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc4253249, mmCP_DFY_DATA_0 }, + { 0x96400001, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xc410001a, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0xc4140028, mmCP_DFY_DATA_0 }, + { 0x95000005, mmCP_DFY_DATA_0 }, + { 0x1e64001f, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce413249, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x14d00010, mmCP_DFY_DATA_0 }, + { 0xc4180030, mmCP_DFY_DATA_0 }, + { 0xc41c0007, mmCP_DFY_DATA_0 }, + { 0x99000004, mmCP_DFY_DATA_0 }, + { 0x99400009, mmCP_DFY_DATA_0 }, + { 0x9980000c, mmCP_DFY_DATA_0 }, + { 0x80000ab1, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xc420001c, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0x9a0010ac, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xd880003f, mmCP_DFY_DATA_0 }, + { 0x95c00002, mmCP_DFY_DATA_0 }, + { 0xd8c0003f, mmCP_DFY_DATA_0 }, + { 0x80001082, mmCP_DFY_DATA_0 }, + { 0xd8800040, mmCP_DFY_DATA_0 }, + { 0x95c00002, mmCP_DFY_DATA_0 }, + { 0xd8c00040, mmCP_DFY_DATA_0 }, + { 0x800010de, mmCP_DFY_DATA_0 }, + { 0xc010ffff, mmCP_DFY_DATA_0 }, + { 0x18d403f7, mmCP_DFY_DATA_0 }, + { 0x7d0cc009, mmCP_DFY_DATA_0 }, + { 0xc41b0367, mmCP_DFY_DATA_0 }, + { 0x7d958004, mmCP_DFY_DATA_0 }, + { 0x7d85800a, mmCP_DFY_DATA_0 }, + { 0xdc1e0000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d001fc, mmCP_DFY_DATA_0 }, + { 0x05280adc, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000af1, mmCP_DFY_DATA_0 }, + { 0x80000adf, mmCP_DFY_DATA_0 }, + { 0x80000ae7, mmCP_DFY_DATA_0 }, + { 0x8c000ace, mmCP_DFY_DATA_0 }, + { 0xd8c00013, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd8d2000, mmCP_DFY_DATA_0 }, + { 0x99c00010, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x18d803f7, mmCP_DFY_DATA_0 }, + { 0xc010ffff, mmCP_DFY_DATA_0 }, + { 0x7d0cc009, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0x11940014, mmCP_DFY_DATA_0 }, + { 0x29544001, mmCP_DFY_DATA_0 }, + { 0x9a400002, mmCP_DFY_DATA_0 }, + { 0x29544003, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x80000af4, mmCP_DFY_DATA_0 }, + { 0xd8c00013, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd44d2000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0xd8c00013, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd44dc000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d0003c, mmCP_DFY_DATA_0 }, + { 0x95000006, mmCP_DFY_DATA_0 }, + { 0x8c000ace, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcd8d2c00, mmCP_DFY_DATA_0 }, + { 0x99c00003, mmCP_DFY_DATA_0 }, + { 0x80000b0a, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xd44d2c00, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x28148004, mmCP_DFY_DATA_0 }, + { 0x24d800ff, mmCP_DFY_DATA_0 }, + { 0xccc00019, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd4593240, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c0105e, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x50540020, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x2198003f, mmCP_DFY_DATA_0 }, + { 0x199c0034, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x95c00028, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc42d324f, mmCP_DFY_DATA_0 }, + { 0xc4313255, mmCP_DFY_DATA_0 }, + { 0x7ef3400c, mmCP_DFY_DATA_0 }, + { 0x9b400021, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x14e80001, mmCP_DFY_DATA_0 }, + { 0x9a8000af, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x041c0002, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0xccc00010, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01043, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x50540020, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x18a01fe8, mmCP_DFY_DATA_0 }, + { 0x3620005c, mmCP_DFY_DATA_0 }, + { 0x9a00000e, mmCP_DFY_DATA_0 }, + { 0x2464003f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc6290ce7, mmCP_DFY_DATA_0 }, + { 0x16ac001f, mmCP_DFY_DATA_0 }, + { 0x96c00004, mmCP_DFY_DATA_0 }, + { 0x26ac003f, mmCP_DFY_DATA_0 }, + { 0x7ee6c00d, mmCP_DFY_DATA_0 }, + { 0x96c00005, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x2620000f, mmCP_DFY_DATA_0 }, + { 0x9a00fff8, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xce000367, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x9640102e, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x199c0037, mmCP_DFY_DATA_0 }, + { 0x19a00035, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x95c0005d, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xc42d3256, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0x16f8001f, mmCP_DFY_DATA_0 }, + { 0x9780000d, mmCP_DFY_DATA_0 }, + { 0xc4253248, mmCP_DFY_DATA_0 }, + { 0xc035f0ff, mmCP_DFY_DATA_0 }, + { 0x7e764009, mmCP_DFY_DATA_0 }, + { 0x19b401f8, mmCP_DFY_DATA_0 }, + { 0x13740008, mmCP_DFY_DATA_0 }, + { 0x7e76400a, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce413248, mmCP_DFY_DATA_0 }, + { 0xcf01325a, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xd1000072, mmCP_DFY_DATA_0 }, + { 0xc8100072, mmCP_DFY_DATA_0 }, + { 0x55140020, mmCP_DFY_DATA_0 }, + { 0x199c0034, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0x9b800004, mmCP_DFY_DATA_0 }, + { 0x1ae4003e, mmCP_DFY_DATA_0 }, + { 0xce400008, mmCP_DFY_DATA_0 }, + { 0x80000b7c, mmCP_DFY_DATA_0 }, + { 0xc4353254, mmCP_DFY_DATA_0 }, + { 0x16a80008, mmCP_DFY_DATA_0 }, + { 0x1aec003c, mmCP_DFY_DATA_0 }, + { 0x19a4003f, mmCP_DFY_DATA_0 }, + { 0x12a80015, mmCP_DFY_DATA_0 }, + { 0x12ec001f, mmCP_DFY_DATA_0 }, + { 0x1374000b, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc02e4000, mmCP_DFY_DATA_0 }, + { 0x1774000d, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xce400008, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0xc43d3248, mmCP_DFY_DATA_0 }, + { 0x1bfc01e8, mmCP_DFY_DATA_0 }, + { 0x13fc0018, mmCP_DFY_DATA_0 }, + { 0x7dbd800a, mmCP_DFY_DATA_0 }, + { 0x1d98ff15, mmCP_DFY_DATA_0 }, + { 0x592c00fc, mmCP_DFY_DATA_0 }, + { 0xcd80000a, mmCP_DFY_DATA_0 }, + { 0x12e00016, mmCP_DFY_DATA_0 }, + { 0x7da1800a, mmCP_DFY_DATA_0 }, + { 0x592c007e, mmCP_DFY_DATA_0 }, + { 0x12e00015, mmCP_DFY_DATA_0 }, + { 0x7da1800a, mmCP_DFY_DATA_0 }, + { 0xd1000001, mmCP_DFY_DATA_0 }, + { 0xcd800001, mmCP_DFY_DATA_0 }, + { 0x11a0000c, mmCP_DFY_DATA_0 }, + { 0x1264001e, mmCP_DFY_DATA_0 }, + { 0x1620000c, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x7e32000a, mmCP_DFY_DATA_0 }, + { 0x12e4001b, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x5924007e, mmCP_DFY_DATA_0 }, + { 0x12640017, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x19a4003c, mmCP_DFY_DATA_0 }, + { 0x12640018, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xce01325a, mmCP_DFY_DATA_0 }, + { 0xcd013257, mmCP_DFY_DATA_0 }, + { 0xcd413258, mmCP_DFY_DATA_0 }, + { 0xc429325a, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c00fdb, mmCP_DFY_DATA_0 }, + { 0x96800001, mmCP_DFY_DATA_0 }, + { 0x95c00003, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x9780f5ca, mmCP_DFY_DATA_0 }, + { 0xcf400100, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001219, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0xccc00010, mmCP_DFY_DATA_0 }, + { 0x8c001b6d, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc42d324e, mmCP_DFY_DATA_0 }, + { 0xc431324d, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc435324f, mmCP_DFY_DATA_0 }, + { 0xc4293256, mmCP_DFY_DATA_0 }, + { 0x52ec0008, mmCP_DFY_DATA_0 }, + { 0x07740003, mmCP_DFY_DATA_0 }, + { 0x04240002, mmCP_DFY_DATA_0 }, + { 0x269c003f, mmCP_DFY_DATA_0 }, + { 0x7e5e4004, mmCP_DFY_DATA_0 }, + { 0x7f67000f, mmCP_DFY_DATA_0 }, + { 0x97000003, mmCP_DFY_DATA_0 }, + { 0x7f674002, mmCP_DFY_DATA_0 }, + { 0x0b740001, mmCP_DFY_DATA_0 }, + { 0x53740002, mmCP_DFY_DATA_0 }, + { 0x7ef6c011, mmCP_DFY_DATA_0 }, + { 0x1ab42010, mmCP_DFY_DATA_0 }, + { 0x1ab8c006, mmCP_DFY_DATA_0 }, + { 0x16a8000c, mmCP_DFY_DATA_0 }, + { 0x26a80800, mmCP_DFY_DATA_0 }, + { 0x2b740000, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0xcf40001c, mmCP_DFY_DATA_0 }, + { 0xd2c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4180011, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0x8c000bec, mmCP_DFY_DATA_0 }, + { 0x80000b47, mmCP_DFY_DATA_0 }, + { 0xc42c001d, mmCP_DFY_DATA_0 }, + { 0xc4313256, mmCP_DFY_DATA_0 }, + { 0x1b34060b, mmCP_DFY_DATA_0 }, + { 0x1b300077, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x13300017, mmCP_DFY_DATA_0 }, + { 0x04340100, mmCP_DFY_DATA_0 }, + { 0x26ec00ff, mmCP_DFY_DATA_0 }, + { 0xc03a8004, mmCP_DFY_DATA_0 }, + { 0x7ef6c00a, mmCP_DFY_DATA_0 }, + { 0x7f3b000a, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc40c0032, mmCP_DFY_DATA_0 }, + { 0xc410001d, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc415325b, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x18580037, mmCP_DFY_DATA_0 }, + { 0x251000ff, mmCP_DFY_DATA_0 }, + { 0xc421325d, mmCP_DFY_DATA_0 }, + { 0x262001ef, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x99800004, mmCP_DFY_DATA_0 }, + { 0x7d15400a, mmCP_DFY_DATA_0 }, + { 0xcd41325b, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x1d54001f, mmCP_DFY_DATA_0 }, + { 0xcd41325b, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc428000b, mmCP_DFY_DATA_0 }, + { 0xc42c000c, mmCP_DFY_DATA_0 }, + { 0x12a80001, mmCP_DFY_DATA_0 }, + { 0x26a80004, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0xc4340028, mmCP_DFY_DATA_0 }, + { 0x14f00010, mmCP_DFY_DATA_0 }, + { 0xc4380030, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xcd280200, mmCP_DFY_DATA_0 }, + { 0xcd680208, mmCP_DFY_DATA_0 }, + { 0xcda80210, mmCP_DFY_DATA_0 }, + { 0x9b00000c, mmCP_DFY_DATA_0 }, + { 0x9b400014, mmCP_DFY_DATA_0 }, + { 0x9b800017, mmCP_DFY_DATA_0 }, + { 0xc428000b, mmCP_DFY_DATA_0 }, + { 0xc42c000c, mmCP_DFY_DATA_0 }, + { 0x12a80001, mmCP_DFY_DATA_0 }, + { 0x26a80004, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc6930200, mmCP_DFY_DATA_0 }, + { 0xc6970208, mmCP_DFY_DATA_0 }, + { 0xc69b0210, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b000005, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd900003f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd940003f, mmCP_DFY_DATA_0 }, + { 0x80001082, mmCP_DFY_DATA_0 }, + { 0xd9000040, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd9400040, mmCP_DFY_DATA_0 }, + { 0x800010de, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14fc0011, mmCP_DFY_DATA_0 }, + { 0x24f800ff, mmCP_DFY_DATA_0 }, + { 0x33b80001, mmCP_DFY_DATA_0 }, + { 0x97c0fffc, mmCP_DFY_DATA_0 }, + { 0x9b800007, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0x7d83c001, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4093249, mmCP_DFY_DATA_0 }, + { 0x1888003e, mmCP_DFY_DATA_0 }, + { 0x94800020, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0x9a400009, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc419324c, mmCP_DFY_DATA_0 }, + { 0x259c0001, mmCP_DFY_DATA_0 }, + { 0x1598001f, mmCP_DFY_DATA_0 }, + { 0x95c00016, mmCP_DFY_DATA_0 }, + { 0x95800015, mmCP_DFY_DATA_0 }, + { 0x99000003, mmCP_DFY_DATA_0 }, + { 0xd8400036, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14d80011, mmCP_DFY_DATA_0 }, + { 0x24e000ff, mmCP_DFY_DATA_0 }, + { 0x321c0002, mmCP_DFY_DATA_0 }, + { 0x32200001, mmCP_DFY_DATA_0 }, + { 0x9580ffee, mmCP_DFY_DATA_0 }, + { 0x99c00014, mmCP_DFY_DATA_0 }, + { 0x96000004, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x04140001, mmCP_DFY_DATA_0 }, + { 0x80000c30, mmCP_DFY_DATA_0 }, + { 0x9480000a, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95800f29, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x94800004, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95800f23, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0x99400002, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x94800004, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95800f1a, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0xd8800036, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x041c0003, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xc40c0077, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x9600f502, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x98c0f500, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0x9a000f05, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0xc42d3256, mmCP_DFY_DATA_0 }, + { 0x1f30001f, mmCP_DFY_DATA_0 }, + { 0x16e4001f, mmCP_DFY_DATA_0 }, + { 0xcf01325a, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x9640f4f4, mmCP_DFY_DATA_0 }, + { 0xc434000b, mmCP_DFY_DATA_0 }, + { 0x33740002, mmCP_DFY_DATA_0 }, + { 0x9b40f4f1, mmCP_DFY_DATA_0 }, + { 0xc4353254, mmCP_DFY_DATA_0 }, + { 0x16a80008, mmCP_DFY_DATA_0 }, + { 0x1aec003c, mmCP_DFY_DATA_0 }, + { 0x12a80015, mmCP_DFY_DATA_0 }, + { 0x12ec001f, mmCP_DFY_DATA_0 }, + { 0x1374000b, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc02e4000, mmCP_DFY_DATA_0 }, + { 0x1774000d, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0xcf400100, mmCP_DFY_DATA_0 }, + { 0x12780001, mmCP_DFY_DATA_0 }, + { 0x2bb80001, mmCP_DFY_DATA_0 }, + { 0xc00ac005, mmCP_DFY_DATA_0 }, + { 0xc00e0002, mmCP_DFY_DATA_0 }, + { 0x28cc8000, mmCP_DFY_DATA_0 }, + { 0x28884900, mmCP_DFY_DATA_0 }, + { 0x28cc0014, mmCP_DFY_DATA_0 }, + { 0x80000ff3, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x17fc0001, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x96400ee1, mmCP_DFY_DATA_0 }, + { 0xcc41c40a, mmCP_DFY_DATA_0 }, + { 0xcc41c40c, mmCP_DFY_DATA_0 }, + { 0xcc41c40d, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x24d0007f, mmCP_DFY_DATA_0 }, + { 0x15580010, mmCP_DFY_DATA_0 }, + { 0x255400ff, mmCP_DFY_DATA_0 }, + { 0xcd01c411, mmCP_DFY_DATA_0 }, + { 0xcd81c40f, mmCP_DFY_DATA_0 }, + { 0xcd41c40e, mmCP_DFY_DATA_0 }, + { 0xcc41c410, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x04200000, mmCP_DFY_DATA_0 }, + { 0x18e80033, mmCP_DFY_DATA_0 }, + { 0x18ec0034, mmCP_DFY_DATA_0 }, + { 0xcc41c414, mmCP_DFY_DATA_0 }, + { 0xcc41c415, mmCP_DFY_DATA_0 }, + { 0xcd81c413, mmCP_DFY_DATA_0 }, + { 0xcd41c412, mmCP_DFY_DATA_0 }, + { 0x18dc0032, mmCP_DFY_DATA_0 }, + { 0x7c030011, mmCP_DFY_DATA_0 }, + { 0x7c038011, mmCP_DFY_DATA_0 }, + { 0x95c00027, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xc431c417, mmCP_DFY_DATA_0 }, + { 0xc435c416, mmCP_DFY_DATA_0 }, + { 0x96800004, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xc439c419, mmCP_DFY_DATA_0 }, + { 0xc43dc418, mmCP_DFY_DATA_0 }, + { 0xc41c000e, mmCP_DFY_DATA_0 }, + { 0x29dc0008, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xcf413261, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xcf013262, mmCP_DFY_DATA_0 }, + { 0x96800004, mmCP_DFY_DATA_0 }, + { 0xcfc13263, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xcf813264, mmCP_DFY_DATA_0 }, + { 0x18dc0030, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x95c00017, mmCP_DFY_DATA_0 }, + { 0x17fc0001, mmCP_DFY_DATA_0 }, + { 0x9ac00005, mmCP_DFY_DATA_0 }, + { 0x7d77000c, mmCP_DFY_DATA_0 }, + { 0x9bc00015, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0x80000cd6, mmCP_DFY_DATA_0 }, + { 0x51b80020, mmCP_DFY_DATA_0 }, + { 0x53300020, mmCP_DFY_DATA_0 }, + { 0x7f97801a, mmCP_DFY_DATA_0 }, + { 0x7f37001a, mmCP_DFY_DATA_0 }, + { 0x7f3b000c, mmCP_DFY_DATA_0 }, + { 0x9bc0000d, mmCP_DFY_DATA_0 }, + { 0x97800002, mmCP_DFY_DATA_0 }, + { 0x80000cd6, mmCP_DFY_DATA_0 }, + { 0x9a000018, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x28200001, mmCP_DFY_DATA_0 }, + { 0x80000ca7, mmCP_DFY_DATA_0 }, + { 0x18dc0031, mmCP_DFY_DATA_0 }, + { 0x95c00003, mmCP_DFY_DATA_0 }, + { 0xc435c40b, mmCP_DFY_DATA_0 }, + { 0x9740fffd, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc4280032, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x800012c2, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x1bb81ff0, mmCP_DFY_DATA_0 }, + { 0x7f8cc00a, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0xc43d3256, mmCP_DFY_DATA_0 }, + { 0x1bf0060b, mmCP_DFY_DATA_0 }, + { 0x1bfc0077, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x80000cf4, mmCP_DFY_DATA_0 }, + { 0xc43d325a, mmCP_DFY_DATA_0 }, + { 0x1bfc0677, mmCP_DFY_DATA_0 }, + { 0x13fc0017, mmCP_DFY_DATA_0 }, + { 0x04300100, mmCP_DFY_DATA_0 }, + { 0x1bb81fe8, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xc032800b, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x7ffbc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d42011, mmCP_DFY_DATA_0 }, + { 0x17fc0001, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x24cc007f, mmCP_DFY_DATA_0 }, + { 0x7cd4c00a, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc428005e, mmCP_DFY_DATA_0 }, + { 0x96800e6c, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x596001fc, mmCP_DFY_DATA_0 }, + { 0x12200009, mmCP_DFY_DATA_0 }, + { 0x7ce0c00a, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x505c0020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x50600020, mmCP_DFY_DATA_0 }, + { 0x7de1c01a, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xccc0001b, mmCP_DFY_DATA_0 }, + { 0xd140001d, mmCP_DFY_DATA_0 }, + { 0xd180001f, mmCP_DFY_DATA_0 }, + { 0xd1c00020, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x95000010, mmCP_DFY_DATA_0 }, + { 0x04300000, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8240010, mmCP_DFY_DATA_0 }, + { 0x7e5e800c, mmCP_DFY_DATA_0 }, + { 0x9bc00015, mmCP_DFY_DATA_0 }, + { 0x9a80000c, mmCP_DFY_DATA_0 }, + { 0x9b000024, mmCP_DFY_DATA_0 }, + { 0x28300001, mmCP_DFY_DATA_0 }, + { 0x122c0004, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x80000d1f, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8240010, mmCP_DFY_DATA_0 }, + { 0x566c0020, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce413261, mmCP_DFY_DATA_0 }, + { 0xcec13262, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc4340032, mmCP_DFY_DATA_0 }, + { 0x2b740008, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x96800005, mmCP_DFY_DATA_0 }, + { 0x566c0020, mmCP_DFY_DATA_0 }, + { 0xce413261, mmCP_DFY_DATA_0 }, + { 0xcec13262, mmCP_DFY_DATA_0 }, + { 0x800012c2, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x1bb81fe8, mmCP_DFY_DATA_0 }, + { 0x7f8cc00a, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0xc43d3256, mmCP_DFY_DATA_0 }, + { 0x1bf0060b, mmCP_DFY_DATA_0 }, + { 0x1bfc0077, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x80000d57, mmCP_DFY_DATA_0 }, + { 0xc43d325a, mmCP_DFY_DATA_0 }, + { 0x1bfc0677, mmCP_DFY_DATA_0 }, + { 0x13fc0017, mmCP_DFY_DATA_0 }, + { 0x04300100, mmCP_DFY_DATA_0 }, + { 0x1bb81fe8, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xc0328009, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x7ffbc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4253246, mmCP_DFY_DATA_0 }, + { 0xc4113245, mmCP_DFY_DATA_0 }, + { 0x04143000, mmCP_DFY_DATA_0 }, + { 0xcd413267, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e51001a, mmCP_DFY_DATA_0 }, + { 0xc4153267, mmCP_DFY_DATA_0 }, + { 0x7d2d0011, mmCP_DFY_DATA_0 }, + { 0x19640057, mmCP_DFY_DATA_0 }, + { 0x19580213, mmCP_DFY_DATA_0 }, + { 0x19600199, mmCP_DFY_DATA_0 }, + { 0x7da6400a, mmCP_DFY_DATA_0 }, + { 0x7e26400a, mmCP_DFY_DATA_0 }, + { 0xd1000025, mmCP_DFY_DATA_0 }, + { 0xce400024, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x04142000, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcd413267, mmCP_DFY_DATA_0 }, + { 0xc4153267, mmCP_DFY_DATA_0 }, + { 0x99400001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x18d40030, mmCP_DFY_DATA_0 }, + { 0x18d80034, mmCP_DFY_DATA_0 }, + { 0x05280d83, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0x7c424001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000d8a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x80000d95, mmCP_DFY_DATA_0 }, + { 0x80000db1, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x80000d95, mmCP_DFY_DATA_0 }, + { 0x80000dbc, mmCP_DFY_DATA_0 }, + { 0x11540010, mmCP_DFY_DATA_0 }, + { 0x7e010001, mmCP_DFY_DATA_0 }, + { 0x8c00187c, mmCP_DFY_DATA_0 }, + { 0x7d75400a, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd4610000, mmCP_DFY_DATA_0 }, + { 0x9580f3d8, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8000016, mmCP_DFY_DATA_0 }, + { 0x526c0020, mmCP_DFY_DATA_0 }, + { 0x18e80058, mmCP_DFY_DATA_0 }, + { 0x7e2ec01a, mmCP_DFY_DATA_0 }, + { 0xd2c00072, mmCP_DFY_DATA_0 }, + { 0xc82c0072, mmCP_DFY_DATA_0 }, + { 0x5ae0073a, mmCP_DFY_DATA_0 }, + { 0x7ea2800a, mmCP_DFY_DATA_0 }, + { 0x9940000a, mmCP_DFY_DATA_0 }, + { 0xce800024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9580f3c6, mmCP_DFY_DATA_0 }, + { 0xc4380012, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xdc3a0000, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0xce800024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xcc400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9b80fffb, mmCP_DFY_DATA_0 }, + { 0x9980fff5, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc02a0001, mmCP_DFY_DATA_0 }, + { 0x2aa80001, mmCP_DFY_DATA_0 }, + { 0x16200002, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce01c405, mmCP_DFY_DATA_0 }, + { 0xd441c406, mmCP_DFY_DATA_0 }, + { 0x9580f3b1, mmCP_DFY_DATA_0 }, + { 0xc439c409, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a40000b, mmCP_DFY_DATA_0 }, + { 0x11540010, mmCP_DFY_DATA_0 }, + { 0x29540002, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd4610000, mmCP_DFY_DATA_0 }, + { 0x9580f3a5, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c00da7, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50500020, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0xd0c00072, mmCP_DFY_DATA_0 }, + { 0xc8280072, mmCP_DFY_DATA_0 }, + { 0x5aac007e, mmCP_DFY_DATA_0 }, + { 0x12d80017, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7d9d800a, mmCP_DFY_DATA_0 }, + { 0x56a00020, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0x7da1800a, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7e82400a, mmCP_DFY_DATA_0 }, + { 0x7e58c01a, mmCP_DFY_DATA_0 }, + { 0x19d4003d, mmCP_DFY_DATA_0 }, + { 0x28182002, mmCP_DFY_DATA_0 }, + { 0x99400030, mmCP_DFY_DATA_0 }, + { 0x8c00104f, mmCP_DFY_DATA_0 }, + { 0xc430000d, mmCP_DFY_DATA_0 }, + { 0xc4340035, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc8140023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0xc011000f, mmCP_DFY_DATA_0 }, + { 0xc4240004, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x7c908009, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x7d614011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7ca4800a, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x7cb0800a, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0x20880188, mmCP_DFY_DATA_0 }, + { 0x54ec0020, mmCP_DFY_DATA_0 }, + { 0x7cb4800a, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x04380008, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x20240090, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0x28240004, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x9a800005, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xd8000016, mmCP_DFY_DATA_0 }, + { 0xcf80003a, mmCP_DFY_DATA_0 }, + { 0xd901a2a4, mmCP_DFY_DATA_0 }, + { 0x80001037, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x1624001f, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0xd841325f, mmCP_DFY_DATA_0 }, + { 0xd8800033, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0004, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8000039, mmCP_DFY_DATA_0 }, + { 0xd0c00038, mmCP_DFY_DATA_0 }, + { 0xc43c0022, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0xc429325f, mmCP_DFY_DATA_0 }, + { 0x26ac0001, mmCP_DFY_DATA_0 }, + { 0x9ac0fffe, mmCP_DFY_DATA_0 }, + { 0x26ac0002, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0xd8800033, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x1b301ff0, mmCP_DFY_DATA_0 }, + { 0x2b300300, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x9680000b, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0004, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400039, mmCP_DFY_DATA_0 }, + { 0xd0c00038, mmCP_DFY_DATA_0 }, + { 0xc43c0022, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0x8c0001a2, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0x24b00008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x18ac0024, mmCP_DFY_DATA_0 }, + { 0x2b304000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4113249, mmCP_DFY_DATA_0 }, + { 0x1910003e, mmCP_DFY_DATA_0 }, + { 0x99000002, mmCP_DFY_DATA_0 }, + { 0xd840003d, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0xcf01326c, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x12a80014, mmCP_DFY_DATA_0 }, + { 0x2220003f, mmCP_DFY_DATA_0 }, + { 0x7e2a000a, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xce01326c, mmCP_DFY_DATA_0 }, + { 0xd8800033, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0004, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8000039, mmCP_DFY_DATA_0 }, + { 0xd0c00038, mmCP_DFY_DATA_0 }, + { 0xc43c0022, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18dc003d, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0x041c0001, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x18d40030, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x18fc0034, mmCP_DFY_DATA_0 }, + { 0x24e8000f, mmCP_DFY_DATA_0 }, + { 0x06a80e71, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000edd, mmCP_DFY_DATA_0 }, + { 0x80000e91, mmCP_DFY_DATA_0 }, + { 0x80000e91, mmCP_DFY_DATA_0 }, + { 0x80000ea1, mmCP_DFY_DATA_0 }, + { 0x80000eaa, mmCP_DFY_DATA_0 }, + { 0x80000e7c, mmCP_DFY_DATA_0 }, + { 0x80000e7f, mmCP_DFY_DATA_0 }, + { 0x80000e7f, mmCP_DFY_DATA_0 }, + { 0x80000e87, mmCP_DFY_DATA_0 }, + { 0x80000e8f, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x51dc0020, mmCP_DFY_DATA_0 }, + { 0x7d9e001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0xc420000e, mmCP_DFY_DATA_0 }, + { 0x2a200008, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0xc4213262, mmCP_DFY_DATA_0 }, + { 0xc4253261, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0xc420000e, mmCP_DFY_DATA_0 }, + { 0x2a200008, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0xc4213264, mmCP_DFY_DATA_0 }, + { 0xc4253263, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0xc820001f, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0x18e82005, mmCP_DFY_DATA_0 }, + { 0x51e00020, mmCP_DFY_DATA_0 }, + { 0x2aa80000, mmCP_DFY_DATA_0 }, + { 0x7da1801a, mmCP_DFY_DATA_0 }, + { 0xd1800072, mmCP_DFY_DATA_0 }, + { 0xc8180072, mmCP_DFY_DATA_0 }, + { 0x59a001fc, mmCP_DFY_DATA_0 }, + { 0x12200009, mmCP_DFY_DATA_0 }, + { 0x7ea2800a, mmCP_DFY_DATA_0 }, + { 0xce80001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8200011, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0x15980002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd81c400, mmCP_DFY_DATA_0 }, + { 0xc421c401, mmCP_DFY_DATA_0 }, + { 0x95400041, mmCP_DFY_DATA_0 }, + { 0xc425c401, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0x31ac2580, mmCP_DFY_DATA_0 }, + { 0x9ac00011, mmCP_DFY_DATA_0 }, + { 0x31ac260c, mmCP_DFY_DATA_0 }, + { 0x9ac0000f, mmCP_DFY_DATA_0 }, + { 0x31ac0800, mmCP_DFY_DATA_0 }, + { 0x9ac0000d, mmCP_DFY_DATA_0 }, + { 0x31ac0828, mmCP_DFY_DATA_0 }, + { 0x9ac0000b, mmCP_DFY_DATA_0 }, + { 0x31ac2440, mmCP_DFY_DATA_0 }, + { 0x9ac00009, mmCP_DFY_DATA_0 }, + { 0x31ac2390, mmCP_DFY_DATA_0 }, + { 0x9ac00007, mmCP_DFY_DATA_0 }, + { 0x31ac0093, mmCP_DFY_DATA_0 }, + { 0x9ac00005, mmCP_DFY_DATA_0 }, + { 0x31ac31dc, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x31ac31e6, mmCP_DFY_DATA_0 }, + { 0x96c00004, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x80000ede, mmCP_DFY_DATA_0 }, + { 0x39ac7c06, mmCP_DFY_DATA_0 }, + { 0x3db07c00, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39acc337, mmCP_DFY_DATA_0 }, + { 0x3db0c330, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39acc335, mmCP_DFY_DATA_0 }, + { 0x3db0c336, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39ac9002, mmCP_DFY_DATA_0 }, + { 0x3db09001, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39ac9012, mmCP_DFY_DATA_0 }, + { 0x3db09011, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39acec70, mmCP_DFY_DATA_0 }, + { 0x3db0ec6f, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc5a10000, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0x05980001, mmCP_DFY_DATA_0 }, + { 0xc5a50000, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x05280eea, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000ef1, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x80000efe, mmCP_DFY_DATA_0 }, + { 0x80000f11, mmCP_DFY_DATA_0 }, + { 0x80000f2e, mmCP_DFY_DATA_0 }, + { 0x80000efe, mmCP_DFY_DATA_0 }, + { 0x80000f1f, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0x05980001, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x97c0f26f, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x51ec0020, mmCP_DFY_DATA_0 }, + { 0x18e80058, mmCP_DFY_DATA_0 }, + { 0x7daec01a, mmCP_DFY_DATA_0 }, + { 0xd2c00072, mmCP_DFY_DATA_0 }, + { 0xc82c0072, mmCP_DFY_DATA_0 }, + { 0x5af8073a, mmCP_DFY_DATA_0 }, + { 0x7eba800a, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xce800024, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0x95400003, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x97c0f25c, mmCP_DFY_DATA_0 }, + { 0xc4380012, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc02a0001, mmCP_DFY_DATA_0 }, + { 0x2aa80001, mmCP_DFY_DATA_0 }, + { 0x15980002, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xcd81c405, mmCP_DFY_DATA_0 }, + { 0xce01c406, mmCP_DFY_DATA_0 }, + { 0x95400003, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xce41c406, mmCP_DFY_DATA_0 }, + { 0x97c0f24e, mmCP_DFY_DATA_0 }, + { 0xc439c409, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a40f247, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0x95400004, mmCP_DFY_DATA_0 }, + { 0x05980001, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0x97c0f240, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x31ac2580, mmCP_DFY_DATA_0 }, + { 0x9ac00011, mmCP_DFY_DATA_0 }, + { 0x31ac260c, mmCP_DFY_DATA_0 }, + { 0x9ac0000f, mmCP_DFY_DATA_0 }, + { 0x31ac0800, mmCP_DFY_DATA_0 }, + { 0x9ac0000d, mmCP_DFY_DATA_0 }, + { 0x31ac0828, mmCP_DFY_DATA_0 }, + { 0x9ac0000b, mmCP_DFY_DATA_0 }, + { 0x31ac2440, mmCP_DFY_DATA_0 }, + { 0x9ac00009, mmCP_DFY_DATA_0 }, + { 0x31ac2390, mmCP_DFY_DATA_0 }, + { 0x9ac00007, mmCP_DFY_DATA_0 }, + { 0x31ac0093, mmCP_DFY_DATA_0 }, + { 0x9ac00005, mmCP_DFY_DATA_0 }, + { 0x31ac31dc, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x31ac31e6, mmCP_DFY_DATA_0 }, + { 0x96c00004, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x80000ef2, mmCP_DFY_DATA_0 }, + { 0x39ac7c06, mmCP_DFY_DATA_0 }, + { 0x3db07c00, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39acc337, mmCP_DFY_DATA_0 }, + { 0x3db0c330, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39acc335, mmCP_DFY_DATA_0 }, + { 0x3db0c336, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39acec70, mmCP_DFY_DATA_0 }, + { 0x3db0ec6f, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39ac9002, mmCP_DFY_DATA_0 }, + { 0x3db09002, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39ac9012, mmCP_DFY_DATA_0 }, + { 0x3db09012, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x80000ef1, mmCP_DFY_DATA_0 }, + { 0xc40c0006, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x95c00001, mmCP_DFY_DATA_0 }, + { 0xc434000e, mmCP_DFY_DATA_0 }, + { 0x2b740008, mmCP_DFY_DATA_0 }, + { 0x2b780001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd8c1325e, mmCP_DFY_DATA_0 }, + { 0xcf80001a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x7c034001, mmCP_DFY_DATA_0 }, + { 0x7c038001, mmCP_DFY_DATA_0 }, + { 0x18e0007d, mmCP_DFY_DATA_0 }, + { 0x32240003, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0x32240000, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xcd01c080, mmCP_DFY_DATA_0 }, + { 0xcd41c081, mmCP_DFY_DATA_0 }, + { 0x80000f88, mmCP_DFY_DATA_0 }, + { 0x51640020, mmCP_DFY_DATA_0 }, + { 0x7e52401a, mmCP_DFY_DATA_0 }, + { 0xd2400072, mmCP_DFY_DATA_0 }, + { 0xc8280072, mmCP_DFY_DATA_0 }, + { 0xce81c080, mmCP_DFY_DATA_0 }, + { 0x56ac0020, mmCP_DFY_DATA_0 }, + { 0x26f0ffff, mmCP_DFY_DATA_0 }, + { 0xcf01c081, mmCP_DFY_DATA_0 }, + { 0x1af000fc, mmCP_DFY_DATA_0 }, + { 0x1334000a, mmCP_DFY_DATA_0 }, + { 0x24e02000, mmCP_DFY_DATA_0 }, + { 0x7f63400a, mmCP_DFY_DATA_0 }, + { 0x18e00074, mmCP_DFY_DATA_0 }, + { 0x32240003, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0x32240000, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xcd81c082, mmCP_DFY_DATA_0 }, + { 0xcdc1c083, mmCP_DFY_DATA_0 }, + { 0x80000f9d, mmCP_DFY_DATA_0 }, + { 0x51e40020, mmCP_DFY_DATA_0 }, + { 0x7e5a401a, mmCP_DFY_DATA_0 }, + { 0xd2400072, mmCP_DFY_DATA_0 }, + { 0xc8280072, mmCP_DFY_DATA_0 }, + { 0xce81c082, mmCP_DFY_DATA_0 }, + { 0x56ac0020, mmCP_DFY_DATA_0 }, + { 0x26f0ffff, mmCP_DFY_DATA_0 }, + { 0xcf01c083, mmCP_DFY_DATA_0 }, + { 0x1af000fc, mmCP_DFY_DATA_0 }, + { 0x13380016, mmCP_DFY_DATA_0 }, + { 0x18e00039, mmCP_DFY_DATA_0 }, + { 0x12200019, mmCP_DFY_DATA_0 }, + { 0x7fa3800a, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x18e0007d, mmCP_DFY_DATA_0 }, + { 0x1220001d, mmCP_DFY_DATA_0 }, + { 0x7fa3800a, mmCP_DFY_DATA_0 }, + { 0x18e00074, mmCP_DFY_DATA_0 }, + { 0x12200014, mmCP_DFY_DATA_0 }, + { 0x7fa3800a, mmCP_DFY_DATA_0 }, + { 0xcf81c078, mmCP_DFY_DATA_0 }, + { 0xcfc1c084, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18dc003d, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0x041c0000, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x31140005, mmCP_DFY_DATA_0 }, + { 0x99400003, mmCP_DFY_DATA_0 }, + { 0x31140006, mmCP_DFY_DATA_0 }, + { 0x95400002, mmCP_DFY_DATA_0 }, + { 0x8c00104f, mmCP_DFY_DATA_0 }, + { 0x05280fb7, mmCP_DFY_DATA_0 }, + { 0x28140002, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000fbe, mmCP_DFY_DATA_0 }, + { 0x80000fbe, mmCP_DFY_DATA_0 }, + { 0x80000fc2, mmCP_DFY_DATA_0 }, + { 0x80000fbe, mmCP_DFY_DATA_0 }, + { 0x80000fd1, mmCP_DFY_DATA_0 }, + { 0x80000ff2, mmCP_DFY_DATA_0 }, + { 0x80000ff2, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x18e80039, mmCP_DFY_DATA_0 }, + { 0x52a8003b, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x7d69401a, mmCP_DFY_DATA_0 }, + { 0xc41c0017, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xd140004b, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc414000d, mmCP_DFY_DATA_0 }, + { 0x04180001, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0x7d958004, mmCP_DFY_DATA_0 }, + { 0xcd800035, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3249, mmCP_DFY_DATA_0 }, + { 0x1bfc003e, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0xc4100019, mmCP_DFY_DATA_0 }, + { 0x7d150005, mmCP_DFY_DATA_0 }, + { 0x25100001, mmCP_DFY_DATA_0 }, + { 0x9500000b, mmCP_DFY_DATA_0 }, + { 0x97c0fffc, mmCP_DFY_DATA_0 }, + { 0xc4180021, mmCP_DFY_DATA_0 }, + { 0x159c0011, mmCP_DFY_DATA_0 }, + { 0x259800ff, mmCP_DFY_DATA_0 }, + { 0x31a00003, mmCP_DFY_DATA_0 }, + { 0x31a40001, mmCP_DFY_DATA_0 }, + { 0x7e25800a, mmCP_DFY_DATA_0 }, + { 0x95c0fff5, mmCP_DFY_DATA_0 }, + { 0x9580fff4, mmCP_DFY_DATA_0 }, + { 0x80000fef, mmCP_DFY_DATA_0 }, + { 0xc411326f, mmCP_DFY_DATA_0 }, + { 0x1d100010, mmCP_DFY_DATA_0 }, + { 0xcd01326f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x04380000, mmCP_DFY_DATA_0 }, + { 0xc430000d, mmCP_DFY_DATA_0 }, + { 0xc8140023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0xc011000f, mmCP_DFY_DATA_0 }, + { 0xc4240004, mmCP_DFY_DATA_0 }, + { 0x33b40003, mmCP_DFY_DATA_0 }, + { 0x97400003, mmCP_DFY_DATA_0 }, + { 0xc0340008, mmCP_DFY_DATA_0 }, + { 0x80000ffe, mmCP_DFY_DATA_0 }, + { 0xc4340035, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x7c908009, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x7d614011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7ca4800a, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x7cb0800a, mmCP_DFY_DATA_0 }, + { 0x282c2002, mmCP_DFY_DATA_0 }, + { 0x208801a8, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0x7cb4800a, mmCP_DFY_DATA_0 }, + { 0xcec00013, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x042c0008, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x20240030, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0x9b800013, mmCP_DFY_DATA_0 }, + { 0xcc400026, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x28340000, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x507c0020, mmCP_DFY_DATA_0 }, + { 0x7d7d401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x557c0020, mmCP_DFY_DATA_0 }, + { 0x28342002, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcd400026, mmCP_DFY_DATA_0 }, + { 0xcfc00026, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0x9a80000e, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a80000b, mmCP_DFY_DATA_0 }, + { 0x8000102f, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x9a800005, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x1cccfe08, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcec0003a, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3249, mmCP_DFY_DATA_0 }, + { 0x1bfc003e, mmCP_DFY_DATA_0 }, + { 0x9bc00007, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x16a80008, mmCP_DFY_DATA_0 }, + { 0xce800009, mmCP_DFY_DATA_0 }, + { 0xc42c005e, mmCP_DFY_DATA_0 }, + { 0x96c00b33, mmCP_DFY_DATA_0 }, + { 0xd840003c, mmCP_DFY_DATA_0 }, + { 0xc4200025, mmCP_DFY_DATA_0 }, + { 0x7da2400f, mmCP_DFY_DATA_0 }, + { 0x7da28002, mmCP_DFY_DATA_0 }, + { 0x7e1ac002, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0x7d2ac002, mmCP_DFY_DATA_0 }, + { 0x3ef40010, mmCP_DFY_DATA_0 }, + { 0x9b40f11d, mmCP_DFY_DATA_0 }, + { 0x04380030, mmCP_DFY_DATA_0 }, + { 0xcf81325e, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xde410000, mmCP_DFY_DATA_0 }, + { 0xdcc10000, mmCP_DFY_DATA_0 }, + { 0xdd010000, mmCP_DFY_DATA_0 }, + { 0xdd410000, mmCP_DFY_DATA_0 }, + { 0xdd810000, mmCP_DFY_DATA_0 }, + { 0xddc10000, mmCP_DFY_DATA_0 }, + { 0xde010000, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x7c024001, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc8100086, mmCP_DFY_DATA_0 }, + { 0x5510003f, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x99000011, mmCP_DFY_DATA_0 }, + { 0x80001075, mmCP_DFY_DATA_0 }, + { 0x9900000c, mmCP_DFY_DATA_0 }, + { 0xc40c0026, mmCP_DFY_DATA_0 }, + { 0xc4100081, mmCP_DFY_DATA_0 }, + { 0xc4140025, mmCP_DFY_DATA_0 }, + { 0x7d15800f, mmCP_DFY_DATA_0 }, + { 0x7d15c002, mmCP_DFY_DATA_0 }, + { 0x7d520002, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x7cde0002, mmCP_DFY_DATA_0 }, + { 0x3e20001a, mmCP_DFY_DATA_0 }, + { 0x9a000009, mmCP_DFY_DATA_0 }, + { 0x040c0030, mmCP_DFY_DATA_0 }, + { 0xccc1325e, mmCP_DFY_DATA_0 }, + { 0x80001071, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c00b01, mmCP_DFY_DATA_0 }, + { 0x04240001, mmCP_DFY_DATA_0 }, + { 0xdc200000, mmCP_DFY_DATA_0 }, + { 0xdc1c0000, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0x96400004, mmCP_DFY_DATA_0 }, + { 0xdc240000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xdc240000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcc40003f, mmCP_DFY_DATA_0 }, + { 0xd8c00010, mmCP_DFY_DATA_0 }, + { 0xc4080029, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x18a400e5, mmCP_DFY_DATA_0 }, + { 0x12500009, mmCP_DFY_DATA_0 }, + { 0x248c0008, mmCP_DFY_DATA_0 }, + { 0x94c00006, mmCP_DFY_DATA_0 }, + { 0x200c006d, mmCP_DFY_DATA_0 }, + { 0x7cd0c00a, mmCP_DFY_DATA_0 }, + { 0xccc1326c, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x200c0228, mmCP_DFY_DATA_0 }, + { 0x7cd0c00a, mmCP_DFY_DATA_0 }, + { 0xccc1326c, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xc40c002a, mmCP_DFY_DATA_0 }, + { 0xc410002b, mmCP_DFY_DATA_0 }, + { 0x18881fe8, mmCP_DFY_DATA_0 }, + { 0x18d4072c, mmCP_DFY_DATA_0 }, + { 0x18cc00d1, mmCP_DFY_DATA_0 }, + { 0x7cd4c00a, mmCP_DFY_DATA_0 }, + { 0x3094000d, mmCP_DFY_DATA_0 }, + { 0x38d80000, mmCP_DFY_DATA_0 }, + { 0x311c0003, mmCP_DFY_DATA_0 }, + { 0x99400006, mmCP_DFY_DATA_0 }, + { 0x30940007, mmCP_DFY_DATA_0 }, + { 0x1620001f, mmCP_DFY_DATA_0 }, + { 0x9940001d, mmCP_DFY_DATA_0 }, + { 0x9a000023, mmCP_DFY_DATA_0 }, + { 0x800010c4, mmCP_DFY_DATA_0 }, + { 0x9580001a, mmCP_DFY_DATA_0 }, + { 0x99c00019, mmCP_DFY_DATA_0 }, + { 0xccc00041, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0xc418002c, mmCP_DFY_DATA_0 }, + { 0x9940000d, mmCP_DFY_DATA_0 }, + { 0x259c007f, mmCP_DFY_DATA_0 }, + { 0x95c00013, mmCP_DFY_DATA_0 }, + { 0x19a00030, mmCP_DFY_DATA_0 }, + { 0xcdc0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xd8400022, mmCP_DFY_DATA_0 }, + { 0xc430000f, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x9a000012, mmCP_DFY_DATA_0 }, + { 0xd8400023, mmCP_DFY_DATA_0 }, + { 0x800010cb, mmCP_DFY_DATA_0 }, + { 0x199c0fe8, mmCP_DFY_DATA_0 }, + { 0xcdc0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xd8400023, mmCP_DFY_DATA_0 }, + { 0xc430000f, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x800010cb, mmCP_DFY_DATA_0 }, + { 0xd8c00010, mmCP_DFY_DATA_0 }, + { 0xd8000022, mmCP_DFY_DATA_0 }, + { 0xd8000023, mmCP_DFY_DATA_0 }, + { 0xc430005e, mmCP_DFY_DATA_0 }, + { 0x97000aac, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0xc434002e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0x2020002c, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xce01326c, mmCP_DFY_DATA_0 }, + { 0x17780001, mmCP_DFY_DATA_0 }, + { 0x27740001, mmCP_DFY_DATA_0 }, + { 0x07a810d8, mmCP_DFY_DATA_0 }, + { 0xcf400010, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0x80000bfc, mmCP_DFY_DATA_0 }, + { 0x800012e9, mmCP_DFY_DATA_0 }, + { 0x8000104c, mmCP_DFY_DATA_0 }, + { 0xcc400040, mmCP_DFY_DATA_0 }, + { 0xd8800010, mmCP_DFY_DATA_0 }, + { 0xc4180032, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x200c007d, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325b, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x28240007, mmCP_DFY_DATA_0 }, + { 0xde430000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0x24b00008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x98c00002, mmCP_DFY_DATA_0 }, + { 0xd840003d, mmCP_DFY_DATA_0 }, + { 0x2b304000, mmCP_DFY_DATA_0 }, + { 0xcf01326c, mmCP_DFY_DATA_0 }, + { 0xc431326c, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x192400fd, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x06681110, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0x18ac0024, mmCP_DFY_DATA_0 }, + { 0x19180070, mmCP_DFY_DATA_0 }, + { 0x19100078, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x18f40058, mmCP_DFY_DATA_0 }, + { 0x5978073a, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80001117, mmCP_DFY_DATA_0 }, + { 0x80001118, mmCP_DFY_DATA_0 }, + { 0x80001122, mmCP_DFY_DATA_0 }, + { 0x8000112d, mmCP_DFY_DATA_0 }, + { 0x80001130, mmCP_DFY_DATA_0 }, + { 0x80001133, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000117b, mmCP_DFY_DATA_0 }, + { 0x24ec0f00, mmCP_DFY_DATA_0 }, + { 0x32ec0600, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xc4300006, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x8000117b, mmCP_DFY_DATA_0 }, + { 0x24ec0f00, mmCP_DFY_DATA_0 }, + { 0x32ec0600, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xc4300006, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x8000117b, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0x80001122, mmCP_DFY_DATA_0 }, + { 0xc81c0020, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0x80001122, mmCP_DFY_DATA_0 }, + { 0x8c00116b, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc02a0200, mmCP_DFY_DATA_0 }, + { 0x7e8e8009, mmCP_DFY_DATA_0 }, + { 0x22a8003d, mmCP_DFY_DATA_0 }, + { 0x22a80074, mmCP_DFY_DATA_0 }, + { 0x2774001c, mmCP_DFY_DATA_0 }, + { 0x13740014, mmCP_DFY_DATA_0 }, + { 0x7eb6800a, mmCP_DFY_DATA_0 }, + { 0x25ecffff, mmCP_DFY_DATA_0 }, + { 0x55700020, mmCP_DFY_DATA_0 }, + { 0x15f40010, mmCP_DFY_DATA_0 }, + { 0x13740002, mmCP_DFY_DATA_0 }, + { 0x275c001f, mmCP_DFY_DATA_0 }, + { 0x95c00027, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0x7f41c001, mmCP_DFY_DATA_0 }, + { 0x15dc0002, mmCP_DFY_DATA_0 }, + { 0x39e00008, mmCP_DFY_DATA_0 }, + { 0x25dc0007, mmCP_DFY_DATA_0 }, + { 0x7dc1c01e, mmCP_DFY_DATA_0 }, + { 0x05dc0001, mmCP_DFY_DATA_0 }, + { 0x96000004, mmCP_DFY_DATA_0 }, + { 0x05e40008, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001168, mmCP_DFY_DATA_0 }, + { 0x7dc2001e, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x05e40008, mmCP_DFY_DATA_0 }, + { 0x7e62000e, mmCP_DFY_DATA_0 }, + { 0x9a000004, mmCP_DFY_DATA_0 }, + { 0x7da58001, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001165, mmCP_DFY_DATA_0 }, + { 0x7dc2001e, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x7e1a0001, mmCP_DFY_DATA_0 }, + { 0x05cc0008, mmCP_DFY_DATA_0 }, + { 0x7e0d000e, mmCP_DFY_DATA_0 }, + { 0x95000007, mmCP_DFY_DATA_0 }, + { 0x7e02401e, mmCP_DFY_DATA_0 }, + { 0x06640001, mmCP_DFY_DATA_0 }, + { 0x06640008, mmCP_DFY_DATA_0 }, + { 0x05d80008, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001168, mmCP_DFY_DATA_0 }, + { 0x7dc2401e, mmCP_DFY_DATA_0 }, + { 0x06640001, mmCP_DFY_DATA_0 }, + { 0x7da58001, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x05e00008, mmCP_DFY_DATA_0 }, + { 0x7da2000c, mmCP_DFY_DATA_0 }, + { 0x9600ffe6, mmCP_DFY_DATA_0 }, + { 0x17640002, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xc4200006, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x8c00116b, mmCP_DFY_DATA_0 }, + { 0xc420000e, mmCP_DFY_DATA_0 }, + { 0x2a200001, mmCP_DFY_DATA_0 }, + { 0xce00001a, mmCP_DFY_DATA_0 }, + { 0xce81c078, mmCP_DFY_DATA_0 }, + { 0xcec1c080, mmCP_DFY_DATA_0 }, + { 0xcc01c081, mmCP_DFY_DATA_0 }, + { 0xcd41c082, mmCP_DFY_DATA_0 }, + { 0xcf01c083, mmCP_DFY_DATA_0 }, + { 0x12640002, mmCP_DFY_DATA_0 }, + { 0x22640435, mmCP_DFY_DATA_0 }, + { 0xce41c084, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x0528117e, mmCP_DFY_DATA_0 }, + { 0x312c0003, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x80001185, mmCP_DFY_DATA_0 }, + { 0x80001182, mmCP_DFY_DATA_0 }, + { 0x80001182, mmCP_DFY_DATA_0 }, + { 0xc4300012, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0x9ac0000c, mmCP_DFY_DATA_0 }, + { 0xc03a0400, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x15980008, mmCP_DFY_DATA_0 }, + { 0x1198001c, mmCP_DFY_DATA_0 }, + { 0x7d81c00a, mmCP_DFY_DATA_0 }, + { 0xcdc130b7, mmCP_DFY_DATA_0 }, + { 0xcf8130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x04240008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0xc41c0049, mmCP_DFY_DATA_0 }, + { 0x19a000e8, mmCP_DFY_DATA_0 }, + { 0x29a80008, mmCP_DFY_DATA_0 }, + { 0x7de2c00c, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc421325e, mmCP_DFY_DATA_0 }, + { 0x26200010, mmCP_DFY_DATA_0 }, + { 0xc415326d, mmCP_DFY_DATA_0 }, + { 0x9a000006, mmCP_DFY_DATA_0 }, + { 0xc420007d, mmCP_DFY_DATA_0 }, + { 0x96000004, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xce40003e, mmCP_DFY_DATA_0 }, + { 0x800011a3, mmCP_DFY_DATA_0 }, + { 0x7d654001, mmCP_DFY_DATA_0 }, + { 0xcd41326d, mmCP_DFY_DATA_0 }, + { 0x7c020001, mmCP_DFY_DATA_0 }, + { 0x96000005, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0xc4240081, mmCP_DFY_DATA_0 }, + { 0xc4140025, mmCP_DFY_DATA_0 }, + { 0x800011b6, mmCP_DFY_DATA_0 }, + { 0xc4253279, mmCP_DFY_DATA_0 }, + { 0xc415326d, mmCP_DFY_DATA_0 }, + { 0xc431326c, mmCP_DFY_DATA_0 }, + { 0x2730003f, mmCP_DFY_DATA_0 }, + { 0x3b380006, mmCP_DFY_DATA_0 }, + { 0x97800004, mmCP_DFY_DATA_0 }, + { 0x3f38000b, mmCP_DFY_DATA_0 }, + { 0x9b800004, mmCP_DFY_DATA_0 }, + { 0x800011b4, mmCP_DFY_DATA_0 }, + { 0x04300006, mmCP_DFY_DATA_0 }, + { 0x800011b4, mmCP_DFY_DATA_0 }, + { 0x0430000b, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x7fb10004, mmCP_DFY_DATA_0 }, + { 0x7e57000f, mmCP_DFY_DATA_0 }, + { 0x7e578002, mmCP_DFY_DATA_0 }, + { 0x7d67c002, mmCP_DFY_DATA_0 }, + { 0x0be40001, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x7d3a4002, mmCP_DFY_DATA_0 }, + { 0x202c002c, mmCP_DFY_DATA_0 }, + { 0xc421325e, mmCP_DFY_DATA_0 }, + { 0x04280020, mmCP_DFY_DATA_0 }, + { 0xcec1326c, mmCP_DFY_DATA_0 }, + { 0x26200010, mmCP_DFY_DATA_0 }, + { 0x3e640010, mmCP_DFY_DATA_0 }, + { 0x96000003, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xce81325e, mmCP_DFY_DATA_0 }, + { 0xc4300028, mmCP_DFY_DATA_0 }, + { 0xc434002e, mmCP_DFY_DATA_0 }, + { 0x17780001, mmCP_DFY_DATA_0 }, + { 0x27740001, mmCP_DFY_DATA_0 }, + { 0x07a811cf, mmCP_DFY_DATA_0 }, + { 0x9b00feb8, mmCP_DFY_DATA_0 }, + { 0xcf400010, mmCP_DFY_DATA_0 }, + { 0xc414005e, mmCP_DFY_DATA_0 }, + { 0x954009a7, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0x80000bfc, mmCP_DFY_DATA_0 }, + { 0x800012e9, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0xccc1c07c, mmCP_DFY_DATA_0 }, + { 0xcc41c07d, mmCP_DFY_DATA_0 }, + { 0xcc41c08c, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xcc41c079, mmCP_DFY_DATA_0 }, + { 0xcd01c07e, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x18f0012f, mmCP_DFY_DATA_0 }, + { 0x18f40612, mmCP_DFY_DATA_0 }, + { 0x18cc00c1, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x7cf7400a, mmCP_DFY_DATA_0 }, + { 0x39600004, mmCP_DFY_DATA_0 }, + { 0x9a000002, mmCP_DFY_DATA_0 }, + { 0xc0140004, mmCP_DFY_DATA_0 }, + { 0x11600001, mmCP_DFY_DATA_0 }, + { 0x18fc003e, mmCP_DFY_DATA_0 }, + { 0x9740001c, mmCP_DFY_DATA_0 }, + { 0xcf400041, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0x97c00003, mmCP_DFY_DATA_0 }, + { 0x166c001f, mmCP_DFY_DATA_0 }, + { 0x800011ee, mmCP_DFY_DATA_0 }, + { 0x1a6c003e, mmCP_DFY_DATA_0 }, + { 0x96c00006, mmCP_DFY_DATA_0 }, + { 0x04200002, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x800011e8, mmCP_DFY_DATA_0 }, + { 0xc428002c, mmCP_DFY_DATA_0 }, + { 0x96800010, mmCP_DFY_DATA_0 }, + { 0x26ac007f, mmCP_DFY_DATA_0 }, + { 0xcec0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x1ab00030, mmCP_DFY_DATA_0 }, + { 0x1aac0fe8, mmCP_DFY_DATA_0 }, + { 0xc434000f, mmCP_DFY_DATA_0 }, + { 0x9b40ffff, mmCP_DFY_DATA_0 }, + { 0x97000008, mmCP_DFY_DATA_0 }, + { 0xcec0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc434000f, mmCP_DFY_DATA_0 }, + { 0x9b40ffff, mmCP_DFY_DATA_0 }, + { 0x80001205, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0x166c001f, mmCP_DFY_DATA_0 }, + { 0x11600001, mmCP_DFY_DATA_0 }, + { 0x9ac0fffa, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8000033, mmCP_DFY_DATA_0 }, + { 0xc438000b, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0001, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd841c07f, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x1bfc0078, mmCP_DFY_DATA_0 }, + { 0x7ffbc00c, mmCP_DFY_DATA_0 }, + { 0x97c0fffd, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc03a2800, mmCP_DFY_DATA_0 }, + { 0xcf81c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04380040, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380060, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x17fc001f, mmCP_DFY_DATA_0 }, + { 0x04380010, mmCP_DFY_DATA_0 }, + { 0x9bc0fffa, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd801c07f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0xcfc00078, mmCP_DFY_DATA_0 }, + { 0xd8000034, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc03ae000, mmCP_DFY_DATA_0 }, + { 0xcf81c200, mmCP_DFY_DATA_0 }, + { 0xc03a0800, mmCP_DFY_DATA_0 }, + { 0xcf81c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04380040, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x17fc001f, mmCP_DFY_DATA_0 }, + { 0x04380010, mmCP_DFY_DATA_0 }, + { 0x9bc0fffa, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc03ae000, mmCP_DFY_DATA_0 }, + { 0xcf81c200, mmCP_DFY_DATA_0 }, + { 0xc03a4000, mmCP_DFY_DATA_0 }, + { 0xcf81c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x17fc001f, mmCP_DFY_DATA_0 }, + { 0x04380010, mmCP_DFY_DATA_0 }, + { 0x9bc0fffa, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x30d00002, mmCP_DFY_DATA_0 }, + { 0x99000052, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x9640090f, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x1514001f, mmCP_DFY_DATA_0 }, + { 0x19180038, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0x99400030, mmCP_DFY_DATA_0 }, + { 0x30dc0001, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x99c0000a, mmCP_DFY_DATA_0 }, + { 0xc42d324e, mmCP_DFY_DATA_0 }, + { 0xc431324d, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc435324f, mmCP_DFY_DATA_0 }, + { 0xc4293256, mmCP_DFY_DATA_0 }, + { 0x1ab0c006, mmCP_DFY_DATA_0 }, + { 0x52ec0008, mmCP_DFY_DATA_0 }, + { 0x8000127f, mmCP_DFY_DATA_0 }, + { 0xc42d3258, mmCP_DFY_DATA_0 }, + { 0xc4313257, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc4353259, mmCP_DFY_DATA_0 }, + { 0xc429325a, mmCP_DFY_DATA_0 }, + { 0x1ab0c012, mmCP_DFY_DATA_0 }, + { 0x07740001, mmCP_DFY_DATA_0 }, + { 0x04240002, mmCP_DFY_DATA_0 }, + { 0x26a0003f, mmCP_DFY_DATA_0 }, + { 0x7e624004, mmCP_DFY_DATA_0 }, + { 0x7f67800f, mmCP_DFY_DATA_0 }, + { 0x97800002, mmCP_DFY_DATA_0 }, + { 0x04340000, mmCP_DFY_DATA_0 }, + { 0x53740002, mmCP_DFY_DATA_0 }, + { 0x7ef6c011, mmCP_DFY_DATA_0 }, + { 0x1ab42010, mmCP_DFY_DATA_0 }, + { 0x16a8000c, mmCP_DFY_DATA_0 }, + { 0x26a80800, mmCP_DFY_DATA_0 }, + { 0x2b740000, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0xcf40001c, mmCP_DFY_DATA_0 }, + { 0xd2c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4100011, mmCP_DFY_DATA_0 }, + { 0x1514001f, mmCP_DFY_DATA_0 }, + { 0x99400006, mmCP_DFY_DATA_0 }, + { 0x9980000a, mmCP_DFY_DATA_0 }, + { 0x8c0012e1, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0x80001267, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x964008d7, mmCP_DFY_DATA_0 }, + { 0xd9800036, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc42c001d, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x1b300677, mmCP_DFY_DATA_0 }, + { 0x11dc000c, mmCP_DFY_DATA_0 }, + { 0x800012aa, mmCP_DFY_DATA_0 }, + { 0xc4313256, mmCP_DFY_DATA_0 }, + { 0x1b34060b, mmCP_DFY_DATA_0 }, + { 0x1b300077, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x13300017, mmCP_DFY_DATA_0 }, + { 0x04340100, mmCP_DFY_DATA_0 }, + { 0x26ec00ff, mmCP_DFY_DATA_0 }, + { 0xc03a8002, mmCP_DFY_DATA_0 }, + { 0x7ef6c00a, mmCP_DFY_DATA_0 }, + { 0x7edec00a, mmCP_DFY_DATA_0 }, + { 0x7f3b000a, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc4140032, mmCP_DFY_DATA_0 }, + { 0xc410001d, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x1858003f, mmCP_DFY_DATA_0 }, + { 0x251000ff, mmCP_DFY_DATA_0 }, + { 0x99800007, mmCP_DFY_DATA_0 }, + { 0x7d0cc00a, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x18d0006c, mmCP_DFY_DATA_0 }, + { 0x18d407f0, mmCP_DFY_DATA_0 }, + { 0x9900000e, mmCP_DFY_DATA_0 }, + { 0x04100002, mmCP_DFY_DATA_0 }, + { 0xc4193256, mmCP_DFY_DATA_0 }, + { 0xc41d324f, mmCP_DFY_DATA_0 }, + { 0x2598003f, mmCP_DFY_DATA_0 }, + { 0x7d190004, mmCP_DFY_DATA_0 }, + { 0x7d5d4001, mmCP_DFY_DATA_0 }, + { 0x7d52000f, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0xcd41324f, mmCP_DFY_DATA_0 }, + { 0x800012d8, mmCP_DFY_DATA_0 }, + { 0x7d514002, mmCP_DFY_DATA_0 }, + { 0xcd41324f, mmCP_DFY_DATA_0 }, + { 0x800012d8, mmCP_DFY_DATA_0 }, + { 0xc4193259, mmCP_DFY_DATA_0 }, + { 0xc41d325a, mmCP_DFY_DATA_0 }, + { 0x7d958001, mmCP_DFY_DATA_0 }, + { 0x7dd5c002, mmCP_DFY_DATA_0 }, + { 0xcd813259, mmCP_DFY_DATA_0 }, + { 0xcdc1325a, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x1ccc001e, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0xc4340028, mmCP_DFY_DATA_0 }, + { 0x14f00010, mmCP_DFY_DATA_0 }, + { 0xc4380030, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x9b000004, mmCP_DFY_DATA_0 }, + { 0x9b40000c, mmCP_DFY_DATA_0 }, + { 0x9b80000f, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b000005, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd980003f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd9c0003f, mmCP_DFY_DATA_0 }, + { 0x80001082, mmCP_DFY_DATA_0 }, + { 0xd9800040, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd9c00040, mmCP_DFY_DATA_0 }, + { 0x800010de, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x33f80003, mmCP_DFY_DATA_0 }, + { 0x97800051, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0x24b00008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4353249, mmCP_DFY_DATA_0 }, + { 0x1b74003e, mmCP_DFY_DATA_0 }, + { 0x9b400002, mmCP_DFY_DATA_0 }, + { 0xd840003d, mmCP_DFY_DATA_0 }, + { 0x2b304000, mmCP_DFY_DATA_0 }, + { 0xcf01326c, mmCP_DFY_DATA_0 }, + { 0xc431326c, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x1b4c00f8, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x50700020, mmCP_DFY_DATA_0 }, + { 0x04e81324, mmCP_DFY_DATA_0 }, + { 0x18ac0024, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x50600020, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0x30e40004, mmCP_DFY_DATA_0 }, + { 0x9a400007, mmCP_DFY_DATA_0 }, + { 0x7d71401a, mmCP_DFY_DATA_0 }, + { 0x596401fc, mmCP_DFY_DATA_0 }, + { 0x12640009, mmCP_DFY_DATA_0 }, + { 0x1b74008d, mmCP_DFY_DATA_0 }, + { 0x7e76400a, mmCP_DFY_DATA_0 }, + { 0x2a640000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000132c, mmCP_DFY_DATA_0 }, + { 0x8000133b, mmCP_DFY_DATA_0 }, + { 0x80001344, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc42530b5, mmCP_DFY_DATA_0 }, + { 0x1a68003a, mmCP_DFY_DATA_0 }, + { 0x9a80fffe, mmCP_DFY_DATA_0 }, + { 0x2024003a, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x25980700, mmCP_DFY_DATA_0 }, + { 0x11980014, mmCP_DFY_DATA_0 }, + { 0x7d19000a, mmCP_DFY_DATA_0 }, + { 0xcd0130b7, mmCP_DFY_DATA_0 }, + { 0xce4130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xce40001c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc4240011, mmCP_DFY_DATA_0 }, + { 0x7de6800f, mmCP_DFY_DATA_0 }, + { 0x9a80ffea, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xce40001c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8240011, mmCP_DFY_DATA_0 }, + { 0x7de1c01a, mmCP_DFY_DATA_0 }, + { 0x7de6800f, mmCP_DFY_DATA_0 }, + { 0x9a80ffe0, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x8c00104f, mmCP_DFY_DATA_0 }, + { 0x28182002, mmCP_DFY_DATA_0 }, + { 0xc430000d, mmCP_DFY_DATA_0 }, + { 0xc4340035, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc8140023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0xc4240004, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x7d614011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7ca4800a, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x7cb0800a, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0x7cb4800a, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x042c0008, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x20240030, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x1b4c00f8, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0xcc400026, mmCP_DFY_DATA_0 }, + { 0x28340000, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x507c0020, mmCP_DFY_DATA_0 }, + { 0x30e40004, mmCP_DFY_DATA_0 }, + { 0x9a400005, mmCP_DFY_DATA_0 }, + { 0x7d7d401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x557c0020, mmCP_DFY_DATA_0 }, + { 0x28342002, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcd400026, mmCP_DFY_DATA_0 }, + { 0xcfc00026, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x9a800005, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0x04380028, mmCP_DFY_DATA_0 }, + { 0xcec0003a, mmCP_DFY_DATA_0 }, + { 0xcf81a2a4, mmCP_DFY_DATA_0 }, + { 0x80001037, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c007eb, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50500020, mmCP_DFY_DATA_0 }, + { 0x7d0d001a, mmCP_DFY_DATA_0 }, + { 0xd1000072, mmCP_DFY_DATA_0 }, + { 0xc8100072, mmCP_DFY_DATA_0 }, + { 0x591c01fc, mmCP_DFY_DATA_0 }, + { 0x11dc0009, mmCP_DFY_DATA_0 }, + { 0x45140210, mmCP_DFY_DATA_0 }, + { 0x595801fc, mmCP_DFY_DATA_0 }, + { 0x11980009, mmCP_DFY_DATA_0 }, + { 0x29dc0000, mmCP_DFY_DATA_0 }, + { 0xcdc0001c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4200011, mmCP_DFY_DATA_0 }, + { 0x1624001f, mmCP_DFY_DATA_0 }, + { 0x96400069, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xce013249, mmCP_DFY_DATA_0 }, + { 0x1a307fe8, mmCP_DFY_DATA_0 }, + { 0xcf00000a, mmCP_DFY_DATA_0 }, + { 0x23304076, mmCP_DFY_DATA_0 }, + { 0xd1000001, mmCP_DFY_DATA_0 }, + { 0xcf000001, mmCP_DFY_DATA_0 }, + { 0xc41d3254, mmCP_DFY_DATA_0 }, + { 0xc4253256, mmCP_DFY_DATA_0 }, + { 0x18cc00e8, mmCP_DFY_DATA_0 }, + { 0x10cc0015, mmCP_DFY_DATA_0 }, + { 0x4514020c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4200011, mmCP_DFY_DATA_0 }, + { 0xce013248, mmCP_DFY_DATA_0 }, + { 0x1a2001e8, mmCP_DFY_DATA_0 }, + { 0x12200014, mmCP_DFY_DATA_0 }, + { 0x2a204001, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0x1a64003c, mmCP_DFY_DATA_0 }, + { 0x1264001f, mmCP_DFY_DATA_0 }, + { 0x11dc0009, mmCP_DFY_DATA_0 }, + { 0x15dc000b, mmCP_DFY_DATA_0 }, + { 0x7dcdc00a, mmCP_DFY_DATA_0 }, + { 0x7e5dc00a, mmCP_DFY_DATA_0 }, + { 0xcdc00100, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcf00000d, mmCP_DFY_DATA_0 }, + { 0xcf00000a, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x04340022, mmCP_DFY_DATA_0 }, + { 0x07740001, mmCP_DFY_DATA_0 }, + { 0x04300010, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0xd4412e01, mmCP_DFY_DATA_0 }, + { 0x0434001e, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xdf030000, mmCP_DFY_DATA_0 }, + { 0xd4412e40, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc41c030, mmCP_DFY_DATA_0 }, + { 0xcc41c031, mmCP_DFY_DATA_0 }, + { 0x248dfffe, mmCP_DFY_DATA_0 }, + { 0xccc12e00, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcc812e00, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x45140248, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc8200011, mmCP_DFY_DATA_0 }, + { 0xce013257, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce013258, mmCP_DFY_DATA_0 }, + { 0x0434000c, mmCP_DFY_DATA_0 }, + { 0xdb000024, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x45540008, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc8200011, mmCP_DFY_DATA_0 }, + { 0xce013259, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xc0337fff, mmCP_DFY_DATA_0 }, + { 0x7f220009, mmCP_DFY_DATA_0 }, + { 0xce01325a, mmCP_DFY_DATA_0 }, + { 0x55300020, mmCP_DFY_DATA_0 }, + { 0x7d01c001, mmCP_DFY_DATA_0 }, + { 0x042c01d0, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x06ec0004, mmCP_DFY_DATA_0 }, + { 0x7f01c001, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x041c0002, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0xc4380012, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50500020, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xd0c00072, mmCP_DFY_DATA_0 }, + { 0xc8240072, mmCP_DFY_DATA_0 }, + { 0xd240001e, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x19682011, mmCP_DFY_DATA_0 }, + { 0x5a6c01fc, mmCP_DFY_DATA_0 }, + { 0x12ec0009, mmCP_DFY_DATA_0 }, + { 0x7eeac00a, mmCP_DFY_DATA_0 }, + { 0x2aec0000, mmCP_DFY_DATA_0 }, + { 0xcec0001c, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc430000f, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0xc4180011, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x99800007, mmCP_DFY_DATA_0 }, + { 0xdf830000, mmCP_DFY_DATA_0 }, + { 0xcfa0000c, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xd8000012, mmCP_DFY_DATA_0 }, + { 0xc43c0008, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400012, mmCP_DFY_DATA_0 }, + { 0xc43c0008, mmCP_DFY_DATA_0 }, + { 0x97c0ffff, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380007, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x17b80001, mmCP_DFY_DATA_0 }, + { 0x18d40038, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x9b800004, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc414005e, mmCP_DFY_DATA_0 }, + { 0x9540073d, mmCP_DFY_DATA_0 }, + { 0x18c80066, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x30880001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x94800008, mmCP_DFY_DATA_0 }, + { 0x8c00187c, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc42c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd910000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x7d410001, mmCP_DFY_DATA_0 }, + { 0x043c0000, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0x04240001, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x4220000c, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0xcc000078, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x24e80007, mmCP_DFY_DATA_0 }, + { 0x24ec0010, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x9ac00006, mmCP_DFY_DATA_0 }, + { 0xc42c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc5310000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x80001465, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xd1000072, mmCP_DFY_DATA_0 }, + { 0xc82c0072, mmCP_DFY_DATA_0 }, + { 0xd2c0001e, mmCP_DFY_DATA_0 }, + { 0x18f02011, mmCP_DFY_DATA_0 }, + { 0x5aec01fc, mmCP_DFY_DATA_0 }, + { 0x12ec0009, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0x2aec0000, mmCP_DFY_DATA_0 }, + { 0xcec0001c, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x96800012, mmCP_DFY_DATA_0 }, + { 0x12a80001, mmCP_DFY_DATA_0 }, + { 0x0aa80001, mmCP_DFY_DATA_0 }, + { 0x06a8146a, mmCP_DFY_DATA_0 }, + { 0x7f1f0009, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x7f1b400f, mmCP_DFY_DATA_0 }, + { 0x80001478, mmCP_DFY_DATA_0 }, + { 0x7f1b400e, mmCP_DFY_DATA_0 }, + { 0x80001478, mmCP_DFY_DATA_0 }, + { 0x7f1b400c, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f1b400d, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f1b400f, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f1b400e, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f334002, mmCP_DFY_DATA_0 }, + { 0x97400014, mmCP_DFY_DATA_0 }, + { 0x8000147b, mmCP_DFY_DATA_0 }, + { 0x9b400012, mmCP_DFY_DATA_0 }, + { 0x9b800005, mmCP_DFY_DATA_0 }, + { 0x9bc0001f, mmCP_DFY_DATA_0 }, + { 0x7e024001, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x8000144a, mmCP_DFY_DATA_0 }, + { 0xc40c0032, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d325b, mmCP_DFY_DATA_0 }, + { 0x1bb81ff0, mmCP_DFY_DATA_0 }, + { 0x7fbfc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x94800007, mmCP_DFY_DATA_0 }, + { 0x8c00187c, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc42c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd910000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x9b800003, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc40c0032, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x800012c2, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0xc43d3256, mmCP_DFY_DATA_0 }, + { 0x1bf0060b, mmCP_DFY_DATA_0 }, + { 0x1bfc0077, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x800014a9, mmCP_DFY_DATA_0 }, + { 0xc43d325a, mmCP_DFY_DATA_0 }, + { 0x1bfc0677, mmCP_DFY_DATA_0 }, + { 0x04300100, mmCP_DFY_DATA_0 }, + { 0x1bb81ff0, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xc0328007, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x13fc0017, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x7ffbc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0xc03a0002, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcf8130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x043c0000, mmCP_DFY_DATA_0 }, + { 0xc414000e, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7dd9c01a, mmCP_DFY_DATA_0 }, + { 0x45dc0390, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0x1b380057, mmCP_DFY_DATA_0 }, + { 0x1b340213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd1c00025, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0x7c424001, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x7c428001, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0x7c42c001, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0x7c430001, mmCP_DFY_DATA_0 }, + { 0xcf000026, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0xcf800026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xd840004f, mmCP_DFY_DATA_0 }, + { 0x1a0800fd, mmCP_DFY_DATA_0 }, + { 0x109c000a, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x7dd9c00a, mmCP_DFY_DATA_0 }, + { 0xcdc13265, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0xce080228, mmCP_DFY_DATA_0 }, + { 0x9880000e, mmCP_DFY_DATA_0 }, + { 0xce480250, mmCP_DFY_DATA_0 }, + { 0xce880258, mmCP_DFY_DATA_0 }, + { 0xd8080230, mmCP_DFY_DATA_0 }, + { 0xd8080238, mmCP_DFY_DATA_0 }, + { 0xd8080240, mmCP_DFY_DATA_0 }, + { 0xd8080248, mmCP_DFY_DATA_0 }, + { 0xd8080268, mmCP_DFY_DATA_0 }, + { 0xd8080270, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x97c0ec75, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x041c0010, mmCP_DFY_DATA_0 }, + { 0x26180001, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x16200001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x99c0fffb, mmCP_DFY_DATA_0 }, + { 0xccc80230, mmCP_DFY_DATA_0 }, + { 0xd8080238, mmCP_DFY_DATA_0 }, + { 0xd8080240, mmCP_DFY_DATA_0 }, + { 0xd8080248, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0xce480250, mmCP_DFY_DATA_0 }, + { 0xce880258, mmCP_DFY_DATA_0 }, + { 0x52a80020, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x041c0020, mmCP_DFY_DATA_0 }, + { 0x66580001, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x56640001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x99c0fffb, mmCP_DFY_DATA_0 }, + { 0xccc80260, mmCP_DFY_DATA_0 }, + { 0xd8080268, mmCP_DFY_DATA_0 }, + { 0xd8080270, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0xcec80288, mmCP_DFY_DATA_0 }, + { 0xcf080290, mmCP_DFY_DATA_0 }, + { 0xcec80298, mmCP_DFY_DATA_0 }, + { 0xcf0802a0, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x041c0010, mmCP_DFY_DATA_0 }, + { 0xcf4802a8, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x17740001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x99c0fffb, mmCP_DFY_DATA_0 }, + { 0xccc802b0, mmCP_DFY_DATA_0 }, + { 0xd80802b8, mmCP_DFY_DATA_0 }, + { 0x178c000b, mmCP_DFY_DATA_0 }, + { 0x27b8003f, mmCP_DFY_DATA_0 }, + { 0x7cf8c001, mmCP_DFY_DATA_0 }, + { 0xcf8802c0, mmCP_DFY_DATA_0 }, + { 0xccc802c8, mmCP_DFY_DATA_0 }, + { 0xcf8802d0, mmCP_DFY_DATA_0 }, + { 0xcf8802d8, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x25b8ffff, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0xc48f0238, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x24cc000f, mmCP_DFY_DATA_0 }, + { 0x7cd2800c, mmCP_DFY_DATA_0 }, + { 0x9a80000b, mmCP_DFY_DATA_0 }, + { 0xc5230309, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0x7e3a400c, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x80001539, mmCP_DFY_DATA_0 }, + { 0xcd08034b, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x98c00004, mmCP_DFY_DATA_0 }, + { 0xcd880353, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0xc49b0353, mmCP_DFY_DATA_0 }, + { 0xc4930238, mmCP_DFY_DATA_0 }, + { 0xc48f0228, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x7cd14005, mmCP_DFY_DATA_0 }, + { 0x25540001, mmCP_DFY_DATA_0 }, + { 0x99400004, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x8000154f, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0xcd080238, mmCP_DFY_DATA_0 }, + { 0xcd08034b, mmCP_DFY_DATA_0 }, + { 0x08cc0001, mmCP_DFY_DATA_0 }, + { 0x2598ffff, mmCP_DFY_DATA_0 }, + { 0x3d200008, mmCP_DFY_DATA_0 }, + { 0xccc80230, mmCP_DFY_DATA_0 }, + { 0xcd900309, mmCP_DFY_DATA_0 }, + { 0xd8100319, mmCP_DFY_DATA_0 }, + { 0x04340801, mmCP_DFY_DATA_0 }, + { 0x2198003f, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcd910ce7, mmCP_DFY_DATA_0 }, + { 0xc4190ce6, mmCP_DFY_DATA_0 }, + { 0x7d918005, mmCP_DFY_DATA_0 }, + { 0x25980001, mmCP_DFY_DATA_0 }, + { 0x9580fffd, mmCP_DFY_DATA_0 }, + { 0x7d918004, mmCP_DFY_DATA_0 }, + { 0xcd810ce6, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0xcdd1054f, mmCP_DFY_DATA_0 }, + { 0x8000156e, mmCP_DFY_DATA_0 }, + { 0x090c0008, mmCP_DFY_DATA_0 }, + { 0xcdcd050e, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x110c0014, mmCP_DFY_DATA_0 }, + { 0x28cc4001, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xcc41230a, mmCP_DFY_DATA_0 }, + { 0xcc41230b, mmCP_DFY_DATA_0 }, + { 0xcc41230c, mmCP_DFY_DATA_0 }, + { 0xcc41230d, mmCP_DFY_DATA_0 }, + { 0xcc480329, mmCP_DFY_DATA_0 }, + { 0xcc48032a, mmCP_DFY_DATA_0 }, + { 0xcc4802e0, mmCP_DFY_DATA_0 }, + { 0xd8000055, mmCP_DFY_DATA_0 }, + { 0xc48f02e0, mmCP_DFY_DATA_0 }, + { 0x24d8003f, mmCP_DFY_DATA_0 }, + { 0x09940001, mmCP_DFY_DATA_0 }, + { 0x44100001, mmCP_DFY_DATA_0 }, + { 0x9580002c, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x51100001, mmCP_DFY_DATA_0 }, + { 0x69100001, mmCP_DFY_DATA_0 }, + { 0x8000157f, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0xc4970290, mmCP_DFY_DATA_0 }, + { 0xc49b0288, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xc49b02a0, mmCP_DFY_DATA_0 }, + { 0xc49f0298, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x041c0040, mmCP_DFY_DATA_0 }, + { 0x04200000, mmCP_DFY_DATA_0 }, + { 0x7dcdc002, mmCP_DFY_DATA_0 }, + { 0x7d924019, mmCP_DFY_DATA_0 }, + { 0x7d26400c, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x9a400008, mmCP_DFY_DATA_0 }, + { 0x51100001, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x99c0fffa, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0x80001579, mmCP_DFY_DATA_0 }, + { 0x7d010021, mmCP_DFY_DATA_0 }, + { 0x7d914019, mmCP_DFY_DATA_0 }, + { 0xc4930238, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0xcd480298, mmCP_DFY_DATA_0 }, + { 0xcd8802a0, mmCP_DFY_DATA_0 }, + { 0x10d40010, mmCP_DFY_DATA_0 }, + { 0x12180016, mmCP_DFY_DATA_0 }, + { 0xc51f0309, mmCP_DFY_DATA_0 }, + { 0x7d95800a, mmCP_DFY_DATA_0 }, + { 0x7d62000a, mmCP_DFY_DATA_0 }, + { 0x7dd9c00a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdd00309, mmCP_DFY_DATA_0 }, + { 0xce113320, mmCP_DFY_DATA_0 }, + { 0xc48f02e0, mmCP_DFY_DATA_0 }, + { 0xc49b02b0, mmCP_DFY_DATA_0 }, + { 0x18dc01e8, mmCP_DFY_DATA_0 }, + { 0x7dd9400e, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x95c0001d, mmCP_DFY_DATA_0 }, + { 0x95400003, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0x800015aa, mmCP_DFY_DATA_0 }, + { 0xc48f0238, mmCP_DFY_DATA_0 }, + { 0xc4a302b8, mmCP_DFY_DATA_0 }, + { 0x12240004, mmCP_DFY_DATA_0 }, + { 0x7e5e400a, mmCP_DFY_DATA_0 }, + { 0xc4ab02a8, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0xce4c0319, mmCP_DFY_DATA_0 }, + { 0x7d9d8002, mmCP_DFY_DATA_0 }, + { 0x7ea14005, mmCP_DFY_DATA_0 }, + { 0x25540001, mmCP_DFY_DATA_0 }, + { 0x99400004, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x2620000f, mmCP_DFY_DATA_0 }, + { 0x800015bc, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x04240001, mmCP_DFY_DATA_0 }, + { 0x7e624004, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x7d25000a, mmCP_DFY_DATA_0 }, + { 0x2620000f, mmCP_DFY_DATA_0 }, + { 0x99c0fff4, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd0d3330, mmCP_DFY_DATA_0 }, + { 0xce0802b8, mmCP_DFY_DATA_0 }, + { 0xcd8802b0, mmCP_DFY_DATA_0 }, + { 0xc4ab02e0, mmCP_DFY_DATA_0 }, + { 0x1aa807f0, mmCP_DFY_DATA_0 }, + { 0xc48f02d0, mmCP_DFY_DATA_0 }, + { 0xc49702d8, mmCP_DFY_DATA_0 }, + { 0xc49b02c8, mmCP_DFY_DATA_0 }, + { 0xc49f02c0, mmCP_DFY_DATA_0 }, + { 0x96800028, mmCP_DFY_DATA_0 }, + { 0x7d4e000f, mmCP_DFY_DATA_0 }, + { 0x9600000b, mmCP_DFY_DATA_0 }, + { 0x7d964002, mmCP_DFY_DATA_0 }, + { 0x7e6a000f, mmCP_DFY_DATA_0 }, + { 0x96000003, mmCP_DFY_DATA_0 }, + { 0x7d694001, mmCP_DFY_DATA_0 }, + { 0x800015e9, mmCP_DFY_DATA_0 }, + { 0x7cde4002, mmCP_DFY_DATA_0 }, + { 0x7e6a000f, mmCP_DFY_DATA_0 }, + { 0x96000008, mmCP_DFY_DATA_0 }, + { 0x7de94001, mmCP_DFY_DATA_0 }, + { 0x800015e9, mmCP_DFY_DATA_0 }, + { 0x7cd64002, mmCP_DFY_DATA_0 }, + { 0x7e6a000e, mmCP_DFY_DATA_0 }, + { 0x96000003, mmCP_DFY_DATA_0 }, + { 0x7d694001, mmCP_DFY_DATA_0 }, + { 0x800015e9, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0x800015cd, mmCP_DFY_DATA_0 }, + { 0xc4930238, mmCP_DFY_DATA_0 }, + { 0x7d698002, mmCP_DFY_DATA_0 }, + { 0xcd4802d8, mmCP_DFY_DATA_0 }, + { 0x129c0008, mmCP_DFY_DATA_0 }, + { 0xc50f0319, mmCP_DFY_DATA_0 }, + { 0x11a0000e, mmCP_DFY_DATA_0 }, + { 0x11140001, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x7e1e000a, mmCP_DFY_DATA_0 }, + { 0x1198000a, mmCP_DFY_DATA_0 }, + { 0xcd953300, mmCP_DFY_DATA_0 }, + { 0x7e0e000a, mmCP_DFY_DATA_0 }, + { 0x12a8000a, mmCP_DFY_DATA_0 }, + { 0xce953301, mmCP_DFY_DATA_0 }, + { 0xce100319, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0xc4b70280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x7f73800a, mmCP_DFY_DATA_0 }, + { 0x536c0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x9780eb68, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x043c0003, mmCP_DFY_DATA_0 }, + { 0x80001609, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x30b40000, mmCP_DFY_DATA_0 }, + { 0x9b400011, mmCP_DFY_DATA_0 }, + { 0xc4b70258, mmCP_DFY_DATA_0 }, + { 0xc4b30250, mmCP_DFY_DATA_0 }, + { 0x53780020, mmCP_DFY_DATA_0 }, + { 0x7fb3801a, mmCP_DFY_DATA_0 }, + { 0x7faf8019, mmCP_DFY_DATA_0 }, + { 0x04300020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x67b40001, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x57b80001, mmCP_DFY_DATA_0 }, + { 0x97400002, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9b00fffb, mmCP_DFY_DATA_0 }, + { 0xc4bb0260, mmCP_DFY_DATA_0 }, + { 0x7fab8001, mmCP_DFY_DATA_0 }, + { 0xcf880260, mmCP_DFY_DATA_0 }, + { 0x04300020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x66f40001, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x56ec0001, mmCP_DFY_DATA_0 }, + { 0x97400005, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4353247, mmCP_DFY_DATA_0 }, + { 0x7f7f4009, mmCP_DFY_DATA_0 }, + { 0x9b40fffe, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9b00fff7, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x269c0007, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0x29dc0008, mmCP_DFY_DATA_0 }, + { 0x26a00018, mmCP_DFY_DATA_0 }, + { 0x12200003, mmCP_DFY_DATA_0 }, + { 0x7de1c00a, mmCP_DFY_DATA_0 }, + { 0x26a00060, mmCP_DFY_DATA_0 }, + { 0x06200020, mmCP_DFY_DATA_0 }, + { 0x16200001, mmCP_DFY_DATA_0 }, + { 0x7de1c00a, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x269c0018, mmCP_DFY_DATA_0 }, + { 0x26a00007, mmCP_DFY_DATA_0 }, + { 0x26a40060, mmCP_DFY_DATA_0 }, + { 0x11dc0006, mmCP_DFY_DATA_0 }, + { 0x12200006, mmCP_DFY_DATA_0 }, + { 0x16640001, mmCP_DFY_DATA_0 }, + { 0x29dc0008, mmCP_DFY_DATA_0 }, + { 0x7de1c00a, mmCP_DFY_DATA_0 }, + { 0x7de5c00a, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4b70228, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0xccc80230, mmCP_DFY_DATA_0 }, + { 0x7f514005, mmCP_DFY_DATA_0 }, + { 0x25540001, mmCP_DFY_DATA_0 }, + { 0x99400004, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x80001644, mmCP_DFY_DATA_0 }, + { 0xc4b30248, mmCP_DFY_DATA_0 }, + { 0xcd080240, mmCP_DFY_DATA_0 }, + { 0x7f130005, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0x9b000002, mmCP_DFY_DATA_0 }, + { 0x8c001688, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001219, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x04340801, mmCP_DFY_DATA_0 }, + { 0x7f130004, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcf01051e, mmCP_DFY_DATA_0 }, + { 0xc42d051f, mmCP_DFY_DATA_0 }, + { 0x7ed2c005, mmCP_DFY_DATA_0 }, + { 0x26ec0001, mmCP_DFY_DATA_0 }, + { 0x96c0fffd, mmCP_DFY_DATA_0 }, + { 0xcf01051f, mmCP_DFY_DATA_0 }, + { 0xd8000055, mmCP_DFY_DATA_0 }, + { 0xc5170309, mmCP_DFY_DATA_0 }, + { 0x195c07f0, mmCP_DFY_DATA_0 }, + { 0x196007f6, mmCP_DFY_DATA_0 }, + { 0x04340000, mmCP_DFY_DATA_0 }, + { 0x95c00008, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x04340001, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x53740001, mmCP_DFY_DATA_0 }, + { 0x6b740001, mmCP_DFY_DATA_0 }, + { 0x80001665, mmCP_DFY_DATA_0 }, + { 0xc4a702a0, mmCP_DFY_DATA_0 }, + { 0xc4ab0298, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x7f634014, mmCP_DFY_DATA_0 }, + { 0x7e76401a, mmCP_DFY_DATA_0 }, + { 0xc4300004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x56680020, mmCP_DFY_DATA_0 }, + { 0xd8113320, mmCP_DFY_DATA_0 }, + { 0xce480298, mmCP_DFY_DATA_0 }, + { 0xce8802a0, mmCP_DFY_DATA_0 }, + { 0xc5170319, mmCP_DFY_DATA_0 }, + { 0xc4b702b0, mmCP_DFY_DATA_0 }, + { 0x255c000f, mmCP_DFY_DATA_0 }, + { 0x7f5f4001, mmCP_DFY_DATA_0 }, + { 0xd8113330, mmCP_DFY_DATA_0 }, + { 0xcf4802b0, mmCP_DFY_DATA_0 }, + { 0x11340001, mmCP_DFY_DATA_0 }, + { 0x195c07e8, mmCP_DFY_DATA_0 }, + { 0x196007ee, mmCP_DFY_DATA_0 }, + { 0xd8353300, mmCP_DFY_DATA_0 }, + { 0x7e1e4001, mmCP_DFY_DATA_0 }, + { 0xd8353301, mmCP_DFY_DATA_0 }, + { 0xce4802d0, mmCP_DFY_DATA_0 }, + { 0xd8100309, mmCP_DFY_DATA_0 }, + { 0xd8100319, mmCP_DFY_DATA_0 }, + { 0xcf000008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc48f0250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7cd4c01a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x64d80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x54cc0001, mmCP_DFY_DATA_0 }, + { 0x95800060, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4193247, mmCP_DFY_DATA_0 }, + { 0x25980001, mmCP_DFY_DATA_0 }, + { 0x9580005c, mmCP_DFY_DATA_0 }, + { 0x7dc24001, mmCP_DFY_DATA_0 }, + { 0xc41d3248, mmCP_DFY_DATA_0 }, + { 0x25dc000f, mmCP_DFY_DATA_0 }, + { 0x7dd2000c, mmCP_DFY_DATA_0 }, + { 0x96000057, mmCP_DFY_DATA_0 }, + { 0xc41d3255, mmCP_DFY_DATA_0 }, + { 0xc435324f, mmCP_DFY_DATA_0 }, + { 0x7df5c00c, mmCP_DFY_DATA_0 }, + { 0x99c00004, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x25980040, mmCP_DFY_DATA_0 }, + { 0x9580fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x1bb0003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1bb000e8, mmCP_DFY_DATA_0 }, + { 0x33380003, mmCP_DFY_DATA_0 }, + { 0x9b800046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xc4393260, mmCP_DFY_DATA_0 }, + { 0x1bb000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x800016f1, mmCP_DFY_DATA_0 }, + { 0xce400013, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x7f3b0009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b800ff, mmCP_DFY_DATA_0 }, + { 0x9b80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x1a7003e6, mmCP_DFY_DATA_0 }, + { 0x27380003, mmCP_DFY_DATA_0 }, + { 0x13b80004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x1a7000e8, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x07b80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x1a700064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x800016df, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7fb30002, mmCP_DFY_DATA_0 }, + { 0xc4392083, mmCP_DFY_DATA_0 }, + { 0x7fb38005, mmCP_DFY_DATA_0 }, + { 0x27b80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xce400013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffca, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x800016f2, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940ff9c, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd840004f, mmCP_DFY_DATA_0 }, + { 0xc414000e, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0xd80802e9, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18fc0064, mmCP_DFY_DATA_0 }, + { 0x9bc00042, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7dd9801a, mmCP_DFY_DATA_0 }, + { 0x45980400, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x043c3000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0x9bc00001, mmCP_DFY_DATA_0 }, + { 0x1b380057, mmCP_DFY_DATA_0 }, + { 0x1b340213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0x14f4001d, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x9bc0001c, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x192807fa, mmCP_DFY_DATA_0 }, + { 0xc4bf0258, mmCP_DFY_DATA_0 }, + { 0xc4a70250, mmCP_DFY_DATA_0 }, + { 0x53fc0020, mmCP_DFY_DATA_0 }, + { 0x7e7e401a, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0x04300000, mmCP_DFY_DATA_0 }, + { 0x667c0001, mmCP_DFY_DATA_0 }, + { 0x56640001, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x97c0fffd, mmCP_DFY_DATA_0 }, + { 0x07300001, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x7eebc00c, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x97c0fff8, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x43300007, mmCP_DFY_DATA_0 }, + { 0x53300002, mmCP_DFY_DATA_0 }, + { 0x7db30011, mmCP_DFY_DATA_0 }, + { 0xd3000025, mmCP_DFY_DATA_0 }, + { 0xc03ec005, mmCP_DFY_DATA_0 }, + { 0x2bfca200, mmCP_DFY_DATA_0 }, + { 0xcfc00026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0xcd000026, mmCP_DFY_DATA_0 }, + { 0x192807fa, mmCP_DFY_DATA_0 }, + { 0xc01f007f, mmCP_DFY_DATA_0 }, + { 0x7d1d0009, mmCP_DFY_DATA_0 }, + { 0x2110007d, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x203c003f, mmCP_DFY_DATA_0 }, + { 0xcfc13256, mmCP_DFY_DATA_0 }, + { 0x8c0017f5, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0x18fc01e8, mmCP_DFY_DATA_0 }, + { 0xcfc13248, mmCP_DFY_DATA_0 }, + { 0x8c00185b, mmCP_DFY_DATA_0 }, + { 0xd8413247, mmCP_DFY_DATA_0 }, + { 0x0b740001, mmCP_DFY_DATA_0 }, + { 0x9b40ffd5, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x97c0ea24, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x14d4001d, mmCP_DFY_DATA_0 }, + { 0xc4930260, mmCP_DFY_DATA_0 }, + { 0x7d52400e, mmCP_DFY_DATA_0 }, + { 0xc49f0258, mmCP_DFY_DATA_0 }, + { 0xc4a30250, mmCP_DFY_DATA_0 }, + { 0x51dc0020, mmCP_DFY_DATA_0 }, + { 0x7de1801a, mmCP_DFY_DATA_0 }, + { 0x96400017, mmCP_DFY_DATA_0 }, + { 0x7d534002, mmCP_DFY_DATA_0 }, + { 0xc4af0270, mmCP_DFY_DATA_0 }, + { 0x7dae4005, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x32e0001f, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0xcec80270, mmCP_DFY_DATA_0 }, + { 0x8000174f, mmCP_DFY_DATA_0 }, + { 0x0b740001, mmCP_DFY_DATA_0 }, + { 0x8c00178a, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x9b40fff3, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0xc4ab0268, mmCP_DFY_DATA_0 }, + { 0x7daa4005, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x32a0001f, mmCP_DFY_DATA_0 }, + { 0x9a400005, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0x24280000, mmCP_DFY_DATA_0 }, + { 0x80001765, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xc01f007f, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x7d1d0009, mmCP_DFY_DATA_0 }, + { 0x2110007d, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xd8013256, mmCP_DFY_DATA_0 }, + { 0x8c0017f2, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0xc4113248, mmCP_DFY_DATA_0 }, + { 0x15100004, mmCP_DFY_DATA_0 }, + { 0x11100004, mmCP_DFY_DATA_0 }, + { 0xc4b3034b, mmCP_DFY_DATA_0 }, + { 0x7f13000a, mmCP_DFY_DATA_0 }, + { 0xcf013248, mmCP_DFY_DATA_0 }, + { 0xc4930260, mmCP_DFY_DATA_0 }, + { 0x8c001855, mmCP_DFY_DATA_0 }, + { 0x32a4001f, mmCP_DFY_DATA_0 }, + { 0xd8413247, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x09100001, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0x24280000, mmCP_DFY_DATA_0 }, + { 0xcd080260, mmCP_DFY_DATA_0 }, + { 0xce880268, mmCP_DFY_DATA_0 }, + { 0x9940ffc0, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7ec28001, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x32e0001f, mmCP_DFY_DATA_0 }, + { 0xc4253247, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9640005e, mmCP_DFY_DATA_0 }, + { 0xc4293265, mmCP_DFY_DATA_0 }, + { 0xc4253255, mmCP_DFY_DATA_0 }, + { 0xc431324f, mmCP_DFY_DATA_0 }, + { 0x7e72400c, mmCP_DFY_DATA_0 }, + { 0x26a80040, mmCP_DFY_DATA_0 }, + { 0x9a400002, mmCP_DFY_DATA_0 }, + { 0x9680fff7, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x1aa4003f, mmCP_DFY_DATA_0 }, + { 0x96400049, mmCP_DFY_DATA_0 }, + { 0x1aa400e8, mmCP_DFY_DATA_0 }, + { 0x32680003, mmCP_DFY_DATA_0 }, + { 0x9a800046, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9640000a, mmCP_DFY_DATA_0 }, + { 0xc4293260, mmCP_DFY_DATA_0 }, + { 0x1aa400e4, mmCP_DFY_DATA_0 }, + { 0x32640004, mmCP_DFY_DATA_0 }, + { 0x96400040, mmCP_DFY_DATA_0 }, + { 0xc425325d, mmCP_DFY_DATA_0 }, + { 0x26640010, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x800017e2, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc027ffff, mmCP_DFY_DATA_0 }, + { 0x2e6400ff, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x7e6a4009, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x26a800ff, mmCP_DFY_DATA_0 }, + { 0x9a80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4240009, mmCP_DFY_DATA_0 }, + { 0x26640008, mmCP_DFY_DATA_0 }, + { 0x9640fffe, mmCP_DFY_DATA_0 }, + { 0x19e403e6, mmCP_DFY_DATA_0 }, + { 0x26680003, mmCP_DFY_DATA_0 }, + { 0x12a80004, mmCP_DFY_DATA_0 }, + { 0x26640003, mmCP_DFY_DATA_0 }, + { 0x12640003, mmCP_DFY_DATA_0 }, + { 0x7ea68001, mmCP_DFY_DATA_0 }, + { 0x19e400e8, mmCP_DFY_DATA_0 }, + { 0x7ea68001, mmCP_DFY_DATA_0 }, + { 0x12640001, mmCP_DFY_DATA_0 }, + { 0x7ea68001, mmCP_DFY_DATA_0 }, + { 0x06a80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19e40064, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x96400009, mmCP_DFY_DATA_0 }, + { 0x16a40005, mmCP_DFY_DATA_0 }, + { 0x06640003, mmCP_DFY_DATA_0 }, + { 0xce412082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0a640003, mmCP_DFY_DATA_0 }, + { 0x800017d0, mmCP_DFY_DATA_0 }, + { 0x16a40005, mmCP_DFY_DATA_0 }, + { 0xce412082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x12640005, mmCP_DFY_DATA_0 }, + { 0x7ea64002, mmCP_DFY_DATA_0 }, + { 0xc4292083, mmCP_DFY_DATA_0 }, + { 0x7ea68005, mmCP_DFY_DATA_0 }, + { 0x26a80001, mmCP_DFY_DATA_0 }, + { 0x9a80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc425325d, mmCP_DFY_DATA_0 }, + { 0x26640010, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x26a400ff, mmCP_DFY_DATA_0 }, + { 0x9a40ffca, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0x2024007b, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0x800017e3, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0xc4a70280, mmCP_DFY_DATA_0 }, + { 0xc4ab0278, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x04280001, mmCP_DFY_DATA_0 }, + { 0x7eae8014, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x56680020, mmCP_DFY_DATA_0 }, + { 0xce480278, mmCP_DFY_DATA_0 }, + { 0xce880280, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0xcec80270, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0x800017fe, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcf800026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0x800017fe, mmCP_DFY_DATA_0 }, + { 0xc43b02eb, mmCP_DFY_DATA_0 }, + { 0xc42302ec, mmCP_DFY_DATA_0 }, + { 0xcf813245, mmCP_DFY_DATA_0 }, + { 0xce013246, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7fa3801a, mmCP_DFY_DATA_0 }, + { 0x47b8020c, mmCP_DFY_DATA_0 }, + { 0x15e00008, mmCP_DFY_DATA_0 }, + { 0x1220000a, mmCP_DFY_DATA_0 }, + { 0x2a206032, mmCP_DFY_DATA_0 }, + { 0x513c001e, mmCP_DFY_DATA_0 }, + { 0x7e3e001a, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x9bc00005, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x8000180f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x1b3c0077, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7ff3000a, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x2b300032, mmCP_DFY_DATA_0 }, + { 0x043c3000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0xd200000b, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xd3800002, mmCP_DFY_DATA_0 }, + { 0xcf000002, mmCP_DFY_DATA_0 }, + { 0xd8000040, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0xd8400040, mmCP_DFY_DATA_0 }, + { 0xd8400018, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xd8000018, mmCP_DFY_DATA_0 }, + { 0xd8800010, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0x7dc30001, mmCP_DFY_DATA_0 }, + { 0xdc1e0000, mmCP_DFY_DATA_0 }, + { 0x04380032, mmCP_DFY_DATA_0 }, + { 0xcf80000e, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0xcc413248, mmCP_DFY_DATA_0 }, + { 0xc43d3269, mmCP_DFY_DATA_0 }, + { 0x27fc000f, mmCP_DFY_DATA_0 }, + { 0x33fc0003, mmCP_DFY_DATA_0 }, + { 0x97c00011, mmCP_DFY_DATA_0 }, + { 0x043c001f, mmCP_DFY_DATA_0 }, + { 0xdfc30000, mmCP_DFY_DATA_0 }, + { 0xd4413249, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x043c0024, mmCP_DFY_DATA_0 }, + { 0x0bfc0021, mmCP_DFY_DATA_0 }, + { 0xdfc30000, mmCP_DFY_DATA_0 }, + { 0xd441326a, mmCP_DFY_DATA_0 }, + { 0x173c0008, mmCP_DFY_DATA_0 }, + { 0x1b300303, mmCP_DFY_DATA_0 }, + { 0x7f3f0001, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x7ff3c004, mmCP_DFY_DATA_0 }, + { 0xcfc13084, mmCP_DFY_DATA_0 }, + { 0x80001842, mmCP_DFY_DATA_0 }, + { 0x043c0024, mmCP_DFY_DATA_0 }, + { 0xdfc30000, mmCP_DFY_DATA_0 }, + { 0xd4413249, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x23fc003f, mmCP_DFY_DATA_0 }, + { 0xcfc1326d, mmCP_DFY_DATA_0 }, + { 0x0bb80026, mmCP_DFY_DATA_0 }, + { 0xdf830000, mmCP_DFY_DATA_0 }, + { 0xd441326e, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0xc4393265, mmCP_DFY_DATA_0 }, + { 0x1fb8ffc6, mmCP_DFY_DATA_0 }, + { 0xddc30000, mmCP_DFY_DATA_0 }, + { 0xcf813265, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0xcdc0000c, mmCP_DFY_DATA_0 }, + { 0x80001852, mmCP_DFY_DATA_0 }, + { 0xcdc0000d, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcdc13252, mmCP_DFY_DATA_0 }, + { 0xce013253, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x80001878, mmCP_DFY_DATA_0 }, + { 0xc49f02e9, mmCP_DFY_DATA_0 }, + { 0x99c00018, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcdc13252, mmCP_DFY_DATA_0 }, + { 0xce013253, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x043c3000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0x97c0ffff, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc41c0012, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x80001878, mmCP_DFY_DATA_0 }, + { 0xc41f02ed, mmCP_DFY_DATA_0 }, + { 0xc42302ee, mmCP_DFY_DATA_0 }, + { 0xcdc13252, mmCP_DFY_DATA_0 }, + { 0xce013253, mmCP_DFY_DATA_0 }, + { 0x04200001, mmCP_DFY_DATA_0 }, + { 0x7e2a0004, mmCP_DFY_DATA_0 }, + { 0xce013084, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x28340001, mmCP_DFY_DATA_0 }, + { 0x313c0bcc, mmCP_DFY_DATA_0 }, + { 0x9bc00010, mmCP_DFY_DATA_0 }, + { 0x393c051f, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0x3d3c050e, mmCP_DFY_DATA_0 }, + { 0x9bc0000c, mmCP_DFY_DATA_0 }, + { 0x97c0000c, mmCP_DFY_DATA_0 }, + { 0x393c0560, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0x3d3c054f, mmCP_DFY_DATA_0 }, + { 0x9bc00007, mmCP_DFY_DATA_0 }, + { 0x97c00007, mmCP_DFY_DATA_0 }, + { 0x393c1538, mmCP_DFY_DATA_0 }, + { 0x9bc00005, mmCP_DFY_DATA_0 }, + { 0x3d3c1537, mmCP_DFY_DATA_0 }, + { 0x9bc00002, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0x2b740800, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18e8007c, mmCP_DFY_DATA_0 }, + { 0x7c42c001, mmCP_DFY_DATA_0 }, + { 0x06a8189a, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0x800018c5, mmCP_DFY_DATA_0 }, + { 0x800018f2, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x18d0007e, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x09200001, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x09240002, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x99000011, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc42130b5, mmCP_DFY_DATA_0 }, + { 0x1a24002c, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x2020002c, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0x1198001c, mmCP_DFY_DATA_0 }, + { 0x10cc0004, mmCP_DFY_DATA_0 }, + { 0x14cc0004, mmCP_DFY_DATA_0 }, + { 0x7cd8c00a, mmCP_DFY_DATA_0 }, + { 0xccc130b7, mmCP_DFY_DATA_0 }, + { 0xce0130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0x5978073a, mmCP_DFY_DATA_0 }, + { 0x2bb80002, mmCP_DFY_DATA_0 }, + { 0xcf800024, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9600e8a8, mmCP_DFY_DATA_0 }, + { 0xc4300012, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0x9640e8a5, mmCP_DFY_DATA_0 }, + { 0x800018a9, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0xc55b0309, mmCP_DFY_DATA_0 }, + { 0x3d5c0010, mmCP_DFY_DATA_0 }, + { 0x05540001, mmCP_DFY_DATA_0 }, + { 0x2598ffff, mmCP_DFY_DATA_0 }, + { 0x09780001, mmCP_DFY_DATA_0 }, + { 0x7dad800c, mmCP_DFY_DATA_0 }, + { 0x99c0ffd2, mmCP_DFY_DATA_0 }, + { 0x9580fff9, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x442c0000, mmCP_DFY_DATA_0 }, + { 0x65180001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9580000b, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc41d3248, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x25dc000f, mmCP_DFY_DATA_0 }, + { 0x7df9c00c, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xd8c13260, mmCP_DFY_DATA_0 }, + { 0xd901325d, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940fff1, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x66d80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x56ec0001, mmCP_DFY_DATA_0 }, + { 0x95800005, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc421325d, mmCP_DFY_DATA_0 }, + { 0x26240007, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940fff7, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc41d3254, mmCP_DFY_DATA_0 }, + { 0xc023007f, mmCP_DFY_DATA_0 }, + { 0x19e4003e, mmCP_DFY_DATA_0 }, + { 0x7de1c009, mmCP_DFY_DATA_0 }, + { 0x7dee000c, mmCP_DFY_DATA_0 }, + { 0x96400008, mmCP_DFY_DATA_0 }, + { 0x96000007, mmCP_DFY_DATA_0 }, + { 0xd8c13260, mmCP_DFY_DATA_0 }, + { 0xd901325d, mmCP_DFY_DATA_0 }, + { 0xc421325d, mmCP_DFY_DATA_0 }, + { 0x261c0007, mmCP_DFY_DATA_0 }, + { 0x99c0fffe, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940fff0, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18e00064, mmCP_DFY_DATA_0 }, + { 0x06281911, mmCP_DFY_DATA_0 }, + { 0x14f4001d, mmCP_DFY_DATA_0 }, + { 0x24cc0003, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80001915, mmCP_DFY_DATA_0 }, + { 0x800019af, mmCP_DFY_DATA_0 }, + { 0x80001a2b, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xcc48032b, mmCP_DFY_DATA_0 }, + { 0xcc480333, mmCP_DFY_DATA_0 }, + { 0xcc48033b, mmCP_DFY_DATA_0 }, + { 0xcc480343, mmCP_DFY_DATA_0 }, + { 0x98800011, mmCP_DFY_DATA_0 }, + { 0xc4213246, mmCP_DFY_DATA_0 }, + { 0xc4253245, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26401a, mmCP_DFY_DATA_0 }, + { 0x46640400, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04203000, mmCP_DFY_DATA_0 }, + { 0xce013267, mmCP_DFY_DATA_0 }, + { 0xc4213267, mmCP_DFY_DATA_0 }, + { 0x9a000001, mmCP_DFY_DATA_0 }, + { 0x1b3c0057, mmCP_DFY_DATA_0 }, + { 0x1b200213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7e3e000a, mmCP_DFY_DATA_0 }, + { 0x7e32000a, mmCP_DFY_DATA_0 }, + { 0xce000024, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04180000, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x7f438001, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc41d3247, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0x95c00068, mmCP_DFY_DATA_0 }, + { 0xc4213254, mmCP_DFY_DATA_0 }, + { 0x1a1c003e, mmCP_DFY_DATA_0 }, + { 0x95c00065, mmCP_DFY_DATA_0 }, + { 0xc01f007f, mmCP_DFY_DATA_0 }, + { 0x7e1e0009, mmCP_DFY_DATA_0 }, + { 0x97800062, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x43bc0008, mmCP_DFY_DATA_0 }, + { 0x7fcbc001, mmCP_DFY_DATA_0 }, + { 0xc7df032b, mmCP_DFY_DATA_0 }, + { 0x7e1fc00c, mmCP_DFY_DATA_0 }, + { 0x97c0fffa, mmCP_DFY_DATA_0 }, + { 0x043c0101, mmCP_DFY_DATA_0 }, + { 0x94c00002, mmCP_DFY_DATA_0 }, + { 0x043c0102, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x1bb0003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1bb000e8, mmCP_DFY_DATA_0 }, + { 0x33380003, mmCP_DFY_DATA_0 }, + { 0x9b800046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0xc4393260, mmCP_DFY_DATA_0 }, + { 0x1bb000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x80001994, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x7f3b0009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b800ff, mmCP_DFY_DATA_0 }, + { 0x9b80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x19f003e6, mmCP_DFY_DATA_0 }, + { 0x27380003, mmCP_DFY_DATA_0 }, + { 0x13b80004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x19f000e8, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x07b80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19f00064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x80001982, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7fb30002, mmCP_DFY_DATA_0 }, + { 0xc4392083, mmCP_DFY_DATA_0 }, + { 0x7fb38005, mmCP_DFY_DATA_0 }, + { 0x27b80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffcb, mmCP_DFY_DATA_0 }, + { 0xcfc1325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x80001995, mmCP_DFY_DATA_0 }, + { 0xcfc1325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x98800009, mmCP_DFY_DATA_0 }, + { 0x41bc0007, mmCP_DFY_DATA_0 }, + { 0x53fc0002, mmCP_DFY_DATA_0 }, + { 0x7e7fc011, mmCP_DFY_DATA_0 }, + { 0xd3c00025, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc43c0012, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0x653c0001, mmCP_DFY_DATA_0 }, + { 0x7dbd8001, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9940ff8f, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0xc55b0309, mmCP_DFY_DATA_0 }, + { 0x3d5c0010, mmCP_DFY_DATA_0 }, + { 0x2598ffff, mmCP_DFY_DATA_0 }, + { 0x05540001, mmCP_DFY_DATA_0 }, + { 0x7d91800c, mmCP_DFY_DATA_0 }, + { 0x95c00003, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x9580fff8, mmCP_DFY_DATA_0 }, + { 0x09780001, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x65180001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9580005d, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4253247, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x04200101, mmCP_DFY_DATA_0 }, + { 0x96400058, mmCP_DFY_DATA_0 }, + { 0x7dc24001, mmCP_DFY_DATA_0 }, + { 0xc41d3248, mmCP_DFY_DATA_0 }, + { 0x25dc000f, mmCP_DFY_DATA_0 }, + { 0x7df9c00c, mmCP_DFY_DATA_0 }, + { 0x95c00053, mmCP_DFY_DATA_0 }, + { 0x94c00002, mmCP_DFY_DATA_0 }, + { 0x04200102, mmCP_DFY_DATA_0 }, + { 0x7e41c001, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x1a70003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1a7000e8, mmCP_DFY_DATA_0 }, + { 0x33240003, mmCP_DFY_DATA_0 }, + { 0x9a400046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xc4253260, mmCP_DFY_DATA_0 }, + { 0x1a7000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x80001a21, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x7f270009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x266400ff, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x19f003e6, mmCP_DFY_DATA_0 }, + { 0x27240003, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x19f000e8, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x06640002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19f00064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x16700005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x80001a0f, mmCP_DFY_DATA_0 }, + { 0x16700005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7e730002, mmCP_DFY_DATA_0 }, + { 0xc4252083, mmCP_DFY_DATA_0 }, + { 0x7e724005, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9a40ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x267000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffca, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x80001a22, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940ff9f, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x8c001a31, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc4213246, mmCP_DFY_DATA_0 }, + { 0xc4253245, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26401a, mmCP_DFY_DATA_0 }, + { 0x46640400, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04203000, mmCP_DFY_DATA_0 }, + { 0xce013267, mmCP_DFY_DATA_0 }, + { 0xc4213267, mmCP_DFY_DATA_0 }, + { 0x9a000001, mmCP_DFY_DATA_0 }, + { 0x1b180057, mmCP_DFY_DATA_0 }, + { 0x1b200213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7e1a000a, mmCP_DFY_DATA_0 }, + { 0x7e32000a, mmCP_DFY_DATA_0 }, + { 0xce000024, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x65180001, mmCP_DFY_DATA_0 }, + { 0x95800060, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4193247, mmCP_DFY_DATA_0 }, + { 0x25980001, mmCP_DFY_DATA_0 }, + { 0x04200101, mmCP_DFY_DATA_0 }, + { 0x94c00005, mmCP_DFY_DATA_0 }, + { 0x30f00005, mmCP_DFY_DATA_0 }, + { 0x04200005, mmCP_DFY_DATA_0 }, + { 0x9b000002, mmCP_DFY_DATA_0 }, + { 0x04200102, mmCP_DFY_DATA_0 }, + { 0x95800056, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x1bb0003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1bb000e8, mmCP_DFY_DATA_0 }, + { 0x33380003, mmCP_DFY_DATA_0 }, + { 0x9b800046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xc4393260, mmCP_DFY_DATA_0 }, + { 0x1bb000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x80001aa2, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x7f3b0009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b800ff, mmCP_DFY_DATA_0 }, + { 0x9b80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x19f003e6, mmCP_DFY_DATA_0 }, + { 0x27380003, mmCP_DFY_DATA_0 }, + { 0x13b80004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x19f000e8, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x07b80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19f00064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x80001a90, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7fb30002, mmCP_DFY_DATA_0 }, + { 0xc4392083, mmCP_DFY_DATA_0 }, + { 0x7fb38005, mmCP_DFY_DATA_0 }, + { 0x27b80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffca, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf00325b, mmCP_DFY_DATA_0 }, + { 0x80001aa3, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc49b02e9, mmCP_DFY_DATA_0 }, + { 0x99800005, mmCP_DFY_DATA_0 }, + { 0xd2400025, mmCP_DFY_DATA_0 }, + { 0x4664001c, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9940ff9c, mmCP_DFY_DATA_0 }, + { 0xc49b02e9, mmCP_DFY_DATA_0 }, + { 0x99800008, mmCP_DFY_DATA_0 }, + { 0xc430000e, mmCP_DFY_DATA_0 }, + { 0x2b300008, mmCP_DFY_DATA_0 }, + { 0xcf000013, mmCP_DFY_DATA_0 }, + { 0x04302000, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x244c00ff, mmCP_DFY_DATA_0 }, + { 0xcc4c0200, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc44f0200, mmCP_DFY_DATA_0 }, + { 0xc410000b, mmCP_DFY_DATA_0 }, + { 0xc414000c, mmCP_DFY_DATA_0 }, + { 0x7d158010, mmCP_DFY_DATA_0 }, + { 0x059cc000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccdd0000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c0037, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0xcc000049, mmCP_DFY_DATA_0 }, + { 0xc40c003a, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x24d00001, mmCP_DFY_DATA_0 }, + { 0x9500e69a, mmCP_DFY_DATA_0 }, + { 0x18d0003b, mmCP_DFY_DATA_0 }, + { 0x18d40021, mmCP_DFY_DATA_0 }, + { 0x99400006, mmCP_DFY_DATA_0 }, + { 0xd840004a, mmCP_DFY_DATA_0 }, + { 0xc40c003c, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0x14cc0001, mmCP_DFY_DATA_0 }, + { 0x94c00028, mmCP_DFY_DATA_0 }, + { 0xd8000033, mmCP_DFY_DATA_0 }, + { 0xc438000b, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0001, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd841c07f, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x1bfc0078, mmCP_DFY_DATA_0 }, + { 0x7ffbc00c, mmCP_DFY_DATA_0 }, + { 0x97c0fffd, mmCP_DFY_DATA_0 }, + { 0x99000004, mmCP_DFY_DATA_0 }, + { 0xc0120840, mmCP_DFY_DATA_0 }, + { 0x282c0040, mmCP_DFY_DATA_0 }, + { 0x80001ae8, mmCP_DFY_DATA_0 }, + { 0xc0121841, mmCP_DFY_DATA_0 }, + { 0x282c001a, mmCP_DFY_DATA_0 }, + { 0xcd01c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04200004, mmCP_DFY_DATA_0 }, + { 0xcec0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0x166c001f, mmCP_DFY_DATA_0 }, + { 0x04200004, mmCP_DFY_DATA_0 }, + { 0x9ac0fffb, mmCP_DFY_DATA_0 }, + { 0xc434000f, mmCP_DFY_DATA_0 }, + { 0x9b40ffff, mmCP_DFY_DATA_0 }, + { 0xd801c07f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0xce400078, mmCP_DFY_DATA_0 }, + { 0xd8000034, mmCP_DFY_DATA_0 }, + { 0x9940e66b, mmCP_DFY_DATA_0 }, + { 0xd800004a, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c0036, mmCP_DFY_DATA_0 }, + { 0x24d00001, mmCP_DFY_DATA_0 }, + { 0x9900fffe, mmCP_DFY_DATA_0 }, + { 0x18cc0021, mmCP_DFY_DATA_0 }, + { 0xccc00047, mmCP_DFY_DATA_0 }, + { 0xcc000046, mmCP_DFY_DATA_0 }, + { 0xc40c0039, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0xc40c003d, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x24d003ff, mmCP_DFY_DATA_0 }, + { 0x18d47fea, mmCP_DFY_DATA_0 }, + { 0x18d87ff4, mmCP_DFY_DATA_0 }, + { 0xcd00004c, mmCP_DFY_DATA_0 }, + { 0xcd40004e, mmCP_DFY_DATA_0 }, + { 0xcd80004d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd41c405, mmCP_DFY_DATA_0 }, + { 0xc02a0001, mmCP_DFY_DATA_0 }, + { 0x2aa80001, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xcd01c406, mmCP_DFY_DATA_0 }, + { 0xcc01c406, mmCP_DFY_DATA_0 }, + { 0xcc01c406, mmCP_DFY_DATA_0 }, + { 0xc40c0006, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0xc414000e, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0x295c0001, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8c1325e, mmCP_DFY_DATA_0 }, + { 0xcdc0001a, mmCP_DFY_DATA_0 }, + { 0x11980002, mmCP_DFY_DATA_0 }, + { 0x4110000c, mmCP_DFY_DATA_0 }, + { 0xc0160800, mmCP_DFY_DATA_0 }, + { 0x7d15000a, mmCP_DFY_DATA_0 }, + { 0xc0164010, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd41c078, mmCP_DFY_DATA_0 }, + { 0xcc01c080, mmCP_DFY_DATA_0 }, + { 0xcc01c081, mmCP_DFY_DATA_0 }, + { 0xcd81c082, mmCP_DFY_DATA_0 }, + { 0xcc01c083, mmCP_DFY_DATA_0 }, + { 0xcd01c084, mmCP_DFY_DATA_0 }, + { 0xc40c0006, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400048, mmCP_DFY_DATA_0 }, + { 0xc40c003b, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd801c40a, mmCP_DFY_DATA_0 }, + { 0xd901c40d, mmCP_DFY_DATA_0 }, + { 0xd801c410, mmCP_DFY_DATA_0 }, + { 0xd801c40e, mmCP_DFY_DATA_0 }, + { 0xd801c40f, mmCP_DFY_DATA_0 }, + { 0xc40c0040, mmCP_DFY_DATA_0 }, + { 0x04140001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x9940ffff, mmCP_DFY_DATA_0 }, + { 0x04140096, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1c400, mmCP_DFY_DATA_0 }, + { 0xc411c401, mmCP_DFY_DATA_0 }, + { 0x9500fffa, mmCP_DFY_DATA_0 }, + { 0xc424003e, mmCP_DFY_DATA_0 }, + { 0x04d00001, mmCP_DFY_DATA_0 }, + { 0x11100002, mmCP_DFY_DATA_0 }, + { 0xcd01c40c, mmCP_DFY_DATA_0 }, + { 0xc0180034, mmCP_DFY_DATA_0 }, + { 0xcd81c411, mmCP_DFY_DATA_0 }, + { 0xd841c414, mmCP_DFY_DATA_0 }, + { 0x0a540001, mmCP_DFY_DATA_0 }, + { 0xcd41c412, mmCP_DFY_DATA_0 }, + { 0x2468000f, mmCP_DFY_DATA_0 }, + { 0xc419c416, mmCP_DFY_DATA_0 }, + { 0x41980003, mmCP_DFY_DATA_0 }, + { 0xc41c003f, mmCP_DFY_DATA_0 }, + { 0x7dda0001, mmCP_DFY_DATA_0 }, + { 0x12200002, mmCP_DFY_DATA_0 }, + { 0x10cc0002, mmCP_DFY_DATA_0 }, + { 0xccc1c40c, mmCP_DFY_DATA_0 }, + { 0xd901c411, mmCP_DFY_DATA_0 }, + { 0xce41c412, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xce292e40, mmCP_DFY_DATA_0 }, + { 0xcc412e01, mmCP_DFY_DATA_0 }, + { 0xcc412e02, mmCP_DFY_DATA_0 }, + { 0xcc412e03, mmCP_DFY_DATA_0 }, + { 0xcc412e00, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xdc120000, mmCP_DFY_DATA_0 }, + { 0x31144000, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0xdc030000, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xcc3c000c, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x33f80003, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x9780e601, mmCP_DFY_DATA_0 }, + { 0x188cfff0, mmCP_DFY_DATA_0 }, + { 0x04e40002, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x96400006, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x96400003, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x80001b74, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x54106500, mmCP_DFY_ADDR_LO }, + { 0x7e000200, mmCP_DFY_DATA_0 }, + { 0x7e020204, mmCP_DFY_DATA_0 }, + { 0xc00a0505, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xbf8c007f, mmCP_DFY_DATA_0 }, + { 0xb8900904, mmCP_DFY_DATA_0 }, + { 0xb8911a04, mmCP_DFY_DATA_0 }, + { 0xb8920304, mmCP_DFY_DATA_0 }, + { 0xb8930b44, mmCP_DFY_DATA_0 }, + { 0x921c0d0c, mmCP_DFY_DATA_0 }, + { 0x921c1c13, mmCP_DFY_DATA_0 }, + { 0x921d0c12, mmCP_DFY_DATA_0 }, + { 0x811c1d1c, mmCP_DFY_DATA_0 }, + { 0x811c111c, mmCP_DFY_DATA_0 }, + { 0x921cff1c, mmCP_DFY_DATA_0 }, + { 0x00000400, mmCP_DFY_DATA_0 }, + { 0x921dff10, mmCP_DFY_DATA_0 }, + { 0x00000100, mmCP_DFY_DATA_0 }, + { 0x81181d1c, mmCP_DFY_DATA_0 }, + { 0x7e040218, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050002, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050102, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050002, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050102, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050002, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050102, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x54106900, mmCP_DFY_ADDR_LO }, + { 0x7e080200, mmCP_DFY_DATA_0 }, + { 0x7e100204, mmCP_DFY_DATA_0 }, + { 0xbefc00ff, mmCP_DFY_DATA_0 }, + { 0x00010000, mmCP_DFY_DATA_0 }, + { 0x24200087, mmCP_DFY_DATA_0 }, + { 0x262200ff, mmCP_DFY_DATA_0 }, + { 0x000001f0, mmCP_DFY_DATA_0 }, + { 0x20222282, mmCP_DFY_DATA_0 }, + { 0x28182111, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x54116f00, mmCP_DFY_ADDR_LO }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fe8, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000041, mmCP_DFY_DATA_0 }, + { 0x0000000c, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54116f00, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb454105e, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x000000c0, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54117300, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4541065, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000500, mmCP_DFY_DATA_0 }, + { 0x0000001c, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54117700, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4541069, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000444, mmCP_DFY_DATA_0 }, + { 0x0000008a, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54117b00, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_MEC_CNTL }, + { 0x00000000, mmCP_MEC_CNTL }, + { 0x00000004, mmSRBM_GFX_CNTL }, + { 0x54116f00, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000005, mmSRBM_GFX_CNTL }, + { 0x54117300, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000006, mmSRBM_GFX_CNTL }, + { 0x54117700, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000007, mmSRBM_GFX_CNTL }, + { 0x54117b00, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000004, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000104, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000204, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000304, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000404, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000504, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000604, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000704, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000005, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000105, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000205, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000305, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000405, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000505, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000605, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000705, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000006, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000106, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000206, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000306, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000406, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000506, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000606, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000706, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000007, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000107, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000207, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000307, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000407, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000507, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000607, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000707, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000008, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000108, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000208, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000308, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000408, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000508, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000608, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000708, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000009, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000109, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000209, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000309, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000409, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000509, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000609, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000709, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000004, mmSRBM_GFX_CNTL }, + { 0x01010101, mmCP_PQ_WPTR_POLL_CNTL1 }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, 0xffffffff }, }; #endif diff --git a/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h b/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h index 0de443612312..76039860580d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h +++ b/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h @@ -29,17 +29,7 @@ #define mmCP_HYP_MEC2_UCODE_ADDR 0xf81c #define mmCP_HYP_MEC2_UCODE_DATA 0xf81d -enum PWR_Command { - PwrCmdNull = 0, - PwrCmdWrite, - PwrCmdEnd, - PwrCmdMax -}; - -typedef enum PWR_Command PWR_Command; - struct PWR_Command_Table { - PWR_Command command; uint32_t data; uint32_t reg; }; @@ -50,10037 +40,10037 @@ typedef struct PWR_Command_Table PWR_Command_Table; #define PWR_VIRUS_TABLE_SIZE 10031 static const PWR_Command_Table pwr_virus_table[PWR_VIRUS_TABLE_SIZE] = { - { PwrCmdWrite, 0x00000000, mmRLC_CNTL }, - { PwrCmdWrite, 0x00000002, mmRLC_SRM_CNTL }, - { PwrCmdWrite, 0x15000000, mmCP_ME_CNTL }, - { PwrCmdWrite, 0x50000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x0840800a, mmCP_RB0_CNTL }, - { PwrCmdWrite, 0xf30fff0f, mmTCC_CTRL }, - { PwrCmdWrite, 0x00000002, mmTCC_EXE_DISABLE }, - { PwrCmdWrite, 0x000000ff, mmTCP_ADDR_CONFIG }, - { PwrCmdWrite, 0x540ff000, mmCP_CPC_IC_BASE_LO }, - { PwrCmdWrite, 0x000000b4, mmCP_CPC_IC_BASE_HI }, - { PwrCmdWrite, 0x00010000, mmCP_HYP_MEC1_UCODE_ADDR }, - { PwrCmdWrite, 0x00041b75, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000710e8, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000910dd, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000a1081, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000b016f, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000c0e3c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000d10ec, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000e0188, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00101b5d, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00150a6c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00170c5e, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x001d0c8c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x001e0cfe, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00221408, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00370d7b, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00390dcb, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x003c142f, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x003f0b27, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00400e63, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00500f62, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00460fa7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00490fa7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x005811d4, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00680ad6, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00760b00, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00780b0c, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00790af7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x007d1aba, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x007e1abe, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00591260, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x005a12fb, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00861ac7, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x008c1b01, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x008d1b34, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a014b9, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a1152e, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a216fb, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a41890, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a31906, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00a50b14, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00621387, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x005c0b27, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00160a75, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { PwrCmdWrite, 0x00010000, mmCP_HYP_MEC2_UCODE_ADDR }, - { PwrCmdWrite, 0x00041b75, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000710e8, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000910dd, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000a1081, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000b016f, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000c0e3c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000d10ec, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000e0188, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00101b5d, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00150a6c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00170c5e, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x001d0c8c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x001e0cfe, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00221408, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00370d7b, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00390dcb, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x003c142f, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x003f0b27, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00400e63, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00500f62, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00460fa7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00490fa7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x005811d4, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00680ad6, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00760b00, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00780b0c, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00790af7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x007d1aba, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x007e1abe, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00591260, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x005a12fb, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00861ac7, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x008c1b01, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x008d1b34, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a014b9, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a1152e, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a216fb, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a41890, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a31906, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00a50b14, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00621387, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x005c0b27, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x00160a75, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x540fe800, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0x7e000200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e020201, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e040204, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e060205, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a080500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a0a0303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54106f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000400b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00004000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00804fac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x540fef00, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0xc0031502, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00001e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x540ff000, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000145, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdcc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080061, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ccffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3cd08000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1cd0ffcf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x050c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x84c00000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000067, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000006a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000008f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000099, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800000a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800000af, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x388c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08880002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d808001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc0700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10c017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0d000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01b10, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x280c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x280c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x280c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca88004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc00006f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28180080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10c017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000013b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd4c0380, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdcc0388, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdcc038c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0c0390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0c0394, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4c0398, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4c039c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8c03a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8c03a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcecc03a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcecc03ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0c03b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0c03b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4c03b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4c03bc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8c03c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57b80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8c03c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfcc03c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57fc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfcc03cc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05dc002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc12009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d200a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc012009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25e01c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25e40300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25e800c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25ec003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e25c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de5c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xddc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31100006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4df0388, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d7038c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d5dc01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4e30390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d70394, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d62001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4e70398, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d7039c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d66401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4eb03a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d6a801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ef03a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d6ec01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4f303b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d73001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4f703b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703bc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d77401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4fb03c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7b801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ff03c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d703cc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7fc01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4d70380, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1c88001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc01e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3cd00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0085, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc006a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc01e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3cd00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1c88001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400051, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aac0027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04080002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000367, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9880fff3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04080010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80c0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80c0319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9880fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d4001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x155c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e80180, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900091a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280196, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d4fe04, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800001b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000032b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000352, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000035f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000701, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000047c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000019f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d98001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0044, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9400036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11540015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a4003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1998003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af0007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15dc000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d65400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a38003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd5c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800045, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411326a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415326b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000056, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40005a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29988000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000073, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001b6d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00005f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000075, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26f00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d190004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af07fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0434001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04343000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf413267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd1c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0160, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc810001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b4c0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f4f400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55180020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x248dfffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc12e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af4007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33740003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ae8003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26680001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253348, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413348, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253348, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x958000d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000315, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04303000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26680001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1714000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d77400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c01e2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e5c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1334e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01334f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813351, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd881334d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3271, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50cc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cdcc011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05900008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00006a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0006b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3272, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d594002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54d00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc12e23, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd012e24, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc12e25, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b340057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b280213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980198, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e40020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20cc003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01e0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2d540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x078c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07d40000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001239, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04f80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x057c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd5c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840007c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c018a6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e22, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800007c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c018a2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800002e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800002e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540188f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc013cfff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x38d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdcc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01882, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000304, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x49980198, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e40020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000329, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc812e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16ec001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1998003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a18003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4093249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1888003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419324c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1598001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d80011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24dc00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31e00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31dc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95801827, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14dc0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a0000ad, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04080000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af4003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca88005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f4b4009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d33400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a4004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1eecffdd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800003c3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa80030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a8004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3272, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e80042, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e8e800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de9c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3271, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50cc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce8c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd30011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11e80007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd300001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1660001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e320009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0328000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e72400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0430000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ac000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d310002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa87600, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280222, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22ec003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8380018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57b00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04343108, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2374007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32a80003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e40213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc0199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cecc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800003e7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980104, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x49980104, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800003f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000448, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf41326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x254c0700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a641fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0726, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a640200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1237b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01755, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde830000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0174c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bb80040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100044, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19180024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x551c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000043d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840006c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000043f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282000f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2555fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0360001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5e124dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e624001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fff9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2555fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980158, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x49980158, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980170, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1154000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e80488, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0006c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f807f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e40077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000048e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000494, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000685, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000686, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800006ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ccc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d79400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e7a400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52a8001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d69401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec0028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004cc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419324e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26e8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12f4000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d324d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d75401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d290004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f8f4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f52800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50e00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004d1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0dc002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x6665fc00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a644000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f534002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x6665fc00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004d7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12f4000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d75401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a644000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e804e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004e7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800004f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000505, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x277401ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf41325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84131db, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26edf000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05a80507, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000050c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000528, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000057d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800005c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800005f3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00063b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000624, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1be00fe4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000066, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400067, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00063b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000624, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ed6c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113271, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193272, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d51401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113274, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253276, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400061, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2730000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7db1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00062, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000063, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400065, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec0188, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26e01000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c131fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x191807e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192007ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x69dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de20014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x561c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013344, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13345, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425334d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419334e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d334f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253351, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec01b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2010007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1910003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2010003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x191807e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2511fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013344, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013345, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180050, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280042, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813273, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13275, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400067, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07d40000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00124f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x057c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec0190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2154003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bd800e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f598004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1be800e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801327a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800005f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000075, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a4004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x277401ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf41325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xda000068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113277, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425334d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419334e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d334f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213350, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253351, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b680057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b700213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b740199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46ec01b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1334a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1be000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0360001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc63124dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fff9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fc14001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c1c03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000697, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27301fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31100005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900008e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000075e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a9feff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d30b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00ac006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28880700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0006de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30d4000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41530b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19980028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800006c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8380023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa38011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c2002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3800025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202400d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27301fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000712, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x194c1c03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c002d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e80714, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000071c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000720, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000747, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000071d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800007c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000732, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000745, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000744, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000072e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a64008c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000075e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0fff1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000723, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41f02f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000743, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8813247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffde, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000072e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0007e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84131db, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195800e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dd7fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1a001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46200200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04283247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af80057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af40213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6f400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6990000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x329c325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x329c3269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x329c3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01defff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d8009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000078a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fff2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03e7ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3f0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1f30001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03e4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d30b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000b80, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x203c003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31dc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e40213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc0199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cecc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000448, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19580066, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15600008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0120001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da18001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d24db, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580137b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00ee000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19080070, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x190c00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2518000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05a80809, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000080e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000080f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000898, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000946, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009e1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a80811, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000815, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000834, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3045, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c091, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31300021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000241, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000084a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02f0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4252087, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5668001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000084a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431ecaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31300021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293059, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00021d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001a41, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43b02f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56f00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8813247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000085e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x950001fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aec0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a40006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de6000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10e40008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2110003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d10ff9e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0245301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801325f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0121fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29108eff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0127ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0131fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e524009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd2400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0180003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd1c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000866, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a8089a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000089e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800008fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000945, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000945, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31300022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2738000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc79d3300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc7a13301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8393300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce793301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x964012a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c028009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800008d2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x242c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02620c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2f0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800008d2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdf93300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce393301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000903, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31240022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ec30011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32f80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x67180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bfc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd981325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000915, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c1325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fff6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f818001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001606, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d838001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16240014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a2801f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2a000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00075e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f40014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33e80010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680ffec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a80948, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000094c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000099b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x459801e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2738000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc79d3300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc7a13301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8393300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce793301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x964011fe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c028009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000978, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x242c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0260800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2f0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000978, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdf93300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce393301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dda801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e838011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001802, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x469c0390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0014df, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31280014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8802ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800062, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31280034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04a809e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800009ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a45, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a59, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a59, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a70250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e72401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b342010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x172c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b30c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04383000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b38007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33b40003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4598001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740002f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002eb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002ed, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4002ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04382000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd84802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001715, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04382000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffbc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04341001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431ecaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a55, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x233c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0130b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49302ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5198001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80002f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53b8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7db9801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000a5e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01106, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e02, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c010fd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce4c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc80c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x58e801fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc01e2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e5c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x44cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55900020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x44cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd812e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd012e02, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd412e03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2264003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1e64001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ab1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a0010ac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd880003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc010ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d403f7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0cc009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41b0367, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d958004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d85800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280adc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000af1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000adf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ae7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000ace, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8d2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d803f7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc010ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0cc009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11940014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29544001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29544003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000af4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd44d2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd44dc000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000ace, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8d2c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000b0a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd44d2c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28148004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4593240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0105e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef3400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14e80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a8000af, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c01043, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a01fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3620005c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2464003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6290ce7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16ac001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ee6c00d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000367, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640102e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a00035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16f8001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc035f0ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e764009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19b401f8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ae4003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000b7c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a4003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc01e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dbd800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d98ff15, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x592c00fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12e00016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x592c007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12e00015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1620000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12e4001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5924007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a4003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00fdb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780f5ca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001b6d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d324e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431324d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x269c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e4004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f67000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f674002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab42010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab8c006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a8000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000bec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000b47, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b34060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a8004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18580037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x262001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d54001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd280200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd680208, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcda80210, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6930200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc6970208, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc69b0210, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd900003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd940003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14fc0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24f800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd88130b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d83c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4093249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1888003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000671, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419324c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1598001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d80011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x321c0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580ffee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c30, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9480000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800f29, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800f23, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800f1a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600f502, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0f500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000f05, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1f30001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16e4001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640f4f4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40f4f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aec003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1374000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02e4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1774000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00ac005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00e0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc8000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28884900, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ff3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400ee1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c40a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c40c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c40d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d0007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15580010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x255400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c411, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c40f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c40e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c410, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ec0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c414, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c415, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c413, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c412, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c030011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c038011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431c417, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435c416, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c419, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc418, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf413261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13263, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813264, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc0030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d77000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000cd6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51b80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f97801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000cd6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ca7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc0031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435c40b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4280032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000cf4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc032800b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d42011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800e6c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x596001fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ce0c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x505c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50600020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x122c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d1f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x566c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x566c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce413261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec13262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d57, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0328009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04143000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e51001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d2d0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19640057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19580213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19600199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da6400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04142000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd413267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4153267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d80034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280d83, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c424001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d8a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d95, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000db1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000d95, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000dbc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11540010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e010001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d75400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4610000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x526c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2ec01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5ae0073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea2800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3c6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc3a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980fff5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01c405, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd441c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3b1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c409, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11540010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4610000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580f3a5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00da7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5aac007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12d80017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56a00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e82400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e58c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19d4003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28182002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc011000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c908009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20880188, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20240090, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1624001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b301ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2330003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0001a2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1910003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2220003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2a000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc0034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e8000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80e71, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000edd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e91, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e91, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ea1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000eaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e7c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e7f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e7f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e87, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000e8f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9e001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213262, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253261, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213264, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253263, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc820001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e82005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da1801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1800072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8180072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x59a001fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea2800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce80001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd180001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421c401, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c401, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ee6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2580, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac260c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0828, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2440, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0093, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ede, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac7c06, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db07c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc337, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc335, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c336, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acec70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ebc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5a10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5a50000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280eea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ef1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000efe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f11, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f2e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000efe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f1f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f26f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7daec01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5af8073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eba800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f25c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c405, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56240020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f24e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c409, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40f247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce190000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0f240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439c040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2580, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac260c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0828, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2440, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac2390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac0093, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31dc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31ac31e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ef2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac7c06, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db07c00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc337, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acc335, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0c336, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39acec70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39ac9012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3db09012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ef1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c1325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c034001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c038001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e0007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f88, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e52401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ac0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26f0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af000fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1334000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e02000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f63400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000f9d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51e40020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8280072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ac0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26f0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1af000fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13380016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e0007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1220001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31140005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31140006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05280fb7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28140002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fc2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fbe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fd1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ff2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ff2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e80039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52a8003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d69401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140004b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d958004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d150005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x159c0011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31a00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31a40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e25800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0fff5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d100010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01326f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc011000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33b40003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0340008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000ffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c908009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c2002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x208801a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20240030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x507c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7d401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x557c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28342002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000102f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1cccfe08, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00b33, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da2400f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da28002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1ac002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d2ac002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3ef40010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40f11d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdcc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd410000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdd810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xddc10000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c024001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100086, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5510003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001075, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d520002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cde0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e20001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001071, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00b01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc0c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc240000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc40003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4080029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a400e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12500009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x248c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x200c006d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x200c0228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18881fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d4072c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc00d1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3094000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x38d80000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x311c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30940007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1620001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010c4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x259c007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a00030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010cb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x199c0fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010cb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000aac, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434002e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2020002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07a810d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000104c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x200c007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28240007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xde430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d3249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192400fd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06681110, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19180070, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19100078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f40058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5978073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001117, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001118, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000112d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001130, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001133, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ec0f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32ec0600, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ec0f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32ec0600, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000117b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc81c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55e00020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001122, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e8e8009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22a8003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22a80074, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2774001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eb6800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25ecffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55700020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15f40010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x275c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15dc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc1c01e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e40008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc2001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e40008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e62000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da58001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001165, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc2001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e0d000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95000007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e02401e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05d80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc2401e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da58001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da2000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600ffe6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00116b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce00001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x22640435, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0528117e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x312c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001185, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001182, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001182, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a0400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1198001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d81c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19a000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de2c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc420007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011a3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d654001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c020001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011b6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253279, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc415326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2730003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3b380006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3f38000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0430000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb10004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e57000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e578002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d67c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0be40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d3a4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x202c002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26200010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e640010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce81325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434002e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07a811cf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00feb8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x954009a7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000bfc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f0012f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f40612, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc00c1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf7400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x39600004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0140004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11600001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9740001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a6c003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800011e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ac007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab00030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aac0fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001205, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11600001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a2800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03ae000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a0800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03ae000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a4000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17fc001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30d00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000052, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640090f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1514001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19180038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d324e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431324d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab0c006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000127f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d3258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab0c012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e624004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f67800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53740002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ab42010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a8000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f6b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1514001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0012e1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x964008d7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9800036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012aa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b34060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f37000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a8002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7edec00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4140032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1858003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0cc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0006c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d407f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d190004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d5d4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d52000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d514002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d958001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd5c002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc1325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1ccc001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd980003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9800040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd9c00040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800010de, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33f80003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800051, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc80003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24b00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18a800e5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1d980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7da9800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b74003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b304000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431326c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50700020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04e81324, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18ac0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50600020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30e40004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d71401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x596401fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b74008d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a640000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000132c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000133b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001344, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42530b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a68003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2024003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d19000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de6800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce40001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc428000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de6800f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffe0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00104f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28182002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340035, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140023, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d614011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4100026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05980008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb0800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3e280008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cb4800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20240030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ca48001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x507c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30e40004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d7d401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x557c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28342002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c018001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf81a2a4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c007eb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d0d001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8100072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x591c01fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45140210, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x595801fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1624001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a307fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x23304076, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc00e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0015, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4514020c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a2001e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a204001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a64003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1264001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15dc000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dcdc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5dc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340022, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0434001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf430000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4412e40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c030, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41c031, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x248dfffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc12e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc812e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45140248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013257, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0434000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdb000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd140001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9980ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8200011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013259, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0337fff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f220009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d01c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f01c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c01c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c000d61, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50500020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd0c00072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8240072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd240001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19682011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5a6c01fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eeac00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aec0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4180011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf830000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfa0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4380007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40038, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400029, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9540073d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18c80066, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30880001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd910000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4220000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24e80007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24ec0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5310000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001465, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1000072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc82c0072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2c0001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18f02011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5aec01fc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12ec0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aec0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a8146a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1f0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001478, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001478, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f1b400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f334002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000147b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e024001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000144a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fbfc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x251001ef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94800007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00187c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42c0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd910000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40d325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800012c2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13f4000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bf0060b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800014a9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d325a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0677, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0328007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb7800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13fc0017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03a0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45dc0390, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04183000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b380057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b340213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c424001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c428001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c42c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c430001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c434001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04182000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd813267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a0800fd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x109c000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce080228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9880000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ec75, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52a80020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80288, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf080290, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf0802a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4802a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27580001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc802b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80802b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x178c000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cf8c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8802c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc802c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8802d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf8802d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25b8ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd2800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5230309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e3a400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001539, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd08034b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd880353, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b0353, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd14005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000154f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd080238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd08034b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d200008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd900309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8100319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340801, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2198003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd910ce7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4190ce6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d918005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d918004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd810ce6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdd1054f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000156e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x090c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdcd050e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x040c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x110c0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc41230d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc480329, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc48032a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc4802e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f02e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d8003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09940001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x44100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x69100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000157f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970290, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b0288, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f0298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x041c0040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dcdc002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d924019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d26400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001579, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d010021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d914019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd480298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8802a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10d40010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12180016, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc51f0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d95800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d62000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdd00309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce113320, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f02e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18dc01e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c0001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015aa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a302b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12240004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e5e400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab02a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04100000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4c0319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d9d8002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea14005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015bc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04240001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e624004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d25000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2620000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd0d3330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0802b8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd8802b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab02e0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa807f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f02d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49702d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02c8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f02c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96800028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d4e000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d964002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d694001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cde4002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de94001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd64002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d694001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00163f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800015cd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930238, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d698002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd4802d8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x129c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc50f0319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11a0000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1198000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd953300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e0e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a8000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce953301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce100319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b70280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73800a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x536c0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780eb68, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001609, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30b40000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b400011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b70258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53780020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb3801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7faf8019, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x67b40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x57b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bb0260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fab8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf880260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66f40001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4353247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7f4009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fff7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x269c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a00018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a00060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x269c0018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a40060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11dc0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29dc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de5c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b70228, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc80230, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f514005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2510000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001644, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd080240, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f130005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001688, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00120d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001219, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001232, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340801, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f130004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01051e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42d051f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ed2c005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01051f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000055, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5170309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195c07f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x196007f6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x6b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001665, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a702a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab0298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f634014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e76401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56680020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8113320, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480298, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce8802a0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc5170319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b702b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x255c000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f5f4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8113330, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf4802b0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x195c07e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x196007ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8353300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e4001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8353301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce4802d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8100309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8100319, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc48f0250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd4c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x64d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580005c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc24001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd2000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc435324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df5c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800016f1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a700064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800016df, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800016f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff9c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd80802e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc0064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00042, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51980020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dd9801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x45980400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b380057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b340213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f7b400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f73400a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f4001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192807fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf0258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a70250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53fc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e7e401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x667c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0aec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eebc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x43300007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7db30011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3000025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc03ec005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfca200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x192807fa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1d0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2110007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x203c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0017f5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18fc01e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00185b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffd5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ea24, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14d4001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d52400e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f0258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a30250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51dc0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400017, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d534002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dae4005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32e0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000174f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b740001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00178a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40fff3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001608, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab0268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7daa4005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32a0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001765, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d1d0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2110007d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8013256, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c0017f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd013254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4113248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b3034b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f13000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001855, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32a4001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8413247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd080260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880268, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ffc0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ec28001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32e0001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253255, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431324f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e72400c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9680fff7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa4003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32680003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4293260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1aa400e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017e2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc027ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2e6400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a4009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4240009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e403e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26680003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12a80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e400e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e40064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x32640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a40005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce412082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a640003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017d0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16a40005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce412082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea64002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4292083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ea68005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc429325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26a400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2024007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017e3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4a70280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4ab0278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52640020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7eae8014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e6a401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56680020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce480278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce880280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x042c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec80270, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017fe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800017fe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43b02eb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42302ec, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fa3801a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x47b8020c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x15e00008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1220000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2a206032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x513c001e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e3e001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000180f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b3c0077, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1330000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd200000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4200007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3800002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc30001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc1e0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04380032, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf80000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001427, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc413248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3269, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33fc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bfc0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd441326a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x173c0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300303, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3f0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ff3c004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001842, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdfc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4413249, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c43c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x23fc003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1326d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdf830000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd441326e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1fb8ffc6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xddc30000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf813265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001852, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c00142b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001878, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49f02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c00018, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c420001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c3000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c0012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001878, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41f02ed, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42302ee, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc13252, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013253, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e2a0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28340001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x313c0bcc, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x393c051f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d3c050e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x393c0560, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d3c054f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x393c1538, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d3c1537, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b740800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e8007c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c42c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a8189a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800018c5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800018f2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c414001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0007e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x50580020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d59401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc8140072, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09240002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c418001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4340004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc42130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a24002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2020002c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc418000d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1198001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7cd8c00a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc130b7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce0130b5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd1400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x5978073a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bb80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf800024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd800026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9600e8a8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9640e8a5, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800018a9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc55b0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d5c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dad800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0ffd2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x442c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df9c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c13260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940fff1, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x66d80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x56ec0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26240007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940fff7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc023007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19e4003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7de1c009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dee000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96000007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c13260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc421325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x261c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940fff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000189e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28cc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43d3265, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bc800ea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18e00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06281911, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14f4001d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24cc0003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x86800000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001915, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x800019af, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a2b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8000016a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc48032b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc480333, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc48033b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc480343, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98800011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46640400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04203000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b3c0057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b200213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e3e000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04180000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f438001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00068, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213254, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a1c003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00065, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc01f007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1e0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97800062, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0bb80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x43bc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fcbc001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc7df032b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1fc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0101, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c0102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001994, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001982, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffcb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001995, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc1325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98800009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x41bc0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x53fc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e7fc011, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd3c00025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0012, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x653c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dbd8001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff8f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2bfc0008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x043c2000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcfc13267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c410001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc55b0309, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x3d5c0010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2598ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x05540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d91800c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580fff8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09780001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9580005d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200101, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400058, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dc24001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41d3248, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25dc000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7df9c00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95c00053, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e41c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a70003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a400046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1a7000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a21, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f270009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x266400ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27240003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12640004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06640002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16700005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a0f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x16700005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e730002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4252083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e724005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x26640001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a40ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x267000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a22, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff9f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001a31, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8080280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213246, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4253245, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52200020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e26401a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x46640400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04203000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4213267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b180057, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b200213, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1b300199, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e1a000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e32000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce000024, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4970258, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4930250, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x51540020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4af0280, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4b30278, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x52ec0020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140020, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04280000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x65180001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800060, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x8c001628, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4193247, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x25980001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200101, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x30f00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95800056, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb0003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b800046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4393260, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bb000e4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001aa2, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc033ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2f3000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f3b0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf01325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b800ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4300009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9700fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f003e6, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27380003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13b80004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f000e8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07b80002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x19f00064, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33300002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0b300003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001a90, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x17b00005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf012082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01203f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x13300005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb30002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4392083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7fb38005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c00034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc00013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc431325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27300010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc439325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27b000ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b00ffca, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2030007b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf00325b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001aa3, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce01325d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04300001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7f2b0014, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd2400025, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4664001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000026, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400027, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x06a80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55100001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ff9c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc49b02e9, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99800008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc430000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2b300008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf000013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04302000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcf013267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc4313267, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x244c00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc4c0200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc44f0200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc410000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d158010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x059cc000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccdd0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0037, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000049, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500e69a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d0003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d40021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd840004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x14cc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c00028, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000033, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc438000b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0009, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x27fc0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43dc07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1bfc0078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x97c0fffd, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x99000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0120840, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c0040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001ae8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0121841, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x282c001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c07c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c08c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c079, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c07e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcec0001b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a200001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9a00ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x166c001f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04200004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9ac0fffb, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc434000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9b40ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc425c07f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8000034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940e66b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800004a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0036, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9900fffe, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18cc0021, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc00047, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc000046, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0039, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c40c001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24d003ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d47fea, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x18d87ff4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd00004c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd40004e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd80004d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c405, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc02a0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2aa80001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c406, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc414000e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x29540008, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x295c0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8c1325e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcdc0001a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11980002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x4110000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0160800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7d15000a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0164010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c080, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c081, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c082, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc01c083, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c084, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x98c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400048, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c003b, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x94c0ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000c16, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c40a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901c40d, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c410, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c40e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd801c40f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc40c0040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x09540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9940ffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04140096, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8400013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc411c401, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9500fffa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424003e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04d00001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x11100002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd01c40c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0180034, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd81c411, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd841c414, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0a540001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcd41c412, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x2468000f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc419c416, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x41980003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc41c003f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7dda0001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x12200002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x10cc0002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xccc1c40c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd901c411, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce41c412, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd8800013, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xce292e40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e01, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e02, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e03, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc412e00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000aa7, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc43c0007, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc120000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x31144000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x95400005, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xdc030000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd800002a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xcc3c000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b70, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x33f80003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd4400078, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x9780e601, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x188cfff0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x04e40002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001190, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400006, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x90000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc424005e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x96400003, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7c408001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x88000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80001b74, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000168, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110501, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120206, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130703, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92100400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92110105, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92120602, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x92130307, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x54106500, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0x7e000200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e020204, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc00a0505, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf8c007f, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8900904, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8911a04, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8920304, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb8930b44, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921c0d0c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921c1c13, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921d0c12, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x811c1d1c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x811c111c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921cff1c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000400, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x921dff10, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000100, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x81181d1c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e040218, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0701000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050102, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xe0501000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80050302, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x54106900, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0x7e080200, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x7e100204, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbefc00ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00010000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x24200087, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x262200ff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000001f0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x20222282, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x28182111, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000040c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd81a0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000080c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xd86c0000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x1100000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xbf810000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x80000004, mmCP_DFY_CNTL }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_ADDR_HI }, - { PwrCmdWrite, 0x54116f00, mmCP_DFY_ADDR_LO }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fe8, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000041, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000000c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54116f00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb454105e, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000c0, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54117300, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4541065, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000500, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000001c, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54117700, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xc0310800, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000040, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4541069, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000444, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x0000008a, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x07808000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xffffffff, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000002, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x55555555, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee40, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000010, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000001, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000004, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x54117b00, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00005301, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0xb4540fef, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x540fee20, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x000000b4, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x08000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_DFY_DATA_0 }, - { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_MEC_CNTL }, - { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54116f00, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000005, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54117300, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000006, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54117700, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000007, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x54117b00, mmCP_MQD_BASE_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { PwrCmdWrite, 0xb4540fef, mmCP_HQD_PQ_BASE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { PwrCmdWrite, 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { PwrCmdWrite, 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { PwrCmdWrite, 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { PwrCmdWrite, 0x00010000, mmCP_HQD_VMID }, - { PwrCmdWrite, 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000104, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000204, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000304, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000404, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000504, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000604, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000704, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000005, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000105, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000205, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000305, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000405, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000505, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000605, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000705, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000006, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000106, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000206, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000306, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000406, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000506, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000606, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000706, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000007, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000107, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000207, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000307, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000407, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000507, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000607, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000707, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000008, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000108, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000208, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000308, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000408, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000508, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000608, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000708, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000009, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000109, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000209, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000309, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000409, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000509, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000609, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000709, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_RPTR }, - { PwrCmdWrite, 0x00000000, mmCP_HQD_PQ_WPTR }, - { PwrCmdWrite, 0x00000001, mmCP_HQD_ACTIVE }, - { PwrCmdWrite, 0x00000004, mmSRBM_GFX_CNTL }, - { PwrCmdWrite, 0x01010101, mmCP_PQ_WPTR_POLL_CNTL1 }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdWrite, 0x00000000, mmGRBM_STATUS }, - { PwrCmdEnd, 0x00000000, 0x00000000 }, + { 0x00000000, mmRLC_CNTL }, + { 0x00000002, mmRLC_SRM_CNTL }, + { 0x15000000, mmCP_ME_CNTL }, + { 0x50000000, mmCP_MEC_CNTL }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x0840800a, mmCP_RB0_CNTL }, + { 0xf30fff0f, mmTCC_CTRL }, + { 0x00000002, mmTCC_EXE_DISABLE }, + { 0x000000ff, mmTCP_ADDR_CONFIG }, + { 0x540ff000, mmCP_CPC_IC_BASE_LO }, + { 0x000000b4, mmCP_CPC_IC_BASE_HI }, + { 0x00010000, mmCP_HYP_MEC1_UCODE_ADDR }, + { 0x00041b75, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000710e8, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000910dd, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000a1081, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000b016f, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000c0e3c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000d10ec, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000e0188, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00101b5d, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00150a6c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00170c5e, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x001d0c8c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x001e0cfe, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00221408, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00370d7b, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00390dcb, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x003c142f, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x003f0b27, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00400e63, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00500f62, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00460fa7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00490fa7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x005811d4, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00680ad6, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00760b00, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00780b0c, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00790af7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x007d1aba, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x007e1abe, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00591260, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x005a12fb, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00861ac7, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x008c1b01, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x008d1b34, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a014b9, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a1152e, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a216fb, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a41890, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a31906, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00a50b14, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00621387, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x005c0b27, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00160a75, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, + { 0x00010000, mmCP_HYP_MEC2_UCODE_ADDR }, + { 0x00041b75, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000710e8, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000910dd, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000a1081, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000b016f, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000c0e3c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000d10ec, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000e0188, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00101b5d, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00150a6c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00170c5e, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x001d0c8c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x001e0cfe, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00221408, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00370d7b, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00390dcb, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x003c142f, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x003f0b27, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00400e63, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00500f62, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00460fa7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00490fa7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x005811d4, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00680ad6, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00760b00, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00780b0c, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00790af7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x007d1aba, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x007e1abe, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00591260, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x005a12fb, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00861ac7, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x008c1b01, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x008d1b34, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a014b9, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a1152e, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a216fb, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a41890, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a31906, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00a50b14, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00621387, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x005c0b27, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x00160a75, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x540fe800, mmCP_DFY_ADDR_LO }, + { 0x7e000200, mmCP_DFY_DATA_0 }, + { 0x7e020201, mmCP_DFY_DATA_0 }, + { 0x7e040204, mmCP_DFY_DATA_0 }, + { 0x7e060205, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080102, mmCP_DFY_DATA_0 }, + { 0x0a0a0701, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0x0a080500, mmCP_DFY_DATA_0 }, + { 0x0a0a0303, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000005, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54106f00, mmCP_DFY_DATA_0 }, + { 0x000400b4, mmCP_DFY_DATA_0 }, + { 0x00004000, mmCP_DFY_DATA_0 }, + { 0x00804fac, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x540fef00, mmCP_DFY_ADDR_LO }, + { 0xc0031502, mmCP_DFY_DATA_0 }, + { 0x00001e00, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x540ff000, mmCP_DFY_ADDR_LO }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x80000145, mmCP_DFY_DATA_0 }, + { 0x94800001, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0x95400001, mmCP_DFY_DATA_0 }, + { 0x95800001, mmCP_DFY_DATA_0 }, + { 0xdc810000, mmCP_DFY_DATA_0 }, + { 0xdcc10000, mmCP_DFY_DATA_0 }, + { 0xdd010000, mmCP_DFY_DATA_0 }, + { 0xdd410000, mmCP_DFY_DATA_0 }, + { 0xdd810000, mmCP_DFY_DATA_0 }, + { 0xc4080061, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8000003, mmCP_DFY_DATA_0 }, + { 0xc40c0001, mmCP_DFY_DATA_0 }, + { 0x24ccffff, mmCP_DFY_DATA_0 }, + { 0x3cd08000, mmCP_DFY_DATA_0 }, + { 0x9500fffd, mmCP_DFY_DATA_0 }, + { 0x1cd0ffcf, mmCP_DFY_DATA_0 }, + { 0x7d018001, mmCP_DFY_DATA_0 }, + { 0xc4140004, mmCP_DFY_DATA_0 }, + { 0x050c0019, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x84c00000, mmCP_DFY_DATA_0 }, + { 0x80000023, mmCP_DFY_DATA_0 }, + { 0x80000067, mmCP_DFY_DATA_0 }, + { 0x8000006a, mmCP_DFY_DATA_0 }, + { 0x8000006d, mmCP_DFY_DATA_0 }, + { 0x80000079, mmCP_DFY_DATA_0 }, + { 0x80000084, mmCP_DFY_DATA_0 }, + { 0x8000008f, mmCP_DFY_DATA_0 }, + { 0x80000099, mmCP_DFY_DATA_0 }, + { 0x800000a0, mmCP_DFY_DATA_0 }, + { 0x800000af, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0xc4080007, mmCP_DFY_DATA_0 }, + { 0x388c0001, mmCP_DFY_DATA_0 }, + { 0x08880002, mmCP_DFY_DATA_0 }, + { 0x04100003, mmCP_DFY_DATA_0 }, + { 0x94c00005, mmCP_DFY_DATA_0 }, + { 0x98800003, mmCP_DFY_DATA_0 }, + { 0x04100004, mmCP_DFY_DATA_0 }, + { 0x8000002d, mmCP_DFY_DATA_0 }, + { 0x04100005, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0000, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x28080001, mmCP_DFY_DATA_0 }, + { 0xcc000004, mmCP_DFY_DATA_0 }, + { 0x7d808001, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0xcc800005, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcd013278, mmCP_DFY_DATA_0 }, + { 0xc4113278, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0x24cc0700, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc4113255, mmCP_DFY_DATA_0 }, + { 0xcd01324f, mmCP_DFY_DATA_0 }, + { 0xc4113254, mmCP_DFY_DATA_0 }, + { 0x1d10ffdf, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0x10cc0014, mmCP_DFY_DATA_0 }, + { 0x1d10c017, mmCP_DFY_DATA_0 }, + { 0x7d0d000a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd0130b7, mmCP_DFY_DATA_0 }, + { 0x14cc0010, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0x8000005d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14d00011, mmCP_DFY_DATA_0 }, + { 0x9500fffe, mmCP_DFY_DATA_0 }, + { 0xdc030000, mmCP_DFY_DATA_0 }, + { 0xd800000c, mmCP_DFY_DATA_0 }, + { 0xd800000d, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01b10, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc00e0080, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0xc00e0800, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0x04100006, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0000, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x280c0008, mmCP_DFY_DATA_0 }, + { 0xccc00052, mmCP_DFY_DATA_0 }, + { 0xd8000021, mmCP_DFY_DATA_0 }, + { 0x28180039, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0x04100007, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0001, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x280c0010, mmCP_DFY_DATA_0 }, + { 0xccc00052, mmCP_DFY_DATA_0 }, + { 0x28180039, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0xd8400053, mmCP_DFY_DATA_0 }, + { 0x04100008, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0003, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x280c0020, mmCP_DFY_DATA_0 }, + { 0xccc00052, mmCP_DFY_DATA_0 }, + { 0x28180039, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0xdc030000, mmCP_DFY_DATA_0 }, + { 0xd8000069, mmCP_DFY_DATA_0 }, + { 0x28080001, mmCP_DFY_DATA_0 }, + { 0xc428000d, mmCP_DFY_DATA_0 }, + { 0x7ca88004, mmCP_DFY_DATA_0 }, + { 0xcc800079, mmCP_DFY_DATA_0 }, + { 0x04280001, mmCP_DFY_DATA_0 }, + { 0xcc00006f, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0x04100010, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0xccc00078, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0x28180080, mmCP_DFY_DATA_0 }, + { 0x80000034, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xcd013278, mmCP_DFY_DATA_0 }, + { 0xc4113278, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0xc4113254, mmCP_DFY_DATA_0 }, + { 0x1d10c017, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0xcd0130b7, mmCP_DFY_DATA_0 }, + { 0x8000013b, mmCP_DFY_DATA_0 }, + { 0x95c00001, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0x96400001, mmCP_DFY_DATA_0 }, + { 0x96800001, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x97400001, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x97c00001, mmCP_DFY_DATA_0 }, + { 0xdc810000, mmCP_DFY_DATA_0 }, + { 0xc40c000c, mmCP_DFY_DATA_0 }, + { 0xcd4c0380, mmCP_DFY_DATA_0 }, + { 0xcdcc0388, mmCP_DFY_DATA_0 }, + { 0x55dc0020, mmCP_DFY_DATA_0 }, + { 0xcdcc038c, mmCP_DFY_DATA_0 }, + { 0xce0c0390, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce0c0394, mmCP_DFY_DATA_0 }, + { 0xce4c0398, mmCP_DFY_DATA_0 }, + { 0x56640020, mmCP_DFY_DATA_0 }, + { 0xce4c039c, mmCP_DFY_DATA_0 }, + { 0xce8c03a0, mmCP_DFY_DATA_0 }, + { 0x56a80020, mmCP_DFY_DATA_0 }, + { 0xce8c03a4, mmCP_DFY_DATA_0 }, + { 0xcecc03a8, mmCP_DFY_DATA_0 }, + { 0x56ec0020, mmCP_DFY_DATA_0 }, + { 0xcecc03ac, mmCP_DFY_DATA_0 }, + { 0xcf0c03b0, mmCP_DFY_DATA_0 }, + { 0x57300020, mmCP_DFY_DATA_0 }, + { 0xcf0c03b4, mmCP_DFY_DATA_0 }, + { 0xcf4c03b8, mmCP_DFY_DATA_0 }, + { 0x57740020, mmCP_DFY_DATA_0 }, + { 0xcf4c03bc, mmCP_DFY_DATA_0 }, + { 0xcf8c03c0, mmCP_DFY_DATA_0 }, + { 0x57b80020, mmCP_DFY_DATA_0 }, + { 0xcf8c03c4, mmCP_DFY_DATA_0 }, + { 0xcfcc03c8, mmCP_DFY_DATA_0 }, + { 0x57fc0020, mmCP_DFY_DATA_0 }, + { 0xcfcc03cc, mmCP_DFY_DATA_0 }, + { 0xd9000033, mmCP_DFY_DATA_0 }, + { 0xc41c0009, mmCP_DFY_DATA_0 }, + { 0x25dc0010, mmCP_DFY_DATA_0 }, + { 0x95c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc41c000c, mmCP_DFY_DATA_0 }, + { 0x05dc002f, mmCP_DFY_DATA_0 }, + { 0xcdc12009, mmCP_DFY_DATA_0 }, + { 0xc41d200a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc012009, mmCP_DFY_DATA_0 }, + { 0xd9000034, mmCP_DFY_DATA_0 }, + { 0x25e01c00, mmCP_DFY_DATA_0 }, + { 0x12200013, mmCP_DFY_DATA_0 }, + { 0x25e40300, mmCP_DFY_DATA_0 }, + { 0x12640008, mmCP_DFY_DATA_0 }, + { 0x25e800c0, mmCP_DFY_DATA_0 }, + { 0x12a80002, mmCP_DFY_DATA_0 }, + { 0x25ec003f, mmCP_DFY_DATA_0 }, + { 0x7e25c00a, mmCP_DFY_DATA_0 }, + { 0x7eae400a, mmCP_DFY_DATA_0 }, + { 0x7de5c00a, mmCP_DFY_DATA_0 }, + { 0xddc10000, mmCP_DFY_DATA_0 }, + { 0xc02ee000, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0xc40c005f, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x24d000ff, mmCP_DFY_DATA_0 }, + { 0x31100006, mmCP_DFY_DATA_0 }, + { 0x9500007b, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xdc1c0000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1c200, mmCP_DFY_DATA_0 }, + { 0xc40c000c, mmCP_DFY_DATA_0 }, + { 0xc4df0388, mmCP_DFY_DATA_0 }, + { 0xc4d7038c, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d5dc01a, mmCP_DFY_DATA_0 }, + { 0xc4e30390, mmCP_DFY_DATA_0 }, + { 0xc4d70394, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d62001a, mmCP_DFY_DATA_0 }, + { 0xc4e70398, mmCP_DFY_DATA_0 }, + { 0xc4d7039c, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d66401a, mmCP_DFY_DATA_0 }, + { 0xc4eb03a0, mmCP_DFY_DATA_0 }, + { 0xc4d703a4, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d6a801a, mmCP_DFY_DATA_0 }, + { 0xc4ef03a8, mmCP_DFY_DATA_0 }, + { 0xc4d703ac, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d6ec01a, mmCP_DFY_DATA_0 }, + { 0xc4f303b0, mmCP_DFY_DATA_0 }, + { 0xc4d703b4, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d73001a, mmCP_DFY_DATA_0 }, + { 0xc4f703b8, mmCP_DFY_DATA_0 }, + { 0xc4d703bc, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d77401a, mmCP_DFY_DATA_0 }, + { 0xc4fb03c0, mmCP_DFY_DATA_0 }, + { 0xc4d703c4, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d7b801a, mmCP_DFY_DATA_0 }, + { 0xc4ff03c8, mmCP_DFY_DATA_0 }, + { 0xc4d703cc, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d7fc01a, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0xcc800013, mmCP_DFY_DATA_0 }, + { 0xc4d70380, mmCP_DFY_DATA_0 }, + { 0xc4080001, mmCP_DFY_DATA_0 }, + { 0x1c88001c, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0xc40c0083, mmCP_DFY_DATA_0 }, + { 0x94c00010, mmCP_DFY_DATA_0 }, + { 0xdc0e0000, mmCP_DFY_DATA_0 }, + { 0x94c0000e, mmCP_DFY_DATA_0 }, + { 0xc40c0082, mmCP_DFY_DATA_0 }, + { 0x24d00001, mmCP_DFY_DATA_0 }, + { 0x9900000b, mmCP_DFY_DATA_0 }, + { 0x18cc01e3, mmCP_DFY_DATA_0 }, + { 0x3cd00004, mmCP_DFY_DATA_0 }, + { 0x95000008, mmCP_DFY_DATA_0 }, + { 0xc40c0085, mmCP_DFY_DATA_0 }, + { 0x18cc006a, mmCP_DFY_DATA_0 }, + { 0x98c00005, mmCP_DFY_DATA_0 }, + { 0xc40c0082, mmCP_DFY_DATA_0 }, + { 0x18cc01e3, mmCP_DFY_DATA_0 }, + { 0x3cd00004, mmCP_DFY_DATA_0 }, + { 0x9900fffa, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0xcc800004, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4080001, mmCP_DFY_DATA_0 }, + { 0x1c88001c, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0xcc800004, mmCP_DFY_DATA_0 }, + { 0xdc080000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400051, mmCP_DFY_DATA_0 }, + { 0xc428000c, mmCP_DFY_DATA_0 }, + { 0x04180018, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a80001f, mmCP_DFY_DATA_0 }, + { 0x9a40001e, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4293265, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x1aac0027, mmCP_DFY_DATA_0 }, + { 0x2aa80080, mmCP_DFY_DATA_0 }, + { 0xce813265, mmCP_DFY_DATA_0 }, + { 0x9ac00017, mmCP_DFY_DATA_0 }, + { 0xd80002f1, mmCP_DFY_DATA_0 }, + { 0x04080002, mmCP_DFY_DATA_0 }, + { 0x08880001, mmCP_DFY_DATA_0 }, + { 0xd8080250, mmCP_DFY_DATA_0 }, + { 0xd8080258, mmCP_DFY_DATA_0 }, + { 0xd8080230, mmCP_DFY_DATA_0 }, + { 0xd8080238, mmCP_DFY_DATA_0 }, + { 0xd8080240, mmCP_DFY_DATA_0 }, + { 0xd8080248, mmCP_DFY_DATA_0 }, + { 0xd8080268, mmCP_DFY_DATA_0 }, + { 0xd8080270, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0xd8080228, mmCP_DFY_DATA_0 }, + { 0xd8000367, mmCP_DFY_DATA_0 }, + { 0x9880fff3, mmCP_DFY_DATA_0 }, + { 0x04080010, mmCP_DFY_DATA_0 }, + { 0x08880001, mmCP_DFY_DATA_0 }, + { 0xd80c0309, mmCP_DFY_DATA_0 }, + { 0xd80c0319, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x9880fffc, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc00e0100, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8000016e, mmCP_DFY_DATA_0 }, + { 0xc4180032, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x95800001, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d0003f, mmCP_DFY_DATA_0 }, + { 0x24d4001f, mmCP_DFY_DATA_0 }, + { 0x24d80001, mmCP_DFY_DATA_0 }, + { 0x155c0001, mmCP_DFY_DATA_0 }, + { 0x05e80180, mmCP_DFY_DATA_0 }, + { 0x9900000b, mmCP_DFY_DATA_0 }, + { 0x202c003d, mmCP_DFY_DATA_0 }, + { 0xcd800010, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0xc42d325b, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0x80000bfc, mmCP_DFY_DATA_0 }, + { 0x800012e9, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xc410001b, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0xd8000031, mmCP_DFY_DATA_0 }, + { 0x9900091a, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x24d000ff, mmCP_DFY_DATA_0 }, + { 0x05280196, mmCP_DFY_DATA_0 }, + { 0x18d4fe04, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x800001b4, mmCP_DFY_DATA_0 }, + { 0x8000032b, mmCP_DFY_DATA_0 }, + { 0x80000350, mmCP_DFY_DATA_0 }, + { 0x80000352, mmCP_DFY_DATA_0 }, + { 0x8000035f, mmCP_DFY_DATA_0 }, + { 0x80000701, mmCP_DFY_DATA_0 }, + { 0x8000047c, mmCP_DFY_DATA_0 }, + { 0x8000019f, mmCP_DFY_DATA_0 }, + { 0x80000800, mmCP_DFY_DATA_0 }, + { 0xc419325b, mmCP_DFY_DATA_0 }, + { 0x1d98001f, mmCP_DFY_DATA_0 }, + { 0xcd81325b, mmCP_DFY_DATA_0 }, + { 0x8c00003f, mmCP_DFY_DATA_0 }, + { 0xc4140004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04100002, mmCP_DFY_DATA_0 }, + { 0x8c000043, mmCP_DFY_DATA_0 }, + { 0x28cc0002, mmCP_DFY_DATA_0 }, + { 0xccc00050, mmCP_DFY_DATA_0 }, + { 0xc43c0044, mmCP_DFY_DATA_0 }, + { 0x27fc0003, mmCP_DFY_DATA_0 }, + { 0x9bc00002, mmCP_DFY_DATA_0 }, + { 0x97c00006, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0x8c000055, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcd400008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x7d40c001, mmCP_DFY_DATA_0 }, + { 0xd8400028, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xd9400036, mmCP_DFY_DATA_0 }, + { 0xc4193256, mmCP_DFY_DATA_0 }, + { 0xc41d3254, mmCP_DFY_DATA_0 }, + { 0x15540008, mmCP_DFY_DATA_0 }, + { 0xcd400009, mmCP_DFY_DATA_0 }, + { 0xcd40005b, mmCP_DFY_DATA_0 }, + { 0xcd40005e, mmCP_DFY_DATA_0 }, + { 0xcd40005d, mmCP_DFY_DATA_0 }, + { 0xd840006d, mmCP_DFY_DATA_0 }, + { 0xc421325a, mmCP_DFY_DATA_0 }, + { 0xc42d3249, mmCP_DFY_DATA_0 }, + { 0x11540015, mmCP_DFY_DATA_0 }, + { 0x19a4003c, mmCP_DFY_DATA_0 }, + { 0x1998003f, mmCP_DFY_DATA_0 }, + { 0x1af0007d, mmCP_DFY_DATA_0 }, + { 0x11dc000b, mmCP_DFY_DATA_0 }, + { 0x1264001f, mmCP_DFY_DATA_0 }, + { 0x15dc000d, mmCP_DFY_DATA_0 }, + { 0x7d65400a, mmCP_DFY_DATA_0 }, + { 0x13300018, mmCP_DFY_DATA_0 }, + { 0x1a38003f, mmCP_DFY_DATA_0 }, + { 0x7dd5c00a, mmCP_DFY_DATA_0 }, + { 0x7df1c00a, mmCP_DFY_DATA_0 }, + { 0xcd800045, mmCP_DFY_DATA_0 }, + { 0xcdc00100, mmCP_DFY_DATA_0 }, + { 0xc411326a, mmCP_DFY_DATA_0 }, + { 0xc415326b, mmCP_DFY_DATA_0 }, + { 0xc419326c, mmCP_DFY_DATA_0 }, + { 0xc41d326d, mmCP_DFY_DATA_0 }, + { 0xc425326e, mmCP_DFY_DATA_0 }, + { 0xc4293279, mmCP_DFY_DATA_0 }, + { 0xce800077, mmCP_DFY_DATA_0 }, + { 0xcd000056, mmCP_DFY_DATA_0 }, + { 0xcd400057, mmCP_DFY_DATA_0 }, + { 0xcd800058, mmCP_DFY_DATA_0 }, + { 0xcdc00059, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x259c8000, mmCP_DFY_DATA_0 }, + { 0x99c00004, mmCP_DFY_DATA_0 }, + { 0xce40005a, mmCP_DFY_DATA_0 }, + { 0x29988000, mmCP_DFY_DATA_0 }, + { 0xcd813265, mmCP_DFY_DATA_0 }, + { 0xc4113248, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0xcd000073, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0xc411326f, mmCP_DFY_DATA_0 }, + { 0x17300019, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x25140fff, mmCP_DFY_DATA_0 }, + { 0x95400007, mmCP_DFY_DATA_0 }, + { 0xd800003a, mmCP_DFY_DATA_0 }, + { 0x8c001b6d, mmCP_DFY_DATA_0 }, + { 0xc4153279, mmCP_DFY_DATA_0 }, + { 0xcd400077, mmCP_DFY_DATA_0 }, + { 0xcd00005f, mmCP_DFY_DATA_0 }, + { 0xd8000075, mmCP_DFY_DATA_0 }, + { 0x26f00001, mmCP_DFY_DATA_0 }, + { 0x15100010, mmCP_DFY_DATA_0 }, + { 0x7d190004, mmCP_DFY_DATA_0 }, + { 0xcd000035, mmCP_DFY_DATA_0 }, + { 0x97000035, mmCP_DFY_DATA_0 }, + { 0x1af07fe8, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcf00000d, mmCP_DFY_DATA_0 }, + { 0xcf00000a, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x04340022, mmCP_DFY_DATA_0 }, + { 0x07740001, mmCP_DFY_DATA_0 }, + { 0x04300010, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0xd4412e01, mmCP_DFY_DATA_0 }, + { 0x0434001e, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xdf030000, mmCP_DFY_DATA_0 }, + { 0xd4412e40, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc41c030, mmCP_DFY_DATA_0 }, + { 0xcc41c031, mmCP_DFY_DATA_0 }, + { 0xc43dc031, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x04343000, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0xcf413267, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7dd1c01a, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0x45dc0160, mmCP_DFY_DATA_0 }, + { 0xc810001f, mmCP_DFY_DATA_0 }, + { 0x1b4c0057, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x7f4f400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x55180020, mmCP_DFY_DATA_0 }, + { 0x2198003f, mmCP_DFY_DATA_0 }, + { 0xd1c00025, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xcd000026, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9bc00001, mmCP_DFY_DATA_0 }, + { 0x248dfffe, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xccc12e00, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x1af4007d, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0x33740003, mmCP_DFY_DATA_0 }, + { 0x26d80001, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x1ae8003e, mmCP_DFY_DATA_0 }, + { 0x9680000c, mmCP_DFY_DATA_0 }, + { 0xc4253277, mmCP_DFY_DATA_0 }, + { 0x26680001, mmCP_DFY_DATA_0 }, + { 0x96800009, mmCP_DFY_DATA_0 }, + { 0x2a640002, mmCP_DFY_DATA_0 }, + { 0xce413277, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc4253348, mmCP_DFY_DATA_0 }, + { 0xce413348, mmCP_DFY_DATA_0 }, + { 0xc4253348, mmCP_DFY_DATA_0 }, + { 0x96400001, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9b400003, mmCP_DFY_DATA_0 }, + { 0x958000d8, mmCP_DFY_DATA_0 }, + { 0x80000315, mmCP_DFY_DATA_0 }, + { 0xc4253277, mmCP_DFY_DATA_0 }, + { 0x04303000, mmCP_DFY_DATA_0 }, + { 0x26680001, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x96800041, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x1714000c, mmCP_DFY_DATA_0 }, + { 0x25540800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x459801b0, mmCP_DFY_DATA_0 }, + { 0x7d77400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x04240010, mmCP_DFY_DATA_0 }, + { 0x199c01e2, mmCP_DFY_DATA_0 }, + { 0x7e5e4002, mmCP_DFY_DATA_0 }, + { 0x3e5c0004, mmCP_DFY_DATA_0 }, + { 0x3e540002, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0x95c00006, mmCP_DFY_DATA_0 }, + { 0xc80c0011, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x54d00020, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0x80000282, mmCP_DFY_DATA_0 }, + { 0x95400015, mmCP_DFY_DATA_0 }, + { 0xc80c0011, mmCP_DFY_DATA_0 }, + { 0x0a640002, mmCP_DFY_DATA_0 }, + { 0x041c0001, mmCP_DFY_DATA_0 }, + { 0x45980008, mmCP_DFY_DATA_0 }, + { 0x54d00020, mmCP_DFY_DATA_0 }, + { 0x96400004, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0x041c0000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0x99c00003, mmCP_DFY_DATA_0 }, + { 0xc8180011, mmCP_DFY_DATA_0 }, + { 0x80000282, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0x80000282, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xc80c0011, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0xc8140011, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1334e, mmCP_DFY_DATA_0 }, + { 0xcd01334f, mmCP_DFY_DATA_0 }, + { 0xcd413350, mmCP_DFY_DATA_0 }, + { 0xcd813351, mmCP_DFY_DATA_0 }, + { 0xd881334d, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4193273, mmCP_DFY_DATA_0 }, + { 0xc41d3275, mmCP_DFY_DATA_0 }, + { 0xc40d3271, mmCP_DFY_DATA_0 }, + { 0xc4113270, mmCP_DFY_DATA_0 }, + { 0xc4153274, mmCP_DFY_DATA_0 }, + { 0x50cc0020, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0x7cdcc011, mmCP_DFY_DATA_0 }, + { 0x05900008, mmCP_DFY_DATA_0 }, + { 0xcd00006a, mmCP_DFY_DATA_0 }, + { 0xcdc0006b, mmCP_DFY_DATA_0 }, + { 0xc41d3272, mmCP_DFY_DATA_0 }, + { 0x7d594002, mmCP_DFY_DATA_0 }, + { 0x54d00020, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xccc12e23, mmCP_DFY_DATA_0 }, + { 0xcd012e24, mmCP_DFY_DATA_0 }, + { 0xcdc12e25, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x15540002, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x1b340057, mmCP_DFY_DATA_0 }, + { 0x1b280213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x45980198, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x7f2b000a, mmCP_DFY_DATA_0 }, + { 0x55e40020, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcd40000d, mmCP_DFY_DATA_0 }, + { 0xcd40000a, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x20cc003c, mmCP_DFY_DATA_0 }, + { 0xccc13249, mmCP_DFY_DATA_0 }, + { 0xc4113274, mmCP_DFY_DATA_0 }, + { 0xdd430000, mmCP_DFY_DATA_0 }, + { 0xc01e0001, mmCP_DFY_DATA_0 }, + { 0x29dc0002, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0xd8000036, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0x2d540002, mmCP_DFY_DATA_0 }, + { 0x95400022, mmCP_DFY_DATA_0 }, + { 0x078c0000, mmCP_DFY_DATA_0 }, + { 0x07d40000, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001239, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x04f80000, mmCP_DFY_DATA_0 }, + { 0x057c0000, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc414000d, mmCP_DFY_DATA_0 }, + { 0xc41c0019, mmCP_DFY_DATA_0 }, + { 0x7dd5c005, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0xd840007c, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0xd8400069, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c018a6, mmCP_DFY_DATA_0 }, + { 0xd4412e22, mmCP_DFY_DATA_0 }, + { 0xd800007c, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c018a2, mmCP_DFY_DATA_0 }, + { 0x95c00007, mmCP_DFY_DATA_0 }, + { 0xc40c0019, mmCP_DFY_DATA_0 }, + { 0x7cd4c005, mmCP_DFY_DATA_0 }, + { 0x24cc0001, mmCP_DFY_DATA_0 }, + { 0x94c00008, mmCP_DFY_DATA_0 }, + { 0x9680fffc, mmCP_DFY_DATA_0 }, + { 0x800002e3, mmCP_DFY_DATA_0 }, + { 0xc40c0057, mmCP_DFY_DATA_0 }, + { 0x7cd0c002, mmCP_DFY_DATA_0 }, + { 0x94c00003, mmCP_DFY_DATA_0 }, + { 0x9680fffd, mmCP_DFY_DATA_0 }, + { 0x800002e3, mmCP_DFY_DATA_0 }, + { 0xd8000069, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcd013273, mmCP_DFY_DATA_0 }, + { 0xcd013275, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc414005e, mmCP_DFY_DATA_0 }, + { 0x9540188f, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0xc013cfff, mmCP_DFY_DATA_0 }, + { 0x7cd0c009, mmCP_DFY_DATA_0 }, + { 0xccc13249, mmCP_DFY_DATA_0 }, + { 0x9680000b, mmCP_DFY_DATA_0 }, + { 0xc40c0077, mmCP_DFY_DATA_0 }, + { 0x38d00001, mmCP_DFY_DATA_0 }, + { 0x99000006, mmCP_DFY_DATA_0 }, + { 0x04cc0002, mmCP_DFY_DATA_0 }, + { 0xdcc30000, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01882, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd800000d, mmCP_DFY_DATA_0 }, + { 0x80000304, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0xd840002f, mmCP_DFY_DATA_0 }, + { 0xc41c0015, mmCP_DFY_DATA_0 }, + { 0x95c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400030, mmCP_DFY_DATA_0 }, + { 0xc41c0016, mmCP_DFY_DATA_0 }, + { 0x95c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8000030, mmCP_DFY_DATA_0 }, + { 0xc41c0016, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xd800002f, mmCP_DFY_DATA_0 }, + { 0xc41c0015, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x49980198, mmCP_DFY_DATA_0 }, + { 0x55e40020, mmCP_DFY_DATA_0 }, + { 0x459801a0, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x04302000, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x96800004, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0xd8000036, mmCP_DFY_DATA_0 }, + { 0x80000329, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcc812e00, mmCP_DFY_DATA_0 }, + { 0x04302000, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0xc4193256, mmCP_DFY_DATA_0 }, + { 0xc42d3249, mmCP_DFY_DATA_0 }, + { 0x16ec001f, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x1998003e, mmCP_DFY_DATA_0 }, + { 0xcec00031, mmCP_DFY_DATA_0 }, + { 0xd8000036, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0x97800004, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xce00000a, mmCP_DFY_DATA_0 }, + { 0x1a18003e, mmCP_DFY_DATA_0 }, + { 0xcd800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0x7d43c001, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4093249, mmCP_DFY_DATA_0 }, + { 0x1888003e, mmCP_DFY_DATA_0 }, + { 0x94800015, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0xc419324c, mmCP_DFY_DATA_0 }, + { 0x259c0001, mmCP_DFY_DATA_0 }, + { 0x1598001f, mmCP_DFY_DATA_0 }, + { 0x95c0000d, mmCP_DFY_DATA_0 }, + { 0x9580000c, mmCP_DFY_DATA_0 }, + { 0x99000003, mmCP_DFY_DATA_0 }, + { 0xd8400036, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14d80011, mmCP_DFY_DATA_0 }, + { 0x24dc00ff, mmCP_DFY_DATA_0 }, + { 0x31e00002, mmCP_DFY_DATA_0 }, + { 0x31dc0003, mmCP_DFY_DATA_0 }, + { 0x9580fff0, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0x99c00002, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0x94800004, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95801827, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8800036, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8c00036, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xc4180014, mmCP_DFY_DATA_0 }, + { 0x9580ffff, mmCP_DFY_DATA_0 }, + { 0xd840002f, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14dc0011, mmCP_DFY_DATA_0 }, + { 0x95c0fffe, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd800006d, mmCP_DFY_DATA_0 }, + { 0xc41d3246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51dc0020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0xd8400028, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc420000b, mmCP_DFY_DATA_0 }, + { 0x32200002, mmCP_DFY_DATA_0 }, + { 0x9a0000ad, mmCP_DFY_DATA_0 }, + { 0x04200032, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0xde030000, mmCP_DFY_DATA_0 }, + { 0xd8400033, mmCP_DFY_DATA_0 }, + { 0x04080000, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0002, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xc42c0015, mmCP_DFY_DATA_0 }, + { 0x96c0ffff, mmCP_DFY_DATA_0 }, + { 0xd800002e, mmCP_DFY_DATA_0 }, + { 0xc42d3249, mmCP_DFY_DATA_0 }, + { 0x1af4003e, mmCP_DFY_DATA_0 }, + { 0x9740004d, mmCP_DFY_DATA_0 }, + { 0xc428000d, mmCP_DFY_DATA_0 }, + { 0xc4080060, mmCP_DFY_DATA_0 }, + { 0x7ca88005, mmCP_DFY_DATA_0 }, + { 0x24880001, mmCP_DFY_DATA_0 }, + { 0x7f4b4009, mmCP_DFY_DATA_0 }, + { 0x97400046, mmCP_DFY_DATA_0 }, + { 0xc4313274, mmCP_DFY_DATA_0 }, + { 0xc4100057, mmCP_DFY_DATA_0 }, + { 0x7d33400c, mmCP_DFY_DATA_0 }, + { 0x97400009, mmCP_DFY_DATA_0 }, + { 0x28240100, mmCP_DFY_DATA_0 }, + { 0x7e6a4004, mmCP_DFY_DATA_0 }, + { 0xce400079, mmCP_DFY_DATA_0 }, + { 0x1eecffdd, mmCP_DFY_DATA_0 }, + { 0xcec13249, mmCP_DFY_DATA_0 }, + { 0xcf013273, mmCP_DFY_DATA_0 }, + { 0xcf013275, mmCP_DFY_DATA_0 }, + { 0x800003c3, mmCP_DFY_DATA_0 }, + { 0xc429326f, mmCP_DFY_DATA_0 }, + { 0x1aa80030, mmCP_DFY_DATA_0 }, + { 0x96800006, mmCP_DFY_DATA_0 }, + { 0x28240001, mmCP_DFY_DATA_0 }, + { 0xc428000d, mmCP_DFY_DATA_0 }, + { 0x06a80008, mmCP_DFY_DATA_0 }, + { 0x7e6a8004, mmCP_DFY_DATA_0 }, + { 0xce800035, mmCP_DFY_DATA_0 }, + { 0xc41d3272, mmCP_DFY_DATA_0 }, + { 0x25cc0001, mmCP_DFY_DATA_0 }, + { 0x10cc0004, mmCP_DFY_DATA_0 }, + { 0x19e80042, mmCP_DFY_DATA_0 }, + { 0x25dc0006, mmCP_DFY_DATA_0 }, + { 0x11dc0001, mmCP_DFY_DATA_0 }, + { 0x7e8e800a, mmCP_DFY_DATA_0 }, + { 0x7de9c00a, mmCP_DFY_DATA_0 }, + { 0xc40d3271, mmCP_DFY_DATA_0 }, + { 0xc4293270, mmCP_DFY_DATA_0 }, + { 0x50cc0020, mmCP_DFY_DATA_0 }, + { 0x7ce8c01a, mmCP_DFY_DATA_0 }, + { 0x7cd30011, mmCP_DFY_DATA_0 }, + { 0x11e80007, mmCP_DFY_DATA_0 }, + { 0x2aa80000, mmCP_DFY_DATA_0 }, + { 0xce80001c, mmCP_DFY_DATA_0 }, + { 0xd300001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x1b30003f, mmCP_DFY_DATA_0 }, + { 0x33300000, mmCP_DFY_DATA_0 }, + { 0xc4240059, mmCP_DFY_DATA_0 }, + { 0x1660001f, mmCP_DFY_DATA_0 }, + { 0x7e320009, mmCP_DFY_DATA_0 }, + { 0xc0328000, mmCP_DFY_DATA_0 }, + { 0x7e72400a, mmCP_DFY_DATA_0 }, + { 0x0430000c, mmCP_DFY_DATA_0 }, + { 0x9a000002, mmCP_DFY_DATA_0 }, + { 0x04300008, mmCP_DFY_DATA_0 }, + { 0xc02ac000, mmCP_DFY_DATA_0 }, + { 0x7d310002, mmCP_DFY_DATA_0 }, + { 0x17300002, mmCP_DFY_DATA_0 }, + { 0x2aa87600, mmCP_DFY_DATA_0 }, + { 0x7cd0c011, mmCP_DFY_DATA_0 }, + { 0xcdc00024, mmCP_DFY_DATA_0 }, + { 0xd0c00025, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0x04280222, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc4280058, mmCP_DFY_DATA_0 }, + { 0x22ec003d, mmCP_DFY_DATA_0 }, + { 0xcec13249, mmCP_DFY_DATA_0 }, + { 0xcd013273, mmCP_DFY_DATA_0 }, + { 0xce813275, mmCP_DFY_DATA_0 }, + { 0xd800007b, mmCP_DFY_DATA_0 }, + { 0xc8380018, mmCP_DFY_DATA_0 }, + { 0x57b00020, mmCP_DFY_DATA_0 }, + { 0x04343108, mmCP_DFY_DATA_0 }, + { 0xc429325d, mmCP_DFY_DATA_0 }, + { 0x040c3000, mmCP_DFY_DATA_0 }, + { 0x13740008, mmCP_DFY_DATA_0 }, + { 0x2374007e, mmCP_DFY_DATA_0 }, + { 0x32a80003, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x18ec0057, mmCP_DFY_DATA_0 }, + { 0x18e40213, mmCP_DFY_DATA_0 }, + { 0x18cc0199, mmCP_DFY_DATA_0 }, + { 0x7cecc00a, mmCP_DFY_DATA_0 }, + { 0x7ce4c00a, mmCP_DFY_DATA_0 }, + { 0x94800003, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x800003e7, mmCP_DFY_DATA_0 }, + { 0x04200022, mmCP_DFY_DATA_0 }, + { 0xde030000, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x04200010, mmCP_DFY_DATA_0 }, + { 0xde030000, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0x45980104, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xcf800026, mmCP_DFY_DATA_0 }, + { 0xcf000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x49980104, mmCP_DFY_DATA_0 }, + { 0x9a80000a, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x45980168, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x800003f2, mmCP_DFY_DATA_0 }, + { 0x8c000448, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x040c2000, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0xd8400030, mmCP_DFY_DATA_0 }, + { 0xc42c0016, mmCP_DFY_DATA_0 }, + { 0x96c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8000030, mmCP_DFY_DATA_0 }, + { 0xc42c0016, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xd800002f, mmCP_DFY_DATA_0 }, + { 0xc42c0015, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400034, mmCP_DFY_DATA_0 }, + { 0xc4300025, mmCP_DFY_DATA_0 }, + { 0xc4340024, mmCP_DFY_DATA_0 }, + { 0xc4380081, mmCP_DFY_DATA_0 }, + { 0xcf813279, mmCP_DFY_DATA_0 }, + { 0xcf41326e, mmCP_DFY_DATA_0 }, + { 0xcf01326d, mmCP_DFY_DATA_0 }, + { 0x94c0000d, mmCP_DFY_DATA_0 }, + { 0x254c0700, mmCP_DFY_DATA_0 }, + { 0xc424001e, mmCP_DFY_DATA_0 }, + { 0x10cc0010, mmCP_DFY_DATA_0 }, + { 0x1a641fe8, mmCP_DFY_DATA_0 }, + { 0x28cc0726, mmCP_DFY_DATA_0 }, + { 0x2a640200, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1237b, mmCP_DFY_DATA_0 }, + { 0x2264003f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8813260, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0xc4240033, mmCP_DFY_DATA_0 }, + { 0xc4280034, mmCP_DFY_DATA_0 }, + { 0xd9000036, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x96400006, mmCP_DFY_DATA_0 }, + { 0xde430000, mmCP_DFY_DATA_0 }, + { 0xce40000c, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01755, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x9680000a, mmCP_DFY_DATA_0 }, + { 0xce80000a, mmCP_DFY_DATA_0 }, + { 0x06a80002, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xde830000, mmCP_DFY_DATA_0 }, + { 0xce80000d, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c0174c, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xc4393265, mmCP_DFY_DATA_0 }, + { 0x2bb80040, mmCP_DFY_DATA_0 }, + { 0xd8400032, mmCP_DFY_DATA_0 }, + { 0xcf813265, mmCP_DFY_DATA_0 }, + { 0xc4200012, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xc4100044, mmCP_DFY_DATA_0 }, + { 0x19180024, mmCP_DFY_DATA_0 }, + { 0xc8100072, mmCP_DFY_DATA_0 }, + { 0x551c003f, mmCP_DFY_DATA_0 }, + { 0x99c00003, mmCP_DFY_DATA_0 }, + { 0x95800010, mmCP_DFY_DATA_0 }, + { 0x8000043d, mmCP_DFY_DATA_0 }, + { 0xc00c8000, mmCP_DFY_DATA_0 }, + { 0xd840006c, mmCP_DFY_DATA_0 }, + { 0x28200000, mmCP_DFY_DATA_0 }, + { 0x8000043f, mmCP_DFY_DATA_0 }, + { 0xc00c4000, mmCP_DFY_DATA_0 }, + { 0x282000f0, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc4113255, mmCP_DFY_DATA_0 }, + { 0xcd01324f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xccc130b5, mmCP_DFY_DATA_0 }, + { 0xce000053, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x195c00e8, mmCP_DFY_DATA_0 }, + { 0xc4100004, mmCP_DFY_DATA_0 }, + { 0x2555fff0, mmCP_DFY_DATA_0 }, + { 0xc0360001, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0x29540001, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0x04280004, mmCP_DFY_DATA_0 }, + { 0xc420000b, mmCP_DFY_DATA_0 }, + { 0x32200002, mmCP_DFY_DATA_0 }, + { 0x9a000009, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0xc5e124dc, mmCP_DFY_DATA_0 }, + { 0x0aa80001, mmCP_DFY_DATA_0 }, + { 0x7ef6c001, mmCP_DFY_DATA_0 }, + { 0x7e624001, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0x9a80fff9, mmCP_DFY_DATA_0 }, + { 0xc02ee000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x2555fff0, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0xc42d3255, mmCP_DFY_DATA_0 }, + { 0xc4353259, mmCP_DFY_DATA_0 }, + { 0xd8013260, mmCP_DFY_DATA_0 }, + { 0x45980158, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x49980158, mmCP_DFY_DATA_0 }, + { 0x45980170, mmCP_DFY_DATA_0 }, + { 0xc4200012, mmCP_DFY_DATA_0 }, + { 0x16200010, mmCP_DFY_DATA_0 }, + { 0x9a00fffe, mmCP_DFY_DATA_0 }, + { 0xccc00024, mmCP_DFY_DATA_0 }, + { 0xd1800025, mmCP_DFY_DATA_0 }, + { 0xc429324f, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcd000008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x7d43c001, mmCP_DFY_DATA_0 }, + { 0x195400e8, mmCP_DFY_DATA_0 }, + { 0x1154000a, mmCP_DFY_DATA_0 }, + { 0x18dc00e8, mmCP_DFY_DATA_0 }, + { 0x05e80488, mmCP_DFY_DATA_0 }, + { 0x18d0006c, mmCP_DFY_DATA_0 }, + { 0x18f807f0, mmCP_DFY_DATA_0 }, + { 0x18e40077, mmCP_DFY_DATA_0 }, + { 0x18ec0199, mmCP_DFY_DATA_0 }, + { 0x7e6e400a, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000048e, mmCP_DFY_DATA_0 }, + { 0x80000494, mmCP_DFY_DATA_0 }, + { 0x800004de, mmCP_DFY_DATA_0 }, + { 0x80000685, mmCP_DFY_DATA_0 }, + { 0x80000686, mmCP_DFY_DATA_0 }, + { 0x800006ac, mmCP_DFY_DATA_0 }, + { 0x1ccc001f, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4293254, mmCP_DFY_DATA_0 }, + { 0x1264000a, mmCP_DFY_DATA_0 }, + { 0xc4300004, mmCP_DFY_DATA_0 }, + { 0x7d79400a, mmCP_DFY_DATA_0 }, + { 0x7e7a400a, mmCP_DFY_DATA_0 }, + { 0x52a8001e, mmCP_DFY_DATA_0 }, + { 0x15180001, mmCP_DFY_DATA_0 }, + { 0x7d69401a, mmCP_DFY_DATA_0 }, + { 0x202c007d, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x95000008, mmCP_DFY_DATA_0 }, + { 0x95800028, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x1aec0028, mmCP_DFY_DATA_0 }, + { 0xc40d325c, mmCP_DFY_DATA_0 }, + { 0x800004cc, mmCP_DFY_DATA_0 }, + { 0xc42d3256, mmCP_DFY_DATA_0 }, + { 0xc419324e, mmCP_DFY_DATA_0 }, + { 0x26e8003f, mmCP_DFY_DATA_0 }, + { 0x1aec003e, mmCP_DFY_DATA_0 }, + { 0x12f4000e, mmCP_DFY_DATA_0 }, + { 0xc41d324d, mmCP_DFY_DATA_0 }, + { 0xc40d324f, mmCP_DFY_DATA_0 }, + { 0x7d75401a, mmCP_DFY_DATA_0 }, + { 0x04100002, mmCP_DFY_DATA_0 }, + { 0x7d290004, mmCP_DFY_DATA_0 }, + { 0x7f8f4001, mmCP_DFY_DATA_0 }, + { 0x7f52800f, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x50e00002, mmCP_DFY_DATA_0 }, + { 0x51980008, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x800004d1, mmCP_DFY_DATA_0 }, + { 0x7d0dc002, mmCP_DFY_DATA_0 }, + { 0x6665fc00, mmCP_DFY_DATA_0 }, + { 0x7e5e401a, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x7da1c011, mmCP_DFY_DATA_0 }, + { 0xd140000b, mmCP_DFY_DATA_0 }, + { 0xd1c00002, mmCP_DFY_DATA_0 }, + { 0x2a644000, mmCP_DFY_DATA_0 }, + { 0xce400002, mmCP_DFY_DATA_0 }, + { 0x7f534002, mmCP_DFY_DATA_0 }, + { 0x6665fc00, mmCP_DFY_DATA_0 }, + { 0x7e76401a, mmCP_DFY_DATA_0 }, + { 0xd1800002, mmCP_DFY_DATA_0 }, + { 0xce400002, mmCP_DFY_DATA_0 }, + { 0x800004d7, mmCP_DFY_DATA_0 }, + { 0xc42d325a, mmCP_DFY_DATA_0 }, + { 0xc4193258, mmCP_DFY_DATA_0 }, + { 0x1aec003e, mmCP_DFY_DATA_0 }, + { 0xc41d3257, mmCP_DFY_DATA_0 }, + { 0xc4213259, mmCP_DFY_DATA_0 }, + { 0x12f4000e, mmCP_DFY_DATA_0 }, + { 0x7d75401a, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x52200002, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x7da1c011, mmCP_DFY_DATA_0 }, + { 0xd140000b, mmCP_DFY_DATA_0 }, + { 0xd1c00002, mmCP_DFY_DATA_0 }, + { 0x2a644000, mmCP_DFY_DATA_0 }, + { 0xce400002, mmCP_DFY_DATA_0 }, + { 0x202c003d, mmCP_DFY_DATA_0 }, + { 0xcf000008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0xc42d325b, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4193260, mmCP_DFY_DATA_0 }, + { 0x259c0007, mmCP_DFY_DATA_0 }, + { 0x15980004, mmCP_DFY_DATA_0 }, + { 0x05e804e3, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x800004e7, mmCP_DFY_DATA_0 }, + { 0x800004f0, mmCP_DFY_DATA_0 }, + { 0x80000505, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc435325d, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0x277401ef, mmCP_DFY_DATA_0 }, + { 0xcf41325d, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0x9640fff4, mmCP_DFY_DATA_0 }, + { 0x17e00008, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xd84131db, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xcd800009, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc42d325b, mmCP_DFY_DATA_0 }, + { 0x1b301ff8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0x26edf000, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0xd8413260, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x05a80507, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000050c, mmCP_DFY_DATA_0 }, + { 0x80000528, mmCP_DFY_DATA_0 }, + { 0x8000057d, mmCP_DFY_DATA_0 }, + { 0x800005c2, mmCP_DFY_DATA_0 }, + { 0x800005f3, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9a400012, mmCP_DFY_DATA_0 }, + { 0x1bd400e8, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xcd40005e, mmCP_DFY_DATA_0 }, + { 0xc41c004d, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x99c0000c, mmCP_DFY_DATA_0 }, + { 0xc4100019, mmCP_DFY_DATA_0 }, + { 0x7d150005, mmCP_DFY_DATA_0 }, + { 0x25100001, mmCP_DFY_DATA_0 }, + { 0x99000008, mmCP_DFY_DATA_0 }, + { 0x8c00063b, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0x2511fffd, mmCP_DFY_DATA_0 }, + { 0xcd013277, mmCP_DFY_DATA_0 }, + { 0xd801326f, mmCP_DFY_DATA_0 }, + { 0x80000624, mmCP_DFY_DATA_0 }, + { 0x04240012, mmCP_DFY_DATA_0 }, + { 0x1be00fe4, mmCP_DFY_DATA_0 }, + { 0xce413260, mmCP_DFY_DATA_0 }, + { 0xce000066, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400068, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9a400013, mmCP_DFY_DATA_0 }, + { 0x1bd400e8, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xcd40005e, mmCP_DFY_DATA_0 }, + { 0xc41c004d, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x99c0000d, mmCP_DFY_DATA_0 }, + { 0xc4100019, mmCP_DFY_DATA_0 }, + { 0x7d150005, mmCP_DFY_DATA_0 }, + { 0x25100001, mmCP_DFY_DATA_0 }, + { 0x99000009, mmCP_DFY_DATA_0 }, + { 0xd8400067, mmCP_DFY_DATA_0 }, + { 0x8c00063b, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0x2511fffd, mmCP_DFY_DATA_0 }, + { 0xcd013277, mmCP_DFY_DATA_0 }, + { 0xd801326f, mmCP_DFY_DATA_0 }, + { 0x80000624, mmCP_DFY_DATA_0 }, + { 0x1bd400e8, mmCP_DFY_DATA_0 }, + { 0xc42c0060, mmCP_DFY_DATA_0 }, + { 0x7ed6c005, mmCP_DFY_DATA_0 }, + { 0x26ec0001, mmCP_DFY_DATA_0 }, + { 0xc4113271, mmCP_DFY_DATA_0 }, + { 0xc4153270, mmCP_DFY_DATA_0 }, + { 0xc4193272, mmCP_DFY_DATA_0 }, + { 0xc41d3273, mmCP_DFY_DATA_0 }, + { 0x04280022, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d51401a, mmCP_DFY_DATA_0 }, + { 0xc4113274, mmCP_DFY_DATA_0 }, + { 0xc4213275, mmCP_DFY_DATA_0 }, + { 0xc4253276, mmCP_DFY_DATA_0 }, + { 0xc4313248, mmCP_DFY_DATA_0 }, + { 0xd1400061, mmCP_DFY_DATA_0 }, + { 0x2730000f, mmCP_DFY_DATA_0 }, + { 0x13300010, mmCP_DFY_DATA_0 }, + { 0x7db1800a, mmCP_DFY_DATA_0 }, + { 0xcd800060, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0x05dc0008, mmCP_DFY_DATA_0 }, + { 0xcdc00062, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xcd000063, mmCP_DFY_DATA_0 }, + { 0xce000064, mmCP_DFY_DATA_0 }, + { 0xce400065, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0xce813260, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc820001f, mmCP_DFY_DATA_0 }, + { 0x1b700057, mmCP_DFY_DATA_0 }, + { 0x1b680213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x46ec0188, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0x17e00008, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x26e01000, mmCP_DFY_DATA_0 }, + { 0x9a00fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd9c131fc, mmCP_DFY_DATA_0 }, + { 0xcd800009, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0x29dc0001, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0x191807e4, mmCP_DFY_DATA_0 }, + { 0x192007ec, mmCP_DFY_DATA_0 }, + { 0x95400004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x9580000e, mmCP_DFY_DATA_0 }, + { 0x09980001, mmCP_DFY_DATA_0 }, + { 0x041c0001, mmCP_DFY_DATA_0 }, + { 0x95800005, mmCP_DFY_DATA_0 }, + { 0x09980001, mmCP_DFY_DATA_0 }, + { 0x51dc0001, mmCP_DFY_DATA_0 }, + { 0x69dc0001, mmCP_DFY_DATA_0 }, + { 0x9980fffd, mmCP_DFY_DATA_0 }, + { 0x7de20014, mmCP_DFY_DATA_0 }, + { 0x561c0020, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xce013344, mmCP_DFY_DATA_0 }, + { 0xcdc13345, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x95400022, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425334d, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9640fffe, mmCP_DFY_DATA_0 }, + { 0xc419334e, mmCP_DFY_DATA_0 }, + { 0xc41d334f, mmCP_DFY_DATA_0 }, + { 0xc4213350, mmCP_DFY_DATA_0 }, + { 0xc4253351, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x1b680057, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x46ec01b0, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0x04280032, mmCP_DFY_DATA_0 }, + { 0xce813260, mmCP_DFY_DATA_0 }, + { 0xd8800068, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x2010007d, mmCP_DFY_DATA_0 }, + { 0xcd01325b, mmCP_DFY_DATA_0 }, + { 0xc411325b, mmCP_DFY_DATA_0 }, + { 0x1910003e, mmCP_DFY_DATA_0 }, + { 0x9500fffe, mmCP_DFY_DATA_0 }, + { 0x04100040, mmCP_DFY_DATA_0 }, + { 0xcd00001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc410000f, mmCP_DFY_DATA_0 }, + { 0x9900ffff, mmCP_DFY_DATA_0 }, + { 0x04100060, mmCP_DFY_DATA_0 }, + { 0xcd00001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc410000f, mmCP_DFY_DATA_0 }, + { 0x9900ffff, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x2010003d, mmCP_DFY_DATA_0 }, + { 0xcd01325b, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0x191807e4, mmCP_DFY_DATA_0 }, + { 0x9540000b, mmCP_DFY_DATA_0 }, + { 0x2511fffd, mmCP_DFY_DATA_0 }, + { 0xcd013277, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x95800005, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8013344, mmCP_DFY_DATA_0 }, + { 0xd8013345, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4180050, mmCP_DFY_DATA_0 }, + { 0xc41c0052, mmCP_DFY_DATA_0 }, + { 0x04280042, mmCP_DFY_DATA_0 }, + { 0xcd813273, mmCP_DFY_DATA_0 }, + { 0xcdc13275, mmCP_DFY_DATA_0 }, + { 0xce813260, mmCP_DFY_DATA_0 }, + { 0xd9000068, mmCP_DFY_DATA_0 }, + { 0xd8400067, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x07d40000, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c00124f, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x057c0000, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x1b680057, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0xc820001f, mmCP_DFY_DATA_0 }, + { 0x46ec0190, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc4153249, mmCP_DFY_DATA_0 }, + { 0x2154003d, mmCP_DFY_DATA_0 }, + { 0xc41c0019, mmCP_DFY_DATA_0 }, + { 0x1bd800e8, mmCP_DFY_DATA_0 }, + { 0x7dd9c005, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xcd80005e, mmCP_DFY_DATA_0 }, + { 0xc420004d, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x11dc0010, mmCP_DFY_DATA_0 }, + { 0x7e1e000a, mmCP_DFY_DATA_0 }, + { 0xcd413249, mmCP_DFY_DATA_0 }, + { 0xce01326f, mmCP_DFY_DATA_0 }, + { 0x28340001, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7f598004, mmCP_DFY_DATA_0 }, + { 0xcd800035, mmCP_DFY_DATA_0 }, + { 0x1be800e8, mmCP_DFY_DATA_0 }, + { 0xc42c004a, mmCP_DFY_DATA_0 }, + { 0xce80005e, mmCP_DFY_DATA_0 }, + { 0xd801327a, mmCP_DFY_DATA_0 }, + { 0xd800005f, mmCP_DFY_DATA_0 }, + { 0xd8000075, mmCP_DFY_DATA_0 }, + { 0xd800007f, mmCP_DFY_DATA_0 }, + { 0xc424004c, mmCP_DFY_DATA_0 }, + { 0xce41326e, mmCP_DFY_DATA_0 }, + { 0xcec0005e, mmCP_DFY_DATA_0 }, + { 0x28240100, mmCP_DFY_DATA_0 }, + { 0x7e6a4004, mmCP_DFY_DATA_0 }, + { 0xce400079, mmCP_DFY_DATA_0 }, + { 0xc435325d, mmCP_DFY_DATA_0 }, + { 0x277401ef, mmCP_DFY_DATA_0 }, + { 0x04240020, mmCP_DFY_DATA_0 }, + { 0xce41325e, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xd8013260, mmCP_DFY_DATA_0 }, + { 0xcf41325d, mmCP_DFY_DATA_0 }, + { 0xda000068, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4113277, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0x29dc0001, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0x9540002d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x042c3000, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3246, mmCP_DFY_DATA_0 }, + { 0xc4313245, mmCP_DFY_DATA_0 }, + { 0xc4353267, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425334d, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9640fffe, mmCP_DFY_DATA_0 }, + { 0xc419334e, mmCP_DFY_DATA_0 }, + { 0xc41d334f, mmCP_DFY_DATA_0 }, + { 0xc4213350, mmCP_DFY_DATA_0 }, + { 0xc4253351, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x1b680057, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x1b700213, mmCP_DFY_DATA_0 }, + { 0x1b740199, mmCP_DFY_DATA_0 }, + { 0x46ec01b0, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x042c2000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcec13267, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x96c00001, mmCP_DFY_DATA_0 }, + { 0xc41c000b, mmCP_DFY_DATA_0 }, + { 0xc420000c, mmCP_DFY_DATA_0 }, + { 0x11dc0002, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdc1334a, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc430000b, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0x9b000010, mmCP_DFY_DATA_0 }, + { 0x1be000e8, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0xc0360001, mmCP_DFY_DATA_0 }, + { 0x04280004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0xc63124dc, mmCP_DFY_DATA_0 }, + { 0x0aa80001, mmCP_DFY_DATA_0 }, + { 0x7ef6c001, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x9a80fff9, mmCP_DFY_DATA_0 }, + { 0xc02ee000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcec1c200, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4253260, mmCP_DFY_DATA_0 }, + { 0x7fc14001, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x98c00005, mmCP_DFY_DATA_0 }, + { 0x194c1c03, mmCP_DFY_DATA_0 }, + { 0xccc0003b, mmCP_DFY_DATA_0 }, + { 0xc40c002d, mmCP_DFY_DATA_0 }, + { 0x80000697, mmCP_DFY_DATA_0 }, + { 0xc420004a, mmCP_DFY_DATA_0 }, + { 0x194c00e8, mmCP_DFY_DATA_0 }, + { 0xccc0005e, mmCP_DFY_DATA_0 }, + { 0xc40c004c, mmCP_DFY_DATA_0 }, + { 0xc431326d, mmCP_DFY_DATA_0 }, + { 0x27301fff, mmCP_DFY_DATA_0 }, + { 0xce00005e, mmCP_DFY_DATA_0 }, + { 0x7cf0c00d, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c00008, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0x1b301ff8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x25100007, mmCP_DFY_DATA_0 }, + { 0x31100005, mmCP_DFY_DATA_0 }, + { 0x9900008e, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x8000075e, mmCP_DFY_DATA_0 }, + { 0x202c007d, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0xc4293265, mmCP_DFY_DATA_0 }, + { 0xc4353254, mmCP_DFY_DATA_0 }, + { 0x26a9feff, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x1374000b, mmCP_DFY_DATA_0 }, + { 0xc40c000d, mmCP_DFY_DATA_0 }, + { 0xd8000009, mmCP_DFY_DATA_0 }, + { 0x1774000d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc41d30b8, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x95c00008, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xccc00009, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xce813265, mmCP_DFY_DATA_0 }, + { 0xcf400100, mmCP_DFY_DATA_0 }, + { 0xc00ac006, mmCP_DFY_DATA_0 }, + { 0xc00e0000, mmCP_DFY_DATA_0 }, + { 0x28880700, mmCP_DFY_DATA_0 }, + { 0x28cc0014, mmCP_DFY_DATA_0 }, + { 0x8c0006de, mmCP_DFY_DATA_0 }, + { 0x14cc0010, mmCP_DFY_DATA_0 }, + { 0x30d4000f, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x10cc0010, mmCP_DFY_DATA_0 }, + { 0x28cc0014, mmCP_DFY_DATA_0 }, + { 0x99400009, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc41530b8, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x19980028, mmCP_DFY_DATA_0 }, + { 0x99400003, mmCP_DFY_DATA_0 }, + { 0x99800002, mmCP_DFY_DATA_0 }, + { 0x800006c8, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x15600008, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xc8380023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x7fa38011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x282c2002, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0xcec00013, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x042c0008, mmCP_DFY_DATA_0 }, + { 0xd3800025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x202400d0, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0x28240006, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x9a800004, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x24d8003f, mmCP_DFY_DATA_0 }, + { 0xd840003c, mmCP_DFY_DATA_0 }, + { 0xcec0003a, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcd81a2a4, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc41d325d, mmCP_DFY_DATA_0 }, + { 0x25dc0007, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x94c0000a, mmCP_DFY_DATA_0 }, + { 0xc420004a, mmCP_DFY_DATA_0 }, + { 0x194c00e8, mmCP_DFY_DATA_0 }, + { 0xccc0005e, mmCP_DFY_DATA_0 }, + { 0xc40c004c, mmCP_DFY_DATA_0 }, + { 0xc431326d, mmCP_DFY_DATA_0 }, + { 0x27301fff, mmCP_DFY_DATA_0 }, + { 0xce00005e, mmCP_DFY_DATA_0 }, + { 0x7cf0c00d, mmCP_DFY_DATA_0 }, + { 0x80000712, mmCP_DFY_DATA_0 }, + { 0x194c1c03, mmCP_DFY_DATA_0 }, + { 0xccc0003b, mmCP_DFY_DATA_0 }, + { 0xc40c002d, mmCP_DFY_DATA_0 }, + { 0x05e80714, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000071c, mmCP_DFY_DATA_0 }, + { 0x80000720, mmCP_DFY_DATA_0 }, + { 0x80000747, mmCP_DFY_DATA_0 }, + { 0x8000071d, mmCP_DFY_DATA_0 }, + { 0x800007c4, mmCP_DFY_DATA_0 }, + { 0x80000732, mmCP_DFY_DATA_0 }, + { 0x80000745, mmCP_DFY_DATA_0 }, + { 0x80000744, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x98c00006, mmCP_DFY_DATA_0 }, + { 0x8000072e, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c0000c, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4253265, mmCP_DFY_DATA_0 }, + { 0x2a64008c, mmCP_DFY_DATA_0 }, + { 0xce413265, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0x1b301fe8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0xd8013260, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0x8000075e, mmCP_DFY_DATA_0 }, + { 0x98c0fff1, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c00002, mmCP_DFY_DATA_0 }, + { 0x80000723, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc41f02f1, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0xd8013247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0x80000743, mmCP_DFY_DATA_0 }, + { 0xd8813247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0xc4100004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcd000008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0x98c0ffde, mmCP_DFY_DATA_0 }, + { 0x8000072e, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x8c0007e0, mmCP_DFY_DATA_0 }, + { 0x95c00012, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x15600008, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0xce000009, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd84131db, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0xcd800009, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0x1b301ff8, mmCP_DFY_DATA_0 }, + { 0x2b300400, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8413260, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x04240000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x041c3000, mmCP_DFY_DATA_0 }, + { 0xcdc13267, mmCP_DFY_DATA_0 }, + { 0xc41d3267, mmCP_DFY_DATA_0 }, + { 0xc41d3265, mmCP_DFY_DATA_0 }, + { 0x25dc8000, mmCP_DFY_DATA_0 }, + { 0x95c00007, mmCP_DFY_DATA_0 }, + { 0xc41c004a, mmCP_DFY_DATA_0 }, + { 0x195800e8, mmCP_DFY_DATA_0 }, + { 0xcd80005e, mmCP_DFY_DATA_0 }, + { 0xc418004c, mmCP_DFY_DATA_0 }, + { 0xcd81326e, mmCP_DFY_DATA_0 }, + { 0xcdc0005e, mmCP_DFY_DATA_0 }, + { 0xc41d3265, mmCP_DFY_DATA_0 }, + { 0x25dd7fff, mmCP_DFY_DATA_0 }, + { 0xcdc13265, mmCP_DFY_DATA_0 }, + { 0xc41d3246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0xc42d3267, mmCP_DFY_DATA_0 }, + { 0x51e00020, mmCP_DFY_DATA_0 }, + { 0x7e1a001a, mmCP_DFY_DATA_0 }, + { 0x46200200, mmCP_DFY_DATA_0 }, + { 0x04283247, mmCP_DFY_DATA_0 }, + { 0x04300033, mmCP_DFY_DATA_0 }, + { 0x1af80057, mmCP_DFY_DATA_0 }, + { 0x1af40213, mmCP_DFY_DATA_0 }, + { 0x042c000c, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f6f400a, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2000025, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xc6990000, mmCP_DFY_DATA_0 }, + { 0x329c325d, mmCP_DFY_DATA_0 }, + { 0x99c00008, mmCP_DFY_DATA_0 }, + { 0x329c3269, mmCP_DFY_DATA_0 }, + { 0x99c00006, mmCP_DFY_DATA_0 }, + { 0x329c3267, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0xc01defff, mmCP_DFY_DATA_0 }, + { 0x7d9d8009, mmCP_DFY_DATA_0 }, + { 0x8000078a, mmCP_DFY_DATA_0 }, + { 0x25980000, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0x9b00fff2, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc43c0012, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd801325b, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0xc03e7ff0, mmCP_DFY_DATA_0 }, + { 0x7f3f0009, mmCP_DFY_DATA_0 }, + { 0xcf01325a, mmCP_DFY_DATA_0 }, + { 0xc4313249, mmCP_DFY_DATA_0 }, + { 0x1f30001f, mmCP_DFY_DATA_0 }, + { 0xcf013249, mmCP_DFY_DATA_0 }, + { 0xc03e4000, mmCP_DFY_DATA_0 }, + { 0xcfc13254, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8013254, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0xd801324f, mmCP_DFY_DATA_0 }, + { 0xd8013255, mmCP_DFY_DATA_0 }, + { 0xd8013247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0x1b300028, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001219, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x9900000d, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0x9700000b, mmCP_DFY_DATA_0 }, + { 0xc43d30b5, mmCP_DFY_DATA_0 }, + { 0x1bf0003a, mmCP_DFY_DATA_0 }, + { 0x9b000b80, mmCP_DFY_DATA_0 }, + { 0x203c003a, mmCP_DFY_DATA_0 }, + { 0xc430000e, mmCP_DFY_DATA_0 }, + { 0x27300700, mmCP_DFY_DATA_0 }, + { 0x13300014, mmCP_DFY_DATA_0 }, + { 0x2b300001, mmCP_DFY_DATA_0 }, + { 0xcf0130b7, mmCP_DFY_DATA_0 }, + { 0xcfc130b5, mmCP_DFY_DATA_0 }, + { 0x46200008, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd2000025, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0x9bc00001, mmCP_DFY_DATA_0 }, + { 0xccc00010, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4080007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0xc4193260, mmCP_DFY_DATA_0 }, + { 0x259c0003, mmCP_DFY_DATA_0 }, + { 0x31dc0003, mmCP_DFY_DATA_0 }, + { 0x95c00014, mmCP_DFY_DATA_0 }, + { 0x040c3000, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x18ec0057, mmCP_DFY_DATA_0 }, + { 0x18e40213, mmCP_DFY_DATA_0 }, + { 0x18cc0199, mmCP_DFY_DATA_0 }, + { 0x7cecc00a, mmCP_DFY_DATA_0 }, + { 0x7ce4c00a, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x8c000448, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x040c2000, mmCP_DFY_DATA_0 }, + { 0xccc13267, mmCP_DFY_DATA_0 }, + { 0xc40d3267, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0xcc800010, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc418000b, mmCP_DFY_DATA_0 }, + { 0x31980002, mmCP_DFY_DATA_0 }, + { 0x041c0000, mmCP_DFY_DATA_0 }, + { 0x9980001c, mmCP_DFY_DATA_0 }, + { 0x19580066, mmCP_DFY_DATA_0 }, + { 0x15600008, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0xc0120001, mmCP_DFY_DATA_0 }, + { 0x11980003, mmCP_DFY_DATA_0 }, + { 0x04240004, mmCP_DFY_DATA_0 }, + { 0x7da18001, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1c200, mmCP_DFY_DATA_0 }, + { 0xc41d24db, mmCP_DFY_DATA_0 }, + { 0x7cd0c001, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0x7dd9c005, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0x99c00002, mmCP_DFY_DATA_0 }, + { 0x9a40fff8, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x9580137b, mmCP_DFY_DATA_0 }, + { 0xc00ee000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1c200, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd840004f, mmCP_DFY_DATA_0 }, + { 0xc4113269, mmCP_DFY_DATA_0 }, + { 0x19080070, mmCP_DFY_DATA_0 }, + { 0x190c00e8, mmCP_DFY_DATA_0 }, + { 0x2510003f, mmCP_DFY_DATA_0 }, + { 0x2518000f, mmCP_DFY_DATA_0 }, + { 0xcd813268, mmCP_DFY_DATA_0 }, + { 0x05a80809, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000080e, mmCP_DFY_DATA_0 }, + { 0x8000080f, mmCP_DFY_DATA_0 }, + { 0x80000898, mmCP_DFY_DATA_0 }, + { 0x80000946, mmCP_DFY_DATA_0 }, + { 0x800009e1, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x04a80811, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000815, mmCP_DFY_DATA_0 }, + { 0x80000834, mmCP_DFY_DATA_0 }, + { 0x8000085e, mmCP_DFY_DATA_0 }, + { 0x8000085e, mmCP_DFY_DATA_0 }, + { 0x04341001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc42d3045, mmCP_DFY_DATA_0 }, + { 0xcec1c091, mmCP_DFY_DATA_0 }, + { 0x31300021, mmCP_DFY_DATA_0 }, + { 0x9700000b, mmCP_DFY_DATA_0 }, + { 0xd84002f1, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xc4293059, mmCP_DFY_DATA_0 }, + { 0x56a8001f, mmCP_DFY_DATA_0 }, + { 0x7f2b000a, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x9b000241, mmCP_DFY_DATA_0 }, + { 0x8000084a, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc43130b6, mmCP_DFY_DATA_0 }, + { 0x9b000003, mmCP_DFY_DATA_0 }, + { 0xc02f0001, mmCP_DFY_DATA_0 }, + { 0xcec130b6, mmCP_DFY_DATA_0 }, + { 0xc4252087, mmCP_DFY_DATA_0 }, + { 0x5668001a, mmCP_DFY_DATA_0 }, + { 0x26a80005, mmCP_DFY_DATA_0 }, + { 0x9a80fffd, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd80130b6, mmCP_DFY_DATA_0 }, + { 0x8000084a, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04341001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc431ecaa, mmCP_DFY_DATA_0 }, + { 0x27300080, mmCP_DFY_DATA_0 }, + { 0x9b000010, mmCP_DFY_DATA_0 }, + { 0xc02e0001, mmCP_DFY_DATA_0 }, + { 0xcec130b6, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd80130b6, mmCP_DFY_DATA_0 }, + { 0x31300021, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xd84002f1, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xc4293059, mmCP_DFY_DATA_0 }, + { 0x56a8001f, mmCP_DFY_DATA_0 }, + { 0x7f2b000a, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x9b00021d, mmCP_DFY_DATA_0 }, + { 0xdd410000, mmCP_DFY_DATA_0 }, + { 0x040c0005, mmCP_DFY_DATA_0 }, + { 0xd84802e9, mmCP_DFY_DATA_0 }, + { 0x8c001a41, mmCP_DFY_DATA_0 }, + { 0xc43b02f1, mmCP_DFY_DATA_0 }, + { 0x9b800006, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xcec80278, mmCP_DFY_DATA_0 }, + { 0x56f00020, mmCP_DFY_DATA_0 }, + { 0xcf080280, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8813247, mmCP_DFY_DATA_0 }, + { 0xd80802e9, mmCP_DFY_DATA_0 }, + { 0x8000085e, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x31100011, mmCP_DFY_DATA_0 }, + { 0x950001fa, mmCP_DFY_DATA_0 }, + { 0xc02e0001, mmCP_DFY_DATA_0 }, + { 0x2aec0008, mmCP_DFY_DATA_0 }, + { 0xc01c0020, mmCP_DFY_DATA_0 }, + { 0xc0180001, mmCP_DFY_DATA_0 }, + { 0xc00c0007, mmCP_DFY_DATA_0 }, + { 0x11a40006, mmCP_DFY_DATA_0 }, + { 0x7de6000a, mmCP_DFY_DATA_0 }, + { 0x10e40008, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x7e2e000a, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0xc4113254, mmCP_DFY_DATA_0 }, + { 0x1d10ffdf, mmCP_DFY_DATA_0 }, + { 0x2110003e, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0xd801324f, mmCP_DFY_DATA_0 }, + { 0xd8013255, mmCP_DFY_DATA_0 }, + { 0x1d10ff9e, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0xd8013247, mmCP_DFY_DATA_0 }, + { 0xd801325d, mmCP_DFY_DATA_0 }, + { 0xd801325e, mmCP_DFY_DATA_0 }, + { 0xc0245301, mmCP_DFY_DATA_0 }, + { 0xce413249, mmCP_DFY_DATA_0 }, + { 0xd801325f, mmCP_DFY_DATA_0 }, + { 0xc425326c, mmCP_DFY_DATA_0 }, + { 0xc0121fff, mmCP_DFY_DATA_0 }, + { 0x29108eff, mmCP_DFY_DATA_0 }, + { 0x7e524009, mmCP_DFY_DATA_0 }, + { 0xce41326c, mmCP_DFY_DATA_0 }, + { 0xc425325a, mmCP_DFY_DATA_0 }, + { 0xc0127ff0, mmCP_DFY_DATA_0 }, + { 0x7e524009, mmCP_DFY_DATA_0 }, + { 0xce41325a, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0xc0131fff, mmCP_DFY_DATA_0 }, + { 0x7e524009, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0xd801326d, mmCP_DFY_DATA_0 }, + { 0xd801326e, mmCP_DFY_DATA_0 }, + { 0xd8013279, mmCP_DFY_DATA_0 }, + { 0x94c00003, mmCP_DFY_DATA_0 }, + { 0x08cc0001, mmCP_DFY_DATA_0 }, + { 0x80000866, mmCP_DFY_DATA_0 }, + { 0xc00c0007, mmCP_DFY_DATA_0 }, + { 0x95800003, mmCP_DFY_DATA_0 }, + { 0x09980001, mmCP_DFY_DATA_0 }, + { 0x80000866, mmCP_DFY_DATA_0 }, + { 0xc0100010, mmCP_DFY_DATA_0 }, + { 0x7dd2400c, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xc0180003, mmCP_DFY_DATA_0 }, + { 0x7dd1c002, mmCP_DFY_DATA_0 }, + { 0x80000866, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x04a8089a, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000089e, mmCP_DFY_DATA_0 }, + { 0x800008fa, mmCP_DFY_DATA_0 }, + { 0x80000945, mmCP_DFY_DATA_0 }, + { 0x80000945, mmCP_DFY_DATA_0 }, + { 0x31300022, mmCP_DFY_DATA_0 }, + { 0x97000007, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d91801a, mmCP_DFY_DATA_0 }, + { 0x459801e0, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x2738000f, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8300011, mmCP_DFY_DATA_0 }, + { 0x97000036, mmCP_DFY_DATA_0 }, + { 0x45980008, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8340011, mmCP_DFY_DATA_0 }, + { 0x9740002f, mmCP_DFY_DATA_0 }, + { 0xc43c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x13b80001, mmCP_DFY_DATA_0 }, + { 0xc79d3300, mmCP_DFY_DATA_0 }, + { 0xc7a13301, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xd8393300, mmCP_DFY_DATA_0 }, + { 0xc0260001, mmCP_DFY_DATA_0 }, + { 0xce793301, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x964012a4, mmCP_DFY_DATA_0 }, + { 0x7c028009, mmCP_DFY_DATA_0 }, + { 0x9740001c, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x99800004, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x06a80400, mmCP_DFY_DATA_0 }, + { 0x800008d2, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0x29640001, mmCP_DFY_DATA_0 }, + { 0xce40001a, mmCP_DFY_DATA_0 }, + { 0x242c0000, mmCP_DFY_DATA_0 }, + { 0x06ec0400, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x9980fffd, mmCP_DFY_DATA_0 }, + { 0xc02620c0, mmCP_DFY_DATA_0 }, + { 0xce41c078, mmCP_DFY_DATA_0 }, + { 0xce81c080, mmCP_DFY_DATA_0 }, + { 0xcc01c081, mmCP_DFY_DATA_0 }, + { 0xcf01c082, mmCP_DFY_DATA_0 }, + { 0x57240020, mmCP_DFY_DATA_0 }, + { 0xce41c083, mmCP_DFY_DATA_0 }, + { 0xc0260400, mmCP_DFY_DATA_0 }, + { 0x7e6e400a, mmCP_DFY_DATA_0 }, + { 0xce41c084, mmCP_DFY_DATA_0 }, + { 0x7eae8001, mmCP_DFY_DATA_0 }, + { 0x7f2f0011, mmCP_DFY_DATA_0 }, + { 0x800008d2, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xcdf93300, mmCP_DFY_DATA_0 }, + { 0xce393301, mmCP_DFY_DATA_0 }, + { 0xcfc00008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc43c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xcfc00008, mmCP_DFY_DATA_0 }, + { 0x80000903, mmCP_DFY_DATA_0 }, + { 0x31240022, mmCP_DFY_DATA_0 }, + { 0x96400008, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43130b8, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x7ec30011, mmCP_DFY_DATA_0 }, + { 0x32f80000, mmCP_DFY_DATA_0 }, + { 0x9b800011, mmCP_DFY_DATA_0 }, + { 0x043c0020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x67180001, mmCP_DFY_DATA_0 }, + { 0x0bfc0001, mmCP_DFY_DATA_0 }, + { 0x57300001, mmCP_DFY_DATA_0 }, + { 0x95800006, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x9a400003, mmCP_DFY_DATA_0 }, + { 0xd981325d, mmCP_DFY_DATA_0 }, + { 0x80000915, mmCP_DFY_DATA_0 }, + { 0xd9c1325d, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9bc0fff6, mmCP_DFY_DATA_0 }, + { 0x7f818001, mmCP_DFY_DATA_0 }, + { 0x8c001606, mmCP_DFY_DATA_0 }, + { 0x7d838001, mmCP_DFY_DATA_0 }, + { 0x94800010, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc41d3259, mmCP_DFY_DATA_0 }, + { 0xc421325a, mmCP_DFY_DATA_0 }, + { 0x16240014, mmCP_DFY_DATA_0 }, + { 0x12640014, mmCP_DFY_DATA_0 }, + { 0x1a2801f0, mmCP_DFY_DATA_0 }, + { 0x12a80010, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0x7e2a000a, mmCP_DFY_DATA_0 }, + { 0x7de1c001, mmCP_DFY_DATA_0 }, + { 0x7e5e400a, mmCP_DFY_DATA_0 }, + { 0x9b800002, mmCP_DFY_DATA_0 }, + { 0x2264003f, mmCP_DFY_DATA_0 }, + { 0xce41325a, mmCP_DFY_DATA_0 }, + { 0xd8013259, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x8c00075e, mmCP_DFY_DATA_0 }, + { 0xc4af0228, mmCP_DFY_DATA_0 }, + { 0x043c0000, mmCP_DFY_DATA_0 }, + { 0x66d80001, mmCP_DFY_DATA_0 }, + { 0x95800010, mmCP_DFY_DATA_0 }, + { 0x04300002, mmCP_DFY_DATA_0 }, + { 0x1330000d, mmCP_DFY_DATA_0 }, + { 0x13f40014, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x04380040, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380060, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x07fc0001, mmCP_DFY_DATA_0 }, + { 0x56ec0001, mmCP_DFY_DATA_0 }, + { 0x33e80010, mmCP_DFY_DATA_0 }, + { 0x9680ffec, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x04a80948, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000094c, mmCP_DFY_DATA_0 }, + { 0x8000099b, mmCP_DFY_DATA_0 }, + { 0x800009e0, mmCP_DFY_DATA_0 }, + { 0x800009e0, mmCP_DFY_DATA_0 }, + { 0xc43c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d91801a, mmCP_DFY_DATA_0 }, + { 0x459801e0, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x2738000f, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8300011, mmCP_DFY_DATA_0 }, + { 0x97000033, mmCP_DFY_DATA_0 }, + { 0x45980008, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc8340011, mmCP_DFY_DATA_0 }, + { 0x9740002c, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x13b80001, mmCP_DFY_DATA_0 }, + { 0xc79d3300, mmCP_DFY_DATA_0 }, + { 0xc7a13301, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xd8393300, mmCP_DFY_DATA_0 }, + { 0xc0260001, mmCP_DFY_DATA_0 }, + { 0xce793301, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x964011fe, mmCP_DFY_DATA_0 }, + { 0x7c028009, mmCP_DFY_DATA_0 }, + { 0x9740001c, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x99800004, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x06a80400, mmCP_DFY_DATA_0 }, + { 0x80000978, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0x29640001, mmCP_DFY_DATA_0 }, + { 0xce40001a, mmCP_DFY_DATA_0 }, + { 0x242c0000, mmCP_DFY_DATA_0 }, + { 0x06ec0400, mmCP_DFY_DATA_0 }, + { 0x57740001, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x9980fffd, mmCP_DFY_DATA_0 }, + { 0xc0260010, mmCP_DFY_DATA_0 }, + { 0xce41c078, mmCP_DFY_DATA_0 }, + { 0xcf01c080, mmCP_DFY_DATA_0 }, + { 0x57240020, mmCP_DFY_DATA_0 }, + { 0xce41c081, mmCP_DFY_DATA_0 }, + { 0xce81c082, mmCP_DFY_DATA_0 }, + { 0xcc01c083, mmCP_DFY_DATA_0 }, + { 0xc0260800, mmCP_DFY_DATA_0 }, + { 0x7e6e400a, mmCP_DFY_DATA_0 }, + { 0xce41c084, mmCP_DFY_DATA_0 }, + { 0x7eae8001, mmCP_DFY_DATA_0 }, + { 0x7f2f0011, mmCP_DFY_DATA_0 }, + { 0x80000978, mmCP_DFY_DATA_0 }, + { 0xc4180006, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xcdf93300, mmCP_DFY_DATA_0 }, + { 0xce393301, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xcfc00008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7dda801a, mmCP_DFY_DATA_0 }, + { 0x7d41c001, mmCP_DFY_DATA_0 }, + { 0x7e838011, mmCP_DFY_DATA_0 }, + { 0xd84802e9, mmCP_DFY_DATA_0 }, + { 0x8c001802, mmCP_DFY_DATA_0 }, + { 0x469c0390, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4200011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4240011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4280011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc42c0011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0x45dc0004, mmCP_DFY_DATA_0 }, + { 0xd1c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4380011, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x8c0014df, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x31280014, mmCP_DFY_DATA_0 }, + { 0xce8802ef, mmCP_DFY_DATA_0 }, + { 0x9a800062, mmCP_DFY_DATA_0 }, + { 0x31280034, mmCP_DFY_DATA_0 }, + { 0x9a800060, mmCP_DFY_DATA_0 }, + { 0x04a809e8, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x800009ec, mmCP_DFY_DATA_0 }, + { 0x80000a45, mmCP_DFY_DATA_0 }, + { 0x80000a59, mmCP_DFY_DATA_0 }, + { 0x80000a59, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4113246, mmCP_DFY_DATA_0 }, + { 0xc4193245, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0x7d91801a, mmCP_DFY_DATA_0 }, + { 0x45980400, mmCP_DFY_DATA_0 }, + { 0xc4b30258, mmCP_DFY_DATA_0 }, + { 0xc4a70250, mmCP_DFY_DATA_0 }, + { 0x53300020, mmCP_DFY_DATA_0 }, + { 0x7e72401a, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x1b342010, mmCP_DFY_DATA_0 }, + { 0x172c000c, mmCP_DFY_DATA_0 }, + { 0x26ec0800, mmCP_DFY_DATA_0 }, + { 0x1b30c012, mmCP_DFY_DATA_0 }, + { 0x7ef7400a, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x2b300000, mmCP_DFY_DATA_0 }, + { 0xcf00001c, mmCP_DFY_DATA_0 }, + { 0x042c0020, mmCP_DFY_DATA_0 }, + { 0x66740001, mmCP_DFY_DATA_0 }, + { 0x97400041, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04383000, mmCP_DFY_DATA_0 }, + { 0xcf813267, mmCP_DFY_DATA_0 }, + { 0xc4393267, mmCP_DFY_DATA_0 }, + { 0x9b800001, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x1b38007e, mmCP_DFY_DATA_0 }, + { 0x33b40003, mmCP_DFY_DATA_0 }, + { 0x9b400003, mmCP_DFY_DATA_0 }, + { 0x4598001c, mmCP_DFY_DATA_0 }, + { 0x9740002f, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc40c0011, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4100011, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002eb, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002ec, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002ed, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4340011, mmCP_DFY_DATA_0 }, + { 0xcf4002ee, mmCP_DFY_DATA_0 }, + { 0x45980004, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04382000, mmCP_DFY_DATA_0 }, + { 0xcf813267, mmCP_DFY_DATA_0 }, + { 0xd84802e9, mmCP_DFY_DATA_0 }, + { 0x8c001715, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04382000, mmCP_DFY_DATA_0 }, + { 0xcf813267, mmCP_DFY_DATA_0 }, + { 0x56640001, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x9ac0ffbc, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x04341001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x94800005, mmCP_DFY_DATA_0 }, + { 0xc431ecaa, mmCP_DFY_DATA_0 }, + { 0x27300080, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000a55, mmCP_DFY_DATA_0 }, + { 0xc43130b6, mmCP_DFY_DATA_0 }, + { 0x233c0032, mmCP_DFY_DATA_0 }, + { 0xcfc130b6, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcf0130b6, mmCP_DFY_DATA_0 }, + { 0xc49302ef, mmCP_DFY_DATA_0 }, + { 0x99000003, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8413247, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0x80000a5a, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04180001, mmCP_DFY_DATA_0 }, + { 0x5198001f, mmCP_DFY_DATA_0 }, + { 0xcd813268, mmCP_DFY_DATA_0 }, + { 0xc4193269, mmCP_DFY_DATA_0 }, + { 0x2598000f, mmCP_DFY_DATA_0 }, + { 0x9980fffe, mmCP_DFY_DATA_0 }, + { 0xd80002f1, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8013268, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04380001, mmCP_DFY_DATA_0 }, + { 0x53b8001f, mmCP_DFY_DATA_0 }, + { 0x7db9801a, mmCP_DFY_DATA_0 }, + { 0xcd813268, mmCP_DFY_DATA_0 }, + { 0x80000a5e, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01106, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcc412e01, mmCP_DFY_DATA_0 }, + { 0xcc412e02, mmCP_DFY_DATA_0 }, + { 0xcc412e03, mmCP_DFY_DATA_0 }, + { 0xcc412e00, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c010fd, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50640020, mmCP_DFY_DATA_0 }, + { 0x7ce4c01a, mmCP_DFY_DATA_0 }, + { 0xd0c00072, mmCP_DFY_DATA_0 }, + { 0xc80c0072, mmCP_DFY_DATA_0 }, + { 0x58e801fc, mmCP_DFY_DATA_0 }, + { 0x12a80009, mmCP_DFY_DATA_0 }, + { 0x2aa80000, mmCP_DFY_DATA_0 }, + { 0xd0c0001e, mmCP_DFY_DATA_0 }, + { 0xce80001c, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc424000f, mmCP_DFY_DATA_0 }, + { 0x9a40ffff, mmCP_DFY_DATA_0 }, + { 0x04240010, mmCP_DFY_DATA_0 }, + { 0x18dc01e2, mmCP_DFY_DATA_0 }, + { 0x7e5e4002, mmCP_DFY_DATA_0 }, + { 0x3e5c0003, mmCP_DFY_DATA_0 }, + { 0x3e540002, mmCP_DFY_DATA_0 }, + { 0x95c00006, mmCP_DFY_DATA_0 }, + { 0xc8180011, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0x55140020, mmCP_DFY_DATA_0 }, + { 0x80000aa2, mmCP_DFY_DATA_0 }, + { 0x9540000a, mmCP_DFY_DATA_0 }, + { 0xc8180011, mmCP_DFY_DATA_0 }, + { 0x44cc0008, mmCP_DFY_DATA_0 }, + { 0x55900020, mmCP_DFY_DATA_0 }, + { 0xd0c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc424000f, mmCP_DFY_DATA_0 }, + { 0x9a40ffff, mmCP_DFY_DATA_0 }, + { 0xc4140011, mmCP_DFY_DATA_0 }, + { 0x80000aa2, mmCP_DFY_DATA_0 }, + { 0x44cc0004, mmCP_DFY_DATA_0 }, + { 0xc4180011, mmCP_DFY_DATA_0 }, + { 0xd0c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc424000f, mmCP_DFY_DATA_0 }, + { 0x9a40ffff, mmCP_DFY_DATA_0 }, + { 0xc8100011, mmCP_DFY_DATA_0 }, + { 0x55140020, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcd812e01, mmCP_DFY_DATA_0 }, + { 0xcd012e02, mmCP_DFY_DATA_0 }, + { 0xcd412e03, mmCP_DFY_DATA_0 }, + { 0xcc412e00, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc4253249, mmCP_DFY_DATA_0 }, + { 0x2264003f, mmCP_DFY_DATA_0 }, + { 0xce413249, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc4253249, mmCP_DFY_DATA_0 }, + { 0x96400001, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xc410001a, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0xc4140028, mmCP_DFY_DATA_0 }, + { 0x95000005, mmCP_DFY_DATA_0 }, + { 0x1e64001f, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce413249, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x14d00010, mmCP_DFY_DATA_0 }, + { 0xc4180030, mmCP_DFY_DATA_0 }, + { 0xc41c0007, mmCP_DFY_DATA_0 }, + { 0x99000004, mmCP_DFY_DATA_0 }, + { 0x99400009, mmCP_DFY_DATA_0 }, + { 0x9980000c, mmCP_DFY_DATA_0 }, + { 0x80000ab1, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xc420001c, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0x9a0010ac, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xd880003f, mmCP_DFY_DATA_0 }, + { 0x95c00002, mmCP_DFY_DATA_0 }, + { 0xd8c0003f, mmCP_DFY_DATA_0 }, + { 0x80001082, mmCP_DFY_DATA_0 }, + { 0xd8800040, mmCP_DFY_DATA_0 }, + { 0x95c00002, mmCP_DFY_DATA_0 }, + { 0xd8c00040, mmCP_DFY_DATA_0 }, + { 0x800010de, mmCP_DFY_DATA_0 }, + { 0xc010ffff, mmCP_DFY_DATA_0 }, + { 0x18d403f7, mmCP_DFY_DATA_0 }, + { 0x7d0cc009, mmCP_DFY_DATA_0 }, + { 0xc41b0367, mmCP_DFY_DATA_0 }, + { 0x7d958004, mmCP_DFY_DATA_0 }, + { 0x7d85800a, mmCP_DFY_DATA_0 }, + { 0xdc1e0000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d001fc, mmCP_DFY_DATA_0 }, + { 0x05280adc, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000af1, mmCP_DFY_DATA_0 }, + { 0x80000adf, mmCP_DFY_DATA_0 }, + { 0x80000ae7, mmCP_DFY_DATA_0 }, + { 0x8c000ace, mmCP_DFY_DATA_0 }, + { 0xd8c00013, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd8d2000, mmCP_DFY_DATA_0 }, + { 0x99c00010, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x18d803f7, mmCP_DFY_DATA_0 }, + { 0xc010ffff, mmCP_DFY_DATA_0 }, + { 0x7d0cc009, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0x11940014, mmCP_DFY_DATA_0 }, + { 0x29544001, mmCP_DFY_DATA_0 }, + { 0x9a400002, mmCP_DFY_DATA_0 }, + { 0x29544003, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x80000af4, mmCP_DFY_DATA_0 }, + { 0xd8c00013, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd44d2000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0xd8c00013, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd44dc000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d0003c, mmCP_DFY_DATA_0 }, + { 0x95000006, mmCP_DFY_DATA_0 }, + { 0x8c000ace, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcd8d2c00, mmCP_DFY_DATA_0 }, + { 0x99c00003, mmCP_DFY_DATA_0 }, + { 0x80000b0a, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xd44d2c00, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x28148004, mmCP_DFY_DATA_0 }, + { 0x24d800ff, mmCP_DFY_DATA_0 }, + { 0xccc00019, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd4593240, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c0105e, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x50540020, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x2198003f, mmCP_DFY_DATA_0 }, + { 0x199c0034, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x95c00028, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc42d324f, mmCP_DFY_DATA_0 }, + { 0xc4313255, mmCP_DFY_DATA_0 }, + { 0x7ef3400c, mmCP_DFY_DATA_0 }, + { 0x9b400021, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x14e80001, mmCP_DFY_DATA_0 }, + { 0x9a8000af, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x041c0002, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0xccc00010, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c01043, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x50540020, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x18a01fe8, mmCP_DFY_DATA_0 }, + { 0x3620005c, mmCP_DFY_DATA_0 }, + { 0x9a00000e, mmCP_DFY_DATA_0 }, + { 0x2464003f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc6290ce7, mmCP_DFY_DATA_0 }, + { 0x16ac001f, mmCP_DFY_DATA_0 }, + { 0x96c00004, mmCP_DFY_DATA_0 }, + { 0x26ac003f, mmCP_DFY_DATA_0 }, + { 0x7ee6c00d, mmCP_DFY_DATA_0 }, + { 0x96c00005, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x2620000f, mmCP_DFY_DATA_0 }, + { 0x9a00fff8, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xce000367, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x9640102e, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x199c0037, mmCP_DFY_DATA_0 }, + { 0x19a00035, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x95c0005d, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xc42d3256, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0x16f8001f, mmCP_DFY_DATA_0 }, + { 0x9780000d, mmCP_DFY_DATA_0 }, + { 0xc4253248, mmCP_DFY_DATA_0 }, + { 0xc035f0ff, mmCP_DFY_DATA_0 }, + { 0x7e764009, mmCP_DFY_DATA_0 }, + { 0x19b401f8, mmCP_DFY_DATA_0 }, + { 0x13740008, mmCP_DFY_DATA_0 }, + { 0x7e76400a, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce413248, mmCP_DFY_DATA_0 }, + { 0xcf01325a, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xd1000072, mmCP_DFY_DATA_0 }, + { 0xc8100072, mmCP_DFY_DATA_0 }, + { 0x55140020, mmCP_DFY_DATA_0 }, + { 0x199c0034, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0x9b800004, mmCP_DFY_DATA_0 }, + { 0x1ae4003e, mmCP_DFY_DATA_0 }, + { 0xce400008, mmCP_DFY_DATA_0 }, + { 0x80000b7c, mmCP_DFY_DATA_0 }, + { 0xc4353254, mmCP_DFY_DATA_0 }, + { 0x16a80008, mmCP_DFY_DATA_0 }, + { 0x1aec003c, mmCP_DFY_DATA_0 }, + { 0x19a4003f, mmCP_DFY_DATA_0 }, + { 0x12a80015, mmCP_DFY_DATA_0 }, + { 0x12ec001f, mmCP_DFY_DATA_0 }, + { 0x1374000b, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc02e4000, mmCP_DFY_DATA_0 }, + { 0x1774000d, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xce400008, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0xc43d3248, mmCP_DFY_DATA_0 }, + { 0x1bfc01e8, mmCP_DFY_DATA_0 }, + { 0x13fc0018, mmCP_DFY_DATA_0 }, + { 0x7dbd800a, mmCP_DFY_DATA_0 }, + { 0x1d98ff15, mmCP_DFY_DATA_0 }, + { 0x592c00fc, mmCP_DFY_DATA_0 }, + { 0xcd80000a, mmCP_DFY_DATA_0 }, + { 0x12e00016, mmCP_DFY_DATA_0 }, + { 0x7da1800a, mmCP_DFY_DATA_0 }, + { 0x592c007e, mmCP_DFY_DATA_0 }, + { 0x12e00015, mmCP_DFY_DATA_0 }, + { 0x7da1800a, mmCP_DFY_DATA_0 }, + { 0xd1000001, mmCP_DFY_DATA_0 }, + { 0xcd800001, mmCP_DFY_DATA_0 }, + { 0x11a0000c, mmCP_DFY_DATA_0 }, + { 0x1264001e, mmCP_DFY_DATA_0 }, + { 0x1620000c, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x7e32000a, mmCP_DFY_DATA_0 }, + { 0x12e4001b, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x5924007e, mmCP_DFY_DATA_0 }, + { 0x12640017, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0x19a4003c, mmCP_DFY_DATA_0 }, + { 0x12640018, mmCP_DFY_DATA_0 }, + { 0x7e26000a, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xce01325a, mmCP_DFY_DATA_0 }, + { 0xcd013257, mmCP_DFY_DATA_0 }, + { 0xcd413258, mmCP_DFY_DATA_0 }, + { 0xc429325a, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c00fdb, mmCP_DFY_DATA_0 }, + { 0x96800001, mmCP_DFY_DATA_0 }, + { 0x95c00003, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x9780f5ca, mmCP_DFY_DATA_0 }, + { 0xcf400100, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0xd9000010, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001219, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0xccc00010, mmCP_DFY_DATA_0 }, + { 0x8c001b6d, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc42d324e, mmCP_DFY_DATA_0 }, + { 0xc431324d, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc435324f, mmCP_DFY_DATA_0 }, + { 0xc4293256, mmCP_DFY_DATA_0 }, + { 0x52ec0008, mmCP_DFY_DATA_0 }, + { 0x07740003, mmCP_DFY_DATA_0 }, + { 0x04240002, mmCP_DFY_DATA_0 }, + { 0x269c003f, mmCP_DFY_DATA_0 }, + { 0x7e5e4004, mmCP_DFY_DATA_0 }, + { 0x7f67000f, mmCP_DFY_DATA_0 }, + { 0x97000003, mmCP_DFY_DATA_0 }, + { 0x7f674002, mmCP_DFY_DATA_0 }, + { 0x0b740001, mmCP_DFY_DATA_0 }, + { 0x53740002, mmCP_DFY_DATA_0 }, + { 0x7ef6c011, mmCP_DFY_DATA_0 }, + { 0x1ab42010, mmCP_DFY_DATA_0 }, + { 0x1ab8c006, mmCP_DFY_DATA_0 }, + { 0x16a8000c, mmCP_DFY_DATA_0 }, + { 0x26a80800, mmCP_DFY_DATA_0 }, + { 0x2b740000, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0xcf40001c, mmCP_DFY_DATA_0 }, + { 0xd2c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4180011, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0x8c000bec, mmCP_DFY_DATA_0 }, + { 0x80000b47, mmCP_DFY_DATA_0 }, + { 0xc42c001d, mmCP_DFY_DATA_0 }, + { 0xc4313256, mmCP_DFY_DATA_0 }, + { 0x1b34060b, mmCP_DFY_DATA_0 }, + { 0x1b300077, mmCP_DFY_DATA_0 }, + { 0x7f370009, mmCP_DFY_DATA_0 }, + { 0x13300017, mmCP_DFY_DATA_0 }, + { 0x04340100, mmCP_DFY_DATA_0 }, + { 0x26ec00ff, mmCP_DFY_DATA_0 }, + { 0xc03a8004, mmCP_DFY_DATA_0 }, + { 0x7ef6c00a, mmCP_DFY_DATA_0 }, + { 0x7f3b000a, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc40c0032, mmCP_DFY_DATA_0 }, + { 0xc410001d, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc415325b, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x18580037, mmCP_DFY_DATA_0 }, + { 0x251000ff, mmCP_DFY_DATA_0 }, + { 0xc421325d, mmCP_DFY_DATA_0 }, + { 0x262001ef, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x99800004, mmCP_DFY_DATA_0 }, + { 0x7d15400a, mmCP_DFY_DATA_0 }, + { 0xcd41325b, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x1d54001f, mmCP_DFY_DATA_0 }, + { 0xcd41325b, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc428000b, mmCP_DFY_DATA_0 }, + { 0xc42c000c, mmCP_DFY_DATA_0 }, + { 0x12a80001, mmCP_DFY_DATA_0 }, + { 0x26a80004, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0xc4340028, mmCP_DFY_DATA_0 }, + { 0x14f00010, mmCP_DFY_DATA_0 }, + { 0xc4380030, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xcd280200, mmCP_DFY_DATA_0 }, + { 0xcd680208, mmCP_DFY_DATA_0 }, + { 0xcda80210, mmCP_DFY_DATA_0 }, + { 0x9b00000c, mmCP_DFY_DATA_0 }, + { 0x9b400014, mmCP_DFY_DATA_0 }, + { 0x9b800017, mmCP_DFY_DATA_0 }, + { 0xc428000b, mmCP_DFY_DATA_0 }, + { 0xc42c000c, mmCP_DFY_DATA_0 }, + { 0x12a80001, mmCP_DFY_DATA_0 }, + { 0x26a80004, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc6930200, mmCP_DFY_DATA_0 }, + { 0xc6970208, mmCP_DFY_DATA_0 }, + { 0xc69b0210, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b000005, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd900003f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd940003f, mmCP_DFY_DATA_0 }, + { 0x80001082, mmCP_DFY_DATA_0 }, + { 0xd9000040, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd9400040, mmCP_DFY_DATA_0 }, + { 0x800010de, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14fc0011, mmCP_DFY_DATA_0 }, + { 0x24f800ff, mmCP_DFY_DATA_0 }, + { 0x33b80001, mmCP_DFY_DATA_0 }, + { 0x97c0fffc, mmCP_DFY_DATA_0 }, + { 0x9b800007, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc4380004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd88130b8, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0x7d83c001, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4093249, mmCP_DFY_DATA_0 }, + { 0x1888003e, mmCP_DFY_DATA_0 }, + { 0x94800020, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0x8c000671, mmCP_DFY_DATA_0 }, + { 0x9a400009, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc419324c, mmCP_DFY_DATA_0 }, + { 0x259c0001, mmCP_DFY_DATA_0 }, + { 0x1598001f, mmCP_DFY_DATA_0 }, + { 0x95c00016, mmCP_DFY_DATA_0 }, + { 0x95800015, mmCP_DFY_DATA_0 }, + { 0x99000003, mmCP_DFY_DATA_0 }, + { 0xd8400036, mmCP_DFY_DATA_0 }, + { 0x04100001, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0x14d80011, mmCP_DFY_DATA_0 }, + { 0x24e000ff, mmCP_DFY_DATA_0 }, + { 0x321c0002, mmCP_DFY_DATA_0 }, + { 0x32200001, mmCP_DFY_DATA_0 }, + { 0x9580ffee, mmCP_DFY_DATA_0 }, + { 0x99c00014, mmCP_DFY_DATA_0 }, + { 0x96000004, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x04140001, mmCP_DFY_DATA_0 }, + { 0x80000c30, mmCP_DFY_DATA_0 }, + { 0x9480000a, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95800f29, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x94800004, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95800f23, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0x99400002, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0xcf800008, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x94800004, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0xc418005e, mmCP_DFY_DATA_0 }, + { 0x95800f1a, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0xd8800036, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x041c0003, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xc40c0077, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x9600f502, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x98c0f500, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0x9a000f05, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0xc42d3256, mmCP_DFY_DATA_0 }, + { 0x1f30001f, mmCP_DFY_DATA_0 }, + { 0x16e4001f, mmCP_DFY_DATA_0 }, + { 0xcf01325a, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x9640f4f4, mmCP_DFY_DATA_0 }, + { 0xc434000b, mmCP_DFY_DATA_0 }, + { 0x33740002, mmCP_DFY_DATA_0 }, + { 0x9b40f4f1, mmCP_DFY_DATA_0 }, + { 0xc4353254, mmCP_DFY_DATA_0 }, + { 0x16a80008, mmCP_DFY_DATA_0 }, + { 0x1aec003c, mmCP_DFY_DATA_0 }, + { 0x12a80015, mmCP_DFY_DATA_0 }, + { 0x12ec001f, mmCP_DFY_DATA_0 }, + { 0x1374000b, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0xc02e4000, mmCP_DFY_DATA_0 }, + { 0x1774000d, mmCP_DFY_DATA_0 }, + { 0x7eae800a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0xcf400100, mmCP_DFY_DATA_0 }, + { 0x12780001, mmCP_DFY_DATA_0 }, + { 0x2bb80001, mmCP_DFY_DATA_0 }, + { 0xc00ac005, mmCP_DFY_DATA_0 }, + { 0xc00e0002, mmCP_DFY_DATA_0 }, + { 0x28cc8000, mmCP_DFY_DATA_0 }, + { 0x28884900, mmCP_DFY_DATA_0 }, + { 0x28cc0014, mmCP_DFY_DATA_0 }, + { 0x80000ff3, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x17fc0001, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x96400ee1, mmCP_DFY_DATA_0 }, + { 0xcc41c40a, mmCP_DFY_DATA_0 }, + { 0xcc41c40c, mmCP_DFY_DATA_0 }, + { 0xcc41c40d, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x24d0007f, mmCP_DFY_DATA_0 }, + { 0x15580010, mmCP_DFY_DATA_0 }, + { 0x255400ff, mmCP_DFY_DATA_0 }, + { 0xcd01c411, mmCP_DFY_DATA_0 }, + { 0xcd81c40f, mmCP_DFY_DATA_0 }, + { 0xcd41c40e, mmCP_DFY_DATA_0 }, + { 0xcc41c410, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x04200000, mmCP_DFY_DATA_0 }, + { 0x18e80033, mmCP_DFY_DATA_0 }, + { 0x18ec0034, mmCP_DFY_DATA_0 }, + { 0xcc41c414, mmCP_DFY_DATA_0 }, + { 0xcc41c415, mmCP_DFY_DATA_0 }, + { 0xcd81c413, mmCP_DFY_DATA_0 }, + { 0xcd41c412, mmCP_DFY_DATA_0 }, + { 0x18dc0032, mmCP_DFY_DATA_0 }, + { 0x7c030011, mmCP_DFY_DATA_0 }, + { 0x7c038011, mmCP_DFY_DATA_0 }, + { 0x95c00027, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xc431c417, mmCP_DFY_DATA_0 }, + { 0xc435c416, mmCP_DFY_DATA_0 }, + { 0x96800004, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xc439c419, mmCP_DFY_DATA_0 }, + { 0xc43dc418, mmCP_DFY_DATA_0 }, + { 0xc41c000e, mmCP_DFY_DATA_0 }, + { 0x29dc0008, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xcf413261, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xcf013262, mmCP_DFY_DATA_0 }, + { 0x96800004, mmCP_DFY_DATA_0 }, + { 0xcfc13263, mmCP_DFY_DATA_0 }, + { 0x96c00002, mmCP_DFY_DATA_0 }, + { 0xcf813264, mmCP_DFY_DATA_0 }, + { 0x18dc0030, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x95c00017, mmCP_DFY_DATA_0 }, + { 0x17fc0001, mmCP_DFY_DATA_0 }, + { 0x9ac00005, mmCP_DFY_DATA_0 }, + { 0x7d77000c, mmCP_DFY_DATA_0 }, + { 0x9bc00015, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0x80000cd6, mmCP_DFY_DATA_0 }, + { 0x51b80020, mmCP_DFY_DATA_0 }, + { 0x53300020, mmCP_DFY_DATA_0 }, + { 0x7f97801a, mmCP_DFY_DATA_0 }, + { 0x7f37001a, mmCP_DFY_DATA_0 }, + { 0x7f3b000c, mmCP_DFY_DATA_0 }, + { 0x9bc0000d, mmCP_DFY_DATA_0 }, + { 0x97800002, mmCP_DFY_DATA_0 }, + { 0x80000cd6, mmCP_DFY_DATA_0 }, + { 0x9a000018, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x28200001, mmCP_DFY_DATA_0 }, + { 0x80000ca7, mmCP_DFY_DATA_0 }, + { 0x18dc0031, mmCP_DFY_DATA_0 }, + { 0x95c00003, mmCP_DFY_DATA_0 }, + { 0xc435c40b, mmCP_DFY_DATA_0 }, + { 0x9740fffd, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc4280032, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x800012c2, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x1bb81ff0, mmCP_DFY_DATA_0 }, + { 0x7f8cc00a, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0xc43d3256, mmCP_DFY_DATA_0 }, + { 0x1bf0060b, mmCP_DFY_DATA_0 }, + { 0x1bfc0077, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x80000cf4, mmCP_DFY_DATA_0 }, + { 0xc43d325a, mmCP_DFY_DATA_0 }, + { 0x1bfc0677, mmCP_DFY_DATA_0 }, + { 0x13fc0017, mmCP_DFY_DATA_0 }, + { 0x04300100, mmCP_DFY_DATA_0 }, + { 0x1bb81fe8, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xc032800b, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x7ffbc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d42011, mmCP_DFY_DATA_0 }, + { 0x17fc0001, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x24cc007f, mmCP_DFY_DATA_0 }, + { 0x7cd4c00a, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc428005e, mmCP_DFY_DATA_0 }, + { 0x96800e6c, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x596001fc, mmCP_DFY_DATA_0 }, + { 0x12200009, mmCP_DFY_DATA_0 }, + { 0x7ce0c00a, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x505c0020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x50600020, mmCP_DFY_DATA_0 }, + { 0x7de1c01a, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xccc0001b, mmCP_DFY_DATA_0 }, + { 0xd140001d, mmCP_DFY_DATA_0 }, + { 0xd180001f, mmCP_DFY_DATA_0 }, + { 0xd1c00020, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x95000010, mmCP_DFY_DATA_0 }, + { 0x04300000, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8240010, mmCP_DFY_DATA_0 }, + { 0x7e5e800c, mmCP_DFY_DATA_0 }, + { 0x9bc00015, mmCP_DFY_DATA_0 }, + { 0x9a80000c, mmCP_DFY_DATA_0 }, + { 0x9b000024, mmCP_DFY_DATA_0 }, + { 0x28300001, mmCP_DFY_DATA_0 }, + { 0x122c0004, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x80000d1f, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8240010, mmCP_DFY_DATA_0 }, + { 0x566c0020, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce413261, mmCP_DFY_DATA_0 }, + { 0xcec13262, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc4340032, mmCP_DFY_DATA_0 }, + { 0x2b740008, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x96800005, mmCP_DFY_DATA_0 }, + { 0x566c0020, mmCP_DFY_DATA_0 }, + { 0xce413261, mmCP_DFY_DATA_0 }, + { 0xcec13262, mmCP_DFY_DATA_0 }, + { 0x800012c2, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x1bb81fe8, mmCP_DFY_DATA_0 }, + { 0x7f8cc00a, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0xc43d3256, mmCP_DFY_DATA_0 }, + { 0x1bf0060b, mmCP_DFY_DATA_0 }, + { 0x1bfc0077, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x80000d57, mmCP_DFY_DATA_0 }, + { 0xc43d325a, mmCP_DFY_DATA_0 }, + { 0x1bfc0677, mmCP_DFY_DATA_0 }, + { 0x13fc0017, mmCP_DFY_DATA_0 }, + { 0x04300100, mmCP_DFY_DATA_0 }, + { 0x1bb81fe8, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xc0328009, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x7ffbc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc4253246, mmCP_DFY_DATA_0 }, + { 0xc4113245, mmCP_DFY_DATA_0 }, + { 0x04143000, mmCP_DFY_DATA_0 }, + { 0xcd413267, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e51001a, mmCP_DFY_DATA_0 }, + { 0xc4153267, mmCP_DFY_DATA_0 }, + { 0x7d2d0011, mmCP_DFY_DATA_0 }, + { 0x19640057, mmCP_DFY_DATA_0 }, + { 0x19580213, mmCP_DFY_DATA_0 }, + { 0x19600199, mmCP_DFY_DATA_0 }, + { 0x7da6400a, mmCP_DFY_DATA_0 }, + { 0x7e26400a, mmCP_DFY_DATA_0 }, + { 0xd1000025, mmCP_DFY_DATA_0 }, + { 0xce400024, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x04142000, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xcd413267, mmCP_DFY_DATA_0 }, + { 0xc4153267, mmCP_DFY_DATA_0 }, + { 0x99400001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x18d40030, mmCP_DFY_DATA_0 }, + { 0x18d80034, mmCP_DFY_DATA_0 }, + { 0x05280d83, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0x7c424001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000d8a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x80000d95, mmCP_DFY_DATA_0 }, + { 0x80000db1, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x80000d95, mmCP_DFY_DATA_0 }, + { 0x80000dbc, mmCP_DFY_DATA_0 }, + { 0x11540010, mmCP_DFY_DATA_0 }, + { 0x7e010001, mmCP_DFY_DATA_0 }, + { 0x8c00187c, mmCP_DFY_DATA_0 }, + { 0x7d75400a, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd4610000, mmCP_DFY_DATA_0 }, + { 0x9580f3d8, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8000016, mmCP_DFY_DATA_0 }, + { 0x526c0020, mmCP_DFY_DATA_0 }, + { 0x18e80058, mmCP_DFY_DATA_0 }, + { 0x7e2ec01a, mmCP_DFY_DATA_0 }, + { 0xd2c00072, mmCP_DFY_DATA_0 }, + { 0xc82c0072, mmCP_DFY_DATA_0 }, + { 0x5ae0073a, mmCP_DFY_DATA_0 }, + { 0x7ea2800a, mmCP_DFY_DATA_0 }, + { 0x9940000a, mmCP_DFY_DATA_0 }, + { 0xce800024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9580f3c6, mmCP_DFY_DATA_0 }, + { 0xc4380012, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xdc3a0000, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0xce800024, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xcc400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9b80fffb, mmCP_DFY_DATA_0 }, + { 0x9980fff5, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc02a0001, mmCP_DFY_DATA_0 }, + { 0x2aa80001, mmCP_DFY_DATA_0 }, + { 0x16200002, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xce01c405, mmCP_DFY_DATA_0 }, + { 0xd441c406, mmCP_DFY_DATA_0 }, + { 0x9580f3b1, mmCP_DFY_DATA_0 }, + { 0xc439c409, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a40000b, mmCP_DFY_DATA_0 }, + { 0x11540010, mmCP_DFY_DATA_0 }, + { 0x29540002, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd4610000, mmCP_DFY_DATA_0 }, + { 0x9580f3a5, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c00da7, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50500020, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0xd0c00072, mmCP_DFY_DATA_0 }, + { 0xc8280072, mmCP_DFY_DATA_0 }, + { 0x5aac007e, mmCP_DFY_DATA_0 }, + { 0x12d80017, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7d9d800a, mmCP_DFY_DATA_0 }, + { 0x56a00020, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0x7da1800a, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7e82400a, mmCP_DFY_DATA_0 }, + { 0x7e58c01a, mmCP_DFY_DATA_0 }, + { 0x19d4003d, mmCP_DFY_DATA_0 }, + { 0x28182002, mmCP_DFY_DATA_0 }, + { 0x99400030, mmCP_DFY_DATA_0 }, + { 0x8c00104f, mmCP_DFY_DATA_0 }, + { 0xc430000d, mmCP_DFY_DATA_0 }, + { 0xc4340035, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc8140023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0xc011000f, mmCP_DFY_DATA_0 }, + { 0xc4240004, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x7c908009, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x7d614011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7ca4800a, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x7cb0800a, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0x20880188, mmCP_DFY_DATA_0 }, + { 0x54ec0020, mmCP_DFY_DATA_0 }, + { 0x7cb4800a, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x04380008, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x20240090, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0x28240004, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x9a800005, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xd8000016, mmCP_DFY_DATA_0 }, + { 0xcf80003a, mmCP_DFY_DATA_0 }, + { 0xd901a2a4, mmCP_DFY_DATA_0 }, + { 0x80001037, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x1624001f, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0xd841325f, mmCP_DFY_DATA_0 }, + { 0xd8800033, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0004, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8000039, mmCP_DFY_DATA_0 }, + { 0xd0c00038, mmCP_DFY_DATA_0 }, + { 0xc43c0022, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0xc429325f, mmCP_DFY_DATA_0 }, + { 0x26ac0001, mmCP_DFY_DATA_0 }, + { 0x9ac0fffe, mmCP_DFY_DATA_0 }, + { 0x26ac0002, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xc430001e, mmCP_DFY_DATA_0 }, + { 0xd8800033, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x1b301ff0, mmCP_DFY_DATA_0 }, + { 0x2b300300, mmCP_DFY_DATA_0 }, + { 0x2330003f, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x9680000b, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0004, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400039, mmCP_DFY_DATA_0 }, + { 0xd0c00038, mmCP_DFY_DATA_0 }, + { 0xc43c0022, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0x8c0001a2, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0x24b00008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x18ac0024, mmCP_DFY_DATA_0 }, + { 0x2b304000, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4113249, mmCP_DFY_DATA_0 }, + { 0x1910003e, mmCP_DFY_DATA_0 }, + { 0x99000002, mmCP_DFY_DATA_0 }, + { 0xd840003d, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x51100020, mmCP_DFY_DATA_0 }, + { 0xcf01326c, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x12a80014, mmCP_DFY_DATA_0 }, + { 0x2220003f, mmCP_DFY_DATA_0 }, + { 0x7e2a000a, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xce01326c, mmCP_DFY_DATA_0 }, + { 0xd8800033, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0004, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8000039, mmCP_DFY_DATA_0 }, + { 0xd0c00038, mmCP_DFY_DATA_0 }, + { 0xc43c0022, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0xd8800034, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18dc003d, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0x041c0001, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x18d40030, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x18fc0034, mmCP_DFY_DATA_0 }, + { 0x24e8000f, mmCP_DFY_DATA_0 }, + { 0x06a80e71, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000edd, mmCP_DFY_DATA_0 }, + { 0x80000e91, mmCP_DFY_DATA_0 }, + { 0x80000e91, mmCP_DFY_DATA_0 }, + { 0x80000ea1, mmCP_DFY_DATA_0 }, + { 0x80000eaa, mmCP_DFY_DATA_0 }, + { 0x80000e7c, mmCP_DFY_DATA_0 }, + { 0x80000e7f, mmCP_DFY_DATA_0 }, + { 0x80000e7f, mmCP_DFY_DATA_0 }, + { 0x80000e87, mmCP_DFY_DATA_0 }, + { 0x80000e8f, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x51dc0020, mmCP_DFY_DATA_0 }, + { 0x7d9e001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0xc420000e, mmCP_DFY_DATA_0 }, + { 0x2a200008, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0xc4213262, mmCP_DFY_DATA_0 }, + { 0xc4253261, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0xc420000e, mmCP_DFY_DATA_0 }, + { 0x2a200008, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0xc4213264, mmCP_DFY_DATA_0 }, + { 0xc4253263, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0xc820001f, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0x18e82005, mmCP_DFY_DATA_0 }, + { 0x51e00020, mmCP_DFY_DATA_0 }, + { 0x2aa80000, mmCP_DFY_DATA_0 }, + { 0x7da1801a, mmCP_DFY_DATA_0 }, + { 0xd1800072, mmCP_DFY_DATA_0 }, + { 0xc8180072, mmCP_DFY_DATA_0 }, + { 0x59a001fc, mmCP_DFY_DATA_0 }, + { 0x12200009, mmCP_DFY_DATA_0 }, + { 0x7ea2800a, mmCP_DFY_DATA_0 }, + { 0xce80001c, mmCP_DFY_DATA_0 }, + { 0xd180001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8200011, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0x15980002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd81c400, mmCP_DFY_DATA_0 }, + { 0xc421c401, mmCP_DFY_DATA_0 }, + { 0x95400041, mmCP_DFY_DATA_0 }, + { 0xc425c401, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0x80000ee6, mmCP_DFY_DATA_0 }, + { 0x31ac2580, mmCP_DFY_DATA_0 }, + { 0x9ac00011, mmCP_DFY_DATA_0 }, + { 0x31ac260c, mmCP_DFY_DATA_0 }, + { 0x9ac0000f, mmCP_DFY_DATA_0 }, + { 0x31ac0800, mmCP_DFY_DATA_0 }, + { 0x9ac0000d, mmCP_DFY_DATA_0 }, + { 0x31ac0828, mmCP_DFY_DATA_0 }, + { 0x9ac0000b, mmCP_DFY_DATA_0 }, + { 0x31ac2440, mmCP_DFY_DATA_0 }, + { 0x9ac00009, mmCP_DFY_DATA_0 }, + { 0x31ac2390, mmCP_DFY_DATA_0 }, + { 0x9ac00007, mmCP_DFY_DATA_0 }, + { 0x31ac0093, mmCP_DFY_DATA_0 }, + { 0x9ac00005, mmCP_DFY_DATA_0 }, + { 0x31ac31dc, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x31ac31e6, mmCP_DFY_DATA_0 }, + { 0x96c00004, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x80000ede, mmCP_DFY_DATA_0 }, + { 0x39ac7c06, mmCP_DFY_DATA_0 }, + { 0x3db07c00, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39acc337, mmCP_DFY_DATA_0 }, + { 0x3db0c330, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39acc335, mmCP_DFY_DATA_0 }, + { 0x3db0c336, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39ac9002, mmCP_DFY_DATA_0 }, + { 0x3db09001, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39ac9012, mmCP_DFY_DATA_0 }, + { 0x3db09011, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0x39acec70, mmCP_DFY_DATA_0 }, + { 0x3db0ec6f, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000ebc, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc5a10000, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0x05980001, mmCP_DFY_DATA_0 }, + { 0xc5a50000, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e26001a, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x05280eea, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000ef1, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x80000efe, mmCP_DFY_DATA_0 }, + { 0x80000f11, mmCP_DFY_DATA_0 }, + { 0x80000f2e, mmCP_DFY_DATA_0 }, + { 0x80000efe, mmCP_DFY_DATA_0 }, + { 0x80000f1f, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0x05980001, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x97c0f26f, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x51ec0020, mmCP_DFY_DATA_0 }, + { 0x18e80058, mmCP_DFY_DATA_0 }, + { 0x7daec01a, mmCP_DFY_DATA_0 }, + { 0xd2c00072, mmCP_DFY_DATA_0 }, + { 0xc82c0072, mmCP_DFY_DATA_0 }, + { 0x5af8073a, mmCP_DFY_DATA_0 }, + { 0x7eba800a, mmCP_DFY_DATA_0 }, + { 0xd2c00025, mmCP_DFY_DATA_0 }, + { 0xce800024, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0x95400003, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x97c0f25c, mmCP_DFY_DATA_0 }, + { 0xc4380012, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc02a0001, mmCP_DFY_DATA_0 }, + { 0x2aa80001, mmCP_DFY_DATA_0 }, + { 0x15980002, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xcd81c405, mmCP_DFY_DATA_0 }, + { 0xce01c406, mmCP_DFY_DATA_0 }, + { 0x95400003, mmCP_DFY_DATA_0 }, + { 0x56240020, mmCP_DFY_DATA_0 }, + { 0xce41c406, mmCP_DFY_DATA_0 }, + { 0x97c0f24e, mmCP_DFY_DATA_0 }, + { 0xc439c409, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424000b, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9a40f247, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0x95400004, mmCP_DFY_DATA_0 }, + { 0x05980001, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce190000, mmCP_DFY_DATA_0 }, + { 0x97c0f240, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc439c040, mmCP_DFY_DATA_0 }, + { 0x97800001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x31ac2580, mmCP_DFY_DATA_0 }, + { 0x9ac00011, mmCP_DFY_DATA_0 }, + { 0x31ac260c, mmCP_DFY_DATA_0 }, + { 0x9ac0000f, mmCP_DFY_DATA_0 }, + { 0x31ac0800, mmCP_DFY_DATA_0 }, + { 0x9ac0000d, mmCP_DFY_DATA_0 }, + { 0x31ac0828, mmCP_DFY_DATA_0 }, + { 0x9ac0000b, mmCP_DFY_DATA_0 }, + { 0x31ac2440, mmCP_DFY_DATA_0 }, + { 0x9ac00009, mmCP_DFY_DATA_0 }, + { 0x31ac2390, mmCP_DFY_DATA_0 }, + { 0x9ac00007, mmCP_DFY_DATA_0 }, + { 0x31ac0093, mmCP_DFY_DATA_0 }, + { 0x9ac00005, mmCP_DFY_DATA_0 }, + { 0x31ac31dc, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x31ac31e6, mmCP_DFY_DATA_0 }, + { 0x96c00004, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0x80000ef2, mmCP_DFY_DATA_0 }, + { 0x39ac7c06, mmCP_DFY_DATA_0 }, + { 0x3db07c00, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39acc337, mmCP_DFY_DATA_0 }, + { 0x3db0c330, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39acc335, mmCP_DFY_DATA_0 }, + { 0x3db0c336, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39acec70, mmCP_DFY_DATA_0 }, + { 0x3db0ec6f, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39ac9002, mmCP_DFY_DATA_0 }, + { 0x3db09002, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x39ac9012, mmCP_DFY_DATA_0 }, + { 0x3db09012, mmCP_DFY_DATA_0 }, + { 0x9ac00003, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x80000f40, mmCP_DFY_DATA_0 }, + { 0x80000ef1, mmCP_DFY_DATA_0 }, + { 0xc40c0006, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x95c00001, mmCP_DFY_DATA_0 }, + { 0xc434000e, mmCP_DFY_DATA_0 }, + { 0x2b740008, mmCP_DFY_DATA_0 }, + { 0x2b780001, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xd8c1325e, mmCP_DFY_DATA_0 }, + { 0xcf80001a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x7c034001, mmCP_DFY_DATA_0 }, + { 0x7c038001, mmCP_DFY_DATA_0 }, + { 0x18e0007d, mmCP_DFY_DATA_0 }, + { 0x32240003, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0x32240000, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xcd01c080, mmCP_DFY_DATA_0 }, + { 0xcd41c081, mmCP_DFY_DATA_0 }, + { 0x80000f88, mmCP_DFY_DATA_0 }, + { 0x51640020, mmCP_DFY_DATA_0 }, + { 0x7e52401a, mmCP_DFY_DATA_0 }, + { 0xd2400072, mmCP_DFY_DATA_0 }, + { 0xc8280072, mmCP_DFY_DATA_0 }, + { 0xce81c080, mmCP_DFY_DATA_0 }, + { 0x56ac0020, mmCP_DFY_DATA_0 }, + { 0x26f0ffff, mmCP_DFY_DATA_0 }, + { 0xcf01c081, mmCP_DFY_DATA_0 }, + { 0x1af000fc, mmCP_DFY_DATA_0 }, + { 0x1334000a, mmCP_DFY_DATA_0 }, + { 0x24e02000, mmCP_DFY_DATA_0 }, + { 0x7f63400a, mmCP_DFY_DATA_0 }, + { 0x18e00074, mmCP_DFY_DATA_0 }, + { 0x32240003, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0x32240000, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0xcd81c082, mmCP_DFY_DATA_0 }, + { 0xcdc1c083, mmCP_DFY_DATA_0 }, + { 0x80000f9d, mmCP_DFY_DATA_0 }, + { 0x51e40020, mmCP_DFY_DATA_0 }, + { 0x7e5a401a, mmCP_DFY_DATA_0 }, + { 0xd2400072, mmCP_DFY_DATA_0 }, + { 0xc8280072, mmCP_DFY_DATA_0 }, + { 0xce81c082, mmCP_DFY_DATA_0 }, + { 0x56ac0020, mmCP_DFY_DATA_0 }, + { 0x26f0ffff, mmCP_DFY_DATA_0 }, + { 0xcf01c083, mmCP_DFY_DATA_0 }, + { 0x1af000fc, mmCP_DFY_DATA_0 }, + { 0x13380016, mmCP_DFY_DATA_0 }, + { 0x18e00039, mmCP_DFY_DATA_0 }, + { 0x12200019, mmCP_DFY_DATA_0 }, + { 0x7fa3800a, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x18e0007d, mmCP_DFY_DATA_0 }, + { 0x1220001d, mmCP_DFY_DATA_0 }, + { 0x7fa3800a, mmCP_DFY_DATA_0 }, + { 0x18e00074, mmCP_DFY_DATA_0 }, + { 0x12200014, mmCP_DFY_DATA_0 }, + { 0x7fa3800a, mmCP_DFY_DATA_0 }, + { 0xcf81c078, mmCP_DFY_DATA_0 }, + { 0xcfc1c084, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18dc003d, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0x041c0000, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x18d001e8, mmCP_DFY_DATA_0 }, + { 0x31140005, mmCP_DFY_DATA_0 }, + { 0x99400003, mmCP_DFY_DATA_0 }, + { 0x31140006, mmCP_DFY_DATA_0 }, + { 0x95400002, mmCP_DFY_DATA_0 }, + { 0x8c00104f, mmCP_DFY_DATA_0 }, + { 0x05280fb7, mmCP_DFY_DATA_0 }, + { 0x28140002, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000fbe, mmCP_DFY_DATA_0 }, + { 0x80000fbe, mmCP_DFY_DATA_0 }, + { 0x80000fc2, mmCP_DFY_DATA_0 }, + { 0x80000fbe, mmCP_DFY_DATA_0 }, + { 0x80000fd1, mmCP_DFY_DATA_0 }, + { 0x80000ff2, mmCP_DFY_DATA_0 }, + { 0x80000ff2, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x18e80039, mmCP_DFY_DATA_0 }, + { 0x52a8003b, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x7d69401a, mmCP_DFY_DATA_0 }, + { 0xc41c0017, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xd140004b, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc414000d, mmCP_DFY_DATA_0 }, + { 0x04180001, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0x7d958004, mmCP_DFY_DATA_0 }, + { 0xcd800035, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3249, mmCP_DFY_DATA_0 }, + { 0x1bfc003e, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd8400074, mmCP_DFY_DATA_0 }, + { 0xc4100019, mmCP_DFY_DATA_0 }, + { 0x7d150005, mmCP_DFY_DATA_0 }, + { 0x25100001, mmCP_DFY_DATA_0 }, + { 0x9500000b, mmCP_DFY_DATA_0 }, + { 0x97c0fffc, mmCP_DFY_DATA_0 }, + { 0xc4180021, mmCP_DFY_DATA_0 }, + { 0x159c0011, mmCP_DFY_DATA_0 }, + { 0x259800ff, mmCP_DFY_DATA_0 }, + { 0x31a00003, mmCP_DFY_DATA_0 }, + { 0x31a40001, mmCP_DFY_DATA_0 }, + { 0x7e25800a, mmCP_DFY_DATA_0 }, + { 0x95c0fff5, mmCP_DFY_DATA_0 }, + { 0x9580fff4, mmCP_DFY_DATA_0 }, + { 0x80000fef, mmCP_DFY_DATA_0 }, + { 0xc411326f, mmCP_DFY_DATA_0 }, + { 0x1d100010, mmCP_DFY_DATA_0 }, + { 0xcd01326f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd8000074, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x04380000, mmCP_DFY_DATA_0 }, + { 0xc430000d, mmCP_DFY_DATA_0 }, + { 0xc8140023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0xc011000f, mmCP_DFY_DATA_0 }, + { 0xc4240004, mmCP_DFY_DATA_0 }, + { 0x33b40003, mmCP_DFY_DATA_0 }, + { 0x97400003, mmCP_DFY_DATA_0 }, + { 0xc0340008, mmCP_DFY_DATA_0 }, + { 0x80000ffe, mmCP_DFY_DATA_0 }, + { 0xc4340035, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x7c908009, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x7d614011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7ca4800a, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x7cb0800a, mmCP_DFY_DATA_0 }, + { 0x282c2002, mmCP_DFY_DATA_0 }, + { 0x208801a8, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0x7cb4800a, mmCP_DFY_DATA_0 }, + { 0xcec00013, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x042c0008, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x20240030, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0x9b800013, mmCP_DFY_DATA_0 }, + { 0xcc400026, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x28340000, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x507c0020, mmCP_DFY_DATA_0 }, + { 0x7d7d401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x557c0020, mmCP_DFY_DATA_0 }, + { 0x28342002, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcd400026, mmCP_DFY_DATA_0 }, + { 0xcfc00026, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0x9a80000e, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a80000b, mmCP_DFY_DATA_0 }, + { 0x8000102f, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x9a800005, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x1cccfe08, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcec0003a, mmCP_DFY_DATA_0 }, + { 0xccc1a2a4, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3249, mmCP_DFY_DATA_0 }, + { 0x1bfc003e, mmCP_DFY_DATA_0 }, + { 0x9bc00007, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x16a80008, mmCP_DFY_DATA_0 }, + { 0xce800009, mmCP_DFY_DATA_0 }, + { 0xc42c005e, mmCP_DFY_DATA_0 }, + { 0x96c00b33, mmCP_DFY_DATA_0 }, + { 0xd840003c, mmCP_DFY_DATA_0 }, + { 0xc4200025, mmCP_DFY_DATA_0 }, + { 0x7da2400f, mmCP_DFY_DATA_0 }, + { 0x7da28002, mmCP_DFY_DATA_0 }, + { 0x7e1ac002, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0x7d2ac002, mmCP_DFY_DATA_0 }, + { 0x3ef40010, mmCP_DFY_DATA_0 }, + { 0x9b40f11d, mmCP_DFY_DATA_0 }, + { 0x04380030, mmCP_DFY_DATA_0 }, + { 0xcf81325e, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xde410000, mmCP_DFY_DATA_0 }, + { 0xdcc10000, mmCP_DFY_DATA_0 }, + { 0xdd010000, mmCP_DFY_DATA_0 }, + { 0xdd410000, mmCP_DFY_DATA_0 }, + { 0xdd810000, mmCP_DFY_DATA_0 }, + { 0xddc10000, mmCP_DFY_DATA_0 }, + { 0xde010000, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x7c024001, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc8100086, mmCP_DFY_DATA_0 }, + { 0x5510003f, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x98c00003, mmCP_DFY_DATA_0 }, + { 0x99000011, mmCP_DFY_DATA_0 }, + { 0x80001075, mmCP_DFY_DATA_0 }, + { 0x9900000c, mmCP_DFY_DATA_0 }, + { 0xc40c0026, mmCP_DFY_DATA_0 }, + { 0xc4100081, mmCP_DFY_DATA_0 }, + { 0xc4140025, mmCP_DFY_DATA_0 }, + { 0x7d15800f, mmCP_DFY_DATA_0 }, + { 0x7d15c002, mmCP_DFY_DATA_0 }, + { 0x7d520002, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x7cde0002, mmCP_DFY_DATA_0 }, + { 0x3e20001a, mmCP_DFY_DATA_0 }, + { 0x9a000009, mmCP_DFY_DATA_0 }, + { 0x040c0030, mmCP_DFY_DATA_0 }, + { 0xccc1325e, mmCP_DFY_DATA_0 }, + { 0x80001071, mmCP_DFY_DATA_0 }, + { 0xd9c00036, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c00b01, mmCP_DFY_DATA_0 }, + { 0x04240001, mmCP_DFY_DATA_0 }, + { 0xdc200000, mmCP_DFY_DATA_0 }, + { 0xdc1c0000, mmCP_DFY_DATA_0 }, + { 0xdc180000, mmCP_DFY_DATA_0 }, + { 0xdc140000, mmCP_DFY_DATA_0 }, + { 0xdc100000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0x96400004, mmCP_DFY_DATA_0 }, + { 0xdc240000, mmCP_DFY_DATA_0 }, + { 0xdc0c0000, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xdc240000, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xcc40003f, mmCP_DFY_DATA_0 }, + { 0xd8c00010, mmCP_DFY_DATA_0 }, + { 0xc4080029, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x18a400e5, mmCP_DFY_DATA_0 }, + { 0x12500009, mmCP_DFY_DATA_0 }, + { 0x248c0008, mmCP_DFY_DATA_0 }, + { 0x94c00006, mmCP_DFY_DATA_0 }, + { 0x200c006d, mmCP_DFY_DATA_0 }, + { 0x7cd0c00a, mmCP_DFY_DATA_0 }, + { 0xccc1326c, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x200c0228, mmCP_DFY_DATA_0 }, + { 0x7cd0c00a, mmCP_DFY_DATA_0 }, + { 0xccc1326c, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0xc40c002a, mmCP_DFY_DATA_0 }, + { 0xc410002b, mmCP_DFY_DATA_0 }, + { 0x18881fe8, mmCP_DFY_DATA_0 }, + { 0x18d4072c, mmCP_DFY_DATA_0 }, + { 0x18cc00d1, mmCP_DFY_DATA_0 }, + { 0x7cd4c00a, mmCP_DFY_DATA_0 }, + { 0x3094000d, mmCP_DFY_DATA_0 }, + { 0x38d80000, mmCP_DFY_DATA_0 }, + { 0x311c0003, mmCP_DFY_DATA_0 }, + { 0x99400006, mmCP_DFY_DATA_0 }, + { 0x30940007, mmCP_DFY_DATA_0 }, + { 0x1620001f, mmCP_DFY_DATA_0 }, + { 0x9940001d, mmCP_DFY_DATA_0 }, + { 0x9a000023, mmCP_DFY_DATA_0 }, + { 0x800010c4, mmCP_DFY_DATA_0 }, + { 0x9580001a, mmCP_DFY_DATA_0 }, + { 0x99c00019, mmCP_DFY_DATA_0 }, + { 0xccc00041, mmCP_DFY_DATA_0 }, + { 0x25140001, mmCP_DFY_DATA_0 }, + { 0xc418002c, mmCP_DFY_DATA_0 }, + { 0x9940000d, mmCP_DFY_DATA_0 }, + { 0x259c007f, mmCP_DFY_DATA_0 }, + { 0x95c00013, mmCP_DFY_DATA_0 }, + { 0x19a00030, mmCP_DFY_DATA_0 }, + { 0xcdc0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xd8400022, mmCP_DFY_DATA_0 }, + { 0xc430000f, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x9a000012, mmCP_DFY_DATA_0 }, + { 0xd8400023, mmCP_DFY_DATA_0 }, + { 0x800010cb, mmCP_DFY_DATA_0 }, + { 0x199c0fe8, mmCP_DFY_DATA_0 }, + { 0xcdc0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xd8400023, mmCP_DFY_DATA_0 }, + { 0xc430000f, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x800010cb, mmCP_DFY_DATA_0 }, + { 0xd8c00010, mmCP_DFY_DATA_0 }, + { 0xd8000022, mmCP_DFY_DATA_0 }, + { 0xd8000023, mmCP_DFY_DATA_0 }, + { 0xc430005e, mmCP_DFY_DATA_0 }, + { 0x97000aac, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0xc434002e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0x2020002c, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0xce01326c, mmCP_DFY_DATA_0 }, + { 0x17780001, mmCP_DFY_DATA_0 }, + { 0x27740001, mmCP_DFY_DATA_0 }, + { 0x07a810d8, mmCP_DFY_DATA_0 }, + { 0xcf400010, mmCP_DFY_DATA_0 }, + { 0xc421326c, mmCP_DFY_DATA_0 }, + { 0x96000001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0x80000bfc, mmCP_DFY_DATA_0 }, + { 0x800012e9, mmCP_DFY_DATA_0 }, + { 0x8000104c, mmCP_DFY_DATA_0 }, + { 0xcc400040, mmCP_DFY_DATA_0 }, + { 0xd8800010, mmCP_DFY_DATA_0 }, + { 0xc4180032, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0x200c007d, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325b, mmCP_DFY_DATA_0 }, + { 0x95000001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x28240007, mmCP_DFY_DATA_0 }, + { 0xde430000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0x24b00008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc40d3249, mmCP_DFY_DATA_0 }, + { 0x18cc003e, mmCP_DFY_DATA_0 }, + { 0x98c00002, mmCP_DFY_DATA_0 }, + { 0xd840003d, mmCP_DFY_DATA_0 }, + { 0x2b304000, mmCP_DFY_DATA_0 }, + { 0xcf01326c, mmCP_DFY_DATA_0 }, + { 0xc431326c, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x192400fd, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x06681110, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0x18ac0024, mmCP_DFY_DATA_0 }, + { 0x19180070, mmCP_DFY_DATA_0 }, + { 0x19100078, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x18f40058, mmCP_DFY_DATA_0 }, + { 0x5978073a, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80001117, mmCP_DFY_DATA_0 }, + { 0x80001118, mmCP_DFY_DATA_0 }, + { 0x80001122, mmCP_DFY_DATA_0 }, + { 0x8000112d, mmCP_DFY_DATA_0 }, + { 0x80001130, mmCP_DFY_DATA_0 }, + { 0x80001133, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000117b, mmCP_DFY_DATA_0 }, + { 0x24ec0f00, mmCP_DFY_DATA_0 }, + { 0x32ec0600, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xc4300006, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x8000117b, mmCP_DFY_DATA_0 }, + { 0x24ec0f00, mmCP_DFY_DATA_0 }, + { 0x32ec0600, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xc4300006, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x8000117b, mmCP_DFY_DATA_0 }, + { 0xc81c001f, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0x80001122, mmCP_DFY_DATA_0 }, + { 0xc81c0020, mmCP_DFY_DATA_0 }, + { 0x55e00020, mmCP_DFY_DATA_0 }, + { 0x80001122, mmCP_DFY_DATA_0 }, + { 0x8c00116b, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc02a0200, mmCP_DFY_DATA_0 }, + { 0x7e8e8009, mmCP_DFY_DATA_0 }, + { 0x22a8003d, mmCP_DFY_DATA_0 }, + { 0x22a80074, mmCP_DFY_DATA_0 }, + { 0x2774001c, mmCP_DFY_DATA_0 }, + { 0x13740014, mmCP_DFY_DATA_0 }, + { 0x7eb6800a, mmCP_DFY_DATA_0 }, + { 0x25ecffff, mmCP_DFY_DATA_0 }, + { 0x55700020, mmCP_DFY_DATA_0 }, + { 0x15f40010, mmCP_DFY_DATA_0 }, + { 0x13740002, mmCP_DFY_DATA_0 }, + { 0x275c001f, mmCP_DFY_DATA_0 }, + { 0x95c00027, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0x7f41c001, mmCP_DFY_DATA_0 }, + { 0x15dc0002, mmCP_DFY_DATA_0 }, + { 0x39e00008, mmCP_DFY_DATA_0 }, + { 0x25dc0007, mmCP_DFY_DATA_0 }, + { 0x7dc1c01e, mmCP_DFY_DATA_0 }, + { 0x05dc0001, mmCP_DFY_DATA_0 }, + { 0x96000004, mmCP_DFY_DATA_0 }, + { 0x05e40008, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001168, mmCP_DFY_DATA_0 }, + { 0x7dc2001e, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x05e40008, mmCP_DFY_DATA_0 }, + { 0x7e62000e, mmCP_DFY_DATA_0 }, + { 0x9a000004, mmCP_DFY_DATA_0 }, + { 0x7da58001, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001165, mmCP_DFY_DATA_0 }, + { 0x7dc2001e, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x7e1a0001, mmCP_DFY_DATA_0 }, + { 0x05cc0008, mmCP_DFY_DATA_0 }, + { 0x7e0d000e, mmCP_DFY_DATA_0 }, + { 0x95000007, mmCP_DFY_DATA_0 }, + { 0x7e02401e, mmCP_DFY_DATA_0 }, + { 0x06640001, mmCP_DFY_DATA_0 }, + { 0x06640008, mmCP_DFY_DATA_0 }, + { 0x05d80008, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001168, mmCP_DFY_DATA_0 }, + { 0x7dc2401e, mmCP_DFY_DATA_0 }, + { 0x06640001, mmCP_DFY_DATA_0 }, + { 0x7da58001, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x05e00008, mmCP_DFY_DATA_0 }, + { 0x7da2000c, mmCP_DFY_DATA_0 }, + { 0x9600ffe6, mmCP_DFY_DATA_0 }, + { 0x17640002, mmCP_DFY_DATA_0 }, + { 0x8c00116e, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xc4200006, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x8c00116b, mmCP_DFY_DATA_0 }, + { 0xc420000e, mmCP_DFY_DATA_0 }, + { 0x2a200001, mmCP_DFY_DATA_0 }, + { 0xce00001a, mmCP_DFY_DATA_0 }, + { 0xce81c078, mmCP_DFY_DATA_0 }, + { 0xcec1c080, mmCP_DFY_DATA_0 }, + { 0xcc01c081, mmCP_DFY_DATA_0 }, + { 0xcd41c082, mmCP_DFY_DATA_0 }, + { 0xcf01c083, mmCP_DFY_DATA_0 }, + { 0x12640002, mmCP_DFY_DATA_0 }, + { 0x22640435, mmCP_DFY_DATA_0 }, + { 0xce41c084, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x0528117e, mmCP_DFY_DATA_0 }, + { 0x312c0003, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x80001185, mmCP_DFY_DATA_0 }, + { 0x80001182, mmCP_DFY_DATA_0 }, + { 0x80001182, mmCP_DFY_DATA_0 }, + { 0xc4300012, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0x9ac0000c, mmCP_DFY_DATA_0 }, + { 0xc03a0400, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x15980008, mmCP_DFY_DATA_0 }, + { 0x1198001c, mmCP_DFY_DATA_0 }, + { 0x7d81c00a, mmCP_DFY_DATA_0 }, + { 0xcdc130b7, mmCP_DFY_DATA_0 }, + { 0xcf8130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x04240008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0xc41c0049, mmCP_DFY_DATA_0 }, + { 0x19a000e8, mmCP_DFY_DATA_0 }, + { 0x29a80008, mmCP_DFY_DATA_0 }, + { 0x7de2c00c, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xc421325e, mmCP_DFY_DATA_0 }, + { 0x26200010, mmCP_DFY_DATA_0 }, + { 0xc415326d, mmCP_DFY_DATA_0 }, + { 0x9a000006, mmCP_DFY_DATA_0 }, + { 0xc420007d, mmCP_DFY_DATA_0 }, + { 0x96000004, mmCP_DFY_DATA_0 }, + { 0x96c00003, mmCP_DFY_DATA_0 }, + { 0xce40003e, mmCP_DFY_DATA_0 }, + { 0x800011a3, mmCP_DFY_DATA_0 }, + { 0x7d654001, mmCP_DFY_DATA_0 }, + { 0xcd41326d, mmCP_DFY_DATA_0 }, + { 0x7c020001, mmCP_DFY_DATA_0 }, + { 0x96000005, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0xc4240081, mmCP_DFY_DATA_0 }, + { 0xc4140025, mmCP_DFY_DATA_0 }, + { 0x800011b6, mmCP_DFY_DATA_0 }, + { 0xc4253279, mmCP_DFY_DATA_0 }, + { 0xc415326d, mmCP_DFY_DATA_0 }, + { 0xc431326c, mmCP_DFY_DATA_0 }, + { 0x2730003f, mmCP_DFY_DATA_0 }, + { 0x3b380006, mmCP_DFY_DATA_0 }, + { 0x97800004, mmCP_DFY_DATA_0 }, + { 0x3f38000b, mmCP_DFY_DATA_0 }, + { 0x9b800004, mmCP_DFY_DATA_0 }, + { 0x800011b4, mmCP_DFY_DATA_0 }, + { 0x04300006, mmCP_DFY_DATA_0 }, + { 0x800011b4, mmCP_DFY_DATA_0 }, + { 0x0430000b, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x7fb10004, mmCP_DFY_DATA_0 }, + { 0x7e57000f, mmCP_DFY_DATA_0 }, + { 0x7e578002, mmCP_DFY_DATA_0 }, + { 0x7d67c002, mmCP_DFY_DATA_0 }, + { 0x0be40001, mmCP_DFY_DATA_0 }, + { 0x97000002, mmCP_DFY_DATA_0 }, + { 0x7d3a4002, mmCP_DFY_DATA_0 }, + { 0x202c002c, mmCP_DFY_DATA_0 }, + { 0xc421325e, mmCP_DFY_DATA_0 }, + { 0x04280020, mmCP_DFY_DATA_0 }, + { 0xcec1326c, mmCP_DFY_DATA_0 }, + { 0x26200010, mmCP_DFY_DATA_0 }, + { 0x3e640010, mmCP_DFY_DATA_0 }, + { 0x96000003, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0xce81325e, mmCP_DFY_DATA_0 }, + { 0xc4300028, mmCP_DFY_DATA_0 }, + { 0xc434002e, mmCP_DFY_DATA_0 }, + { 0x17780001, mmCP_DFY_DATA_0 }, + { 0x27740001, mmCP_DFY_DATA_0 }, + { 0x07a811cf, mmCP_DFY_DATA_0 }, + { 0x9b00feb8, mmCP_DFY_DATA_0 }, + { 0xcf400010, mmCP_DFY_DATA_0 }, + { 0xc414005e, mmCP_DFY_DATA_0 }, + { 0x954009a7, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0x80000bfc, mmCP_DFY_DATA_0 }, + { 0x800012e9, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0xccc1c07c, mmCP_DFY_DATA_0 }, + { 0xcc41c07d, mmCP_DFY_DATA_0 }, + { 0xcc41c08c, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xcc41c079, mmCP_DFY_DATA_0 }, + { 0xcd01c07e, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x18f0012f, mmCP_DFY_DATA_0 }, + { 0x18f40612, mmCP_DFY_DATA_0 }, + { 0x18cc00c1, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x7cf7400a, mmCP_DFY_DATA_0 }, + { 0x39600004, mmCP_DFY_DATA_0 }, + { 0x9a000002, mmCP_DFY_DATA_0 }, + { 0xc0140004, mmCP_DFY_DATA_0 }, + { 0x11600001, mmCP_DFY_DATA_0 }, + { 0x18fc003e, mmCP_DFY_DATA_0 }, + { 0x9740001c, mmCP_DFY_DATA_0 }, + { 0xcf400041, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0x97c00003, mmCP_DFY_DATA_0 }, + { 0x166c001f, mmCP_DFY_DATA_0 }, + { 0x800011ee, mmCP_DFY_DATA_0 }, + { 0x1a6c003e, mmCP_DFY_DATA_0 }, + { 0x96c00006, mmCP_DFY_DATA_0 }, + { 0x04200002, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x800011e8, mmCP_DFY_DATA_0 }, + { 0xc428002c, mmCP_DFY_DATA_0 }, + { 0x96800010, mmCP_DFY_DATA_0 }, + { 0x26ac007f, mmCP_DFY_DATA_0 }, + { 0xcec0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x1ab00030, mmCP_DFY_DATA_0 }, + { 0x1aac0fe8, mmCP_DFY_DATA_0 }, + { 0xc434000f, mmCP_DFY_DATA_0 }, + { 0x9b40ffff, mmCP_DFY_DATA_0 }, + { 0x97000008, mmCP_DFY_DATA_0 }, + { 0xcec0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc434000f, mmCP_DFY_DATA_0 }, + { 0x9b40ffff, mmCP_DFY_DATA_0 }, + { 0x80001205, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0x166c001f, mmCP_DFY_DATA_0 }, + { 0x11600001, mmCP_DFY_DATA_0 }, + { 0x9ac0fffa, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8000033, mmCP_DFY_DATA_0 }, + { 0xc438000b, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0001, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd841c07f, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x1bfc0078, mmCP_DFY_DATA_0 }, + { 0x7ffbc00c, mmCP_DFY_DATA_0 }, + { 0x97c0fffd, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc03a2800, mmCP_DFY_DATA_0 }, + { 0xcf81c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04380040, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380060, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x17fc001f, mmCP_DFY_DATA_0 }, + { 0x04380010, mmCP_DFY_DATA_0 }, + { 0x9bc0fffa, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd801c07f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0xcfc00078, mmCP_DFY_DATA_0 }, + { 0xd8000034, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc03ae000, mmCP_DFY_DATA_0 }, + { 0xcf81c200, mmCP_DFY_DATA_0 }, + { 0xc03a0800, mmCP_DFY_DATA_0 }, + { 0xcf81c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04380040, mmCP_DFY_DATA_0 }, + { 0xcf80001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x17fc001f, mmCP_DFY_DATA_0 }, + { 0x04380010, mmCP_DFY_DATA_0 }, + { 0x9bc0fffa, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc03ae000, mmCP_DFY_DATA_0 }, + { 0xcf81c200, mmCP_DFY_DATA_0 }, + { 0xc03a4000, mmCP_DFY_DATA_0 }, + { 0xcf81c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04380002, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x17fc001f, mmCP_DFY_DATA_0 }, + { 0x04380010, mmCP_DFY_DATA_0 }, + { 0x9bc0fffa, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x30d00002, mmCP_DFY_DATA_0 }, + { 0x99000052, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x9640090f, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xc428000e, mmCP_DFY_DATA_0 }, + { 0x1514001f, mmCP_DFY_DATA_0 }, + { 0x19180038, mmCP_DFY_DATA_0 }, + { 0x2aa80008, mmCP_DFY_DATA_0 }, + { 0x99400030, mmCP_DFY_DATA_0 }, + { 0x30dc0001, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0x99c0000a, mmCP_DFY_DATA_0 }, + { 0xc42d324e, mmCP_DFY_DATA_0 }, + { 0xc431324d, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc435324f, mmCP_DFY_DATA_0 }, + { 0xc4293256, mmCP_DFY_DATA_0 }, + { 0x1ab0c006, mmCP_DFY_DATA_0 }, + { 0x52ec0008, mmCP_DFY_DATA_0 }, + { 0x8000127f, mmCP_DFY_DATA_0 }, + { 0xc42d3258, mmCP_DFY_DATA_0 }, + { 0xc4313257, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc4353259, mmCP_DFY_DATA_0 }, + { 0xc429325a, mmCP_DFY_DATA_0 }, + { 0x1ab0c012, mmCP_DFY_DATA_0 }, + { 0x07740001, mmCP_DFY_DATA_0 }, + { 0x04240002, mmCP_DFY_DATA_0 }, + { 0x26a0003f, mmCP_DFY_DATA_0 }, + { 0x7e624004, mmCP_DFY_DATA_0 }, + { 0x7f67800f, mmCP_DFY_DATA_0 }, + { 0x97800002, mmCP_DFY_DATA_0 }, + { 0x04340000, mmCP_DFY_DATA_0 }, + { 0x53740002, mmCP_DFY_DATA_0 }, + { 0x7ef6c011, mmCP_DFY_DATA_0 }, + { 0x1ab42010, mmCP_DFY_DATA_0 }, + { 0x16a8000c, mmCP_DFY_DATA_0 }, + { 0x26a80800, mmCP_DFY_DATA_0 }, + { 0x2b740000, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0x7f6b400a, mmCP_DFY_DATA_0 }, + { 0xcf40001c, mmCP_DFY_DATA_0 }, + { 0xd2c0001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc438000f, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xc4100011, mmCP_DFY_DATA_0 }, + { 0x1514001f, mmCP_DFY_DATA_0 }, + { 0x99400006, mmCP_DFY_DATA_0 }, + { 0x9980000a, mmCP_DFY_DATA_0 }, + { 0x8c0012e1, mmCP_DFY_DATA_0 }, + { 0xc40c0007, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0x80001267, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x964008d7, mmCP_DFY_DATA_0 }, + { 0xd9800036, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc42c001d, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0xc431325a, mmCP_DFY_DATA_0 }, + { 0x1b300677, mmCP_DFY_DATA_0 }, + { 0x11dc000c, mmCP_DFY_DATA_0 }, + { 0x800012aa, mmCP_DFY_DATA_0 }, + { 0xc4313256, mmCP_DFY_DATA_0 }, + { 0x1b34060b, mmCP_DFY_DATA_0 }, + { 0x1b300077, mmCP_DFY_DATA_0 }, + { 0x7f37000a, mmCP_DFY_DATA_0 }, + { 0x13300017, mmCP_DFY_DATA_0 }, + { 0x04340100, mmCP_DFY_DATA_0 }, + { 0x26ec00ff, mmCP_DFY_DATA_0 }, + { 0xc03a8002, mmCP_DFY_DATA_0 }, + { 0x7ef6c00a, mmCP_DFY_DATA_0 }, + { 0x7edec00a, mmCP_DFY_DATA_0 }, + { 0x7f3b000a, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0xcec1325b, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xc4140032, mmCP_DFY_DATA_0 }, + { 0xc410001d, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x1858003f, mmCP_DFY_DATA_0 }, + { 0x251000ff, mmCP_DFY_DATA_0 }, + { 0x99800007, mmCP_DFY_DATA_0 }, + { 0x7d0cc00a, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x18d0006c, mmCP_DFY_DATA_0 }, + { 0x18d407f0, mmCP_DFY_DATA_0 }, + { 0x9900000e, mmCP_DFY_DATA_0 }, + { 0x04100002, mmCP_DFY_DATA_0 }, + { 0xc4193256, mmCP_DFY_DATA_0 }, + { 0xc41d324f, mmCP_DFY_DATA_0 }, + { 0x2598003f, mmCP_DFY_DATA_0 }, + { 0x7d190004, mmCP_DFY_DATA_0 }, + { 0x7d5d4001, mmCP_DFY_DATA_0 }, + { 0x7d52000f, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0xcd41324f, mmCP_DFY_DATA_0 }, + { 0x800012d8, mmCP_DFY_DATA_0 }, + { 0x7d514002, mmCP_DFY_DATA_0 }, + { 0xcd41324f, mmCP_DFY_DATA_0 }, + { 0x800012d8, mmCP_DFY_DATA_0 }, + { 0xc4193259, mmCP_DFY_DATA_0 }, + { 0xc41d325a, mmCP_DFY_DATA_0 }, + { 0x7d958001, mmCP_DFY_DATA_0 }, + { 0x7dd5c002, mmCP_DFY_DATA_0 }, + { 0xcd813259, mmCP_DFY_DATA_0 }, + { 0xcdc1325a, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x1ccc001e, mmCP_DFY_DATA_0 }, + { 0xccc1325b, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x94c00001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c0021, mmCP_DFY_DATA_0 }, + { 0xc4340028, mmCP_DFY_DATA_0 }, + { 0x14f00010, mmCP_DFY_DATA_0 }, + { 0xc4380030, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x9b000004, mmCP_DFY_DATA_0 }, + { 0x9b40000c, mmCP_DFY_DATA_0 }, + { 0x9b80000f, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x17300001, mmCP_DFY_DATA_0 }, + { 0x9b000005, mmCP_DFY_DATA_0 }, + { 0xccc00037, mmCP_DFY_DATA_0 }, + { 0x8c000190, mmCP_DFY_DATA_0 }, + { 0xd8000032, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8000028, mmCP_DFY_DATA_0 }, + { 0xd800002b, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd980003f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd9c0003f, mmCP_DFY_DATA_0 }, + { 0x80001082, mmCP_DFY_DATA_0 }, + { 0xd9800040, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0xd9c00040, mmCP_DFY_DATA_0 }, + { 0x800010de, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0x33f80003, mmCP_DFY_DATA_0 }, + { 0x97800051, mmCP_DFY_DATA_0 }, + { 0xcc80003b, mmCP_DFY_DATA_0 }, + { 0x24b00008, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x18a800e5, mmCP_DFY_DATA_0 }, + { 0x1d980008, mmCP_DFY_DATA_0 }, + { 0x12a80008, mmCP_DFY_DATA_0 }, + { 0x7da9800a, mmCP_DFY_DATA_0 }, + { 0x29980008, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc4353249, mmCP_DFY_DATA_0 }, + { 0x1b74003e, mmCP_DFY_DATA_0 }, + { 0x9b400002, mmCP_DFY_DATA_0 }, + { 0xd840003d, mmCP_DFY_DATA_0 }, + { 0x2b304000, mmCP_DFY_DATA_0 }, + { 0xcf01326c, mmCP_DFY_DATA_0 }, + { 0xc431326c, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x1b4c00f8, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x50700020, mmCP_DFY_DATA_0 }, + { 0x04e81324, mmCP_DFY_DATA_0 }, + { 0x18ac0024, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x50600020, mmCP_DFY_DATA_0 }, + { 0xcc400078, mmCP_DFY_DATA_0 }, + { 0x30e40004, mmCP_DFY_DATA_0 }, + { 0x9a400007, mmCP_DFY_DATA_0 }, + { 0x7d71401a, mmCP_DFY_DATA_0 }, + { 0x596401fc, mmCP_DFY_DATA_0 }, + { 0x12640009, mmCP_DFY_DATA_0 }, + { 0x1b74008d, mmCP_DFY_DATA_0 }, + { 0x7e76400a, mmCP_DFY_DATA_0 }, + { 0x2a640000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x8000132c, mmCP_DFY_DATA_0 }, + { 0x8000133b, mmCP_DFY_DATA_0 }, + { 0x80001344, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc42530b5, mmCP_DFY_DATA_0 }, + { 0x1a68003a, mmCP_DFY_DATA_0 }, + { 0x9a80fffe, mmCP_DFY_DATA_0 }, + { 0x2024003a, mmCP_DFY_DATA_0 }, + { 0xc418000e, mmCP_DFY_DATA_0 }, + { 0x25980700, mmCP_DFY_DATA_0 }, + { 0x11980014, mmCP_DFY_DATA_0 }, + { 0x7d19000a, mmCP_DFY_DATA_0 }, + { 0xcd0130b7, mmCP_DFY_DATA_0 }, + { 0xce4130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xce40001c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc4240011, mmCP_DFY_DATA_0 }, + { 0x7de6800f, mmCP_DFY_DATA_0 }, + { 0x9a80ffea, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0xce40001c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc428000f, mmCP_DFY_DATA_0 }, + { 0x9a80ffff, mmCP_DFY_DATA_0 }, + { 0xc8240011, mmCP_DFY_DATA_0 }, + { 0x7de1c01a, mmCP_DFY_DATA_0 }, + { 0x7de6800f, mmCP_DFY_DATA_0 }, + { 0x9a80ffe0, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x8c00104f, mmCP_DFY_DATA_0 }, + { 0x28182002, mmCP_DFY_DATA_0 }, + { 0xc430000d, mmCP_DFY_DATA_0 }, + { 0xc4340035, mmCP_DFY_DATA_0 }, + { 0xcd800013, mmCP_DFY_DATA_0 }, + { 0xc8140023, mmCP_DFY_DATA_0 }, + { 0xc4180081, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0xc4240004, mmCP_DFY_DATA_0 }, + { 0x11a00002, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x7d614011, mmCP_DFY_DATA_0 }, + { 0xc4100026, mmCP_DFY_DATA_0 }, + { 0x05980008, mmCP_DFY_DATA_0 }, + { 0x7ca4800a, mmCP_DFY_DATA_0 }, + { 0x7d1a0002, mmCP_DFY_DATA_0 }, + { 0x7cb0800a, mmCP_DFY_DATA_0 }, + { 0x3e280008, mmCP_DFY_DATA_0 }, + { 0x7cb4800a, mmCP_DFY_DATA_0 }, + { 0xc4300027, mmCP_DFY_DATA_0 }, + { 0x042c0008, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xcf000024, mmCP_DFY_DATA_0 }, + { 0x20240030, mmCP_DFY_DATA_0 }, + { 0x7ca48001, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x1b4c00f8, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0xcc400026, mmCP_DFY_DATA_0 }, + { 0x28340000, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x507c0020, mmCP_DFY_DATA_0 }, + { 0x30e40004, mmCP_DFY_DATA_0 }, + { 0x9a400005, mmCP_DFY_DATA_0 }, + { 0x7d7d401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x557c0020, mmCP_DFY_DATA_0 }, + { 0x28342002, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcd400026, mmCP_DFY_DATA_0 }, + { 0xcfc00026, mmCP_DFY_DATA_0 }, + { 0xd4400026, mmCP_DFY_DATA_0 }, + { 0xcc000026, mmCP_DFY_DATA_0 }, + { 0x9a800005, mmCP_DFY_DATA_0 }, + { 0x32280000, mmCP_DFY_DATA_0 }, + { 0x9a800002, mmCP_DFY_DATA_0 }, + { 0x9a000000, mmCP_DFY_DATA_0 }, + { 0x7c018001, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0x04380028, mmCP_DFY_DATA_0 }, + { 0xcec0003a, mmCP_DFY_DATA_0 }, + { 0xcf81a2a4, mmCP_DFY_DATA_0 }, + { 0x80001037, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc40c005e, mmCP_DFY_DATA_0 }, + { 0x94c007eb, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50500020, mmCP_DFY_DATA_0 }, + { 0x7d0d001a, mmCP_DFY_DATA_0 }, + { 0xd1000072, mmCP_DFY_DATA_0 }, + { 0xc8100072, mmCP_DFY_DATA_0 }, + { 0x591c01fc, mmCP_DFY_DATA_0 }, + { 0x11dc0009, mmCP_DFY_DATA_0 }, + { 0x45140210, mmCP_DFY_DATA_0 }, + { 0x595801fc, mmCP_DFY_DATA_0 }, + { 0x11980009, mmCP_DFY_DATA_0 }, + { 0x29dc0000, mmCP_DFY_DATA_0 }, + { 0xcdc0001c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4200011, mmCP_DFY_DATA_0 }, + { 0x1624001f, mmCP_DFY_DATA_0 }, + { 0x96400069, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xce013249, mmCP_DFY_DATA_0 }, + { 0x1a307fe8, mmCP_DFY_DATA_0 }, + { 0xcf00000a, mmCP_DFY_DATA_0 }, + { 0x23304076, mmCP_DFY_DATA_0 }, + { 0xd1000001, mmCP_DFY_DATA_0 }, + { 0xcf000001, mmCP_DFY_DATA_0 }, + { 0xc41d3254, mmCP_DFY_DATA_0 }, + { 0xc4253256, mmCP_DFY_DATA_0 }, + { 0x18cc00e8, mmCP_DFY_DATA_0 }, + { 0x10cc0015, mmCP_DFY_DATA_0 }, + { 0x4514020c, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc4200011, mmCP_DFY_DATA_0 }, + { 0xce013248, mmCP_DFY_DATA_0 }, + { 0x1a2001e8, mmCP_DFY_DATA_0 }, + { 0x12200014, mmCP_DFY_DATA_0 }, + { 0x2a204001, mmCP_DFY_DATA_0 }, + { 0xce000013, mmCP_DFY_DATA_0 }, + { 0x1a64003c, mmCP_DFY_DATA_0 }, + { 0x1264001f, mmCP_DFY_DATA_0 }, + { 0x11dc0009, mmCP_DFY_DATA_0 }, + { 0x15dc000b, mmCP_DFY_DATA_0 }, + { 0x7dcdc00a, mmCP_DFY_DATA_0 }, + { 0x7e5dc00a, mmCP_DFY_DATA_0 }, + { 0xcdc00100, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xd8400010, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcf00000d, mmCP_DFY_DATA_0 }, + { 0xcf00000a, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x04340022, mmCP_DFY_DATA_0 }, + { 0x07740001, mmCP_DFY_DATA_0 }, + { 0x04300010, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0xd4412e01, mmCP_DFY_DATA_0 }, + { 0x0434001e, mmCP_DFY_DATA_0 }, + { 0xdf430000, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xdf030000, mmCP_DFY_DATA_0 }, + { 0xd4412e40, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc41c030, mmCP_DFY_DATA_0 }, + { 0xcc41c031, mmCP_DFY_DATA_0 }, + { 0x248dfffe, mmCP_DFY_DATA_0 }, + { 0xccc12e00, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xcc812e00, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xd8000010, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x45140248, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc8200011, mmCP_DFY_DATA_0 }, + { 0xce013257, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xce013258, mmCP_DFY_DATA_0 }, + { 0x0434000c, mmCP_DFY_DATA_0 }, + { 0xdb000024, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x45540008, mmCP_DFY_DATA_0 }, + { 0xd140001e, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc418000f, mmCP_DFY_DATA_0 }, + { 0x9980ffff, mmCP_DFY_DATA_0 }, + { 0xc8200011, mmCP_DFY_DATA_0 }, + { 0xce013259, mmCP_DFY_DATA_0 }, + { 0x56200020, mmCP_DFY_DATA_0 }, + { 0xc0337fff, mmCP_DFY_DATA_0 }, + { 0x7f220009, mmCP_DFY_DATA_0 }, + { 0xce01325a, mmCP_DFY_DATA_0 }, + { 0x55300020, mmCP_DFY_DATA_0 }, + { 0x7d01c001, mmCP_DFY_DATA_0 }, + { 0x042c01d0, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x06ec0004, mmCP_DFY_DATA_0 }, + { 0x7f01c001, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0x041c0002, mmCP_DFY_DATA_0 }, + { 0x042c01c8, mmCP_DFY_DATA_0 }, + { 0x8c000d61, mmCP_DFY_DATA_0 }, + { 0xc4380012, mmCP_DFY_DATA_0 }, + { 0x9b80ffff, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x50500020, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0x7cd0c01a, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xd0c00072, mmCP_DFY_DATA_0 }, + { 0xc8240072, mmCP_DFY_DATA_0 }, + { 0xd240001e, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x19682011, mmCP_DFY_DATA_0 }, + { 0x5a6c01fc, mmCP_DFY_DATA_0 }, + { 0x12ec0009, mmCP_DFY_DATA_0 }, + { 0x7eeac00a, mmCP_DFY_DATA_0 }, + { 0x2aec0000, mmCP_DFY_DATA_0 }, + { 0xcec0001c, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc430000f, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0xc4180011, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x99800007, mmCP_DFY_DATA_0 }, + { 0xdf830000, mmCP_DFY_DATA_0 }, + { 0xcfa0000c, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xd8000012, mmCP_DFY_DATA_0 }, + { 0xc43c0008, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd8400012, mmCP_DFY_DATA_0 }, + { 0xc43c0008, mmCP_DFY_DATA_0 }, + { 0x97c0ffff, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4380007, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x17b80001, mmCP_DFY_DATA_0 }, + { 0x18d40038, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x9b800004, mmCP_DFY_DATA_0 }, + { 0xd8400029, mmCP_DFY_DATA_0 }, + { 0xc414005e, mmCP_DFY_DATA_0 }, + { 0x9540073d, mmCP_DFY_DATA_0 }, + { 0x18c80066, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x30880001, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x94800008, mmCP_DFY_DATA_0 }, + { 0x8c00187c, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc42c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd910000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x7d410001, mmCP_DFY_DATA_0 }, + { 0x043c0000, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0x04240001, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x4220000c, mmCP_DFY_DATA_0 }, + { 0x0a640001, mmCP_DFY_DATA_0 }, + { 0xcc000078, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x24e80007, mmCP_DFY_DATA_0 }, + { 0x24ec0010, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x9ac00006, mmCP_DFY_DATA_0 }, + { 0xc42c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc5310000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x80001465, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xd1000072, mmCP_DFY_DATA_0 }, + { 0xc82c0072, mmCP_DFY_DATA_0 }, + { 0xd2c0001e, mmCP_DFY_DATA_0 }, + { 0x18f02011, mmCP_DFY_DATA_0 }, + { 0x5aec01fc, mmCP_DFY_DATA_0 }, + { 0x12ec0009, mmCP_DFY_DATA_0 }, + { 0x7ef2c00a, mmCP_DFY_DATA_0 }, + { 0x2aec0000, mmCP_DFY_DATA_0 }, + { 0xcec0001c, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0xc42c000f, mmCP_DFY_DATA_0 }, + { 0x9ac0ffff, mmCP_DFY_DATA_0 }, + { 0xc4300011, mmCP_DFY_DATA_0 }, + { 0x96800012, mmCP_DFY_DATA_0 }, + { 0x12a80001, mmCP_DFY_DATA_0 }, + { 0x0aa80001, mmCP_DFY_DATA_0 }, + { 0x06a8146a, mmCP_DFY_DATA_0 }, + { 0x7f1f0009, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x7f1b400f, mmCP_DFY_DATA_0 }, + { 0x80001478, mmCP_DFY_DATA_0 }, + { 0x7f1b400e, mmCP_DFY_DATA_0 }, + { 0x80001478, mmCP_DFY_DATA_0 }, + { 0x7f1b400c, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f1b400d, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f1b400f, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f1b400e, mmCP_DFY_DATA_0 }, + { 0x8000147a, mmCP_DFY_DATA_0 }, + { 0x7f334002, mmCP_DFY_DATA_0 }, + { 0x97400014, mmCP_DFY_DATA_0 }, + { 0x8000147b, mmCP_DFY_DATA_0 }, + { 0x9b400012, mmCP_DFY_DATA_0 }, + { 0x9b800005, mmCP_DFY_DATA_0 }, + { 0x9bc0001f, mmCP_DFY_DATA_0 }, + { 0x7e024001, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x8000144a, mmCP_DFY_DATA_0 }, + { 0xc40c0032, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d325b, mmCP_DFY_DATA_0 }, + { 0x1bb81ff0, mmCP_DFY_DATA_0 }, + { 0x7fbfc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0xc411325d, mmCP_DFY_DATA_0 }, + { 0x251001ef, mmCP_DFY_DATA_0 }, + { 0xcd01325d, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x94800007, mmCP_DFY_DATA_0 }, + { 0x8c00187c, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xc42c0004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcd910000, mmCP_DFY_DATA_0 }, + { 0xcec00008, mmCP_DFY_DATA_0 }, + { 0x9b800003, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0xc40c0032, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc40d325b, mmCP_DFY_DATA_0 }, + { 0x800012c2, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xc438001d, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0x13f4000c, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0xc43d3256, mmCP_DFY_DATA_0 }, + { 0x1bf0060b, mmCP_DFY_DATA_0 }, + { 0x1bfc0077, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x800014a9, mmCP_DFY_DATA_0 }, + { 0xc43d325a, mmCP_DFY_DATA_0 }, + { 0x1bfc0677, mmCP_DFY_DATA_0 }, + { 0x04300100, mmCP_DFY_DATA_0 }, + { 0x1bb81ff0, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xc0328007, mmCP_DFY_DATA_0 }, + { 0x7fb7800a, mmCP_DFY_DATA_0 }, + { 0x13fc0017, mmCP_DFY_DATA_0 }, + { 0x7ff3c00a, mmCP_DFY_DATA_0 }, + { 0x7ffbc00a, mmCP_DFY_DATA_0 }, + { 0xcfc1325b, mmCP_DFY_DATA_0 }, + { 0xc03a0002, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xcf8130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0x043c0000, mmCP_DFY_DATA_0 }, + { 0xc414000e, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7dd9c01a, mmCP_DFY_DATA_0 }, + { 0x45dc0390, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04183000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0x1b380057, mmCP_DFY_DATA_0 }, + { 0x1b340213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0xd1c00025, mmCP_DFY_DATA_0 }, + { 0xcc800026, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0x7c424001, mmCP_DFY_DATA_0 }, + { 0xce400026, mmCP_DFY_DATA_0 }, + { 0x7c428001, mmCP_DFY_DATA_0 }, + { 0xce800026, mmCP_DFY_DATA_0 }, + { 0x7c42c001, mmCP_DFY_DATA_0 }, + { 0xcec00026, mmCP_DFY_DATA_0 }, + { 0x7c430001, mmCP_DFY_DATA_0 }, + { 0xcf000026, mmCP_DFY_DATA_0 }, + { 0x7c434001, mmCP_DFY_DATA_0 }, + { 0xcf400026, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0xcf800026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0x04182000, mmCP_DFY_DATA_0 }, + { 0xcd813267, mmCP_DFY_DATA_0 }, + { 0xd840004f, mmCP_DFY_DATA_0 }, + { 0x1a0800fd, mmCP_DFY_DATA_0 }, + { 0x109c000a, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x7dd9c00a, mmCP_DFY_DATA_0 }, + { 0xcdc13265, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0xce080228, mmCP_DFY_DATA_0 }, + { 0x9880000e, mmCP_DFY_DATA_0 }, + { 0xce480250, mmCP_DFY_DATA_0 }, + { 0xce880258, mmCP_DFY_DATA_0 }, + { 0xd8080230, mmCP_DFY_DATA_0 }, + { 0xd8080238, mmCP_DFY_DATA_0 }, + { 0xd8080240, mmCP_DFY_DATA_0 }, + { 0xd8080248, mmCP_DFY_DATA_0 }, + { 0xd8080268, mmCP_DFY_DATA_0 }, + { 0xd8080270, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x97c0ec75, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x041c0010, mmCP_DFY_DATA_0 }, + { 0x26180001, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x16200001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x99c0fffb, mmCP_DFY_DATA_0 }, + { 0xccc80230, mmCP_DFY_DATA_0 }, + { 0xd8080238, mmCP_DFY_DATA_0 }, + { 0xd8080240, mmCP_DFY_DATA_0 }, + { 0xd8080248, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0xce480250, mmCP_DFY_DATA_0 }, + { 0xce880258, mmCP_DFY_DATA_0 }, + { 0x52a80020, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x041c0020, mmCP_DFY_DATA_0 }, + { 0x66580001, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x56640001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x99c0fffb, mmCP_DFY_DATA_0 }, + { 0xccc80260, mmCP_DFY_DATA_0 }, + { 0xd8080268, mmCP_DFY_DATA_0 }, + { 0xd8080270, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0xcec80288, mmCP_DFY_DATA_0 }, + { 0xcf080290, mmCP_DFY_DATA_0 }, + { 0xcec80298, mmCP_DFY_DATA_0 }, + { 0xcf0802a0, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x041c0010, mmCP_DFY_DATA_0 }, + { 0xcf4802a8, mmCP_DFY_DATA_0 }, + { 0x27580001, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x17740001, mmCP_DFY_DATA_0 }, + { 0x95800002, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x99c0fffb, mmCP_DFY_DATA_0 }, + { 0xccc802b0, mmCP_DFY_DATA_0 }, + { 0xd80802b8, mmCP_DFY_DATA_0 }, + { 0x178c000b, mmCP_DFY_DATA_0 }, + { 0x27b8003f, mmCP_DFY_DATA_0 }, + { 0x7cf8c001, mmCP_DFY_DATA_0 }, + { 0xcf8802c0, mmCP_DFY_DATA_0 }, + { 0xccc802c8, mmCP_DFY_DATA_0 }, + { 0xcf8802d0, mmCP_DFY_DATA_0 }, + { 0xcf8802d8, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x25b8ffff, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0xc48f0238, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x24cc000f, mmCP_DFY_DATA_0 }, + { 0x7cd2800c, mmCP_DFY_DATA_0 }, + { 0x9a80000b, mmCP_DFY_DATA_0 }, + { 0xc5230309, mmCP_DFY_DATA_0 }, + { 0x2620ffff, mmCP_DFY_DATA_0 }, + { 0x7e3a400c, mmCP_DFY_DATA_0 }, + { 0x9a400004, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x80001539, mmCP_DFY_DATA_0 }, + { 0xcd08034b, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x98c00004, mmCP_DFY_DATA_0 }, + { 0xcd880353, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0xc49b0353, mmCP_DFY_DATA_0 }, + { 0xc4930238, mmCP_DFY_DATA_0 }, + { 0xc48f0228, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x7cd14005, mmCP_DFY_DATA_0 }, + { 0x25540001, mmCP_DFY_DATA_0 }, + { 0x99400004, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x8000154f, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0xcd080238, mmCP_DFY_DATA_0 }, + { 0xcd08034b, mmCP_DFY_DATA_0 }, + { 0x08cc0001, mmCP_DFY_DATA_0 }, + { 0x2598ffff, mmCP_DFY_DATA_0 }, + { 0x3d200008, mmCP_DFY_DATA_0 }, + { 0xccc80230, mmCP_DFY_DATA_0 }, + { 0xcd900309, mmCP_DFY_DATA_0 }, + { 0xd8100319, mmCP_DFY_DATA_0 }, + { 0x04340801, mmCP_DFY_DATA_0 }, + { 0x2198003f, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcd910ce7, mmCP_DFY_DATA_0 }, + { 0xc4190ce6, mmCP_DFY_DATA_0 }, + { 0x7d918005, mmCP_DFY_DATA_0 }, + { 0x25980001, mmCP_DFY_DATA_0 }, + { 0x9580fffd, mmCP_DFY_DATA_0 }, + { 0x7d918004, mmCP_DFY_DATA_0 }, + { 0xcd810ce6, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0xcdd1054f, mmCP_DFY_DATA_0 }, + { 0x8000156e, mmCP_DFY_DATA_0 }, + { 0x090c0008, mmCP_DFY_DATA_0 }, + { 0xcdcd050e, mmCP_DFY_DATA_0 }, + { 0x040c0000, mmCP_DFY_DATA_0 }, + { 0x110c0014, mmCP_DFY_DATA_0 }, + { 0x28cc4001, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xcc41230a, mmCP_DFY_DATA_0 }, + { 0xcc41230b, mmCP_DFY_DATA_0 }, + { 0xcc41230c, mmCP_DFY_DATA_0 }, + { 0xcc41230d, mmCP_DFY_DATA_0 }, + { 0xcc480329, mmCP_DFY_DATA_0 }, + { 0xcc48032a, mmCP_DFY_DATA_0 }, + { 0xcc4802e0, mmCP_DFY_DATA_0 }, + { 0xd8000055, mmCP_DFY_DATA_0 }, + { 0xc48f02e0, mmCP_DFY_DATA_0 }, + { 0x24d8003f, mmCP_DFY_DATA_0 }, + { 0x09940001, mmCP_DFY_DATA_0 }, + { 0x44100001, mmCP_DFY_DATA_0 }, + { 0x9580002c, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x51100001, mmCP_DFY_DATA_0 }, + { 0x69100001, mmCP_DFY_DATA_0 }, + { 0x8000157f, mmCP_DFY_DATA_0 }, + { 0x24cc003f, mmCP_DFY_DATA_0 }, + { 0xc4970290, mmCP_DFY_DATA_0 }, + { 0xc49b0288, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xc49b02a0, mmCP_DFY_DATA_0 }, + { 0xc49f0298, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7d9d801a, mmCP_DFY_DATA_0 }, + { 0x041c0040, mmCP_DFY_DATA_0 }, + { 0x04200000, mmCP_DFY_DATA_0 }, + { 0x7dcdc002, mmCP_DFY_DATA_0 }, + { 0x7d924019, mmCP_DFY_DATA_0 }, + { 0x7d26400c, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x9a400008, mmCP_DFY_DATA_0 }, + { 0x51100001, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x99c0fffa, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0x80001579, mmCP_DFY_DATA_0 }, + { 0x7d010021, mmCP_DFY_DATA_0 }, + { 0x7d914019, mmCP_DFY_DATA_0 }, + { 0xc4930238, mmCP_DFY_DATA_0 }, + { 0x55580020, mmCP_DFY_DATA_0 }, + { 0xcd480298, mmCP_DFY_DATA_0 }, + { 0xcd8802a0, mmCP_DFY_DATA_0 }, + { 0x10d40010, mmCP_DFY_DATA_0 }, + { 0x12180016, mmCP_DFY_DATA_0 }, + { 0xc51f0309, mmCP_DFY_DATA_0 }, + { 0x7d95800a, mmCP_DFY_DATA_0 }, + { 0x7d62000a, mmCP_DFY_DATA_0 }, + { 0x7dd9c00a, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcdd00309, mmCP_DFY_DATA_0 }, + { 0xce113320, mmCP_DFY_DATA_0 }, + { 0xc48f02e0, mmCP_DFY_DATA_0 }, + { 0xc49b02b0, mmCP_DFY_DATA_0 }, + { 0x18dc01e8, mmCP_DFY_DATA_0 }, + { 0x7dd9400e, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x95c0001d, mmCP_DFY_DATA_0 }, + { 0x95400003, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0x800015aa, mmCP_DFY_DATA_0 }, + { 0xc48f0238, mmCP_DFY_DATA_0 }, + { 0xc4a302b8, mmCP_DFY_DATA_0 }, + { 0x12240004, mmCP_DFY_DATA_0 }, + { 0x7e5e400a, mmCP_DFY_DATA_0 }, + { 0xc4ab02a8, mmCP_DFY_DATA_0 }, + { 0x04100000, mmCP_DFY_DATA_0 }, + { 0xce4c0319, mmCP_DFY_DATA_0 }, + { 0x7d9d8002, mmCP_DFY_DATA_0 }, + { 0x7ea14005, mmCP_DFY_DATA_0 }, + { 0x25540001, mmCP_DFY_DATA_0 }, + { 0x99400004, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x2620000f, mmCP_DFY_DATA_0 }, + { 0x800015bc, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x04240001, mmCP_DFY_DATA_0 }, + { 0x7e624004, mmCP_DFY_DATA_0 }, + { 0x06200001, mmCP_DFY_DATA_0 }, + { 0x7d25000a, mmCP_DFY_DATA_0 }, + { 0x2620000f, mmCP_DFY_DATA_0 }, + { 0x99c0fff4, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd0d3330, mmCP_DFY_DATA_0 }, + { 0xce0802b8, mmCP_DFY_DATA_0 }, + { 0xcd8802b0, mmCP_DFY_DATA_0 }, + { 0xc4ab02e0, mmCP_DFY_DATA_0 }, + { 0x1aa807f0, mmCP_DFY_DATA_0 }, + { 0xc48f02d0, mmCP_DFY_DATA_0 }, + { 0xc49702d8, mmCP_DFY_DATA_0 }, + { 0xc49b02c8, mmCP_DFY_DATA_0 }, + { 0xc49f02c0, mmCP_DFY_DATA_0 }, + { 0x96800028, mmCP_DFY_DATA_0 }, + { 0x7d4e000f, mmCP_DFY_DATA_0 }, + { 0x9600000b, mmCP_DFY_DATA_0 }, + { 0x7d964002, mmCP_DFY_DATA_0 }, + { 0x7e6a000f, mmCP_DFY_DATA_0 }, + { 0x96000003, mmCP_DFY_DATA_0 }, + { 0x7d694001, mmCP_DFY_DATA_0 }, + { 0x800015e9, mmCP_DFY_DATA_0 }, + { 0x7cde4002, mmCP_DFY_DATA_0 }, + { 0x7e6a000f, mmCP_DFY_DATA_0 }, + { 0x96000008, mmCP_DFY_DATA_0 }, + { 0x7de94001, mmCP_DFY_DATA_0 }, + { 0x800015e9, mmCP_DFY_DATA_0 }, + { 0x7cd64002, mmCP_DFY_DATA_0 }, + { 0x7e6a000e, mmCP_DFY_DATA_0 }, + { 0x96000003, mmCP_DFY_DATA_0 }, + { 0x7d694001, mmCP_DFY_DATA_0 }, + { 0x800015e9, mmCP_DFY_DATA_0 }, + { 0xc48f0230, mmCP_DFY_DATA_0 }, + { 0xc4930240, mmCP_DFY_DATA_0 }, + { 0x8c00163f, mmCP_DFY_DATA_0 }, + { 0x800015cd, mmCP_DFY_DATA_0 }, + { 0xc4930238, mmCP_DFY_DATA_0 }, + { 0x7d698002, mmCP_DFY_DATA_0 }, + { 0xcd4802d8, mmCP_DFY_DATA_0 }, + { 0x129c0008, mmCP_DFY_DATA_0 }, + { 0xc50f0319, mmCP_DFY_DATA_0 }, + { 0x11a0000e, mmCP_DFY_DATA_0 }, + { 0x11140001, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x7e1e000a, mmCP_DFY_DATA_0 }, + { 0x1198000a, mmCP_DFY_DATA_0 }, + { 0xcd953300, mmCP_DFY_DATA_0 }, + { 0x7e0e000a, mmCP_DFY_DATA_0 }, + { 0x12a8000a, mmCP_DFY_DATA_0 }, + { 0xce953301, mmCP_DFY_DATA_0 }, + { 0xce100319, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0xc4b70280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x7f73800a, mmCP_DFY_DATA_0 }, + { 0x536c0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x9780eb68, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x043c0003, mmCP_DFY_DATA_0 }, + { 0x80001609, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x30b40000, mmCP_DFY_DATA_0 }, + { 0x9b400011, mmCP_DFY_DATA_0 }, + { 0xc4b70258, mmCP_DFY_DATA_0 }, + { 0xc4b30250, mmCP_DFY_DATA_0 }, + { 0x53780020, mmCP_DFY_DATA_0 }, + { 0x7fb3801a, mmCP_DFY_DATA_0 }, + { 0x7faf8019, mmCP_DFY_DATA_0 }, + { 0x04300020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x67b40001, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x57b80001, mmCP_DFY_DATA_0 }, + { 0x97400002, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9b00fffb, mmCP_DFY_DATA_0 }, + { 0xc4bb0260, mmCP_DFY_DATA_0 }, + { 0x7fab8001, mmCP_DFY_DATA_0 }, + { 0xcf880260, mmCP_DFY_DATA_0 }, + { 0x04300020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x66f40001, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x56ec0001, mmCP_DFY_DATA_0 }, + { 0x97400005, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4353247, mmCP_DFY_DATA_0 }, + { 0x7f7f4009, mmCP_DFY_DATA_0 }, + { 0x9b40fffe, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9b00fff7, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x269c0007, mmCP_DFY_DATA_0 }, + { 0x11dc0008, mmCP_DFY_DATA_0 }, + { 0x29dc0008, mmCP_DFY_DATA_0 }, + { 0x26a00018, mmCP_DFY_DATA_0 }, + { 0x12200003, mmCP_DFY_DATA_0 }, + { 0x7de1c00a, mmCP_DFY_DATA_0 }, + { 0x26a00060, mmCP_DFY_DATA_0 }, + { 0x06200020, mmCP_DFY_DATA_0 }, + { 0x16200001, mmCP_DFY_DATA_0 }, + { 0x7de1c00a, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x269c0018, mmCP_DFY_DATA_0 }, + { 0x26a00007, mmCP_DFY_DATA_0 }, + { 0x26a40060, mmCP_DFY_DATA_0 }, + { 0x11dc0006, mmCP_DFY_DATA_0 }, + { 0x12200006, mmCP_DFY_DATA_0 }, + { 0x16640001, mmCP_DFY_DATA_0 }, + { 0x29dc0008, mmCP_DFY_DATA_0 }, + { 0x7de1c00a, mmCP_DFY_DATA_0 }, + { 0x7de5c00a, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4b70228, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x04cc0001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0xccc80230, mmCP_DFY_DATA_0 }, + { 0x7f514005, mmCP_DFY_DATA_0 }, + { 0x25540001, mmCP_DFY_DATA_0 }, + { 0x99400004, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x2510000f, mmCP_DFY_DATA_0 }, + { 0x80001644, mmCP_DFY_DATA_0 }, + { 0xc4b30248, mmCP_DFY_DATA_0 }, + { 0xcd080240, mmCP_DFY_DATA_0 }, + { 0x7f130005, mmCP_DFY_DATA_0 }, + { 0x27300001, mmCP_DFY_DATA_0 }, + { 0x9b000002, mmCP_DFY_DATA_0 }, + { 0x8c001688, mmCP_DFY_DATA_0 }, + { 0x8c00120d, mmCP_DFY_DATA_0 }, + { 0x8c001219, mmCP_DFY_DATA_0 }, + { 0x8c001232, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x04340801, mmCP_DFY_DATA_0 }, + { 0x7f130004, mmCP_DFY_DATA_0 }, + { 0xcf400013, mmCP_DFY_DATA_0 }, + { 0xcf01051e, mmCP_DFY_DATA_0 }, + { 0xc42d051f, mmCP_DFY_DATA_0 }, + { 0x7ed2c005, mmCP_DFY_DATA_0 }, + { 0x26ec0001, mmCP_DFY_DATA_0 }, + { 0x96c0fffd, mmCP_DFY_DATA_0 }, + { 0xcf01051f, mmCP_DFY_DATA_0 }, + { 0xd8000055, mmCP_DFY_DATA_0 }, + { 0xc5170309, mmCP_DFY_DATA_0 }, + { 0x195c07f0, mmCP_DFY_DATA_0 }, + { 0x196007f6, mmCP_DFY_DATA_0 }, + { 0x04340000, mmCP_DFY_DATA_0 }, + { 0x95c00008, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x04340001, mmCP_DFY_DATA_0 }, + { 0x95c00005, mmCP_DFY_DATA_0 }, + { 0x09dc0001, mmCP_DFY_DATA_0 }, + { 0x53740001, mmCP_DFY_DATA_0 }, + { 0x6b740001, mmCP_DFY_DATA_0 }, + { 0x80001665, mmCP_DFY_DATA_0 }, + { 0xc4a702a0, mmCP_DFY_DATA_0 }, + { 0xc4ab0298, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x7f634014, mmCP_DFY_DATA_0 }, + { 0x7e76401a, mmCP_DFY_DATA_0 }, + { 0xc4300004, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x56680020, mmCP_DFY_DATA_0 }, + { 0xd8113320, mmCP_DFY_DATA_0 }, + { 0xce480298, mmCP_DFY_DATA_0 }, + { 0xce8802a0, mmCP_DFY_DATA_0 }, + { 0xc5170319, mmCP_DFY_DATA_0 }, + { 0xc4b702b0, mmCP_DFY_DATA_0 }, + { 0x255c000f, mmCP_DFY_DATA_0 }, + { 0x7f5f4001, mmCP_DFY_DATA_0 }, + { 0xd8113330, mmCP_DFY_DATA_0 }, + { 0xcf4802b0, mmCP_DFY_DATA_0 }, + { 0x11340001, mmCP_DFY_DATA_0 }, + { 0x195c07e8, mmCP_DFY_DATA_0 }, + { 0x196007ee, mmCP_DFY_DATA_0 }, + { 0xd8353300, mmCP_DFY_DATA_0 }, + { 0x7e1e4001, mmCP_DFY_DATA_0 }, + { 0xd8353301, mmCP_DFY_DATA_0 }, + { 0xce4802d0, mmCP_DFY_DATA_0 }, + { 0xd8100309, mmCP_DFY_DATA_0 }, + { 0xd8100319, mmCP_DFY_DATA_0 }, + { 0xcf000008, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc48f0250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7cd4c01a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x64d80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x54cc0001, mmCP_DFY_DATA_0 }, + { 0x95800060, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4193247, mmCP_DFY_DATA_0 }, + { 0x25980001, mmCP_DFY_DATA_0 }, + { 0x9580005c, mmCP_DFY_DATA_0 }, + { 0x7dc24001, mmCP_DFY_DATA_0 }, + { 0xc41d3248, mmCP_DFY_DATA_0 }, + { 0x25dc000f, mmCP_DFY_DATA_0 }, + { 0x7dd2000c, mmCP_DFY_DATA_0 }, + { 0x96000057, mmCP_DFY_DATA_0 }, + { 0xc41d3255, mmCP_DFY_DATA_0 }, + { 0xc435324f, mmCP_DFY_DATA_0 }, + { 0x7df5c00c, mmCP_DFY_DATA_0 }, + { 0x99c00004, mmCP_DFY_DATA_0 }, + { 0xc4193265, mmCP_DFY_DATA_0 }, + { 0x25980040, mmCP_DFY_DATA_0 }, + { 0x9580fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x1bb0003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1bb000e8, mmCP_DFY_DATA_0 }, + { 0x33380003, mmCP_DFY_DATA_0 }, + { 0x9b800046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xc4393260, mmCP_DFY_DATA_0 }, + { 0x1bb000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x800016f1, mmCP_DFY_DATA_0 }, + { 0xce400013, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x7f3b0009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b800ff, mmCP_DFY_DATA_0 }, + { 0x9b80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x1a7003e6, mmCP_DFY_DATA_0 }, + { 0x27380003, mmCP_DFY_DATA_0 }, + { 0x13b80004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x1a7000e8, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x07b80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x1a700064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x800016df, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7fb30002, mmCP_DFY_DATA_0 }, + { 0xc4392083, mmCP_DFY_DATA_0 }, + { 0x7fb38005, mmCP_DFY_DATA_0 }, + { 0x27b80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xce400013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffca, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x800016f2, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940ff9c, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xd840004f, mmCP_DFY_DATA_0 }, + { 0xc414000e, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0xd80802e9, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18fc0064, mmCP_DFY_DATA_0 }, + { 0x9bc00042, mmCP_DFY_DATA_0 }, + { 0xc4193246, mmCP_DFY_DATA_0 }, + { 0xc41d3245, mmCP_DFY_DATA_0 }, + { 0x51980020, mmCP_DFY_DATA_0 }, + { 0x7dd9801a, mmCP_DFY_DATA_0 }, + { 0x45980400, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x043c3000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0x9bc00001, mmCP_DFY_DATA_0 }, + { 0x1b380057, mmCP_DFY_DATA_0 }, + { 0x1b340213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7f7b400a, mmCP_DFY_DATA_0 }, + { 0x7f73400a, mmCP_DFY_DATA_0 }, + { 0xcf400024, mmCP_DFY_DATA_0 }, + { 0x14f4001d, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x9bc0001c, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x192807fa, mmCP_DFY_DATA_0 }, + { 0xc4bf0258, mmCP_DFY_DATA_0 }, + { 0xc4a70250, mmCP_DFY_DATA_0 }, + { 0x53fc0020, mmCP_DFY_DATA_0 }, + { 0x7e7e401a, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0x04300000, mmCP_DFY_DATA_0 }, + { 0x667c0001, mmCP_DFY_DATA_0 }, + { 0x56640001, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x97c0fffd, mmCP_DFY_DATA_0 }, + { 0x07300001, mmCP_DFY_DATA_0 }, + { 0x0aec0001, mmCP_DFY_DATA_0 }, + { 0x7eebc00c, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x97c0fff8, mmCP_DFY_DATA_0 }, + { 0x0b300001, mmCP_DFY_DATA_0 }, + { 0x43300007, mmCP_DFY_DATA_0 }, + { 0x53300002, mmCP_DFY_DATA_0 }, + { 0x7db30011, mmCP_DFY_DATA_0 }, + { 0xd3000025, mmCP_DFY_DATA_0 }, + { 0xc03ec005, mmCP_DFY_DATA_0 }, + { 0x2bfca200, mmCP_DFY_DATA_0 }, + { 0xcfc00026, mmCP_DFY_DATA_0 }, + { 0xccc00026, mmCP_DFY_DATA_0 }, + { 0xcd000026, mmCP_DFY_DATA_0 }, + { 0x192807fa, mmCP_DFY_DATA_0 }, + { 0xc01f007f, mmCP_DFY_DATA_0 }, + { 0x7d1d0009, mmCP_DFY_DATA_0 }, + { 0x2110007d, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x203c003f, mmCP_DFY_DATA_0 }, + { 0xcfc13256, mmCP_DFY_DATA_0 }, + { 0x8c0017f5, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0x18fc01e8, mmCP_DFY_DATA_0 }, + { 0xcfc13248, mmCP_DFY_DATA_0 }, + { 0x8c00185b, mmCP_DFY_DATA_0 }, + { 0xd8413247, mmCP_DFY_DATA_0 }, + { 0x0b740001, mmCP_DFY_DATA_0 }, + { 0x9b40ffd5, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x97c0ea24, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x14d4001d, mmCP_DFY_DATA_0 }, + { 0xc4930260, mmCP_DFY_DATA_0 }, + { 0x7d52400e, mmCP_DFY_DATA_0 }, + { 0xc49f0258, mmCP_DFY_DATA_0 }, + { 0xc4a30250, mmCP_DFY_DATA_0 }, + { 0x51dc0020, mmCP_DFY_DATA_0 }, + { 0x7de1801a, mmCP_DFY_DATA_0 }, + { 0x96400017, mmCP_DFY_DATA_0 }, + { 0x7d534002, mmCP_DFY_DATA_0 }, + { 0xc4af0270, mmCP_DFY_DATA_0 }, + { 0x7dae4005, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x32e0001f, mmCP_DFY_DATA_0 }, + { 0x9a400006, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0xcec80270, mmCP_DFY_DATA_0 }, + { 0x8000174f, mmCP_DFY_DATA_0 }, + { 0x0b740001, mmCP_DFY_DATA_0 }, + { 0x8c00178a, mmCP_DFY_DATA_0 }, + { 0x05100001, mmCP_DFY_DATA_0 }, + { 0x9b40fff3, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x8c001608, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0xc4ab0268, mmCP_DFY_DATA_0 }, + { 0x7daa4005, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x32a0001f, mmCP_DFY_DATA_0 }, + { 0x9a400005, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0x24280000, mmCP_DFY_DATA_0 }, + { 0x80001765, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0xc01f007f, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x7d1d0009, mmCP_DFY_DATA_0 }, + { 0x2110007d, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xd8013256, mmCP_DFY_DATA_0 }, + { 0x8c0017f2, mmCP_DFY_DATA_0 }, + { 0xcd013254, mmCP_DFY_DATA_0 }, + { 0xc4113248, mmCP_DFY_DATA_0 }, + { 0x15100004, mmCP_DFY_DATA_0 }, + { 0x11100004, mmCP_DFY_DATA_0 }, + { 0xc4b3034b, mmCP_DFY_DATA_0 }, + { 0x7f13000a, mmCP_DFY_DATA_0 }, + { 0xcf013248, mmCP_DFY_DATA_0 }, + { 0xc4930260, mmCP_DFY_DATA_0 }, + { 0x8c001855, mmCP_DFY_DATA_0 }, + { 0x32a4001f, mmCP_DFY_DATA_0 }, + { 0xd8413247, mmCP_DFY_DATA_0 }, + { 0xd800004f, mmCP_DFY_DATA_0 }, + { 0x09100001, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x96400002, mmCP_DFY_DATA_0 }, + { 0x24280000, mmCP_DFY_DATA_0 }, + { 0xcd080260, mmCP_DFY_DATA_0 }, + { 0xce880268, mmCP_DFY_DATA_0 }, + { 0x9940ffc0, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x7ec28001, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x32e0001f, mmCP_DFY_DATA_0 }, + { 0xc4253247, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9640005e, mmCP_DFY_DATA_0 }, + { 0xc4293265, mmCP_DFY_DATA_0 }, + { 0xc4253255, mmCP_DFY_DATA_0 }, + { 0xc431324f, mmCP_DFY_DATA_0 }, + { 0x7e72400c, mmCP_DFY_DATA_0 }, + { 0x26a80040, mmCP_DFY_DATA_0 }, + { 0x9a400002, mmCP_DFY_DATA_0 }, + { 0x9680fff7, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x1aa4003f, mmCP_DFY_DATA_0 }, + { 0x96400049, mmCP_DFY_DATA_0 }, + { 0x1aa400e8, mmCP_DFY_DATA_0 }, + { 0x32680003, mmCP_DFY_DATA_0 }, + { 0x9a800046, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x9640000a, mmCP_DFY_DATA_0 }, + { 0xc4293260, mmCP_DFY_DATA_0 }, + { 0x1aa400e4, mmCP_DFY_DATA_0 }, + { 0x32640004, mmCP_DFY_DATA_0 }, + { 0x96400040, mmCP_DFY_DATA_0 }, + { 0xc425325d, mmCP_DFY_DATA_0 }, + { 0x26640010, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x800017e2, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc027ffff, mmCP_DFY_DATA_0 }, + { 0x2e6400ff, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x7e6a4009, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x26a800ff, mmCP_DFY_DATA_0 }, + { 0x9a80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4240009, mmCP_DFY_DATA_0 }, + { 0x26640008, mmCP_DFY_DATA_0 }, + { 0x9640fffe, mmCP_DFY_DATA_0 }, + { 0x19e403e6, mmCP_DFY_DATA_0 }, + { 0x26680003, mmCP_DFY_DATA_0 }, + { 0x12a80004, mmCP_DFY_DATA_0 }, + { 0x26640003, mmCP_DFY_DATA_0 }, + { 0x12640003, mmCP_DFY_DATA_0 }, + { 0x7ea68001, mmCP_DFY_DATA_0 }, + { 0x19e400e8, mmCP_DFY_DATA_0 }, + { 0x7ea68001, mmCP_DFY_DATA_0 }, + { 0x12640001, mmCP_DFY_DATA_0 }, + { 0x7ea68001, mmCP_DFY_DATA_0 }, + { 0x06a80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19e40064, mmCP_DFY_DATA_0 }, + { 0x32640002, mmCP_DFY_DATA_0 }, + { 0x96400009, mmCP_DFY_DATA_0 }, + { 0x16a40005, mmCP_DFY_DATA_0 }, + { 0x06640003, mmCP_DFY_DATA_0 }, + { 0xce412082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0a640003, mmCP_DFY_DATA_0 }, + { 0x800017d0, mmCP_DFY_DATA_0 }, + { 0x16a40005, mmCP_DFY_DATA_0 }, + { 0xce412082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x12640005, mmCP_DFY_DATA_0 }, + { 0x7ea64002, mmCP_DFY_DATA_0 }, + { 0xc4292083, mmCP_DFY_DATA_0 }, + { 0x7ea68005, mmCP_DFY_DATA_0 }, + { 0x26a80001, mmCP_DFY_DATA_0 }, + { 0x9a80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc425325d, mmCP_DFY_DATA_0 }, + { 0x26640010, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0xc429325b, mmCP_DFY_DATA_0 }, + { 0x26a400ff, mmCP_DFY_DATA_0 }, + { 0x9a40ffca, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0x2024007b, mmCP_DFY_DATA_0 }, + { 0xce41325b, mmCP_DFY_DATA_0 }, + { 0x800017e3, mmCP_DFY_DATA_0 }, + { 0xd841325d, mmCP_DFY_DATA_0 }, + { 0xc4a70280, mmCP_DFY_DATA_0 }, + { 0xc4ab0278, mmCP_DFY_DATA_0 }, + { 0x52640020, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x04280001, mmCP_DFY_DATA_0 }, + { 0x7eae8014, mmCP_DFY_DATA_0 }, + { 0x7e6a401a, mmCP_DFY_DATA_0 }, + { 0x56680020, mmCP_DFY_DATA_0 }, + { 0xce480278, mmCP_DFY_DATA_0 }, + { 0xce880280, mmCP_DFY_DATA_0 }, + { 0x06ec0001, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0x042c0000, mmCP_DFY_DATA_0 }, + { 0xcec80270, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0x800017fe, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x9bc00006, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcf800026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0x800017fe, mmCP_DFY_DATA_0 }, + { 0xc43b02eb, mmCP_DFY_DATA_0 }, + { 0xc42302ec, mmCP_DFY_DATA_0 }, + { 0xcf813245, mmCP_DFY_DATA_0 }, + { 0xce013246, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7fa3801a, mmCP_DFY_DATA_0 }, + { 0x47b8020c, mmCP_DFY_DATA_0 }, + { 0x15e00008, mmCP_DFY_DATA_0 }, + { 0x1220000a, mmCP_DFY_DATA_0 }, + { 0x2a206032, mmCP_DFY_DATA_0 }, + { 0x513c001e, mmCP_DFY_DATA_0 }, + { 0x7e3e001a, mmCP_DFY_DATA_0 }, + { 0xc4bf02e9, mmCP_DFY_DATA_0 }, + { 0x9bc00005, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x8000180f, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x1b3c0077, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7ff3000a, mmCP_DFY_DATA_0 }, + { 0x1330000a, mmCP_DFY_DATA_0 }, + { 0x2b300032, mmCP_DFY_DATA_0 }, + { 0x043c3000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0xd200000b, mmCP_DFY_DATA_0 }, + { 0xc4200007, mmCP_DFY_DATA_0 }, + { 0xd3800002, mmCP_DFY_DATA_0 }, + { 0xcf000002, mmCP_DFY_DATA_0 }, + { 0xd8000040, mmCP_DFY_DATA_0 }, + { 0x96000002, mmCP_DFY_DATA_0 }, + { 0xd8400040, mmCP_DFY_DATA_0 }, + { 0xd8400018, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xd8000018, mmCP_DFY_DATA_0 }, + { 0xd8800010, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0x7dc30001, mmCP_DFY_DATA_0 }, + { 0xdc1e0000, mmCP_DFY_DATA_0 }, + { 0x04380032, mmCP_DFY_DATA_0 }, + { 0xcf80000e, mmCP_DFY_DATA_0 }, + { 0x8c001427, mmCP_DFY_DATA_0 }, + { 0xcc413248, mmCP_DFY_DATA_0 }, + { 0xc43d3269, mmCP_DFY_DATA_0 }, + { 0x27fc000f, mmCP_DFY_DATA_0 }, + { 0x33fc0003, mmCP_DFY_DATA_0 }, + { 0x97c00011, mmCP_DFY_DATA_0 }, + { 0x043c001f, mmCP_DFY_DATA_0 }, + { 0xdfc30000, mmCP_DFY_DATA_0 }, + { 0xd4413249, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x043c0024, mmCP_DFY_DATA_0 }, + { 0x0bfc0021, mmCP_DFY_DATA_0 }, + { 0xdfc30000, mmCP_DFY_DATA_0 }, + { 0xd441326a, mmCP_DFY_DATA_0 }, + { 0x173c0008, mmCP_DFY_DATA_0 }, + { 0x1b300303, mmCP_DFY_DATA_0 }, + { 0x7f3f0001, mmCP_DFY_DATA_0 }, + { 0x043c0001, mmCP_DFY_DATA_0 }, + { 0x7ff3c004, mmCP_DFY_DATA_0 }, + { 0xcfc13084, mmCP_DFY_DATA_0 }, + { 0x80001842, mmCP_DFY_DATA_0 }, + { 0x043c0024, mmCP_DFY_DATA_0 }, + { 0xdfc30000, mmCP_DFY_DATA_0 }, + { 0xd4413249, mmCP_DFY_DATA_0 }, + { 0x7c43c001, mmCP_DFY_DATA_0 }, + { 0x23fc003f, mmCP_DFY_DATA_0 }, + { 0xcfc1326d, mmCP_DFY_DATA_0 }, + { 0x0bb80026, mmCP_DFY_DATA_0 }, + { 0xdf830000, mmCP_DFY_DATA_0 }, + { 0xd441326e, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0x7c438001, mmCP_DFY_DATA_0 }, + { 0xc4393265, mmCP_DFY_DATA_0 }, + { 0x1fb8ffc6, mmCP_DFY_DATA_0 }, + { 0xddc30000, mmCP_DFY_DATA_0 }, + { 0xcf813265, mmCP_DFY_DATA_0 }, + { 0x9a000003, mmCP_DFY_DATA_0 }, + { 0xcdc0000c, mmCP_DFY_DATA_0 }, + { 0x80001852, mmCP_DFY_DATA_0 }, + { 0xcdc0000d, mmCP_DFY_DATA_0 }, + { 0xce000010, mmCP_DFY_DATA_0 }, + { 0x8c00142b, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcdc13252, mmCP_DFY_DATA_0 }, + { 0xce013253, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x80001878, mmCP_DFY_DATA_0 }, + { 0xc49f02e9, mmCP_DFY_DATA_0 }, + { 0x99c00018, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x7c420001, mmCP_DFY_DATA_0 }, + { 0xcdc13252, mmCP_DFY_DATA_0 }, + { 0xce013253, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x043c3000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xc43d3267, mmCP_DFY_DATA_0 }, + { 0x97c0ffff, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xce000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc41c0012, mmCP_DFY_DATA_0 }, + { 0x99c0ffff, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0x80001878, mmCP_DFY_DATA_0 }, + { 0xc41f02ed, mmCP_DFY_DATA_0 }, + { 0xc42302ee, mmCP_DFY_DATA_0 }, + { 0xcdc13252, mmCP_DFY_DATA_0 }, + { 0xce013253, mmCP_DFY_DATA_0 }, + { 0x04200001, mmCP_DFY_DATA_0 }, + { 0x7e2a0004, mmCP_DFY_DATA_0 }, + { 0xce013084, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x28340001, mmCP_DFY_DATA_0 }, + { 0x313c0bcc, mmCP_DFY_DATA_0 }, + { 0x9bc00010, mmCP_DFY_DATA_0 }, + { 0x393c051f, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0x3d3c050e, mmCP_DFY_DATA_0 }, + { 0x9bc0000c, mmCP_DFY_DATA_0 }, + { 0x97c0000c, mmCP_DFY_DATA_0 }, + { 0x393c0560, mmCP_DFY_DATA_0 }, + { 0x9bc00004, mmCP_DFY_DATA_0 }, + { 0x3d3c054f, mmCP_DFY_DATA_0 }, + { 0x9bc00007, mmCP_DFY_DATA_0 }, + { 0x97c00007, mmCP_DFY_DATA_0 }, + { 0x393c1538, mmCP_DFY_DATA_0 }, + { 0x9bc00005, mmCP_DFY_DATA_0 }, + { 0x3d3c1537, mmCP_DFY_DATA_0 }, + { 0x9bc00002, mmCP_DFY_DATA_0 }, + { 0x97c00002, mmCP_DFY_DATA_0 }, + { 0x2b740800, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18e8007c, mmCP_DFY_DATA_0 }, + { 0x7c42c001, mmCP_DFY_DATA_0 }, + { 0x06a8189a, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0x800018c5, mmCP_DFY_DATA_0 }, + { 0x800018f2, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0x7c414001, mmCP_DFY_DATA_0 }, + { 0x18d0007e, mmCP_DFY_DATA_0 }, + { 0x50580020, mmCP_DFY_DATA_0 }, + { 0x09200001, mmCP_DFY_DATA_0 }, + { 0x7d59401a, mmCP_DFY_DATA_0 }, + { 0xd1400072, mmCP_DFY_DATA_0 }, + { 0xc8140072, mmCP_DFY_DATA_0 }, + { 0x09240002, mmCP_DFY_DATA_0 }, + { 0x7c418001, mmCP_DFY_DATA_0 }, + { 0x7c41c001, mmCP_DFY_DATA_0 }, + { 0x99000011, mmCP_DFY_DATA_0 }, + { 0xc4340004, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd8400008, mmCP_DFY_DATA_0 }, + { 0xc42130b5, mmCP_DFY_DATA_0 }, + { 0x1a24002c, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x2020002c, mmCP_DFY_DATA_0 }, + { 0xc418000d, mmCP_DFY_DATA_0 }, + { 0x1198001c, mmCP_DFY_DATA_0 }, + { 0x10cc0004, mmCP_DFY_DATA_0 }, + { 0x14cc0004, mmCP_DFY_DATA_0 }, + { 0x7cd8c00a, mmCP_DFY_DATA_0 }, + { 0xccc130b7, mmCP_DFY_DATA_0 }, + { 0xce0130b5, mmCP_DFY_DATA_0 }, + { 0xcf400008, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0xd1400025, mmCP_DFY_DATA_0 }, + { 0x5978073a, mmCP_DFY_DATA_0 }, + { 0x2bb80002, mmCP_DFY_DATA_0 }, + { 0xcf800024, mmCP_DFY_DATA_0 }, + { 0xcd800026, mmCP_DFY_DATA_0 }, + { 0xcdc00026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x9600e8a8, mmCP_DFY_DATA_0 }, + { 0xc4300012, mmCP_DFY_DATA_0 }, + { 0x9b00ffff, mmCP_DFY_DATA_0 }, + { 0x9640e8a5, mmCP_DFY_DATA_0 }, + { 0x800018a9, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0xc55b0309, mmCP_DFY_DATA_0 }, + { 0x3d5c0010, mmCP_DFY_DATA_0 }, + { 0x05540001, mmCP_DFY_DATA_0 }, + { 0x2598ffff, mmCP_DFY_DATA_0 }, + { 0x09780001, mmCP_DFY_DATA_0 }, + { 0x7dad800c, mmCP_DFY_DATA_0 }, + { 0x99c0ffd2, mmCP_DFY_DATA_0 }, + { 0x9580fff9, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x442c0000, mmCP_DFY_DATA_0 }, + { 0x65180001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9580000b, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc41d3248, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x25dc000f, mmCP_DFY_DATA_0 }, + { 0x7df9c00c, mmCP_DFY_DATA_0 }, + { 0x95c00004, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xd8c13260, mmCP_DFY_DATA_0 }, + { 0xd901325d, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940fff1, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x66d80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x56ec0001, mmCP_DFY_DATA_0 }, + { 0x95800005, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc421325d, mmCP_DFY_DATA_0 }, + { 0x26240007, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940fff7, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc41d3254, mmCP_DFY_DATA_0 }, + { 0xc023007f, mmCP_DFY_DATA_0 }, + { 0x19e4003e, mmCP_DFY_DATA_0 }, + { 0x7de1c009, mmCP_DFY_DATA_0 }, + { 0x7dee000c, mmCP_DFY_DATA_0 }, + { 0x96400008, mmCP_DFY_DATA_0 }, + { 0x96000007, mmCP_DFY_DATA_0 }, + { 0xd8c13260, mmCP_DFY_DATA_0 }, + { 0xd901325d, mmCP_DFY_DATA_0 }, + { 0xc421325d, mmCP_DFY_DATA_0 }, + { 0x261c0007, mmCP_DFY_DATA_0 }, + { 0x99c0fffe, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940fff0, mmCP_DFY_DATA_0 }, + { 0x8000189e, mmCP_DFY_DATA_0 }, + { 0xc40c000e, mmCP_DFY_DATA_0 }, + { 0x28cc0008, mmCP_DFY_DATA_0 }, + { 0xccc00013, mmCP_DFY_DATA_0 }, + { 0xc43d3265, mmCP_DFY_DATA_0 }, + { 0x1bc800ea, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x18e00064, mmCP_DFY_DATA_0 }, + { 0x06281911, mmCP_DFY_DATA_0 }, + { 0x14f4001d, mmCP_DFY_DATA_0 }, + { 0x24cc0003, mmCP_DFY_DATA_0 }, + { 0x86800000, mmCP_DFY_DATA_0 }, + { 0x80001915, mmCP_DFY_DATA_0 }, + { 0x800019af, mmCP_DFY_DATA_0 }, + { 0x80001a2b, mmCP_DFY_DATA_0 }, + { 0x8000016a, mmCP_DFY_DATA_0 }, + { 0xcc48032b, mmCP_DFY_DATA_0 }, + { 0xcc480333, mmCP_DFY_DATA_0 }, + { 0xcc48033b, mmCP_DFY_DATA_0 }, + { 0xcc480343, mmCP_DFY_DATA_0 }, + { 0x98800011, mmCP_DFY_DATA_0 }, + { 0xc4213246, mmCP_DFY_DATA_0 }, + { 0xc4253245, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26401a, mmCP_DFY_DATA_0 }, + { 0x46640400, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04203000, mmCP_DFY_DATA_0 }, + { 0xce013267, mmCP_DFY_DATA_0 }, + { 0xc4213267, mmCP_DFY_DATA_0 }, + { 0x9a000001, mmCP_DFY_DATA_0 }, + { 0x1b3c0057, mmCP_DFY_DATA_0 }, + { 0x1b200213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7e3e000a, mmCP_DFY_DATA_0 }, + { 0x7e32000a, mmCP_DFY_DATA_0 }, + { 0xce000024, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04180000, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x7f438001, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc41d3247, mmCP_DFY_DATA_0 }, + { 0x25dc0001, mmCP_DFY_DATA_0 }, + { 0x95c00068, mmCP_DFY_DATA_0 }, + { 0xc4213254, mmCP_DFY_DATA_0 }, + { 0x1a1c003e, mmCP_DFY_DATA_0 }, + { 0x95c00065, mmCP_DFY_DATA_0 }, + { 0xc01f007f, mmCP_DFY_DATA_0 }, + { 0x7e1e0009, mmCP_DFY_DATA_0 }, + { 0x97800062, mmCP_DFY_DATA_0 }, + { 0x0bb80001, mmCP_DFY_DATA_0 }, + { 0x43bc0008, mmCP_DFY_DATA_0 }, + { 0x7fcbc001, mmCP_DFY_DATA_0 }, + { 0xc7df032b, mmCP_DFY_DATA_0 }, + { 0x7e1fc00c, mmCP_DFY_DATA_0 }, + { 0x97c0fffa, mmCP_DFY_DATA_0 }, + { 0x043c0101, mmCP_DFY_DATA_0 }, + { 0x94c00002, mmCP_DFY_DATA_0 }, + { 0x043c0102, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x1bb0003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1bb000e8, mmCP_DFY_DATA_0 }, + { 0x33380003, mmCP_DFY_DATA_0 }, + { 0x9b800046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0xc4393260, mmCP_DFY_DATA_0 }, + { 0x1bb000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x80001994, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x7f3b0009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b800ff, mmCP_DFY_DATA_0 }, + { 0x9b80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x19f003e6, mmCP_DFY_DATA_0 }, + { 0x27380003, mmCP_DFY_DATA_0 }, + { 0x13b80004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x19f000e8, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x07b80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19f00064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x80001982, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7fb30002, mmCP_DFY_DATA_0 }, + { 0xc4392083, mmCP_DFY_DATA_0 }, + { 0x7fb38005, mmCP_DFY_DATA_0 }, + { 0x27b80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffcb, mmCP_DFY_DATA_0 }, + { 0xcfc1325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x80001995, mmCP_DFY_DATA_0 }, + { 0xcfc1325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x98800009, mmCP_DFY_DATA_0 }, + { 0x41bc0007, mmCP_DFY_DATA_0 }, + { 0x53fc0002, mmCP_DFY_DATA_0 }, + { 0x7e7fc011, mmCP_DFY_DATA_0 }, + { 0xd3c00025, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0xc43c0012, mmCP_DFY_DATA_0 }, + { 0x9bc0ffff, mmCP_DFY_DATA_0 }, + { 0x653c0001, mmCP_DFY_DATA_0 }, + { 0x7dbd8001, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9940ff8f, mmCP_DFY_DATA_0 }, + { 0xc43c000e, mmCP_DFY_DATA_0 }, + { 0x2bfc0008, mmCP_DFY_DATA_0 }, + { 0xcfc00013, mmCP_DFY_DATA_0 }, + { 0x043c2000, mmCP_DFY_DATA_0 }, + { 0xcfc13267, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x7c410001, mmCP_DFY_DATA_0 }, + { 0x04140000, mmCP_DFY_DATA_0 }, + { 0xc55b0309, mmCP_DFY_DATA_0 }, + { 0x3d5c0010, mmCP_DFY_DATA_0 }, + { 0x2598ffff, mmCP_DFY_DATA_0 }, + { 0x05540001, mmCP_DFY_DATA_0 }, + { 0x7d91800c, mmCP_DFY_DATA_0 }, + { 0x95c00003, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x9580fff8, mmCP_DFY_DATA_0 }, + { 0x09780001, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x65180001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9580005d, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4253247, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x04200101, mmCP_DFY_DATA_0 }, + { 0x96400058, mmCP_DFY_DATA_0 }, + { 0x7dc24001, mmCP_DFY_DATA_0 }, + { 0xc41d3248, mmCP_DFY_DATA_0 }, + { 0x25dc000f, mmCP_DFY_DATA_0 }, + { 0x7df9c00c, mmCP_DFY_DATA_0 }, + { 0x95c00053, mmCP_DFY_DATA_0 }, + { 0x94c00002, mmCP_DFY_DATA_0 }, + { 0x04200102, mmCP_DFY_DATA_0 }, + { 0x7e41c001, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x1a70003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1a7000e8, mmCP_DFY_DATA_0 }, + { 0x33240003, mmCP_DFY_DATA_0 }, + { 0x9a400046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xc4253260, mmCP_DFY_DATA_0 }, + { 0x1a7000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x80001a21, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x7f270009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x266400ff, mmCP_DFY_DATA_0 }, + { 0x9a40fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x19f003e6, mmCP_DFY_DATA_0 }, + { 0x27240003, mmCP_DFY_DATA_0 }, + { 0x12640004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x19f000e8, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7e724001, mmCP_DFY_DATA_0 }, + { 0x06640002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19f00064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x16700005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x80001a0f, mmCP_DFY_DATA_0 }, + { 0x16700005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7e730002, mmCP_DFY_DATA_0 }, + { 0xc4252083, mmCP_DFY_DATA_0 }, + { 0x7e724005, mmCP_DFY_DATA_0 }, + { 0x26640001, mmCP_DFY_DATA_0 }, + { 0x9a40ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc425325b, mmCP_DFY_DATA_0 }, + { 0x267000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffca, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0x80001a22, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x9940ff9f, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x8c001a31, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0xd8080278, mmCP_DFY_DATA_0 }, + { 0xd8080280, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc4213246, mmCP_DFY_DATA_0 }, + { 0xc4253245, mmCP_DFY_DATA_0 }, + { 0x52200020, mmCP_DFY_DATA_0 }, + { 0x7e26401a, mmCP_DFY_DATA_0 }, + { 0x46640400, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x04203000, mmCP_DFY_DATA_0 }, + { 0xce013267, mmCP_DFY_DATA_0 }, + { 0xc4213267, mmCP_DFY_DATA_0 }, + { 0x9a000001, mmCP_DFY_DATA_0 }, + { 0x1b180057, mmCP_DFY_DATA_0 }, + { 0x1b200213, mmCP_DFY_DATA_0 }, + { 0x1b300199, mmCP_DFY_DATA_0 }, + { 0x7e1a000a, mmCP_DFY_DATA_0 }, + { 0x7e32000a, mmCP_DFY_DATA_0 }, + { 0xce000024, mmCP_DFY_DATA_0 }, + { 0xc4970258, mmCP_DFY_DATA_0 }, + { 0xc4930250, mmCP_DFY_DATA_0 }, + { 0x51540020, mmCP_DFY_DATA_0 }, + { 0x7d15001a, mmCP_DFY_DATA_0 }, + { 0xc4af0280, mmCP_DFY_DATA_0 }, + { 0xc4b30278, mmCP_DFY_DATA_0 }, + { 0x52ec0020, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0x04140020, mmCP_DFY_DATA_0 }, + { 0x04280000, mmCP_DFY_DATA_0 }, + { 0x65180001, mmCP_DFY_DATA_0 }, + { 0x95800060, mmCP_DFY_DATA_0 }, + { 0x8c001628, mmCP_DFY_DATA_0 }, + { 0xc4193247, mmCP_DFY_DATA_0 }, + { 0x25980001, mmCP_DFY_DATA_0 }, + { 0x04200101, mmCP_DFY_DATA_0 }, + { 0x94c00005, mmCP_DFY_DATA_0 }, + { 0x30f00005, mmCP_DFY_DATA_0 }, + { 0x04200005, mmCP_DFY_DATA_0 }, + { 0x9b000002, mmCP_DFY_DATA_0 }, + { 0x04200102, mmCP_DFY_DATA_0 }, + { 0x95800056, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x1bb0003f, mmCP_DFY_DATA_0 }, + { 0x97000049, mmCP_DFY_DATA_0 }, + { 0x1bb000e8, mmCP_DFY_DATA_0 }, + { 0x33380003, mmCP_DFY_DATA_0 }, + { 0x9b800046, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x9700000a, mmCP_DFY_DATA_0 }, + { 0xc4393260, mmCP_DFY_DATA_0 }, + { 0x1bb000e4, mmCP_DFY_DATA_0 }, + { 0x33300004, mmCP_DFY_DATA_0 }, + { 0x97000040, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0x80001aa2, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc033ffff, mmCP_DFY_DATA_0 }, + { 0x2f3000ff, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x7f3b0009, mmCP_DFY_DATA_0 }, + { 0xcf01325b, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b800ff, mmCP_DFY_DATA_0 }, + { 0x9b80fffe, mmCP_DFY_DATA_0 }, + { 0xd8c00033, mmCP_DFY_DATA_0 }, + { 0xc4300009, mmCP_DFY_DATA_0 }, + { 0x27300008, mmCP_DFY_DATA_0 }, + { 0x9700fffe, mmCP_DFY_DATA_0 }, + { 0x19f003e6, mmCP_DFY_DATA_0 }, + { 0x27380003, mmCP_DFY_DATA_0 }, + { 0x13b80004, mmCP_DFY_DATA_0 }, + { 0x27300003, mmCP_DFY_DATA_0 }, + { 0x13300003, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x19f000e8, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x13300001, mmCP_DFY_DATA_0 }, + { 0x7fb38001, mmCP_DFY_DATA_0 }, + { 0x07b80002, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0x19f00064, mmCP_DFY_DATA_0 }, + { 0x33300002, mmCP_DFY_DATA_0 }, + { 0x97000009, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0x07300003, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x0b300003, mmCP_DFY_DATA_0 }, + { 0x80001a90, mmCP_DFY_DATA_0 }, + { 0x17b00005, mmCP_DFY_DATA_0 }, + { 0xcf012082, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcc01203f, mmCP_DFY_DATA_0 }, + { 0x13300005, mmCP_DFY_DATA_0 }, + { 0x7fb30002, mmCP_DFY_DATA_0 }, + { 0xc4392083, mmCP_DFY_DATA_0 }, + { 0x7fb38005, mmCP_DFY_DATA_0 }, + { 0x27b80001, mmCP_DFY_DATA_0 }, + { 0x9b80ffdf, mmCP_DFY_DATA_0 }, + { 0xd8c00034, mmCP_DFY_DATA_0 }, + { 0xcdc00013, mmCP_DFY_DATA_0 }, + { 0xc431325d, mmCP_DFY_DATA_0 }, + { 0x27300010, mmCP_DFY_DATA_0 }, + { 0x9b00fffe, mmCP_DFY_DATA_0 }, + { 0xc439325b, mmCP_DFY_DATA_0 }, + { 0x27b000ff, mmCP_DFY_DATA_0 }, + { 0x9b00ffca, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x2030007b, mmCP_DFY_DATA_0 }, + { 0xcf00325b, mmCP_DFY_DATA_0 }, + { 0x80001aa3, mmCP_DFY_DATA_0 }, + { 0xce01325d, mmCP_DFY_DATA_0 }, + { 0x04300001, mmCP_DFY_DATA_0 }, + { 0x7f2b0014, mmCP_DFY_DATA_0 }, + { 0x7ef2c01a, mmCP_DFY_DATA_0 }, + { 0xc49b02e9, mmCP_DFY_DATA_0 }, + { 0x99800005, mmCP_DFY_DATA_0 }, + { 0xd2400025, mmCP_DFY_DATA_0 }, + { 0x4664001c, mmCP_DFY_DATA_0 }, + { 0xd8000026, mmCP_DFY_DATA_0 }, + { 0xd8400027, mmCP_DFY_DATA_0 }, + { 0x06a80001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x55100001, mmCP_DFY_DATA_0 }, + { 0x9940ff9c, mmCP_DFY_DATA_0 }, + { 0xc49b02e9, mmCP_DFY_DATA_0 }, + { 0x99800008, mmCP_DFY_DATA_0 }, + { 0xc430000e, mmCP_DFY_DATA_0 }, + { 0x2b300008, mmCP_DFY_DATA_0 }, + { 0xcf000013, mmCP_DFY_DATA_0 }, + { 0x04302000, mmCP_DFY_DATA_0 }, + { 0xcf013267, mmCP_DFY_DATA_0 }, + { 0xc4313267, mmCP_DFY_DATA_0 }, + { 0x97000001, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0x244c00ff, mmCP_DFY_DATA_0 }, + { 0xcc4c0200, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc44f0200, mmCP_DFY_DATA_0 }, + { 0xc410000b, mmCP_DFY_DATA_0 }, + { 0xc414000c, mmCP_DFY_DATA_0 }, + { 0x7d158010, mmCP_DFY_DATA_0 }, + { 0x059cc000, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccdd0000, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c0037, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0xcc000049, mmCP_DFY_DATA_0 }, + { 0xc40c003a, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x24d00001, mmCP_DFY_DATA_0 }, + { 0x9500e69a, mmCP_DFY_DATA_0 }, + { 0x18d0003b, mmCP_DFY_DATA_0 }, + { 0x18d40021, mmCP_DFY_DATA_0 }, + { 0x99400006, mmCP_DFY_DATA_0 }, + { 0xd840004a, mmCP_DFY_DATA_0 }, + { 0xc40c003c, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0x14cc0001, mmCP_DFY_DATA_0 }, + { 0x94c00028, mmCP_DFY_DATA_0 }, + { 0xd8000033, mmCP_DFY_DATA_0 }, + { 0xc438000b, mmCP_DFY_DATA_0 }, + { 0xc43c0009, mmCP_DFY_DATA_0 }, + { 0x27fc0001, mmCP_DFY_DATA_0 }, + { 0x97c0fffe, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd841c07f, mmCP_DFY_DATA_0 }, + { 0xc43dc07f, mmCP_DFY_DATA_0 }, + { 0x1bfc0078, mmCP_DFY_DATA_0 }, + { 0x7ffbc00c, mmCP_DFY_DATA_0 }, + { 0x97c0fffd, mmCP_DFY_DATA_0 }, + { 0x99000004, mmCP_DFY_DATA_0 }, + { 0xc0120840, mmCP_DFY_DATA_0 }, + { 0x282c0040, mmCP_DFY_DATA_0 }, + { 0x80001ae8, mmCP_DFY_DATA_0 }, + { 0xc0121841, mmCP_DFY_DATA_0 }, + { 0x282c001a, mmCP_DFY_DATA_0 }, + { 0xcd01c07c, mmCP_DFY_DATA_0 }, + { 0xcc01c07d, mmCP_DFY_DATA_0 }, + { 0xcc01c08c, mmCP_DFY_DATA_0 }, + { 0xcc01c079, mmCP_DFY_DATA_0 }, + { 0xcc01c07e, mmCP_DFY_DATA_0 }, + { 0x04200004, mmCP_DFY_DATA_0 }, + { 0xcec0001b, mmCP_DFY_DATA_0 }, + { 0xd8400021, mmCP_DFY_DATA_0 }, + { 0x0a200001, mmCP_DFY_DATA_0 }, + { 0x9a00ffff, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0x166c001f, mmCP_DFY_DATA_0 }, + { 0x04200004, mmCP_DFY_DATA_0 }, + { 0x9ac0fffb, mmCP_DFY_DATA_0 }, + { 0xc434000f, mmCP_DFY_DATA_0 }, + { 0x9b40ffff, mmCP_DFY_DATA_0 }, + { 0xd801c07f, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xc425c07f, mmCP_DFY_DATA_0 }, + { 0xce400078, mmCP_DFY_DATA_0 }, + { 0xd8000034, mmCP_DFY_DATA_0 }, + { 0x9940e66b, mmCP_DFY_DATA_0 }, + { 0xd800004a, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc40c0036, mmCP_DFY_DATA_0 }, + { 0x24d00001, mmCP_DFY_DATA_0 }, + { 0x9900fffe, mmCP_DFY_DATA_0 }, + { 0x18cc0021, mmCP_DFY_DATA_0 }, + { 0xccc00047, mmCP_DFY_DATA_0 }, + { 0xcc000046, mmCP_DFY_DATA_0 }, + { 0xc40c0039, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0xc40c003d, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0x7c40c001, mmCP_DFY_DATA_0 }, + { 0x24d003ff, mmCP_DFY_DATA_0 }, + { 0x18d47fea, mmCP_DFY_DATA_0 }, + { 0x18d87ff4, mmCP_DFY_DATA_0 }, + { 0xcd00004c, mmCP_DFY_DATA_0 }, + { 0xcd40004e, mmCP_DFY_DATA_0 }, + { 0xcd80004d, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd41c405, mmCP_DFY_DATA_0 }, + { 0xc02a0001, mmCP_DFY_DATA_0 }, + { 0x2aa80001, mmCP_DFY_DATA_0 }, + { 0xce800013, mmCP_DFY_DATA_0 }, + { 0xcd01c406, mmCP_DFY_DATA_0 }, + { 0xcc01c406, mmCP_DFY_DATA_0 }, + { 0xcc01c406, mmCP_DFY_DATA_0 }, + { 0xc40c0006, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0xc414000e, mmCP_DFY_DATA_0 }, + { 0x29540008, mmCP_DFY_DATA_0 }, + { 0x295c0001, mmCP_DFY_DATA_0 }, + { 0xcd400013, mmCP_DFY_DATA_0 }, + { 0xd8c1325e, mmCP_DFY_DATA_0 }, + { 0xcdc0001a, mmCP_DFY_DATA_0 }, + { 0x11980002, mmCP_DFY_DATA_0 }, + { 0x4110000c, mmCP_DFY_DATA_0 }, + { 0xc0160800, mmCP_DFY_DATA_0 }, + { 0x7d15000a, mmCP_DFY_DATA_0 }, + { 0xc0164010, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xcd41c078, mmCP_DFY_DATA_0 }, + { 0xcc01c080, mmCP_DFY_DATA_0 }, + { 0xcc01c081, mmCP_DFY_DATA_0 }, + { 0xcd81c082, mmCP_DFY_DATA_0 }, + { 0xcc01c083, mmCP_DFY_DATA_0 }, + { 0xcd01c084, mmCP_DFY_DATA_0 }, + { 0xc40c0006, mmCP_DFY_DATA_0 }, + { 0x98c0ffff, mmCP_DFY_DATA_0 }, + { 0xd8400048, mmCP_DFY_DATA_0 }, + { 0xc40c003b, mmCP_DFY_DATA_0 }, + { 0x94c0ffff, mmCP_DFY_DATA_0 }, + { 0x80000c16, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xd801c40a, mmCP_DFY_DATA_0 }, + { 0xd901c40d, mmCP_DFY_DATA_0 }, + { 0xd801c410, mmCP_DFY_DATA_0 }, + { 0xd801c40e, mmCP_DFY_DATA_0 }, + { 0xd801c40f, mmCP_DFY_DATA_0 }, + { 0xc40c0040, mmCP_DFY_DATA_0 }, + { 0x04140001, mmCP_DFY_DATA_0 }, + { 0x09540001, mmCP_DFY_DATA_0 }, + { 0x9940ffff, mmCP_DFY_DATA_0 }, + { 0x04140096, mmCP_DFY_DATA_0 }, + { 0xd8400013, mmCP_DFY_DATA_0 }, + { 0xccc1c400, mmCP_DFY_DATA_0 }, + { 0xc411c401, mmCP_DFY_DATA_0 }, + { 0x9500fffa, mmCP_DFY_DATA_0 }, + { 0xc424003e, mmCP_DFY_DATA_0 }, + { 0x04d00001, mmCP_DFY_DATA_0 }, + { 0x11100002, mmCP_DFY_DATA_0 }, + { 0xcd01c40c, mmCP_DFY_DATA_0 }, + { 0xc0180034, mmCP_DFY_DATA_0 }, + { 0xcd81c411, mmCP_DFY_DATA_0 }, + { 0xd841c414, mmCP_DFY_DATA_0 }, + { 0x0a540001, mmCP_DFY_DATA_0 }, + { 0xcd41c412, mmCP_DFY_DATA_0 }, + { 0x2468000f, mmCP_DFY_DATA_0 }, + { 0xc419c416, mmCP_DFY_DATA_0 }, + { 0x41980003, mmCP_DFY_DATA_0 }, + { 0xc41c003f, mmCP_DFY_DATA_0 }, + { 0x7dda0001, mmCP_DFY_DATA_0 }, + { 0x12200002, mmCP_DFY_DATA_0 }, + { 0x10cc0002, mmCP_DFY_DATA_0 }, + { 0xccc1c40c, mmCP_DFY_DATA_0 }, + { 0xd901c411, mmCP_DFY_DATA_0 }, + { 0xce41c412, mmCP_DFY_DATA_0 }, + { 0xd8800013, mmCP_DFY_DATA_0 }, + { 0xce292e40, mmCP_DFY_DATA_0 }, + { 0xcc412e01, mmCP_DFY_DATA_0 }, + { 0xcc412e02, mmCP_DFY_DATA_0 }, + { 0xcc412e03, mmCP_DFY_DATA_0 }, + { 0xcc412e00, mmCP_DFY_DATA_0 }, + { 0x80000aa7, mmCP_DFY_DATA_0 }, + { 0xc43c0007, mmCP_DFY_DATA_0 }, + { 0xdc120000, mmCP_DFY_DATA_0 }, + { 0x31144000, mmCP_DFY_DATA_0 }, + { 0x95400005, mmCP_DFY_DATA_0 }, + { 0xdc030000, mmCP_DFY_DATA_0 }, + { 0xd800002a, mmCP_DFY_DATA_0 }, + { 0xcc3c000c, mmCP_DFY_DATA_0 }, + { 0x80001b70, mmCP_DFY_DATA_0 }, + { 0x33f80003, mmCP_DFY_DATA_0 }, + { 0xd4400078, mmCP_DFY_DATA_0 }, + { 0x9780e601, mmCP_DFY_DATA_0 }, + { 0x188cfff0, mmCP_DFY_DATA_0 }, + { 0x04e40002, mmCP_DFY_DATA_0 }, + { 0x80001190, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x96400006, mmCP_DFY_DATA_0 }, + { 0x90000000, mmCP_DFY_DATA_0 }, + { 0xc424005e, mmCP_DFY_DATA_0 }, + { 0x96400003, mmCP_DFY_DATA_0 }, + { 0x7c408001, mmCP_DFY_DATA_0 }, + { 0x88000000, mmCP_DFY_DATA_0 }, + { 0x80001b74, mmCP_DFY_DATA_0 }, + { 0x80000168, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0x92100004, mmCP_DFY_DATA_0 }, + { 0x92110501, mmCP_DFY_DATA_0 }, + { 0x92120206, mmCP_DFY_DATA_0 }, + { 0x92130703, mmCP_DFY_DATA_0 }, + { 0x92100400, mmCP_DFY_DATA_0 }, + { 0x92110105, mmCP_DFY_DATA_0 }, + { 0x92120602, mmCP_DFY_DATA_0 }, + { 0x92130307, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x54106500, mmCP_DFY_ADDR_LO }, + { 0x7e000200, mmCP_DFY_DATA_0 }, + { 0x7e020204, mmCP_DFY_DATA_0 }, + { 0xc00a0505, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xbf8c007f, mmCP_DFY_DATA_0 }, + { 0xb8900904, mmCP_DFY_DATA_0 }, + { 0xb8911a04, mmCP_DFY_DATA_0 }, + { 0xb8920304, mmCP_DFY_DATA_0 }, + { 0xb8930b44, mmCP_DFY_DATA_0 }, + { 0x921c0d0c, mmCP_DFY_DATA_0 }, + { 0x921c1c13, mmCP_DFY_DATA_0 }, + { 0x921d0c12, mmCP_DFY_DATA_0 }, + { 0x811c1d1c, mmCP_DFY_DATA_0 }, + { 0x811c111c, mmCP_DFY_DATA_0 }, + { 0x921cff1c, mmCP_DFY_DATA_0 }, + { 0x00000400, mmCP_DFY_DATA_0 }, + { 0x921dff10, mmCP_DFY_DATA_0 }, + { 0x00000100, mmCP_DFY_DATA_0 }, + { 0x81181d1c, mmCP_DFY_DATA_0 }, + { 0x7e040218, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050002, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050102, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050002, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050102, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050002, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0701000, mmCP_DFY_DATA_0 }, + { 0x80050102, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xe0501000, mmCP_DFY_DATA_0 }, + { 0x80050302, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x54106900, mmCP_DFY_ADDR_LO }, + { 0x7e080200, mmCP_DFY_DATA_0 }, + { 0x7e100204, mmCP_DFY_DATA_0 }, + { 0xbefc00ff, mmCP_DFY_DATA_0 }, + { 0x00010000, mmCP_DFY_DATA_0 }, + { 0x24200087, mmCP_DFY_DATA_0 }, + { 0x262200ff, mmCP_DFY_DATA_0 }, + { 0x000001f0, mmCP_DFY_DATA_0 }, + { 0x20222282, mmCP_DFY_DATA_0 }, + { 0x28182111, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000040c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd81a0000, mmCP_DFY_DATA_0 }, + { 0x0000080c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xd86c0000, mmCP_DFY_DATA_0 }, + { 0x1100000c, mmCP_DFY_DATA_0 }, + { 0xbf810000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x80000004, mmCP_DFY_CNTL }, + { 0x000000b4, mmCP_DFY_ADDR_HI }, + { 0x54116f00, mmCP_DFY_ADDR_LO }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fe8, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000041, mmCP_DFY_DATA_0 }, + { 0x0000000c, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54116f00, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb454105e, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x000000c0, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54117300, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4541065, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000500, mmCP_DFY_DATA_0 }, + { 0x0000001c, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54117700, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xc0310800, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000040, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4541069, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000444, mmCP_DFY_DATA_0 }, + { 0x0000008a, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x07808000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0xffffffff, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000002, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x55555555, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee40, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000010, mmCP_DFY_DATA_0 }, + { 0x00000001, mmCP_DFY_DATA_0 }, + { 0x00000004, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x54117b00, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00005301, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0xb4540fef, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x540fee20, mmCP_DFY_DATA_0 }, + { 0x000000b4, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x08000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, mmCP_MEC_CNTL }, + { 0x00000000, mmCP_MEC_CNTL }, + { 0x00000004, mmSRBM_GFX_CNTL }, + { 0x54116f00, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000005, mmSRBM_GFX_CNTL }, + { 0x54117300, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000006, mmSRBM_GFX_CNTL }, + { 0x54117700, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000007, mmSRBM_GFX_CNTL }, + { 0x54117b00, mmCP_MQD_BASE_ADDR }, + { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, + { 0xb4540fef, mmCP_HQD_PQ_BASE }, + { 0x00000000, mmCP_HQD_PQ_BASE_HI }, + { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, + { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, + { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, + { 0x00010000, mmCP_HQD_VMID }, + { 0xc8318509, mmCP_HQD_PQ_CONTROL }, + { 0x00000004, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000104, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000204, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000304, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000404, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000504, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000604, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000704, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000005, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000105, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000205, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000305, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000405, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000505, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000605, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000705, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000006, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000106, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000206, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000306, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000406, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000506, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000606, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000706, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000007, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000107, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000207, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000307, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000407, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000507, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000607, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000707, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000008, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000108, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000208, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000308, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000408, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000508, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000608, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000708, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000009, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000109, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000209, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000309, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000409, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000509, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000609, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000709, mmSRBM_GFX_CNTL }, + { 0x00000000, mmCP_HQD_ACTIVE }, + { 0x00000000, mmCP_HQD_PQ_RPTR }, + { 0x00000000, mmCP_HQD_PQ_WPTR }, + { 0x00000001, mmCP_HQD_ACTIVE }, + { 0x00000004, mmSRBM_GFX_CNTL }, + { 0x01010101, mmCP_PQ_WPTR_POLL_CNTL1 }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, mmGRBM_STATUS }, + { 0x00000000, 0xFFFFFFFF }, }; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 5b25e067b2f1..3820fe8f944a 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -166,25 +166,15 @@ static int fiji_setup_pwr_virus(struct pp_hwmgr *hwmgr) uint32_t reg, data; const PWR_Command_Table *pvirus = PwrVirusTable; - struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) { - switch (pvirus->command) { - case PwrCmdWrite: - reg = pvirus->reg; - data = pvirus->data; + reg = pvirus->reg; + data = pvirus->data; + if (reg != 0xffffffff) cgs_write_register(hwmgr->device, reg, data); - break; - - case PwrCmdEnd: + else { result = 0; break; - - default: - pr_info("Table Exit with Invalid Command!"); - smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL; - result = -EINVAL; - break; } pvirus++; } diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 22b8ecbf7fce..b73b2b445cee 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -67,25 +67,15 @@ static int polaris10_setup_pwr_virus(struct pp_hwmgr *hwmgr) uint32_t reg, data; const PWR_Command_Table *pvirus = pwr_virus_table; - struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) { - switch (pvirus->command) { - case PwrCmdWrite: - reg = pvirus->reg; - data = pvirus->data; + reg = pvirus->reg; + data = pvirus->data; + if (reg != 0xffffffff) { cgs_write_register(hwmgr->device, reg, data); - break; - - case PwrCmdEnd: + } else { result = 0; break; - - default: - pr_info("Table Exit with Invalid Command!"); - smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL; - result = -EINVAL; - break; } pvirus++; } -- cgit v1.2.3 From 2b6a81f437a7cc8787bae5d7ef64bf77cf8bb0ec Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 16:12:28 +1000 Subject: drm/amdgpu: use designated initialiser for thermal_irq_src. This fixes the 0-day build warning. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 73969f35846c..35e80c969737 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -124,9 +124,9 @@ static int phm_ctf_irq(void *private_data, } static const struct cgs_irq_src_funcs thermal_irq_src[3] = { - {NULL, phm_thermal_l2h_irq}, - {NULL, phm_thermal_h2l_irq}, - {NULL, phm_ctf_irq} + { .handler = phm_thermal_l2h_irq }, + { .handler = phm_thermal_h2l_irq }, + { .handler = phm_ctf_irq } }; int hwmgr_early_init(struct pp_instance *handle) -- cgit v1.2.3 From 7a88ef02c76dff12b0a9ea0e9da346f650e6f168 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 16:34:44 +1000 Subject: amdgpu/pp: reduce size of vega10_fuses_default I've no idea why this is like this, why store 64-bit fields as a string, and then parse the strings, this is just over engineered. Reduce the size of the amdgpu.o by 80k. text data bss dec hex filename 1331332 17982 1008 1350322 149ab2 amdgpu.o 1244668 17982 1008 1263658 13482a amdgpu.o Acked-by: Harry Wentland Acked-by: Alex Deucer Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c | 2485 ++++++++++---------- .../gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h | 2 +- 2 files changed, 1238 insertions(+), 1249 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c index 2b08371102be..8ba75d43fba6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.c @@ -2,1241 +2,1241 @@ #include static const struct phm_fuses_default vega10_fuses_default[] = { - {"0000001000010011111010101001010011011110000011100100100101100100",0x00003C96,0xFFFFE226,0x00000656,0x00002203,0xFFFFF201,0x000003FF,0x00002203,0xFFFFF201,0x000003FF}, - {"0000001000010011111010101001010011011110000010100001100010000100",0x00003CC5,0xFFFFE23A,0x0000064E,0x00002258,0xFFFFF1F7,0x000003FC,0x00002258,0xFFFFF1F7,0x000003FC}, - {"0000001000010011111010101001010011011110000011100011000110100100",0x00003CAF,0xFFFFE36E,0x00000602,0x00001E98,0xFFFFF569,0x00000357,0x00001E98,0xFFFFF569,0x00000357}, - {"0000001000010011111010101001010011011110001011000001000101000100",0x0000391A,0xFFFFE548,0x000005C9,0x00001B98,0xFFFFF707,0x00000324,0x00001B98,0xFFFFF707,0x00000324}, - {"0000001000010011111010101001010011011110001011000001100011000100",0x00003821,0xFFFFE674,0x00000597,0x00002196,0xFFFFF361,0x000003C0,0x00002196,0xFFFFF361,0x000003C0}, - {"0000001000010011111010101001010011011110001001100011100010000100",0x000044A2,0xFFFFDCB7,0x00000738,0x0000325C,0xFFFFE6A7,0x000005E6,0x0000325C,0xFFFFE6A7,0x000005E6}, - {"0000001000010011111010101001010011011110000010000010100100100100",0x00004057,0xFFFFE1CF,0x0000063C,0x00002E2E,0xFFFFEB62,0x000004FD,0x00002E2E,0xFFFFEB62,0x000004FD}, - {"0000001000010011111010101001010011011110001010000100100100100100",0x00003FD0,0xFFFFDF0F,0x000006E5,0x0000267C,0xFFFFEE2D,0x000004AB,0x0000267C,0xFFFFEE2D,0x000004AB}, - {"0000001000010011111010101001010011011110001010000000100100000100",0x00003F13,0xFFFFE010,0x000006AD,0x000020E7,0xFFFFF266,0x000003EC,0x000020E7,0xFFFFF266,0x000003EC}, - {"0000001000010011111010101001010011011110000010000010000001000100",0x00004088,0xFFFFDFAB,0x000006B6,0x0000252B,0xFFFFEFDB,0x00000458,0x0000252B,0xFFFFEFDB,0x00000458}, - {"0000001000010011111010101001010011011110001010000011100010000100",0x00003EF6,0xFFFFE017,0x000006AA,0x00001F67,0xFFFFF369,0x000003BE,0x00001F67,0xFFFFF369,0x000003BE}, - {"0000001000010011111010101001010011011110001011000010000110000100",0x00003CDD,0xFFFFE2A7,0x0000063C,0x000026C6,0xFFFFEF38,0x00000478,0x000026C6,0xFFFFEF38,0x00000478}, - {"0000001000010011111010101001010011011110000100000101000100100100",0x00003FA8,0xFFFFDF02,0x000006F0,0x000027FE,0xFFFFECF6,0x000004EA,0x000027FE,0xFFFFECF6,0x000004EA}, - {"0000001000010011111010101001010011011110001001100011100011000100",0x00004670,0xFFFFDC40,0x00000742,0x00003A7A,0xFFFFE1A7,0x000006B6,0x00003A7A,0xFFFFE1A7,0x000006B6}, - {"0000001000010011111010101001010011011110001011000011000000100100",0x00003CDC,0xFFFFE18C,0x00000683,0x00002A69,0xFFFFEBE7,0x00000515,0x00002A69,0xFFFFEBE7,0x00000515}, - {"0000001000010011111010101001010011011110000011100011100011000100",0x00003CEC,0xFFFFE38E,0x00000601,0x00002752,0xFFFFEFA7,0x00000453,0x00002752,0xFFFFEFA7,0x00000453}, - {"0000001000010011111010101001010011011110001011000001000100100100",0x000037D0,0xFFFFE634,0x000005A7,0x00001CD2,0xFFFFF644,0x00000348,0x00001CD2,0xFFFFF644,0x00000348}, - {"0000001000010011111010101001010011011110001010000011100101100100",0x00003DF5,0xFFFFE0A5,0x00000698,0x00001FD5,0xFFFFF30E,0x000003D1,0x00001FD5,0xFFFFF30E,0x000003D1}, - {"0000001000010011111010101001010011011110000010000010100011000100",0x00004201,0xFFFFE03E,0x00000688,0x00003206,0xFFFFE852,0x0000058A,0x00003206,0xFFFFE852,0x0000058A}, - {"0000001000010011111010101001010011011110001011000001100001100100",0x00003BED,0xFFFFE2F5,0x00000638,0x0000270D,0xFFFFEED0,0x0000048E,0x0000270D,0xFFFFEED0,0x0000048E}, - {"0000001000010011111010101001010011011110000010100001100100000100",0x00003E82,0xFFFFE1BE,0x00000654,0x000025FB,0xFFFFEFFA,0x00000448,0x000025FB,0xFFFFEFFA,0x00000448}, - {"0000001000010011111010101001010011011110001011000100000011000100",0x00003962,0xFFFFE4B9,0x000005EF,0x00002385,0xFFFFF156,0x00000423,0x00002385,0xFFFFF156,0x00000423}, - {"0000001000010011111010101001010011011110001011000000100101000100",0x00003D88,0xFFFFE21A,0x00000655,0x0000295A,0xFFFFED68,0x000004C4,0x0000295A,0xFFFFED68,0x000004C4}, - {"0000001000010011111010101001010011011110001011000001000100000100",0x00003AA4,0xFFFFE4A3,0x000005E0,0x000022EF,0xFFFFF250,0x000003EB,0x000022EF,0xFFFFF250,0x000003EB}, - {"0000001000010011111010101001010011011110000011100010100110100100",0x00003D97,0xFFFFE30D,0x0000060D,0x0000205D,0xFFFFF45D,0x00000380,0x0000205D,0xFFFFF45D,0x00000380}, - {"0000001000010011111010101001010011011110001011000100000010100100",0x000039B6,0xFFFFE446,0x00000605,0x00002325,0xFFFFF16C,0x0000041F,0x00002325,0xFFFFF16C,0x0000041F}, - {"0000001000010011111010101001010011011110001001100011100100000100",0x0000457E,0xFFFFDCF6,0x00000722,0x00003972,0xFFFFE27B,0x0000068E,0x00003972,0xFFFFE27B,0x0000068E}, - {"0000001000010011111010101001010011011110000010100001100100100100",0x00003FB8,0xFFFFE101,0x00000670,0x00002787,0xFFFFEEF5,0x00000471,0x00002787,0xFFFFEEF5,0x00000471}, - {"0000001000010011111010101001010011011110000011100011100010100100",0x00003BB2,0xFFFFE430,0x000005EA,0x000024A5,0xFFFFF162,0x00000409,0x000024A5,0xFFFFF162,0x00000409}, - {"0000001000010011111010101001010011011110000010000010000101000100",0x00003EC5,0xFFFFE1BD,0x0000064F,0x000022F0,0xFFFFF227,0x000003E8,0x000022F0,0xFFFFF227,0x000003E8}, - {"0000001000010011111010101001010011011110001011000011000101100100",0x000038A7,0xFFFFE59F,0x000005C1,0x000021CC,0xFFFFF2DF,0x000003D9,0x000021CC,0xFFFFF2DF,0x000003D9}, - {"0000001000010011111010101001010011011110001100100100000110000100",0x00002995,0xFFFFEF7A,0x0000044C,0x00001552,0xFFFFFB5D,0x00000292,0x00001552,0xFFFFFB5D,0x00000292}, - {"0000001000010011111010101001010011011110001011000100000001100100",0x00003B26,0xFFFFE2D3,0x00000649,0x000023B4,0xFFFFF09B,0x00000449,0x000023B4,0xFFFFF09B,0x00000449}, - {"0000001000010011111010101001010011011110000010000001000100100100",0x000040D2,0xFFFFE00A,0x00000696,0x000022DA,0xFFFFF1E9,0x000003F2,0x000022DA,0xFFFFF1E9,0x000003F2}, - {"0000001000010011111010101001010011011110001011000011100100100100",0x00003C98,0xFFFFE365,0x00000618,0x00002D5D,0xFFFFEB3A,0x0000051D,0x00002D5D,0xFFFFEB3A,0x0000051D}, - {"0000001000010011111010101001010011011110001011000001000010100100",0x00003BBD,0xFFFFE37E,0x00000617,0x0000252E,0xFFFFF06E,0x00000441,0x0000252E,0xFFFFF06E,0x00000441}, - {"0000001000010011111010101001010011011110001001100010100100100100",0x00004363,0xFFFFDF7A,0x000006A0,0x000031F5,0xFFFFE880,0x0000057B,0x000031F5,0xFFFFE880,0x0000057B}, - {"0000001000010011111010101001010011011110000011100011100001000100",0x00003CFC,0xFFFFE2AF,0x0000062E,0x0000212A,0xFFFFF335,0x000003BF,0x0000212A,0xFFFFF335,0x000003BF}, - {"0000001000010011111010101001010011011110000111000100100100100100",0x0000252D,0xFFFFF31B,0x000003C3,0x00001A1A,0xFFFFF882,0x00000325,0x00001A1A,0xFFFFF882,0x00000325}, - {"0000001000010011111010101001010011011110000010100010100110100100",0x00003FE2,0xFFFFDFEF,0x000006AC,0x000025A2,0xFFFFEF84,0x00000462,0x000025A2,0xFFFFEF84,0x00000462}, - {"0000001000010011111010101001010011011110000010000010000011100100",0x000040A5,0xFFFFE13B,0x0000065B,0x00002C13,0xFFFFEC75,0x000004D7,0x00002C13,0xFFFFEC75,0x000004D7}, - {"0000001000010011111010101001010011011110000011100100100010100100",0x00003E42,0xFFFFE1B3,0x00000657,0x0000221D,0xFFFFF273,0x000003DE,0x0000221D,0xFFFFF273,0x000003DE}, - {"0000001000010011111010101001010011011110000010100010000011100100",0x00003E7F,0xFFFFE255,0x00000638,0x00002D30,0xFFFFEB8A,0x00000503,0x00002D30,0xFFFFEB8A,0x00000503}, - {"0000001000010011111010101001010011011110001011000010100111000100",0x00003E56,0xFFFFE16D,0x00000670,0x000028DC,0xFFFFEDA0,0x000004BA,0x000028DC,0xFFFFEDA0,0x000004BA}, - {"0000001000010011111010101001010011011110001001100011000010100100",0x000044AD,0xFFFFDE24,0x000006DD,0x000031AD,0xFFFFE850,0x00000585,0x000031AD,0xFFFFE850,0x00000585}, - {"0000001000010011111010101001010011011110001011000010000011100100",0x00003AF3,0xFFFFE5B0,0x000005A6,0x00002CF6,0xFFFFEC75,0x000004DD,0x00002CF6,0xFFFFEC75,0x000004DD}, - {"0000001000010011111010101001010011011110000010100010000010000100",0x00003E66,0xFFFFE19E,0x0000065B,0x00002332,0xFFFFF1B9,0x000003FD,0x00002332,0xFFFFF1B9,0x000003FD}, - {"0000001000010011111010101001010011011110000010000010100010000100",0x00003FB4,0xFFFFE0A5,0x00000686,0x0000253E,0xFFFFF02E,0x00000444,0x0000253E,0xFFFFF02E,0x00000444}, - {"0000001000010011111010101001010011011110001010000001100010100100",0x00003E28,0xFFFFE14D,0x0000066E,0x00001FE2,0xFFFFF39A,0x000003B1,0x00001FE2,0xFFFFF39A,0x000003B1}, - {"0000001000010011111010101001010011011110001011000000100100000100",0x000039E6,0xFFFFE44B,0x000005FE,0x0000210C,0xFFFFF2F4,0x000003DA,0x0000210C,0xFFFFF2F4,0x000003DA}, - {"0000001000010011111010101001010011011110001011000101000100000100",0x00003A4D,0xFFFFE252,0x0000067A,0x000027E2,0xFFFFECED,0x000004FA,0x000027E2,0xFFFFECED,0x000004FA}, - {"0000001000010011111010101001010011011110000010100010100101100100",0x00004065,0xFFFFE02F,0x0000069B,0x0000299D,0xFFFFED38,0x000004C2,0x0000299D,0xFFFFED38,0x000004C2}, - {"0000001000010011111010101001010011011110000011100010000010100100",0x000039EE,0xFFFFE603,0x00000594,0x0000214F,0xFFFFF429,0x0000038E,0x0000214F,0xFFFFF429,0x0000038E}, - {"0000001000010011111010101001010011011110000011100100100011100100",0x00003BD2,0xFFFFE351,0x00000618,0x000020B8,0xFFFFF377,0x000003B4,0x000020B8,0xFFFFF377,0x000003B4}, - {"0000001000010011111010101001010011011110000010100011000100100100",0x00003FAA,0xFFFFE183,0x0000065E,0x000032AE,0xFFFFE7C2,0x000005A6,0x000032AE,0xFFFFE7C2,0x000005A6}, - {"0000001000010011111010101001010011011110001011000010100110000100",0x00003AFB,0xFFFFE3E4,0x00000608,0x00002293,0xFFFFF21F,0x000003FA,0x00002293,0xFFFFF21F,0x000003FA}, - {"0000001000010011111010101001010011011110001001100010000001100100",0x0000448B,0xFFFFDD5D,0x0000070D,0x00002E4E,0xFFFFE9DF,0x00000551,0x00002E4E,0xFFFFE9DF,0x00000551}, - {"0000001000010011111010101001010011011110000011100010000110000100",0x00003D46,0xFFFFE39B,0x000005F3,0x0000218E,0xFFFFF3CD,0x00000398,0x0000218E,0xFFFFF3CD,0x00000398}, - {"0000001000010011111010101001010011011110000010000100100011100100",0x00003F01,0xFFFFDFD9,0x000006BF,0x000023AF,0xFFFFF04E,0x0000044C,0x000023AF,0xFFFFF04E,0x0000044C}, - {"0000001000010011111010101001010011011110000100000010100110100100",0x0000403D,0xFFFFDF6B,0x000006C9,0x0000270D,0xFFFFEE4B,0x0000049E,0x0000270D,0xFFFFEE4B,0x0000049E}, - {"0000001000010011111010101001010011011110000011100011100101100100",0x00003C11,0xFFFFE35C,0x00000613,0x000020F9,0xFFFFF365,0x000003B9,0x000020F9,0xFFFFF365,0x000003B9}, - {"0000001000010011111010101001010011011110001011000011100010000100",0x00003B58,0xFFFFE37D,0x0000061F,0x00002698,0xFFFFEF46,0x00000478,0x00002698,0xFFFFEF46,0x00000478}, - {"0000001000010011111010101001010011011110001010000100000110100100",0x00003EBC,0xFFFFDF7A,0x000006D6,0x0000212B,0xFFFFF195,0x0000041B,0x0000212B,0xFFFFF195,0x0000041B}, - {"0000001000010011111010101001010011011110000010000100100011000100",0x00004050,0xFFFFDEB3,0x000006FE,0x00002D6C,0xFFFFE961,0x00000582,0x00002D6C,0xFFFFE961,0x00000582}, - {"0000001000010011111010101001010011011110001001100010000001000100",0x000043F0,0xFFFFDD9C,0x00000702,0x00002B31,0xFFFFEBEA,0x000004F7,0x00002B31,0xFFFFEBEA,0x000004F7}, - {"0000001000010011111010101001010011011110000100000000100100100100",0x00003EFA,0xFFFFE093,0x00000696,0x000026DB,0xFFFFEEB3,0x00000489,0x000026DB,0xFFFFEEB3,0x00000489}, - {"0000001000010011111010101001010011011110000010000010000001100100",0x0000425D,0xFFFFDE8D,0x000006E6,0x00002CA4,0xFFFFEAD2,0x00000531,0x00002CA4,0xFFFFEAD2,0x00000531}, - {"0000001000010011111010101001010011011110001001100011100110100100",0x000043B0,0xFFFFDD03,0x00000728,0x00002946,0xFFFFECA6,0x000004DE,0x00002946,0xFFFFECA6,0x000004DE}, - {"0000001000010011111010101001010011011110001010000010100001100100",0x00003F6A,0xFFFFE03A,0x0000069D,0x00002208,0xFFFFF1F8,0x000003F6,0x00002208,0xFFFFF1F8,0x000003F6}, - {"0000001000010011111010101001010011011110001011000010100101100100",0x00003A94,0xFFFFE4A7,0x000005E2,0x000024D0,0xFFFFF100,0x00000426,0x000024D0,0xFFFFF100,0x00000426}, - {"0000001000010011111010101001010011011110001010000001000011000100",0x00003F2F,0xFFFFE0A3,0x00000688,0x00002198,0xFFFFF271,0x000003E2,0x00002198,0xFFFFF271,0x000003E2}, - {"0000001000010011111010101001010011011110000100000100100011100100",0x00003EA5,0xFFFFE032,0x000006AE,0x0000227C,0xFFFFF130,0x00000426,0x0000227C,0xFFFFF130,0x00000426}, - {"0000001000010011111010101001010011011110001001100100000101000100",0x0000442F,0xFFFFDBC4,0x0000078B,0x00003CD6,0xFFFFDE6C,0x0000076C,0x00003CD6,0xFFFFDE6C,0x0000076C}, - {"0000001000010011111010101001010011011110001010000010100010000100",0x00003DDE,0xFFFFE174,0x00000668,0x00001FF4,0xFFFFF38F,0x000003B1,0x00001FF4,0xFFFFF38F,0x000003B1}, - {"0000001000010011111010101001010011011110000010100011000101000100",0x000040B0,0xFFFFE016,0x000006A0,0x00002DBB,0xFFFFEA7F,0x00000537,0x00002DBB,0xFFFFEA7F,0x00000537}, - {"0000001000010011111010101001010011011110001011000011000100000100",0x00003429,0xFFFFEA97,0x000004DD,0x000024D5,0xFFFFF26F,0x000003DF,0x000024D5,0xFFFFF26F,0x000003DF}, - {"0000001000010011111010101001010011011110000011100001100100000100",0x00003AEB,0xFFFFE590,0x000005A3,0x000022CB,0xFFFFF347,0x000003B2,0x000022CB,0xFFFFF347,0x000003B2}, - {"0000001000010011111010101001010011011110001010000011100100000100",0x00003B8E,0xFFFFE2EF,0x00000636,0x00002351,0xFFFFF143,0x0000041C,0x00002351,0xFFFFF143,0x0000041C}, - {"0000001000010011111010101001010011011110001100100100000011000100",0x00002926,0xFFFFF0B0,0x00000410,0x0000194E,0xFFFFF94E,0x000002E9,0x0000194E,0xFFFFF94E,0x000002E9}, - {"0000001000010011111010101001010011011110001010000011000110000100",0x0000402B,0xFFFFDF78,0x000006C2,0x00002273,0xFFFFF16C,0x00000414,0x00002273,0xFFFFF16C,0x00000414}, - {"0000001000010011111010101001010011011110000010100001000010100100",0x00003D6A,0xFFFFE1D3,0x00000659,0x00002006,0xFFFFF394,0x000003B1,0x00002006,0xFFFFF394,0x000003B1}, - {"0000001000010011111010101001010011011110001010000100000001100100",0x00004042,0xFFFFDFD8,0x000006A8,0x00002135,0xFFFFF29F,0x000003D9,0x00002135,0xFFFFF29F,0x000003D9}, - {"0000001000010011111010101001010011011110000010000010000010100100",0x0000405B,0xFFFFE093,0x00000682,0x0000288F,0xFFFFEE3A,0x00000491,0x0000288F,0xFFFFEE3A,0x00000491}, - {"0000001000010011111010101001010011011110001011000100100010100100",0x00003A49,0xFFFFE30C,0x00000648,0x000023F9,0xFFFFF02D,0x00000460,0x000023F9,0xFFFFF02D,0x00000460}, - {"0000001000010011111010101001010011011110001010000010100101100100",0x00003D59,0xFFFFE1CC,0x0000065B,0x00002013,0xFFFFF37D,0x000003B6,0x00002013,0xFFFFF37D,0x000003B6}, - {"0000001000010011111010101001010011011110001011000011100110000100",0x000040C1,0xFFFFDF8C,0x000006CA,0x00003271,0xFFFFE6CA,0x000005EA,0x00003271,0xFFFFE6CA,0x000005EA}, - {"0000001000010011111010101001010011011110001001100010000011100100",0x000042E9,0xFFFFDFDC,0x0000068C,0x00002ED9,0xFFFFEAAF,0x0000051B,0x00002ED9,0xFFFFEAAF,0x0000051B}, - {"0000001000010011111010101001010011011110000010000011000010000100",0x000042ED,0xFFFFDE50,0x000006F0,0x00002FCF,0xFFFFE8BB,0x0000058C,0x00002FCF,0xFFFFE8BB,0x0000058C}, - {"0000001000010011111010101001010011011110000010100100000100000100",0x00003EBD,0xFFFFE099,0x00000698,0x00002709,0xFFFFEE7B,0x00000495,0x00002709,0xFFFFEE7B,0x00000495}, - {"0000001000010011111010101001010011011110001010000100100100000100",0x00003F71,0xFFFFDF82,0x000006C9,0x0000219B,0xFFFFF1AD,0x0000040F,0x0000219B,0xFFFFF1AD,0x0000040F}, - {"0000001000010011111010101001010011011110001010000000100011100100",0x00003E73,0xFFFFE080,0x0000069B,0x000020E7,0xFFFFF273,0x000003E9,0x000020E7,0xFFFFF273,0x000003E9}, - {"0000001000010011111010101001010011011110000011100011000110000100",0x00003E14,0xFFFFE278,0x0000062C,0x00002275,0xFFFFF2B3,0x000003CE,0x00002275,0xFFFFF2B3,0x000003CE}, - {"0000001000010011111010101001010011011110001011000010000110100100",0x00003ABB,0xFFFFE3B9,0x00000615,0x00002192,0xFFFFF28F,0x000003EB,0x00002192,0xFFFFF28F,0x000003EB}, - {"0000001000010011111010101001010011011110001010000011000100100100",0x00003D53,0xFFFFE255,0x00000643,0x0000275B,0xFFFFEEED,0x00000479,0x0000275B,0xFFFFEEED,0x00000479}, - {"0000001000010011111010101001010011011110001001100010100001100100",0x000043E3,0xFFFFDDC3,0x000006FB,0x00002B6B,0xFFFFEBD6,0x000004FA,0x00002B6B,0xFFFFEBD6,0x000004FA}, - {"0000001000010011111010101001010011011110000011100010000101000100",0x00003BDE,0xFFFFE507,0x000005B4,0x000022CE,0xFFFFF358,0x000003AB,0x000022CE,0xFFFFF358,0x000003AB}, - {"0000001000010011111010101001010011011110001100100011000101100100",0x00002460,0xFFFFF3B5,0x000003A2,0x000014E7,0xFFFFFC32,0x0000027C,0x000014E7,0xFFFFFC32,0x0000027C}, - {"0000001000010011111010101001010011011110001010000010000011000100",0x00003D20,0xFFFFE298,0x0000062F,0x00002080,0xFFFFF3AF,0x000003A8,0x00002080,0xFFFFF3AF,0x000003A8}, - {"0000001000010011111010101001010011011110000010000001100100000100",0x00003E14,0xFFFFE221,0x00000641,0x000021BB,0xFFFFF2EA,0x000003CA,0x000021BB,0xFFFFF2EA,0x000003CA}, - {"0000001000010011111010101001010011011110000010100100000011000100",0x00003DE1,0xFFFFE14E,0x00000677,0x00002468,0xFFFFF068,0x00000440,0x00002468,0xFFFFF068,0x00000440}, - {"0000001000010011111010101001010011011110001001100001000010000100",0x00004372,0xFFFFDDF8,0x000006F5,0x00002B3F,0xFFFFEBE8,0x000004F8,0x00002B3F,0xFFFFEBE8,0x000004F8}, - {"0000001000010011111010101001010011011110000010100010100011000100",0x00003E4F,0xFFFFE2A3,0x0000062B,0x00002F5A,0xFFFFEA37,0x0000053B,0x00002F5A,0xFFFFEA37,0x0000053B}, - {"0000001000010011111010101001010011011110001010000101000011100100",0x00003E07,0xFFFFE02F,0x000006B6,0x0000216B,0xFFFFF1A3,0x00000416,0x0000216B,0xFFFFF1A3,0x00000416}, - {"0000001000010011111010101001010011011110001010000011100010100100",0x00003DAB,0xFFFFE128,0x0000067F,0x0000216F,0xFFFFF236,0x000003F3,0x0000216F,0xFFFFF236,0x000003F3}, - {"0000001000010011111010101001010011011110001011000010100100100100",0x0000364B,0xFFFFE8CB,0x0000052A,0x00002568,0xFFFFF1B2,0x00000400,0x00002568,0xFFFFF1B2,0x00000400}, - {"0000001000010011111010101001010011011110001001100001000001100100",0x00004219,0xFFFFDE87,0x000006E8,0x00002C59,0xFFFFEAEE,0x00000529,0x00002C59,0xFFFFEAEE,0x00000529}, - {"0000001000010011111010101001010011011110000011100001100101000100",0x000039A8,0xFFFFE602,0x00000594,0x00001D06,0xFFFFF6F0,0x00000316,0x00001D06,0xFFFFF6F0,0x00000316}, - {"0000001000010011111010101001010011011110001001100001000011100100",0x00004052,0xFFFFE01C,0x00000698,0x00002310,0xFFFFF1A1,0x000003FE,0x00002310,0xFFFFF1A1,0x000003FE}, - {"0000001000010011111010101001010011011110000011100010100000100100",0x00003C1C,0xFFFFE3EB,0x000005F1,0x00002289,0xFFFFF2CF,0x000003C9,0x00002289,0xFFFFF2CF,0x000003C9}, - {"0000001000010011111010101001010011011110000011100101000100100100",0x00003F19,0xFFFFE085,0x0000069E,0x00002B94,0xFFFFEB72,0x0000051D,0x00002B94,0xFFFFEB72,0x0000051D}, - {"0000001000010011111010101001010011011110000011100100000110100100",0x00003C51,0xFFFFE2AD,0x00000638,0x0000206B,0xFFFFF361,0x000003BE,0x0000206B,0xFFFFF361,0x000003BE}, - {"0000001000010011111010101001010011011110001001100001000011000100",0x000040B9,0xFFFFDFBB,0x000006AB,0x0000241F,0xFFFFF0CC,0x00000425,0x0000241F,0xFFFFF0CC,0x00000425}, - {"0000001000010011111010101001010011011110000010100010000001100100",0x00003E62,0xFFFFE12C,0x00000678,0x00002445,0xFFFFF09E,0x00000435,0x00002445,0xFFFFF09E,0x00000435}, - {"0000001000010011111010101001010011011110000011100001100110000100",0x00003C97,0xFFFFE399,0x000005FB,0x0000209D,0xFFFFF41D,0x0000038F,0x0000209D,0xFFFFF41D,0x0000038F}, - {"0000001000010011111010101001010011011110000011100011000101000100",0x00003FF9,0xFFFFE1E9,0x0000063E,0x00002E96,0xFFFFEAF5,0x00000516,0x00002E96,0xFFFFEAF5,0x00000516}, - {"0000001000010011111010101001010011011110000010100011000010000100",0x00003F04,0xFFFFE109,0x0000067A,0x000026E1,0xFFFFEF0B,0x00000476,0x000026E1,0xFFFFEF0B,0x00000476}, - {"0000001000010011111010101001010011011110000100000001000100100100",0x00003E3E,0xFFFFE187,0x00000660,0x00002049,0xFFFFF38D,0x000003B0,0x00002049,0xFFFFF38D,0x000003B0}, - {"0000001000010011111010101001010011011110001010000010100101000100",0x00003D58,0xFFFFE253,0x0000063D,0x00002158,0xFFFFF308,0x000003C3,0x00002158,0xFFFFF308,0x000003C3}, - {"0000001000010011111010101001010011011110000010000100000011000100",0x00004074,0xFFFFDF8D,0x000006C0,0x00002799,0xFFFFEE19,0x000004A5,0x00002799,0xFFFFEE19,0x000004A5}, - {"0000001000010011111010101001010011011110001010000001100100100100",0x00003DAF,0xFFFFE1C9,0x00000659,0x000020E5,0xFFFFF313,0x000003C6,0x000020E5,0xFFFFF313,0x000003C6}, - {"0000001000010011111010101001010011011110000010100011100101100100",0x000041DD,0xFFFFDDFA,0x0000071B,0x0000348D,0xFFFFE4B4,0x0000064C,0x0000348D,0xFFFFE4B4,0x0000064C}, - {"0000001000010011111010101001010011011110001011000010100010000100",0x00003947,0xFFFFE5AE,0x000005B8,0x000024A6,0xFFFFF140,0x0000041D,0x000024A6,0xFFFFF140,0x0000041D}, - {"0000001000010011111010101001010011011110000100000001100001000100",0x00003D35,0xFFFFE197,0x0000066E,0x00002248,0xFFFFF1BC,0x00000408,0x00002248,0xFFFFF1BC,0x00000408}, - {"0000001000010011111010101001010011011110000010100001100011100100",0x00003F4F,0xFFFFE13E,0x0000066D,0x00002AF0,0xFFFFEC99,0x000004DB,0x00002AF0,0xFFFFEC99,0x000004DB}, - {"0000001000010011111010101001010011011110001001100011100101000100",0x0000430F,0xFFFFDDFB,0x000006FC,0x00002D4D,0xFFFFEA55,0x00000540,0x00002D4D,0xFFFFEA55,0x00000540}, - {"0000001000010011111010101001010011011110000011100010100101000100",0x00003B22,0xFFFFE543,0x000005B1,0x000022E1,0xFFFFF31B,0x000003B9,0x000022E1,0xFFFFF31B,0x000003B9}, - {"0000001000010011111010101001010011011110000011100010000010000100",0x00003978,0xFFFFE611,0x00000592,0x00001C36,0xFFFFF771,0x00000302,0x00001C36,0xFFFFF771,0x00000302}, - {"0000001000010011111010101001010011011110001001100010000101100100",0x000044DF,0xFFFFDDAB,0x000006F2,0x00002CEA,0xFFFFEB47,0x00000507,0x00002CEA,0xFFFFEB47,0x00000507}, - {"0000001000010011111010101001010011011110000010100011100011000100",0x00003E9B,0xFFFFE12C,0x0000067C,0x00002B79,0xFFFFEBD9,0x00000503,0x00002B79,0xFFFFEBD9,0x00000503}, - {"0000001000010011111010101001010011011110001001100011000001000100",0x00004464,0xFFFFDCD3,0x00000731,0x00002D14,0xFFFFEA2D,0x0000054E,0x00002D14,0xFFFFEA2D,0x0000054E}, - {"0000001000010011111010101001010011011110001010000001000100100100",0x00003FB3,0xFFFFE052,0x00000693,0x000020AC,0xFFFFF311,0x000003C6,0x000020AC,0xFFFFF311,0x000003C6}, - {"0000001000010011111010101001010011011110001011000001000010000100",0x00003BDA,0xFFFFE2FB,0x00000636,0x0000261E,0xFFFFEF72,0x00000471,0x0000261E,0xFFFFEF72,0x00000471}, - {"0000001000010011111010101001010011011110001011000001100101100100",0x00003D72,0xFFFFE28A,0x0000063E,0x000029D8,0xFFFFED54,0x000004C7,0x000029D8,0xFFFFED54,0x000004C7}, - {"0000001000010011111010101001010011011110001011000010100000100100",0x00003E26,0xFFFFE102,0x00000694,0x00002DD1,0xFFFFE9CA,0x0000056D,0x00002DD1,0xFFFFE9CA,0x0000056D}, - {"0000001000010011111010101001010011011110000100000100000100100100",0x000041CD,0xFFFFDE97,0x000006ED,0x00002DE5,0xFFFFE9B9,0x00000565,0x00002DE5,0xFFFFE9B9,0x00000565}, - {"0000001000010011111010101001010011011110000010100010100110000100",0x00003F30,0xFFFFE06E,0x00000698,0x000024FF,0xFFFFEFFC,0x0000044F,0x000024FF,0xFFFFEFFC,0x0000044F}, - {"0000001000010011111010101001010011011110001011000011100011000100",0x0000378B,0xFFFFE6B4,0x00000594,0x000023A7,0xFFFFF1DC,0x00000407,0x000023A7,0xFFFFF1DC,0x00000407}, - {"0000001000010011111010101001010011011110000011100100000101100100",0x00003CD7,0xFFFFE28D,0x00000636,0x00002036,0xFFFFF3B5,0x000003AA,0x00002036,0xFFFFF3B5,0x000003AA}, - {"0000001000010011111010101001010011011110000010100011100010000100",0x00003EF9,0xFFFFE0AA,0x0000068D,0x000024D3,0xFFFFF02F,0x00000445,0x000024D3,0xFFFFF02F,0x00000445}, - {"0000001000010011111010101001010011011110001010000011100101000100",0x00003D08,0xFFFFE1BB,0x00000665,0x00002159,0xFFFFF26F,0x000003E6,0x00002159,0xFFFFF26F,0x000003E6}, - {"0000001000010011111010101001010011011110001011000010000011000100",0x000038A9,0xFFFFE6CA,0x00000580,0x000025D3,0xFFFFF101,0x00000421,0x000025D3,0xFFFFF101,0x00000421}, - {"0000001000010011111010101001010011011110000010100010000010100100",0x00003E45,0xFFFFE1F8,0x0000064D,0x000027E3,0xFFFFEEBB,0x0000047F,0x000027E3,0xFFFFEEBB,0x0000047F}, - {"0000001000010011111010101001010011011110000011100011100001100100",0x00003F76,0xFFFFE128,0x0000066E,0x0000286B,0xFFFFEE4C,0x00000493,0x0000286B,0xFFFFEE4C,0x00000493}, - {"0000001000010011111010101001010011011110001001100100000100000100",0x0000440D,0xFFFFDCA2,0x0000074F,0x00003817,0xFFFFE256,0x000006AF,0x00003817,0xFFFFE256,0x000006AF}, - {"0000001000010011111010101001010011011110000100000101000100000100",0x00003EE1,0xFFFFDFA7,0x000006D4,0x000027EA,0xFFFFED2B,0x000004DE,0x000027EA,0xFFFFED2B,0x000004DE}, - {"0000001000010011111010101001010011011110001011000011100001100100",0x00003C62,0xFFFFE285,0x0000064A,0x00002520,0xFFFFF001,0x0000045C,0x00002520,0xFFFFF001,0x0000045C}, - {"0000001000010011111010101001010011011110001100100011100101100100",0x0000272E,0xFFFFF17A,0x000003FA,0x0000150B,0xFFFFFBD5,0x00000284,0x0000150B,0xFFFFFBD5,0x00000284}, - {"0000001000010011111010101001010011011110001001100001100100100100",0x00004275,0xFFFFDF69,0x000006A5,0x000025AA,0xFFFFF05C,0x0000042B,0x000025AA,0xFFFFF05C,0x0000042B}, - {"0000001000010011111010101001010011011110000011100100000011100100",0x00003CAA,0xFFFFE392,0x000005FF,0x000023A8,0xFFFFF20E,0x000003E9,0x000023A8,0xFFFFF20E,0x000003E9}, - {"0000001000010011111010101001010011011110001011000101000011000100",0x00003CF8,0xFFFFE0FB,0x000006A6,0x00002CA7,0xFFFFE9FF,0x0000056E,0x00002CA7,0xFFFFE9FF,0x0000056E}, - {"0000001000010011111010101001010011011110001010000010000100100100",0x00003D00,0xFFFFE296,0x00000633,0x000021C1,0xFFFFF2C8,0x000003CF,0x000021C1,0xFFFFF2C8,0x000003CF}, - {"0000001000010011111010101001010011011110001010000011100011100100",0x00003B46,0xFFFFE301,0x00000632,0x0000204C,0xFFFFF33B,0x000003C8,0x0000204C,0xFFFFF33B,0x000003C8}, - {"0000001000010011111010101001010011011110001000000100000101100100",0x00002026,0xFFFFF5CE,0x00000368,0x00001598,0xFFFFFB29,0x000002C3,0x00001598,0xFFFFFB29,0x000002C3}, - {"0000001000010011111010101001010011011110001010000011000101100100",0x00003DCA,0xFFFFE178,0x00000668,0x00001FDB,0xFFFFF39D,0x000003AF,0x00001FDB,0xFFFFF39D,0x000003AF}, - {"0000001000010011111010101001010011011110001011000100100011000100",0x00003A59,0xFFFFE327,0x00000642,0x000024B9,0xFFFFEFC4,0x00000471,0x000024B9,0xFFFFEFC4,0x00000471}, - {"0000001000010011111010101001010011011110001011000010100101000100",0x00003C26,0xFFFFE440,0x000005EB,0x00002C0F,0xFFFFEC88,0x000004E0,0x00002C0F,0xFFFFEC88,0x000004E0}, - {"0000001000010011111010101001010011011110000010000011100010000100",0x00004149,0xFFFFDEB8,0x000006E7,0x0000280A,0xFFFFED89,0x000004C2,0x0000280A,0xFFFFED89,0x000004C2}, - {"0000001000010011111010101001010011011110000011100100000100100100",0x00003EB4,0xFFFFE1E5,0x0000064D,0x0000299F,0xFFFFEDB3,0x000004A9,0x0000299F,0xFFFFEDB3,0x000004A9}, - {"0000001000010011111010101001010011011110001011000011100110100100",0x00003BBF,0xFFFFE268,0x0000065A,0x00002504,0xFFFFEFB0,0x00000470,0x00002504,0xFFFFEFB0,0x00000470}, - {"0000001000010011111010101001010011011110000010000100100100000100",0x00004203,0xFFFFDDC6,0x00000720,0x0000303B,0xFFFFE78F,0x000005D0,0x0000303B,0xFFFFE78F,0x000005D0}, - {"0000001000010011111010101001010011011110000011100011100110000100",0x00003DA3,0xFFFFE244,0x0000063E,0x000021B4,0xFFFFF2DA,0x000003CD,0x000021B4,0xFFFFF2DA,0x000003CD}, - {"0000001000010011111010101001010011011110000010100011100011100100",0x00004035,0xFFFFE065,0x0000069B,0x00003323,0xFFFFE6D6,0x000005D8,0x00003323,0xFFFFE6D6,0x000005D8}, - {"0000001000010011111010101001010011011110001011000001000101100100",0x00003944,0xFFFFE4E5,0x000005E2,0x00001F3C,0xFFFFF456,0x0000039D,0x00001F3C,0xFFFFF456,0x0000039D}, - {"0000001000010011111010101001010011011110000001100001100100000100",0x000032D8,0xFFFFEAE8,0x000004E6,0x00001812,0xFFFFFA1C,0x000002BC,0x00001812,0xFFFFFA1C,0x000002BC}, - {"0000001000010011111100001111110101000010110100100010100101000100",0x000041F6,0xFFFFE025,0x0000069A,0x0000241E,0xFFFFF1B4,0x00000402,0x0000241E,0xFFFFF1B4,0x00000402}, - {"0000001000010011111100001111111010011001000011000011000010100100",0x00003300,0xFFFFEB60,0x000004C1,0x00001E15,0xFFFFF6A6,0x0000033B,0x00001E15,0xFFFFF6A6,0x0000033B}, - {"0000001000010011111010101001010011011110000001000000100010100100",0x000037F0,0xFFFFE68F,0x0000059B,0x00001F8A,0xFFFFF467,0x000003A3,0x00001F8A,0xFFFFF467,0x000003A3}, - {"0000001000010011111100001111111010011001000110000010100110000100",0x000025D8,0xFFFFF2AA,0x000003C3,0x000018A8,0xFFFFF9BE,0x000002D2,0x000018A8,0xFFFFF9BE,0x000002D2}, - {"0000001000010011111100001111111010011001000001100010000011000100",0x0000364F,0xFFFFE988,0x000004FC,0x00001E51,0xFFFFF633,0x0000034F,0x00001E51,0xFFFFF633,0x0000034F}, - {"0000001000010011111010101001010011011110000001100001000101000100",0x00002288,0xFFFFF483,0x0000036C,0x0000280F,0xFFFFEF39,0x0000047B,0x0000280F,0xFFFFEF39,0x0000047B}, - {"0000001000010011111100001111111010011001000010000010000010000100",0x00003322,0xFFFFEA7E,0x000004ED,0x00001DAD,0xFFFFF62B,0x00000355,0x00001DAD,0xFFFFF62B,0x00000355}, - {"0000001000010011111010101001010011011110000000100101000011100100",0x00002B7B,0xFFFFEE4F,0x0000045B,0x00001AA2,0xFFFFF710,0x0000033E,0x00001AA2,0xFFFFF710,0x0000033E}, - {"0000001000010011111100001111111010011001000001000010000011000100",0x000034CC,0xFFFFEA79,0x000004E4,0x00001B05,0xFFFFF8B3,0x000002EC,0x00001B05,0xFFFFF8B3,0x000002EC}, - {"0000001000010011111100001111110101000010110111000010100001100100",0x00003837,0xFFFFE5ED,0x000005C3,0x00001ACB,0xFFFFF7B2,0x00000314,0x00001ACB,0xFFFFF7B2,0x00000314}, - {"0000001000010011111100001111111010011001000001000100000101100100",0x0000352D,0xFFFFE88F,0x00000548,0x000021E6,0xFFFFF3B5,0x000003AA,0x000021E6,0xFFFFF3B5,0x000003AA}, - {"0000001000010011111100001111111010011001000010100100100010000100",0x00003300,0xFFFFE835,0x0000057B,0x00001A85,0xFFFFF715,0x00000336,0x00001A85,0xFFFFF715,0x00000336}, - {"0000001000010011111010101001010011011110000001000100100010100100",0x000033FA,0xFFFFE851,0x00000565,0x00001A8E,0xFFFFF727,0x0000033B,0x00001A8E,0xFFFFF727,0x0000033B}, - {"0000001000010011111100001111110101000010110110100011100100100100",0x000039D3,0xFFFFE5D3,0x000005B0,0x00001888,0xFFFFF978,0x000002C8,0x00001888,0xFFFFF978,0x000002C8}, - {"0000001000010011111100001111111010011001000011100100100001100100",0x00002F6B,0xFFFFEC53,0x000004B9,0x00001C15,0xFFFFF71B,0x00000337,0x00001C15,0xFFFFF71B,0x00000337}, - {"0000001000010011111100001111111010011001000001100100000101000100",0x0000384D,0xFFFFE737,0x00000569,0x00001D2D,0xFFFFF673,0x00000343,0x00001D2D,0xFFFFF673,0x00000343}, - {"0000001000010011111100001111111010011001000001100010000010100100",0x00003A49,0xFFFFE70B,0x0000055F,0x00001A63,0xFFFFF8CD,0x000002E2,0x00001A63,0xFFFFF8CD,0x000002E2}, - {"0000001000010011111100001111111010011001000001000010100110000100",0x0000311E,0xFFFFEB97,0x000004C6,0x00001EAE,0xFFFFF5A9,0x00000367,0x00001EAE,0xFFFFF5A9,0x00000367}, - {"0000001000010011111100001111111010011001000011100001000100100100",0x000027D3,0xFFFFF075,0x00000417,0x00002001,0xFFFFF44A,0x000003A2,0x00002001,0xFFFFF44A,0x000003A2}, - {"0000001000010011111100001111111010011001000001100100100100000100",0x00003B72,0xFFFFE4BD,0x000005DC,0x00001D76,0xFFFFF606,0x0000035A,0x00001D76,0xFFFFF606,0x0000035A}, - {"0000001000010011111100001111111010011001000100000001000100100100",0x00002E0F,0xFFFFECA7,0x000004AE,0x00001DC6,0xFFFFF5BF,0x0000036A,0x00001DC6,0xFFFFF5BF,0x0000036A}, - {"0000001000010011111100001111111010011001000000100011100010100100",0x000032C7,0xFFFFEA7A,0x000004F0,0x00001A7B,0xFFFFF827,0x00000301,0x00001A7B,0xFFFFF827,0x00000301}, - {"0000001000010011111010101001010011011110000001000100100010000100",0x0000312D,0xFFFFEA39,0x00000515,0x00001948,0xFFFFF800,0x00000318,0x00001948,0xFFFFF800,0x00000318}, - {"0000001000010011111010101001010011011110000001100010000010000100",0x00003611,0xFFFFE8D7,0x00000533,0x00001929,0xFFFFF965,0x000002D2,0x00001929,0xFFFFF965,0x000002D2}, - {"0000001000010011111100001111111010011001001011000011000011100100",0x00002FE2,0xFFFFED89,0x00000470,0x00001A3C,0xFFFFF955,0x000002D5,0x00001A3C,0xFFFFF955,0x000002D5}, - {"0000001000010011111010101001010011011110000000100000100010100100",0x000035FF,0xFFFFE884,0x00000548,0x0000182A,0xFFFFF9AB,0x000002CF,0x0000182A,0xFFFFF9AB,0x000002CF}, - {"0000001000010011111100001111111010011001000000100010000011100100",0x00003597,0xFFFFE904,0x00000528,0x00001A94,0xFFFFF840,0x00000300,0x00001A94,0xFFFFF840,0x00000300}, - {"0000001000010011111100001111111010011001000110000001100101000100",0x000026CB,0xFFFFF1FB,0x000003E4,0x000017CC,0xFFFFFA25,0x000002C8,0x000017CC,0xFFFFFA25,0x000002C8}, - {"0000001000010011111010101001010011011110000001100000100011000100",0x00003274,0xFFFFEA39,0x0000050C,0x00001B20,0xFFFFF7C1,0x00000314,0x00001B20,0xFFFFF7C1,0x00000314}, - {"0000001000010011111100001111110101000010110110000010100100100100",0x0000280B,0xFFFFF283,0x000003B5,0x000018D0,0xFFFFF992,0x000002EC,0x000018D0,0xFFFFF992,0x000002EC}, - {"0000001000010011111100001111111010011001000001100010000100000100",0x000033AB,0xFFFFEB1B,0x000004C4,0x00001FEE,0xFFFFF53A,0x00000378,0x00001FEE,0xFFFFF53A,0x00000378}, - {"0000001000010011111100001111111010011001000010100011100101100100",0x00002F79,0xFFFFEB0C,0x000004FA,0x00001E57,0xFFFFF4BF,0x0000039B,0x00001E57,0xFFFFF4BF,0x0000039B}, - {"0000001000010011111100001111111010011001000001000100100011100100",0x00003487,0xFFFFE8F2,0x00000539,0x0000185B,0xFFFFF9AE,0x000002BA,0x0000185B,0xFFFFF9AE,0x000002BA}, - {"0000001000010011111100001111111010011001000010100001100010100100",0x00003500,0xFFFFE793,0x0000058A,0x00001AA2,0xFFFFF792,0x0000031D,0x00001AA2,0xFFFFF792,0x0000031D}, - {"0000001000010011111100001111111010011001000010000001000101100100",0x00003943,0xFFFFE54D,0x000005D9,0x00001BC8,0xFFFFF6E0,0x00000339,0x00001BC8,0xFFFFF6E0,0x00000339}, - {"0000001000010011111010101001010011011110000001000011000010100100",0x0000306D,0xFFFFEC5E,0x000004A5,0x00001A3A,0xFFFFF85F,0x00000304,0x00001A3A,0xFFFFF85F,0x00000304}, - {"0000001000010011111100001111110101000010110110000011000010000100",0x00002BA4,0xFFFFEE8D,0x0000046A,0x0000198C,0xFFFFF88E,0x00000307,0x0000198C,0xFFFFF88E,0x00000307}, - {"0000001000010011111100001111110101000010110100100001100011100100",0x00003D30,0xFFFFE2F6,0x0000062A,0x000025DC,0xFFFFF074,0x00000435,0x000025DC,0xFFFFF074,0x00000435}, - {"0000001000010011111100001111110101000010110110000011100101100100",0x00002CD6,0xFFFFED79,0x0000049B,0x000016D0,0xFFFFFA53,0x000002BB,0x000016D0,0xFFFFFA53,0x000002BB}, - {"0000001000010011111100001111111010011001000101100011000101100100",0x00002484,0xFFFFF3BD,0x000003A0,0x000015B8,0xFFFFFB6B,0x000002A4,0x000015B8,0xFFFFFB6B,0x000002A4}, - {"0000001000010011111100001111111010011001000011100011100101000100",0x000038AE,0xFFFFE6D1,0x00000587,0x00001A2A,0xFFFFF8F1,0x000002D4,0x00001A2A,0xFFFFF8F1,0x000002D4}, - {"0000001000010011111100001111111010011001000001000100100101000100",0x000036FD,0xFFFFE76C,0x00000576,0x00001EE4,0xFFFFF58D,0x00000361,0x00001EE4,0xFFFFF58D,0x00000361}, - {"0000001000010011111100001111110101000010110110000011000010100100",0x00002BCF,0xFFFFEF28,0x00000448,0x00001B93,0xFFFFF7BA,0x00000327,0x00001B93,0xFFFFF7BA,0x00000327}, - {"0000001000010011111100001111111010011001000001100010100010000100",0x00003834,0xFFFFE818,0x0000053B,0x00001AFE,0xFFFFF85C,0x000002F3,0x00001AFE,0xFFFFF85C,0x000002F3}, - {"0000001000010011111100001111111010011001001100100011000110100100",0x00002EF7,0xFFFFEBFC,0x000004CE,0x00001897,0xFFFFF8EF,0x000002EC,0x00001897,0xFFFFF8EF,0x000002EC}, - {"0000001000010011111100001111111010011001001011000001100011000100",0x000035BD,0xFFFFE8BB,0x0000053B,0x00001F22,0xFFFFF561,0x00000373,0x00001F22,0xFFFFF561,0x00000373}, - {"0000001000010011111100001111111010011001000110000011100110000100",0x00002D42,0xFFFFEE1D,0x00000478,0x000016F0,0xFFFFFAAE,0x000002B3,0x000016F0,0xFFFFFAAE,0x000002B3}, - {"0000001000010011111010101001010011011110000001000101000100100100",0x00002F98,0xFFFFEB3C,0x000004F0,0x00001903,0xFFFFF818,0x00000319,0x00001903,0xFFFFF818,0x00000319}, - {"0000001000010011111100001111110101000010110101000010000101000100",0x00004081,0xFFFFDF13,0x000006F3,0x00002A6D,0xFFFFEC1B,0x00000509,0x00002A6D,0xFFFFEC1B,0x00000509}, - {"0000001000010011111010101001010011011110000001000000100100000100",0x00002D68,0xFFFFED21,0x00000498,0x00001FF6,0xFFFFF427,0x000003B0,0x00001FF6,0xFFFFF427,0x000003B0}, - {"0000001000010011111100001111111010011001000000100011100010000100",0x00003243,0xFFFFEA5C,0x000004FD,0x000020FB,0xFFFFF39E,0x000003C0,0x000020FB,0xFFFFF39E,0x000003C0}, - {"0000001000010011111100001111110101000010110110000100100010100100",0x00002F20,0xFFFFEC19,0x000004C6,0x00001748,0xFFFFF99F,0x000002DA,0x00001748,0xFFFFF99F,0x000002DA}, - {"0000001000010011111100001111111010011001000100000011100110000100",0x00002D68,0xFFFFED21,0x00000498,0x00001A43,0xFFFFF843,0x000002F9,0x00001A43,0xFFFFF843,0x000002F9}, - {"0000001000010011111100001111111010011001000000100010000010100100",0x0000396E,0xFFFFE616,0x000005A9,0x00001A51,0xFFFFF850,0x000002FA,0x00001A51,0xFFFFF850,0x000002FA}, - {"0000001000010011111100001111111010011001000001000011000101000100",0x0000305C,0xFFFFED4B,0x0000046C,0x00001CF9,0xFFFFF7BA,0x00000304,0x00001CF9,0xFFFFF7BA,0x00000304}, - {"0000001000010011111100001111110101000010110110100100000101100100",0x0000343C,0xFFFFE869,0x00000559,0x00001CE2,0xFFFFF614,0x00000359,0x00001CE2,0xFFFFF614,0x00000359}, - {"0000001000010011111100001111111010011001000110000011100101100100",0x00002782,0xFFFFF1FE,0x000003D9,0x000015DC,0xFFFFFB8B,0x00000290,0x000015DC,0xFFFFFB8B,0x00000290}, - {"0000001000010011111100001111111010011001000110000001100011000100",0x00002B9C,0xFFFFEF63,0x00000443,0x00001369,0xFFFFFD51,0x00000244,0x00001369,0xFFFFFD51,0x00000244}, - {"0000001000010011111100001111111010011001000010100010000010000100",0x000035F8,0xFFFFE743,0x00000592,0x000018D8,0xFFFFF8EE,0x000002E4,0x000018D8,0xFFFFF8EE,0x000002E4}, - {"0000001000010011111010101001010011011110000001100010100001000100",0x00002B72,0xFFFFEF1E,0x0000043C,0x00002647,0xFFFFF092,0x0000043E,0x00002647,0xFFFFF092,0x0000043E}, - {"0000001000010011111100001111111010011001000100000010000110000100",0x00002EC9,0xFFFFEC5F,0x000004B8,0x000018B6,0xFFFFF936,0x000002D8,0x000018B6,0xFFFFF936,0x000002D8}, - {"0000001000010011111100001111111010011001000001100100000010000100",0x000038A7,0xFFFFE6AC,0x00000589,0x00001C42,0xFFFFF70B,0x00000329,0x00001C42,0xFFFFF70B,0x00000329}, - {"0000001000010011111100001111111010011001001100000000100010100100",0x00002F6B,0xFFFFEBF6,0x000004CF,0x000018AE,0xFFFFF928,0x000002E3,0x000018AE,0xFFFFF928,0x000002E3}, - {"0000001000010011111100001111110101000010110110100101000100000100",0x000029CD,0xFFFFEEE1,0x00000459,0x00001AB5,0xFFFFF76F,0x00000324,0x00001AB5,0xFFFFF76F,0x00000324}, - {"0000001000010011111010101001010011011110000001100011100011000100",0x00003921,0xFFFFE71D,0x00000577,0x00001646,0xFFFFFB24,0x00000293,0x00001646,0xFFFFFB24,0x00000293}, - {"0000001000010011111010101001010011011110000001000100000101100100",0x00003940,0xFFFFE521,0x000005E8,0x00001947,0xFFFFF839,0x0000030D,0x00001947,0xFFFFF839,0x0000030D}, - {"0000001000010011111100001111110101000010110100100100000101100100",0x00003DCA,0xFFFFE211,0x00000659,0x0000250E,0xFFFFF072,0x00000443,0x0000250E,0xFFFFF072,0x00000443}, - {"0000001000010011111100001111111010011001000011000000100100000100",0x00002E95,0xFFFFEC20,0x000004C9,0x000015B4,0xFFFFFAD3,0x0000029D,0x000015B4,0xFFFFFAD3,0x0000029D}, - {"0000001000010011111100001111111010011001000001000001000010000100",0x00002C11,0xFFFFEE6E,0x00000468,0x00001901,0xFFFFF924,0x000002E7,0x00001901,0xFFFFF924,0x000002E7}, - {"0000001000010011111010101001010011011110000001100010000100000100",0x0000293F,0xFFFFF158,0x000003E6,0x0000183F,0xFFFFF9F6,0x000002D2,0x0000183F,0xFFFFF9F6,0x000002D2}, - {"0000001000010011111100001111111010011001000011100001000100000100",0x00002A67,0xFFFFEF34,0x0000043E,0x00001C6F,0xFFFFF6F1,0x0000032B,0x00001C6F,0xFFFFF6F1,0x0000032B}, - {"0000001000010011111010101001010011011110000001100101000100100100",0x00002F8D,0xFFFFEB77,0x000004DA,0x00001C0D,0xFFFFF627,0x00000365,0x00001C0D,0xFFFFF627,0x00000365}, - {"0000001000010011111100001111111010011001000011000011100011000100",0x00003476,0xFFFFEA5B,0x000004E7,0x00001DBF,0xFFFFF6C7,0x00000333,0x00001DBF,0xFFFFF6C7,0x00000333}, - {"0000001000010011111100001111111010011001000011100000100101000100",0x00003336,0xFFFFE92F,0x00000546,0x00001614,0xFFFFFAE0,0x00000296,0x00001614,0xFFFFFAE0,0x00000296}, - {"0000001000010011111100001111111010011001000101100010000101100100",0x00002513,0xFFFFF323,0x000003BC,0x000016DB,0xFFFFFA79,0x000002CD,0x000016DB,0xFFFFFA79,0x000002CD}, - {"0000001000010011111100001111111010011001000010100010100101000100",0x000035A7,0xFFFFE78E,0x00000584,0x00001B0D,0xFFFFF77D,0x0000031F,0x00001B0D,0xFFFFF77D,0x0000031F}, - {"0000001000010011111100001111111010011001001100100011100011100100",0x00003171,0xFFFFEB98,0x000004C6,0x00001C76,0xFFFFF71F,0x0000032F,0x00001C76,0xFFFFF71F,0x0000032F}, - {"0000001000010011111100001111110101000010110110100001000010000100",0x00002C52,0xFFFFED2E,0x000004A7,0x00002182,0xFFFFF2F4,0x000003E4,0x00002182,0xFFFFF2F4,0x000003E4}, - {"0000001000010011111100001111111010011001000100000010100100100100",0x000032E1,0xFFFFEB39,0x000004D0,0x00001B55,0xFFFFF859,0x000002FA,0x00001B55,0xFFFFF859,0x000002FA}, - {"0000001000010011111100001111111010011001000110000100100010100100",0x000029B6,0xFFFFEFF7,0x00000430,0x0000151B,0xFFFFFBC6,0x0000027F,0x0000151B,0xFFFFFBC6,0x0000027F}, - {"0000001000010011111100001111110101000010110110100001100101100100",0x00002FF7,0xFFFFEB67,0x000004DA,0x000020E9,0xFFFFF363,0x000003CE,0x000020E9,0xFFFFF363,0x000003CE}, - {"0000001000010011111100001111110101000010110110100101000100100100",0x00003CDD,0xFFFFE2B2,0x00000649,0x00001B18,0xFFFFF739,0x00000329,0x00001B18,0xFFFFF739,0x00000329}, - {"0000001000010011111100001111111010011001000001100010100010100100",0x00003C82,0xFFFFE5C6,0x0000058E,0x00001F3F,0xFFFFF5AD,0x00000361,0x00001F3F,0xFFFFF5AD,0x00000361}, - {"0000001000010011111100001111110101000010110111000100000010000100",0x0000319B,0xFFFFEA15,0x0000051B,0x00001CC9,0xFFFFF62E,0x00000358,0x00001CC9,0xFFFFF62E,0x00000358}, - {"0000001000010011111010101001010011011110000001100011100011100100",0x000032B6,0xFFFFEB2B,0x000004D6,0x000018E0,0xFFFFF966,0x000002DE,0x000018E0,0xFFFFF966,0x000002DE}, - {"0000001000010011111010101001010011011110000000100011100110000100",0x0000300A,0xFFFFEBA6,0x000004D1,0x00001CFD,0xFFFFF5F6,0x0000036D,0x00001CFD,0xFFFFF5F6,0x0000036D}, - {"0000001000010011111100001111110101000010110110000010100110000100",0x000026A9,0xFFFFF15D,0x00000400,0x00001561,0xFFFFFB1F,0x000002A0,0x00001561,0xFFFFFB1F,0x000002A0}, - {"0000001000010011111100001111111010011001000011100101000100100100",0x00003123,0xFFFFEAD2,0x000004FA,0x000018CB,0xFFFFF8F5,0x000002EC,0x000018CB,0xFFFFF8F5,0x000002EC}, - {"0000001000010011111100001111111010011001000110000100000011000100",0x00003577,0xFFFFE935,0x00000533,0x000016CD,0xFFFFFB44,0x00000289,0x000016CD,0xFFFFFB44,0x00000289}, - {"0000001000010011111100001111111010011001001010000010000110000100",0x00002875,0xFFFFF170,0x000003F3,0x00001567,0xFFFFFBD5,0x00000289,0x00001567,0xFFFFFBD5,0x00000289}, - {"0000001000010011111100001111111010011001000010000100000010000100",0x00003AE2,0xFFFFE538,0x000005C1,0x00001CB4,0xFFFFF6A3,0x0000033C,0x00001CB4,0xFFFFF6A3,0x0000033C}, - {"0000001000010011111100001111111010011001000011000011100011100100",0x000031DF,0xFFFFEC2A,0x000004A3,0x00001EF0,0xFFFFF626,0x00000352,0x00001EF0,0xFFFFF626,0x00000352}, - {"0000001000010011111100001111110101000010110100100101000101000100",0x00004A6A,0xFFFFDB15,0x00000758,0x000027F3,0xFFFFEEEE,0x00000479,0x000027F3,0xFFFFEEEE,0x00000479}, - {"0000001000010011111010101001010011011110000001100011100100000100",0x00002BB9,0xFFFFEF5D,0x00000433,0x00001589,0xFFFFFB57,0x00000295,0x00001589,0xFFFFFB57,0x00000295}, - {"0000001000010011111100001111111010011001000001000010000101100100",0x000033A0,0xFFFFE98F,0x00000528,0x00001CB4,0xFFFFF706,0x0000032D,0x00001CB4,0xFFFFF706,0x0000032D}, - {"0000001000010011111100001111111010011001000101100011000001100100",0x0000248E,0xFFFFF380,0x000003AC,0x000016EA,0xFFFFFA6C,0x000002CE,0x000016EA,0xFFFFFA6C,0x000002CE}, - {"0000001000010011111100001111111010011001000000100010000110100100",0x00002FE2,0xFFFFEB2F,0x000004E9,0x00001D4E,0xFFFFF56B,0x00000380,0x00001D4E,0xFFFFF56B,0x00000380}, - {"0000001000010011111100001111111010011001000010100010100010000100",0x00003283,0xFFFFE9E7,0x0000051D,0x00000694,0xFFFFFD32,0x000003C3,0x00000694,0xFFFFFD32,0x000003C3}, - {"0000001000010011111100001111110101000010110110000101000011000100",0x00002EE4,0xFFFFEBFD,0x000004D3,0x0000151A,0xFFFFFAF6,0x000002A4,0x0000151A,0xFFFFFAF6,0x000002A4}, - {"0000001000010011111100001111110101000010110111000001100011100100",0x0000302D,0xFFFFEB7F,0x000004DA,0x00001E6D,0xFFFFF54B,0x00000380,0x00001E6D,0xFFFFF54B,0x00000380}, - {"0000001000010011111100001111110101000010110110100101000011000100",0x000033DA,0xFFFFE7FB,0x0000057F,0x00001DED,0xFFFFF50E,0x0000038D,0x00001DED,0xFFFFF50E,0x0000038D}, - {"0000001000010011111100001111111010011001001011000100000010000100",0x000030B5,0xFFFFEBB8,0x000004C4,0x00001C3F,0xFFFFF726,0x0000032A,0x00001C3F,0xFFFFF726,0x0000032A}, - {"0000001000010011111100001111111010011001000010000011000111000100",0x00003BBD,0xFFFFE55C,0x000005B8,0x000019DB,0xFFFFF8BB,0x000002EF,0x000019DB,0xFFFFF8BB,0x000002EF}, - {"0000001000010011111100001111111010011001000011100011100010000100",0x00002964,0xFFFFF051,0x0000040E,0x000025CD,0xFFFFF11B,0x0000041F,0x000025CD,0xFFFFF11B,0x0000041F}, - {"0000001000010011111100001111110101000010110111000100100010000100",0x000033F5,0xFFFFE863,0x00000560,0x00001BCE,0xFFFFF689,0x0000034B,0x00001BCE,0xFFFFF689,0x0000034B}, - {"0000001000010011111100001111111010011001000010100010100001100100",0x00003294,0xFFFFE924,0x00000548,0x00001D41,0xFFFFF580,0x0000037D,0x00001D41,0xFFFFF580,0x0000037D}, - {"0000001000010011111100001111110101000010110111000011100110100100",0x000034FB,0xFFFFE7FE,0x0000056D,0x00001CB1,0xFFFFF635,0x00000357,0x00001CB1,0xFFFFF635,0x00000357}, - {"0000001000010011111100001111111010011001000010100001000010100100",0x00002E28,0xFFFFEBB9,0x000004E0,0x00001B20,0xFFFFF6E3,0x0000033C,0x00001B20,0xFFFFF6E3,0x0000033C}, - {"0000001000010011111100001111110101000010110110100001100100000100",0x00002799,0xFFFFF0F4,0x000003FC,0x00001C9D,0xFFFFF6A1,0x00000345,0x00001C9D,0xFFFFF6A1,0x00000345}, - {"0000001000010011111100001111111010011001000001100100000100000100",0x00003AEA,0xFFFFE5DB,0x0000059D,0x00001B61,0xFFFFF7F0,0x00000301,0x00001B61,0xFFFFF7F0,0x00000301}, - {"0000001000010011111010101001010011011110000001000001100110000100",0x000031F6,0xFFFFEAB8,0x000004F3,0x00001D90,0xFFFFF622,0x00000359,0x00001D90,0xFFFFF622,0x00000359}, - {"0000001000010011111100001111111010011001000011000100000001100100",0x000031B8,0xFFFFEA61,0x0000050F,0x0000199D,0xFFFFF87C,0x000002FD,0x0000199D,0xFFFFF87C,0x000002FD}, - {"0000001000010011111100001111110101000010110100100011000101000100",0x00004514,0xFFFFDDFF,0x000006F6,0x000022CD,0xFFFFF29F,0x000003D9,0x000022CD,0xFFFFF29F,0x000003D9}, - {"0000001000010011111010101001010011011110000001000011000101100100",0x00002F30,0xFFFFECB8,0x000004A0,0x00001B07,0xFFFFF7E2,0x00000313,0x00001B07,0xFFFFF7E2,0x00000313}, - {"0000001000010011111100001111110101000010110111000011000010100100",0x0000383B,0xFFFFE702,0x00000581,0x00001A08,0xFFFFF8CA,0x000002E2,0x00001A08,0xFFFFF8CA,0x000002E2}, - {"0000001000010011111100001111111010011001000000100010000101100100",0x00002CC5,0xFFFFEDF8,0x00000465,0x00001F47,0xFFFFF4B2,0x00000393,0x00001F47,0xFFFFF4B2,0x00000393}, - {"0000001000010011111100001111111010011001000101100010000111000100",0x00002304,0xFFFFF453,0x00000384,0x0000170A,0xFFFFFA3F,0x000002CE,0x0000170A,0xFFFFFA3F,0x000002CE}, - {"0000001000010011111100001111111010011001000010100101000100100100",0x0000337E,0xFFFFE850,0x0000056E,0x00001BDD,0xFFFFF668,0x00000353,0x00001BDD,0xFFFFF668,0x00000353}, - {"0000001000010011111100001111111010011001000011100100100100100100",0x00002E2F,0xFFFFEC9B,0x000004AE,0x00001C4D,0xFFFFF6D3,0x00000338,0x00001C4D,0xFFFFF6D3,0x00000338}, - {"0000001000010011111010101001010011011110000001100001000100100100",0x00002DDD,0xFFFFEDA4,0x00000477,0x00002010,0xFFFFF4BB,0x00000390,0x00002010,0xFFFFF4BB,0x00000390}, - {"0000001000010011111100001111110101000010110110100100100011100100",0x0000290C,0xFFFFEF61,0x00000445,0x00002133,0xFFFFF324,0x000003D8,0x00002133,0xFFFFF324,0x000003D8}, - {"0000001000010011111100001111111010011001000001100010100100100100",0x0000371E,0xFFFFE8D5,0x00000524,0x00001C3A,0xFFFFF7AE,0x00000314,0x00001C3A,0xFFFFF7AE,0x00000314}, - {"0000001000010011111100001111110101000010110110000011100011100100",0x00002A58,0xFFFFF007,0x00000429,0x000018A6,0xFFFFF98F,0x000002E1,0x000018A6,0xFFFFF98F,0x000002E1}, - {"0000001000010011111100001111111010011001000000100011000010000100",0x00002FED,0xFFFFEC48,0x000004AA,0x00001E9D,0xFFFFF584,0x00000370,0x00001E9D,0xFFFFF584,0x00000370}, - {"0000001000010011111100001111111010011001000110000001100010000100",0x00002829,0xFFFFF15F,0x000003F7,0x0000157E,0xFFFFFBD4,0x00000282,0x0000157E,0xFFFFFBD4,0x00000282}, - {"0000001000010011111100001111111010011001000100000001100100100100",0x000030CF,0xFFFFEB8D,0x000004CE,0x00001A4C,0xFFFFF868,0x000002F7,0x00001A4C,0xFFFFF868,0x000002F7}, - {"0000001000010011111100001111110101000010110110100010000010000100",0x00002C8F,0xFFFFEDD2,0x0000047D,0x00001CCE,0xFFFFF6A1,0x00000343,0x00001CCE,0xFFFFF6A1,0x00000343}, - {"0000001000010011111100001111111010011001000110000010000101100100",0x00002A84,0xFFFFEFBA,0x0000043E,0x000015EF,0xFFFFFB4B,0x0000029E,0x000015EF,0xFFFFFB4B,0x0000029E}, - {"0000001000010011111100001111111010011001000011000010100010100100",0x000034CA,0xFFFFEA08,0x000004FF,0x00001C19,0xFFFFF7ED,0x00000309,0x00001C19,0xFFFFF7ED,0x00000309}, - {"0000001000010011111100001111111010011001000101100011100110100100",0x00002187,0xFFFFF4B0,0x0000037E,0x0000154A,0xFFFFFB0C,0x000002AE,0x0000154A,0xFFFFFB0C,0x000002AE}, - {"0000001000010011111100001111110101000010110110100011100001000100",0x00002F4F,0xFFFFEB3C,0x000004F8,0x0000181F,0xFFFFF92D,0x000002DF,0x0000181F,0xFFFFF92D,0x000002DF}, - {"0000001000010011111100001111111010011001000001000001000011100100",0x0000290C,0xFFFFF0B1,0x000003FC,0x00001DB0,0xFFFFF636,0x00000355,0x00001DB0,0xFFFFF636,0x00000355}, - {"0000001000010011111100001111111010011001000010100001000001100100",0x000034C1,0xFFFFE888,0x0000055A,0x000019BF,0xFFFFF881,0x000002FB,0x000019BF,0xFFFFF881,0x000002FB}, - {"0000001000010011111100001111110101000010110111000001100011000100",0x00003139,0xFFFFEA98,0x00000504,0x000019F2,0xFFFFF820,0x0000030B,0x000019F2,0xFFFFF820,0x0000030B}, - {"0000001000010011111100001111110101000010110110000011000101000100",0x00002CAC,0xFFFFEEB2,0x00000458,0x0000152C,0xFFFFFBEF,0x0000027B,0x0000152C,0xFFFFFBEF,0x0000027B}, - {"0000001000010011111100001111111010011001001011000011100011100100",0x00003577,0xFFFFE99C,0x0000050D,0x00001E64,0xFFFFF679,0x0000033F,0x00001E64,0xFFFFF679,0x0000033F}, - {"0000001000010011111100001111110101000010110110100100000100000100",0x0000263A,0xFFFFF1E4,0x000003D4,0x00001F68,0xFFFFF4ED,0x00000386,0x00001F68,0xFFFFF4ED,0x00000386}, - {"0000001000010011111100001111110101000010110110000001100110000100",0x00002CE9,0xFFFFED63,0x00000497,0x00001810,0xFFFFF94D,0x000002E3,0x00001810,0xFFFFF94D,0x000002E3}, - {"0000001000010011111010101001010011011110000001000100000100000100",0x0000318A,0xFFFFEAC8,0x000004F5,0x0000195C,0xFFFFF896,0x000002FB,0x0000195C,0xFFFFF896,0x000002FB}, - {"0000001000010011111100001111110101000010110110000011100100000100",0x00002C41,0xFFFFEEC6,0x0000045D,0x000017DD,0xFFFFFA16,0x000002CB,0x000017DD,0xFFFFFA16,0x000002CB}, - {"0000001000010011111100001111111010011001000000100011000110100100",0x00002DD4,0xFFFFEC98,0x000004AD,0x00001BD7,0xFFFFF69F,0x00000347,0x00001BD7,0xFFFFF69F,0x00000347}, - {"0000001000010011111100001111110101000010110110100011100101000100",0x00003351,0xFFFFE9B2,0x0000051A,0x00001CA1,0xFFFFF6A4,0x00000341,0x00001CA1,0xFFFFF6A4,0x00000341}, - {"0000001000010011111100001111111010011001000000100001000100000100",0x0000322D,0xFFFFE9BE,0x00000527,0x00001CF9,0xFFFFF5EB,0x00000366,0x00001CF9,0xFFFFF5EB,0x00000366}, - {"0000001000010011111100001111111010011001000011000010100011000100",0x00003678,0xFFFFE9A8,0x00000503,0x00001AD4,0xFFFFF8F6,0x000002E3,0x00001AD4,0xFFFFF8F6,0x000002E3}, - {"0000001000010011111100001111111010011001000101100001100100100100",0x0000260E,0xFFFFF2C1,0x000003CA,0x00001139,0xFFFFFE48,0x00000236,0x00001139,0xFFFFFE48,0x00000236}, - {"0000001000010011111100001111111010011001000010100010000101100100",0x000033D3,0xFFFFE872,0x00000565,0x00001B72,0xFFFFF713,0x00000332,0x00001B72,0xFFFFF713,0x00000332}, - {"0000001000010011111100001111111010011001001100100011100001000100",0x0000309B,0xFFFFEB42,0x000004E4,0x00001918,0xFFFFF8C8,0x000002F2,0x00001918,0xFFFFF8C8,0x000002F2}, - {"0000001000010011111100001111111010011001000110000010100001100100",0x000028B8,0xFFFFF105,0x00000402,0x000018BB,0xFFFFF9BC,0x000002D3,0x000018BB,0xFFFFF9BC,0x000002D3}, - {"0000001000010011111100001111111010011001000010100001100010000100",0x00003123,0xFFFFE9D1,0x00000534,0x00001B19,0xFFFFF6FE,0x0000033C,0x00001B19,0xFFFFF6FE,0x0000033C}, - {"0000001000010011111100001111111010011001000000100010000101000100",0x00003216,0xFFFFEA8E,0x000004F6,0x00001F72,0xFFFFF4CE,0x0000038B,0x00001F72,0xFFFFF4CE,0x0000038B}, - {"0000001000010011111100001111111010011001000101100010100101100100",0x00002564,0xFFFFF32D,0x000003B6,0x00001685,0xFFFFFADB,0x000002BB,0x00001685,0xFFFFFADB,0x000002BB}, - {"0000001000010011111100001111110101000010110110100010100100100100",0x00002E60,0xFFFFED13,0x00000497,0x00001CA5,0xFFFFF6B9,0x00000346,0x00001CA5,0xFFFFF6B9,0x00000346}, - {"0000001000010011111100001111111010011001000011100011100110100100",0x0000336D,0xFFFFE934,0x0000053B,0x00001B3E,0xFFFFF763,0x00000327,0x00001B3E,0xFFFFF763,0x00000327}, - {"0000001000010011111100001111111010011001000100000001000010000100",0x0000274A,0xFFFFF119,0x000003FA,0x00001D75,0xFFFFF5CD,0x0000036F,0x00001D75,0xFFFFF5CD,0x0000036F}, - {"0000001000010011111100001111110101000010110110100010000101100100",0x0000366B,0xFFFFE70A,0x0000059A,0x00001ED8,0xFFFFF501,0x00000389,0x00001ED8,0xFFFFF501,0x00000389}, - {"0000001000010011111100001111111010011001001000100011100101100100",0x00003164,0xFFFFEAB4,0x000004FA,0x00001C52,0xFFFFF6E0,0x00000336,0x00001C52,0xFFFFF6E0,0x00000336}, - {"0000001000010011111100001111110101000010110100100011000001100100",0x00004224,0xFFFFDF7F,0x000006C1,0x00002A52,0xFFFFED5E,0x000004BB,0x00002A52,0xFFFFED5E,0x000004BB}, - {"0000001000010011111100001111111010011001000100000010100001100100",0x000030E3,0xFFFFEB07,0x000004ED,0x00001FD3,0xFFFFF46D,0x000003A1,0x00001FD3,0xFFFFF46D,0x000003A1}, - {"0000001000010011111100001111110101000010110110000010100010000100",0x00002AEB,0xFFFFEF1B,0x00000454,0x00001829,0xFFFFF995,0x000002DD,0x00001829,0xFFFFF995,0x000002DD}, - {"0000001000010011111100001111110101000010110111000101000011100100",0x0000346B,0xFFFFE7A2,0x0000058B,0x000020C5,0xFFFFF2E8,0x000003EC,0x000020C5,0xFFFFF2E8,0x000003EC}, - {"0000001000010011111100001111110101000010110111000100000101100100",0x000039CF,0xFFFFE5D7,0x000005A9,0x00001D66,0xFFFFF5D6,0x00000366,0x00001D66,0xFFFFF5D6,0x00000366}, - {"0000001000010011111100001111111010011001000001000001100011100100",0x000034AC,0xFFFFE9AE,0x00000515,0x00001A28,0xFFFFF904,0x000002DC,0x00001A28,0xFFFFF904,0x000002DC}, - {"0000001000010011111100001111110101000010110111000010000010000100",0x00002D68,0xFFFFED21,0x00000498,0x00001C6F,0xFFFFF686,0x0000034C,0x00001C6F,0xFFFFF686,0x0000034C}, - {"0000001000010011111100001111111010011001000010000010000011000100",0x0000328B,0xFFFFEBA1,0x000004B4,0x00001DA3,0xFFFFF683,0x00000349,0x00001DA3,0xFFFFF683,0x00000349}, - {"0000001000010011111100001111111010011001000110000010100011000100",0x000027DC,0xFFFFF295,0x000003BF,0x000019C1,0xFFFFF98E,0x000002E8,0x000019C1,0xFFFFF98E,0x000002E8}, - {"0000001000010011111100001111111010011001000110000100000010000100",0x00002756,0xFFFFF1D7,0x000003DF,0x000015D9,0xFFFFFB51,0x00000298,0x000015D9,0xFFFFFB51,0x00000298}, - {"0000001000010011111100001111111010011001000010000011100010000100",0x00003526,0xFFFFE907,0x00000526,0x000017AB,0xFFFFFA12,0x000002AB,0x000017AB,0xFFFFFA12,0x000002AB}, - {"0000001000010011111100001111110101000010110110100001100011100100",0x0000351B,0xFFFFE8B7,0x00000540,0x00001A86,0xFFFFF821,0x00000303,0x00001A86,0xFFFFF821,0x00000303}, - {"0000001000010011111100001111111010011001000101100100000101000100",0x000024B2,0xFFFFF34E,0x000003B1,0x000018E2,0xFFFFF926,0x000002FC,0x000018E2,0xFFFFF926,0x000002FC}, - {"0000001000010011111100001111110101000010110110000010100010100100",0x00002F36,0xFFFFED5D,0x00000486,0x0000157A,0xFFFFFB85,0x00000293,0x0000157A,0xFFFFFB85,0x00000293}, - {"0000001000010011111100001111110101000010110111000101000011000100",0x00003A6E,0xFFFFE456,0x000005FD,0x00001F68,0xFFFFF3D1,0x000003C3,0x00001F68,0xFFFFF3D1,0x000003C3}, - {"0000001000010011111100001111111010011001000010100011000110100100",0x00002BC3,0xFFFFED2D,0x000004A7,0x00001C3F,0xFFFFF609,0x00000364,0x00001C3F,0xFFFFF609,0x00000364}, - {"0000001000010011111100001111111010011001000011100010000010000100",0x000032E1,0xFFFFEA83,0x000004F6,0x00001B37,0xFFFFF842,0x000002F5,0x00001B37,0xFFFFF842,0x000002F5}, - {"0000001000010011111100001111110101000010110110000011000110000100",0x000028E3,0xFFFFF07F,0x00000412,0x00001676,0xFFFFFA68,0x000002BE,0x00001676,0xFFFFFA68,0x000002BE}, - {"0000001000010011111100001111110101000010110100100001000100000100",0x0000444C,0xFFFFDDAD,0x00000712,0x00002634,0xFFFFEF89,0x0000046C,0x00002634,0xFFFFEF89,0x0000046C}, - {"0000001000010011111100001111111010011001000001000001100011000100",0x00003121,0xFFFFEBBB,0x000004C6,0x00001C98,0xFFFFF72B,0x0000032D,0x00001C98,0xFFFFF72B,0x0000032D}, - {"0000001000010011111100001111110101000010110110000100000010100100",0x00002C31,0xFFFFEDC4,0x00000490,0x0000162D,0xFFFFFA8E,0x000002B4,0x0000162D,0xFFFFFA8E,0x000002B4}, - {"0000001000010011111100001111110101000010110110100001100011000100",0x00002749,0xFFFFF112,0x000003FC,0x00001C85,0xFFFFF6B8,0x00000342,0x00001C85,0xFFFFF6B8,0x00000342}, - {"0000001000010011111100001111111010011001000001000100000100000100",0x00003159,0xFFFFEB99,0x000004C2,0x00001BD0,0xFFFFF7CA,0x00000307,0x00001BD0,0xFFFFF7CA,0x00000307}, - {"0000001000010011111100001111111010011001000101100100000101100100",0x00002610,0xFFFFF1FD,0x000003EC,0x000016BE,0xFFFFFA53,0x000002CB,0x000016BE,0xFFFFFA53,0x000002CB}, - {"0000001000010011111100001111111010011001000000100011000110000100",0x000037B5,0xFFFFE63D,0x000005B5,0x00002285,0xFFFFF25D,0x000003F7,0x00002285,0xFFFFF25D,0x000003F7}, - {"0000001000010011111100001111111010011001000010100010100010100100",0x00002FEE,0xFFFFEB47,0x000004EF,0x00001CBE,0xFFFFF64E,0x00000358,0x00001CBE,0xFFFFF64E,0x00000358}, - {"0000001000010011111100001111111010011001000100000101000100000100",0x00002E90,0xFFFFEC48,0x000004C0,0x00001A47,0xFFFFF7D1,0x0000031A,0x00001A47,0xFFFFF7D1,0x0000031A}, - {"0000001000010011111100001111110101000010110110100100000010000100",0x000034AB,0xFFFFE84A,0x00000559,0x00001A72,0xFFFFF79A,0x0000031C,0x00001A72,0xFFFFF79A,0x0000031C}, - {"0000001000010011111100001111111010011001000110000011100010000100",0x00002F7B,0xFFFFECFC,0x0000049C,0x00001814,0xFFFFFA22,0x000002C2,0x00001814,0xFFFFFA22,0x000002C2}, - {"0000001000010011111100001111111010011001000000100001100101100100",0x00003618,0xFFFFE709,0x00000596,0x00001EBF,0xFFFFF482,0x000003A5,0x00001EBF,0xFFFFF482,0x000003A5}, - {"0000001000010011111010101001010011011110000000100100100100000100",0x0000341B,0xFFFFE8B2,0x0000054F,0x00001D26,0xFFFFF578,0x00000388,0x00001D26,0xFFFFF578,0x00000388}, - {"0000001000010011111100001111111010011001000100000010000101000100",0x000030F6,0xFFFFEB89,0x000004CD,0x000019C0,0xFFFFF8CC,0x000002E6,0x000019C0,0xFFFFF8CC,0x000002E6}, - {"0000001000010011111100001111111010011001001010000100000110100100",0x00002B76,0xFFFFEF6C,0x00000444,0x00001563,0xFFFFFBBE,0x0000028D,0x00001563,0xFFFFFBBE,0x0000028D}, - {"0000001000010011111100001111110101000010110110000001100001100100",0x00002BA2,0xFFFFEE31,0x0000047F,0x00001A3D,0xFFFFF7F3,0x00000320,0x00001A3D,0xFFFFF7F3,0x00000320}, - {"0000001000010011111100001111111010011001001011000100100011100100",0x00003545,0xFFFFE87A,0x0000054A,0x00001B5A,0xFFFFF7B0,0x0000030C,0x00001B5A,0xFFFFF7B0,0x0000030C}, - {"0000001000010011111010101001010011011110000001000010100101000100",0x00003879,0xFFFFE73F,0x00000578,0x00001649,0xFFFFFB57,0x00000283,0x00001649,0xFFFFFB57,0x00000283}, - {"0000001000010011111100001111110101000010110110000100000011000100",0x00002772,0xFFFFF0F1,0x00000410,0x0000142F,0xFFFFFBCF,0x00000287,0x0000142F,0xFFFFFBCF,0x00000287}, - {"0000001000010011111100001111110101000010110110100011000110000100",0x00003228,0xFFFFE98E,0x00000535,0x00001F48,0xFFFFF495,0x00000399,0x00001F48,0xFFFFF495,0x00000399}, - {"0000001000010011111100001111111010011001000011100100000011100100",0x00002887,0xFFFFF119,0x000003E8,0x000021AA,0xFFFFF3F5,0x000003A5,0x000021AA,0xFFFFF3F5,0x000003A5}, - {"0000001000010011111100001111110101000010110110100010100010100100",0x0000301F,0xFFFFEBB2,0x000004D2,0x00001C02,0xFFFFF736,0x0000032B,0x00001C02,0xFFFFF736,0x0000032B}, - {"0000001000010011111100001111111010011001000110000010000010100100",0x00002E13,0xFFFFEE3F,0x00000468,0x000016AC,0xFFFFFB32,0x0000029E,0x000016AC,0xFFFFFB32,0x0000029E}, - {"0000001000010011111100001111111010011001000001000100100100100100",0x00003478,0xFFFFE8F9,0x00000538,0x00001DAB,0xFFFFF645,0x00000345,0x00001DAB,0xFFFFF645,0x00000345}, - {"0000001000010011111100001111111010011001000001100000100011000100",0x000030C6,0xFFFFEB6C,0x000004D4,0x0000184A,0xFFFFF934,0x000002E1,0x0000184A,0xFFFFF934,0x000002E1}, - {"0000001000010011111100001111111010011001000010100010000001000100",0x00002F1B,0xFFFFEBD3,0x000004D3,0x000019E7,0xFFFFF813,0x0000030D,0x000019E7,0xFFFFF813,0x0000030D}, - {"0000001000010011111100001111111010011001000000100011100100000100",0x00003214,0xFFFFEAE9,0x000004E0,0x0000178F,0xFFFFFA1C,0x000002B1,0x0000178F,0xFFFFFA1C,0x000002B1}, - {"0000001000010011111100001111110101000010110111000011000101000100",0x0000399C,0xFFFFE738,0x0000055E,0x00001EA1,0xFFFFF5E7,0x0000035A,0x00001EA1,0xFFFFF5E7,0x0000035A}, - {"0000001000010011111100001111111010011001000001100101000011000100",0x00003A01,0xFFFFE5B2,0x000005B6,0x00001D95,0xFFFFF5D2,0x0000036A,0x00001D95,0xFFFFF5D2,0x0000036A}, - {"0000001000010011111100001111111010011001000001000011100010000100",0x0000310D,0xFFFFEB78,0x000004D0,0x00001C06,0xFFFFF76E,0x0000031A,0x00001C06,0xFFFFF76E,0x0000031A}, - {"0000001000010011111100001111111010011001000001100011100001100100",0x00003CD1,0xFFFFE42F,0x000005EB,0x00001933,0xFFFFF91F,0x000002D4,0x00001933,0xFFFFF91F,0x000002D4}, - {"0000001000010011111100001111110101000010110110100011000101100100",0x00003119,0xFFFFEB1B,0x000004E1,0x00001FC7,0xFFFFF46A,0x000003A2,0x00001FC7,0xFFFFF46A,0x000003A2}, - {"0000001000010011111010101001010011011110000001100100100010100100",0x0000390D,0xFFFFE566,0x000005D8,0x00001EC6,0xFFFFF4DC,0x00000391,0x00001EC6,0xFFFFF4DC,0x00000391}, - {"0000001000010011111100001111110101000010110110100001000011000100",0x00003446,0xFFFFE858,0x00000561,0x00001FDB,0xFFFFF3FF,0x000003B9,0x00001FDB,0xFFFFF3FF,0x000003B9}, - {"0000001000010011111100001111111010011001000001000100100100000100",0x000032BA,0xFFFFEA07,0x00000511,0x00001B25,0xFFFFF7C9,0x0000030D,0x00001B25,0xFFFFF7C9,0x0000030D}, - {"0000001000010011111100001111111010011001000011100001100001100100",0x00002CCF,0xFFFFEDE5,0x00000478,0x00001BC8,0xFFFFF761,0x00000326,0x00001BC8,0xFFFFF761,0x00000326}, - {"0000001000010011111100001111111010011001000001100010100110000100",0x0000400E,0xFFFFE1CB,0x00000652,0x00001AF8,0xFFFFF7B9,0x00000312,0x00001AF8,0xFFFFF7B9,0x00000312}, - {"0000001000010011111100001111111010011001000001000000100011100100",0x00002F24,0xFFFFEC2A,0x000004C7,0x00001B94,0xFFFFF748,0x00000333,0x00001B94,0xFFFFF748,0x00000333}, - {"0000001000010011111100001111110101000010110100100001100100100100",0x00003FDA,0xFFFFE1C1,0x0000064B,0x00002427,0xFFFFF180,0x0000040C,0x00002427,0xFFFFF180,0x0000040C}, - {"0000001000010011111100001111111010011001000010100001100011000100",0x00002F6B,0xFFFFEBA7,0x000004DD,0x00001C25,0xFFFFF6C1,0x00000344,0x00001C25,0xFFFFF6C1,0x00000344}, - {"0000001000010011111100001111111010011001000110000010000100000100",0x00002A53,0xFFFFF0EE,0x00000402,0x000017C6,0xFFFFFAA0,0x000002BF,0x000017C6,0xFFFFFAA0,0x000002BF}, - {"0000001000010011111100001111111010011001000100000101000101000100",0x000031F4,0xFFFFEA34,0x00000517,0x000016FF,0xFFFFFA4E,0x000002AC,0x000016FF,0xFFFFFA4E,0x000002AC}, - {"0000001000010011111100001111111010011001001100100010000101000100",0x00002E24,0xFFFFED46,0x00000489,0x00001712,0xFFFFFA5D,0x000002AC,0x00001712,0xFFFFFA5D,0x000002AC}, - {"0000001000010011111100001111111010011001000110000010100000100100",0x000028CD,0xFFFFF0E3,0x0000040E,0x00001606,0xFFFFFB37,0x000002A4,0x00001606,0xFFFFFB37,0x000002A4}, - {"0000001000010011111100001111111010011001000000100010000011000100",0x00003184,0xFFFFEB88,0x000004C3,0x000018DA,0xFFFFF939,0x000002DB,0x000018DA,0xFFFFF939,0x000002DB}, - {"0000001000010011111100001111111010011001000101100010000100100100",0x0000239B,0xFFFFF470,0x00000386,0x00001714,0xFFFFFA9F,0x000002C8,0x00001714,0xFFFFFA9F,0x000002C8}, - {"0000001000010011111100001111110101000010110111000011100011100100",0x00003641,0xFFFFE92B,0x00000515,0x00001BE2,0xFFFFF795,0x0000031B,0x00001BE2,0xFFFFF795,0x0000031B}, - {"0000001000010011111100001111111010011001001011000001000101000100",0x00003278,0xFFFFEA17,0x00000510,0x00001B71,0xFFFFF778,0x0000031D,0x00001B71,0xFFFFF778,0x0000031D}, - {"0000001000010011111100001111111010011001000001100010100001000100",0x000035B9,0xFFFFE8DA,0x0000052D,0x00001A6A,0xFFFFF83B,0x000002FF,0x00001A6A,0xFFFFF83B,0x000002FF}, - {"0000001000010011111100001111111010011001000011100001100011000100",0x00002E5E,0xFFFFED32,0x0000048B,0x00001E7D,0xFFFFF60E,0x0000034E,0x00001E7D,0xFFFFF60E,0x0000034E}, - {"0000001000010011111100001111111010011001000100000001100110100100",0x00003178,0xFFFFEA52,0x00000513,0x00001AD0,0xFFFFF793,0x0000031F,0x00001AD0,0xFFFFF793,0x0000031F}, - {"0000001000010011111100001111110101000010110101000100000100000100",0x00003A2C,0xFFFFE346,0x00000641,0x000023D0,0xFFFFF0CE,0x00000433,0x000023D0,0xFFFFF0CE,0x00000433}, - {"0000001000010011111100001111110101000010110110000001100011000100",0x000028FD,0xFFFFF02A,0x0000042B,0x0000152B,0xFFFFFB90,0x00000289,0x0000152B,0xFFFFFB90,0x00000289}, - {"0000001000010011111100001111111010011001000011100011000010000100",0x000030DE,0xFFFFEBDF,0x000004BE,0x00001CDC,0xFFFFF747,0x0000031C,0x00001CDC,0xFFFFF747,0x0000031C}, - {"0000001000010011111100001111111010011001000000100001100101000100",0x000036CB,0xFFFFE6EE,0x00000596,0x00002096,0xFFFFF3C2,0x000003BB,0x00002096,0xFFFFF3C2,0x000003BB}, - {"0000001000010011111100001111111010011001000011000100100011000100",0x00003172,0xFFFFEAC1,0x000004F4,0x00001C87,0xFFFFF6CD,0x00000337,0x00001C87,0xFFFFF6CD,0x00000337}, - {"0000001000010011111100001111110101000010110100100100100001100100",0x00004A18,0xFFFFDB34,0x00000758,0x0000213C,0xFFFFF3A2,0x000003AC,0x0000213C,0xFFFFF3A2,0x000003AC}, - {"0000001000010011111100001111111010011001000000100010000100000100",0x000031F3,0xFFFFEB73,0x000004C6,0x00001B23,0xFFFFF7CB,0x0000031A,0x00001B23,0xFFFFF7CB,0x0000031A}, - {"0000001000010011111100001111111010011001000010100010100100100100",0x000031C0,0xFFFFEABA,0x000004F7,0x00001A5A,0xFFFFF845,0x000002FF,0x00001A5A,0xFFFFF845,0x000002FF}, - {"0000001000010011111100001111111010011001000100000100100101000100",0x00003B77,0xFFFFE3B3,0x00000623,0x00001BCA,0xFFFFF6F8,0x00000333,0x00001BCA,0xFFFFF6F8,0x00000333}, - {"0000001000010011111100001111111010011001000010100011100101000100",0x000035AF,0xFFFFE76D,0x00000588,0x00001C16,0xFFFFF6AB,0x00000341,0x00001C16,0xFFFFF6AB,0x00000341}, - {"0000001000010011111010101001010011011110000001000011100011000100",0x000032AD,0xFFFFEA8E,0x000004F8,0x00001A3A,0xFFFFF832,0x0000030E,0x00001A3A,0xFFFFF832,0x0000030E}, - {"0000001000010011111100001111111010011001000100000100100010000100",0x00002E92,0xFFFFEBD2,0x000004DA,0x00001E04,0xFFFFF51E,0x0000038A,0x00001E04,0xFFFFF51E,0x0000038A}, - {"0000001000010011111100001111110101000010110101000100000010100100",0x00003E57,0xFFFFE0F7,0x0000068F,0x000021F1,0xFFFFF1C6,0x00000411,0x000021F1,0xFFFFF1C6,0x00000411}, - {"0000001000010011111100001111111010011001000010000010000110100100",0x00003598,0xFFFFE8BB,0x00000535,0x00001B62,0xFFFFF764,0x00000326,0x00001B62,0xFFFFF764,0x00000326}, - {"0000001000010011111100001111111010011001000010100011100010000100",0x00002B15,0xFFFFEDEC,0x00000487,0x00001E8B,0xFFFFF4AB,0x0000039F,0x00001E8B,0xFFFFF4AB,0x0000039F}, - {"0000001000010011111010101001010011011110000001100000100100000100",0x0000267E,0xFFFFF1A7,0x000003E1,0x000021C1,0xFFFFF2E9,0x000003EA,0x000021C1,0xFFFFF2E9,0x000003EA}, - {"0000001000010011111010101001010011011110000000100011100110100100",0x00002ED7,0xFFFFEC88,0x000004A6,0x00001DEC,0xFFFFF57C,0x00000378,0x00001DEC,0xFFFFF57C,0x00000378}, - {"0000001000010011111010101001010011011110000001000100000110100100",0x00003365,0xFFFFE946,0x00000536,0x000019E9,0xFFFFF7E0,0x0000031D,0x000019E9,0xFFFFF7E0,0x0000031D}, - {"0000001000010011111100001111111010011001000110000001100011100100",0x000029A4,0xFFFFF0FD,0x000003FE,0x0000163F,0xFFFFFB68,0x00000299,0x0000163F,0xFFFFFB68,0x00000299}, - {"0000001000010011111010101001010011011110000000100001100100000100",0x0000348D,0xFFFFE9F7,0x00000509,0x000017A0,0xFFFFFA59,0x000002B6,0x000017A0,0xFFFFFA59,0x000002B6}, - {"0000001000010011111100001111111010011001000001100001000011000100",0x00003144,0xFFFFEB23,0x000004D9,0x00001C9B,0xFFFFF664,0x00000351,0x00001C9B,0xFFFFF664,0x00000351}, - {"0000001000010011111010101001010011011110000001100010000011100100",0x00002E95,0xFFFFEE1A,0x00000463,0x00001707,0xFFFFFAB7,0x000002B3,0x00001707,0xFFFFFAB7,0x000002B3}, - {"0000001000010011111100001111110101000010110101000001100001100100",0x0000489C,0xFFFFDA43,0x000007AC,0x00002866,0xFFFFED6B,0x000004D0,0x00002866,0xFFFFED6B,0x000004D0}, - {"0000001000010011111100001111111010011001000101100001100001000100",0x00002895,0xFFFFF10A,0x0000040A,0x000013E9,0xFFFFFC9F,0x0000026E,0x000013E9,0xFFFFFC9F,0x0000026E}, - {"0000001000010011111100001111111010011001000001100001100101100100",0x000033A0,0xFFFFE9B1,0x00000510,0x00001D96,0xFFFFF5AE,0x0000036F,0x00001D96,0xFFFFF5AE,0x0000036F}, - {"0000001000010011111100001111111010011001000010000011100110000100",0x0000327C,0xFFFFEAEA,0x000004DD,0x00001D45,0xFFFFF649,0x00000356,0x00001D45,0xFFFFF649,0x00000356}, - {"0000001000010011111010101001010011011110000000100100100010100100",0x000031DF,0xFFFFE9AB,0x0000052F,0x000019C8,0xFFFFF7B7,0x00000321,0x000019C8,0xFFFFF7B7,0x00000321}, - {"0000001000010011111100001111111010011001000101100100000010100100",0x00002BCC,0xFFFFEEF4,0x0000045C,0x000015CD,0xFFFFFB58,0x0000029E,0x000015CD,0xFFFFFB58,0x0000029E}, - {"0000001000010011111100001111111010011001000001100011100011100100",0x00003534,0xFFFFEA10,0x000004EB,0x00001BB6,0xFFFFF7B9,0x00000314,0x00001BB6,0xFFFFF7B9,0x00000314}, - {"0000001000010011111100001111111010011001000001000001100110000100",0x00002F4F,0xFFFFEC35,0x000004B9,0x0000205D,0xFFFFF47F,0x00000392,0x0000205D,0xFFFFF47F,0x00000392}, - {"0000001000010011111100001111111010011001000011000010000010100100",0x00003295,0xFFFFEB1C,0x000004D6,0x000019C1,0xFFFFF931,0x000002D5,0x000019C1,0xFFFFF931,0x000002D5}, - {"0000001000010011111100001111111010011001000000100100000101000100",0x00003557,0xFFFFE7F7,0x00000568,0x00002342,0xFFFFF1F9,0x00000405,0x00002342,0xFFFFF1F9,0x00000405}, - {"0000001000010011111100001111111010011001000001000101000011000100",0x00003487,0xFFFFE872,0x0000055D,0x000019D7,0xFFFFF823,0x0000030C,0x000019D7,0xFFFFF823,0x0000030C}, - {"0000001000010011111100001111111010011001001011000011100101000100",0x0000378F,0xFFFFE7A6,0x00000566,0x00001875,0xFFFFFA04,0x000002AF,0x00001875,0xFFFFFA04,0x000002AF}, - {"0000001000010011111010101001010011011110000000100011000011100100",0x00002A67,0xFFFFF157,0x000003DD,0x000017BD,0xFFFFFA53,0x000002D1,0x000017BD,0xFFFFFA53,0x000002D1}, - {"0000001000010011111100001111110101000010110100100010000011100100",0x000030B5,0xFFFFEB32,0x000004D9,0x00002129,0xFFFFF38A,0x000003BB,0x00002129,0xFFFFF38A,0x000003BB}, - {"0000001000010011111100001111111010011001000001100001000010100100",0x00003786,0xFFFFE703,0x00000584,0x00001D63,0xFFFFF5DC,0x00000367,0x00001D63,0xFFFFF5DC,0x00000367}, - {"0000001000010011111100001111110101000010110110100010000011000100",0x0000346A,0xFFFFE93E,0x0000052C,0x00001B27,0xFFFFF79D,0x0000031F,0x00001B27,0xFFFFF79D,0x0000031F}, - {"0000001000010011111100001111111010011001000011100011000000100100",0x0000294E,0xFFFFF0A5,0x00000409,0x00001928,0xFFFFF93B,0x000002E6,0x00001928,0xFFFFF93B,0x000002E6}, - {"0000001000010011111100001111110101000010110101000001000011000100",0x00003E09,0xFFFFE0FF,0x00000694,0x000025A0,0xFFFFEF0F,0x0000048F,0x000025A0,0xFFFFEF0F,0x0000048F}, - {"0000001000010011111100001111111010011001000010100010100101100100",0x00003197,0xFFFFEA06,0x00000520,0x00001B42,0xFFFFF73B,0x0000032A,0x00001B42,0xFFFFF73B,0x0000032A}, - {"0000001000010011111100001111111010011001000101100001100001100100",0x000022CB,0xFFFFF3FC,0x000003A3,0x00001449,0xFFFFFBD0,0x00000297,0x00001449,0xFFFFFBD0,0x00000297}, - {"0000001000010011111100001111110101000010110110000010100101000100",0x00002A79,0xFFFFEFD2,0x00000433,0x00001585,0xFFFFFB92,0x0000028E,0x00001585,0xFFFFFB92,0x0000028E}, - {"0000001000010011111100001111111010011001000011000100000110000100",0x00003249,0xFFFFEA92,0x000004F4,0x000019CB,0xFFFFF8CF,0x000002E1,0x000019CB,0xFFFFF8CF,0x000002E1}, - {"0000001000010011111010101001010011011110000000100001100010100100",0x00002CEA,0xFFFFEE46,0x00000463,0x00001A5E,0xFFFFF83C,0x0000030D,0x00001A5E,0xFFFFF83C,0x0000030D}, - {"0000001000010011111100001111110101000010110111000101000101000100",0x00003AE2,0xFFFFE422,0x00000600,0x00001C65,0xFFFFF62F,0x0000034B,0x00001C65,0xFFFFF62F,0x0000034B}, - {"0000001000010011111100001111111010011001000110000001000110000100",0x000026A0,0xFFFFF1C2,0x000003F8,0x000010E5,0xFFFFFE56,0x0000022A,0x000010E5,0xFFFFFE56,0x0000022A}, - {"0000001000010011111100001111111010011001001010000010100110100100",0x00002A7B,0xFFFFF063,0x00000417,0x000016FC,0xFFFFFAD7,0x000002B1,0x000016FC,0xFFFFFAD7,0x000002B1}, - {"0000001000010011111100001111111010011001001100100001000011000100",0x00003092,0xFFFFEAB9,0x00000507,0x00001AE3,0xFFFFF783,0x00000323,0x00001AE3,0xFFFFF783,0x00000323}, - {"0000001000010011111100001111111010011001000001000011100011100100",0x00003265,0xFFFFEBE8,0x000004AA,0x00001D65,0xFFFFF73F,0x00000321,0x00001D65,0xFFFFF73F,0x00000321}, - {"0000001000010011111010101001010011011110000000100011000010000100",0x00002F14,0xFFFFECC2,0x000004A4,0x00001A8D,0xFFFFF7F3,0x0000031D,0x00001A8D,0xFFFFF7F3,0x0000031D}, - {"0000001000010011111100001111110101000010110111000001000011100100",0x000035FB,0xFFFFE6D3,0x000005AC,0x00001B19,0xFFFFF712,0x00000338,0x00001B19,0xFFFFF712,0x00000338}, - {"0000001000010011111100001111110101000010110110100010000100100100",0x00003519,0xFFFFE8CC,0x0000053A,0x00001A0F,0xFFFFF86E,0x000002F5,0x00001A0F,0xFFFFF86E,0x000002F5}, - {"0000001000010011111100001111111010011001001011000010000101000100",0x0000364C,0xFFFFE879,0x00000541,0x00001A42,0xFFFFF8BA,0x000002E2,0x00001A42,0xFFFFF8BA,0x000002E2}, - {"0000001000010011111010101001010011011110000000100001100011000100",0x000029BA,0xFFFFF09A,0x00000408,0x00001986,0xFFFFF8D9,0x000002FE,0x00001986,0xFFFFF8D9,0x000002FE}, - {"0000001000010011111100001111110101000010110110100011100011100100",0x00003507,0xFFFFE961,0x00000518,0x00001B79,0xFFFFF775,0x00000325,0x00001B79,0xFFFFF775,0x00000325}, - {"0000001000010011111100001111110101000010110111000011000110000100",0x00003AD5,0xFFFFE415,0x00000613,0x00001CB4,0xFFFFF66D,0x00000348,0x00001CB4,0xFFFFF66D,0x00000348}, - {"0000001000010011111100001111111010011001000101100100000011100100",0x000023D1,0xFFFFF42B,0x0000038F,0x00001546,0xFFFFFBA0,0x0000029F,0x00001546,0xFFFFFBA0,0x0000029F}, - {"0000001000010011111100001111111010011001000010100001100100100100",0x0000399E,0xFFFFE518,0x000005E7,0x00001990,0xFFFFF871,0x000002FB,0x00001990,0xFFFFF871,0x000002FB}, - {"0000001000010011111100001111110101000010110110000010100101100100",0x00002EDE,0xFFFFEC93,0x000004B8,0x0000152C,0xFFFFFBB3,0x0000027E,0x0000152C,0xFFFFFBB3,0x0000027E}, - {"0000001000010011111010101001010011011110000001000010100101100100",0x00003140,0xFFFFEBC9,0x000004BB,0x000016BE,0xFFFFFB0A,0x00000288,0x000016BE,0xFFFFFB0A,0x00000288}, - {"0000001000010011111100001111111010011001000001100100000001100100",0x000030F6,0xFFFFEB89,0x000004CD,0x0000185D,0xFFFFF95A,0x000002D9,0x0000185D,0xFFFFF95A,0x000002D9}, - {"0000001000010011111100001111111010011001000000100011100001000100",0x0000389C,0xFFFFE65A,0x000005A2,0x0000195D,0xFFFFF8C8,0x000002E8,0x0000195D,0xFFFFF8C8,0x000002E8}, - {"0000001000010011111100001111111010011001000001000010000100000100",0x0000362B,0xFFFFE9EC,0x000004F6,0x00001605,0xFFFFFC1C,0x00000263,0x00001605,0xFFFFFC1C,0x00000263}, - {"0000001000010011111100001111111010011001001010100001100101100100",0x00002946,0xFFFFF04F,0x00000426,0x000015BA,0xFFFFFB2F,0x000002A3,0x000015BA,0xFFFFFB2F,0x000002A3}, - {"0000001000010011111100001111111010011001000010000010000110000100",0x0000368E,0xFFFFE837,0x0000054A,0x000017D7,0xFFFFF9EB,0x000002BA,0x000017D7,0xFFFFF9EB,0x000002BA}, - {"0000001000010011111100001111110101000010110110100010100001000100",0x00002E74,0xFFFFEBE8,0x000004DA,0x00001DD6,0xFFFFF57E,0x00000379,0x00001DD6,0xFFFFF57E,0x00000379}, - {"0000001000010011111100001111111010011001000001000001100101000100",0x0000322D,0xFFFFEAA8,0x000004F5,0x00001B55,0xFFFFF7DD,0x0000030B,0x00001B55,0xFFFFF7DD,0x0000030B}, - {"0000001000010011111100001111111010011001000110000001100100000100",0x00002A29,0xFFFFF07B,0x00000416,0x00001671,0xFFFFFB3E,0x0000029F,0x00001671,0xFFFFFB3E,0x0000029F}, - {"0000001000010011111100001111110101000010110110100010000100000100",0x000030F6,0xFFFFEB89,0x000004CD,0x00001815,0xFFFFF9AE,0x000002C9,0x00001815,0xFFFFF9AE,0x000002C9}, - {"0000001000010011111100001111111010011001000011100001000011100100",0x0000265F,0xFFFFF1CB,0x000003D5,0x00001ED2,0xFFFFF539,0x0000037A,0x00001ED2,0xFFFFF539,0x0000037A}, - {"0000001000010011111100001111111010011001000101100010000110000100",0x000027A8,0xFFFFF10D,0x00000413,0x000014B5,0xFFFFFBA1,0x00000299,0x000014B5,0xFFFFFBA1,0x00000299}, - {"0000001000010011111100001111111010011001000001000011000001100100",0x00002CEE,0xFFFFEDF6,0x00000476,0x00001A99,0xFFFFF83E,0x00000305,0x00001A99,0xFFFFF83E,0x00000305}, - {"0000001000010011111100001111111010011001000001100100000011000100",0x0000346C,0xFFFFEA17,0x000004EF,0x00001D38,0xFFFFF69F,0x0000033D,0x00001D38,0xFFFFF69F,0x0000033D}, - {"0000001000010011111100001111110101000010110110100010100101000100",0x00002DBB,0xFFFFED35,0x00000490,0x000018C1,0xFFFFF930,0x000002DA,0x000018C1,0xFFFFF930,0x000002DA}, - {"0000001000010011111100001111111010011001000001000010100100100100",0x000038DF,0xFFFFE8A7,0x0000051E,0x00001B59,0xFFFFF915,0x000002D3,0x00001B59,0xFFFFF915,0x000002D3}, - {"0000001000010011111100001111111010011001000010000000100101000100",0x00003384,0xFFFFE979,0x00000524,0x00001AF3,0xFFFFF74C,0x0000032F,0x00001AF3,0xFFFFF74C,0x0000032F}, - {"0000001000010011111100001111111010011001000110000001100001100100",0x0000258B,0xFFFFF2AE,0x000003CB,0x0000190C,0xFFFFF93E,0x000002EF,0x0000190C,0xFFFFF93E,0x000002EF}, - {"0000001000010011111100001111111010011001000100000011100010000100",0x000034F1,0xFFFFE84B,0x0000055E,0x00001CB8,0xFFFFF670,0x0000034A,0x00001CB8,0xFFFFF670,0x0000034A}, - {"0000001000010011111100001111111010011001000011000010000100000100",0x000030FB,0xFFFFECD2,0x00000488,0x00001BF4,0xFFFFF821,0x00000302,0x00001BF4,0xFFFFF821,0x00000302}, - {"0000001000010011111100001111111010011001000001100011000001000100",0x000036A6,0xFFFFE815,0x00000556,0x000018FD,0xFFFFF925,0x000002DF,0x000018FD,0xFFFFF925,0x000002DF}, - {"0000001000010011111010101001010011011110000000100011000001000100",0x0000302A,0xFFFFEB79,0x000004E0,0x00001C11,0xFFFFF694,0x00000358,0x00001C11,0xFFFFF694,0x00000358}, - {"0000001000010011111100001111111010011001000110000001000100100100",0x00002555,0xFFFFF2C4,0x000003CB,0x000017E3,0xFFFFFA1F,0x000002CB,0x000017E3,0xFFFFFA1F,0x000002CB}, - {"0000001000010011111100001111111010011001000010100011000101100100",0x000032A3,0xFFFFE933,0x00000544,0x000019D3,0xFFFFF81A,0x00000306,0x000019D3,0xFFFFF81A,0x00000306}, - {"0000001000010011111100001111110101000010110110000101000100000100",0x00002B91,0xFFFFED81,0x000004A9,0x0000158B,0xFFFFFAB9,0x000002AC,0x0000158B,0xFFFFFAB9,0x000002AC}, - {"0000001000010011111100001111111010011001000011100010000011000100",0x00003537,0xFFFFE912,0x0000052C,0x00001C8A,0xFFFFF754,0x0000031B,0x00001C8A,0xFFFFF754,0x0000031B}, - {"0000001000010011111010101001010011011110000001100011000110000100",0x000032E1,0xFFFFEA5A,0x000004F9,0x000017B4,0xFFFFF9D9,0x000002C2,0x000017B4,0xFFFFF9D9,0x000002C2}, - {"0000001000010011111100001111110101000010110100100001000011000100",0x00003B76,0xFFFFE330,0x00000636,0x000026FB,0xFFFFEF06,0x00000481,0x000026FB,0xFFFFEF06,0x00000481}, - {"0000001000010011111100001111111010011001000001000010000101000100",0x0000320C,0xFFFFEB84,0x000004C3,0x00001A3A,0xFFFFF8E9,0x000002DF,0x00001A3A,0xFFFFF8E9,0x000002DF}, - {"0000001000010011111100001111111010011001000000100011100110000100",0x0000317D,0xFFFFEA1F,0x00000515,0x00002100,0xFFFFF31B,0x000003DD,0x00002100,0xFFFFF31B,0x000003DD}, - {"0000001000010011111100001111110101000010110101000011000101100100",0x00003DCB,0xFFFFE0B4,0x000006B4,0x00002160,0xFFFFF269,0x000003F0,0x00002160,0xFFFFF269,0x000003F0}, - {"0000001000010011111100001111111010011001000101100001100011000100",0x00002737,0xFFFFF218,0x000003E1,0x000015B5,0xFFFFFB8F,0x0000029C,0x000015B5,0xFFFFFB8F,0x0000029C}, - {"0000001000010011111010101001010011011110000000100011000110000100",0x0000318F,0xFFFFEB3F,0x000004D8,0x00001938,0xFFFFF8E9,0x000002EB,0x00001938,0xFFFFF8E9,0x000002EB}, - {"0000001000010011111100001111111010011001000100000100100011000100",0x000031BD,0xFFFFE9DE,0x00000527,0x000018A7,0xFFFFF8CA,0x000002ED,0x000018A7,0xFFFFF8CA,0x000002ED}, - {"0000001000010011111100001111110101000010110110100011100010000100",0x00002F77,0xFFFFEC2F,0x000004B4,0x00001D25,0xFFFFF61B,0x0000035D,0x00001D25,0xFFFFF61B,0x0000035D}, - {"0000001000010011111100001111111010011001000011100100100100000100",0x00002CCA,0xFFFFEDB3,0x0000047C,0x00001FBD,0xFFFFF4A7,0x00000391,0x00001FBD,0xFFFFF4A7,0x00000391}, - {"0000001000010011111100001111110101000010110101000011100010100100",0x00003FF6,0xFFFFE058,0x000006A2,0x000024CD,0xFFFFF026,0x00000452,0x000024CD,0xFFFFF026,0x00000452}, - {"0000001000010011111100001111111010011001000010100011100011100100",0x00003161,0xFFFFEAC8,0x000004F3,0x00001BB6,0xFFFFF72A,0x0000032B,0x00001BB6,0xFFFFF72A,0x0000032B}, - {"0000001000010011111100001111110101000010110110000011100010100100",0x00002EA0,0xFFFFECA6,0x000004B7,0x000018C2,0xFFFFF94E,0x000002E1,0x000018C2,0xFFFFF94E,0x000002E1}, - {"0000001000010011111100001111111010011001000110000010000110000100",0x00002F62,0xFFFFEC9E,0x000004B8,0x00001531,0xFFFFFBCD,0x00000285,0x00001531,0xFFFFFBCD,0x00000285}, - {"0000001000010011111100001111111010011001000001000100000010100100",0x00003013,0xFFFFEBD6,0x000004C2,0x00001B01,0xFFFFF802,0x000002FF,0x00001B01,0xFFFFF802,0x000002FF}, - {"0000001000010011111100001111111010011001000110000011000001100100",0x00002972,0xFFFFF08D,0x00000417,0x00001A32,0xFFFFF8A4,0x00000305,0x00001A32,0xFFFFF8A4,0x00000305}, - {"0000001000010011111100001111110101000010110110000010000011100100",0x00002E95,0xFFFFED94,0x00000487,0x00001529,0xFFFFFC26,0x00000271,0x00001529,0xFFFFFC26,0x00000271}, - {"0000001000010011111100001111111010011001000010100001000010000100",0x00002D6A,0xFFFFEC79,0x000004C1,0x00001AE2,0xFFFFF725,0x00000337,0x00001AE2,0xFFFFF725,0x00000337}, - {"0000001000010011111100001111111010011001000000100001100010000100",0x000036B4,0xFFFFE704,0x00000591,0x00001E7E,0xFFFFF51C,0x00000383,0x00001E7E,0xFFFFF51C,0x00000383}, - {"0000001000010011111100001111111010011001000001000001100001000100",0x00002A6F,0xFFFFEF70,0x00000443,0x00001BAA,0xFFFFF752,0x00000336,0x00001BAA,0xFFFFF752,0x00000336}, - {"0000001000010011111100001111111010011001000110000011100101000100",0x00002C66,0xFFFFEF5F,0x0000043A,0x000019F7,0xFFFFF931,0x000002EC,0x000019F7,0xFFFFF931,0x000002EC}, - {"0000001000010011111010101001010011011110000001100011000111000100",0x00003852,0xFFFFE6AB,0x00000590,0x000019C1,0xFFFFF8B1,0x000002E5,0x000019C1,0xFFFFF8B1,0x000002E5}, - {"0000001000010011111100001111110101000010110110100011000100100100",0x00003521,0xFFFFE932,0x00000523,0x000018A9,0xFFFFF96B,0x000002D0,0x000018A9,0xFFFFF96B,0x000002D0}, - {"0000001000010011111100001111111010011001000001100010000101100100",0x000031B9,0xFFFFEB36,0x000004D0,0x00001D65,0xFFFFF612,0x0000035D,0x00001D65,0xFFFFF612,0x0000035D}, - {"0000001000010011111100001111110101000010110101000001000001100100",0x00003ED0,0xFFFFE135,0x00000679,0x00002351,0xFFFFF0FE,0x00000433,0x00002351,0xFFFFF0FE,0x00000433}, - {"0000001000010011111100001111111010011001000010100010000011100100",0x000033ED,0xFFFFE91A,0x00000541,0x00001C93,0xFFFFF6A0,0x0000034A,0x00001C93,0xFFFFF6A0,0x0000034A}, - {"0000001000010011111010101001010011011110000000100001100001000100",0x0000356F,0xFFFFE8F7,0x00000530,0x000016BF,0xFFFFFA85,0x000002AB,0x000016BF,0xFFFFFA85,0x000002AB}, - {"0000001000010011111100001111111010011001000110000100000011100100",0x00002304,0xFFFFF4F3,0x00000364,0x000017CC,0xFFFFFA41,0x000002CA,0x000017CC,0xFFFFFA41,0x000002CA}, - {"0000001000010011111100001111111010011001000101100001000101100100",0x00002887,0xFFFFEFD7,0x00000450,0x00001474,0xFFFFFB94,0x00000299,0x00001474,0xFFFFFB94,0x00000299}, - {"0000001000010011111100001111111010011001000001100011000001100100",0x00003D0B,0xFFFFE416,0x000005EF,0x00001C7E,0xFFFFF71D,0x00000325,0x00001C7E,0xFFFFF71D,0x00000325}, - {"0000001000010011111100001111111010011001000010000001000011100100",0x00003185,0xFFFFEAFA,0x000004E4,0x00001A12,0xFFFFF83C,0x00000303,0x00001A12,0xFFFFF83C,0x00000303}, - {"0000001000010011111100001111111010011001000010100001100101000100",0x00003032,0xFFFFEAE6,0x000004FC,0x00001B2A,0xFFFFF73F,0x0000032B,0x00001B2A,0xFFFFF73F,0x0000032B}, - {"0000001000010011111100001111110101000010110110000011100011000100",0x00002691,0xFFFFF22D,0x000003D6,0x00001700,0xFFFFFA6E,0x000002C0,0x00001700,0xFFFFFA6E,0x000002C0}, - {"0000001000010011111100001111111010011001000000100001100010100100",0x00002B2F,0xFFFFEEC4,0x0000044B,0x0000215F,0xFFFFF33F,0x000003D2,0x0000215F,0xFFFFF33F,0x000003D2}, - {"0000001000010011111100001111111010011001000010100100000110000100",0x000034AA,0xFFFFE706,0x000005B1,0x00001B28,0xFFFFF6B5,0x00000349,0x00001B28,0xFFFFF6B5,0x00000349}, - {"0000001000010011111100001111110101000010110110100010100101100100",0x0000307E,0xFFFFEB38,0x000004E6,0x00001A22,0xFFFFF83F,0x00000300,0x00001A22,0xFFFFF83F,0x00000300}, - {"0000001000010011111100001111111010011001000001100001100010100100",0x000038D6,0xFFFFE6D8,0x0000057C,0x00001B24,0xFFFFF7E4,0x00000307,0x00001B24,0xFFFFF7E4,0x00000307}, - {"0000001000010011111100001111111010011001000110000011000001000100",0x00002757,0xFFFFF1E8,0x000003DD,0x000017F5,0xFFFFFA15,0x000002C8,0x000017F5,0xFFFFFA15,0x000002C8}, - {"0000001000010011111100001111111010011001000010000011000110000100",0x000031FC,0xFFFFEB3E,0x000004CE,0x00001B4C,0xFFFFF7AD,0x00000319,0x00001B4C,0xFFFFF7AD,0x00000319}, - {"0000001000010011111100001111111010011001001100000001100001100100",0x00002933,0xFFFFF073,0x0000040E,0x00001C3C,0xFFFFF701,0x0000033C,0x00001C3C,0xFFFFF701,0x0000033C}, - {"0000001000010011111100001111110101000010110100100001100010100100",0x000040BB,0xFFFFE066,0x0000069A,0x0000257F,0xFFFFF08A,0x00000435,0x0000257F,0xFFFFF08A,0x00000435}, - {"0000001000010011111100001111111010011001000100000001000010100100",0x0000305B,0xFFFFEB9B,0x000004CB,0x00001996,0xFFFFF846,0x00000308,0x00001996,0xFFFFF846,0x00000308}, - {"0000001000010011111100001111111010011001000001100100100010000100",0x000039C0,0xFFFFE5D3,0x000005B0,0x00001A8D,0xFFFFF7DA,0x00000313,0x00001A8D,0xFFFFF7DA,0x00000313}, - {"0000001000010011111010101001010011011110000000100001000010100100",0x00002E23,0xFFFFED3F,0x0000048F,0x0000189D,0xFFFFF94C,0x000002DE,0x0000189D,0xFFFFF94C,0x000002DE}, - {"0000001000010011111010101001010011011110000000100001100110000100",0x0000332B,0xFFFFE9F1,0x00000516,0x000018E6,0xFFFFF8FE,0x000002EC,0x000018E6,0xFFFFF8FE,0x000002EC}, - {"0000001000010011111100001111111010011001000010000011100011000100",0x000034A0,0xFFFFEA44,0x000004E4,0x00001ECD,0xFFFFF5B4,0x00000364,0x00001ECD,0xFFFFF5B4,0x00000364}, - {"0000001000010011111100001111110101000010110100100100000100000100",0x0000448C,0xFFFFDF34,0x000006A8,0x0000231C,0xFFFFF286,0x000003D9,0x0000231C,0xFFFFF286,0x000003D9}, - {"0000001000010011111010101001010011011110000001100010000101000100",0x00002D8C,0xFFFFEE65,0x00000456,0x000018B1,0xFFFFF9C8,0x000002C8,0x000018B1,0xFFFFF9C8,0x000002C8}, - {"0000001000010011111100001111111010011001000001100001100100000100",0x00003527,0xFFFFE9BF,0x000004FD,0x00001D23,0xFFFFF69F,0x00000342,0x00001D23,0xFFFFF69F,0x00000342}, - {"0000001000010011111100001111110101000010110111000011100010100100",0x00002C51,0xFFFFEDC3,0x00000483,0x00001BE0,0xFFFFF720,0x0000032D,0x00001BE0,0xFFFFF720,0x0000032D}, - {"0000001000010011111100001111111010011001000010100011000001000100",0x00002C6C,0xFFFFECEB,0x000004B7,0x00001C86,0xFFFFF5E7,0x00000371,0x00001C86,0xFFFFF5E7,0x00000371}, - {"0000001000010011111100001111111010011001000001000101000101000100",0x000037CF,0xFFFFE6BE,0x00000599,0x000018CD,0xFFFFF967,0x000002C7,0x000018CD,0xFFFFF967,0x000002C7}, - {"0000001000010011111100001111111010011001000100000011000101100100",0x00002E6F,0xFFFFED1D,0x0000048E,0x00001ADC,0xFFFFF7F4,0x0000030E,0x00001ADC,0xFFFFF7F4,0x0000030E}, - {"0000001000010011111100001111110101000010110101000010100110000100",0x00003FF3,0xFFFFDF13,0x000006F9,0x000025BF,0xFFFFEEEE,0x00000497,0x000025BF,0xFFFFEEEE,0x00000497}, - {"0000001000010011111100001111110101000010110111000101000100000100",0x00004135,0xFFFFDF97,0x000006CC,0x00001D52,0xFFFFF541,0x00000383,0x00001D52,0xFFFFF541,0x00000383}, - {"0000001000010011111100001111110101000010110111000010000011100100",0x00002EA9,0xFFFFEDDB,0x0000045F,0x0000197C,0xFFFFF8E1,0x000002F0,0x0000197C,0xFFFFF8E1,0x000002F0}, - {"0000001000010011111010101001010011011110000001000011000010000100",0x0000345C,0xFFFFE922,0x00000532,0x00001922,0xFFFFF8C7,0x000002F1,0x00001922,0xFFFFF8C7,0x000002F1}, - {"0000001000010011111100001111111010011001000001100100000100100100",0x000035C4,0xFFFFE8FE,0x00000521,0x00001C87,0xFFFFF6F3,0x00000330,0x00001C87,0xFFFFF6F3,0x00000330}, - {"0000001000010011111100001111110101000010110110000011000101100100",0x00002888,0xFFFFF08A,0x0000041E,0x0000150F,0xFFFFFB87,0x00000291,0x0000150F,0xFFFFFB87,0x00000291}, - {"0000001000010011111100001111111010011001000010100001000100100100",0x000035E9,0xFFFFE657,0x000005CC,0x00001BD6,0xFFFFF664,0x00000355,0x00001BD6,0xFFFFF664,0x00000355}, - {"0000001000010011111100001111111010011001000101100100100011100100",0x00002F94,0xFFFFEBD0,0x000004E5,0x00001333,0xFFFFFCA7,0x00000266,0x00001333,0xFFFFFCA7,0x00000266}, - {"0000001000010011111100001111111010011001000110000001100101100100",0x000029E7,0xFFFFF009,0x00000433,0x0000144A,0xFFFFFC37,0x0000027D,0x0000144A,0xFFFFFC37,0x0000027D}, - {"0000001000010011111100001111111010011001001011000001100101000100",0x00003418,0xFFFFE979,0x00000521,0x00001D33,0xFFFFF66B,0x0000034A,0x00001D33,0xFFFFF66B,0x0000034A}, - {"0000001000010011111010101001010011011110000001000100000011100100",0x00003656,0xFFFFE79D,0x0000057A,0x000017C2,0xFFFFF992,0x000002D4,0x000017C2,0xFFFFF992,0x000002D4}, - {"0000001000010011111100001111111010011001000011000100000011000100",0x00002EB2,0xFFFFECFE,0x00000493,0x00001F2A,0xFFFFF543,0x0000037B,0x00001F2A,0xFFFFF543,0x0000037B}, - {"0000001000010011111100001111111010011001000000100001000100100100",0x00002FC1,0xFFFFEB3F,0x000004E8,0x00001CD0,0xFFFFF5F7,0x00000364,0x00001CD0,0xFFFFF5F7,0x00000364}, - {"0000001000010011111100001111111010011001000011000001000100100100",0x0000307B,0xFFFFEB66,0x000004DE,0x00001953,0xFFFFF8ED,0x000002E4,0x00001953,0xFFFFF8ED,0x000002E4}, - {"0000001000010011111100001111110101000010110110100001100010000100",0x00002CAA,0xFFFFED07,0x000004AC,0x0000251C,0xFFFFF086,0x0000044D,0x0000251C,0xFFFFF086,0x0000044D}, - {"0000001000010011111010101001010011011110000001000011100101000100",0x00002C94,0xFFFFEE5F,0x0000045B,0x000018D7,0xFFFFF900,0x000002EB,0x000018D7,0xFFFFF900,0x000002EB}, - {"0000001000010011111100001111111010011001000000100001100001100100",0x000031F1,0xFFFFE9BE,0x0000052E,0x00001DDF,0xFFFFF558,0x00000380,0x00001DDF,0xFFFFF558,0x00000380}, - {"0000001000010011111100001111111010011001000011100101000011000100",0x00002603,0xFFFFF1E9,0x000003DA,0x00001B37,0xFFFFF75A,0x0000032F,0x00001B37,0xFFFFF75A,0x0000032F}, - {"0000001000010011111100001111110101000010110110100011000001000100",0x00003992,0xFFFFE4F9,0x000005EB,0x00001775,0xFFFFF9B8,0x000002C2,0x00001775,0xFFFFF9B8,0x000002C2}, - {"0000001000010011111100001111111010011001000110000100100101100100",0x000029DA,0xFFFFF052,0x0000041F,0x000016E2,0xFFFFFA99,0x000002BB,0x000016E2,0xFFFFFA99,0x000002BB}, - {"0000001000010011111100001111111010011001000100000001000001100100",0x00002FF2,0xFFFFEB8F,0x000004DF,0x00001AF6,0xFFFFF7A1,0x00000321,0x00001AF6,0xFFFFF7A1,0x00000321}, - {"0000001000010011111100001111111010011001000101100000100011100100",0x00002590,0xFFFFF222,0x000003EE,0x0000130B,0xFFFFFCC9,0x00000268,0x0000130B,0xFFFFFCC9,0x00000268}, - {"0000001000010011111100001111111010011001000000100100000001100100",0x000038A2,0xFFFFE65F,0x000005A2,0x000018B1,0xFFFFF917,0x000002E1,0x000018B1,0xFFFFF917,0x000002E1}, - {"0000001000010011111100001111110101000010110111000100100011100100",0x000035FD,0xFFFFE73C,0x0000058D,0x00001BB3,0xFFFFF6E1,0x00000337,0x00001BB3,0xFFFFF6E1,0x00000337}, - {"0000001000010011111100001111111010011001000100000011100011000100",0x00002AB7,0xFFFFEF98,0x00000429,0x00001F35,0xFFFFF539,0x0000037C,0x00001F35,0xFFFFF539,0x0000037C}, - {"0000001000010011111100001111111010011001000010100000100101000100",0x000034BA,0xFFFFE73D,0x000005A6,0x000018A6,0xFFFFF888,0x000002FB,0x000018A6,0xFFFFF888,0x000002FB}, - {"0000001000010011111100001111111010011001000001100011100001000100",0x000032EA,0xFFFFEA78,0x000004F4,0x00001AB6,0xFFFFF812,0x00000308,0x00001AB6,0xFFFFF812,0x00000308}, - {"0000001000010011111100001111111010011001000011000011000001000100",0x00002BE9,0xFFFFEE9A,0x00000457,0x00001942,0xFFFFF8D2,0x000002F2,0x00001942,0xFFFFF8D2,0x000002F2}, - {"0000001000010011111100001111111010011001000100000101000100100100",0x00002FAB,0xFFFFEB76,0x000004E1,0x00001DCA,0xFFFFF57D,0x00000378,0x00001DCA,0xFFFFF57D,0x00000378}, - {"0000001000010011111100001111111010011001001011100010100001000100",0x0000330A,0xFFFFE9E1,0x0000051B,0x00001CC4,0xFFFFF6DF,0x00000335,0x00001CC4,0xFFFFF6DF,0x00000335}, - {"0000001000010011111100001111111010011001000110000010100010100100",0x000027D8,0xFFFFF276,0x000003BF,0x0000178A,0xFFFFFABF,0x000002B5,0x0000178A,0xFFFFFABF,0x000002B5}, - {"0000001000010011111100001111110101000010110111000011100001100100",0x0000340A,0xFFFFE86D,0x00000562,0x00001B85,0xFFFFF719,0x0000032F,0x00001B85,0xFFFFF719,0x0000032F}, - {"0000001000010011111010101001010011011110000001100011000010000100",0x00003879,0xFFFFE73F,0x00000578,0x0000161C,0xFFFFFB6B,0x00000281,0x0000161C,0xFFFFFB6B,0x00000281}, - {"0000001000010011111100001111111010011001000110000100000001100100",0x00002879,0xFFFFF0F8,0x0000040A,0x00001749,0xFFFFFA37,0x000002CC,0x00001749,0xFFFFFA37,0x000002CC}, - {"0000001000010011111100001111111010011001000001000011100101100100",0x00002C3A,0xFFFFEEA0,0x0000044F,0x00001D57,0xFFFFF6C2,0x00000332,0x00001D57,0xFFFFF6C2,0x00000332}, - {"0000001000010011111010101001010011011110000000100001100101100100",0x000035BB,0xFFFFE90D,0x0000052A,0x000017D9,0xFFFFF9F5,0x000002C3,0x000017D9,0xFFFFF9F5,0x000002C3}, - {"0000001000010011111010101001010011011110000001000001000100100100",0x000031F1,0xFFFFEAD4,0x000004ED,0x00001F10,0xFFFFF539,0x0000037D,0x00001F10,0xFFFFF539,0x0000037D}, - {"0000001000010011111100001111111010011001000100000010100000100100",0x00002A1A,0xFFFFEFAD,0x00000430,0x00001D47,0xFFFFF62F,0x0000035E,0x00001D47,0xFFFFF62F,0x0000035E}, - {"0000001000010011111100001111111010011001000101100100100100100100",0x00002AF0,0xFFFFEEDC,0x00000465,0x0000145F,0xFFFFFBEB,0x00000281,0x0000145F,0xFFFFFBEB,0x00000281}, - {"0000001000010011111100001111111010011001000110000011000101100100",0x00002657,0xFFFFF2E0,0x000003B6,0x00001664,0xFFFFFB37,0x000002A2,0x00001664,0xFFFFFB37,0x000002A2}, - {"0000001000010011111100001111110101000010110100000011100001100100",0x00003183,0xFFFFE9F1,0x0000052B,0x00002020,0xFFFFF3CE,0x000003C1,0x00002020,0xFFFFF3CE,0x000003C1}, - {"0000001000010011111100001111110101000010110001100010100011100100",0x00003240,0xFFFFEB65,0x000004C7,0x00002425,0xFFFFF245,0x000003F3,0x00002425,0xFFFFF245,0x000003F3}, - {"0000001000010011111010101001010011011110001100100001000100000100",0x000023D0,0xFFFFF400,0x00000397,0x00001345,0xFFFFFD6B,0x00000241,0x00001345,0xFFFFFD6B,0x00000241}, - {"0000001000010011111100001111110101000010110011100011100010100100",0x00003440,0xFFFFE872,0x0000055B,0x00002247,0xFFFFF296,0x000003E8,0x00002247,0xFFFFF296,0x000003E8}, - {"0000001000010011111100001111110101000010110100000100100100000100",0x00003275,0xFFFFE970,0x00000538,0x00001F94,0xFFFFF429,0x000003AD,0x00001F94,0xFFFFF429,0x000003AD}, - {"0000001000010011111100001111110101000010110001100100000010100100",0x00003918,0xFFFFE5DA,0x000005B6,0x000024FC,0xFFFFF106,0x00000426,0x000024FC,0xFFFFF106,0x00000426}, - {"0000001000010011111010101001010011011110000001100010000001000100",0x0000334B,0xFFFFEA39,0x000004FD,0x00001983,0xFFFFF8F6,0x000002E2,0x00001983,0xFFFFF8F6,0x000002E2}, - {"0000001000010011111100001111110101000010110001100100100110000100",0x00003B59,0xFFFFE4D0,0x000005DA,0x00002605,0xFFFFF090,0x00000439,0x00002605,0xFFFFF090,0x00000439}, - {"0000001000010011111100001111110101000010110100000011000100100100",0x00003251,0xFFFFEA46,0x00000511,0x00002781,0xFFFFEF84,0x00000470,0x00002781,0xFFFFEF84,0x00000470}, - {"0000001000010011111100001111110101000010110010100011000101100100",0x00003304,0xFFFFE926,0x00000542,0x00001EE9,0xFFFFF4E4,0x0000038B,0x00001EE9,0xFFFFF4E4,0x0000038B}, - {"0000001000010011111100001111110101000010110011000011100011000100",0x00002F4C,0xFFFFEC0C,0x000004C4,0x00001E49,0xFFFFF578,0x00000374,0x00001E49,0xFFFFF578,0x00000374}, - {"0000001000010011111010101001010011011110000111000010000101100100",0x00002034,0xFFFFF692,0x0000034C,0x000014B8,0xFFFFFC5B,0x00000294,0x000014B8,0xFFFFFC5B,0x00000294}, - {"0000001000010011111100001111110101000010110011100100100100100100",0x0000385F,0xFFFFE513,0x000005F3,0x000024E7,0xFFFFF053,0x00000450,0x000024E7,0xFFFFF053,0x00000450}, - {"0000001000010011111010101001010011011110000111000100000011100100",0x00001D70,0xFFFFF821,0x0000030F,0x00001541,0xFFFFFBB4,0x000002B0,0x00001541,0xFFFFFBB4,0x000002B0}, - {"0000001000010011111100001111110101000010110100000010000010000100",0x000034EB,0xFFFFE7FF,0x00000575,0x000019B4,0xFFFFF836,0x00000308,0x000019B4,0xFFFFF836,0x00000308}, - {"0000001000010011111100001111110101000010110100000101000011100100",0x000037C9,0xFFFFE5D4,0x000005CD,0x000026A1,0xFFFFEF0C,0x00000491,0x000026A1,0xFFFFEF0C,0x00000491}, - {"0000001000010011111010101001010011011110000100100001100101000100",0x00002918,0xFFFFF148,0x000003E9,0x00001A49,0xFFFFF94C,0x000002CF,0x00001A49,0xFFFFF94C,0x000002CF}, - {"0000001000010011111100001111110101000010110010100100000001100100",0x00002F90,0xFFFFEAB5,0x00000514,0x00001707,0xFFFFF9C7,0x000002C4,0x00001707,0xFFFFF9C7,0x000002C4}, - {"0000001000010011111010101001010011011110000001100010000001100100",0x0000327E,0xFFFFEA99,0x000004F4,0x0000194F,0xFFFFF929,0x000002DC,0x0000194F,0xFFFFF929,0x000002DC}, - {"0000001000010011111100001111110101000010110001100100000010000100",0x0000326F,0xFFFFE9CF,0x00000519,0x00002240,0xFFFFF299,0x000003E7,0x00002240,0xFFFFF299,0x000003E7}, - {"0000001000010011111010101001010011011110001100100001000100100100",0x000022FB,0xFFFFF4C6,0x00000371,0x00001506,0xFFFFFC73,0x00000265,0x00001506,0xFFFFFC73,0x00000265}, - {"0000001000010011111100001111110101000010110010100011100100100100",0x00003AD6,0xFFFFE470,0x000005FE,0x00001F03,0xFFFFF4F3,0x00000387,0x00001F03,0xFFFFF4F3,0x00000387}, - {"0000001000010011111010101001010011011110001000000001000100100100",0x00001F11,0xFFFFF756,0x00000332,0x00001666,0xFFFFFB8A,0x000002B2,0x00001666,0xFFFFFB8A,0x000002B2}, - {"0000001000010011111010101001010011011110000000100011100010100100",0x00002A5F,0xFFFFEFA7,0x00000430,0x00001943,0xFFFFF8C6,0x000002F7,0x00001943,0xFFFFF8C6,0x000002F7}, - {"0000001000010011111010101001010011011110000101100101000011100100",0x0000235E,0xFFFFF3B4,0x000003B3,0x00001489,0xFFFFFBCF,0x0000029B,0x00001489,0xFFFFFBCF,0x0000029B}, - {"0000001000010011111100001111110101000010110011000011100010100100",0x00003570,0xFFFFE780,0x0000058D,0x00001B1D,0xFFFFF767,0x00000325,0x00001B1D,0xFFFFF767,0x00000325}, - {"0000001000010011111010101001010011011110000001000010000001100100",0x00003678,0xFFFFE7C3,0x00000569,0x00001831,0xFFFFF98E,0x000002C8,0x00001831,0xFFFFF98E,0x000002C8}, - {"0000001000010011111010101001010011011110001000000001100001100100",0x000020B9,0xFFFFF625,0x0000035A,0x000015C5,0xFFFFFB8A,0x000002B5,0x000015C5,0xFFFFFB8A,0x000002B5}, - {"0000001000010011111100001111110101000010110001100011000110000100",0x00003985,0xFFFFE529,0x000005DD,0x00002165,0xFFFFF351,0x000003C5,0x00002165,0xFFFFF351,0x000003C5}, - {"0000001000010011111100001111110101000010110100000010000001100100",0x0000322A,0xFFFFE99D,0x00000535,0x000019A1,0xFFFFF844,0x00000305,0x000019A1,0xFFFFF844,0x00000305}, - {"0000001000010011111100001111110101000010110100000101000100000100",0x000033ED,0xFFFFE834,0x00000571,0x00002094,0xFFFFF33A,0x000003DB,0x00002094,0xFFFFF33A,0x000003DB}, - {"0000001000010011111010101001010011011110001000000100000011000100",0x00001D10,0xFFFFF84D,0x0000030B,0x00001659,0xFFFFFB0A,0x000002CB,0x00001659,0xFFFFFB0A,0x000002CB}, - {"0000001000010011111010101001010011011110000111000001000100100100",0x0000210F,0xFFFFF644,0x00000355,0x00001A4A,0xFFFFF90F,0x00000310,0x00001A4A,0xFFFFF90F,0x00000310}, - {"0000001000010011111010101001010011011110000101100100000101100100",0x00001CA8,0xFFFFF813,0x00000316,0x00001440,0xFFFFFC1C,0x0000029D,0x00001440,0xFFFFFC1C,0x0000029D}, - {"0000001000010011111010101001010011011110001100100001000011000100",0x00002864,0xFFFFF15A,0x000003FA,0x0000137F,0xFFFFFD43,0x00000248,0x0000137F,0xFFFFFD43,0x00000248}, - {"0000001000010011111100001111110101000010110100000100000110000100",0x00002CDB,0xFFFFECFD,0x000004A7,0x00002472,0xFFFFF0E1,0x00000437,0x00002472,0xFFFFF0E1,0x00000437}, - {"0000001000010011111100001111110101000010110011000101000100000100",0x00003348,0xFFFFE8CA,0x00000554,0x00001E91,0xFFFFF4D4,0x00000392,0x00001E91,0xFFFFF4D4,0x00000392}, - {"0000001000010011111100001111110101000010110001100100100101000100",0x00003989,0xFFFFE4BB,0x000005F8,0x00001ACB,0xFFFFF780,0x00000319,0x00001ACB,0xFFFFF780,0x00000319}, - {"0000001000010011111100001111110101000010110010100010000100000100",0x00003238,0xFFFFEA09,0x0000051E,0x00001F08,0xFFFFF4F4,0x0000038C,0x00001F08,0xFFFFF4F4,0x0000038C}, - {"0000001000010011111010101001010011011110000100100000100100000100",0x00002453,0xFFFFF3B0,0x0000038D,0x00001AED,0xFFFFF8A2,0x000002EA,0x00001AED,0xFFFFF8A2,0x000002EA}, - {"0000001000010011111010101001010011011110000111000011000000100100",0x00002459,0xFFFFF409,0x000003A8,0x000017B5,0xFFFFFA53,0x000002E1,0x000017B5,0xFFFFFA53,0x000002E1}, - {"0000001000010011111010101001010011011110000000100001000110000100",0x0000310D,0xFFFFEB78,0x000004D0,0x00001DC9,0xFFFFF5D5,0x00000368,0x00001DC9,0xFFFFF5D5,0x00000368}, - {"0000001000010011111010101001010011011110000000100011000100000100",0x000031BF,0xFFFFECA3,0x00000498,0x00001DC9,0xFFFFF717,0x00000336,0x00001DC9,0xFFFFF717,0x00000336}, - {"0000001000010011111100001111110101000010110011100010000100000100",0x00003896,0xFFFFE5DD,0x000005C5,0x000023E2,0xFFFFF1A1,0x00000416,0x000023E2,0xFFFFF1A1,0x00000416}, - {"0000001000010011111010101001010011011110001100100011100100000100",0x000023CB,0xFFFFF4C8,0x00000372,0x00001C33,0xFFFFF7D5,0x0000032A,0x00001C33,0xFFFFF7D5,0x0000032A}, - {"0000001000010011111100001111110101000010110100000010000011000100",0x00002F6B,0xFFFFEBF0,0x000004CE,0x00001C89,0xFFFFF689,0x0000034D,0x00001C89,0xFFFFF689,0x0000034D}, - {"0000001000010011111100001111110101000010110011100011100100000100",0x00003E72,0xFFFFE211,0x0000065D,0x0000218D,0xFFFFF309,0x000003DC,0x0000218D,0xFFFFF309,0x000003DC}, - {"0000001000010011111010101001010011011110000000100010000010000100",0x00002612,0xFFFFF2C3,0x000003AD,0x000019F7,0xFFFFF891,0x000002FE,0x000019F7,0xFFFFF891,0x000002FE}, - {"0000001000010011111010101001010011011110000101100100000110000100",0x0000205D,0xFFFFF59F,0x00000372,0x000012E6,0xFFFFFD0A,0x00000270,0x000012E6,0xFFFFFD0A,0x00000270}, - {"0000001000010011111100001111110101000010110010100010000100100100",0x00002ECB,0xFFFFEC47,0x000004BD,0x00001936,0xFFFFF8D9,0x000002E4,0x00001936,0xFFFFF8D9,0x000002E4}, - {"0000001000010011111010101001010011011110000001100100100100000100",0x00002BDB,0xFFFFEE6D,0x00000458,0x00001852,0xFFFFF943,0x000002D9,0x00001852,0xFFFFF943,0x000002D9}, - {"0000001000010011111010101001010011011110000100100100100100000100",0x00003387,0xFFFFE958,0x00000534,0x00001932,0xFFFFF8FA,0x000002E4,0x00001932,0xFFFFF8FA,0x000002E4}, - {"0000001000010011111010101001010011011110000000100000100011000100",0x00002E3C,0xFFFFED26,0x00000495,0x00001858,0xFFFFF990,0x000002D1,0x00001858,0xFFFFF990,0x000002D1}, - {"0000001000010011111010101001010011011110000000100010100101100100",0x000033B8,0xFFFFEA5C,0x000004F9,0x00001BD1,0xFFFFF76A,0x0000032E,0x00001BD1,0xFFFFF76A,0x0000032E}, - {"0000001000010011111010101001010011011110000001100010100110000100",0x00002BCE,0xFFFFEEE9,0x00000443,0x00001982,0xFFFFF90D,0x000002DF,0x00001982,0xFFFFF90D,0x000002DF}, - {"0000001000010011111100001111110101000010110100000100100011100100",0x00003495,0xFFFFE7D9,0x0000057B,0x00001D2A,0xFFFFF5A5,0x00000372,0x00001D2A,0xFFFFF5A5,0x00000372}, - {"0000001000010011111100001111110101000010110010100011100011100100",0x000034B1,0xFFFFE88D,0x00000556,0x00002014,0xFFFFF43A,0x000003AA,0x00002014,0xFFFFF43A,0x000003AA}, - {"0000001000010011111100001111110101000010110011000011000100100100",0x00002F96,0xFFFFEC84,0x000004AD,0x000024A2,0xFFFFF1CE,0x0000040A,0x000024A2,0xFFFFF1CE,0x0000040A}, - {"0000001000010011111010101001010011011110000101100001000001100100",0x0000203B,0xFFFFF640,0x00000359,0x000014EC,0xFFFFFC14,0x0000029C,0x000014EC,0xFFFFFC14,0x0000029C}, - {"0000001000010011111100001111110101000010110100000010100110000100",0x000034E2,0xFFFFE7B8,0x00000582,0x00001938,0xFFFFF872,0x000002FA,0x00001938,0xFFFFF872,0x000002FA}, - {"0000001000010011111010101001010011011110000001100011000100100100",0x00002AC7,0xFFFFF0C1,0x000003F5,0x00002268,0xFFFFF39C,0x000003C9,0x00002268,0xFFFFF39C,0x000003C9}, - {"0000001000010011111100001111110101000010110001100011000101000100",0x000036F6,0xFFFFE77F,0x00000571,0x000027D9,0xFFFFEF6F,0x00000461,0x000027D9,0xFFFFEF6F,0x00000461}, - {"0000001000010011111010101001010011011110000100100011000100100100",0x00002BAB,0xFFFFF018,0x00000419,0x00002126,0xFFFFF4E2,0x0000038F,0x00002126,0xFFFFF4E2,0x0000038F}, - {"0000001000010011111010101001010011011110001100100011100100100100",0x000028C4,0xFFFFF161,0x000003F8,0x0000180C,0xFFFFFA4B,0x000002C8,0x0000180C,0xFFFFFA4B,0x000002C8}, - {"0000001000010011111100001111110101000010110010100010100001100100",0x00002F48,0xFFFFEB62,0x000004EE,0x00001912,0xFFFFF8C8,0x000002EA,0x00001912,0xFFFFF8C8,0x000002EA}, - {"0000001000010011111100001111110101000010110011100010100001100100",0x000032DF,0xFFFFE911,0x00000545,0x00001F06,0xFFFFF485,0x0000039C,0x00001F06,0xFFFFF485,0x0000039C}, - {"0000001000010011111100001111110101000010110100000100000101000100",0x000035B8,0xFFFFE74F,0x00000590,0x00001FD7,0xFFFFF410,0x000003AF,0x00001FD7,0xFFFFF410,0x000003AF}, - {"0000001000010011111100001111110101000010110100000101000011000100",0x00003608,0xFFFFE6D7,0x000005A9,0x000024A6,0xFFFFF075,0x00000450,0x000024A6,0xFFFFF075,0x00000450}, - {"0000001000010011111100001111110101000010110010100011100010000100",0x000030AB,0xFFFFEAED,0x000004F5,0x000019EE,0xFFFFF84E,0x000002FC,0x000019EE,0xFFFFF84E,0x000002FC}, - {"0000001000010011111010101001010011011110000001100010000011000100",0x000030C6,0xFFFFEC92,0x0000049E,0x000019BB,0xFFFFF8F1,0x000002F3,0x000019BB,0xFFFFF8F1,0x000002F3}, - {"0000001000010011111100001111110101000010110001100011000010100100",0x00003B27,0xFFFFE544,0x000005C1,0x00002697,0xFFFFF072,0x00000438,0x00002697,0xFFFFF072,0x00000438}, - {"0000001000010011111010101001010011011110000100100100100011100100",0x00002F23,0xFFFFEC48,0x000004B9,0x0000199A,0xFFFFF8CF,0x000002E9,0x0000199A,0xFFFFF8CF,0x000002E9}, - {"0000001000010011111010101001010011011110000001100010100110100100",0x00002BD7,0xFFFFEEAC,0x00000450,0x00001991,0xFFFFF8F4,0x000002E2,0x00001991,0xFFFFF8F4,0x000002E2}, - {"0000001000010011111010101001010011011110000000100010000000100100",0x00003210,0xFFFFEB24,0x000004DE,0x00001BDF,0xFFFFF744,0x00000333,0x00001BDF,0xFFFFF744,0x00000333}, - {"0000001000010011111010101001010011011110001001000100000101000100",0x00002DDC,0xFFFFED0D,0x000004AC,0x000019D0,0xFFFFF869,0x0000030F,0x000019D0,0xFFFFF869,0x0000030F}, - {"0000001000010011111010101001010011011110001000000011100101100100",0x000023E6,0xFFFFF40C,0x000003A9,0x000014EB,0xFFFFFBC4,0x000002AF,0x000014EB,0xFFFFFBC4,0x000002AF}, - {"0000001000010011111100001111110101000010110010100010100110100100",0x000030CE,0xFFFFE9A5,0x0000053C,0x00001C45,0xFFFFF60E,0x0000035D,0x00001C45,0xFFFFF60E,0x0000035D}, - {"0000001000010011111010101001010011011110000101100001000010000100",0x00001E89,0xFFFFF73A,0x00000337,0x0000157C,0xFFFFFBC0,0x000002AA,0x0000157C,0xFFFFFBC0,0x000002AA}, - {"0000001000010011111100001111110101000010110100000100000100100100",0x000036C6,0xFFFFE6CF,0x000005A1,0x00002457,0xFFFFF11D,0x0000042D,0x00002457,0xFFFFF11D,0x0000042D}, - {"0000001000010011111010101001010011011110001100100001100101000100",0x00002815,0xFFFFF19A,0x000003F2,0x000016D2,0xFFFFFB40,0x00000299,0x000016D2,0xFFFFFB40,0x00000299}, - {"0000001000010011111010101001010011011110000111000001100110100100",0x00001FE2,0xFFFFF660,0x00000354,0x000015A7,0xFFFFFB47,0x000002C1,0x000015A7,0xFFFFFB47,0x000002C1}, - {"0000001000010011111010101001010011011110000101100001100101100100",0x00002114,0xFFFFF634,0x00000356,0x000016C1,0xFFFFFB43,0x000002B8,0x000016C1,0xFFFFFB43,0x000002B8}, - {"0000001000010011111100001111110101000010110011000010100011000100",0x000028E3,0xFFFFF075,0x00000414,0x0000203C,0xFFFFF438,0x000003B3,0x0000203C,0xFFFFF438,0x000003B3}, - {"0000001000010011111010101001010011011110000111000011100100100100",0x00001EEB,0xFFFFF7BB,0x0000031A,0x00001580,0xFFFFFBD7,0x000002AD,0x00001580,0xFFFFFBD7,0x000002AD}, - {"0000001000010011111010101001010011011110001001000000100011000100",0x00002BB2,0xFFFFEE72,0x00000470,0x0000192C,0xFFFFF91E,0x000002E7,0x0000192C,0xFFFFF91E,0x000002E7}, - {"0000001000010011111010101001010011011110000001100101000011100100",0x00003A3D,0xFFFFE49D,0x000005F5,0x00001A3B,0xFFFFF7B1,0x00000320,0x00001A3B,0xFFFFF7B1,0x00000320}, - {"0000001000010011111100001111110101000010110011100011000101100100",0x00002E93,0xFFFFEC5A,0x000004B4,0x000025EB,0xFFFFF03C,0x0000044A,0x000025EB,0xFFFFF03C,0x0000044A}, - {"0000001000010011111100001111110101000010110010100010000011000100",0x0000331F,0xFFFFE97A,0x00000531,0x00001A06,0xFFFFF850,0x000002FD,0x00001A06,0xFFFFF850,0x000002FD}, - {"0000001000010011111100001111110101000010110001100011100101100100",0x00003937,0xFFFFE5A0,0x000005C7,0x0000235E,0xFFFFF234,0x000003F2,0x0000235E,0xFFFFF234,0x000003F2}, - {"0000001000010011111010101001010011011110000111100011100100100100",0x00001DD0,0xFFFFF80E,0x00000319,0x000015C7,0xFFFFFB91,0x000002BC,0x000015C7,0xFFFFFB91,0x000002BC}, - {"0000001000010011111100001111110101000010110100000011100101100100",0x00003328,0xFFFFE905,0x0000054A,0x00002054,0xFFFFF3BF,0x000003C0,0x00002054,0xFFFFF3BF,0x000003C0}, - {"0000001000010011111100001111110101000010110011000001000100000100",0x00002FE5,0xFFFFEA65,0x00000520,0x0000188B,0xFFFFF8A7,0x000002F5,0x0000188B,0xFFFFF8A7,0x000002F5}, - {"0000001000010011111100001111110101000010110010100011100010100100",0x00002ED3,0xFFFFEC51,0x000004B9,0x00001888,0xFFFFF96A,0x000002CA,0x00001888,0xFFFFF96A,0x000002CA}, - {"0000001000010011111100001111110101000010110100000011000010000100",0x00002FCC,0xFFFFEB60,0x000004EA,0x00001F8D,0xFFFFF436,0x000003B4,0x00001F8D,0xFFFFF436,0x000003B4}, - {"0000001000010011111100001111110101000010110011100100000010000100",0x0000329F,0xFFFFE8F7,0x0000054F,0x000023DB,0xFFFFF0EE,0x0000043A,0x000023DB,0xFFFFF0EE,0x0000043A}, - {"0000001000010011111010101001010011011110000001000011100010100100",0x000030B5,0xFFFFEBB8,0x000004C4,0x00001AFD,0xFFFFF781,0x00000329,0x00001AFD,0xFFFFF781,0x00000329}, - {"0000001000010011111010101001010011011110000111100001100110100100",0x00001BBF,0xFFFFF8E2,0x000002F7,0x00001722,0xFFFFFA85,0x000002DB,0x00001722,0xFFFFFA85,0x000002DB}, - {"0000001000010011111010101001010011011110000000100010000001000100",0x000030E4,0xFFFFEBE6,0x000004BB,0x00001C80,0xFFFFF6E1,0x0000033E,0x00001C80,0xFFFFF6E1,0x0000033E}, - {"0000001000010011111010101001010011011110000100100010100101000100",0x000030E2,0xFFFFECD0,0x00000492,0x00001CE0,0xFFFFF753,0x0000032F,0x00001CE0,0xFFFFF753,0x0000032F}, - {"0000001000010011111010101001010011011110001100100010100001100100",0x00002513,0xFFFFF323,0x000003BC,0x00001965,0xFFFFF93C,0x000002F0,0x00001965,0xFFFFF93C,0x000002F0}, - {"0000001000010011111010101001010011011110000101100001000010100100",0x00002147,0xFFFFF585,0x0000037A,0x000014CC,0xFFFFFC3B,0x00000296,0x000014CC,0xFFFFFC3B,0x00000296}, - {"0000001000010011111010101001010011011110001100100010000100100100",0x00002507,0xFFFFF432,0x0000038A,0x00001890,0xFFFFFA61,0x000002C6,0x00001890,0xFFFFFA61,0x000002C6}, - {"0000001000010011111010101001010011011110000001100011100010100100",0x0000339B,0xFFFFEA7D,0x000004F0,0x0000191E,0xFFFFF944,0x000002DF,0x0000191E,0xFFFFF944,0x000002DF}, - {"0000001000010011111100001111110101000010110011000010100010100100",0x00002842,0xFFFFF043,0x00000427,0x00001988,0xFFFFF892,0x000002F7,0x00001988,0xFFFFF892,0x000002F7}, - {"0000001000010011111100001111110101000010110001100001100010100100",0x0000389D,0xFFFFE5D8,0x000005BF,0x00001EE1,0xFFFFF4EF,0x00000387,0x00001EE1,0xFFFFF4EF,0x00000387}, - {"0000001000010011111100001111110101000010110011100011000110000100",0x0000396D,0xFFFFE4D7,0x000005F2,0x000020DA,0xFFFFF34E,0x000003CD,0x000020DA,0xFFFFF34E,0x000003CD}, - {"0000001000010011111100001111110101000010110010100011000100000100",0x0000355F,0xFFFFE85A,0x0000055F,0x0000281F,0xFFFFEF28,0x0000047D,0x0000281F,0xFFFFEF28,0x0000047D}, - {"0000001000010011111010101001010011011110000111000101000011100100",0x00002284,0xFFFFF46E,0x00000399,0x00001498,0xFFFFFBE3,0x0000029C,0x00001498,0xFFFFFBE3,0x0000029C}, - {"0000001000010011111010101001010011011110000000100011100101000100",0x000031B6,0xFFFFEB42,0x000004D9,0x00001F54,0xFFFFF4D2,0x00000399,0x00001F54,0xFFFFF4D2,0x00000399}, - {"0000001000010011111100001111110101000010110001100011000001100100",0x000035CE,0xFFFFE79D,0x00000578,0x00001C78,0xFFFFF68C,0x00000344,0x00001C78,0xFFFFF68C,0x00000344}, - {"0000001000010011111010101001010011011110000111100100100101100100",0x00001C0A,0xFFFFF81B,0x00000318,0x00001492,0xFFFFFBCC,0x000002A5,0x00001492,0xFFFFFBCC,0x000002A5}, - {"0000001000010011111010101001010011011110000000100010000110000100",0x00003492,0xFFFFE95C,0x00000526,0x00001A97,0xFFFFF81B,0x0000030B,0x00001A97,0xFFFFF81B,0x0000030B}, - {"0000001000010011111010101001010011011110000101100011000101100100",0x00001E89,0xFFFFF7D0,0x0000031A,0x000017A5,0xFFFFFA99,0x000002D9,0x000017A5,0xFFFFFA99,0x000002D9}, - {"0000001000010011111100001111110101000010110010100100100011000100",0x00002DCC,0xFFFFEBE0,0x000004DE,0x000019BA,0xFFFFF7F5,0x0000030D,0x000019BA,0xFFFFF7F5,0x0000030D}, - {"0000001000010011111010101001010011011110000001000010100110000100",0x000030EF,0xFFFFEBC1,0x000004C0,0x00001AA9,0xFFFFF814,0x0000030A,0x00001AA9,0xFFFFF814,0x0000030A}, - {"0000001000010011111010101001010011011110001001000101000100100100",0x00002EA3,0xFFFFEBF6,0x000004D8,0x00001DCF,0xFFFFF521,0x00000399,0x00001DCF,0xFFFFF521,0x00000399}, - {"0000001000010011111010101001010011011110001100100100000101100100",0x00002B5F,0xFFFFEEA1,0x0000046C,0x000017EB,0xFFFFF9C9,0x000002D4,0x000017EB,0xFFFFF9C9,0x000002D4}, - {"0000001000010011111010101001010011011110000000100100000100000100",0x00002C63,0xFFFFEE82,0x00000455,0x00002268,0xFFFFF29D,0x000003F6,0x00002268,0xFFFFF29D,0x000003F6}, - {"0000001000010011111010101001010011011110000100100001100100000100",0x00002B1A,0xFFFFF016,0x0000041C,0x000019AA,0xFFFFF988,0x000002D2,0x000019AA,0xFFFFF988,0x000002D2}, - {"0000001000010011111100001111110101000010110010100010100101100100",0x0000332F,0xFFFFE934,0x0000053B,0x00001E47,0xFFFFF566,0x00000374,0x00001E47,0xFFFFF566,0x00000374}, - {"0000001000010011111100001111110101000010110010100100100011100100",0x00002995,0xFFFFEEC1,0x00000465,0x0000178F,0xFFFFF995,0x000002C5,0x0000178F,0xFFFFF995,0x000002C5}, - {"0000001000010011111010101001010011011110001000000001100010000100",0x00001C2E,0xFFFFF932,0x000002E9,0x000015C2,0xFFFFFBC5,0x000002AD,0x000015C2,0xFFFFFBC5,0x000002AD}, - {"0000001000010011111100001111110101000010110001100100000011100100",0x00003B08,0xFFFFE4E8,0x000005D8,0x0000209D,0xFFFFF444,0x00000398,0x0000209D,0xFFFFF444,0x00000398}, - {"0000001000010011111010101001010011011110000001000101000011100100",0x00002F1F,0xFFFFEB74,0x000004EB,0x00001F4C,0xFFFFF3D4,0x000003CE,0x00001F4C,0xFFFFF3D4,0x000003CE}, - {"0000001000010011111010101001010011011110000001000011100010000100",0x00003415,0xFFFFE89F,0x00000553,0x0000186B,0xFFFFF8E1,0x000002EF,0x0000186B,0xFFFFF8E1,0x000002EF}, - {"0000001000010011111100001111110101000010110011000001000011000100",0x00003441,0xFFFFE779,0x0000059D,0x000019EA,0xFFFFF7B2,0x0000031F,0x000019EA,0xFFFFF7B2,0x0000031F}, - {"0000001000010011111010101001010011011110000101100100000001100100",0x00002174,0xFFFFF546,0x00000378,0x00001456,0xFFFFFC5F,0x00000284,0x00001456,0xFFFFFC5F,0x00000284}, - {"0000001000010011111100001111110101000010110011100100000011000100",0x00003788,0xFFFFE61E,0x000005BF,0x00001DF4,0xFFFFF562,0x00000374,0x00001DF4,0xFFFFF562,0x00000374}, - {"0000001000010011111010101001010011011110000111100001100001000100",0x00001C41,0xFFFFF8C1,0x000002FC,0x0000171E,0xFFFFFA93,0x000002DE,0x0000171E,0xFFFFFA93,0x000002DE}, - {"0000001000010011111100001111110101000010110010100011100001100100",0x00002B15,0xFFFFEDEC,0x00000487,0x000017E4,0xFFFFF934,0x000002DF,0x000017E4,0xFFFFF934,0x000002DF}, - {"0000001000010011111100001111110101000010110011000011000101000100",0x0000327A,0xFFFFEA71,0x000004FF,0x00001D96,0xFFFFF63B,0x00000351,0x00001D96,0xFFFFF63B,0x00000351}, - {"0000001000010011111010101001010011011110000111100100000001100100",0x000023C6,0xFFFFF3E5,0x000003B6,0x000014DE,0xFFFFFC29,0x00000294,0x000014DE,0xFFFFFC29,0x00000294}, - {"0000001000010011111010101001010011011110000101100100100101000100",0x00001F96,0xFFFFF5FA,0x00000364,0x00001397,0xFFFFFC9D,0x0000027D,0x00001397,0xFFFFFC9D,0x0000027D}, - {"0000001000010011111010101001010011011110000001100011000101000100",0x00002B51,0xFFFFEFB5,0x00000420,0x00001ACA,0xFFFFF824,0x0000030D,0x00001ACA,0xFFFFF824,0x0000030D}, - {"0000001000010011111010101001010011011110000111100100100101000100",0x000020DB,0xFFFFF55B,0x0000037C,0x0000153D,0xFFFFFB5F,0x000002BA,0x0000153D,0xFFFFFB5F,0x000002BA}, - {"0000001000010011111010101001010011011110000000100010000110100100",0x000030BB,0xFFFFEBDA,0x000004BC,0x00001B0E,0xFFFFF7A8,0x0000031E,0x00001B0E,0xFFFFF7A8,0x0000031E}, - {"0000001000010011111100001111110101000010110001100010100100000100",0x000033C4,0xFFFFEA41,0x000004FA,0x000022C6,0xFFFFF363,0x000003BC,0x000022C6,0xFFFFF363,0x000003BC}, - {"0000001000010011111010101001010011011110001001000000100100100100",0x00002D47,0xFFFFEE01,0x00000477,0x000021CD,0xFFFFF36E,0x000003D6,0x000021CD,0xFFFFF36E,0x000003D6}, - {"0000001000010011111010101001010011011110000111100011000110100100",0x00001E7B,0xFFFFF733,0x00000339,0x00001668,0xFFFFFB29,0x000002BF,0x00001668,0xFFFFFB29,0x000002BF}, - {"0000001000010011111100001111110101000010110010100010100110000100",0x00002F7E,0xFFFFEAFF,0x000004FC,0x000018D4,0xFFFFF8BE,0x000002E8,0x000018D4,0xFFFFF8BE,0x000002E8}, - {"0000001000010011111010101001010011011110001100100011100010100100",0x00002635,0xFFFFF2E1,0x000003BC,0x000017A4,0xFFFFFA67,0x000002C3,0x000017A4,0xFFFFFA67,0x000002C3}, - {"0000001000010011111010101001010011011110000100100011000010100100",0x000026CA,0xFFFFF2C1,0x000003B2,0x00001C3E,0xFFFFF7AE,0x0000031F,0x00001C3E,0xFFFFF7AE,0x0000031F}, - {"0000001000010011111010101001010011011110000111000001000001100100",0x00002550,0xFFFFF380,0x000003B5,0x000019F5,0xFFFFF8E7,0x00000313,0x000019F5,0xFFFFF8E7,0x00000313}, - {"0000001000010011111100001111110101000010110010100100100100000100",0x00002FBC,0xFFFFEAF8,0x000004FA,0x000018CC,0xFFFFF8C6,0x000002E8,0x000018CC,0xFFFFF8C6,0x000002E8}, - {"0000001000010011111100001111110101000010110100000001100011100100",0x00002FCC,0xFFFFEB60,0x000004EA,0x00001EFF,0xFFFFF4DA,0x0000038F,0x00001EFF,0xFFFFF4DA,0x0000038F}, - {"0000001000010011111010101001010011011110000101100100000010000100",0x000023E6,0xFFFFF413,0x000003A1,0x00001544,0xFFFFFC16,0x0000028B,0x00001544,0xFFFFFC16,0x0000028B}, - {"0000001000010011111100001111110101000010110011100011000000100100",0x00003251,0xFFFFEAA2,0x000004F5,0x000025B0,0xFFFFF0DF,0x00000431,0x000025B0,0xFFFFF0DF,0x00000431}, - {"0000001000010011111100001111110101000010110100000011100110000100",0x00002F6F,0xFFFFEB67,0x000004E6,0x00002275,0xFFFFF249,0x000003FB,0x00002275,0xFFFFF249,0x000003FB}, - {"0000001000010011111010101001010011011110001100100010100101100100",0x00002597,0xFFFFF34A,0x000003B1,0x00001BCC,0xFFFFF822,0x0000031A,0x00001BCC,0xFFFFF822,0x0000031A}, - {"0000001000010011111100001111110101000010110001100011100001100100",0x00003B1D,0xFFFFE40E,0x0000060D,0x00001F61,0xFFFFF470,0x0000039F,0x00001F61,0xFFFFF470,0x0000039F}, - {"0000001000010011111100001111110101000010110001100100000101000100",0x0000379F,0xFFFFE6DB,0x0000058C,0x00002460,0xFFFFF170,0x00000415,0x00002460,0xFFFFF170,0x00000415}, - {"0000001000010011111010101001010011011110000101100101000101000100",0x00002442,0xFFFFF2FB,0x000003D9,0x00001414,0xFFFFFBDC,0x000002A2,0x00001414,0xFFFFFBDC,0x000002A2}, - {"0000001000010011111010101001010011011110000000100100000011000100",0x00003270,0xFFFFEA0D,0x0000051C,0x00001AFD,0xFFFFF783,0x00000328,0x00001AFD,0xFFFFF783,0x00000328}, - {"0000001000010011111010101001010011011110000101100001000100000100",0x00001B23,0xFFFFF94B,0x000002EB,0x000015F1,0xFFFFFB82,0x000002B4,0x000015F1,0xFFFFFB82,0x000002B4}, - {"0000001000010011111010101001010011011110001100100011100001000100",0x000026AE,0xFFFFF21A,0x000003DB,0x00001827,0xFFFFFA10,0x000002C8,0x00001827,0xFFFFFA10,0x000002C8}, - {"0000001000010011111100001111110101000010110010100100100010000100",0x00002DCF,0xFFFFEBD8,0x000004DB,0x00001A75,0xFFFFF719,0x0000033A,0x00001A75,0xFFFFF719,0x0000033A}, - {"0000001000010011111100001111110101000010110011100100000011100100",0x00003983,0xFFFFE500,0x000005EA,0x000022A6,0xFFFFF25F,0x000003F1,0x000022A6,0xFFFFF25F,0x000003F1}, - {"0000001000010011111010101001010011011110000100100001100011000100",0x00002AD5,0xFFFFF07A,0x00000406,0x000019FB,0xFFFFF961,0x000002D8,0x000019FB,0xFFFFF961,0x000002D8}, - {"0000001000010011111100001111110101000010110010100011100110100100",0x00002A43,0xFFFFEE43,0x00000474,0x00001D65,0xFFFFF538,0x00000387,0x00001D65,0xFFFFF538,0x00000387}, - {"0000001000010011111100001111110101000010110001100010000010000100",0x0000311E,0xFFFFEAF8,0x000004E8,0x00001959,0xFFFFF8E4,0x000002DC,0x00001959,0xFFFFF8E4,0x000002DC}, - {"0000001000010011111100001111110101000010110100000011000110100100",0x0000339A,0xFFFFE8A7,0x00000559,0x00001A04,0xFFFFF7E5,0x00000311,0x00001A04,0xFFFFF7E5,0x00000311}, - {"0000001000010011111010101001010011011110001000000100000101000100",0x000021B3,0xFFFFF50F,0x00000389,0x00001470,0xFFFFFBF7,0x000002A5,0x00001470,0xFFFFFBF7,0x000002A5}, - {"0000001000010011111010101001010011011110000000100001100010000100",0x00003417,0xFFFFE9A6,0x0000051D,0x000018A4,0xFFFFF984,0x000002CF,0x000018A4,0xFFFFF984,0x000002CF}, - {"0000001000010011111010101001010011011110001000000010100110000100",0x00001FED,0xFFFFF6A2,0x00000347,0x00001639,0xFFFFFB59,0x000002BB,0x00001639,0xFFFFFB59,0x000002BB}, - {"0000001000010011111010101001010011011110000100100001100010100100",0x000032D2,0xFFFFEB18,0x000004DC,0x00001A01,0xFFFFF95E,0x000002CF,0x00001A01,0xFFFFF95E,0x000002CF}, - {"0000001000010011111100001111110101000010110100000100000010000100",0x00003147,0xFFFFEA3B,0x00000518,0x0000241D,0xFFFFF11C,0x00000431,0x0000241D,0xFFFFF11C,0x00000431}, - {"0000001000010011111010101001010011011110000111000000100100000100",0x00001D44,0xFFFFF7E7,0x0000031A,0x0000153F,0xFFFFFBBC,0x000002A9,0x0000153F,0xFFFFFBBC,0x000002A9}, - {"0000001000010011111100001111110101000010110011000100000100000100",0x00003690,0xFFFFE6E3,0x000005A4,0x000018DE,0xFFFFF908,0x000002DD,0x000018DE,0xFFFFF908,0x000002DD}, - {"0000001000010011111100001111110101000010110011000010000110000100",0x00003561,0xFFFFE6F8,0x000005AB,0x000018B5,0xFFFFF8A0,0x000002F3,0x000018B5,0xFFFFF8A0,0x000002F3}, - {"0000001000010011111010101001010011011110001100100011000100100100",0x000028F4,0xFFFFF23A,0x000003CE,0x00001BC6,0xFFFFF881,0x00000311,0x00001BC6,0xFFFFF881,0x00000311}, - {"0000001000010011111100001111110101000010110100000011000110000100",0x000035D7,0xFFFFE71C,0x0000059B,0x00001D49,0xFFFFF5C8,0x00000368,0x00001D49,0xFFFFF5C8,0x00000368}, - {"0000001000010011111100001111110101000010110011100001100010100100",0x0000397E,0xFFFFE4CB,0x000005F4,0x00001989,0xFFFFF844,0x000002FD,0x00001989,0xFFFFF844,0x000002FD}, - {"0000001000010011111100001111110101000010110001100010000001100100",0x00003BAB,0xFFFFE332,0x0000063F,0x00001A69,0xFFFFF7B9,0x00000312,0x00001A69,0xFFFFF7B9,0x00000312}, - {"0000001000010011111100001111110101000010110100000011000001100100",0x00002F26,0xFFFFEB82,0x000004E8,0x00001D7D,0xFFFFF590,0x00000379,0x00001D7D,0xFFFFF590,0x00000379}, - {"0000001000010011111010101001010011011110000001100011000110100100",0x00002FDC,0xFFFFEBE0,0x000004C3,0x00001940,0xFFFFF8CC,0x000002EE,0x00001940,0xFFFFF8CC,0x000002EE}, - {"0000001000010011111010101001010011011110000111000000100011100100",0x000021B2,0xFFFFF558,0x00000379,0x00001643,0xFFFFFB1C,0x000002C3,0x00001643,0xFFFFFB1C,0x000002C3}, - {"0000001000010011111010101001010011011110001100100001100100000100",0x00002897,0xFFFFF181,0x000003F7,0x00001990,0xFFFFF994,0x000002E2,0x00001990,0xFFFFF994,0x000002E2}, - {"0000001000010011111010101001010011011110000111100000100100100100",0x00001D19,0xFFFFF829,0x0000031A,0x00001558,0xFFFFFBCA,0x000002AF,0x00001558,0xFFFFFBCA,0x000002AF}, - {"0000001000010011111010101001010011011110000001000011000101000100",0x00003311,0xFFFFEAD9,0x000004E1,0x00001BDC,0xFFFFF79E,0x0000031D,0x00001BDC,0xFFFFF79E,0x0000031D}, - {"0000001000010011111010101001010011011110000111100010100111000100",0x00001E54,0xFFFFF740,0x00000333,0x000016A1,0xFFFFFAF0,0x000002C4,0x000016A1,0xFFFFFAF0,0x000002C4}, - {"0000001000010011111100001111110101000010110011100011100101100100",0x00003266,0xFFFFE9A8,0x00000527,0x00002307,0xFFFFF219,0x000003FC,0x00002307,0xFFFFF219,0x000003FC}, - {"0000001000010011111010101001010011011110001100100001000101000100",0x00001D1F,0xFFFFF82B,0x000002F0,0x000013F0,0xFFFFFD0B,0x0000024E,0x000013F0,0xFFFFFD0B,0x0000024E}, - {"0000001000010011111100001111110101000010110001100100100010100100",0x0000312E,0xFFFFEA67,0x00000502,0x0000222A,0xFFFFF253,0x000003F9,0x0000222A,0xFFFFF253,0x000003F9}, - {"0000001000010011111100001111110101000010110010100100000100100100",0x000032B2,0xFFFFE9AD,0x00000523,0x00001E97,0xFFFFF527,0x0000037F,0x00001E97,0xFFFFF527,0x0000037F}, - {"0000001000010011111010101001010011011110000101100100000011100100",0x00001F6A,0xFFFFF6FC,0x00000338,0x0000164B,0xFFFFFB2C,0x000002C2,0x0000164B,0xFFFFFB2C,0x000002C2}, - {"0000001000010011111010101001010011011110000000100010100011000100",0x00002603,0xFFFFF386,0x00000392,0x00001EE0,0xFFFFF601,0x00000369,0x00001EE0,0xFFFFF601,0x00000369}, - {"0000001000010011111010101001010011011110001000000001000101100100",0x00001D0C,0xFFFFF803,0x00000317,0x00001345,0xFFFFFD52,0x00000260,0x00001345,0xFFFFFD52,0x00000260}, - {"0000001000010011111100001111110101000010110011000001100010000100",0x0000327A,0xFFFFE8E5,0x0000055C,0x00001680,0xFFFFFA2D,0x000002B2,0x00001680,0xFFFFFA2D,0x000002B2}, - {"0000001000010011111100001111110101000010110010100011100101100100",0x000032B8,0xFFFFE91A,0x0000054A,0x00001BAB,0xFFFFF6EC,0x00000338,0x00001BAB,0xFFFFF6EC,0x00000338}, - {"0000001000010011111100001111110101000010110011000011000001000100",0x00002F79,0xFFFFEB63,0x000004EF,0x000017BB,0xFFFFF9B1,0x000002CA,0x000017BB,0xFFFFF9B1,0x000002CA}, - {"0000001000010011111010101001010011011110000001000011100011100100",0x00002AE5,0xFFFFEFCB,0x0000041D,0x0000214A,0xFFFFF3A7,0x000003C7,0x0000214A,0xFFFFF3A7,0x000003C7}, - {"0000001000010011111010101001010011011110001100100010000001100100",0x0000212C,0xFFFFF5BC,0x0000034F,0x000017ED,0xFFFFFA4C,0x000002C1,0x000017ED,0xFFFFFA4C,0x000002C1}, - {"0000001000010011111010101001010011011110000100100001000100100100",0x00002BE7,0xFFFFEF40,0x0000043C,0x00001AE2,0xFFFFF8CF,0x000002E3,0x00001AE2,0xFFFFF8CF,0x000002E3}, - {"0000001000010011111100001111110101000010110100000101000101000100",0x000032DC,0xFFFFE90F,0x00000549,0x00002A2D,0xFFFFECC9,0x000004ED,0x00002A2D,0xFFFFECC9,0x000004ED}, - {"0000001000010011111010101001010011011110000101100001100010100100",0x00001DE3,0xFFFFF80D,0x00000319,0x000016FA,0xFFFFFB42,0x000002BC,0x000016FA,0xFFFFFB42,0x000002BC}, - {"0000001000010011111010101001010011011110000111100010100001000100",0x00001F1B,0xFFFFF6DE,0x00000346,0x00001502,0xFFFFFC23,0x00000298,0x00001502,0xFFFFFC23,0x00000298}, - {"0000001000010011111010101001010011011110000001100001100001100100",0x00003203,0xFFFFEA87,0x000004FE,0x0000194E,0xFFFFF8E3,0x000002EC,0x0000194E,0xFFFFF8E3,0x000002EC}, - {"0000001000010011111100001111110101000010110100000010000101000100",0x0000337A,0xFFFFE8DD,0x00000551,0x00001E3C,0xFFFFF534,0x00000385,0x00001E3C,0xFFFFF534,0x00000385}, - {"0000001000010011111100001111110101000010110010100100100001100100",0x000036F6,0xFFFFE62A,0x000005C5,0x000023C0,0xFFFFF117,0x00000435,0x000023C0,0xFFFFF117,0x00000435}, - {"0000001000010011111100001111110101000010110011000010000101000100",0x00003125,0xFFFFEA4E,0x0000051A,0x00001E6C,0xFFFFF503,0x0000038E,0x00001E6C,0xFFFFF503,0x0000038E}, - {"0000001000010011111010101001010011011110000111000000100010100100",0x00001CD4,0xFFFFF82D,0x0000030E,0x0000156D,0xFFFFFB64,0x000002B8,0x0000156D,0xFFFFFB64,0x000002B8}, - {"0000001000010011111010101001010011011110000000100100000010100100",0x00002F14,0xFFFFEC46,0x000004B8,0x000017F1,0xFFFFF977,0x000002D2,0x000017F1,0xFFFFF977,0x000002D2}, - {"0000001000010011111010101001010011011110000001100100000010100100",0x000031F1,0xFFFFEAD4,0x000004ED,0x0000184C,0xFFFFF983,0x000002D4,0x0000184C,0xFFFFF983,0x000002D4}, - {"0000001000010011111100001111110101000010110100000100100110000100",0x00002EA9,0xFFFFEBD7,0x000004D5,0x0000288D,0xFFFFEDDB,0x000004C0,0x0000288D,0xFFFFEDDB,0x000004C0}, - {"0000001000010011111100001111110101000010110010100011100110000100",0x0000335F,0xFFFFE82C,0x00000579,0x00001DBF,0xFFFFF512,0x0000038C,0x00001DBF,0xFFFFF512,0x0000038C}, - {"0000001000010011111010101001010011011110001000000001000110000100",0x0000224F,0xFFFFF4B5,0x00000391,0x0000138C,0xFFFFFCC3,0x0000027A,0x0000138C,0xFFFFFCC3,0x0000027A}, - {"0000001000010011111010101001010011011110000100100100000010100100",0x0000320D,0xFFFFEACD,0x000004F5,0x00001976,0xFFFFF913,0x000002E2,0x00001976,0xFFFFF913,0x000002E2}, - {"0000001000010011111010101001010011011110001000000010000100000100",0x00001BEB,0xFFFFF99C,0x000002E4,0x000016A4,0xFFFFFB77,0x000002C3,0x000016A4,0xFFFFFB77,0x000002C3}, - {"0000001000010011111010101001010011011110000001100011000001000100",0x0000396E,0xFFFFE616,0x000005A9,0x000018F4,0xFFFFF91A,0x000002E3,0x000018F4,0xFFFFF91A,0x000002E3}, - {"0000001000010011111010101001010011011110000000100010100001100100",0x00003251,0xFFFFEA8E,0x000004FA,0x000018EF,0xFFFFF910,0x000002E4,0x000018EF,0xFFFFF910,0x000002E4}, - {"0000001000010011111010101001010011011110000111000001100100100100",0x00001DAF,0xFFFFF857,0x0000030D,0x00001915,0xFFFFF9D8,0x000002F7,0x00001915,0xFFFFF9D8,0x000002F7}, - {"0000001000010011111010101001010011011110001000000100000110100100",0x000025B6,0xFFFFF26B,0x000003E5,0x00001531,0xFFFFFB68,0x000002AF,0x00001531,0xFFFFFB68,0x000002AF}, - {"0000001000010011111010101001010011011110000001100001100010000100",0x00002B2E,0xFFFFEF2E,0x00000440,0x00001968,0xFFFFF91A,0x000002DF,0x00001968,0xFFFFF91A,0x000002DF}, - {"0000001000010011111010101001010011011110000111000010000001100100",0x00002305,0xFFFFF528,0x00000377,0x000018A4,0xFFFFF9EB,0x000002F0,0x000018A4,0xFFFFF9EB,0x000002F0}, - {"0000001000010011111100001111110101000010110010100100000011000100",0x000032A1,0xFFFFE992,0x0000052E,0x00001A55,0xFFFFF826,0x000002FE,0x00001A55,0xFFFFF826,0x000002FE}, - {"0000001000010011111010101001010011011110000001000010000110000100",0x00002CCD,0xFFFFEE35,0x00000462,0x00001B09,0xFFFFF7E6,0x0000030F,0x00001B09,0xFFFFF7E6,0x0000030F}, - {"0000001000010011111010101001010011011110001100100011000010000100",0x00002602,0xFFFFF2CF,0x000003C5,0x000016EE,0xFFFFFAD4,0x000002B4,0x000016EE,0xFFFFFAD4,0x000002B4}, - {"0000001000010011111100001111110101000010110100000001100101100100",0x00003370,0xFFFFE891,0x00000560,0x000017F0,0xFFFFF930,0x000002DF,0x000017F0,0xFFFFF930,0x000002DF}, - {"0000001000010011111100001111110101000010110010100001100010000100",0x00002EDC,0xFFFFEB6D,0x000004EC,0x000016E6,0xFFFFF9ED,0x000002BC,0x000016E6,0xFFFFF9ED,0x000002BC}, - {"0000001000010011111010101001010011011110000100100010100011000100",0x00002A05,0xFFFFF13D,0x000003F0,0x00002065,0xFFFFF57B,0x00000378,0x00002065,0xFFFFF57B,0x00000378}, - {"0000001000010011111100001111110101000010110011100010000001000100",0x00002F8A,0xFFFFEB6E,0x000004E4,0x00001E3E,0xFFFFF50E,0x0000038D,0x00001E3E,0xFFFFF50E,0x0000038D}, - {"0000001000010011111100001111110101000010110010100011000001000100",0x00002BB5,0xFFFFED6A,0x000004A1,0x000017BF,0xFFFFF937,0x000002E5,0x000017BF,0xFFFFF937,0x000002E5}, - {"0000001000010011111010101001010011011110001000000001100101100100",0x0000202C,0xFFFFF6CE,0x0000033F,0x000015EE,0xFFFFFB83,0x000002B9,0x000015EE,0xFFFFFB83,0x000002B9}, - {"0000001000010011111010101001010011011110000000100010100010000100",0x00002C0C,0xFFFFEF10,0x0000043F,0x00001A73,0xFFFFF83E,0x0000030C,0x00001A73,0xFFFFF83E,0x0000030C}, - {"0000001000010011111010101001010011011110001100100100000100000100",0x0000234F,0xFFFFF460,0x00000385,0x000018C3,0xFFFFF9A5,0x000002DD,0x000018C3,0xFFFFF9A5,0x000002DD}, - {"0000001000010011111100001111110101000010110011100001100100000100",0x00003679,0xFFFFE704,0x00000595,0x00002177,0xFFFFF31A,0x000003D7,0x00002177,0xFFFFF31A,0x000003D7}, - {"0000001000010011111100001111110101000010110010100010100100100100",0x00003008,0xFFFFEBB8,0x000004D5,0x000024FF,0xFFFFF112,0x00000430,0x000024FF,0xFFFFF112,0x00000430}, - {"0000001000010011111100001111110101000010110001100100000110100100",0x00003848,0xFFFFE6A3,0x00000594,0x00002958,0xFFFFEE37,0x000004A0,0x00002958,0xFFFFEE37,0x000004A0}, - {"0000001000010011111100001111110101000010110011000001100100100100",0x00002FDF,0xFFFFEB08,0x000004FD,0x00001D77,0xFFFFF58B,0x0000037A,0x00001D77,0xFFFFF58B,0x0000037A}, - {"0000001000010011111010101001010011011110000001100011000001100100",0x00002EC8,0xFFFFED41,0x00000481,0x00001949,0xFFFFF91C,0x000002DF,0x00001949,0xFFFFF91C,0x000002DF}, - {"0000001000010011111100001111110101000010110100000100000110100100",0x000037C1,0xFFFFE5BA,0x000005D7,0x0000252C,0xFFFFF023,0x00000460,0x0000252C,0xFFFFF023,0x00000460}, - {"0000001000010011111100001111110101000010110011100010100101000100",0x00003716,0xFFFFE70C,0x0000058A,0x000028CC,0xFFFFEE57,0x0000049D,0x000028CC,0xFFFFEE57,0x0000049D}, - {"0000001000010011111100001111110101000010110010100100000011100100",0x000033D1,0xFFFFE8E8,0x00000547,0x00001AB1,0xFFFFF7E5,0x00000309,0x00001AB1,0xFFFFF7E5,0x00000309}, - {"0000001000010011111100001111110101000010110011000010100101000100",0x00002D72,0xFFFFED65,0x0000048E,0x00001E0D,0xFFFFF5A7,0x00000370,0x00001E0D,0xFFFFF5A7,0x00000370}, - {"0000001000010011111010101001010011011110000111000011100110100100",0x00002292,0xFFFFF49F,0x00000393,0x000017F4,0xFFFFF9CD,0x000002F5,0x000017F4,0xFFFFF9CD,0x000002F5}, - {"0000001000010011111010101001010011011110001001000011000001000100",0x000026EE,0xFFFFF18C,0x000003F7,0x000018A7,0xFFFFF95A,0x000002E5,0x000018A7,0xFFFFF95A,0x000002E5}, - {"0000001000010011111010101001010011011110000001000010000101100100",0x00002F62,0xFFFFEC9B,0x000004A4,0x0000194E,0xFFFFF932,0x000002D9,0x0000194E,0xFFFFF932,0x000002D9}, - {"0000001000010011111010101001010011011110000111100011100110000100",0x00001CE8,0xFFFFF7FA,0x0000031C,0x000014CE,0xFFFFFBD4,0x000002AB,0x000014CE,0xFFFFFBD4,0x000002AB}, - {"0000001000010011111010101001010011011110000100100001000011100100",0x00002E5A,0xFFFFEDAB,0x0000047C,0x00001A82,0xFFFFF8F7,0x000002DE,0x00001A82,0xFFFFF8F7,0x000002DE}, - {"0000001000010011111100001111110101000010110011000011000011100100",0x00003057,0xFFFFEC34,0x000004B9,0x00002296,0xFFFFF342,0x000003D0,0x00002296,0xFFFFF342,0x000003D0}, - {"0000001000010011111010101001010011011110000001000001100010100100",0x00002B0F,0xFFFFEF58,0x00000434,0x00001BFD,0xFFFFF721,0x00000330,0x00001BFD,0xFFFFF721,0x00000330}, - {"0000001000010011111010101001010011011110001000000001000010100100",0x00001F01,0xFFFFF751,0x0000032F,0x00001502,0xFFFFFC3E,0x00000296,0x00001502,0xFFFFFC3E,0x00000296}, - {"0000001000010011111100001111110101000010110010100011000001100100",0x00002FF4,0xFFFFEAE2,0x00000503,0x00001B36,0xFFFFF736,0x00000330,0x00001B36,0xFFFFF736,0x00000330}, - {"0000001000010011111100001111110101000010110011100010000001100100",0x00003762,0xFFFFE5AB,0x000005DE,0x000018CB,0xFFFFF896,0x000002F4,0x000018CB,0xFFFFF896,0x000002F4}, - {"0000001000010011111100001111110101000010110011000010000001100100",0x00002890,0xFFFFEF92,0x00000445,0x0000191D,0xFFFFF86F,0x00000302,0x0000191D,0xFFFFF86F,0x00000302}, - {"0000001000010011111010101001010011011110000001000011000001100100",0x00002F76,0xFFFFEC0E,0x000004BF,0x00001F7D,0xFFFFF41A,0x000003C0,0x00001F7D,0xFFFFF41A,0x000003C0}, - {"0000001000010011111010101001010011011110000111100000100010100100",0x00001D55,0xFFFFF7F8,0x0000031E,0x000015DF,0xFFFFFB79,0x000002B7,0x000015DF,0xFFFFFB79,0x000002B7}, - {"0000001000010011111010101001010011011110001000000100100100100100",0x00001FE9,0xFFFFF64A,0x00000353,0x000019E8,0xFFFFF882,0x0000032A,0x000019E8,0xFFFFF882,0x0000032A}, - {"0000001000010011111010101001010011011110000001100011100101100100",0x000030B5,0xFFFFEBB8,0x000004C4,0x00001857,0xFFFFF968,0x000002D8,0x00001857,0xFFFFF968,0x000002D8}, - {"0000001000010011111100001111110101000010110010100010100011000100",0x00003398,0xFFFFE9A3,0x00000524,0x00001FF9,0xFFFFF458,0x000003AD,0x00001FF9,0xFFFFF458,0x000003AD}, - {"0000001000010011111100001111110101000010110011100010100101100100",0x00003897,0xFFFFE5BD,0x000005C8,0x00002519,0xFFFFF0BA,0x00000438,0x00002519,0xFFFFF0BA,0x00000438}, - {"0000001000010011111100001111110101000010110100000100000001100100",0x00003234,0xFFFFE9B1,0x00000530,0x000022CC,0xFFFFF20E,0x00000409,0x000022CC,0xFFFFF20E,0x00000409}, - {"0000001000010011111010101001010011011110001000000101000100000100",0x00001FD2,0xFFFFF641,0x00000354,0x000017C9,0xFFFFF9C0,0x000002FB,0x000017C9,0xFFFFF9C0,0x000002FB}, - {"0000001000010011111100001111110101000010110011100100100011100100",0x00003234,0xFFFFE946,0x0000053D,0x00002267,0xFFFFF1F5,0x0000040D,0x00002267,0xFFFFF1F5,0x0000040D}, - {"0000001000010011111010101001010011011110001000000010100110100100",0x00002330,0xFFFFF474,0x00000399,0x00001490,0xFFFFFC67,0x00000288,0x00001490,0xFFFFFC67,0x00000288}, - {"0000001000010011111100001111110101000010110100000011100100100100",0x000032A3,0xFFFFE9EB,0x0000051B,0x0000234D,0xFFFFF23C,0x000003F7,0x0000234D,0xFFFFF23C,0x000003F7}, - {"0000001000010011111010101001010011011110001000000000100100000100",0x0000217E,0xFFFFF53A,0x00000384,0x00001511,0xFFFFFBF5,0x0000029E,0x00001511,0xFFFFFBF5,0x0000029E}, - {"0000001000010011111100001111110101000010110011100101000011100100",0x0000384F,0xFFFFE562,0x000005E2,0x0000295A,0xFFFFED53,0x000004D3,0x0000295A,0xFFFFED53,0x000004D3}, - {"0000001000010011111100001111110101000010110100000101000100100100",0x00003315,0xFFFFE8D1,0x00000552,0x000025D1,0xFFFFEFAF,0x00000471,0x000025D1,0xFFFFEFAF,0x00000471}, - {"0000001000010011111100001111110101000010110001100100100100100100",0x00004183,0xFFFFDF61,0x000006DA,0x0000193C,0xFFFFF88F,0x000002EC,0x0000193C,0xFFFFF88F,0x000002EC}, - {"0000001000010011111010101001010011011110001001000010000101100100",0x00002DFC,0xFFFFEDF2,0x0000047A,0x00001755,0xFFFFFAC2,0x000002AC,0x00001755,0xFFFFFAC2,0x000002AC}, - {"0000001000010011111100001111110101000010110010100011000110100100",0x000033FE,0xFFFFE774,0x0000059F,0x00001E70,0xFFFFF492,0x000003A0,0x00001E70,0xFFFFF492,0x000003A0}, - {"0000001000010011111100001111110101000010110001100010100110100100",0x000040D7,0xFFFFDFB8,0x000006CE,0x00001AC8,0xFFFFF773,0x0000031D,0x00001AC8,0xFFFFF773,0x0000031D}, - {"0000001000010011111010101001010011011110000111100001000101100100",0x00001D02,0xFFFFF803,0x00000322,0x000015FE,0xFFFFFB71,0x000002BB,0x000015FE,0xFFFFFB71,0x000002BB}, - {"0000001000010011111100001111110101000010110100000010100010000100",0x00002EB0,0xFFFFEC31,0x000004C4,0x00001B3C,0xFFFFF73B,0x00000330,0x00001B3C,0xFFFFF73B,0x00000330}, - {"0000001000010011111100001111110101000010110010100100100110000100",0x00002D9F,0xFFFFECBF,0x000004A8,0x000022B0,0xFFFFF23C,0x000003F9,0x000022B0,0xFFFFF23C,0x000003F9}, - {"0000001000010011111100001111110101000010110011000001100011100100",0x00002C6A,0xFFFFEDAC,0x00000488,0x00002419,0xFFFFF159,0x00000427,0x00002419,0xFFFFF159,0x00000427}, - {"0000001000010011111010101001010011011110000100100001000010100100",0x00002991,0xFFFFF06C,0x0000040E,0x00001AA9,0xFFFFF8D0,0x000002E1,0x00001AA9,0xFFFFF8D0,0x000002E1}, - {"0000001000010011111010101001010011011110000100100011100100000100",0x00002F8E,0xFFFFED1B,0x00000493,0x00001DE4,0xFFFFF69C,0x00000347,0x00001DE4,0xFFFFF69C,0x00000347}, - {"0000001000010011111010101001010011011110001000000100000110000100",0x00002136,0xFFFFF540,0x0000037C,0x000014FF,0xFFFFFB83,0x000002B2,0x000014FF,0xFFFFFB83,0x000002B2}, - {"0000001000010011111010101001010011011110000001100001100011100100",0x0000354C,0xFFFFE97D,0x0000051A,0x00001906,0xFFFFF965,0x000002DD,0x00001906,0xFFFFF965,0x000002DD}, - {"0000001000010011111100001111110101000010110001100010000011000100",0x0000348B,0xFFFFE94D,0x0000051F,0x0000285B,0xFFFFEF1A,0x00000473,0x0000285B,0xFFFFEF1A,0x00000473}, - {"0000001000010011111010101001010011011110001100100001100010100100",0x000026E6,0xFFFFF24E,0x000003D6,0x0000141F,0xFFFFFCCE,0x00000260,0x0000141F,0xFFFFFCCE,0x00000260}, - {"0000001000010011111100001111110101000010110001100100000101100100",0x00003CED,0xFFFFE2A5,0x0000064E,0x00002060,0xFFFFF3E0,0x000003B0,0x00002060,0xFFFFF3E0,0x000003B0}, - {"0000001000010011111010101001010011011110000000100001000010000100",0x000029D4,0xFFFFEFF7,0x00000426,0x00001976,0xFFFFF8E1,0x000002EE,0x00001976,0xFFFFF8E1,0x000002EE}, - {"0000001000010011111100001111110101000010110010100100000010100100",0x00003767,0xFFFFE601,0x000005CC,0x00001D22,0xFFFFF5F4,0x00000361,0x00001D22,0xFFFFF5F4,0x00000361}, - {"0000001000010011111100001111110101000010110001100101000011000100",0x00003CE8,0xFFFFE2E8,0x00000637,0x0000232C,0xFFFFF1E7,0x00000405,0x0000232C,0xFFFFF1E7,0x00000405}, - {"0000001000010011111010101001010011011110001000000001000001100100",0x000023A8,0xFFFFF4CD,0x00000386,0x00001944,0xFFFFF983,0x00000300,0x00001944,0xFFFFF983,0x00000300}, - {"0000001000010011111100001111110101000010110011000011000010100100",0x00003451,0xFFFFE8B9,0x00000551,0x00001AD7,0xFFFFF7BF,0x00000318,0x00001AD7,0xFFFFF7BF,0x00000318}, - {"0000001000010011111100001111110101000010110011100010100110000100",0x0000381B,0xFFFFE5A0,0x000005D0,0x00001E0F,0xFFFFF521,0x00000382,0x00001E0F,0xFFFFF521,0x00000382}, - {"0000001000010011111010101001010011011110001000000011100011000100",0x000023A4,0xFFFFF4A6,0x00000394,0x0000171F,0xFFFFFABB,0x000002D9,0x0000171F,0xFFFFFABB,0x000002D9}, - {"0000001000010011111100001111110101000010110001100010000010100100",0x00003C2B,0xFFFFE447,0x000005F0,0x0000207F,0xFFFFF44E,0x0000039A,0x0000207F,0xFFFFF44E,0x0000039A}, - {"0000001000010011111100001111110101000010110011000011100110000100",0x00002F07,0xFFFFEB70,0x000004E9,0x00001765,0xFFFFF9A5,0x000002C6,0x00001765,0xFFFFF9A5,0x000002C6}, - {"0000001000010011111100001111110101000010110001100010100110000100",0x00003A01,0xFFFFE4E0,0x000005E7,0x0000227A,0xFFFFF292,0x000003E5,0x0000227A,0xFFFFF292,0x000003E5}, - {"0000001000010011111100001111110101000010110011100010000010100100",0x0000376E,0xFFFFE686,0x000005A6,0x00001FCF,0xFFFFF43B,0x000003A8,0x00001FCF,0xFFFFF43B,0x000003A8}, - {"0000001000010011111100001111111111101111010110100100100110000100",0x0000485F,0xFFFFDCC1,0x00000713,0x00002CF8,0xFFFFEC45,0x000004DA,0x00002CF8,0xFFFFEC45,0x000004DA}, - {"0000001000010011111100001111111111101111010111000011000110000100",0x0000331C,0xFFFFE8FF,0x00000541,0x00002366,0xFFFFF19D,0x00000411,0x00002366,0xFFFFF19D,0x00000411}, - {"0000001000010011111100001111111111101111011001000011100001100100",0x00003CF3,0xFFFFE15A,0x00000694,0x00002FB3,0xFFFFE827,0x000005B9,0x00002FB3,0xFFFFE827,0x000005B9}, - {"0000001000010011111010101001010011011110001100100001000100000100",0x000023F3,0xFFFFF3EA,0x0000039A,0x00001345,0xFFFFFD6B,0x00000241,0x00001345,0xFFFFFD6B,0x00000241}, - {"0000001000010011111100001111111111101111010111000010100010100100",0x000038C0,0xFFFFE58A,0x000005CC,0x000023CA,0xFFFFF1AA,0x00000408,0x000023CA,0xFFFFF1AA,0x00000408}, - {"0000001000010011111100001111111111101111011001100010100101000100",0x00004976,0xFFFFDD6A,0x000006D7,0x000033C6,0xFFFFE8EB,0x0000054D,0x000033C6,0xFFFFE8EB,0x0000054D}, - {"0000001000010011111100001111111111101111011001000100100100000100",0x00004049,0xFFFFDF6D,0x000006D8,0x00003129,0xFFFFE716,0x000005E9,0x00003129,0xFFFFE716,0x000005E9}, - {"0000001000010011111100001111111111101111011001100001000101100100",0x000046C2,0xFFFFDCEB,0x0000071C,0x00002E6D,0xFFFFEA8F,0x0000052E,0x00002E6D,0xFFFFEA8F,0x0000052E}, - {"0000001000010011111100001111111111101111011000100011100010100100",0x00004080,0xFFFFE1E1,0x0000063A,0x0000396D,0xFFFFE40A,0x0000062C,0x0000396D,0xFFFFE40A,0x0000062C}, - {"0000001000010011111100001111111111101111010111100010000100100100",0x00003DE0,0xFFFFE358,0x0000060C,0x00002AA2,0xFFFFEDBF,0x000004A0,0x00002AA2,0xFFFFEDBF,0x000004A0}, - {"0000001000010011111100001111111111101111010111100011000101000100",0x00003FC0,0xFFFFE2A1,0x0000061A,0x000027D8,0xFFFFEFEC,0x0000043A,0x000027D8,0xFFFFEFEC,0x0000043A}, - {"0000001000010011111100001111111111101111011001100001100100100100",0x00003FBF,0xFFFFE2F5,0x00000603,0x000032D7,0xFFFFE900,0x00000552,0x000032D7,0xFFFFE900,0x00000552}, - {"0000001000010011111100001111111111101111010111000001000011100100",0x000035EE,0xFFFFE6CA,0x000005A2,0x0000247C,0xFFFFF088,0x00000446,0x0000247C,0xFFFFF088,0x00000446}, - {"0000001000010011111100001111111111101111011001000011100010000100",0x000039C8,0xFFFFE3AE,0x0000062A,0x000028AF,0xFFFFED24,0x000004DF,0x000028AF,0xFFFFED24,0x000004DF}, - {"0000001000010011111100001111111111101111010111000010100010000100",0x00003BDE,0xFFFFE33B,0x00000632,0x00001B6C,0xFFFFF720,0x00000326,0x00001B6C,0xFFFFF720,0x00000326}, - {"0000001000010011111100001111111111101111011100100001000010100100",0x00003818,0xFFFFE57D,0x000005D4,0x000020EF,0xFFFFF327,0x000003CE,0x000020EF,0xFFFFF327,0x000003CE}, - {"0000001000010011111100001111111111101111010111100001100110100100",0x000038DA,0xFFFFE561,0x000005D3,0x0000297D,0xFFFFED6D,0x000004C5,0x0000297D,0xFFFFED6D,0x000004C5}, - {"0000001000010011111100001111111111101111011010000100100010000100",0x000027AC,0xFFFFF0CE,0x00000417,0x00001F5F,0xFFFFF484,0x000003B2,0x00001F5F,0xFFFFF484,0x000003B2}, - {"0000001000010011111100001111111111101111011001100100100010100100",0x00003F02,0xFFFFE222,0x00000643,0x000026D4,0xFFFFF000,0x00000443,0x000026D4,0xFFFFF000,0x00000443}, - {"0000001000010011111100001111111111101111011000100100000101100100",0x00004303,0xFFFFDFE3,0x00000690,0x0000312C,0xFFFFE912,0x00000561,0x0000312C,0xFFFFE912,0x00000561}, - {"0000001000010011111100001111111111101111011000000000100100000100",0x000039E5,0xFFFFE31F,0x00000657,0x00001D23,0xFFFFF51F,0x00000386,0x00001D23,0xFFFFF51F,0x00000386}, - {"0000001000010011111100001111111111101111011001100001000101000100",0x000041FA,0xFFFFE01B,0x00000697,0x00002767,0xFFFFEF90,0x00000455,0x00002767,0xFFFFEF90,0x00000455}, - {"0000001000010011111100001111111111101111011010000011000010100100",0x00002888,0xFFFFF11C,0x00000403,0x00001864,0xFFFFF9D8,0x000002D3,0x00001864,0xFFFFF9D8,0x000002D3}, - {"0000001000010011111010101001010011011110001000000001100001100100",0x0000215C,0xFFFFF5B6,0x0000036D,0x000015C5,0xFFFFFB8A,0x000002B5,0x000015C5,0xFFFFFB8A,0x000002B5}, - {"0000001000010011111100001111111111101111011010000011100110000100",0x00002FAF,0xFFFFEC27,0x000004CA,0x00002184,0xFFFFF39C,0x000003CD,0x00002184,0xFFFFF39C,0x000003CD}, - {"0000001000010011111100001111111111101111010111100001000011000100",0x00004ACE,0xFFFFD9A3,0x000007BC,0x00001A5D,0xFFFFF7F6,0x000002FC,0x00001A5D,0xFFFFF7F6,0x000002FC}, - {"0000001000010011111100001111111111101111010110100011000001000100",0x00003763,0xFFFFE797,0x0000055F,0x000029B5,0xFFFFEEA1,0x00000474,0x000029B5,0xFFFFEEA1,0x00000474}, - {"0000001000010011111100001111111111101111010111100011000101100100",0x00003832,0xFFFFE6F9,0x00000575,0x00002C99,0xFFFFEC42,0x000004E3,0x00002C99,0xFFFFEC42,0x000004E3}, - {"0000001000010011111100001111111111101111011000000100000101100100",0x000041C9,0xFFFFDE33,0x0000071E,0x0000199D,0xFFFFF808,0x000002F9,0x0000199D,0xFFFFF808,0x000002F9}, - {"0000001000010011111100001111111111101111011001000001000101100100",0x0000474A,0xFFFFD96E,0x00000802,0x00002A30,0xFFFFEB57,0x0000053F,0x00002A30,0xFFFFEB57,0x0000053F}, - {"0000001000010011111100001111111111101111010111000011000111000100",0x0000312F,0xFFFFEA6A,0x00000508,0x000029D3,0xFFFFED38,0x000004D3,0x000029D3,0xFFFFED38,0x000004D3}, - {"0000001000010011111100001111111111101111011100100001000011000100",0x00003BD6,0xFFFFE2E7,0x00000644,0x00002093,0xFFFFF37B,0x000003BD,0x00002093,0xFFFFF37B,0x000003BD}, - {"0000001000010011111100001111111111101111011010000100000011100100",0x00002F94,0xFFFFECD4,0x000004A3,0x00002196,0xFFFFF40B,0x000003B5,0x00002196,0xFFFFF40B,0x000003B5}, - {"0000001000010011111100001111111111101111010111100001100101000100",0x0000369B,0xFFFFE762,0x00000571,0x00002726,0xFFFFEF99,0x00000459,0x00002726,0xFFFFEF99,0x00000459}, - {"0000001000010011111100001111111111101111011001000010000001100100",0x00003F57,0xFFFFDF47,0x000006F4,0x00002E5F,0xFFFFE8AE,0x000005AB,0x00002E5F,0xFFFFE8AE,0x000005AB}, - {"0000001000010011111010101001010011011110000010100100000011000100",0x00004313,0xFFFFDD81,0x0000072D,0x00002468,0xFFFFF068,0x00000440,0x00002468,0xFFFFF068,0x00000440}, - {"0000001000010011111100001111111111101111011010000011000001000100",0x00002A35,0xFFFFEFA8,0x00000441,0x00001F3F,0xFFFFF4F3,0x000003A0,0x00001F3F,0xFFFFF4F3,0x000003A0}, - {"0000001000010011111100001111111111101111011001100011000010100100",0x00003E33,0xFFFFE4B0,0x000005AF,0x00002802,0xFFFFF092,0x00000412,0x00002802,0xFFFFF092,0x00000412}, - {"0000001000010011111010101001010011011110001100100011100100000100",0x00002815,0xFFFFF20E,0x000003DD,0x00001C33,0xFFFFF7D5,0x0000032A,0x00001C33,0xFFFFF7D5,0x0000032A}, - {"0000001000010011111100001111111111101111010110100010000110000100",0x00003CC2,0xFFFFE43E,0x000005DE,0x00002C16,0xFFFFECED,0x000004BA,0x00002C16,0xFFFFECED,0x000004BA}, - {"0000001000010011111100001111111111101111010111000100000010000100",0x00003CFA,0xFFFFE1EE,0x00000673,0x00001F7D,0xFFFFF402,0x000003AE,0x00001F7D,0xFFFFF402,0x000003AE}, - {"0000001000010011111100001111111111101111011000100010000100000100",0x0000486E,0xFFFFDD43,0x000006EE,0x000036F0,0xFFFFE609,0x000005D5,0x000036F0,0xFFFFE609,0x000005D5}, - {"0000001000010011111100001111111111101111010111000100100101100100",0x000039FE,0xFFFFE41F,0x00000613,0x0000266C,0xFFFFEF35,0x0000047D,0x0000266C,0xFFFFEF35,0x0000047D}, - {"0000001000010011111010101001010011011110000100100011000100100100",0x00002EA4,0xFFFFEE3B,0x00000462,0x00002126,0xFFFFF4E2,0x0000038F,0x00002126,0xFFFFF4E2,0x0000038F}, - {"0000001000010011111100001111111111101111011010000011100101000100",0x00002D2E,0xFFFFEE7B,0x00000462,0x0000229D,0xFFFFF363,0x000003D4,0x0000229D,0xFFFFF363,0x000003D4}, - {"0000001000010011111100001111111111101111010111100010100001000100",0x0000375C,0xFFFFE695,0x0000059D,0x00002319,0xFFFFF237,0x000003EE,0x00002319,0xFFFFF237,0x000003EE}, - {"0000001000010011111100001111111111101111011100100101000011000100",0x00004522,0xFFFFDC71,0x0000075E,0x0000247E,0xFFFFF0A0,0x0000043C,0x0000247E,0xFFFFF0A0,0x0000043C}, - {"0000001000010011111010101001010011011110000100100100100011100100",0x00002E58,0xFFFFECB9,0x000004A9,0x0000199A,0xFFFFF8CF,0x000002E9,0x0000199A,0xFFFFF8CF,0x000002E9}, - {"0000001000010011111100001111111111101111011001000011100011100100",0x00003791,0xFFFFE5FE,0x000005B6,0x000029F5,0xFFFFED0D,0x000004CD,0x000029F5,0xFFFFED0D,0x000004CD}, - {"0000001000010011111010101001010011011110001001000100000101000100",0x00002E9E,0xFFFFEC8D,0x000004C1,0x000019D0,0xFFFFF869,0x0000030F,0x000019D0,0xFFFFF869,0x0000030F}, - {"0000001000010011111010101001010011011110001000000011100101100100",0x0000237C,0xFFFFF435,0x000003A6,0x000014EB,0xFFFFFBC4,0x000002AF,0x000014EB,0xFFFFFBC4,0x000002AF}, - {"0000001000010011111100001111111111101111011001100010100100100100",0x00003FE5,0xFFFFE4A2,0x000005A0,0x00003416,0xFFFFE995,0x00000523,0x00003416,0xFFFFE995,0x00000523}, - {"0000001000010011111100001111111111101111010111000000100100100100",0x00002B27,0xFFFFED51,0x000004A5,0x000025D1,0xFFFFEF18,0x00000492,0x000025D1,0xFFFFEF18,0x00000492}, - {"0000001000010011111100001111111111101111011010000100100100000100",0x00002D77,0xFFFFED79,0x00000494,0x00002196,0xFFFFF352,0x000003DE,0x00002196,0xFFFFF352,0x000003DE}, - {"0000001000010011111100001111111111101111010111000010000011000100",0x00003750,0xFFFFE6AC,0x00000596,0x00002524,0xFFFFF0B5,0x00000431,0x00002524,0xFFFFF0B5,0x00000431}, - {"0000001000010011111010101001010011011110000100100010100101000100",0x00002896,0xFFFFF1BB,0x000003D9,0x00001CE0,0xFFFFF753,0x0000032F,0x00001CE0,0xFFFFF753,0x0000032F}, - {"0000001000010011111100001111111111101111011001000001100110000100",0x00003CA7,0xFFFFE0F7,0x000006B1,0x00002CB8,0xFFFFE9AB,0x00000587,0x00002CB8,0xFFFFE9AB,0x00000587}, - {"0000001000010011111010101001010011011110001100100010100001100100",0x00002513,0xFFFFF323,0x000003BC,0x00001965,0xFFFFF93C,0x000002F0,0x00001965,0xFFFFF93C,0x000002F0}, - {"0000001000010011111100001111111111101111011001100010000101100100",0x00003914,0xFFFFE683,0x00000586,0x00003120,0xFFFFE9A6,0x00000543,0x00003120,0xFFFFE9A6,0x00000543}, - {"0000001000010011111100001111111111101111011001000011100100000100",0x000040D0,0xFFFFE007,0x000006AC,0x00002B9E,0xFFFFEBF5,0x000004FB,0x00002B9E,0xFFFFEBF5,0x000004FB}, - {"0000001000010011111100001111111111101111010110100100100010000100",0x00004412,0xFFFFDF5F,0x000006A9,0x00002A9E,0xFFFFEDCE,0x00000498,0x00002A9E,0xFFFFEDCE,0x00000498}, - {"0000001000010011111100001111111111101111011000100100100010000100",0x000042A6,0xFFFFDFEF,0x00000696,0x00002E65,0xFFFFEAAE,0x00000529,0x00002E65,0xFFFFEAAE,0x00000529}, - {"0000001000010011111010101001010011011110001100100010000100100100",0x000022E8,0xFFFFF565,0x0000035F,0x00001890,0xFFFFFA61,0x000002C6,0x00001890,0xFFFFFA61,0x000002C6}, - {"0000001000010011111100001111111111101111011000100011100110100100",0x00004637,0xFFFFDDD8,0x000006E9,0x0000349D,0xFFFFE6C8,0x000005C7,0x0000349D,0xFFFFE6C8,0x000005C7}, - {"0000001000010011111010101001010011011110001001100011100100000100",0x00004686,0xFFFFDC58,0x0000073D,0x00003972,0xFFFFE27B,0x0000068E,0x00003972,0xFFFFE27B,0x0000068E}, - {"0000001000010011111100001111111111101111011010000000100011100100",0x00002B35,0xFFFFEE9C,0x0000046C,0x00001F5B,0xFFFFF4A3,0x000003A9,0x00001F5B,0xFFFFF4A3,0x000003A9}, - {"0000001000010011111100001111111111101111011100100100000101000100",0x00003AC9,0xFFFFE3B2,0x0000061B,0x000023A1,0xFFFFF170,0x0000040F,0x000023A1,0xFFFFF170,0x0000040F}, - {"0000001000010011111100001111111111101111010111100001100010000100",0x00003C50,0xFFFFE37E,0x00000617,0x0000218F,0xFFFFF339,0x000003C4,0x0000218F,0xFFFFF339,0x000003C4}, - {"0000001000010011111100001111111111101111011001100011000001000100",0x00003793,0xFFFFE761,0x0000055D,0x000029C7,0xFFFFEE03,0x00000496,0x000029C7,0xFFFFEE03,0x00000496}, - {"0000001000010011111100001111111111101111011001000011100010100100",0x000040B5,0xFFFFDF78,0x000006DA,0x00002DED,0xFFFFEA20,0x00000551,0x00002DED,0xFFFFEA20,0x00000551}, - {"0000001000010011111100001111111111101111011000000001000101000100",0x000039D6,0xFFFFE37D,0x0000063C,0x00001AED,0xFFFFF6E2,0x00000331,0x00001AED,0xFFFFF6E2,0x00000331}, - {"0000001000010011111100001111111111101111011001100010000101000100",0x0000431F,0xFFFFE09B,0x0000066A,0x00002BDF,0xFFFFED93,0x00000496,0x00002BDF,0xFFFFED93,0x00000496}, - {"0000001000010011111100001111111111101111011000100011100001100100",0x00004887,0xFFFFDC65,0x00000721,0x00003669,0xFFFFE5C4,0x000005E9,0x00003669,0xFFFFE5C4,0x000005E9}, - {"0000001000010011111100001111111111101111011001000000100100100100",0x00004120,0xFFFFDDAE,0x00000748,0x0000303B,0xFFFFE70D,0x000005FC,0x0000303B,0xFFFFE70D,0x000005FC}, - {"0000001000010011111100001111111111101111010111100010100010100100",0x0000415D,0xFFFFE0BE,0x0000067B,0x00002FA7,0xFFFFEA28,0x00000538,0x00002FA7,0xFFFFEA28,0x00000538}, - {"0000001000010011111100001111111111101111011010000001100100000100",0x00002B12,0xFFFFEFF9,0x00000428,0x00001DDA,0xFFFFF693,0x00000356,0x00001DDA,0xFFFFF693,0x00000356}, - {"0000001000010011111100001111111111101111010111100011000110000100",0x00003ED3,0xFFFFE28D,0x0000062D,0x00002B00,0xFFFFED4E,0x000004B3,0x00002B00,0xFFFFED4E,0x000004B3}, - {"0000001000010011111100001111111111101111011000100101000010100100",0x00004218,0xFFFFE039,0x0000068F,0x00002F84,0xFFFFEA0C,0x00000541,0x00002F84,0xFFFFEA0C,0x00000541}, - {"0000001000010011111100001111111111101111010110100011100001000100",0x00003FF5,0xFFFFE2A3,0x00000617,0x00003017,0xFFFFEA7A,0x00000520,0x00003017,0xFFFFEA7A,0x00000520}, - {"0000001000010011111100001111111111101111010110100000100010100100",0x00004304,0xFFFFDFCC,0x0000069E,0x00002E0C,0xFFFFEB51,0x00000505,0x00002E0C,0xFFFFEB51,0x00000505}, - {"0000001000010011111100001111111111101111011001000001100101000100",0x00003D3A,0xFFFFE17F,0x00000687,0x0000284C,0xFFFFED83,0x000004CD,0x0000284C,0xFFFFED83,0x000004CD}, - {"0000001000010011111100001111111111101111010111100100000010100100",0x000042F5,0xFFFFDF76,0x000006B2,0x000027B6,0xFFFFEF72,0x00000455,0x000027B6,0xFFFFEF72,0x00000455}, - {"0000001000010011111100001111111111101111010111000011100011000100",0x00004267,0xFFFFDF29,0x000006D5,0x0000298F,0xFFFFEDBD,0x000004AC,0x0000298F,0xFFFFEDBD,0x000004AC}, - {"0000001000010011111010101001010011011110001001000000100100100100",0x0000303E,0xFFFFEC00,0x000004CB,0x000021CD,0xFFFFF36E,0x000003D6,0x000021CD,0xFFFFF36E,0x000003D6}, - {"0000001000010011111100001111111111101111010111100010100011000100",0x00003127,0xFFFFEBDB,0x000004A6,0x00002E95,0xFFFFEB78,0x000004F3,0x00002E95,0xFFFFEB78,0x000004F3}, - {"0000001000010011111010101001010011011110000111000001000001100100",0x00002655,0xFFFFF2D9,0x000003CF,0x000019F5,0xFFFFF8E7,0x00000313,0x000019F5,0xFFFFF8E7,0x00000313}, - {"0000001000010011111010101001010011011110000101100100000010000100",0x00002372,0xFFFFF449,0x0000039B,0x00001544,0xFFFFFC16,0x0000028B,0x00001544,0xFFFFFC16,0x0000028B}, - {"0000001000010011111100001111111111101111011001100010100011000100",0x0000348E,0xFFFFEB20,0x000004B2,0x00002BE8,0xFFFFEE80,0x00000467,0x00002BE8,0xFFFFEE80,0x00000467}, - {"0000001000010011111100001111111111101111010111100001000100000100",0x00004092,0xFFFFE073,0x0000069B,0x00002061,0xFFFFF403,0x000003A0,0x00002061,0xFFFFF403,0x000003A0}, - {"0000001000010011111100001111111111101111011100100010000011100100",0x000039D1,0xFFFFE55D,0x000005CC,0x000025CB,0xFFFFF0C0,0x00000428,0x000025CB,0xFFFFF0C0,0x00000428}, - {"0000001000010011111100001111111111101111010111100100100010000100",0x000042AA,0xFFFFDF68,0x000006C2,0x0000290B,0xFFFFEE78,0x00000485,0x0000290B,0xFFFFEE78,0x00000485}, - {"0000001000010011111100001111111111101111011100100001100011000100",0x0000356F,0xFFFFE7AC,0x0000056E,0x00001BE8,0xFFFFF6E3,0x0000032A,0x00001BE8,0xFFFFF6E3,0x0000032A}, - {"0000001000010011111100001111111111101111010111100001000101000100",0x00003525,0xFFFFE7FF,0x0000055D,0x0000242C,0xFFFFF12E,0x0000041D,0x0000242C,0xFFFFF12E,0x0000041D}, - {"0000001000010011111100001111111111101111010111000100100011000100",0x00003360,0xFFFFE895,0x00000550,0x00002175,0xFFFFF29E,0x000003E9,0x00002175,0xFFFFF29E,0x000003E9}, - {"0000001000010011111100001111111111101111011001000100000010100100",0x00003C94,0xFFFFE1C4,0x0000067E,0x00002E28,0xFFFFE964,0x0000057F,0x00002E28,0xFFFFE964,0x0000057F}, - {"0000001000010011111100001111111111101111011100100100000100100100",0x0000431C,0xFFFFDE4B,0x000006FF,0x00002270,0xFFFFF268,0x000003E5,0x00002270,0xFFFFF268,0x000003E5}, - {"0000001000010011111010101001010011011110000100100001100011000100",0x00002B67,0xFFFFF01D,0x00000414,0x000019FB,0xFFFFF961,0x000002D8,0x000019FB,0xFFFFF961,0x000002D8}, - {"0000001000010011111100001111111111101111010111100011100110000100",0x0000400B,0xFFFFE13D,0x0000066F,0x000024F3,0xFFFFF125,0x00000417,0x000024F3,0xFFFFF125,0x00000417}, - {"0000001000010011111100001111111111101111010110100010000010100100",0x00004460,0xFFFFE00E,0x0000067B,0x000023DF,0xFFFFF2E6,0x000003BB,0x000023DF,0xFFFFF2E6,0x000003BB}, - {"0000001000010011111100001111111111101111011001000001100001100100",0x00003AFB,0xFFFFE2C5,0x00000650,0x00002D46,0xFFFFE9C4,0x00000571,0x00002D46,0xFFFFE9C4,0x00000571}, - {"0000001000010011111100001111111111101111011000100010100100100100",0x00005482,0xFFFFD5BC,0x0000081A,0x00003250,0xFFFFE961,0x00000541,0x00003250,0xFFFFE961,0x00000541}, - {"0000001000010011111100001111111111101111010111000010100101000100",0x00003D27,0xFFFFE2FA,0x00000632,0x00002A4D,0xFFFFED6A,0x000004BB,0x00002A4D,0xFFFFED6A,0x000004BB}, - {"0000001000010011111100001111111111101111011000000001100010100100",0x00003E03,0xFFFFE142,0x00000690,0x00001E08,0xFFFFF555,0x0000036C,0x00001E08,0xFFFFF555,0x0000036C}, - {"0000001000010011111100001111111111101111010111000010000001100100",0x000031B5,0xFFFFE97D,0x00000535,0x0000232E,0xFFFFF166,0x00000422,0x0000232E,0xFFFFF166,0x00000422}, - {"0000001000010011111100001111111111101111010111100001100011100100",0x00003753,0xFFFFE724,0x00000575,0x0000281A,0xFFFFEF1A,0x0000046B,0x0000281A,0xFFFFEF1A,0x0000046B}, - {"0000001000010011111010101001010011011110001000000100000101000100",0x00002071,0xFFFFF5C9,0x0000036F,0x00001470,0xFFFFFBF7,0x000002A5,0x00001470,0xFFFFFBF7,0x000002A5}, - {"0000001000010011111100001111111111101111011010000011000101000100",0x00002799,0xFFFFF223,0x000003CF,0x00001CD3,0xFFFFF74A,0x00000333,0x00001CD3,0xFFFFF74A,0x00000333}, - {"0000001000010011111100001111111111101111011001100001000011000100",0x000040DF,0xFFFFE11C,0x00000664,0x000031D4,0xFFFFE8BC,0x0000056F,0x000031D4,0xFFFFE8BC,0x0000056F}, - {"0000001000010011111100001111111111101111011001000100000011000100",0x00003A4D,0xFFFFE3A6,0x00000627,0x00002871,0xFFFFEDA0,0x000004C0,0x00002871,0xFFFFEDA0,0x000004C0}, - {"0000001000010011111100001111111111101111011010000001100110000100",0x00002AF9,0xFFFFEED7,0x00000464,0x0000219B,0xFFFFF368,0x000003D6,0x0000219B,0xFFFFF368,0x000003D6}, - {"0000001000010011111010101001010011011110001100100011000100100100",0x000026D5,0xFFFFF36C,0x000003A3,0x00001BC6,0xFFFFF881,0x00000311,0x00001BC6,0xFFFFF881,0x00000311}, - {"0000001000010011111100001111111111101111010111100010000001000100",0x0000325D,0xFFFFEA07,0x0000050B,0x000026D1,0xFFFFEFB3,0x0000045A,0x000026D1,0xFFFFEFB3,0x0000045A}, - {"0000001000010011111100001111111111101111011010000010100001100100",0x00002F75,0xFFFFEC64,0x000004BE,0x00001EEB,0xFFFFF559,0x00000386,0x00001EEB,0xFFFFF559,0x00000386}, - {"0000001000010011111100001111111111101111010110100011100010100100",0x00003C2F,0xFFFFE541,0x000005A3,0x000025B6,0xFFFFF16F,0x000003FA,0x000025B6,0xFFFFF16F,0x000003FA}, - {"0000001000010011111100001111111111101111011010000100100100100100",0x00002BC2,0xFFFFEE89,0x0000046A,0x00001D04,0xFFFFF651,0x00000361,0x00001D04,0xFFFFF651,0x00000361}, - {"0000001000010011111100001111111111101111011010000010100110100100",0x00002DD0,0xFFFFED40,0x0000049F,0x00001C8C,0xFFFFF6B3,0x00000353,0x00001C8C,0xFFFFF6B3,0x00000353}, - {"0000001000010011111010101001010011011110000111000000100011100100",0x000021ED,0xFFFFF530,0x00000380,0x00001643,0xFFFFFB1C,0x000002C3,0x00001643,0xFFFFFB1C,0x000002C3}, - {"0000001000010011111010101001010011011110001100100001100100000100",0x000028C7,0xFFFFF160,0x000003FD,0x00001990,0xFFFFF994,0x000002E2,0x00001990,0xFFFFF994,0x000002E2}, - {"0000001000010011111100001111111111101111011001100001000010100100",0x0000431C,0xFFFFDF9D,0x000006A3,0x000034A6,0xFFFFE6B0,0x000005C9,0x000034A6,0xFFFFE6B0,0x000005C9}, - {"0000001000010011111010101001010011011110001001100011000010100100",0x00004115,0xFFFFE0D6,0x00000667,0x000031AD,0xFFFFE850,0x00000585,0x000031AD,0xFFFFE850,0x00000585}, - {"0000001000010011111100001111111111101111011001000011100100100100",0x0000424A,0xFFFFDEEC,0x000006E1,0x0000346A,0xFFFFE5EA,0x00000602,0x0000346A,0xFFFFE5EA,0x00000602}, - {"0000001000010011111100001111111111101111011001100001100110000100",0x00004990,0xFFFFDAFA,0x00000771,0x00002A9C,0xFFFFED37,0x000004BC,0x00002A9C,0xFFFFED37,0x000004BC}, - {"0000001000010011111100001111111111101111011001000010100010100100",0x00003858,0xFFFFE568,0x000005D2,0x00003030,0xFFFFE8B0,0x0000058E,0x00003030,0xFFFFE8B0,0x0000058E}, - {"0000001000010011111100001111111111101111011010000100000101100100",0x00001EDC,0xFFFFF6CD,0x00000322,0x00001FCA,0xFFFFF4BD,0x0000039E,0x00001FCA,0xFFFFF4BD,0x0000039E}, - {"0000001000010011111100001111111111101111011001100010000100100100",0x00004C88,0xFFFFDBA3,0x0000071B,0x000030C4,0xFFFFEAFD,0x000004F7,0x000030C4,0xFFFFEAFD,0x000004F7}, - {"0000001000010011111100001111111111101111011010000000100100000100",0x00002B9A,0xFFFFEE41,0x0000047D,0x00002131,0xFFFFF344,0x000003E5,0x00002131,0xFFFFF344,0x000003E5}, - {"0000001000010011111100001111111111101111011000100011100110000100",0x00003E4B,0xFFFFE33C,0x000005FA,0x00003877,0xFFFFE437,0x0000062E,0x00003877,0xFFFFE437,0x0000062E}, - {"0000001000010011111010101001010011011110001100100010000001100100",0x00002376,0xFFFFF444,0x0000038A,0x000017ED,0xFFFFFA4C,0x000002C1,0x000017ED,0xFFFFFA4C,0x000002C1}, - {"0000001000010011111100001111111111101111011001100001000010000100",0x00004517,0xFFFFDDF4,0x000006F2,0x000030DC,0xFFFFE8EF,0x00000571,0x000030DC,0xFFFFE8EF,0x00000571}, - {"0000001000010011111100001111111111101111011010000001100101000100",0x0000270C,0xFFFFF1F3,0x000003DF,0x0000207B,0xFFFFF474,0x000003AD,0x0000207B,0xFFFFF474,0x000003AD}, - {"0000001000010011111100001111111111101111011001000101000101000100",0x00004086,0xFFFFDF39,0x000006E3,0x00002A24,0xFFFFEC2B,0x000004FF,0x00002A24,0xFFFFEC2B,0x000004FF}, - {"0000001000010011111100001111111111101111010111000011000100100100",0x00003BDE,0xFFFFE45E,0x000005EB,0x00002CD5,0xFFFFEC45,0x000004DD,0x00002CD5,0xFFFFEC45,0x000004DD}, - {"0000001000010011111100001111111111101111011100100011000011100100",0x00003803,0xFFFFE714,0x00000579,0x0000288A,0xFFFFEF21,0x0000046B,0x0000288A,0xFFFFEF21,0x0000046B}, - {"0000001000010011111100001111111111101111011000000001000100000100",0x00003F50,0xFFFFE002,0x000006CD,0x00001AD4,0xFFFFF72E,0x0000031F,0x00001AD4,0xFFFFF72E,0x0000031F}, - {"0000001000010011111100001111111111101111011010000010000011100100",0x00002968,0xFFFFF100,0x00000402,0x00001FB5,0xFFFFF57C,0x0000037F,0x00001FB5,0xFFFFF57C,0x0000037F}, - {"0000001000010011111100001111111111101111011001100010000100000100",0x00004283,0xFFFFE2A7,0x000005F5,0x00003165,0xFFFFEB0C,0x000004EC,0x00003165,0xFFFFEB0C,0x000004EC}, - {"0000001000010011111100001111111111101111011001000011000110100100",0x00004253,0xFFFFDDA8,0x00000732,0x00002E5C,0xFFFFE90A,0x00000593,0x00002E5C,0xFFFFE90A,0x00000593}, - {"0000001000010011111100001111111111101111010111000101000010100100",0x00003551,0xFFFFE756,0x0000058D,0x000029A7,0xFFFFED0C,0x000004DE,0x000029A7,0xFFFFED0C,0x000004DE}, - {"0000001000010011111100001111111111101111011001000010100011000100",0x00003728,0xFFFFE604,0x000005C4,0x00002832,0xFFFFEE64,0x00000493,0x00002832,0xFFFFEE64,0x00000493}, - {"0000001000010011111100001111111111101111011000100011100101100100",0x00004796,0xFFFFDCC8,0x00000715,0x000032AB,0xFFFFE848,0x0000057C,0x000032AB,0xFFFFE848,0x0000057C}, - {"0000001000010011111100001111111111101111011000100001000011000100",0x000049DF,0xFFFFDB24,0x0000075F,0x00003076,0xFFFFE967,0x0000055C,0x00003076,0xFFFFE967,0x0000055C}, - {"0000001000010011111100001111111111101111011100100001000100000100",0x00003F13,0xFFFFE099,0x000006A8,0x00002279,0xFFFFF226,0x000003F3,0x00002279,0xFFFFF226,0x000003F3}, - {"0000001000010011111100001111111111101111011001000011000010100100",0x00003E03,0xFFFFE19F,0x00000674,0x00002D66,0xFFFFEAA7,0x00000537,0x00002D66,0xFFFFEAA7,0x00000537}, - {"0000001000010011111100001111111111101111010111000100000100000100",0x000037DA,0xFFFFE63F,0x000005A7,0x00002543,0xFFFFF0A0,0x00000431,0x00002543,0xFFFFF0A0,0x00000431}, - {"0000001000010011111100001111111111101111011000100100100101000100",0x00003D82,0xFFFFE3F5,0x000005D9,0x0000332F,0xFFFFE834,0x00000577,0x0000332F,0xFFFFE834,0x00000577}, - {"0000001000010011111010101001010011011110000100100010100011000100",0x00002915,0xFFFFF1E0,0x000003D4,0x00002065,0xFFFFF57B,0x00000378,0x00002065,0xFFFFF57B,0x00000378}, - {"0000001000010011111100001111111111101111010111100100100100000100",0x000036FC,0xFFFFE72D,0x00000577,0x00002811,0xFFFFEF30,0x00000464,0x00002811,0xFFFFEF30,0x00000464}, - {"0000001000010011111100001111111111101111011000100011000110000100",0x00004767,0xFFFFDD30,0x000006FD,0x00003703,0xFFFFE564,0x000005F8,0x00003703,0xFFFFE564,0x000005F8}, - {"0000001000010011111100001111111111101111011000000011000110000100",0x00003094,0xFFFFEAA9,0x000004F5,0x000022E7,0xFFFFF200,0x000003FB,0x000022E7,0xFFFFF200,0x000003FB}, - {"0000001000010011111100001111111111101111011001000001000101000100",0x00003EF0,0xFFFFDF83,0x000006ED,0x00002A27,0xFFFFEB7C,0x00000537,0x00002A27,0xFFFFEB7C,0x00000537}, - {"0000001000010011111100001111111111101111011010000001000100100100",0x0000243C,0xFFFFF358,0x000003AC,0x00001DC4,0xFFFFF5E9,0x00000372,0x00001DC4,0xFFFFF5E9,0x00000372}, - {"0000001000010011111100001111111111101111011100100010000101000100",0x0000284B,0xFFFFF036,0x0000040F,0x00001FCD,0xFFFFF445,0x00000395,0x00001FCD,0xFFFFF445,0x00000395}, - {"0000001000010011111100001111111111101111011010000100000011000100",0x00002611,0xFFFFF285,0x000003C7,0x00001CFE,0xFFFFF6A0,0x00000355,0x00001CFE,0xFFFFF6A0,0x00000355}, - {"0000001000010011111010101001010011011110000111000011100110100100",0x00002292,0xFFFFF49F,0x00000393,0x000017F4,0xFFFFF9CD,0x000002F5,0x000017F4,0xFFFFF9CD,0x000002F5}, - {"0000001000010011111100001111111111101111010111100011100010100100",0x000037F3,0xFFFFE68D,0x00000590,0x00002443,0xFFFFF1AD,0x000003FA,0x00002443,0xFFFFF1AD,0x000003FA}, - {"0000001000010011111100001111111111101111011010000010000101000100",0x00002C01,0xFFFFEF3F,0x00000444,0x0000210A,0xFFFFF475,0x000003A7,0x0000210A,0xFFFFF475,0x000003A7}, - {"0000001000010011111010101001010011011110000100100001000011100100",0x00002C0E,0xFFFFEF0F,0x00000446,0x00001A82,0xFFFFF8F7,0x000002DE,0x00001A82,0xFFFFF8F7,0x000002DE}, - {"0000001000010011111100001111111111101111010111100010000011000100",0x00003FA6,0xFFFFE20A,0x0000063F,0x00002E29,0xFFFFEB21,0x00000510,0x00002E29,0xFFFFEB21,0x00000510}, - {"0000001000010011111100001111111111101111010111000010000101100100",0x00003BCD,0xFFFFE31B,0x0000063C,0x000019AF,0xFFFFF83D,0x000002F8,0x000019AF,0xFFFFF83D,0x000002F8}, - {"0000001000010011111100001111111111101111011001100100000101100100",0x000044C8,0xFFFFDF08,0x000006B0,0x00002E2E,0xFFFFEB62,0x000004FD,0x00002E2E,0xFFFFEB62,0x000004FD}, - {"0000001000010011111100001111111111101111010111000001100010000100",0x00003790,0xFFFFE571,0x000005E3,0x00002042,0xFFFFF35D,0x000003CF,0x00002042,0xFFFFF35D,0x000003CF}, - {"0000001000010011111100001111111111101111011000000101000011100100",0x000038AC,0xFFFFE46C,0x00000609,0x0000215E,0xFFFFF22D,0x00000403,0x0000215E,0xFFFFF22D,0x00000403}, - {"0000001000010011111100001111111111101111010111100010100110100100",0x00003A1E,0xFFFFE536,0x000005C9,0x000024F3,0xFFFFF11A,0x0000041B,0x000024F3,0xFFFFF11A,0x0000041B}, - {"0000001000010011111100001111111111101111011001100101000011100100",0x0000431A,0xFFFFDF1B,0x000006C5,0x00002F34,0xFFFFEA02,0x00000545,0x00002F34,0xFFFFEA02,0x00000545}, - {"0000001000010011111100001111111111101111011001000001100100000100",0x000042DC,0xFFFFDE28,0x0000070C,0x00003B53,0xFFFFE0EA,0x000006E2,0x00003B53,0xFFFFE0EA,0x000006E2}, - {"0000001000010011111100001111111111101111011010000011000101100100",0x0000264B,0xFFFFF29A,0x000003C4,0x000021D0,0xFFFFF3CE,0x000003C4,0x000021D0,0xFFFFF3CE,0x000003C4}, - {"0000001000010011111100001111111111101111010110100100000001100100",0x00004225,0xFFFFE0E8,0x00000665,0x00002B53,0xFFFFED89,0x0000049F,0x00002B53,0xFFFFED89,0x0000049F}, - {"0000001000010011111010101001010011011110001000000100100100100100",0x00001FCC,0xFFFFF63F,0x00000358,0x000019E8,0xFFFFF882,0x0000032A,0x000019E8,0xFFFFF882,0x0000032A}, - {"0000001000010011111100001111111111101111011000100100000010100100",0x000045E0,0xFFFFDDD0,0x000006ED,0x00003193,0xFFFFE8BD,0x00000572,0x00003193,0xFFFFE8BD,0x00000572}, - {"0000001000010011111100001111111111101111011010000011100100100100",0x000024FC,0xFFFFF366,0x000003A6,0x00001FE8,0xFFFFF509,0x00000394,0x00001FE8,0xFFFFF509,0x00000394}, - {"0000001000010011111100001111111111101111010111000100100010000100",0x0000378F,0xFFFFE54B,0x000005F1,0x00001C9B,0xFFFFF5C7,0x00000368,0x00001C9B,0xFFFFF5C7,0x00000368}, - {"0000001000010011111100001111111111101111011001000001100010100100",0x00003CF3,0xFFFFE15A,0x00000694,0x00002CDD,0xFFFFEA44,0x00000557,0x00002CDD,0xFFFFEA44,0x00000557}, - {"0000001000010011111010101001010011011110001000000000100100000100",0x000021EC,0xFFFFF4F4,0x0000038F,0x00001511,0xFFFFFBF5,0x0000029E,0x00001511,0xFFFFFBF5,0x0000029E}, - {"0000001000010011111100001111111111101111011000000001000010100100",0x00003C8A,0xFFFFE1C1,0x00000685,0x000019C7,0xFFFFF7E2,0x00000301,0x000019C7,0xFFFFF7E2,0x00000301}, - {"0000001000010011111100001111111111101111010111100010000001100100",0x00003908,0xFFFFE5C7,0x000005B3,0x00002793,0xFFFFEF46,0x00000465,0x00002793,0xFFFFEF46,0x00000465}, - {"0000001000010011111100001111111111101111011000000101000100000100",0x000040A3,0xFFFFDE61,0x00000725,0x00002077,0xFFFFF2CE,0x000003E8,0x00002077,0xFFFFF2CE,0x000003E8}, - {"0000001000010011111100001111111111101111011001100100000101000100",0x00003DCA,0xFFFFE34D,0x00000608,0x00002D66,0xFFFFEBDF,0x000004E8,0x00002D66,0xFFFFEBDF,0x000004E8}, - {"0000001000010011111100001111111111101111010111100101000011000100",0x00003085,0xFFFFEB70,0x000004C8,0x000029B1,0xFFFFEDD9,0x000004A5,0x000029B1,0xFFFFEDD9,0x000004A5}, - {"0000001000010011111010101001010011011110000010000011100010000100",0x00004C73,0xFFFFD676,0x0000086C,0x0000280A,0xFFFFED89,0x000004C2,0x0000280A,0xFFFFED89,0x000004C2}, - {"0000001000010011111010101001010011011110001001000010000101100100",0x00002CE5,0xFFFFEE8C,0x00000466,0x00001755,0xFFFFFAC2,0x000002AC,0x00001755,0xFFFFFAC2,0x000002AC}, - {"0000001000010011111100001111111111101111011000100001000100100100",0x0000489F,0xFFFFDBF1,0x0000073E,0x0000332D,0xFFFFE786,0x000005AD,0x0000332D,0xFFFFE786,0x000005AD}, - {"0000001000010011111100001111111111101111011000000010100001100100",0x00003D09,0xFFFFE193,0x00000689,0x00001E82,0xFFFFF4C0,0x00000386,0x00001E82,0xFFFFF4C0,0x00000386}, - {"0000001000010011111100001111111111101111011001000100000100000100",0x00003E4C,0xFFFFE131,0x00000689,0x00002F4E,0xFFFFE925,0x0000057B,0x00002F4E,0xFFFFE925,0x0000057B}, - {"0000001000010011111100001111111111101111010110100100000010000100",0x00003B31,0xFFFFE53F,0x000005B3,0x0000248A,0xFFFFF211,0x000003DF,0x0000248A,0xFFFFF211,0x000003DF}, - {"0000001000010011111100001111111111101111011001000100000100100100",0x000038DD,0xFFFFE54A,0x000005C9,0x00002B6D,0xFFFFEBDF,0x00000502,0x00002B6D,0xFFFFEBDF,0x00000502}, - {"0000001000010011111100001111111111101111011010000100000001100100",0x00002698,0xFFFFF1A8,0x000003F2,0x00002163,0xFFFFF34B,0x000003E3,0x00002163,0xFFFFF34B,0x000003E3}, - {"0000001000010011111010101001010011011110001000000001000001100100",0x000023A8,0xFFFFF4CD,0x00000386,0x00001944,0xFFFFF983,0x00000300,0x00001944,0xFFFFF983,0x00000300}, - {"0000001000010011111100001111111111101111011001000001100011000100",0x00003EAF,0xFFFFE0C3,0x000006A0,0x000030AB,0xFFFFE829,0x000005A6,0x000030AB,0xFFFFE829,0x000005A6}, - {"0000001000010011111100001111111111101111011010000100100101000100",0x00002E89,0xFFFFECA6,0x000004B6,0x00001FA0,0xFFFFF4A8,0x000003A3,0x00001FA0,0xFFFFF4A8,0x000003A3}, - {"0000001000010011111100001111111111101111011010000010100010100100",0x000028A4,0xFFFFF112,0x00000402,0x00001F7C,0xFFFFF545,0x0000038A,0x00001F7C,0xFFFFF545,0x0000038A}, - {"0000001000010011111100001111111111101111011001100101000010100100",0x00004135,0xFFFFDFA2,0x000006C5,0x0000324C,0xFFFFE7AA,0x000005AF,0x0000324C,0xFFFFE7AA,0x000005AF}, - {"0000001000010011111010101001010011011110001000000011100011000100",0x00002012,0xFFFFF693,0x00000352,0x0000171F,0xFFFFFABB,0x000002D9,0x0000171F,0xFFFFFABB,0x000002D9}, - {"0000001000010011111100001111111111101111011001000011000010000100",0x00003D7C,0xFFFFE1BC,0x00000671,0x00002A45,0xFFFFEC84,0x000004EC,0x00002A45,0xFFFFEC84,0x000004EC}, - {"0000001000010011111100001111111111101111011100100011000001100100",0x00004172,0xFFFFDF58,0x000006DA,0x00002504,0xFFFFF0A6,0x00000431,0x00002504,0xFFFFF0A6,0x00000431}, - {"0000001000010011111100001111111010011001001010000001100101000100",0x000029C7,0xFFFFF087,0x00000414,0x00001DCB,0xFFFFF675,0x0000035F,0x00001DCB,0xFFFFF675,0x0000035F}, - {"0000001000010011111100001111111010011001001010100010100110100100",0x000027F0,0xFFFFF05A,0x00000432,0x00001707,0xFFFFFA0E,0x000002D1,0x00001707,0xFFFFFA0E,0x000002D1}, - {"0000001000010011111100001111111010011001001000100010000101000100",0x00003279,0xFFFFE9F7,0x00000511,0x00001B5E,0xFFFFF787,0x00000317,0x00001B5E,0xFFFFF787,0x00000317}, - {"0000001000010011111100001111111010011001001100100010000110000100",0x000030A5,0xFFFFEABC,0x000004FF,0x000019D1,0xFFFFF83C,0x00000304,0x000019D1,0xFFFFF83C,0x00000304}, - {"0000001000010011111100001111111010011001001010000010100001000100",0x0000283B,0xFFFFF122,0x00000402,0x000019C2,0xFFFFF8E9,0x000002FB,0x000019C2,0xFFFFF8E9,0x000002FB}, - {"0000001000010011111100001111111010011001001011000010000010000100",0x00003376,0xFFFFE9E1,0x00000510,0x000021A7,0xFFFFF39F,0x000003BF,0x000021A7,0xFFFFF39F,0x000003BF}, - {"0000001000010011111100001111111010011001001100100001100011000100",0x000031D2,0xFFFFEA9C,0x000004FC,0x00001F66,0xFFFFF4E4,0x00000390,0x00001F66,0xFFFFF4E4,0x00000390}, - {"0000001000010011111100001111111010011001000110100011100001100100",0x00003006,0xFFFFEB18,0x000004F2,0x000019B3,0xFFFFF84E,0x00000301,0x000019B3,0xFFFFF84E,0x00000301}, - {"0000001000010011111100001111111010011001001100000011100110100100",0x0000364F,0xFFFFE81F,0x00000556,0x00002AC9,0xFFFFED87,0x000004BD,0x00002AC9,0xFFFFED87,0x000004BD}, - {"0000001000010011111100001111111010011001001011100011100001000100",0x00003043,0xFFFFEBAE,0x000004CD,0x00001B0C,0xFFFFF7ED,0x0000030C,0x00001B0C,0xFFFFF7ED,0x0000030C}, - {"0000001000010011111100001111111010011001001100000100100010100100",0x000037CE,0xFFFFE69E,0x00000596,0x0000276B,0xFFFFEF65,0x0000046E,0x0000276B,0xFFFFEF65,0x0000046E}, - {"0000001000010011111100001111111010011001001011000011000100000100",0x00003063,0xFFFFED5E,0x0000046F,0x000024AE,0xFFFFF2C4,0x000003D8,0x000024AE,0xFFFFF2C4,0x000003D8}, - {"0000001000010011111100001111111010011001001011100000100010100100",0x00002F5D,0xFFFFEBDC,0x000004D3,0x00001EDB,0xFFFFF50F,0x0000038E,0x00001EDB,0xFFFFF50F,0x0000038E}, - {"0000001000010011111100001111111010011001001011100100100010100100",0x00003148,0xFFFFEA9A,0x000004FB,0x0000192D,0xFFFFF8E9,0x000002DF,0x0000192D,0xFFFFF8E9,0x000002DF}, - {"0000001000010011111100001111111010011001001011000010000001100100",0x00003682,0xFFFFE7E4,0x0000055C,0x0000250E,0xFFFFF150,0x0000041A,0x0000250E,0xFFFFF150,0x0000041A}, - {"0000001000010011111100001111111010011001001010100010000010000100",0x0000284E,0xFFFFF15A,0x000003F8,0x00001CE2,0xFFFFF6F9,0x0000034F,0x00001CE2,0xFFFFF6F9,0x0000034F}, - {"0000001000010011111100001111111010011001001100000001100010100100",0x00003171,0xFFFFEAE9,0x000004ED,0x00001F40,0xFFFFF513,0x00000384,0x00001F40,0xFFFFF513,0x00000384}, - {"0000001000010011111100001111111010011001001100100011000001000100",0x000031BD,0xFFFFEA64,0x0000050A,0x00001EFD,0xFFFFF4F7,0x00000390,0x00001EFD,0xFFFFF4F7,0x00000390}, - {"0000001000010011111100001111111010011001001011100101000011100100",0x00003050,0xFFFFEB29,0x000004EA,0x000019B3,0xFFFFF878,0x000002F9,0x000019B3,0xFFFFF878,0x000002F9}, - {"0000001000010011111100001111111010011001001011000001100100000100",0x00003400,0xFFFFE9A0,0x0000051A,0x00002460,0xFFFFF1DA,0x00000409,0x00002460,0xFFFFF1DA,0x00000409}, - {"0000001000010011111100001111111010011001001011000100100010000100",0x000034A1,0xFFFFE86F,0x00000558,0x0000255D,0xFFFFF09E,0x00000443,0x0000255D,0xFFFFF09E,0x00000443}, - {"0000001000010011111100001111111010011001001011100100100011100100",0x00003103,0xFFFFEAD7,0x000004F0,0x00001896,0xFFFFF95A,0x000002CC,0x00001896,0xFFFFF95A,0x000002CC}, - {"0000001000010011111100001111111010011001001100000001100011100100",0x00003120,0xFFFFEB9E,0x000004CB,0x000021E8,0xFFFFF3A2,0x000003C1,0x000021E8,0xFFFFF3A2,0x000003C1}, - {"0000001000010011111100001111111010011001000111000101000011100100",0x00003558,0xFFFFE812,0x00000565,0x0000256E,0xFFFFF097,0x00000447,0x0000256E,0xFFFFF097,0x00000447}, - {"0000001000010011111100001111111010011001000110100010100001000100",0x00002DA8,0xFFFFECA8,0x000004B7,0x0000180B,0xFFFFF96D,0x000002D8,0x0000180B,0xFFFFF96D,0x000002D8}, - {"0000001000010011111100001111111010011001001011100011000001100100",0x00003232,0xFFFFEA66,0x000004FF,0x00001DDE,0xFFFFF5FE,0x0000035A,0x00001DDE,0xFFFFF5FE,0x0000035A}, - {"0000001000010011111100001111111010011001001100000101000011100100",0x000034D2,0xFFFFE89F,0x00000548,0x0000246C,0xFFFFF17F,0x00000418,0x0000246C,0xFFFFF17F,0x00000418}, - {"0000001000010011111100001111111010011001001100000100100100000100",0x000033EC,0xFFFFE954,0x0000052A,0x00002323,0xFFFFF279,0x000003EE,0x00002323,0xFFFFF279,0x000003EE}, - {"0000001000010011111100001111111010011001001100000011100010000100",0x000033AA,0xFFFFE955,0x0000052D,0x0000229F,0xFFFFF2B2,0x000003E7,0x0000229F,0xFFFFF2B2,0x000003E7}, - {"0000001000010011111100001111111010011001001100100100100101100100",0x00003258,0xFFFFE9AA,0x0000052A,0x00001D5F,0xFFFFF5D1,0x0000036B,0x00001D5F,0xFFFFF5D1,0x0000036B}, - {"0000001000010011111100001111111010011001001100000010100110100100",0x0000323A,0xFFFFEA5F,0x00000504,0x00002108,0xFFFFF3D5,0x000003BA,0x00002108,0xFFFFF3D5,0x000003BA}, - {"0000001000010011111100001111111010011001001011000010000110000100",0x00003216,0xFFFFEA6B,0x000004FF,0x00001D6E,0xFFFFF640,0x00000350,0x00001D6E,0xFFFFF640,0x00000350}, - {"0000001000010011111100001111111010011001001100100001000011100100",0x000030C5,0xFFFFEAC4,0x000004FC,0x00001924,0xFFFFF8C2,0x000002EE,0x00001924,0xFFFFF8C2,0x000002EE}, - {"0000001000010011111100001111111010011001001100000101000100000100",0x000032BB,0xFFFFE9F1,0x00000515,0x00002211,0xFFFFF31B,0x000003D5,0x00002211,0xFFFFF31B,0x000003D5}, - {"0000001000010011111100001111111010011001001100000100100011000100",0x0000352C,0xFFFFE85B,0x00000553,0x00002410,0xFFFFF1B4,0x0000040F,0x00002410,0xFFFFF1B4,0x0000040F}, - {"0000001000010011111100001111111010011001001000100011100011000100",0x000036A0,0xFFFFE7E8,0x0000055D,0x00002901,0xFFFFEEB8,0x00000489,0x00002901,0xFFFFEEB8,0x00000489}, - {"0000001000010011111100001111111010011001001011000011000001000100",0x00003340,0xFFFFE9D9,0x00000516,0x00002332,0xFFFFF27A,0x000003F0,0x00002332,0xFFFFF27A,0x000003F0}, - {"0000001000010011111100001111111010011001000110100011100010100100",0x00003564,0xFFFFE86D,0x0000054E,0x00002613,0xFFFFF07C,0x00000444,0x00002613,0xFFFFF07C,0x00000444}, - {"0000001000010011111100001111111010011001001010000000100100000100",0x00002AD1,0xFFFFEF0B,0x0000045C,0x00001DEA,0xFFFFF5C8,0x00000381,0x00001DEA,0xFFFFF5C8,0x00000381}, - {"0000001000010011111100001111111010011001001000100010000011100100",0x000035B0,0xFFFFE846,0x00000555,0x000027BE,0xFFFFEF5D,0x00000474,0x000027BE,0xFFFFEF5D,0x00000474}, - {"0000001000010011111100001111111010011001001000100011100010100100",0x000032C4,0xFFFFEA48,0x00000502,0x000022C6,0xFFFFF2DF,0x000003DE,0x000022C6,0xFFFFF2DF,0x000003DE}, - {"0000001000010011111100001111111010011001001100000000100011000100",0x00003036,0xFFFFEB0D,0x000004F9,0x00001FE8,0xFFFFF41A,0x000003BC,0x00001FE8,0xFFFFF41A,0x000003BC}, - {"0000001000010011111100001111111010011001000110100000100100000100",0x000030F8,0xFFFFEA13,0x00000524,0x00001B6A,0xFFFFF6C9,0x0000034A,0x00001B6A,0xFFFFF6C9,0x0000034A}, - {"0000001000010011111100001111111010011001001100000001000010100100",0x00002EE2,0xFFFFEC0C,0x000004CB,0x00001A39,0xFFFFF814,0x0000030F,0x00001A39,0xFFFFF814,0x0000030F}, - {"0000001000010011111100001111111010011001000111000011000110000100",0x00003457,0xFFFFE924,0x0000052A,0x00001E9D,0xFFFFF59C,0x00000363,0x00001E9D,0xFFFFF59C,0x00000363}, - {"0000001000010011111100001111111010011001001100100010100001000100",0x000030BF,0xFFFFEB18,0x000004ED,0x00001D37,0xFFFFF636,0x0000035C,0x00001D37,0xFFFFF636,0x0000035C}, - {"0000001000010011111100001111111010011001001011100100000010000100",0x000031AF,0xFFFFEA75,0x000004FE,0x000019F2,0xFFFFF87A,0x000002F0,0x000019F2,0xFFFFF87A,0x000002F0}, - {"0000001000010011111100001111111010011001001100000010100010000100",0x00003642,0xFFFFE85B,0x00000547,0x00002975,0xFFFFEE98,0x0000048B,0x00002975,0xFFFFEE98,0x0000048B}, - {"0000001000010011111100001111111010011001001011100010100010000100",0x00002E8B,0xFFFFED1E,0x0000048E,0x000019C1,0xFFFFF917,0x000002D6,0x000019C1,0xFFFFF917,0x000002D6}, - {"0000001000010011111100001111111010011001001100100100000110100100",0x000033D9,0xFFFFE8E1,0x00000548,0x0000224B,0xFFFFF298,0x000003F4,0x0000224B,0xFFFFF298,0x000003F4}, - {"0000001000010011111100001111111010011001001011100010100011000100",0x000032BC,0xFFFFEB0F,0x000004D6,0x00002488,0xFFFFF240,0x000003F2,0x00002488,0xFFFFF240,0x000003F2}, - {"0000001000010011111100001111111010011001001100000100100101000100",0x000035FD,0xFFFFE838,0x00000553,0x00002762,0xFFFFEFBC,0x00000460,0x00002762,0xFFFFEFBC,0x00000460}, - {"0000001000010011111100001111111010011001001010000001100010100100",0x0000268B,0xFFFFF263,0x000003D1,0x00001914,0xFFFFF977,0x000002E8,0x00001914,0xFFFFF977,0x000002E8}, - {"0000001000010011111100001111111010011001001011000011000110000100",0x0000330B,0xFFFFEA1E,0x00000505,0x000020B1,0xFFFFF44D,0x0000039E,0x000020B1,0xFFFFF44D,0x0000039E}, - {"0000001000010011111100001111111010011001001000100010000010000100",0x0000326E,0xFFFFEA26,0x00000508,0x00001C17,0xFFFFF722,0x00000328,0x00001C17,0xFFFFF722,0x00000328}, - {"0000001000010011111100001111111010011001001010100011000110100100",0x00002A3F,0xFFFFEEE8,0x0000046D,0x00001B2B,0xFFFFF737,0x0000034D,0x00001B2B,0xFFFFF737,0x0000034D}, - {"0000001000010011111100001111111010011001001011000100000001100100",0x00003732,0xFFFFE765,0x00000574,0x00002A6D,0xFFFFEDA8,0x000004B7,0x00002A6D,0xFFFFEDA8,0x000004B7}, - {"0000001000010011111100001111111010011001001100000000100100100100",0x000034D3,0xFFFFE827,0x00000569,0x000027AA,0xFFFFEEE7,0x00000492,0x000027AA,0xFFFFEEE7,0x00000492}, - {"0000001000010011111100001111111010011001001011100100000011000100",0x00003306,0xFFFFEA39,0x000004FC,0x00001DCC,0xFFFFF655,0x00000344,0x00001DCC,0xFFFFF655,0x00000344}, - {"0000001000010011111100001111111010011001001010000010000001000100",0x00002A48,0xFFFFEFCA,0x00000439,0x00001DED,0xFFFFF60D,0x00000375,0x00001DED,0xFFFFF60D,0x00000375}, - {"0000001000010011111100001111111010011001001100000011100011000100",0x000033A3,0xFFFFEA36,0x000004F9,0x0000247C,0xFFFFF21F,0x000003F4,0x0000247C,0xFFFFF21F,0x000003F4}, - {"0000001000010011111100001111111010011001001011000011000101100100",0x0000311B,0xFFFFEB76,0x000004D1,0x00001EB1,0xFFFFF5B6,0x00000366,0x00001EB1,0xFFFFF5B6,0x00000366}, - {"0000001000010011111100001111111010011001001100100100000101100100",0x00003307,0xFFFFE97F,0x0000052A,0x00001E76,0xFFFFF54D,0x0000037C,0x00001E76,0xFFFFF54D,0x0000037C}, - {"0000001000010011111100001111111010011001000111000010000101000100",0x0000344B,0xFFFFE9C5,0x00000509,0x000020D6,0xFFFFF486,0x0000038F,0x000020D6,0xFFFFF486,0x0000038F}, - {"0000001000010011111100001111111010011001001011000011000101000100",0x000034B9,0xFFFFEA0B,0x000004F7,0x000027B3,0xFFFFF057,0x0000043A,0x000027B3,0xFFFFF057,0x0000043A}, - {"0000001000010011111100001111111010011001001100000001100101100100",0x00003360,0xFFFFE984,0x00000527,0x00002238,0xFFFFF2EE,0x000003E0,0x00002238,0xFFFFF2EE,0x000003E0}, - {"0000001000010011111100001111111010011001001100000010000100100100",0x0000315C,0xFFFFEC05,0x000004B1,0x000023C8,0xFFFFF2CC,0x000003DE,0x000023C8,0xFFFFF2CC,0x000003DE}, - {"0000001000010011111100001111111010011001001011000010100001100100",0x0000389B,0xFFFFE6D5,0x00000582,0x00002C6C,0xFFFFEC92,0x000004DE,0x00002C6C,0xFFFFEC92,0x000004DE}, - {"0000001000010011111100001111111010011001001011100001000100100100",0x00003058,0xFFFFEB30,0x000004E6,0x000019B5,0xFFFFF88B,0x000002F1,0x000019B5,0xFFFFF88B,0x000002F1}, - {"0000001000010011111100001111111010011001001011100000100100000100",0x00002F69,0xFFFFEB4A,0x000004F1,0x00001B82,0xFFFFF6EC,0x00000341,0x00001B82,0xFFFFF6EC,0x00000341}, - {"0000001000010011111100001111111010011001000110100001100011100100",0x000031EB,0xFFFFEA64,0x00000508,0x00002059,0xFFFFF427,0x000003B0,0x00002059,0xFFFFF427,0x000003B0}, - {"0000001000010011111100001111111010011001001000100100000100100100",0x000033E2,0xFFFFE94D,0x0000052A,0x000020BF,0xFFFFF40B,0x000003AB,0x000020BF,0xFFFFF40B,0x000003AB}, - {"0000001000010011111100001111111010011001001010000011000110000100",0x00002AF9,0xFFFFEFE9,0x00000427,0x00001F72,0xFFFFF57A,0x00000383,0x00001F72,0xFFFFF57A,0x00000383}, - {"0000001000010011111100001111111010011001001011000010100000100100",0x00003282,0xFFFFEA88,0x000004FA,0x00002561,0xFFFFF126,0x0000042B,0x00002561,0xFFFFF126,0x0000042B}, - {"0000001000010011111100001111111010011001001100000001000011100100",0x0000308A,0xFFFFEB5D,0x000004E0,0x00001E83,0xFFFFF577,0x00000378,0x00001E83,0xFFFFF577,0x00000378}, - {"0000001000010011111100001111111010011001001100100100100010000100",0x0000336E,0xFFFFE8C8,0x00000553,0x0000217C,0xFFFFF2E1,0x000003EB,0x0000217C,0xFFFFF2E1,0x000003EB}, - {"0000001000010011111100001111111010011001000110100010000101100100",0x000034A9,0xFFFFE838,0x00000561,0x000020CE,0xFFFFF38A,0x000003C7,0x000020CE,0xFFFFF38A,0x000003C7}, - {"0000001000010011111100001111111010011001001000100010000110000100",0x00003152,0xFFFFE9EB,0x00000522,0x00001755,0xFFFFF9A9,0x000002C6,0x00001755,0xFFFFF9A9,0x000002C6}, - {"0000001000010011111100001111111010011001001010000001100010000100",0x0000286E,0xFFFFF136,0x000003FD,0x00001BAB,0xFFFFF7C3,0x0000032C,0x00001BAB,0xFFFFF7C3,0x0000032C}, - {"0000001000010011111100001111111010011001001100000000100101000100",0x0000316B,0xFFFFEA02,0x00000528,0x00002247,0xFFFFF24E,0x00000408,0x00002247,0xFFFFF24E,0x00000408}, - {"0000001000010011111100001111111010011001001011000000100011100100",0x000034CF,0xFFFFE83D,0x00000562,0x00002458,0xFFFFF130,0x00000430,0x00002458,0xFFFFF130,0x00000430}, - {"0000001000010011111100001111111010011001001011000010100110000100",0x00003352,0xFFFFE9D1,0x00000515,0x0000212A,0xFFFFF3DC,0x000003B4,0x0000212A,0xFFFFF3DC,0x000003B4}, - {"0000001000010011111100001111111010011001001010000100000010100100",0x00002946,0xFFFFF09B,0x00000415,0x00001DC9,0xFFFFF650,0x00000366,0x00001DC9,0xFFFFF650,0x00000366}, - {"0000001000010011111100001111111010011001001100000001000100100100",0x00003080,0xFFFFEB47,0x000004E1,0x00001BD5,0xFFFFF73B,0x00000329,0x00001BD5,0xFFFFF73B,0x00000329}, - {"0000001000010011111100001111111010011001000110100001100010000100",0x00002FBD,0xFFFFEB7B,0x000004DD,0x000017FC,0xFFFFF99E,0x000002C7,0x000017FC,0xFFFFF99E,0x000002C7}, - {"0000001000010011111100001111111010011001001010000001000100100100",0x00002A28,0xFFFFF032,0x0000041F,0x00001B19,0xFFFFF83A,0x00000312,0x00001B19,0xFFFFF83A,0x00000312}, - {"0000001000010011111100001111111010011001001000100100000011000100",0x00003420,0xFFFFE936,0x00000530,0x000023C2,0xFFFFF203,0x00000406,0x000023C2,0xFFFFF203,0x00000406}, - {"0000001000010011111100001111111010011001001100000001000101000100",0x00002F7C,0xFFFFEBBA,0x000004D1,0x0000185D,0xFFFFF975,0x000002CA,0x0000185D,0xFFFFF975,0x000002CA}, - {"0000001000010011111100001111111010011001001011100010000001000100",0x00002C51,0xFFFFEE3B,0x0000046F,0x000019AA,0xFFFFF8DD,0x000002ED,0x000019AA,0xFFFFF8DD,0x000002ED}, - {"0000001000010011111100001111111010011001000110100100000101000100",0x000033D6,0xFFFFE8F2,0x0000053D,0x00001D73,0xFFFFF5FB,0x0000035B,0x00001D73,0xFFFFF5FB,0x0000035B}, - {"0000001000010011111100001111111010011001001100100011000010000100",0x000031D9,0xFFFFEAF7,0x000004E4,0x00001EBD,0xFFFFF5A6,0x00000368,0x00001EBD,0xFFFFF5A6,0x00000368}, - {"0000001000010011111100001111111010011001000110100010000010100100",0x00003386,0xFFFFE9CE,0x00000515,0x00002422,0xFFFFF1F3,0x00000405,0x00002422,0xFFFFF1F3,0x00000405}, - {"0000001000010011111100001111111010011001001011000101000011100100",0x000032FB,0xFFFFE9BC,0x00000520,0x00002301,0xFFFFF267,0x000003F7,0x00002301,0xFFFFF267,0x000003F7}, - {"0000001000010011111100001111111010011001001100100010100100100100",0x000032C2,0xFFFFEAC0,0x000004EA,0x0000250F,0xFFFFF1A2,0x00000413,0x0000250F,0xFFFFF1A2,0x00000413}, - {"0000001000010011111100001111111010011001000111000010100101000100",0x00003722,0xFFFFE8A6,0x00000527,0x000026E4,0xFFFFF0F5,0x0000041C,0x000026E4,0xFFFFF0F5,0x0000041C}, - {"0000001000010011111100001111111010011001001011000100100011000100",0x000035A4,0xFFFFE822,0x00000558,0x000022F2,0xFFFFF288,0x000003E8,0x000022F2,0xFFFFF288,0x000003E8}, - {"0000001000010011111100001111111010011001001010000000100100100100",0x00002CD1,0xFFFFEDC6,0x0000048C,0x00001EAF,0xFFFFF53D,0x00000396,0x00001EAF,0xFFFFF53D,0x00000396}, - {"0000001000010011111100001111111010011001001100000001000101100100",0x00003156,0xFFFFEA60,0x0000050B,0x00001BBC,0xFFFFF704,0x00000335,0x00001BBC,0xFFFFF704,0x00000335}, - {"0000001000010011111100001111111010011001001011000101000100000100",0x000034A1,0xFFFFE8C0,0x00000544,0x00002528,0xFFFFF105,0x0000042C,0x00002528,0xFFFFF105,0x0000042C}, - {"0000001000010011111100001111111010011001001100100011000001100100",0x000032CE,0xFFFFE9D3,0x00000520,0x000021FF,0xFFFFF2FD,0x000003E4,0x000021FF,0xFFFFF2FD,0x000003E4}, - {"0000001000010011111100001111111010011001000110100101000010100100",0x000034A0,0xFFFFE823,0x0000056D,0x0000256F,0xFFFFF047,0x0000045A,0x0000256F,0xFFFFF047,0x0000045A}, - {"0000001000010011111100001111111010011001001100000011100101000100",0x00003109,0xFFFFEBD6,0x000004BF,0x000022D4,0xFFFFF32D,0x000003D0,0x000022D4,0xFFFFF32D,0x000003D0}, - {"0000001000010011111100001111111010011001001011000001000101100100",0x000030B7,0xFFFFEAF0,0x000004F3,0x00001AEC,0xFFFFF7A9,0x0000031B,0x00001AEC,0xFFFFF7A9,0x0000031B}, - {"0000001000010011111100001111111010011001001011000011100110100100",0x00003078,0xFFFFEBA4,0x000004CF,0x00001E7A,0xFFFFF5AF,0x0000036B,0x00001E7A,0xFFFFF5AF,0x0000036B}, - {"0000001000010011111100001111111010011001001100000100000100100100",0x00003442,0xFFFFE998,0x00000518,0x000025EA,0xFFFFF0F3,0x0000042B,0x000025EA,0xFFFFF0F3,0x0000042B}, - {"0000001000010011111100001111111010011001001100000010000110100100",0x000031CB,0xFFFFEA80,0x00000501,0x000020A3,0xFFFFF403,0x000003B2,0x000020A3,0xFFFFF403,0x000003B2}, - {"0000001000010011111100001111111010011001001010100010100110000100",0x00002947,0xFFFFF018,0x00000433,0x00001BA5,0xFFFFF75C,0x00000340,0x00001BA5,0xFFFFF75C,0x00000340}, - {"0000001000010011111100001111111010011001001011000011100110000100",0x000033F9,0xFFFFE99D,0x00000518,0x00002231,0xFFFFF358,0x000003C5,0x00002231,0xFFFFF358,0x000003C5}, - {"0000001000010011111100001111111010011001001100100001000100100100",0x00003131,0xFFFFEA45,0x00000513,0x00001973,0xFFFFF85E,0x00000301,0x00001973,0xFFFFF85E,0x00000301}, - {"0000001000010011111100001111111010011001000111000010100110100100",0x00003571,0xFFFFE8AC,0x00000539,0x00002049,0xFFFFF49C,0x0000038D,0x00002049,0xFFFFF49C,0x0000038D}, - {"0000001000010011111100001111111010011001001011100011100001100100",0x0000309E,0xFFFFEB1D,0x000004E8,0x000019ED,0xFFFFF86E,0x000002F8,0x000019ED,0xFFFFF86E,0x000002F8}, - {"0000001000010011111100001111111010011001001100000010100110000100",0x00003091,0xFFFFEB9B,0x000004CC,0x00001D2C,0xFFFFF6A2,0x0000033D,0x00001D2C,0xFFFFF6A2,0x0000033D}, - {"0000001000010011111100001111111010011001001100000000100011100100",0x00003069,0xFFFFEAFD,0x000004F8,0x00001E82,0xFFFFF51C,0x0000038D,0x00001E82,0xFFFFF51C,0x0000038D}, - {"0000001000010011111100001111111010011001001000100001000010100100",0x00003459,0xFFFFE7F2,0x00000572,0x00001DA7,0xFFFFF552,0x0000037F,0x00001DA7,0xFFFFF552,0x0000037F}, - {"0000001000010011111100001111111010011001001100100001000100000100",0x0000304B,0xFFFFEAFB,0x000004F4,0x0000191E,0xFFFFF8BD,0x000002EE,0x0000191E,0xFFFFF8BD,0x000002EE}, - {"0000001000010011111100001111111010011001001100000010000011000100",0x0000346E,0xFFFFEA07,0x000004FD,0x00002767,0xFFFFF058,0x00000440,0x00002767,0xFFFFF058,0x00000440}, - {"0000001000010011111100001111111010011001001011100011000010000100",0x000030B5,0xFFFFEBC1,0x000004C1,0x00001B3C,0xFFFFF818,0x000002FD,0x00001B3C,0xFFFFF818,0x000002FD}, - {"0000001000010011111100001111111010011001001100000000100100000100",0x0000321F,0xFFFFE9EA,0x00000524,0x00002380,0xFFFFF1C2,0x0000041A,0x00002380,0xFFFFF1C2,0x0000041A}, - {"0000001000010011111100001111111010011001001011100011000001000100",0x000030DF,0xFFFFEB37,0x000004E2,0x00001E3C,0xFFFFF5BB,0x00000369,0x00001E3C,0xFFFFF5BB,0x00000369}, - {"0000001000010011111100001111111010011001001010000100100010100100",0x000027E0,0xFFFFF0E2,0x00000416,0x00001A6A,0xFFFFF820,0x00000321,0x00001A6A,0xFFFFF820,0x00000321}, - {"0000001000010011111100001111111010011001000110100001000010000100",0x00002FA1,0xFFFFEB63,0x000004E7,0x0000196B,0xFFFFF880,0x000002FB,0x0000196B,0xFFFFF880,0x000002FB}, - {"0000001000010011111100001111111010011001000111000001000010000100",0x0000310C,0xFFFFEAAF,0x000004FC,0x000019EF,0xFFFFF850,0x000002FD,0x000019EF,0xFFFFF850,0x000002FD}, - {"0000001000010011111100001111111010011001001100100011100100000100",0x0000334A,0xFFFFEA07,0x0000050B,0x00002380,0xFFFFF26F,0x000003F0,0x00002380,0xFFFFF26F,0x000003F0}, - {"0000001000010011111100001111111010011001001100000010100101000100",0x00002FF9,0xFFFFECDC,0x00000492,0x00002297,0xFFFFF394,0x000003BF,0x00002297,0xFFFFF394,0x000003BF}, - {"0000001000010011111100001111111010011001001011000010000101100100",0x0000354B,0xFFFFE894,0x00000546,0x000024C4,0xFFFFF16C,0x0000041B,0x000024C4,0xFFFFF16C,0x0000041B}, - {"0000001000010011111100001111111010011001001000100000100100100100",0x00003245,0xFFFFE92F,0x00000544,0x00001829,0xFFFFF8F1,0x000002EA,0x00001829,0xFFFFF8F1,0x000002EA}, - {"0000001000010011111100001111111010011001001011100100100010000100",0x0000302F,0xFFFFEB51,0x000004E3,0x0000199F,0xFFFFF894,0x000002F4,0x0000199F,0xFFFFF894,0x000002F4}, - {"0000001000010011111100001111111010011001001011100001100011000100",0x00002F54,0xFFFFEC86,0x000004A6,0x00001A6F,0xFFFFF891,0x000002EC,0x00001A6F,0xFFFFF891,0x000002EC}, - {"0000001000010011111100001111111010011001001010000100000101100100",0x00002908,0xFFFFF0D8,0x0000040A,0x00001C9B,0xFFFFF729,0x00000342,0x00001C9B,0xFFFFF729,0x00000342}, - {"0000001000010011111100001111111010011001001100000010100101100100",0x000031D9,0xFFFFEB40,0x000004D7,0x000023F5,0xFFFFF259,0x000003F4,0x000023F5,0xFFFFF259,0x000003F4}, - {"0000001000010011111100001111111010011001001100000100100011100100",0x000034C8,0xFFFFE8C6,0x0000053F,0x00002313,0xFFFFF280,0x000003EC,0x00002313,0xFFFFF280,0x000003EC}, - {"0000001000010011111100001111111010011001001100000101000011000100",0x000037D1,0xFFFFE6A1,0x0000059C,0x00002C6A,0xFFFFEBFF,0x00000504,0x00002C6A,0xFFFFEBFF,0x00000504}, - {"0000001000010011111100001111111010011001001100100001100101100100",0x000030E9,0xFFFFEA6B,0x0000050F,0x00001A2D,0xFFFFF7DF,0x00000316,0x00001A2D,0xFFFFF7DF,0x00000316}, - {"0000001000010011111100001111111010011001001100000010000010000100",0x0000323D,0xFFFFEA95,0x000004F4,0x00001ED2,0xFFFFF584,0x0000036C,0x00001ED2,0xFFFFF584,0x0000036C}, - {"0000001000010011111100001111111010011001001011000011000000100100",0x000033D6,0xFFFFE9DB,0x00000510,0x000027A7,0xFFFFEFC7,0x0000045E,0x000027A7,0xFFFFEFC7,0x0000045E}, - {"0000001000010011111100001111111010011001000111000011000101100100",0x00003444,0xFFFFE98A,0x00000517,0x000020FD,0xFFFFF43F,0x0000039D,0x000020FD,0xFFFFF43F,0x0000039D}, - {"0000001000010011111100001111111010011001001010000000100011100100",0x00002987,0xFFFFEFA1,0x0000044B,0x00001B06,0xFFFFF788,0x0000033C,0x00001B06,0xFFFFF788,0x0000033C}, - {"0000001000010011111100001111111010011001001011000010100011100100",0x0000311D,0xFFFFED20,0x00000474,0x000025DA,0xFFFFF223,0x000003F0,0x000025DA,0xFFFFF223,0x000003F0}, - {"0000001000010011111100001111111010011001001011000001000100100100",0x000032A2,0xFFFFEA0A,0x0000050D,0x00001D48,0xFFFFF659,0x0000034A,0x00001D48,0xFFFFF659,0x0000034A}, - {"0000001000010011111100001111111010011001001000100000100011100100",0x00003110,0xFFFFE9EA,0x00000529,0x00001786,0xFFFFF958,0x000002DB,0x00001786,0xFFFFF958,0x000002DB}, - {"0000001000010011111100001111111010011001001010000010000110100100",0x000027F2,0xFFFFF174,0x000003F7,0x00001C7A,0xFFFFF72A,0x00000348,0x00001C7A,0xFFFFF72A,0x00000348}, - {"0000001000010011111100001111111010011001000111000001000011100100",0x000031DB,0xFFFFEA7D,0x000004FB,0x000019C4,0xFFFFF8B1,0x000002E6,0x000019C4,0xFFFFF8B1,0x000002E6}, - {"0000001000010011111100001111111010011001001011000001000100000100",0x00003158,0xFFFFEAAC,0x000004FA,0x00001BC1,0xFFFFF737,0x0000032B,0x00001BC1,0xFFFFF737,0x0000032B}, - {"0000001000010011111100001111111010011001001100000001000011000100",0x00002F36,0xFFFFEBF9,0x000004CA,0x00001A2A,0xFFFFF83F,0x00000303,0x00001A2A,0xFFFFF83F,0x00000303}, - {"0000001000010011111100001111111010011001001100100011100010100100",0x000032B4,0xFFFFEA72,0x000004FA,0x000021FF,0xFFFFF378,0x000003C5,0x000021FF,0xFFFFF378,0x000003C5}, - {"0000001000010011111100001111111010011001001100000011000101100100",0x00003262,0xFFFFEAFA,0x000004DF,0x00002441,0xFFFFF237,0x000003F6,0x00002441,0xFFFFF237,0x000003F6}, - {"0000001000010011111100001111111010011001001100000011100100100100",0x0000336A,0xFFFFEAFB,0x000004D1,0x00002746,0xFFFFF0B8,0x0000042B,0x00002746,0xFFFFF0B8,0x0000042B}, - {"0000001000010011111100001111111010011001000110100100000010000100",0x000032E5,0xFFFFE923,0x00000541,0x00001DF0,0xFFFFF552,0x00000380,0x00001DF0,0xFFFFF552,0x00000380}, - {"0000001000010011111100001111111010011001001100000100000001100100",0x000035D1,0xFFFFE80B,0x0000055F,0x00002780,0xFFFFEF74,0x0000046F,0x00002780,0xFFFFEF74,0x0000046F}, - {"0000001000010011111100001111111010011001001100000010100010100100",0x000033EC,0xFFFFEA48,0x000004F4,0x0000269F,0xFFFFF0D8,0x0000042A,0x0000269F,0xFFFFF0D8,0x0000042A}, - {"0000001000010011111100001111111010011001001100100011100010000100",0x000030C4,0xFFFFEB39,0x000004E2,0x00001B44,0xFFFFF7AA,0x00000318,0x00001B44,0xFFFFF7AA,0x00000318}, - {"0000001000010011111100001111111010011001001010000001000101000100",0x00002926,0xFFFFF0AF,0x0000040E,0x0000194E,0xFFFFF959,0x000002E2,0x0000194E,0xFFFFF959,0x000002E2}, - {"0000001000010011111100001111111010011001001011000001000011000100",0x00003141,0xFFFFEAAF,0x000004F6,0x00001864,0xFFFFF97C,0x000002C6,0x00001864,0xFFFFF97C,0x000002C6}, - {"0000001000010011111100001111111010011001001100000001000001100100",0x000030B2,0xFFFFEB7C,0x000004DB,0x000022CE,0xFFFFF2B5,0x000003F0,0x000022CE,0xFFFFF2B5,0x000003F0}, - {"0000001000010011111100001111111010011001001100000001100101000100",0x0000318C,0xFFFFEAC7,0x000004F6,0x00002113,0xFFFFF3CA,0x000003BD,0x00002113,0xFFFFF3CA,0x000003BD}, - {"0000001000010011111100001111111010011001001011100001000100000100",0x00002FD2,0xFFFFEB8F,0x000004D9,0x00001996,0xFFFFF89F,0x000002F1,0x00001996,0xFFFFF89F,0x000002F1}, - {"0000001000010011111100001111111010011001000110100010100010100100",0x0000310D,0xFFFFEB25,0x000004E7,0x00001F67,0xFFFFF4EF,0x0000038E,0x00001F67,0xFFFFF4EF,0x0000038E}, - {"0000001000010011111100001111111010011001001010100100100101100100",0x00002BBC,0xFFFFEE68,0x00000477,0x00002050,0xFFFFF41D,0x000003C8,0x00002050,0xFFFFF41D,0x000003C8}, - {"0000001000010011111100001111111010011001001100000010000100000100",0x00003096,0xFFFFECED,0x00000486,0x000024C9,0xFFFFF278,0x000003E7,0x000024C9,0xFFFFF278,0x000003E7}, - {"0000001000010011111100001111111010011001001011000001000010100100",0x00003401,0xFFFFE8F1,0x0000053C,0x00001E75,0xFFFFF55C,0x00000376,0x00001E75,0xFFFFF55C,0x00000376}, - {"0000001000010011111100001111111010011001001100000010100001000100",0x0000319E,0xFFFFEAB1,0x000004F8,0x00001EA3,0xFFFFF567,0x00000378,0x00001EA3,0xFFFFF567,0x00000378}, - {"0000001000010011111100001111111010011001001100100010100101100100",0x000030FD,0xFFFFEB4C,0x000004DB,0x00001CA6,0xFFFFF6E8,0x00000335,0x00001CA6,0xFFFFF6E8,0x00000335}, - {"0000001000010011111100001111111010011001001011100100000010100100",0x000030D6,0xFFFFEB1A,0x000004E4,0x00001A0D,0xFFFFF87D,0x000002EF,0x00001A0D,0xFFFFF87D,0x000002EF}, - {"0000001000010011111100001111111010011001001011000010000100100100",0x0000324B,0xFFFFEB17,0x000004D9,0x00002225,0xFFFFF3A8,0x000003BA,0x00002225,0xFFFFF3A8,0x000003BA}, - {"0000001000010011111100001111111010011001001010000100000010000100",0x00002A00,0xFFFFF02E,0x00000424,0x00001E21,0xFFFFF61D,0x0000036C,0x00001E21,0xFFFFF61D,0x0000036C}, - {"0000001000010011111100001111111010011001001010100100100010100100",0x000029CF,0xFFFFEF53,0x00000457,0x00001B11,0xFFFFF772,0x0000033D,0x00001B11,0xFFFFF772,0x0000033D}, - {"0000001000010011111100001111111010011001000110100011000010100100",0x000032A1,0xFFFFEA63,0x000004FB,0x00001F83,0xFFFFF516,0x0000037E,0x00001F83,0xFFFFF516,0x0000037E}, - {"0000001000010011111100001111111010011001001011100010000011000100",0x0000305C,0xFFFFEC14,0x000004B5,0x00001D0B,0xFFFFF6ED,0x00000332,0x00001D0B,0xFFFFF6ED,0x00000332}, - {"0000001000010011111100001111111010011001001011000001000001100100",0x00003467,0xFFFFE8D5,0x00000543,0x0000243F,0xFFFFF190,0x00000418,0x0000243F,0xFFFFF190,0x00000418}, - {"0000001000010011111100001111111010011001001010100010000001100100",0x00002796,0xFFFFF133,0x00000409,0x00001903,0xFFFFF91C,0x000002FC,0x00001903,0xFFFFF91C,0x000002FC}, - {"0000001000010011111100001111111010011001001100000010000101100100",0x000031F6,0xFFFFEAB7,0x000004F5,0x000022B9,0xFFFFF2D0,0x000003E6,0x000022B9,0xFFFFF2D0,0x000003E6}, - {"0000001000010011111100001111111010011001001011100101000100000100",0x00003196,0xFFFFEA76,0x00000503,0x00001CC5,0xFFFFF67D,0x0000034A,0x00001CC5,0xFFFFF67D,0x0000034A}, - {"0000001000010011111100001111111010011001001100100001000101000100",0x00002F9E,0xFFFFEAD9,0x00000505,0x000017C1,0xFFFFF93D,0x000002DF,0x000017C1,0xFFFFF93D,0x000002DF}, - {"0000001000010011111100001111111010011001001011100010000100100100",0x00002FBC,0xFFFFEC75,0x000004A8,0x00001D6D,0xFFFFF6AC,0x0000033D,0x00001D6D,0xFFFFF6AC,0x0000033D}, - {"0000001000010011111100001111111010011001001011000011100010100100",0x00003541,0xFFFFE921,0x00000524,0x00002662,0xFFFFF0CB,0x0000042B,0x00002662,0xFFFFF0CB,0x0000042B}, - {"0000001000010011111100001111111010011001001010100010000110100100",0x00002953,0xFFFFEF76,0x00000459,0x00001C05,0xFFFFF6A0,0x00000368,0x00001C05,0xFFFFF6A0,0x00000368}, - {"0000001000010011111100001111111010011001001011000100100100100100",0x000034BC,0xFFFFE8DD,0x00000536,0x0000210E,0xFFFFF3F4,0x000003A8,0x0000210E,0xFFFFF3F4,0x000003A8}, - {"0000001000010011111100001111111010011001001011000010100110100100",0x000034BE,0xFFFFE916,0x0000052F,0x000024A1,0xFFFFF1A6,0x00000410,0x000024A1,0xFFFFF1A6,0x00000410}, - {"0000001000010011111100001111111010011001001100000100100101100100",0x000037B5,0xFFFFE7A9,0x0000055B,0x000028A1,0xFFFFEF51,0x00000467,0x000028A1,0xFFFFEF51,0x00000467}, - {"0000001000010011111100001111111010011001001100000001000100000100",0x00002FC5,0xFFFFEBBE,0x000004D1,0x00001BA5,0xFFFFF757,0x00000328,0x00001BA5,0xFFFFF757,0x00000328}, - {"0000001000010011111100001111111010011001001100000100000010100100",0x000033CB,0xFFFFE944,0x0000052B,0x00001FBE,0xFFFFF4B1,0x0000038C,0x00001FBE,0xFFFFF4B1,0x0000038C}, - {"0000001000010011111100001111111010011001001100000001100001000100",0x000030AE,0xFFFFEBA0,0x000004D3,0x00002268,0xFFFFF316,0x000003DD,0x00002268,0xFFFFF316,0x000003DD}, - {"0000001000010011111100001111111010011001001011000010000010100100",0x00002F90,0xFFFFEC5A,0x000004B0,0x00001C3A,0xFFFFF752,0x00000323,0x00001C3A,0xFFFFF752,0x00000323}, - {"0000001000010011111100001111111010011001001011100011100011100100",0x00003113,0xFFFFEB91,0x000004C8,0x00001E3C,0xFFFFF623,0x0000034E,0x00001E3C,0xFFFFF623,0x0000034E}, - {"0000001000010011111100001111111010011001001100100011100110000100",0x0000330B,0xFFFFE94B,0x00000539,0x000020E7,0xFFFFF37E,0x000003CD,0x000020E7,0xFFFFF37E,0x000003CD}, - {"0000001000010011111100001111111010011001001011100010100001100100",0x000031D1,0xFFFFEACB,0x000004ED,0x00001E82,0xFFFFF5B2,0x00000365,0x00001E82,0xFFFFF5B2,0x00000365}, - {"0000001000010011111100001111111010011001001010100011100110000100",0x00002CD5,0xFFFFEDC1,0x0000048D,0x000020F8,0xFFFFF3C1,0x000003D1,0x000020F8,0xFFFFF3C1,0x000003D1}, - { NULL ,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000} + { 0x0213EA94DE0E4964, 0x00003C96, 0xFFFFE226, 0x00000656, 0x00002203, 0xFFFFF201, 0x000003FF, 0x00002203, 0xFFFFF201, 0x000003FF }, + { 0x0213EA94DE0A1884, 0x00003CC5, 0xFFFFE23A, 0x0000064E, 0x00002258, 0xFFFFF1F7, 0x000003FC, 0x00002258, 0xFFFFF1F7, 0x000003FC }, + { 0x0213EA94DE0E31A4, 0x00003CAF, 0xFFFFE36E, 0x00000602, 0x00001E98, 0xFFFFF569, 0x00000357, 0x00001E98, 0xFFFFF569, 0x00000357 }, + { 0x0213EA94DE2C1144, 0x0000391A, 0xFFFFE548, 0x000005C9, 0x00001B98, 0xFFFFF707, 0x00000324, 0x00001B98, 0xFFFFF707, 0x00000324 }, + { 0x0213EA94DE2C18C4, 0x00003821, 0xFFFFE674, 0x00000597, 0x00002196, 0xFFFFF361, 0x000003C0, 0x00002196, 0xFFFFF361, 0x000003C0 }, + { 0x0213EA94DE263884, 0x000044A2, 0xFFFFDCB7, 0x00000738, 0x0000325C, 0xFFFFE6A7, 0x000005E6, 0x0000325C, 0xFFFFE6A7, 0x000005E6 }, + { 0x0213EA94DE082924, 0x00004057, 0xFFFFE1CF, 0x0000063C, 0x00002E2E, 0xFFFFEB62, 0x000004FD, 0x00002E2E, 0xFFFFEB62, 0x000004FD }, + { 0x0213EA94DE284924, 0x00003FD0, 0xFFFFDF0F, 0x000006E5, 0x0000267C, 0xFFFFEE2D, 0x000004AB, 0x0000267C, 0xFFFFEE2D, 0x000004AB }, + { 0x0213EA94DE280904, 0x00003F13, 0xFFFFE010, 0x000006AD, 0x000020E7, 0xFFFFF266, 0x000003EC, 0x000020E7, 0xFFFFF266, 0x000003EC }, + { 0x0213EA94DE082044, 0x00004088, 0xFFFFDFAB, 0x000006B6, 0x0000252B, 0xFFFFEFDB, 0x00000458, 0x0000252B, 0xFFFFEFDB, 0x00000458 }, + { 0x0213EA94DE283884, 0x00003EF6, 0xFFFFE017, 0x000006AA, 0x00001F67, 0xFFFFF369, 0x000003BE, 0x00001F67, 0xFFFFF369, 0x000003BE }, + { 0x0213EA94DE2C2184, 0x00003CDD, 0xFFFFE2A7, 0x0000063C, 0x000026C6, 0xFFFFEF38, 0x00000478, 0x000026C6, 0xFFFFEF38, 0x00000478 }, + { 0x0213EA94DE105124, 0x00003FA8, 0xFFFFDF02, 0x000006F0, 0x000027FE, 0xFFFFECF6, 0x000004EA, 0x000027FE, 0xFFFFECF6, 0x000004EA }, + { 0x0213EA94DE2638C4, 0x00004670, 0xFFFFDC40, 0x00000742, 0x00003A7A, 0xFFFFE1A7, 0x000006B6, 0x00003A7A, 0xFFFFE1A7, 0x000006B6 }, + { 0x0213EA94DE2C3024, 0x00003CDC, 0xFFFFE18C, 0x00000683, 0x00002A69, 0xFFFFEBE7, 0x00000515, 0x00002A69, 0xFFFFEBE7, 0x00000515 }, + { 0x0213EA94DE0E38C4, 0x00003CEC, 0xFFFFE38E, 0x00000601, 0x00002752, 0xFFFFEFA7, 0x00000453, 0x00002752, 0xFFFFEFA7, 0x00000453 }, + { 0x0213EA94DE2C1124, 0x000037D0, 0xFFFFE634, 0x000005A7, 0x00001CD2, 0xFFFFF644, 0x00000348, 0x00001CD2, 0xFFFFF644, 0x00000348 }, + { 0x0213EA94DE283964, 0x00003DF5, 0xFFFFE0A5, 0x00000698, 0x00001FD5, 0xFFFFF30E, 0x000003D1, 0x00001FD5, 0xFFFFF30E, 0x000003D1 }, + { 0x0213EA94DE0828C4, 0x00004201, 0xFFFFE03E, 0x00000688, 0x00003206, 0xFFFFE852, 0x0000058A, 0x00003206, 0xFFFFE852, 0x0000058A }, + { 0x0213EA94DE2C1864, 0x00003BED, 0xFFFFE2F5, 0x00000638, 0x0000270D, 0xFFFFEED0, 0x0000048E, 0x0000270D, 0xFFFFEED0, 0x0000048E }, + { 0x0213EA94DE0A1904, 0x00003E82, 0xFFFFE1BE, 0x00000654, 0x000025FB, 0xFFFFEFFA, 0x00000448, 0x000025FB, 0xFFFFEFFA, 0x00000448 }, + { 0x0213EA94DE2C40C4, 0x00003962, 0xFFFFE4B9, 0x000005EF, 0x00002385, 0xFFFFF156, 0x00000423, 0x00002385, 0xFFFFF156, 0x00000423 }, + { 0x0213EA94DE2C0944, 0x00003D88, 0xFFFFE21A, 0x00000655, 0x0000295A, 0xFFFFED68, 0x000004C4, 0x0000295A, 0xFFFFED68, 0x000004C4 }, + { 0x0213EA94DE2C1104, 0x00003AA4, 0xFFFFE4A3, 0x000005E0, 0x000022EF, 0xFFFFF250, 0x000003EB, 0x000022EF, 0xFFFFF250, 0x000003EB }, + { 0x0213EA94DE0E29A4, 0x00003D97, 0xFFFFE30D, 0x0000060D, 0x0000205D, 0xFFFFF45D, 0x00000380, 0x0000205D, 0xFFFFF45D, 0x00000380 }, + { 0x0213EA94DE2C40A4, 0x000039B6, 0xFFFFE446, 0x00000605, 0x00002325, 0xFFFFF16C, 0x0000041F, 0x00002325, 0xFFFFF16C, 0x0000041F }, + { 0x0213EA94DE263904, 0x0000457E, 0xFFFFDCF6, 0x00000722, 0x00003972, 0xFFFFE27B, 0x0000068E, 0x00003972, 0xFFFFE27B, 0x0000068E }, + { 0x0213EA94DE0A1924, 0x00003FB8, 0xFFFFE101, 0x00000670, 0x00002787, 0xFFFFEEF5, 0x00000471, 0x00002787, 0xFFFFEEF5, 0x00000471 }, + { 0x0213EA94DE0E38A4, 0x00003BB2, 0xFFFFE430, 0x000005EA, 0x000024A5, 0xFFFFF162, 0x00000409, 0x000024A5, 0xFFFFF162, 0x00000409 }, + { 0x0213EA94DE082144, 0x00003EC5, 0xFFFFE1BD, 0x0000064F, 0x000022F0, 0xFFFFF227, 0x000003E8, 0x000022F0, 0xFFFFF227, 0x000003E8 }, + { 0x0213EA94DE2C3164, 0x000038A7, 0xFFFFE59F, 0x000005C1, 0x000021CC, 0xFFFFF2DF, 0x000003D9, 0x000021CC, 0xFFFFF2DF, 0x000003D9 }, + { 0x0213EA94DE324184, 0x00002995, 0xFFFFEF7A, 0x0000044C, 0x00001552, 0xFFFFFB5D, 0x00000292, 0x00001552, 0xFFFFFB5D, 0x00000292 }, + { 0x0213EA94DE2C4064, 0x00003B26, 0xFFFFE2D3, 0x00000649, 0x000023B4, 0xFFFFF09B, 0x00000449, 0x000023B4, 0xFFFFF09B, 0x00000449 }, + { 0x0213EA94DE081124, 0x000040D2, 0xFFFFE00A, 0x00000696, 0x000022DA, 0xFFFFF1E9, 0x000003F2, 0x000022DA, 0xFFFFF1E9, 0x000003F2 }, + { 0x0213EA94DE2C3924, 0x00003C98, 0xFFFFE365, 0x00000618, 0x00002D5D, 0xFFFFEB3A, 0x0000051D, 0x00002D5D, 0xFFFFEB3A, 0x0000051D }, + { 0x0213EA94DE2C10A4, 0x00003BBD, 0xFFFFE37E, 0x00000617, 0x0000252E, 0xFFFFF06E, 0x00000441, 0x0000252E, 0xFFFFF06E, 0x00000441 }, + { 0x0213EA94DE262924, 0x00004363, 0xFFFFDF7A, 0x000006A0, 0x000031F5, 0xFFFFE880, 0x0000057B, 0x000031F5, 0xFFFFE880, 0x0000057B }, + { 0x0213EA94DE0E3844, 0x00003CFC, 0xFFFFE2AF, 0x0000062E, 0x0000212A, 0xFFFFF335, 0x000003BF, 0x0000212A, 0xFFFFF335, 0x000003BF }, + { 0x0213EA94DE1C4924, 0x0000252D, 0xFFFFF31B, 0x000003C3, 0x00001A1A, 0xFFFFF882, 0x00000325, 0x00001A1A, 0xFFFFF882, 0x00000325 }, + { 0x0213EA94DE0A29A4, 0x00003FE2, 0xFFFFDFEF, 0x000006AC, 0x000025A2, 0xFFFFEF84, 0x00000462, 0x000025A2, 0xFFFFEF84, 0x00000462 }, + { 0x0213EA94DE0820E4, 0x000040A5, 0xFFFFE13B, 0x0000065B, 0x00002C13, 0xFFFFEC75, 0x000004D7, 0x00002C13, 0xFFFFEC75, 0x000004D7 }, + { 0x0213EA94DE0E48A4, 0x00003E42, 0xFFFFE1B3, 0x00000657, 0x0000221D, 0xFFFFF273, 0x000003DE, 0x0000221D, 0xFFFFF273, 0x000003DE }, + { 0x0213EA94DE0A20E4, 0x00003E7F, 0xFFFFE255, 0x00000638, 0x00002D30, 0xFFFFEB8A, 0x00000503, 0x00002D30, 0xFFFFEB8A, 0x00000503 }, + { 0x0213EA94DE2C29C4, 0x00003E56, 0xFFFFE16D, 0x00000670, 0x000028DC, 0xFFFFEDA0, 0x000004BA, 0x000028DC, 0xFFFFEDA0, 0x000004BA }, + { 0x0213EA94DE2630A4, 0x000044AD, 0xFFFFDE24, 0x000006DD, 0x000031AD, 0xFFFFE850, 0x00000585, 0x000031AD, 0xFFFFE850, 0x00000585 }, + { 0x0213EA94DE2C20E4, 0x00003AF3, 0xFFFFE5B0, 0x000005A6, 0x00002CF6, 0xFFFFEC75, 0x000004DD, 0x00002CF6, 0xFFFFEC75, 0x000004DD }, + { 0x0213EA94DE0A2084, 0x00003E66, 0xFFFFE19E, 0x0000065B, 0x00002332, 0xFFFFF1B9, 0x000003FD, 0x00002332, 0xFFFFF1B9, 0x000003FD }, + { 0x0213EA94DE082884, 0x00003FB4, 0xFFFFE0A5, 0x00000686, 0x0000253E, 0xFFFFF02E, 0x00000444, 0x0000253E, 0xFFFFF02E, 0x00000444 }, + { 0x0213EA94DE2818A4, 0x00003E28, 0xFFFFE14D, 0x0000066E, 0x00001FE2, 0xFFFFF39A, 0x000003B1, 0x00001FE2, 0xFFFFF39A, 0x000003B1 }, + { 0x0213EA94DE2C0904, 0x000039E6, 0xFFFFE44B, 0x000005FE, 0x0000210C, 0xFFFFF2F4, 0x000003DA, 0x0000210C, 0xFFFFF2F4, 0x000003DA }, + { 0x0213EA94DE2C5104, 0x00003A4D, 0xFFFFE252, 0x0000067A, 0x000027E2, 0xFFFFECED, 0x000004FA, 0x000027E2, 0xFFFFECED, 0x000004FA }, + { 0x0213EA94DE0A2964, 0x00004065, 0xFFFFE02F, 0x0000069B, 0x0000299D, 0xFFFFED38, 0x000004C2, 0x0000299D, 0xFFFFED38, 0x000004C2 }, + { 0x0213EA94DE0E20A4, 0x000039EE, 0xFFFFE603, 0x00000594, 0x0000214F, 0xFFFFF429, 0x0000038E, 0x0000214F, 0xFFFFF429, 0x0000038E }, + { 0x0213EA94DE0E48E4, 0x00003BD2, 0xFFFFE351, 0x00000618, 0x000020B8, 0xFFFFF377, 0x000003B4, 0x000020B8, 0xFFFFF377, 0x000003B4 }, + { 0x0213EA94DE0A3124, 0x00003FAA, 0xFFFFE183, 0x0000065E, 0x000032AE, 0xFFFFE7C2, 0x000005A6, 0x000032AE, 0xFFFFE7C2, 0x000005A6 }, + { 0x0213EA94DE2C2984, 0x00003AFB, 0xFFFFE3E4, 0x00000608, 0x00002293, 0xFFFFF21F, 0x000003FA, 0x00002293, 0xFFFFF21F, 0x000003FA }, + { 0x0213EA94DE262064, 0x0000448B, 0xFFFFDD5D, 0x0000070D, 0x00002E4E, 0xFFFFE9DF, 0x00000551, 0x00002E4E, 0xFFFFE9DF, 0x00000551 }, + { 0x0213EA94DE0E2184, 0x00003D46, 0xFFFFE39B, 0x000005F3, 0x0000218E, 0xFFFFF3CD, 0x00000398, 0x0000218E, 0xFFFFF3CD, 0x00000398 }, + { 0x0213EA94DE0848E4, 0x00003F01, 0xFFFFDFD9, 0x000006BF, 0x000023AF, 0xFFFFF04E, 0x0000044C, 0x000023AF, 0xFFFFF04E, 0x0000044C }, + { 0x0213EA94DE1029A4, 0x0000403D, 0xFFFFDF6B, 0x000006C9, 0x0000270D, 0xFFFFEE4B, 0x0000049E, 0x0000270D, 0xFFFFEE4B, 0x0000049E }, + { 0x0213EA94DE0E3964, 0x00003C11, 0xFFFFE35C, 0x00000613, 0x000020F9, 0xFFFFF365, 0x000003B9, 0x000020F9, 0xFFFFF365, 0x000003B9 }, + { 0x0213EA94DE2C3884, 0x00003B58, 0xFFFFE37D, 0x0000061F, 0x00002698, 0xFFFFEF46, 0x00000478, 0x00002698, 0xFFFFEF46, 0x00000478 }, + { 0x0213EA94DE2841A4, 0x00003EBC, 0xFFFFDF7A, 0x000006D6, 0x0000212B, 0xFFFFF195, 0x0000041B, 0x0000212B, 0xFFFFF195, 0x0000041B }, + { 0x0213EA94DE0848C4, 0x00004050, 0xFFFFDEB3, 0x000006FE, 0x00002D6C, 0xFFFFE961, 0x00000582, 0x00002D6C, 0xFFFFE961, 0x00000582 }, + { 0x0213EA94DE262044, 0x000043F0, 0xFFFFDD9C, 0x00000702, 0x00002B31, 0xFFFFEBEA, 0x000004F7, 0x00002B31, 0xFFFFEBEA, 0x000004F7 }, + { 0x0213EA94DE100924, 0x00003EFA, 0xFFFFE093, 0x00000696, 0x000026DB, 0xFFFFEEB3, 0x00000489, 0x000026DB, 0xFFFFEEB3, 0x00000489 }, + { 0x0213EA94DE082064, 0x0000425D, 0xFFFFDE8D, 0x000006E6, 0x00002CA4, 0xFFFFEAD2, 0x00000531, 0x00002CA4, 0xFFFFEAD2, 0x00000531 }, + { 0x0213EA94DE2639A4, 0x000043B0, 0xFFFFDD03, 0x00000728, 0x00002946, 0xFFFFECA6, 0x000004DE, 0x00002946, 0xFFFFECA6, 0x000004DE }, + { 0x0213EA94DE282864, 0x00003F6A, 0xFFFFE03A, 0x0000069D, 0x00002208, 0xFFFFF1F8, 0x000003F6, 0x00002208, 0xFFFFF1F8, 0x000003F6 }, + { 0x0213EA94DE2C2964, 0x00003A94, 0xFFFFE4A7, 0x000005E2, 0x000024D0, 0xFFFFF100, 0x00000426, 0x000024D0, 0xFFFFF100, 0x00000426 }, + { 0x0213EA94DE2810C4, 0x00003F2F, 0xFFFFE0A3, 0x00000688, 0x00002198, 0xFFFFF271, 0x000003E2, 0x00002198, 0xFFFFF271, 0x000003E2 }, + { 0x0213EA94DE1048E4, 0x00003EA5, 0xFFFFE032, 0x000006AE, 0x0000227C, 0xFFFFF130, 0x00000426, 0x0000227C, 0xFFFFF130, 0x00000426 }, + { 0x0213EA94DE264144, 0x0000442F, 0xFFFFDBC4, 0x0000078B, 0x00003CD6, 0xFFFFDE6C, 0x0000076C, 0x00003CD6, 0xFFFFDE6C, 0x0000076C }, + { 0x0213EA94DE282884, 0x00003DDE, 0xFFFFE174, 0x00000668, 0x00001FF4, 0xFFFFF38F, 0x000003B1, 0x00001FF4, 0xFFFFF38F, 0x000003B1 }, + { 0x0213EA94DE0A3144, 0x000040B0, 0xFFFFE016, 0x000006A0, 0x00002DBB, 0xFFFFEA7F, 0x00000537, 0x00002DBB, 0xFFFFEA7F, 0x00000537 }, + { 0x0213EA94DE2C3104, 0x00003429, 0xFFFFEA97, 0x000004DD, 0x000024D5, 0xFFFFF26F, 0x000003DF, 0x000024D5, 0xFFFFF26F, 0x000003DF }, + { 0x0213EA94DE0E1904, 0x00003AEB, 0xFFFFE590, 0x000005A3, 0x000022CB, 0xFFFFF347, 0x000003B2, 0x000022CB, 0xFFFFF347, 0x000003B2 }, + { 0x0213EA94DE283904, 0x00003B8E, 0xFFFFE2EF, 0x00000636, 0x00002351, 0xFFFFF143, 0x0000041C, 0x00002351, 0xFFFFF143, 0x0000041C }, + { 0x0213EA94DE3240C4, 0x00002926, 0xFFFFF0B0, 0x00000410, 0x0000194E, 0xFFFFF94E, 0x000002E9, 0x0000194E, 0xFFFFF94E, 0x000002E9 }, + { 0x0213EA94DE283184, 0x0000402B, 0xFFFFDF78, 0x000006C2, 0x00002273, 0xFFFFF16C, 0x00000414, 0x00002273, 0xFFFFF16C, 0x00000414 }, + { 0x0213EA94DE0A10A4, 0x00003D6A, 0xFFFFE1D3, 0x00000659, 0x00002006, 0xFFFFF394, 0x000003B1, 0x00002006, 0xFFFFF394, 0x000003B1 }, + { 0x0213EA94DE284064, 0x00004042, 0xFFFFDFD8, 0x000006A8, 0x00002135, 0xFFFFF29F, 0x000003D9, 0x00002135, 0xFFFFF29F, 0x000003D9 }, + { 0x0213EA94DE0820A4, 0x0000405B, 0xFFFFE093, 0x00000682, 0x0000288F, 0xFFFFEE3A, 0x00000491, 0x0000288F, 0xFFFFEE3A, 0x00000491 }, + { 0x0213EA94DE2C48A4, 0x00003A49, 0xFFFFE30C, 0x00000648, 0x000023F9, 0xFFFFF02D, 0x00000460, 0x000023F9, 0xFFFFF02D, 0x00000460 }, + { 0x0213EA94DE282964, 0x00003D59, 0xFFFFE1CC, 0x0000065B, 0x00002013, 0xFFFFF37D, 0x000003B6, 0x00002013, 0xFFFFF37D, 0x000003B6 }, + { 0x0213EA94DE2C3984, 0x000040C1, 0xFFFFDF8C, 0x000006CA, 0x00003271, 0xFFFFE6CA, 0x000005EA, 0x00003271, 0xFFFFE6CA, 0x000005EA }, + { 0x0213EA94DE2620E4, 0x000042E9, 0xFFFFDFDC, 0x0000068C, 0x00002ED9, 0xFFFFEAAF, 0x0000051B, 0x00002ED9, 0xFFFFEAAF, 0x0000051B }, + { 0x0213EA94DE083084, 0x000042ED, 0xFFFFDE50, 0x000006F0, 0x00002FCF, 0xFFFFE8BB, 0x0000058C, 0x00002FCF, 0xFFFFE8BB, 0x0000058C }, + { 0x0213EA94DE0A4104, 0x00003EBD, 0xFFFFE099, 0x00000698, 0x00002709, 0xFFFFEE7B, 0x00000495, 0x00002709, 0xFFFFEE7B, 0x00000495 }, + { 0x0213EA94DE284904, 0x00003F71, 0xFFFFDF82, 0x000006C9, 0x0000219B, 0xFFFFF1AD, 0x0000040F, 0x0000219B, 0xFFFFF1AD, 0x0000040F }, + { 0x0213EA94DE2808E4, 0x00003E73, 0xFFFFE080, 0x0000069B, 0x000020E7, 0xFFFFF273, 0x000003E9, 0x000020E7, 0xFFFFF273, 0x000003E9 }, + { 0x0213EA94DE0E3184, 0x00003E14, 0xFFFFE278, 0x0000062C, 0x00002275, 0xFFFFF2B3, 0x000003CE, 0x00002275, 0xFFFFF2B3, 0x000003CE }, + { 0x0213EA94DE2C21A4, 0x00003ABB, 0xFFFFE3B9, 0x00000615, 0x00002192, 0xFFFFF28F, 0x000003EB, 0x00002192, 0xFFFFF28F, 0x000003EB }, + { 0x0213EA94DE283124, 0x00003D53, 0xFFFFE255, 0x00000643, 0x0000275B, 0xFFFFEEED, 0x00000479, 0x0000275B, 0xFFFFEEED, 0x00000479 }, + { 0x0213EA94DE262864, 0x000043E3, 0xFFFFDDC3, 0x000006FB, 0x00002B6B, 0xFFFFEBD6, 0x000004FA, 0x00002B6B, 0xFFFFEBD6, 0x000004FA }, + { 0x0213EA94DE0E2144, 0x00003BDE, 0xFFFFE507, 0x000005B4, 0x000022CE, 0xFFFFF358, 0x000003AB, 0x000022CE, 0xFFFFF358, 0x000003AB }, + { 0x0213EA94DE323164, 0x00002460, 0xFFFFF3B5, 0x000003A2, 0x000014E7, 0xFFFFFC32, 0x0000027C, 0x000014E7, 0xFFFFFC32, 0x0000027C }, + { 0x0213EA94DE2820C4, 0x00003D20, 0xFFFFE298, 0x0000062F, 0x00002080, 0xFFFFF3AF, 0x000003A8, 0x00002080, 0xFFFFF3AF, 0x000003A8 }, + { 0x0213EA94DE081904, 0x00003E14, 0xFFFFE221, 0x00000641, 0x000021BB, 0xFFFFF2EA, 0x000003CA, 0x000021BB, 0xFFFFF2EA, 0x000003CA }, + { 0x0213EA94DE0A40C4, 0x00003DE1, 0xFFFFE14E, 0x00000677, 0x00002468, 0xFFFFF068, 0x00000440, 0x00002468, 0xFFFFF068, 0x00000440 }, + { 0x0213EA94DE261084, 0x00004372, 0xFFFFDDF8, 0x000006F5, 0x00002B3F, 0xFFFFEBE8, 0x000004F8, 0x00002B3F, 0xFFFFEBE8, 0x000004F8 }, + { 0x0213EA94DE0A28C4, 0x00003E4F, 0xFFFFE2A3, 0x0000062B, 0x00002F5A, 0xFFFFEA37, 0x0000053B, 0x00002F5A, 0xFFFFEA37, 0x0000053B }, + { 0x0213EA94DE2850E4, 0x00003E07, 0xFFFFE02F, 0x000006B6, 0x0000216B, 0xFFFFF1A3, 0x00000416, 0x0000216B, 0xFFFFF1A3, 0x00000416 }, + { 0x0213EA94DE2838A4, 0x00003DAB, 0xFFFFE128, 0x0000067F, 0x0000216F, 0xFFFFF236, 0x000003F3, 0x0000216F, 0xFFFFF236, 0x000003F3 }, + { 0x0213EA94DE2C2924, 0x0000364B, 0xFFFFE8CB, 0x0000052A, 0x00002568, 0xFFFFF1B2, 0x00000400, 0x00002568, 0xFFFFF1B2, 0x00000400 }, + { 0x0213EA94DE261064, 0x00004219, 0xFFFFDE87, 0x000006E8, 0x00002C59, 0xFFFFEAEE, 0x00000529, 0x00002C59, 0xFFFFEAEE, 0x00000529 }, + { 0x0213EA94DE0E1944, 0x000039A8, 0xFFFFE602, 0x00000594, 0x00001D06, 0xFFFFF6F0, 0x00000316, 0x00001D06, 0xFFFFF6F0, 0x00000316 }, + { 0x0213EA94DE2610E4, 0x00004052, 0xFFFFE01C, 0x00000698, 0x00002310, 0xFFFFF1A1, 0x000003FE, 0x00002310, 0xFFFFF1A1, 0x000003FE }, + { 0x0213EA94DE0E2824, 0x00003C1C, 0xFFFFE3EB, 0x000005F1, 0x00002289, 0xFFFFF2CF, 0x000003C9, 0x00002289, 0xFFFFF2CF, 0x000003C9 }, + { 0x0213EA94DE0E5124, 0x00003F19, 0xFFFFE085, 0x0000069E, 0x00002B94, 0xFFFFEB72, 0x0000051D, 0x00002B94, 0xFFFFEB72, 0x0000051D }, + { 0x0213EA94DE0E41A4, 0x00003C51, 0xFFFFE2AD, 0x00000638, 0x0000206B, 0xFFFFF361, 0x000003BE, 0x0000206B, 0xFFFFF361, 0x000003BE }, + { 0x0213EA94DE2610C4, 0x000040B9, 0xFFFFDFBB, 0x000006AB, 0x0000241F, 0xFFFFF0CC, 0x00000425, 0x0000241F, 0xFFFFF0CC, 0x00000425 }, + { 0x0213EA94DE0A2064, 0x00003E62, 0xFFFFE12C, 0x00000678, 0x00002445, 0xFFFFF09E, 0x00000435, 0x00002445, 0xFFFFF09E, 0x00000435 }, + { 0x0213EA94DE0E1984, 0x00003C97, 0xFFFFE399, 0x000005FB, 0x0000209D, 0xFFFFF41D, 0x0000038F, 0x0000209D, 0xFFFFF41D, 0x0000038F }, + { 0x0213EA94DE0E3144, 0x00003FF9, 0xFFFFE1E9, 0x0000063E, 0x00002E96, 0xFFFFEAF5, 0x00000516, 0x00002E96, 0xFFFFEAF5, 0x00000516 }, + { 0x0213EA94DE0A3084, 0x00003F04, 0xFFFFE109, 0x0000067A, 0x000026E1, 0xFFFFEF0B, 0x00000476, 0x000026E1, 0xFFFFEF0B, 0x00000476 }, + { 0x0213EA94DE101124, 0x00003E3E, 0xFFFFE187, 0x00000660, 0x00002049, 0xFFFFF38D, 0x000003B0, 0x00002049, 0xFFFFF38D, 0x000003B0 }, + { 0x0213EA94DE282944, 0x00003D58, 0xFFFFE253, 0x0000063D, 0x00002158, 0xFFFFF308, 0x000003C3, 0x00002158, 0xFFFFF308, 0x000003C3 }, + { 0x0213EA94DE0840C4, 0x00004074, 0xFFFFDF8D, 0x000006C0, 0x00002799, 0xFFFFEE19, 0x000004A5, 0x00002799, 0xFFFFEE19, 0x000004A5 }, + { 0x0213EA94DE281924, 0x00003DAF, 0xFFFFE1C9, 0x00000659, 0x000020E5, 0xFFFFF313, 0x000003C6, 0x000020E5, 0xFFFFF313, 0x000003C6 }, + { 0x0213EA94DE0A3964, 0x000041DD, 0xFFFFDDFA, 0x0000071B, 0x0000348D, 0xFFFFE4B4, 0x0000064C, 0x0000348D, 0xFFFFE4B4, 0x0000064C }, + { 0x0213EA94DE2C2884, 0x00003947, 0xFFFFE5AE, 0x000005B8, 0x000024A6, 0xFFFFF140, 0x0000041D, 0x000024A6, 0xFFFFF140, 0x0000041D }, + { 0x0213EA94DE101844, 0x00003D35, 0xFFFFE197, 0x0000066E, 0x00002248, 0xFFFFF1BC, 0x00000408, 0x00002248, 0xFFFFF1BC, 0x00000408 }, + { 0x0213EA94DE0A18E4, 0x00003F4F, 0xFFFFE13E, 0x0000066D, 0x00002AF0, 0xFFFFEC99, 0x000004DB, 0x00002AF0, 0xFFFFEC99, 0x000004DB }, + { 0x0213EA94DE263944, 0x0000430F, 0xFFFFDDFB, 0x000006FC, 0x00002D4D, 0xFFFFEA55, 0x00000540, 0x00002D4D, 0xFFFFEA55, 0x00000540 }, + { 0x0213EA94DE0E2944, 0x00003B22, 0xFFFFE543, 0x000005B1, 0x000022E1, 0xFFFFF31B, 0x000003B9, 0x000022E1, 0xFFFFF31B, 0x000003B9 }, + { 0x0213EA94DE0E2084, 0x00003978, 0xFFFFE611, 0x00000592, 0x00001C36, 0xFFFFF771, 0x00000302, 0x00001C36, 0xFFFFF771, 0x00000302 }, + { 0x0213EA94DE262164, 0x000044DF, 0xFFFFDDAB, 0x000006F2, 0x00002CEA, 0xFFFFEB47, 0x00000507, 0x00002CEA, 0xFFFFEB47, 0x00000507 }, + { 0x0213EA94DE0A38C4, 0x00003E9B, 0xFFFFE12C, 0x0000067C, 0x00002B79, 0xFFFFEBD9, 0x00000503, 0x00002B79, 0xFFFFEBD9, 0x00000503 }, + { 0x0213EA94DE263044, 0x00004464, 0xFFFFDCD3, 0x00000731, 0x00002D14, 0xFFFFEA2D, 0x0000054E, 0x00002D14, 0xFFFFEA2D, 0x0000054E }, + { 0x0213EA94DE281124, 0x00003FB3, 0xFFFFE052, 0x00000693, 0x000020AC, 0xFFFFF311, 0x000003C6, 0x000020AC, 0xFFFFF311, 0x000003C6 }, + { 0x0213EA94DE2C1084, 0x00003BDA, 0xFFFFE2FB, 0x00000636, 0x0000261E, 0xFFFFEF72, 0x00000471, 0x0000261E, 0xFFFFEF72, 0x00000471 }, + { 0x0213EA94DE2C1964, 0x00003D72, 0xFFFFE28A, 0x0000063E, 0x000029D8, 0xFFFFED54, 0x000004C7, 0x000029D8, 0xFFFFED54, 0x000004C7 }, + { 0x0213EA94DE2C2824, 0x00003E26, 0xFFFFE102, 0x00000694, 0x00002DD1, 0xFFFFE9CA, 0x0000056D, 0x00002DD1, 0xFFFFE9CA, 0x0000056D }, + { 0x0213EA94DE104124, 0x000041CD, 0xFFFFDE97, 0x000006ED, 0x00002DE5, 0xFFFFE9B9, 0x00000565, 0x00002DE5, 0xFFFFE9B9, 0x00000565 }, + { 0x0213EA94DE0A2984, 0x00003F30, 0xFFFFE06E, 0x00000698, 0x000024FF, 0xFFFFEFFC, 0x0000044F, 0x000024FF, 0xFFFFEFFC, 0x0000044F }, + { 0x0213EA94DE2C38C4, 0x0000378B, 0xFFFFE6B4, 0x00000594, 0x000023A7, 0xFFFFF1DC, 0x00000407, 0x000023A7, 0xFFFFF1DC, 0x00000407 }, + { 0x0213EA94DE0E4164, 0x00003CD7, 0xFFFFE28D, 0x00000636, 0x00002036, 0xFFFFF3B5, 0x000003AA, 0x00002036, 0xFFFFF3B5, 0x000003AA }, + { 0x0213EA94DE0A3884, 0x00003EF9, 0xFFFFE0AA, 0x0000068D, 0x000024D3, 0xFFFFF02F, 0x00000445, 0x000024D3, 0xFFFFF02F, 0x00000445 }, + { 0x0213EA94DE283944, 0x00003D08, 0xFFFFE1BB, 0x00000665, 0x00002159, 0xFFFFF26F, 0x000003E6, 0x00002159, 0xFFFFF26F, 0x000003E6 }, + { 0x0213EA94DE2C20C4, 0x000038A9, 0xFFFFE6CA, 0x00000580, 0x000025D3, 0xFFFFF101, 0x00000421, 0x000025D3, 0xFFFFF101, 0x00000421 }, + { 0x0213EA94DE0A20A4, 0x00003E45, 0xFFFFE1F8, 0x0000064D, 0x000027E3, 0xFFFFEEBB, 0x0000047F, 0x000027E3, 0xFFFFEEBB, 0x0000047F }, + { 0x0213EA94DE0E3864, 0x00003F76, 0xFFFFE128, 0x0000066E, 0x0000286B, 0xFFFFEE4C, 0x00000493, 0x0000286B, 0xFFFFEE4C, 0x00000493 }, + { 0x0213EA94DE264104, 0x0000440D, 0xFFFFDCA2, 0x0000074F, 0x00003817, 0xFFFFE256, 0x000006AF, 0x00003817, 0xFFFFE256, 0x000006AF }, + { 0x0213EA94DE105104, 0x00003EE1, 0xFFFFDFA7, 0x000006D4, 0x000027EA, 0xFFFFED2B, 0x000004DE, 0x000027EA, 0xFFFFED2B, 0x000004DE }, + { 0x0213EA94DE2C3864, 0x00003C62, 0xFFFFE285, 0x0000064A, 0x00002520, 0xFFFFF001, 0x0000045C, 0x00002520, 0xFFFFF001, 0x0000045C }, + { 0x0213EA94DE323964, 0x0000272E, 0xFFFFF17A, 0x000003FA, 0x0000150B, 0xFFFFFBD5, 0x00000284, 0x0000150B, 0xFFFFFBD5, 0x00000284 }, + { 0x0213EA94DE261924, 0x00004275, 0xFFFFDF69, 0x000006A5, 0x000025AA, 0xFFFFF05C, 0x0000042B, 0x000025AA, 0xFFFFF05C, 0x0000042B }, + { 0x0213EA94DE0E40E4, 0x00003CAA, 0xFFFFE392, 0x000005FF, 0x000023A8, 0xFFFFF20E, 0x000003E9, 0x000023A8, 0xFFFFF20E, 0x000003E9 }, + { 0x0213EA94DE2C50C4, 0x00003CF8, 0xFFFFE0FB, 0x000006A6, 0x00002CA7, 0xFFFFE9FF, 0x0000056E, 0x00002CA7, 0xFFFFE9FF, 0x0000056E }, + { 0x0213EA94DE282124, 0x00003D00, 0xFFFFE296, 0x00000633, 0x000021C1, 0xFFFFF2C8, 0x000003CF, 0x000021C1, 0xFFFFF2C8, 0x000003CF }, + { 0x0213EA94DE2838E4, 0x00003B46, 0xFFFFE301, 0x00000632, 0x0000204C, 0xFFFFF33B, 0x000003C8, 0x0000204C, 0xFFFFF33B, 0x000003C8 }, + { 0x0213EA94DE204164, 0x00002026, 0xFFFFF5CE, 0x00000368, 0x00001598, 0xFFFFFB29, 0x000002C3, 0x00001598, 0xFFFFFB29, 0x000002C3 }, + { 0x0213EA94DE283164, 0x00003DCA, 0xFFFFE178, 0x00000668, 0x00001FDB, 0xFFFFF39D, 0x000003AF, 0x00001FDB, 0xFFFFF39D, 0x000003AF }, + { 0x0213EA94DE2C48C4, 0x00003A59, 0xFFFFE327, 0x00000642, 0x000024B9, 0xFFFFEFC4, 0x00000471, 0x000024B9, 0xFFFFEFC4, 0x00000471 }, + { 0x0213EA94DE2C2944, 0x00003C26, 0xFFFFE440, 0x000005EB, 0x00002C0F, 0xFFFFEC88, 0x000004E0, 0x00002C0F, 0xFFFFEC88, 0x000004E0 }, + { 0x0213EA94DE083884, 0x00004149, 0xFFFFDEB8, 0x000006E7, 0x0000280A, 0xFFFFED89, 0x000004C2, 0x0000280A, 0xFFFFED89, 0x000004C2 }, + { 0x0213EA94DE0E4124, 0x00003EB4, 0xFFFFE1E5, 0x0000064D, 0x0000299F, 0xFFFFEDB3, 0x000004A9, 0x0000299F, 0xFFFFEDB3, 0x000004A9 }, + { 0x0213EA94DE2C39A4, 0x00003BBF, 0xFFFFE268, 0x0000065A, 0x00002504, 0xFFFFEFB0, 0x00000470, 0x00002504, 0xFFFFEFB0, 0x00000470 }, + { 0x0213EA94DE084904, 0x00004203, 0xFFFFDDC6, 0x00000720, 0x0000303B, 0xFFFFE78F, 0x000005D0, 0x0000303B, 0xFFFFE78F, 0x000005D0 }, + { 0x0213EA94DE0E3984, 0x00003DA3, 0xFFFFE244, 0x0000063E, 0x000021B4, 0xFFFFF2DA, 0x000003CD, 0x000021B4, 0xFFFFF2DA, 0x000003CD }, + { 0x0213EA94DE0A38E4, 0x00004035, 0xFFFFE065, 0x0000069B, 0x00003323, 0xFFFFE6D6, 0x000005D8, 0x00003323, 0xFFFFE6D6, 0x000005D8 }, + { 0x0213EA94DE2C1164, 0x00003944, 0xFFFFE4E5, 0x000005E2, 0x00001F3C, 0xFFFFF456, 0x0000039D, 0x00001F3C, 0xFFFFF456, 0x0000039D }, + { 0x0213EA94DE061904, 0x000032D8, 0xFFFFEAE8, 0x000004E6, 0x00001812, 0xFFFFFA1C, 0x000002BC, 0x00001812, 0xFFFFFA1C, 0x000002BC }, + { 0x0213F0FD42D22944, 0x000041F6, 0xFFFFE025, 0x0000069A, 0x0000241E, 0xFFFFF1B4, 0x00000402, 0x0000241E, 0xFFFFF1B4, 0x00000402 }, + { 0x0213F0FE990C30A4, 0x00003300, 0xFFFFEB60, 0x000004C1, 0x00001E15, 0xFFFFF6A6, 0x0000033B, 0x00001E15, 0xFFFFF6A6, 0x0000033B }, + { 0x0213EA94DE0408A4, 0x000037F0, 0xFFFFE68F, 0x0000059B, 0x00001F8A, 0xFFFFF467, 0x000003A3, 0x00001F8A, 0xFFFFF467, 0x000003A3 }, + { 0x0213F0FE99182984, 0x000025D8, 0xFFFFF2AA, 0x000003C3, 0x000018A8, 0xFFFFF9BE, 0x000002D2, 0x000018A8, 0xFFFFF9BE, 0x000002D2 }, + { 0x0213F0FE990620C4, 0x0000364F, 0xFFFFE988, 0x000004FC, 0x00001E51, 0xFFFFF633, 0x0000034F, 0x00001E51, 0xFFFFF633, 0x0000034F }, + { 0x0213EA94DE061144, 0x00002288, 0xFFFFF483, 0x0000036C, 0x0000280F, 0xFFFFEF39, 0x0000047B, 0x0000280F, 0xFFFFEF39, 0x0000047B }, + { 0x0213F0FE99082084, 0x00003322, 0xFFFFEA7E, 0x000004ED, 0x00001DAD, 0xFFFFF62B, 0x00000355, 0x00001DAD, 0xFFFFF62B, 0x00000355 }, + { 0x0213EA94DE0250E4, 0x00002B7B, 0xFFFFEE4F, 0x0000045B, 0x00001AA2, 0xFFFFF710, 0x0000033E, 0x00001AA2, 0xFFFFF710, 0x0000033E }, + { 0x0213F0FE990420C4, 0x000034CC, 0xFFFFEA79, 0x000004E4, 0x00001B05, 0xFFFFF8B3, 0x000002EC, 0x00001B05, 0xFFFFF8B3, 0x000002EC }, + { 0x0213F0FD42DC2864, 0x00003837, 0xFFFFE5ED, 0x000005C3, 0x00001ACB, 0xFFFFF7B2, 0x00000314, 0x00001ACB, 0xFFFFF7B2, 0x00000314 }, + { 0x0213F0FE99044164, 0x0000352D, 0xFFFFE88F, 0x00000548, 0x000021E6, 0xFFFFF3B5, 0x000003AA, 0x000021E6, 0xFFFFF3B5, 0x000003AA }, + { 0x0213F0FE990A4884, 0x00003300, 0xFFFFE835, 0x0000057B, 0x00001A85, 0xFFFFF715, 0x00000336, 0x00001A85, 0xFFFFF715, 0x00000336 }, + { 0x0213EA94DE0448A4, 0x000033FA, 0xFFFFE851, 0x00000565, 0x00001A8E, 0xFFFFF727, 0x0000033B, 0x00001A8E, 0xFFFFF727, 0x0000033B }, + { 0x0213F0FD42DA3924, 0x000039D3, 0xFFFFE5D3, 0x000005B0, 0x00001888, 0xFFFFF978, 0x000002C8, 0x00001888, 0xFFFFF978, 0x000002C8 }, + { 0x0213F0FE990E4864, 0x00002F6B, 0xFFFFEC53, 0x000004B9, 0x00001C15, 0xFFFFF71B, 0x00000337, 0x00001C15, 0xFFFFF71B, 0x00000337 }, + { 0x0213F0FE99064144, 0x0000384D, 0xFFFFE737, 0x00000569, 0x00001D2D, 0xFFFFF673, 0x00000343, 0x00001D2D, 0xFFFFF673, 0x00000343 }, + { 0x0213F0FE990620A4, 0x00003A49, 0xFFFFE70B, 0x0000055F, 0x00001A63, 0xFFFFF8CD, 0x000002E2, 0x00001A63, 0xFFFFF8CD, 0x000002E2 }, + { 0x0213F0FE99042984, 0x0000311E, 0xFFFFEB97, 0x000004C6, 0x00001EAE, 0xFFFFF5A9, 0x00000367, 0x00001EAE, 0xFFFFF5A9, 0x00000367 }, + { 0x0213F0FE990E1124, 0x000027D3, 0xFFFFF075, 0x00000417, 0x00002001, 0xFFFFF44A, 0x000003A2, 0x00002001, 0xFFFFF44A, 0x000003A2 }, + { 0x0213F0FE99064904, 0x00003B72, 0xFFFFE4BD, 0x000005DC, 0x00001D76, 0xFFFFF606, 0x0000035A, 0x00001D76, 0xFFFFF606, 0x0000035A }, + { 0x0213F0FE99101124, 0x00002E0F, 0xFFFFECA7, 0x000004AE, 0x00001DC6, 0xFFFFF5BF, 0x0000036A, 0x00001DC6, 0xFFFFF5BF, 0x0000036A }, + { 0x0213F0FE990238A4, 0x000032C7, 0xFFFFEA7A, 0x000004F0, 0x00001A7B, 0xFFFFF827, 0x00000301, 0x00001A7B, 0xFFFFF827, 0x00000301 }, + { 0x0213EA94DE044884, 0x0000312D, 0xFFFFEA39, 0x00000515, 0x00001948, 0xFFFFF800, 0x00000318, 0x00001948, 0xFFFFF800, 0x00000318 }, + { 0x0213EA94DE062084, 0x00003611, 0xFFFFE8D7, 0x00000533, 0x00001929, 0xFFFFF965, 0x000002D2, 0x00001929, 0xFFFFF965, 0x000002D2 }, + { 0x0213F0FE992C30E4, 0x00002FE2, 0xFFFFED89, 0x00000470, 0x00001A3C, 0xFFFFF955, 0x000002D5, 0x00001A3C, 0xFFFFF955, 0x000002D5 }, + { 0x0213EA94DE0208A4, 0x000035FF, 0xFFFFE884, 0x00000548, 0x0000182A, 0xFFFFF9AB, 0x000002CF, 0x0000182A, 0xFFFFF9AB, 0x000002CF }, + { 0x0213F0FE990220E4, 0x00003597, 0xFFFFE904, 0x00000528, 0x00001A94, 0xFFFFF840, 0x00000300, 0x00001A94, 0xFFFFF840, 0x00000300 }, + { 0x0213F0FE99181944, 0x000026CB, 0xFFFFF1FB, 0x000003E4, 0x000017CC, 0xFFFFFA25, 0x000002C8, 0x000017CC, 0xFFFFFA25, 0x000002C8 }, + { 0x0213EA94DE0608C4, 0x00003274, 0xFFFFEA39, 0x0000050C, 0x00001B20, 0xFFFFF7C1, 0x00000314, 0x00001B20, 0xFFFFF7C1, 0x00000314 }, + { 0x0213F0FD42D82924, 0x0000280B, 0xFFFFF283, 0x000003B5, 0x000018D0, 0xFFFFF992, 0x000002EC, 0x000018D0, 0xFFFFF992, 0x000002EC }, + { 0x0213F0FE99062104, 0x000033AB, 0xFFFFEB1B, 0x000004C4, 0x00001FEE, 0xFFFFF53A, 0x00000378, 0x00001FEE, 0xFFFFF53A, 0x00000378 }, + { 0x0213F0FE990A3964, 0x00002F79, 0xFFFFEB0C, 0x000004FA, 0x00001E57, 0xFFFFF4BF, 0x0000039B, 0x00001E57, 0xFFFFF4BF, 0x0000039B }, + { 0x0213F0FE990448E4, 0x00003487, 0xFFFFE8F2, 0x00000539, 0x0000185B, 0xFFFFF9AE, 0x000002BA, 0x0000185B, 0xFFFFF9AE, 0x000002BA }, + { 0x0213F0FE990A18A4, 0x00003500, 0xFFFFE793, 0x0000058A, 0x00001AA2, 0xFFFFF792, 0x0000031D, 0x00001AA2, 0xFFFFF792, 0x0000031D }, + { 0x0213F0FE99081164, 0x00003943, 0xFFFFE54D, 0x000005D9, 0x00001BC8, 0xFFFFF6E0, 0x00000339, 0x00001BC8, 0xFFFFF6E0, 0x00000339 }, + { 0x0213EA94DE0430A4, 0x0000306D, 0xFFFFEC5E, 0x000004A5, 0x00001A3A, 0xFFFFF85F, 0x00000304, 0x00001A3A, 0xFFFFF85F, 0x00000304 }, + { 0x0213F0FD42D83084, 0x00002BA4, 0xFFFFEE8D, 0x0000046A, 0x0000198C, 0xFFFFF88E, 0x00000307, 0x0000198C, 0xFFFFF88E, 0x00000307 }, + { 0x0213F0FD42D218E4, 0x00003D30, 0xFFFFE2F6, 0x0000062A, 0x000025DC, 0xFFFFF074, 0x00000435, 0x000025DC, 0xFFFFF074, 0x00000435 }, + { 0x0213F0FD42D83964, 0x00002CD6, 0xFFFFED79, 0x0000049B, 0x000016D0, 0xFFFFFA53, 0x000002BB, 0x000016D0, 0xFFFFFA53, 0x000002BB }, + { 0x0213F0FE99163164, 0x00002484, 0xFFFFF3BD, 0x000003A0, 0x000015B8, 0xFFFFFB6B, 0x000002A4, 0x000015B8, 0xFFFFFB6B, 0x000002A4 }, + { 0x0213F0FE990E3944, 0x000038AE, 0xFFFFE6D1, 0x00000587, 0x00001A2A, 0xFFFFF8F1, 0x000002D4, 0x00001A2A, 0xFFFFF8F1, 0x000002D4 }, + { 0x0213F0FE99044944, 0x000036FD, 0xFFFFE76C, 0x00000576, 0x00001EE4, 0xFFFFF58D, 0x00000361, 0x00001EE4, 0xFFFFF58D, 0x00000361 }, + { 0x0213F0FD42D830A4, 0x00002BCF, 0xFFFFEF28, 0x00000448, 0x00001B93, 0xFFFFF7BA, 0x00000327, 0x00001B93, 0xFFFFF7BA, 0x00000327 }, + { 0x0213F0FE99062884, 0x00003834, 0xFFFFE818, 0x0000053B, 0x00001AFE, 0xFFFFF85C, 0x000002F3, 0x00001AFE, 0xFFFFF85C, 0x000002F3 }, + { 0x0213F0FE993231A4, 0x00002EF7, 0xFFFFEBFC, 0x000004CE, 0x00001897, 0xFFFFF8EF, 0x000002EC, 0x00001897, 0xFFFFF8EF, 0x000002EC }, + { 0x0213F0FE992C18C4, 0x000035BD, 0xFFFFE8BB, 0x0000053B, 0x00001F22, 0xFFFFF561, 0x00000373, 0x00001F22, 0xFFFFF561, 0x00000373 }, + { 0x0213F0FE99183984, 0x00002D42, 0xFFFFEE1D, 0x00000478, 0x000016F0, 0xFFFFFAAE, 0x000002B3, 0x000016F0, 0xFFFFFAAE, 0x000002B3 }, + { 0x0213EA94DE045124, 0x00002F98, 0xFFFFEB3C, 0x000004F0, 0x00001903, 0xFFFFF818, 0x00000319, 0x00001903, 0xFFFFF818, 0x00000319 }, + { 0x0213F0FD42D42144, 0x00004081, 0xFFFFDF13, 0x000006F3, 0x00002A6D, 0xFFFFEC1B, 0x00000509, 0x00002A6D, 0xFFFFEC1B, 0x00000509 }, + { 0x0213EA94DE040904, 0x00002D68, 0xFFFFED21, 0x00000498, 0x00001FF6, 0xFFFFF427, 0x000003B0, 0x00001FF6, 0xFFFFF427, 0x000003B0 }, + { 0x0213F0FE99023884, 0x00003243, 0xFFFFEA5C, 0x000004FD, 0x000020FB, 0xFFFFF39E, 0x000003C0, 0x000020FB, 0xFFFFF39E, 0x000003C0 }, + { 0x0213F0FD42D848A4, 0x00002F20, 0xFFFFEC19, 0x000004C6, 0x00001748, 0xFFFFF99F, 0x000002DA, 0x00001748, 0xFFFFF99F, 0x000002DA }, + { 0x0213F0FE99103984, 0x00002D68, 0xFFFFED21, 0x00000498, 0x00001A43, 0xFFFFF843, 0x000002F9, 0x00001A43, 0xFFFFF843, 0x000002F9 }, + { 0x0213F0FE990220A4, 0x0000396E, 0xFFFFE616, 0x000005A9, 0x00001A51, 0xFFFFF850, 0x000002FA, 0x00001A51, 0xFFFFF850, 0x000002FA }, + { 0x0213F0FE99043144, 0x0000305C, 0xFFFFED4B, 0x0000046C, 0x00001CF9, 0xFFFFF7BA, 0x00000304, 0x00001CF9, 0xFFFFF7BA, 0x00000304 }, + { 0x0213F0FD42DA4164, 0x0000343C, 0xFFFFE869, 0x00000559, 0x00001CE2, 0xFFFFF614, 0x00000359, 0x00001CE2, 0xFFFFF614, 0x00000359 }, + { 0x0213F0FE99183964, 0x00002782, 0xFFFFF1FE, 0x000003D9, 0x000015DC, 0xFFFFFB8B, 0x00000290, 0x000015DC, 0xFFFFFB8B, 0x00000290 }, + { 0x0213F0FE991818C4, 0x00002B9C, 0xFFFFEF63, 0x00000443, 0x00001369, 0xFFFFFD51, 0x00000244, 0x00001369, 0xFFFFFD51, 0x00000244 }, + { 0x0213F0FE990A2084, 0x000035F8, 0xFFFFE743, 0x00000592, 0x000018D8, 0xFFFFF8EE, 0x000002E4, 0x000018D8, 0xFFFFF8EE, 0x000002E4 }, + { 0x0213EA94DE062844, 0x00002B72, 0xFFFFEF1E, 0x0000043C, 0x00002647, 0xFFFFF092, 0x0000043E, 0x00002647, 0xFFFFF092, 0x0000043E }, + { 0x0213F0FE99102184, 0x00002EC9, 0xFFFFEC5F, 0x000004B8, 0x000018B6, 0xFFFFF936, 0x000002D8, 0x000018B6, 0xFFFFF936, 0x000002D8 }, + { 0x0213F0FE99064084, 0x000038A7, 0xFFFFE6AC, 0x00000589, 0x00001C42, 0xFFFFF70B, 0x00000329, 0x00001C42, 0xFFFFF70B, 0x00000329 }, + { 0x0213F0FE993008A4, 0x00002F6B, 0xFFFFEBF6, 0x000004CF, 0x000018AE, 0xFFFFF928, 0x000002E3, 0x000018AE, 0xFFFFF928, 0x000002E3 }, + { 0x0213F0FD42DA5104, 0x000029CD, 0xFFFFEEE1, 0x00000459, 0x00001AB5, 0xFFFFF76F, 0x00000324, 0x00001AB5, 0xFFFFF76F, 0x00000324 }, + { 0x0213EA94DE0638C4, 0x00003921, 0xFFFFE71D, 0x00000577, 0x00001646, 0xFFFFFB24, 0x00000293, 0x00001646, 0xFFFFFB24, 0x00000293 }, + { 0x0213EA94DE044164, 0x00003940, 0xFFFFE521, 0x000005E8, 0x00001947, 0xFFFFF839, 0x0000030D, 0x00001947, 0xFFFFF839, 0x0000030D }, + { 0x0213F0FD42D24164, 0x00003DCA, 0xFFFFE211, 0x00000659, 0x0000250E, 0xFFFFF072, 0x00000443, 0x0000250E, 0xFFFFF072, 0x00000443 }, + { 0x0213F0FE990C0904, 0x00002E95, 0xFFFFEC20, 0x000004C9, 0x000015B4, 0xFFFFFAD3, 0x0000029D, 0x000015B4, 0xFFFFFAD3, 0x0000029D }, + { 0x0213F0FE99041084, 0x00002C11, 0xFFFFEE6E, 0x00000468, 0x00001901, 0xFFFFF924, 0x000002E7, 0x00001901, 0xFFFFF924, 0x000002E7 }, + { 0x0213EA94DE062104, 0x0000293F, 0xFFFFF158, 0x000003E6, 0x0000183F, 0xFFFFF9F6, 0x000002D2, 0x0000183F, 0xFFFFF9F6, 0x000002D2 }, + { 0x0213F0FE990E1104, 0x00002A67, 0xFFFFEF34, 0x0000043E, 0x00001C6F, 0xFFFFF6F1, 0x0000032B, 0x00001C6F, 0xFFFFF6F1, 0x0000032B }, + { 0x0213EA94DE065124, 0x00002F8D, 0xFFFFEB77, 0x000004DA, 0x00001C0D, 0xFFFFF627, 0x00000365, 0x00001C0D, 0xFFFFF627, 0x00000365 }, + { 0x0213F0FE990C38C4, 0x00003476, 0xFFFFEA5B, 0x000004E7, 0x00001DBF, 0xFFFFF6C7, 0x00000333, 0x00001DBF, 0xFFFFF6C7, 0x00000333 }, + { 0x0213F0FE990E0944, 0x00003336, 0xFFFFE92F, 0x00000546, 0x00001614, 0xFFFFFAE0, 0x00000296, 0x00001614, 0xFFFFFAE0, 0x00000296 }, + { 0x0213F0FE99162164, 0x00002513, 0xFFFFF323, 0x000003BC, 0x000016DB, 0xFFFFFA79, 0x000002CD, 0x000016DB, 0xFFFFFA79, 0x000002CD }, + { 0x0213F0FE990A2944, 0x000035A7, 0xFFFFE78E, 0x00000584, 0x00001B0D, 0xFFFFF77D, 0x0000031F, 0x00001B0D, 0xFFFFF77D, 0x0000031F }, + { 0x0213F0FE993238E4, 0x00003171, 0xFFFFEB98, 0x000004C6, 0x00001C76, 0xFFFFF71F, 0x0000032F, 0x00001C76, 0xFFFFF71F, 0x0000032F }, + { 0x0213F0FD42DA1084, 0x00002C52, 0xFFFFED2E, 0x000004A7, 0x00002182, 0xFFFFF2F4, 0x000003E4, 0x00002182, 0xFFFFF2F4, 0x000003E4 }, + { 0x0213F0FE99102924, 0x000032E1, 0xFFFFEB39, 0x000004D0, 0x00001B55, 0xFFFFF859, 0x000002FA, 0x00001B55, 0xFFFFF859, 0x000002FA }, + { 0x0213F0FE991848A4, 0x000029B6, 0xFFFFEFF7, 0x00000430, 0x0000151B, 0xFFFFFBC6, 0x0000027F, 0x0000151B, 0xFFFFFBC6, 0x0000027F }, + { 0x0213F0FD42DA1964, 0x00002FF7, 0xFFFFEB67, 0x000004DA, 0x000020E9, 0xFFFFF363, 0x000003CE, 0x000020E9, 0xFFFFF363, 0x000003CE }, + { 0x0213F0FD42DA5124, 0x00003CDD, 0xFFFFE2B2, 0x00000649, 0x00001B18, 0xFFFFF739, 0x00000329, 0x00001B18, 0xFFFFF739, 0x00000329 }, + { 0x0213F0FE990628A4, 0x00003C82, 0xFFFFE5C6, 0x0000058E, 0x00001F3F, 0xFFFFF5AD, 0x00000361, 0x00001F3F, 0xFFFFF5AD, 0x00000361 }, + { 0x0213F0FD42DC4084, 0x0000319B, 0xFFFFEA15, 0x0000051B, 0x00001CC9, 0xFFFFF62E, 0x00000358, 0x00001CC9, 0xFFFFF62E, 0x00000358 }, + { 0x0213EA94DE0638E4, 0x000032B6, 0xFFFFEB2B, 0x000004D6, 0x000018E0, 0xFFFFF966, 0x000002DE, 0x000018E0, 0xFFFFF966, 0x000002DE }, + { 0x0213EA94DE023984, 0x0000300A, 0xFFFFEBA6, 0x000004D1, 0x00001CFD, 0xFFFFF5F6, 0x0000036D, 0x00001CFD, 0xFFFFF5F6, 0x0000036D }, + { 0x0213F0FD42D82984, 0x000026A9, 0xFFFFF15D, 0x00000400, 0x00001561, 0xFFFFFB1F, 0x000002A0, 0x00001561, 0xFFFFFB1F, 0x000002A0 }, + { 0x0213F0FE990E5124, 0x00003123, 0xFFFFEAD2, 0x000004FA, 0x000018CB, 0xFFFFF8F5, 0x000002EC, 0x000018CB, 0xFFFFF8F5, 0x000002EC }, + { 0x0213F0FE991840C4, 0x00003577, 0xFFFFE935, 0x00000533, 0x000016CD, 0xFFFFFB44, 0x00000289, 0x000016CD, 0xFFFFFB44, 0x00000289 }, + { 0x0213F0FE99282184, 0x00002875, 0xFFFFF170, 0x000003F3, 0x00001567, 0xFFFFFBD5, 0x00000289, 0x00001567, 0xFFFFFBD5, 0x00000289 }, + { 0x0213F0FE99084084, 0x00003AE2, 0xFFFFE538, 0x000005C1, 0x00001CB4, 0xFFFFF6A3, 0x0000033C, 0x00001CB4, 0xFFFFF6A3, 0x0000033C }, + { 0x0213F0FE990C38E4, 0x000031DF, 0xFFFFEC2A, 0x000004A3, 0x00001EF0, 0xFFFFF626, 0x00000352, 0x00001EF0, 0xFFFFF626, 0x00000352 }, + { 0x0213F0FD42D25144, 0x00004A6A, 0xFFFFDB15, 0x00000758, 0x000027F3, 0xFFFFEEEE, 0x00000479, 0x000027F3, 0xFFFFEEEE, 0x00000479 }, + { 0x0213EA94DE063904, 0x00002BB9, 0xFFFFEF5D, 0x00000433, 0x00001589, 0xFFFFFB57, 0x00000295, 0x00001589, 0xFFFFFB57, 0x00000295 }, + { 0x0213F0FE99042164, 0x000033A0, 0xFFFFE98F, 0x00000528, 0x00001CB4, 0xFFFFF706, 0x0000032D, 0x00001CB4, 0xFFFFF706, 0x0000032D }, + { 0x0213F0FE99163064, 0x0000248E, 0xFFFFF380, 0x000003AC, 0x000016EA, 0xFFFFFA6C, 0x000002CE, 0x000016EA, 0xFFFFFA6C, 0x000002CE }, + { 0x0213F0FE990221A4, 0x00002FE2, 0xFFFFEB2F, 0x000004E9, 0x00001D4E, 0xFFFFF56B, 0x00000380, 0x00001D4E, 0xFFFFF56B, 0x00000380 }, + { 0x0213F0FE990A2884, 0x00003283, 0xFFFFE9E7, 0x0000051D, 0x00000694, 0xFFFFFD32, 0x000003C3, 0x00000694, 0xFFFFFD32, 0x000003C3 }, + { 0x0213F0FD42D850C4, 0x00002EE4, 0xFFFFEBFD, 0x000004D3, 0x0000151A, 0xFFFFFAF6, 0x000002A4, 0x0000151A, 0xFFFFFAF6, 0x000002A4 }, + { 0x0213F0FD42DC18E4, 0x0000302D, 0xFFFFEB7F, 0x000004DA, 0x00001E6D, 0xFFFFF54B, 0x00000380, 0x00001E6D, 0xFFFFF54B, 0x00000380 }, + { 0x0213F0FD42DA50C4, 0x000033DA, 0xFFFFE7FB, 0x0000057F, 0x00001DED, 0xFFFFF50E, 0x0000038D, 0x00001DED, 0xFFFFF50E, 0x0000038D }, + { 0x0213F0FE992C4084, 0x000030B5, 0xFFFFEBB8, 0x000004C4, 0x00001C3F, 0xFFFFF726, 0x0000032A, 0x00001C3F, 0xFFFFF726, 0x0000032A }, + { 0x0213F0FE990831C4, 0x00003BBD, 0xFFFFE55C, 0x000005B8, 0x000019DB, 0xFFFFF8BB, 0x000002EF, 0x000019DB, 0xFFFFF8BB, 0x000002EF }, + { 0x0213F0FE990E3884, 0x00002964, 0xFFFFF051, 0x0000040E, 0x000025CD, 0xFFFFF11B, 0x0000041F, 0x000025CD, 0xFFFFF11B, 0x0000041F }, + { 0x0213F0FD42DC4884, 0x000033F5, 0xFFFFE863, 0x00000560, 0x00001BCE, 0xFFFFF689, 0x0000034B, 0x00001BCE, 0xFFFFF689, 0x0000034B }, + { 0x0213F0FE990A2864, 0x00003294, 0xFFFFE924, 0x00000548, 0x00001D41, 0xFFFFF580, 0x0000037D, 0x00001D41, 0xFFFFF580, 0x0000037D }, + { 0x0213F0FD42DC39A4, 0x000034FB, 0xFFFFE7FE, 0x0000056D, 0x00001CB1, 0xFFFFF635, 0x00000357, 0x00001CB1, 0xFFFFF635, 0x00000357 }, + { 0x0213F0FE990A10A4, 0x00002E28, 0xFFFFEBB9, 0x000004E0, 0x00001B20, 0xFFFFF6E3, 0x0000033C, 0x00001B20, 0xFFFFF6E3, 0x0000033C }, + { 0x0213F0FD42DA1904, 0x00002799, 0xFFFFF0F4, 0x000003FC, 0x00001C9D, 0xFFFFF6A1, 0x00000345, 0x00001C9D, 0xFFFFF6A1, 0x00000345 }, + { 0x0213F0FE99064104, 0x00003AEA, 0xFFFFE5DB, 0x0000059D, 0x00001B61, 0xFFFFF7F0, 0x00000301, 0x00001B61, 0xFFFFF7F0, 0x00000301 }, + { 0x0213EA94DE041984, 0x000031F6, 0xFFFFEAB8, 0x000004F3, 0x00001D90, 0xFFFFF622, 0x00000359, 0x00001D90, 0xFFFFF622, 0x00000359 }, + { 0x0213F0FE990C4064, 0x000031B8, 0xFFFFEA61, 0x0000050F, 0x0000199D, 0xFFFFF87C, 0x000002FD, 0x0000199D, 0xFFFFF87C, 0x000002FD }, + { 0x0213F0FD42D23144, 0x00004514, 0xFFFFDDFF, 0x000006F6, 0x000022CD, 0xFFFFF29F, 0x000003D9, 0x000022CD, 0xFFFFF29F, 0x000003D9 }, + { 0x0213EA94DE043164, 0x00002F30, 0xFFFFECB8, 0x000004A0, 0x00001B07, 0xFFFFF7E2, 0x00000313, 0x00001B07, 0xFFFFF7E2, 0x00000313 }, + { 0x0213F0FD42DC30A4, 0x0000383B, 0xFFFFE702, 0x00000581, 0x00001A08, 0xFFFFF8CA, 0x000002E2, 0x00001A08, 0xFFFFF8CA, 0x000002E2 }, + { 0x0213F0FE99022164, 0x00002CC5, 0xFFFFEDF8, 0x00000465, 0x00001F47, 0xFFFFF4B2, 0x00000393, 0x00001F47, 0xFFFFF4B2, 0x00000393 }, + { 0x0213F0FE991621C4, 0x00002304, 0xFFFFF453, 0x00000384, 0x0000170A, 0xFFFFFA3F, 0x000002CE, 0x0000170A, 0xFFFFFA3F, 0x000002CE }, + { 0x0213F0FE990A5124, 0x0000337E, 0xFFFFE850, 0x0000056E, 0x00001BDD, 0xFFFFF668, 0x00000353, 0x00001BDD, 0xFFFFF668, 0x00000353 }, + { 0x0213F0FE990E4924, 0x00002E2F, 0xFFFFEC9B, 0x000004AE, 0x00001C4D, 0xFFFFF6D3, 0x00000338, 0x00001C4D, 0xFFFFF6D3, 0x00000338 }, + { 0x0213EA94DE061124, 0x00002DDD, 0xFFFFEDA4, 0x00000477, 0x00002010, 0xFFFFF4BB, 0x00000390, 0x00002010, 0xFFFFF4BB, 0x00000390 }, + { 0x0213F0FD42DA48E4, 0x0000290C, 0xFFFFEF61, 0x00000445, 0x00002133, 0xFFFFF324, 0x000003D8, 0x00002133, 0xFFFFF324, 0x000003D8 }, + { 0x0213F0FE99062924, 0x0000371E, 0xFFFFE8D5, 0x00000524, 0x00001C3A, 0xFFFFF7AE, 0x00000314, 0x00001C3A, 0xFFFFF7AE, 0x00000314 }, + { 0x0213F0FD42D838E4, 0x00002A58, 0xFFFFF007, 0x00000429, 0x000018A6, 0xFFFFF98F, 0x000002E1, 0x000018A6, 0xFFFFF98F, 0x000002E1 }, + { 0x0213F0FE99023084, 0x00002FED, 0xFFFFEC48, 0x000004AA, 0x00001E9D, 0xFFFFF584, 0x00000370, 0x00001E9D, 0xFFFFF584, 0x00000370 }, + { 0x0213F0FE99181884, 0x00002829, 0xFFFFF15F, 0x000003F7, 0x0000157E, 0xFFFFFBD4, 0x00000282, 0x0000157E, 0xFFFFFBD4, 0x00000282 }, + { 0x0213F0FE99101924, 0x000030CF, 0xFFFFEB8D, 0x000004CE, 0x00001A4C, 0xFFFFF868, 0x000002F7, 0x00001A4C, 0xFFFFF868, 0x000002F7 }, + { 0x0213F0FD42DA2084, 0x00002C8F, 0xFFFFEDD2, 0x0000047D, 0x00001CCE, 0xFFFFF6A1, 0x00000343, 0x00001CCE, 0xFFFFF6A1, 0x00000343 }, + { 0x0213F0FE99182164, 0x00002A84, 0xFFFFEFBA, 0x0000043E, 0x000015EF, 0xFFFFFB4B, 0x0000029E, 0x000015EF, 0xFFFFFB4B, 0x0000029E }, + { 0x0213F0FE990C28A4, 0x000034CA, 0xFFFFEA08, 0x000004FF, 0x00001C19, 0xFFFFF7ED, 0x00000309, 0x00001C19, 0xFFFFF7ED, 0x00000309 }, + { 0x0213F0FE991639A4, 0x00002187, 0xFFFFF4B0, 0x0000037E, 0x0000154A, 0xFFFFFB0C, 0x000002AE, 0x0000154A, 0xFFFFFB0C, 0x000002AE }, + { 0x0213F0FD42DA3844, 0x00002F4F, 0xFFFFEB3C, 0x000004F8, 0x0000181F, 0xFFFFF92D, 0x000002DF, 0x0000181F, 0xFFFFF92D, 0x000002DF }, + { 0x0213F0FE990410E4, 0x0000290C, 0xFFFFF0B1, 0x000003FC, 0x00001DB0, 0xFFFFF636, 0x00000355, 0x00001DB0, 0xFFFFF636, 0x00000355 }, + { 0x0213F0FE990A1064, 0x000034C1, 0xFFFFE888, 0x0000055A, 0x000019BF, 0xFFFFF881, 0x000002FB, 0x000019BF, 0xFFFFF881, 0x000002FB }, + { 0x0213F0FD42DC18C4, 0x00003139, 0xFFFFEA98, 0x00000504, 0x000019F2, 0xFFFFF820, 0x0000030B, 0x000019F2, 0xFFFFF820, 0x0000030B }, + { 0x0213F0FD42D83144, 0x00002CAC, 0xFFFFEEB2, 0x00000458, 0x0000152C, 0xFFFFFBEF, 0x0000027B, 0x0000152C, 0xFFFFFBEF, 0x0000027B }, + { 0x0213F0FE992C38E4, 0x00003577, 0xFFFFE99C, 0x0000050D, 0x00001E64, 0xFFFFF679, 0x0000033F, 0x00001E64, 0xFFFFF679, 0x0000033F }, + { 0x0213F0FD42DA4104, 0x0000263A, 0xFFFFF1E4, 0x000003D4, 0x00001F68, 0xFFFFF4ED, 0x00000386, 0x00001F68, 0xFFFFF4ED, 0x00000386 }, + { 0x0213F0FD42D81984, 0x00002CE9, 0xFFFFED63, 0x00000497, 0x00001810, 0xFFFFF94D, 0x000002E3, 0x00001810, 0xFFFFF94D, 0x000002E3 }, + { 0x0213EA94DE044104, 0x0000318A, 0xFFFFEAC8, 0x000004F5, 0x0000195C, 0xFFFFF896, 0x000002FB, 0x0000195C, 0xFFFFF896, 0x000002FB }, + { 0x0213F0FD42D83904, 0x00002C41, 0xFFFFEEC6, 0x0000045D, 0x000017DD, 0xFFFFFA16, 0x000002CB, 0x000017DD, 0xFFFFFA16, 0x000002CB }, + { 0x0213F0FE990231A4, 0x00002DD4, 0xFFFFEC98, 0x000004AD, 0x00001BD7, 0xFFFFF69F, 0x00000347, 0x00001BD7, 0xFFFFF69F, 0x00000347 }, + { 0x0213F0FD42DA3944, 0x00003351, 0xFFFFE9B2, 0x0000051A, 0x00001CA1, 0xFFFFF6A4, 0x00000341, 0x00001CA1, 0xFFFFF6A4, 0x00000341 }, + { 0x0213F0FE99021104, 0x0000322D, 0xFFFFE9BE, 0x00000527, 0x00001CF9, 0xFFFFF5EB, 0x00000366, 0x00001CF9, 0xFFFFF5EB, 0x00000366 }, + { 0x0213F0FE990C28C4, 0x00003678, 0xFFFFE9A8, 0x00000503, 0x00001AD4, 0xFFFFF8F6, 0x000002E3, 0x00001AD4, 0xFFFFF8F6, 0x000002E3 }, + { 0x0213F0FE99161924, 0x0000260E, 0xFFFFF2C1, 0x000003CA, 0x00001139, 0xFFFFFE48, 0x00000236, 0x00001139, 0xFFFFFE48, 0x00000236 }, + { 0x0213F0FE990A2164, 0x000033D3, 0xFFFFE872, 0x00000565, 0x00001B72, 0xFFFFF713, 0x00000332, 0x00001B72, 0xFFFFF713, 0x00000332 }, + { 0x0213F0FE99323844, 0x0000309B, 0xFFFFEB42, 0x000004E4, 0x00001918, 0xFFFFF8C8, 0x000002F2, 0x00001918, 0xFFFFF8C8, 0x000002F2 }, + { 0x0213F0FE99182864, 0x000028B8, 0xFFFFF105, 0x00000402, 0x000018BB, 0xFFFFF9BC, 0x000002D3, 0x000018BB, 0xFFFFF9BC, 0x000002D3 }, + { 0x0213F0FE990A1884, 0x00003123, 0xFFFFE9D1, 0x00000534, 0x00001B19, 0xFFFFF6FE, 0x0000033C, 0x00001B19, 0xFFFFF6FE, 0x0000033C }, + { 0x0213F0FE99022144, 0x00003216, 0xFFFFEA8E, 0x000004F6, 0x00001F72, 0xFFFFF4CE, 0x0000038B, 0x00001F72, 0xFFFFF4CE, 0x0000038B }, + { 0x0213F0FE99162964, 0x00002564, 0xFFFFF32D, 0x000003B6, 0x00001685, 0xFFFFFADB, 0x000002BB, 0x00001685, 0xFFFFFADB, 0x000002BB }, + { 0x0213F0FD42DA2924, 0x00002E60, 0xFFFFED13, 0x00000497, 0x00001CA5, 0xFFFFF6B9, 0x00000346, 0x00001CA5, 0xFFFFF6B9, 0x00000346 }, + { 0x0213F0FE990E39A4, 0x0000336D, 0xFFFFE934, 0x0000053B, 0x00001B3E, 0xFFFFF763, 0x00000327, 0x00001B3E, 0xFFFFF763, 0x00000327 }, + { 0x0213F0FE99101084, 0x0000274A, 0xFFFFF119, 0x000003FA, 0x00001D75, 0xFFFFF5CD, 0x0000036F, 0x00001D75, 0xFFFFF5CD, 0x0000036F }, + { 0x0213F0FD42DA2164, 0x0000366B, 0xFFFFE70A, 0x0000059A, 0x00001ED8, 0xFFFFF501, 0x00000389, 0x00001ED8, 0xFFFFF501, 0x00000389 }, + { 0x0213F0FE99223964, 0x00003164, 0xFFFFEAB4, 0x000004FA, 0x00001C52, 0xFFFFF6E0, 0x00000336, 0x00001C52, 0xFFFFF6E0, 0x00000336 }, + { 0x0213F0FD42D23064, 0x00004224, 0xFFFFDF7F, 0x000006C1, 0x00002A52, 0xFFFFED5E, 0x000004BB, 0x00002A52, 0xFFFFED5E, 0x000004BB }, + { 0x0213F0FE99102864, 0x000030E3, 0xFFFFEB07, 0x000004ED, 0x00001FD3, 0xFFFFF46D, 0x000003A1, 0x00001FD3, 0xFFFFF46D, 0x000003A1 }, + { 0x0213F0FD42D82884, 0x00002AEB, 0xFFFFEF1B, 0x00000454, 0x00001829, 0xFFFFF995, 0x000002DD, 0x00001829, 0xFFFFF995, 0x000002DD }, + { 0x0213F0FD42DC50E4, 0x0000346B, 0xFFFFE7A2, 0x0000058B, 0x000020C5, 0xFFFFF2E8, 0x000003EC, 0x000020C5, 0xFFFFF2E8, 0x000003EC }, + { 0x0213F0FD42DC4164, 0x000039CF, 0xFFFFE5D7, 0x000005A9, 0x00001D66, 0xFFFFF5D6, 0x00000366, 0x00001D66, 0xFFFFF5D6, 0x00000366 }, + { 0x0213F0FE990418E4, 0x000034AC, 0xFFFFE9AE, 0x00000515, 0x00001A28, 0xFFFFF904, 0x000002DC, 0x00001A28, 0xFFFFF904, 0x000002DC }, + { 0x0213F0FD42DC2084, 0x00002D68, 0xFFFFED21, 0x00000498, 0x00001C6F, 0xFFFFF686, 0x0000034C, 0x00001C6F, 0xFFFFF686, 0x0000034C }, + { 0x0213F0FE990820C4, 0x0000328B, 0xFFFFEBA1, 0x000004B4, 0x00001DA3, 0xFFFFF683, 0x00000349, 0x00001DA3, 0xFFFFF683, 0x00000349 }, + { 0x0213F0FE991828C4, 0x000027DC, 0xFFFFF295, 0x000003BF, 0x000019C1, 0xFFFFF98E, 0x000002E8, 0x000019C1, 0xFFFFF98E, 0x000002E8 }, + { 0x0213F0FE99184084, 0x00002756, 0xFFFFF1D7, 0x000003DF, 0x000015D9, 0xFFFFFB51, 0x00000298, 0x000015D9, 0xFFFFFB51, 0x00000298 }, + { 0x0213F0FE99083884, 0x00003526, 0xFFFFE907, 0x00000526, 0x000017AB, 0xFFFFFA12, 0x000002AB, 0x000017AB, 0xFFFFFA12, 0x000002AB }, + { 0x0213F0FD42DA18E4, 0x0000351B, 0xFFFFE8B7, 0x00000540, 0x00001A86, 0xFFFFF821, 0x00000303, 0x00001A86, 0xFFFFF821, 0x00000303 }, + { 0x0213F0FE99164144, 0x000024B2, 0xFFFFF34E, 0x000003B1, 0x000018E2, 0xFFFFF926, 0x000002FC, 0x000018E2, 0xFFFFF926, 0x000002FC }, + { 0x0213F0FD42D828A4, 0x00002F36, 0xFFFFED5D, 0x00000486, 0x0000157A, 0xFFFFFB85, 0x00000293, 0x0000157A, 0xFFFFFB85, 0x00000293 }, + { 0x0213F0FD42DC50C4, 0x00003A6E, 0xFFFFE456, 0x000005FD, 0x00001F68, 0xFFFFF3D1, 0x000003C3, 0x00001F68, 0xFFFFF3D1, 0x000003C3 }, + { 0x0213F0FE990A31A4, 0x00002BC3, 0xFFFFED2D, 0x000004A7, 0x00001C3F, 0xFFFFF609, 0x00000364, 0x00001C3F, 0xFFFFF609, 0x00000364 }, + { 0x0213F0FE990E2084, 0x000032E1, 0xFFFFEA83, 0x000004F6, 0x00001B37, 0xFFFFF842, 0x000002F5, 0x00001B37, 0xFFFFF842, 0x000002F5 }, + { 0x0213F0FD42D83184, 0x000028E3, 0xFFFFF07F, 0x00000412, 0x00001676, 0xFFFFFA68, 0x000002BE, 0x00001676, 0xFFFFFA68, 0x000002BE }, + { 0x0213F0FD42D21104, 0x0000444C, 0xFFFFDDAD, 0x00000712, 0x00002634, 0xFFFFEF89, 0x0000046C, 0x00002634, 0xFFFFEF89, 0x0000046C }, + { 0x0213F0FE990418C4, 0x00003121, 0xFFFFEBBB, 0x000004C6, 0x00001C98, 0xFFFFF72B, 0x0000032D, 0x00001C98, 0xFFFFF72B, 0x0000032D }, + { 0x0213F0FD42D840A4, 0x00002C31, 0xFFFFEDC4, 0x00000490, 0x0000162D, 0xFFFFFA8E, 0x000002B4, 0x0000162D, 0xFFFFFA8E, 0x000002B4 }, + { 0x0213F0FD42DA18C4, 0x00002749, 0xFFFFF112, 0x000003FC, 0x00001C85, 0xFFFFF6B8, 0x00000342, 0x00001C85, 0xFFFFF6B8, 0x00000342 }, + { 0x0213F0FE99044104, 0x00003159, 0xFFFFEB99, 0x000004C2, 0x00001BD0, 0xFFFFF7CA, 0x00000307, 0x00001BD0, 0xFFFFF7CA, 0x00000307 }, + { 0x0213F0FE99164164, 0x00002610, 0xFFFFF1FD, 0x000003EC, 0x000016BE, 0xFFFFFA53, 0x000002CB, 0x000016BE, 0xFFFFFA53, 0x000002CB }, + { 0x0213F0FE99023184, 0x000037B5, 0xFFFFE63D, 0x000005B5, 0x00002285, 0xFFFFF25D, 0x000003F7, 0x00002285, 0xFFFFF25D, 0x000003F7 }, + { 0x0213F0FE990A28A4, 0x00002FEE, 0xFFFFEB47, 0x000004EF, 0x00001CBE, 0xFFFFF64E, 0x00000358, 0x00001CBE, 0xFFFFF64E, 0x00000358 }, + { 0x0213F0FE99105104, 0x00002E90, 0xFFFFEC48, 0x000004C0, 0x00001A47, 0xFFFFF7D1, 0x0000031A, 0x00001A47, 0xFFFFF7D1, 0x0000031A }, + { 0x0213F0FD42DA4084, 0x000034AB, 0xFFFFE84A, 0x00000559, 0x00001A72, 0xFFFFF79A, 0x0000031C, 0x00001A72, 0xFFFFF79A, 0x0000031C }, + { 0x0213F0FE99183884, 0x00002F7B, 0xFFFFECFC, 0x0000049C, 0x00001814, 0xFFFFFA22, 0x000002C2, 0x00001814, 0xFFFFFA22, 0x000002C2 }, + { 0x0213F0FE99021964, 0x00003618, 0xFFFFE709, 0x00000596, 0x00001EBF, 0xFFFFF482, 0x000003A5, 0x00001EBF, 0xFFFFF482, 0x000003A5 }, + { 0x0213EA94DE024904, 0x0000341B, 0xFFFFE8B2, 0x0000054F, 0x00001D26, 0xFFFFF578, 0x00000388, 0x00001D26, 0xFFFFF578, 0x00000388 }, + { 0x0213F0FE99102144, 0x000030F6, 0xFFFFEB89, 0x000004CD, 0x000019C0, 0xFFFFF8CC, 0x000002E6, 0x000019C0, 0xFFFFF8CC, 0x000002E6 }, + { 0x0213F0FE992841A4, 0x00002B76, 0xFFFFEF6C, 0x00000444, 0x00001563, 0xFFFFFBBE, 0x0000028D, 0x00001563, 0xFFFFFBBE, 0x0000028D }, + { 0x0213F0FD42D81864, 0x00002BA2, 0xFFFFEE31, 0x0000047F, 0x00001A3D, 0xFFFFF7F3, 0x00000320, 0x00001A3D, 0xFFFFF7F3, 0x00000320 }, + { 0x0213F0FE992C48E4, 0x00003545, 0xFFFFE87A, 0x0000054A, 0x00001B5A, 0xFFFFF7B0, 0x0000030C, 0x00001B5A, 0xFFFFF7B0, 0x0000030C }, + { 0x0213EA94DE042944, 0x00003879, 0xFFFFE73F, 0x00000578, 0x00001649, 0xFFFFFB57, 0x00000283, 0x00001649, 0xFFFFFB57, 0x00000283 }, + { 0x0213F0FD42D840C4, 0x00002772, 0xFFFFF0F1, 0x00000410, 0x0000142F, 0xFFFFFBCF, 0x00000287, 0x0000142F, 0xFFFFFBCF, 0x00000287 }, + { 0x0213F0FD42DA3184, 0x00003228, 0xFFFFE98E, 0x00000535, 0x00001F48, 0xFFFFF495, 0x00000399, 0x00001F48, 0xFFFFF495, 0x00000399 }, + { 0x0213F0FE990E40E4, 0x00002887, 0xFFFFF119, 0x000003E8, 0x000021AA, 0xFFFFF3F5, 0x000003A5, 0x000021AA, 0xFFFFF3F5, 0x000003A5 }, + { 0x0213F0FD42DA28A4, 0x0000301F, 0xFFFFEBB2, 0x000004D2, 0x00001C02, 0xFFFFF736, 0x0000032B, 0x00001C02, 0xFFFFF736, 0x0000032B }, + { 0x0213F0FE991820A4, 0x00002E13, 0xFFFFEE3F, 0x00000468, 0x000016AC, 0xFFFFFB32, 0x0000029E, 0x000016AC, 0xFFFFFB32, 0x0000029E }, + { 0x0213F0FE99044924, 0x00003478, 0xFFFFE8F9, 0x00000538, 0x00001DAB, 0xFFFFF645, 0x00000345, 0x00001DAB, 0xFFFFF645, 0x00000345 }, + { 0x0213F0FE990608C4, 0x000030C6, 0xFFFFEB6C, 0x000004D4, 0x0000184A, 0xFFFFF934, 0x000002E1, 0x0000184A, 0xFFFFF934, 0x000002E1 }, + { 0x0213F0FE990A2044, 0x00002F1B, 0xFFFFEBD3, 0x000004D3, 0x000019E7, 0xFFFFF813, 0x0000030D, 0x000019E7, 0xFFFFF813, 0x0000030D }, + { 0x0213F0FE99023904, 0x00003214, 0xFFFFEAE9, 0x000004E0, 0x0000178F, 0xFFFFFA1C, 0x000002B1, 0x0000178F, 0xFFFFFA1C, 0x000002B1 }, + { 0x0213F0FD42DC3144, 0x0000399C, 0xFFFFE738, 0x0000055E, 0x00001EA1, 0xFFFFF5E7, 0x0000035A, 0x00001EA1, 0xFFFFF5E7, 0x0000035A }, + { 0x0213F0FE990650C4, 0x00003A01, 0xFFFFE5B2, 0x000005B6, 0x00001D95, 0xFFFFF5D2, 0x0000036A, 0x00001D95, 0xFFFFF5D2, 0x0000036A }, + { 0x0213F0FE99043884, 0x0000310D, 0xFFFFEB78, 0x000004D0, 0x00001C06, 0xFFFFF76E, 0x0000031A, 0x00001C06, 0xFFFFF76E, 0x0000031A }, + { 0x0213F0FE99063864, 0x00003CD1, 0xFFFFE42F, 0x000005EB, 0x00001933, 0xFFFFF91F, 0x000002D4, 0x00001933, 0xFFFFF91F, 0x000002D4 }, + { 0x0213F0FD42DA3164, 0x00003119, 0xFFFFEB1B, 0x000004E1, 0x00001FC7, 0xFFFFF46A, 0x000003A2, 0x00001FC7, 0xFFFFF46A, 0x000003A2 }, + { 0x0213EA94DE0648A4, 0x0000390D, 0xFFFFE566, 0x000005D8, 0x00001EC6, 0xFFFFF4DC, 0x00000391, 0x00001EC6, 0xFFFFF4DC, 0x00000391 }, + { 0x0213F0FD42DA10C4, 0x00003446, 0xFFFFE858, 0x00000561, 0x00001FDB, 0xFFFFF3FF, 0x000003B9, 0x00001FDB, 0xFFFFF3FF, 0x000003B9 }, + { 0x0213F0FE99044904, 0x000032BA, 0xFFFFEA07, 0x00000511, 0x00001B25, 0xFFFFF7C9, 0x0000030D, 0x00001B25, 0xFFFFF7C9, 0x0000030D }, + { 0x0213F0FE990E1864, 0x00002CCF, 0xFFFFEDE5, 0x00000478, 0x00001BC8, 0xFFFFF761, 0x00000326, 0x00001BC8, 0xFFFFF761, 0x00000326 }, + { 0x0213F0FE99062984, 0x0000400E, 0xFFFFE1CB, 0x00000652, 0x00001AF8, 0xFFFFF7B9, 0x00000312, 0x00001AF8, 0xFFFFF7B9, 0x00000312 }, + { 0x0213F0FE990408E4, 0x00002F24, 0xFFFFEC2A, 0x000004C7, 0x00001B94, 0xFFFFF748, 0x00000333, 0x00001B94, 0xFFFFF748, 0x00000333 }, + { 0x0213F0FD42D21924, 0x00003FDA, 0xFFFFE1C1, 0x0000064B, 0x00002427, 0xFFFFF180, 0x0000040C, 0x00002427, 0xFFFFF180, 0x0000040C }, + { 0x0213F0FE990A18C4, 0x00002F6B, 0xFFFFEBA7, 0x000004DD, 0x00001C25, 0xFFFFF6C1, 0x00000344, 0x00001C25, 0xFFFFF6C1, 0x00000344 }, + { 0x0213F0FE99182104, 0x00002A53, 0xFFFFF0EE, 0x00000402, 0x000017C6, 0xFFFFFAA0, 0x000002BF, 0x000017C6, 0xFFFFFAA0, 0x000002BF }, + { 0x0213F0FE99105144, 0x000031F4, 0xFFFFEA34, 0x00000517, 0x000016FF, 0xFFFFFA4E, 0x000002AC, 0x000016FF, 0xFFFFFA4E, 0x000002AC }, + { 0x0213F0FE99322144, 0x00002E24, 0xFFFFED46, 0x00000489, 0x00001712, 0xFFFFFA5D, 0x000002AC, 0x00001712, 0xFFFFFA5D, 0x000002AC }, + { 0x0213F0FE99182824, 0x000028CD, 0xFFFFF0E3, 0x0000040E, 0x00001606, 0xFFFFFB37, 0x000002A4, 0x00001606, 0xFFFFFB37, 0x000002A4 }, + { 0x0213F0FE990220C4, 0x00003184, 0xFFFFEB88, 0x000004C3, 0x000018DA, 0xFFFFF939, 0x000002DB, 0x000018DA, 0xFFFFF939, 0x000002DB }, + { 0x0213F0FE99162124, 0x0000239B, 0xFFFFF470, 0x00000386, 0x00001714, 0xFFFFFA9F, 0x000002C8, 0x00001714, 0xFFFFFA9F, 0x000002C8 }, + { 0x0213F0FD42DC38E4, 0x00003641, 0xFFFFE92B, 0x00000515, 0x00001BE2, 0xFFFFF795, 0x0000031B, 0x00001BE2, 0xFFFFF795, 0x0000031B }, + { 0x0213F0FE992C1144, 0x00003278, 0xFFFFEA17, 0x00000510, 0x00001B71, 0xFFFFF778, 0x0000031D, 0x00001B71, 0xFFFFF778, 0x0000031D }, + { 0x0213F0FE99062844, 0x000035B9, 0xFFFFE8DA, 0x0000052D, 0x00001A6A, 0xFFFFF83B, 0x000002FF, 0x00001A6A, 0xFFFFF83B, 0x000002FF }, + { 0x0213F0FE990E18C4, 0x00002E5E, 0xFFFFED32, 0x0000048B, 0x00001E7D, 0xFFFFF60E, 0x0000034E, 0x00001E7D, 0xFFFFF60E, 0x0000034E }, + { 0x0213F0FE991019A4, 0x00003178, 0xFFFFEA52, 0x00000513, 0x00001AD0, 0xFFFFF793, 0x0000031F, 0x00001AD0, 0xFFFFF793, 0x0000031F }, + { 0x0213F0FD42D44104, 0x00003A2C, 0xFFFFE346, 0x00000641, 0x000023D0, 0xFFFFF0CE, 0x00000433, 0x000023D0, 0xFFFFF0CE, 0x00000433 }, + { 0x0213F0FD42D818C4, 0x000028FD, 0xFFFFF02A, 0x0000042B, 0x0000152B, 0xFFFFFB90, 0x00000289, 0x0000152B, 0xFFFFFB90, 0x00000289 }, + { 0x0213F0FE990E3084, 0x000030DE, 0xFFFFEBDF, 0x000004BE, 0x00001CDC, 0xFFFFF747, 0x0000031C, 0x00001CDC, 0xFFFFF747, 0x0000031C }, + { 0x0213F0FE99021944, 0x000036CB, 0xFFFFE6EE, 0x00000596, 0x00002096, 0xFFFFF3C2, 0x000003BB, 0x00002096, 0xFFFFF3C2, 0x000003BB }, + { 0x0213F0FE990C48C4, 0x00003172, 0xFFFFEAC1, 0x000004F4, 0x00001C87, 0xFFFFF6CD, 0x00000337, 0x00001C87, 0xFFFFF6CD, 0x00000337 }, + { 0x0213F0FD42D24864, 0x00004A18, 0xFFFFDB34, 0x00000758, 0x0000213C, 0xFFFFF3A2, 0x000003AC, 0x0000213C, 0xFFFFF3A2, 0x000003AC }, + { 0x0213F0FE99022104, 0x000031F3, 0xFFFFEB73, 0x000004C6, 0x00001B23, 0xFFFFF7CB, 0x0000031A, 0x00001B23, 0xFFFFF7CB, 0x0000031A }, + { 0x0213F0FE990A2924, 0x000031C0, 0xFFFFEABA, 0x000004F7, 0x00001A5A, 0xFFFFF845, 0x000002FF, 0x00001A5A, 0xFFFFF845, 0x000002FF }, + { 0x0213F0FE99104944, 0x00003B77, 0xFFFFE3B3, 0x00000623, 0x00001BCA, 0xFFFFF6F8, 0x00000333, 0x00001BCA, 0xFFFFF6F8, 0x00000333 }, + { 0x0213F0FE990A3944, 0x000035AF, 0xFFFFE76D, 0x00000588, 0x00001C16, 0xFFFFF6AB, 0x00000341, 0x00001C16, 0xFFFFF6AB, 0x00000341 }, + { 0x0213EA94DE0438C4, 0x000032AD, 0xFFFFEA8E, 0x000004F8, 0x00001A3A, 0xFFFFF832, 0x0000030E, 0x00001A3A, 0xFFFFF832, 0x0000030E }, + { 0x0213F0FE99104884, 0x00002E92, 0xFFFFEBD2, 0x000004DA, 0x00001E04, 0xFFFFF51E, 0x0000038A, 0x00001E04, 0xFFFFF51E, 0x0000038A }, + { 0x0213F0FD42D440A4, 0x00003E57, 0xFFFFE0F7, 0x0000068F, 0x000021F1, 0xFFFFF1C6, 0x00000411, 0x000021F1, 0xFFFFF1C6, 0x00000411 }, + { 0x0213F0FE990821A4, 0x00003598, 0xFFFFE8BB, 0x00000535, 0x00001B62, 0xFFFFF764, 0x00000326, 0x00001B62, 0xFFFFF764, 0x00000326 }, + { 0x0213F0FE990A3884, 0x00002B15, 0xFFFFEDEC, 0x00000487, 0x00001E8B, 0xFFFFF4AB, 0x0000039F, 0x00001E8B, 0xFFFFF4AB, 0x0000039F }, + { 0x0213EA94DE060904, 0x0000267E, 0xFFFFF1A7, 0x000003E1, 0x000021C1, 0xFFFFF2E9, 0x000003EA, 0x000021C1, 0xFFFFF2E9, 0x000003EA }, + { 0x0213EA94DE0239A4, 0x00002ED7, 0xFFFFEC88, 0x000004A6, 0x00001DEC, 0xFFFFF57C, 0x00000378, 0x00001DEC, 0xFFFFF57C, 0x00000378 }, + { 0x0213EA94DE0441A4, 0x00003365, 0xFFFFE946, 0x00000536, 0x000019E9, 0xFFFFF7E0, 0x0000031D, 0x000019E9, 0xFFFFF7E0, 0x0000031D }, + { 0x0213F0FE991818E4, 0x000029A4, 0xFFFFF0FD, 0x000003FE, 0x0000163F, 0xFFFFFB68, 0x00000299, 0x0000163F, 0xFFFFFB68, 0x00000299 }, + { 0x0213EA94DE021904, 0x0000348D, 0xFFFFE9F7, 0x00000509, 0x000017A0, 0xFFFFFA59, 0x000002B6, 0x000017A0, 0xFFFFFA59, 0x000002B6 }, + { 0x0213F0FE990610C4, 0x00003144, 0xFFFFEB23, 0x000004D9, 0x00001C9B, 0xFFFFF664, 0x00000351, 0x00001C9B, 0xFFFFF664, 0x00000351 }, + { 0x0213EA94DE0620E4, 0x00002E95, 0xFFFFEE1A, 0x00000463, 0x00001707, 0xFFFFFAB7, 0x000002B3, 0x00001707, 0xFFFFFAB7, 0x000002B3 }, + { 0x0213F0FD42D41864, 0x0000489C, 0xFFFFDA43, 0x000007AC, 0x00002866, 0xFFFFED6B, 0x000004D0, 0x00002866, 0xFFFFED6B, 0x000004D0 }, + { 0x0213F0FE99161844, 0x00002895, 0xFFFFF10A, 0x0000040A, 0x000013E9, 0xFFFFFC9F, 0x0000026E, 0x000013E9, 0xFFFFFC9F, 0x0000026E }, + { 0x0213F0FE99061964, 0x000033A0, 0xFFFFE9B1, 0x00000510, 0x00001D96, 0xFFFFF5AE, 0x0000036F, 0x00001D96, 0xFFFFF5AE, 0x0000036F }, + { 0x0213F0FE99083984, 0x0000327C, 0xFFFFEAEA, 0x000004DD, 0x00001D45, 0xFFFFF649, 0x00000356, 0x00001D45, 0xFFFFF649, 0x00000356 }, + { 0x0213EA94DE0248A4, 0x000031DF, 0xFFFFE9AB, 0x0000052F, 0x000019C8, 0xFFFFF7B7, 0x00000321, 0x000019C8, 0xFFFFF7B7, 0x00000321 }, + { 0x0213F0FE991640A4, 0x00002BCC, 0xFFFFEEF4, 0x0000045C, 0x000015CD, 0xFFFFFB58, 0x0000029E, 0x000015CD, 0xFFFFFB58, 0x0000029E }, + { 0x0213F0FE990638E4, 0x00003534, 0xFFFFEA10, 0x000004EB, 0x00001BB6, 0xFFFFF7B9, 0x00000314, 0x00001BB6, 0xFFFFF7B9, 0x00000314 }, + { 0x0213F0FE99041984, 0x00002F4F, 0xFFFFEC35, 0x000004B9, 0x0000205D, 0xFFFFF47F, 0x00000392, 0x0000205D, 0xFFFFF47F, 0x00000392 }, + { 0x0213F0FE990C20A4, 0x00003295, 0xFFFFEB1C, 0x000004D6, 0x000019C1, 0xFFFFF931, 0x000002D5, 0x000019C1, 0xFFFFF931, 0x000002D5 }, + { 0x0213F0FE99024144, 0x00003557, 0xFFFFE7F7, 0x00000568, 0x00002342, 0xFFFFF1F9, 0x00000405, 0x00002342, 0xFFFFF1F9, 0x00000405 }, + { 0x0213F0FE990450C4, 0x00003487, 0xFFFFE872, 0x0000055D, 0x000019D7, 0xFFFFF823, 0x0000030C, 0x000019D7, 0xFFFFF823, 0x0000030C }, + { 0x0213F0FE992C3944, 0x0000378F, 0xFFFFE7A6, 0x00000566, 0x00001875, 0xFFFFFA04, 0x000002AF, 0x00001875, 0xFFFFFA04, 0x000002AF }, + { 0x0213EA94DE0230E4, 0x00002A67, 0xFFFFF157, 0x000003DD, 0x000017BD, 0xFFFFFA53, 0x000002D1, 0x000017BD, 0xFFFFFA53, 0x000002D1 }, + { 0x0213F0FD42D220E4, 0x000030B5, 0xFFFFEB32, 0x000004D9, 0x00002129, 0xFFFFF38A, 0x000003BB, 0x00002129, 0xFFFFF38A, 0x000003BB }, + { 0x0213F0FE990610A4, 0x00003786, 0xFFFFE703, 0x00000584, 0x00001D63, 0xFFFFF5DC, 0x00000367, 0x00001D63, 0xFFFFF5DC, 0x00000367 }, + { 0x0213F0FD42DA20C4, 0x0000346A, 0xFFFFE93E, 0x0000052C, 0x00001B27, 0xFFFFF79D, 0x0000031F, 0x00001B27, 0xFFFFF79D, 0x0000031F }, + { 0x0213F0FE990E3024, 0x0000294E, 0xFFFFF0A5, 0x00000409, 0x00001928, 0xFFFFF93B, 0x000002E6, 0x00001928, 0xFFFFF93B, 0x000002E6 }, + { 0x0213F0FD42D410C4, 0x00003E09, 0xFFFFE0FF, 0x00000694, 0x000025A0, 0xFFFFEF0F, 0x0000048F, 0x000025A0, 0xFFFFEF0F, 0x0000048F }, + { 0x0213F0FE990A2964, 0x00003197, 0xFFFFEA06, 0x00000520, 0x00001B42, 0xFFFFF73B, 0x0000032A, 0x00001B42, 0xFFFFF73B, 0x0000032A }, + { 0x0213F0FE99161864, 0x000022CB, 0xFFFFF3FC, 0x000003A3, 0x00001449, 0xFFFFFBD0, 0x00000297, 0x00001449, 0xFFFFFBD0, 0x00000297 }, + { 0x0213F0FD42D82944, 0x00002A79, 0xFFFFEFD2, 0x00000433, 0x00001585, 0xFFFFFB92, 0x0000028E, 0x00001585, 0xFFFFFB92, 0x0000028E }, + { 0x0213F0FE990C4184, 0x00003249, 0xFFFFEA92, 0x000004F4, 0x000019CB, 0xFFFFF8CF, 0x000002E1, 0x000019CB, 0xFFFFF8CF, 0x000002E1 }, + { 0x0213EA94DE0218A4, 0x00002CEA, 0xFFFFEE46, 0x00000463, 0x00001A5E, 0xFFFFF83C, 0x0000030D, 0x00001A5E, 0xFFFFF83C, 0x0000030D }, + { 0x0213F0FD42DC5144, 0x00003AE2, 0xFFFFE422, 0x00000600, 0x00001C65, 0xFFFFF62F, 0x0000034B, 0x00001C65, 0xFFFFF62F, 0x0000034B }, + { 0x0213F0FE99181184, 0x000026A0, 0xFFFFF1C2, 0x000003F8, 0x000010E5, 0xFFFFFE56, 0x0000022A, 0x000010E5, 0xFFFFFE56, 0x0000022A }, + { 0x0213F0FE992829A4, 0x00002A7B, 0xFFFFF063, 0x00000417, 0x000016FC, 0xFFFFFAD7, 0x000002B1, 0x000016FC, 0xFFFFFAD7, 0x000002B1 }, + { 0x0213F0FE993210C4, 0x00003092, 0xFFFFEAB9, 0x00000507, 0x00001AE3, 0xFFFFF783, 0x00000323, 0x00001AE3, 0xFFFFF783, 0x00000323 }, + { 0x0213F0FE990438E4, 0x00003265, 0xFFFFEBE8, 0x000004AA, 0x00001D65, 0xFFFFF73F, 0x00000321, 0x00001D65, 0xFFFFF73F, 0x00000321 }, + { 0x0213EA94DE023084, 0x00002F14, 0xFFFFECC2, 0x000004A4, 0x00001A8D, 0xFFFFF7F3, 0x0000031D, 0x00001A8D, 0xFFFFF7F3, 0x0000031D }, + { 0x0213F0FD42DC10E4, 0x000035FB, 0xFFFFE6D3, 0x000005AC, 0x00001B19, 0xFFFFF712, 0x00000338, 0x00001B19, 0xFFFFF712, 0x00000338 }, + { 0x0213F0FD42DA2124, 0x00003519, 0xFFFFE8CC, 0x0000053A, 0x00001A0F, 0xFFFFF86E, 0x000002F5, 0x00001A0F, 0xFFFFF86E, 0x000002F5 }, + { 0x0213F0FE992C2144, 0x0000364C, 0xFFFFE879, 0x00000541, 0x00001A42, 0xFFFFF8BA, 0x000002E2, 0x00001A42, 0xFFFFF8BA, 0x000002E2 }, + { 0x0213EA94DE0218C4, 0x000029BA, 0xFFFFF09A, 0x00000408, 0x00001986, 0xFFFFF8D9, 0x000002FE, 0x00001986, 0xFFFFF8D9, 0x000002FE }, + { 0x0213F0FD42DA38E4, 0x00003507, 0xFFFFE961, 0x00000518, 0x00001B79, 0xFFFFF775, 0x00000325, 0x00001B79, 0xFFFFF775, 0x00000325 }, + { 0x0213F0FD42DC3184, 0x00003AD5, 0xFFFFE415, 0x00000613, 0x00001CB4, 0xFFFFF66D, 0x00000348, 0x00001CB4, 0xFFFFF66D, 0x00000348 }, + { 0x0213F0FE991640E4, 0x000023D1, 0xFFFFF42B, 0x0000038F, 0x00001546, 0xFFFFFBA0, 0x0000029F, 0x00001546, 0xFFFFFBA0, 0x0000029F }, + { 0x0213F0FE990A1924, 0x0000399E, 0xFFFFE518, 0x000005E7, 0x00001990, 0xFFFFF871, 0x000002FB, 0x00001990, 0xFFFFF871, 0x000002FB }, + { 0x0213F0FD42D82964, 0x00002EDE, 0xFFFFEC93, 0x000004B8, 0x0000152C, 0xFFFFFBB3, 0x0000027E, 0x0000152C, 0xFFFFFBB3, 0x0000027E }, + { 0x0213EA94DE042964, 0x00003140, 0xFFFFEBC9, 0x000004BB, 0x000016BE, 0xFFFFFB0A, 0x00000288, 0x000016BE, 0xFFFFFB0A, 0x00000288 }, + { 0x0213F0FE99064064, 0x000030F6, 0xFFFFEB89, 0x000004CD, 0x0000185D, 0xFFFFF95A, 0x000002D9, 0x0000185D, 0xFFFFF95A, 0x000002D9 }, + { 0x0213F0FE99023844, 0x0000389C, 0xFFFFE65A, 0x000005A2, 0x0000195D, 0xFFFFF8C8, 0x000002E8, 0x0000195D, 0xFFFFF8C8, 0x000002E8 }, + { 0x0213F0FE99042104, 0x0000362B, 0xFFFFE9EC, 0x000004F6, 0x00001605, 0xFFFFFC1C, 0x00000263, 0x00001605, 0xFFFFFC1C, 0x00000263 }, + { 0x0213F0FE992A1964, 0x00002946, 0xFFFFF04F, 0x00000426, 0x000015BA, 0xFFFFFB2F, 0x000002A3, 0x000015BA, 0xFFFFFB2F, 0x000002A3 }, + { 0x0213F0FE99082184, 0x0000368E, 0xFFFFE837, 0x0000054A, 0x000017D7, 0xFFFFF9EB, 0x000002BA, 0x000017D7, 0xFFFFF9EB, 0x000002BA }, + { 0x0213F0FD42DA2844, 0x00002E74, 0xFFFFEBE8, 0x000004DA, 0x00001DD6, 0xFFFFF57E, 0x00000379, 0x00001DD6, 0xFFFFF57E, 0x00000379 }, + { 0x0213F0FE99041944, 0x0000322D, 0xFFFFEAA8, 0x000004F5, 0x00001B55, 0xFFFFF7DD, 0x0000030B, 0x00001B55, 0xFFFFF7DD, 0x0000030B }, + { 0x0213F0FE99181904, 0x00002A29, 0xFFFFF07B, 0x00000416, 0x00001671, 0xFFFFFB3E, 0x0000029F, 0x00001671, 0xFFFFFB3E, 0x0000029F }, + { 0x0213F0FD42DA2104, 0x000030F6, 0xFFFFEB89, 0x000004CD, 0x00001815, 0xFFFFF9AE, 0x000002C9, 0x00001815, 0xFFFFF9AE, 0x000002C9 }, + { 0x0213F0FE990E10E4, 0x0000265F, 0xFFFFF1CB, 0x000003D5, 0x00001ED2, 0xFFFFF539, 0x0000037A, 0x00001ED2, 0xFFFFF539, 0x0000037A }, + { 0x0213F0FE99162184, 0x000027A8, 0xFFFFF10D, 0x00000413, 0x000014B5, 0xFFFFFBA1, 0x00000299, 0x000014B5, 0xFFFFFBA1, 0x00000299 }, + { 0x0213F0FE99043064, 0x00002CEE, 0xFFFFEDF6, 0x00000476, 0x00001A99, 0xFFFFF83E, 0x00000305, 0x00001A99, 0xFFFFF83E, 0x00000305 }, + { 0x0213F0FE990640C4, 0x0000346C, 0xFFFFEA17, 0x000004EF, 0x00001D38, 0xFFFFF69F, 0x0000033D, 0x00001D38, 0xFFFFF69F, 0x0000033D }, + { 0x0213F0FD42DA2944, 0x00002DBB, 0xFFFFED35, 0x00000490, 0x000018C1, 0xFFFFF930, 0x000002DA, 0x000018C1, 0xFFFFF930, 0x000002DA }, + { 0x0213F0FE99042924, 0x000038DF, 0xFFFFE8A7, 0x0000051E, 0x00001B59, 0xFFFFF915, 0x000002D3, 0x00001B59, 0xFFFFF915, 0x000002D3 }, + { 0x0213F0FE99080944, 0x00003384, 0xFFFFE979, 0x00000524, 0x00001AF3, 0xFFFFF74C, 0x0000032F, 0x00001AF3, 0xFFFFF74C, 0x0000032F }, + { 0x0213F0FE99181864, 0x0000258B, 0xFFFFF2AE, 0x000003CB, 0x0000190C, 0xFFFFF93E, 0x000002EF, 0x0000190C, 0xFFFFF93E, 0x000002EF }, + { 0x0213F0FE99103884, 0x000034F1, 0xFFFFE84B, 0x0000055E, 0x00001CB8, 0xFFFFF670, 0x0000034A, 0x00001CB8, 0xFFFFF670, 0x0000034A }, + { 0x0213F0FE990C2104, 0x000030FB, 0xFFFFECD2, 0x00000488, 0x00001BF4, 0xFFFFF821, 0x00000302, 0x00001BF4, 0xFFFFF821, 0x00000302 }, + { 0x0213F0FE99063044, 0x000036A6, 0xFFFFE815, 0x00000556, 0x000018FD, 0xFFFFF925, 0x000002DF, 0x000018FD, 0xFFFFF925, 0x000002DF }, + { 0x0213EA94DE023044, 0x0000302A, 0xFFFFEB79, 0x000004E0, 0x00001C11, 0xFFFFF694, 0x00000358, 0x00001C11, 0xFFFFF694, 0x00000358 }, + { 0x0213F0FE99181124, 0x00002555, 0xFFFFF2C4, 0x000003CB, 0x000017E3, 0xFFFFFA1F, 0x000002CB, 0x000017E3, 0xFFFFFA1F, 0x000002CB }, + { 0x0213F0FE990A3164, 0x000032A3, 0xFFFFE933, 0x00000544, 0x000019D3, 0xFFFFF81A, 0x00000306, 0x000019D3, 0xFFFFF81A, 0x00000306 }, + { 0x0213F0FD42D85104, 0x00002B91, 0xFFFFED81, 0x000004A9, 0x0000158B, 0xFFFFFAB9, 0x000002AC, 0x0000158B, 0xFFFFFAB9, 0x000002AC }, + { 0x0213F0FE990E20C4, 0x00003537, 0xFFFFE912, 0x0000052C, 0x00001C8A, 0xFFFFF754, 0x0000031B, 0x00001C8A, 0xFFFFF754, 0x0000031B }, + { 0x0213EA94DE063184, 0x000032E1, 0xFFFFEA5A, 0x000004F9, 0x000017B4, 0xFFFFF9D9, 0x000002C2, 0x000017B4, 0xFFFFF9D9, 0x000002C2 }, + { 0x0213F0FD42D210C4, 0x00003B76, 0xFFFFE330, 0x00000636, 0x000026FB, 0xFFFFEF06, 0x00000481, 0x000026FB, 0xFFFFEF06, 0x00000481 }, + { 0x0213F0FE99042144, 0x0000320C, 0xFFFFEB84, 0x000004C3, 0x00001A3A, 0xFFFFF8E9, 0x000002DF, 0x00001A3A, 0xFFFFF8E9, 0x000002DF }, + { 0x0213F0FE99023984, 0x0000317D, 0xFFFFEA1F, 0x00000515, 0x00002100, 0xFFFFF31B, 0x000003DD, 0x00002100, 0xFFFFF31B, 0x000003DD }, + { 0x0213F0FD42D43164, 0x00003DCB, 0xFFFFE0B4, 0x000006B4, 0x00002160, 0xFFFFF269, 0x000003F0, 0x00002160, 0xFFFFF269, 0x000003F0 }, + { 0x0213F0FE991618C4, 0x00002737, 0xFFFFF218, 0x000003E1, 0x000015B5, 0xFFFFFB8F, 0x0000029C, 0x000015B5, 0xFFFFFB8F, 0x0000029C }, + { 0x0213EA94DE023184, 0x0000318F, 0xFFFFEB3F, 0x000004D8, 0x00001938, 0xFFFFF8E9, 0x000002EB, 0x00001938, 0xFFFFF8E9, 0x000002EB }, + { 0x0213F0FE991048C4, 0x000031BD, 0xFFFFE9DE, 0x00000527, 0x000018A7, 0xFFFFF8CA, 0x000002ED, 0x000018A7, 0xFFFFF8CA, 0x000002ED }, + { 0x0213F0FD42DA3884, 0x00002F77, 0xFFFFEC2F, 0x000004B4, 0x00001D25, 0xFFFFF61B, 0x0000035D, 0x00001D25, 0xFFFFF61B, 0x0000035D }, + { 0x0213F0FE990E4904, 0x00002CCA, 0xFFFFEDB3, 0x0000047C, 0x00001FBD, 0xFFFFF4A7, 0x00000391, 0x00001FBD, 0xFFFFF4A7, 0x00000391 }, + { 0x0213F0FD42D438A4, 0x00003FF6, 0xFFFFE058, 0x000006A2, 0x000024CD, 0xFFFFF026, 0x00000452, 0x000024CD, 0xFFFFF026, 0x00000452 }, + { 0x0213F0FE990A38E4, 0x00003161, 0xFFFFEAC8, 0x000004F3, 0x00001BB6, 0xFFFFF72A, 0x0000032B, 0x00001BB6, 0xFFFFF72A, 0x0000032B }, + { 0x0213F0FD42D838A4, 0x00002EA0, 0xFFFFECA6, 0x000004B7, 0x000018C2, 0xFFFFF94E, 0x000002E1, 0x000018C2, 0xFFFFF94E, 0x000002E1 }, + { 0x0213F0FE99182184, 0x00002F62, 0xFFFFEC9E, 0x000004B8, 0x00001531, 0xFFFFFBCD, 0x00000285, 0x00001531, 0xFFFFFBCD, 0x00000285 }, + { 0x0213F0FE990440A4, 0x00003013, 0xFFFFEBD6, 0x000004C2, 0x00001B01, 0xFFFFF802, 0x000002FF, 0x00001B01, 0xFFFFF802, 0x000002FF }, + { 0x0213F0FE99183064, 0x00002972, 0xFFFFF08D, 0x00000417, 0x00001A32, 0xFFFFF8A4, 0x00000305, 0x00001A32, 0xFFFFF8A4, 0x00000305 }, + { 0x0213F0FD42D820E4, 0x00002E95, 0xFFFFED94, 0x00000487, 0x00001529, 0xFFFFFC26, 0x00000271, 0x00001529, 0xFFFFFC26, 0x00000271 }, + { 0x0213F0FE990A1084, 0x00002D6A, 0xFFFFEC79, 0x000004C1, 0x00001AE2, 0xFFFFF725, 0x00000337, 0x00001AE2, 0xFFFFF725, 0x00000337 }, + { 0x0213F0FE99021884, 0x000036B4, 0xFFFFE704, 0x00000591, 0x00001E7E, 0xFFFFF51C, 0x00000383, 0x00001E7E, 0xFFFFF51C, 0x00000383 }, + { 0x0213F0FE99041844, 0x00002A6F, 0xFFFFEF70, 0x00000443, 0x00001BAA, 0xFFFFF752, 0x00000336, 0x00001BAA, 0xFFFFF752, 0x00000336 }, + { 0x0213F0FE99183944, 0x00002C66, 0xFFFFEF5F, 0x0000043A, 0x000019F7, 0xFFFFF931, 0x000002EC, 0x000019F7, 0xFFFFF931, 0x000002EC }, + { 0x0213EA94DE0631C4, 0x00003852, 0xFFFFE6AB, 0x00000590, 0x000019C1, 0xFFFFF8B1, 0x000002E5, 0x000019C1, 0xFFFFF8B1, 0x000002E5 }, + { 0x0213F0FD42DA3124, 0x00003521, 0xFFFFE932, 0x00000523, 0x000018A9, 0xFFFFF96B, 0x000002D0, 0x000018A9, 0xFFFFF96B, 0x000002D0 }, + { 0x0213F0FE99062164, 0x000031B9, 0xFFFFEB36, 0x000004D0, 0x00001D65, 0xFFFFF612, 0x0000035D, 0x00001D65, 0xFFFFF612, 0x0000035D }, + { 0x0213F0FD42D41064, 0x00003ED0, 0xFFFFE135, 0x00000679, 0x00002351, 0xFFFFF0FE, 0x00000433, 0x00002351, 0xFFFFF0FE, 0x00000433 }, + { 0x0213F0FE990A20E4, 0x000033ED, 0xFFFFE91A, 0x00000541, 0x00001C93, 0xFFFFF6A0, 0x0000034A, 0x00001C93, 0xFFFFF6A0, 0x0000034A }, + { 0x0213EA94DE021844, 0x0000356F, 0xFFFFE8F7, 0x00000530, 0x000016BF, 0xFFFFFA85, 0x000002AB, 0x000016BF, 0xFFFFFA85, 0x000002AB }, + { 0x0213F0FE991840E4, 0x00002304, 0xFFFFF4F3, 0x00000364, 0x000017CC, 0xFFFFFA41, 0x000002CA, 0x000017CC, 0xFFFFFA41, 0x000002CA }, + { 0x0213F0FE99161164, 0x00002887, 0xFFFFEFD7, 0x00000450, 0x00001474, 0xFFFFFB94, 0x00000299, 0x00001474, 0xFFFFFB94, 0x00000299 }, + { 0x0213F0FE99063064, 0x00003D0B, 0xFFFFE416, 0x000005EF, 0x00001C7E, 0xFFFFF71D, 0x00000325, 0x00001C7E, 0xFFFFF71D, 0x00000325 }, + { 0x0213F0FE990810E4, 0x00003185, 0xFFFFEAFA, 0x000004E4, 0x00001A12, 0xFFFFF83C, 0x00000303, 0x00001A12, 0xFFFFF83C, 0x00000303 }, + { 0x0213F0FE990A1944, 0x00003032, 0xFFFFEAE6, 0x000004FC, 0x00001B2A, 0xFFFFF73F, 0x0000032B, 0x00001B2A, 0xFFFFF73F, 0x0000032B }, + { 0x0213F0FD42D838C4, 0x00002691, 0xFFFFF22D, 0x000003D6, 0x00001700, 0xFFFFFA6E, 0x000002C0, 0x00001700, 0xFFFFFA6E, 0x000002C0 }, + { 0x0213F0FE990218A4, 0x00002B2F, 0xFFFFEEC4, 0x0000044B, 0x0000215F, 0xFFFFF33F, 0x000003D2, 0x0000215F, 0xFFFFF33F, 0x000003D2 }, + { 0x0213F0FE990A4184, 0x000034AA, 0xFFFFE706, 0x000005B1, 0x00001B28, 0xFFFFF6B5, 0x00000349, 0x00001B28, 0xFFFFF6B5, 0x00000349 }, + { 0x0213F0FD42DA2964, 0x0000307E, 0xFFFFEB38, 0x000004E6, 0x00001A22, 0xFFFFF83F, 0x00000300, 0x00001A22, 0xFFFFF83F, 0x00000300 }, + { 0x0213F0FE990618A4, 0x000038D6, 0xFFFFE6D8, 0x0000057C, 0x00001B24, 0xFFFFF7E4, 0x00000307, 0x00001B24, 0xFFFFF7E4, 0x00000307 }, + { 0x0213F0FE99183044, 0x00002757, 0xFFFFF1E8, 0x000003DD, 0x000017F5, 0xFFFFFA15, 0x000002C8, 0x000017F5, 0xFFFFFA15, 0x000002C8 }, + { 0x0213F0FE99083184, 0x000031FC, 0xFFFFEB3E, 0x000004CE, 0x00001B4C, 0xFFFFF7AD, 0x00000319, 0x00001B4C, 0xFFFFF7AD, 0x00000319 }, + { 0x0213F0FE99301864, 0x00002933, 0xFFFFF073, 0x0000040E, 0x00001C3C, 0xFFFFF701, 0x0000033C, 0x00001C3C, 0xFFFFF701, 0x0000033C }, + { 0x0213F0FD42D218A4, 0x000040BB, 0xFFFFE066, 0x0000069A, 0x0000257F, 0xFFFFF08A, 0x00000435, 0x0000257F, 0xFFFFF08A, 0x00000435 }, + { 0x0213F0FE991010A4, 0x0000305B, 0xFFFFEB9B, 0x000004CB, 0x00001996, 0xFFFFF846, 0x00000308, 0x00001996, 0xFFFFF846, 0x00000308 }, + { 0x0213F0FE99064884, 0x000039C0, 0xFFFFE5D3, 0x000005B0, 0x00001A8D, 0xFFFFF7DA, 0x00000313, 0x00001A8D, 0xFFFFF7DA, 0x00000313 }, + { 0x0213EA94DE0210A4, 0x00002E23, 0xFFFFED3F, 0x0000048F, 0x0000189D, 0xFFFFF94C, 0x000002DE, 0x0000189D, 0xFFFFF94C, 0x000002DE }, + { 0x0213EA94DE021984, 0x0000332B, 0xFFFFE9F1, 0x00000516, 0x000018E6, 0xFFFFF8FE, 0x000002EC, 0x000018E6, 0xFFFFF8FE, 0x000002EC }, + { 0x0213F0FE990838C4, 0x000034A0, 0xFFFFEA44, 0x000004E4, 0x00001ECD, 0xFFFFF5B4, 0x00000364, 0x00001ECD, 0xFFFFF5B4, 0x00000364 }, + { 0x0213F0FD42D24104, 0x0000448C, 0xFFFFDF34, 0x000006A8, 0x0000231C, 0xFFFFF286, 0x000003D9, 0x0000231C, 0xFFFFF286, 0x000003D9 }, + { 0x0213EA94DE062144, 0x00002D8C, 0xFFFFEE65, 0x00000456, 0x000018B1, 0xFFFFF9C8, 0x000002C8, 0x000018B1, 0xFFFFF9C8, 0x000002C8 }, + { 0x0213F0FE99061904, 0x00003527, 0xFFFFE9BF, 0x000004FD, 0x00001D23, 0xFFFFF69F, 0x00000342, 0x00001D23, 0xFFFFF69F, 0x00000342 }, + { 0x0213F0FD42DC38A4, 0x00002C51, 0xFFFFEDC3, 0x00000483, 0x00001BE0, 0xFFFFF720, 0x0000032D, 0x00001BE0, 0xFFFFF720, 0x0000032D }, + { 0x0213F0FE990A3044, 0x00002C6C, 0xFFFFECEB, 0x000004B7, 0x00001C86, 0xFFFFF5E7, 0x00000371, 0x00001C86, 0xFFFFF5E7, 0x00000371 }, + { 0x0213F0FE99045144, 0x000037CF, 0xFFFFE6BE, 0x00000599, 0x000018CD, 0xFFFFF967, 0x000002C7, 0x000018CD, 0xFFFFF967, 0x000002C7 }, + { 0x0213F0FE99103164, 0x00002E6F, 0xFFFFED1D, 0x0000048E, 0x00001ADC, 0xFFFFF7F4, 0x0000030E, 0x00001ADC, 0xFFFFF7F4, 0x0000030E }, + { 0x0213F0FD42D42984, 0x00003FF3, 0xFFFFDF13, 0x000006F9, 0x000025BF, 0xFFFFEEEE, 0x00000497, 0x000025BF, 0xFFFFEEEE, 0x00000497 }, + { 0x0213F0FD42DC5104, 0x00004135, 0xFFFFDF97, 0x000006CC, 0x00001D52, 0xFFFFF541, 0x00000383, 0x00001D52, 0xFFFFF541, 0x00000383 }, + { 0x0213F0FD42DC20E4, 0x00002EA9, 0xFFFFEDDB, 0x0000045F, 0x0000197C, 0xFFFFF8E1, 0x000002F0, 0x0000197C, 0xFFFFF8E1, 0x000002F0 }, + { 0x0213EA94DE043084, 0x0000345C, 0xFFFFE922, 0x00000532, 0x00001922, 0xFFFFF8C7, 0x000002F1, 0x00001922, 0xFFFFF8C7, 0x000002F1 }, + { 0x0213F0FE99064124, 0x000035C4, 0xFFFFE8FE, 0x00000521, 0x00001C87, 0xFFFFF6F3, 0x00000330, 0x00001C87, 0xFFFFF6F3, 0x00000330 }, + { 0x0213F0FD42D83164, 0x00002888, 0xFFFFF08A, 0x0000041E, 0x0000150F, 0xFFFFFB87, 0x00000291, 0x0000150F, 0xFFFFFB87, 0x00000291 }, + { 0x0213F0FE990A1124, 0x000035E9, 0xFFFFE657, 0x000005CC, 0x00001BD6, 0xFFFFF664, 0x00000355, 0x00001BD6, 0xFFFFF664, 0x00000355 }, + { 0x0213F0FE991648E4, 0x00002F94, 0xFFFFEBD0, 0x000004E5, 0x00001333, 0xFFFFFCA7, 0x00000266, 0x00001333, 0xFFFFFCA7, 0x00000266 }, + { 0x0213F0FE99181964, 0x000029E7, 0xFFFFF009, 0x00000433, 0x0000144A, 0xFFFFFC37, 0x0000027D, 0x0000144A, 0xFFFFFC37, 0x0000027D }, + { 0x0213F0FE992C1944, 0x00003418, 0xFFFFE979, 0x00000521, 0x00001D33, 0xFFFFF66B, 0x0000034A, 0x00001D33, 0xFFFFF66B, 0x0000034A }, + { 0x0213EA94DE0440E4, 0x00003656, 0xFFFFE79D, 0x0000057A, 0x000017C2, 0xFFFFF992, 0x000002D4, 0x000017C2, 0xFFFFF992, 0x000002D4 }, + { 0x0213F0FE990C40C4, 0x00002EB2, 0xFFFFECFE, 0x00000493, 0x00001F2A, 0xFFFFF543, 0x0000037B, 0x00001F2A, 0xFFFFF543, 0x0000037B }, + { 0x0213F0FE99021124, 0x00002FC1, 0xFFFFEB3F, 0x000004E8, 0x00001CD0, 0xFFFFF5F7, 0x00000364, 0x00001CD0, 0xFFFFF5F7, 0x00000364 }, + { 0x0213F0FE990C1124, 0x0000307B, 0xFFFFEB66, 0x000004DE, 0x00001953, 0xFFFFF8ED, 0x000002E4, 0x00001953, 0xFFFFF8ED, 0x000002E4 }, + { 0x0213F0FD42DA1884, 0x00002CAA, 0xFFFFED07, 0x000004AC, 0x0000251C, 0xFFFFF086, 0x0000044D, 0x0000251C, 0xFFFFF086, 0x0000044D }, + { 0x0213EA94DE043944, 0x00002C94, 0xFFFFEE5F, 0x0000045B, 0x000018D7, 0xFFFFF900, 0x000002EB, 0x000018D7, 0xFFFFF900, 0x000002EB }, + { 0x0213F0FE99021864, 0x000031F1, 0xFFFFE9BE, 0x0000052E, 0x00001DDF, 0xFFFFF558, 0x00000380, 0x00001DDF, 0xFFFFF558, 0x00000380 }, + { 0x0213F0FE990E50C4, 0x00002603, 0xFFFFF1E9, 0x000003DA, 0x00001B37, 0xFFFFF75A, 0x0000032F, 0x00001B37, 0xFFFFF75A, 0x0000032F }, + { 0x0213F0FD42DA3044, 0x00003992, 0xFFFFE4F9, 0x000005EB, 0x00001775, 0xFFFFF9B8, 0x000002C2, 0x00001775, 0xFFFFF9B8, 0x000002C2 }, + { 0x0213F0FE99184964, 0x000029DA, 0xFFFFF052, 0x0000041F, 0x000016E2, 0xFFFFFA99, 0x000002BB, 0x000016E2, 0xFFFFFA99, 0x000002BB }, + { 0x0213F0FE99101064, 0x00002FF2, 0xFFFFEB8F, 0x000004DF, 0x00001AF6, 0xFFFFF7A1, 0x00000321, 0x00001AF6, 0xFFFFF7A1, 0x00000321 }, + { 0x0213F0FE991608E4, 0x00002590, 0xFFFFF222, 0x000003EE, 0x0000130B, 0xFFFFFCC9, 0x00000268, 0x0000130B, 0xFFFFFCC9, 0x00000268 }, + { 0x0213F0FE99024064, 0x000038A2, 0xFFFFE65F, 0x000005A2, 0x000018B1, 0xFFFFF917, 0x000002E1, 0x000018B1, 0xFFFFF917, 0x000002E1 }, + { 0x0213F0FD42DC48E4, 0x000035FD, 0xFFFFE73C, 0x0000058D, 0x00001BB3, 0xFFFFF6E1, 0x00000337, 0x00001BB3, 0xFFFFF6E1, 0x00000337 }, + { 0x0213F0FE991038C4, 0x00002AB7, 0xFFFFEF98, 0x00000429, 0x00001F35, 0xFFFFF539, 0x0000037C, 0x00001F35, 0xFFFFF539, 0x0000037C }, + { 0x0213F0FE990A0944, 0x000034BA, 0xFFFFE73D, 0x000005A6, 0x000018A6, 0xFFFFF888, 0x000002FB, 0x000018A6, 0xFFFFF888, 0x000002FB }, + { 0x0213F0FE99063844, 0x000032EA, 0xFFFFEA78, 0x000004F4, 0x00001AB6, 0xFFFFF812, 0x00000308, 0x00001AB6, 0xFFFFF812, 0x00000308 }, + { 0x0213F0FE990C3044, 0x00002BE9, 0xFFFFEE9A, 0x00000457, 0x00001942, 0xFFFFF8D2, 0x000002F2, 0x00001942, 0xFFFFF8D2, 0x000002F2 }, + { 0x0213F0FE99105124, 0x00002FAB, 0xFFFFEB76, 0x000004E1, 0x00001DCA, 0xFFFFF57D, 0x00000378, 0x00001DCA, 0xFFFFF57D, 0x00000378 }, + { 0x0213F0FE992E2844, 0x0000330A, 0xFFFFE9E1, 0x0000051B, 0x00001CC4, 0xFFFFF6DF, 0x00000335, 0x00001CC4, 0xFFFFF6DF, 0x00000335 }, + { 0x0213F0FE991828A4, 0x000027D8, 0xFFFFF276, 0x000003BF, 0x0000178A, 0xFFFFFABF, 0x000002B5, 0x0000178A, 0xFFFFFABF, 0x000002B5 }, + { 0x0213F0FD42DC3864, 0x0000340A, 0xFFFFE86D, 0x00000562, 0x00001B85, 0xFFFFF719, 0x0000032F, 0x00001B85, 0xFFFFF719, 0x0000032F }, + { 0x0213EA94DE063084, 0x00003879, 0xFFFFE73F, 0x00000578, 0x0000161C, 0xFFFFFB6B, 0x00000281, 0x0000161C, 0xFFFFFB6B, 0x00000281 }, + { 0x0213F0FE99184064, 0x00002879, 0xFFFFF0F8, 0x0000040A, 0x00001749, 0xFFFFFA37, 0x000002CC, 0x00001749, 0xFFFFFA37, 0x000002CC }, + { 0x0213F0FE99043964, 0x00002C3A, 0xFFFFEEA0, 0x0000044F, 0x00001D57, 0xFFFFF6C2, 0x00000332, 0x00001D57, 0xFFFFF6C2, 0x00000332 }, + { 0x0213EA94DE021964, 0x000035BB, 0xFFFFE90D, 0x0000052A, 0x000017D9, 0xFFFFF9F5, 0x000002C3, 0x000017D9, 0xFFFFF9F5, 0x000002C3 }, + { 0x0213EA94DE041124, 0x000031F1, 0xFFFFEAD4, 0x000004ED, 0x00001F10, 0xFFFFF539, 0x0000037D, 0x00001F10, 0xFFFFF539, 0x0000037D }, + { 0x0213F0FE99102824, 0x00002A1A, 0xFFFFEFAD, 0x00000430, 0x00001D47, 0xFFFFF62F, 0x0000035E, 0x00001D47, 0xFFFFF62F, 0x0000035E }, + { 0x0213F0FE99164924, 0x00002AF0, 0xFFFFEEDC, 0x00000465, 0x0000145F, 0xFFFFFBEB, 0x00000281, 0x0000145F, 0xFFFFFBEB, 0x00000281 }, + { 0x0213F0FE99183164, 0x00002657, 0xFFFFF2E0, 0x000003B6, 0x00001664, 0xFFFFFB37, 0x000002A2, 0x00001664, 0xFFFFFB37, 0x000002A2 }, + { 0x0213F0FD42D03864, 0x00003183, 0xFFFFE9F1, 0x0000052B, 0x00002020, 0xFFFFF3CE, 0x000003C1, 0x00002020, 0xFFFFF3CE, 0x000003C1 }, + { 0x0213F0FD42C628E4, 0x00003240, 0xFFFFEB65, 0x000004C7, 0x00002425, 0xFFFFF245, 0x000003F3, 0x00002425, 0xFFFFF245, 0x000003F3 }, + { 0x0213EA94DE321104, 0x000023D0, 0xFFFFF400, 0x00000397, 0x00001345, 0xFFFFFD6B, 0x00000241, 0x00001345, 0xFFFFFD6B, 0x00000241 }, + { 0x0213F0FD42CE38A4, 0x00003440, 0xFFFFE872, 0x0000055B, 0x00002247, 0xFFFFF296, 0x000003E8, 0x00002247, 0xFFFFF296, 0x000003E8 }, + { 0x0213F0FD42D04904, 0x00003275, 0xFFFFE970, 0x00000538, 0x00001F94, 0xFFFFF429, 0x000003AD, 0x00001F94, 0xFFFFF429, 0x000003AD }, + { 0x0213F0FD42C640A4, 0x00003918, 0xFFFFE5DA, 0x000005B6, 0x000024FC, 0xFFFFF106, 0x00000426, 0x000024FC, 0xFFFFF106, 0x00000426 }, + { 0x0213EA94DE062044, 0x0000334B, 0xFFFFEA39, 0x000004FD, 0x00001983, 0xFFFFF8F6, 0x000002E2, 0x00001983, 0xFFFFF8F6, 0x000002E2 }, + { 0x0213F0FD42C64984, 0x00003B59, 0xFFFFE4D0, 0x000005DA, 0x00002605, 0xFFFFF090, 0x00000439, 0x00002605, 0xFFFFF090, 0x00000439 }, + { 0x0213F0FD42D03124, 0x00003251, 0xFFFFEA46, 0x00000511, 0x00002781, 0xFFFFEF84, 0x00000470, 0x00002781, 0xFFFFEF84, 0x00000470 }, + { 0x0213F0FD42CA3164, 0x00003304, 0xFFFFE926, 0x00000542, 0x00001EE9, 0xFFFFF4E4, 0x0000038B, 0x00001EE9, 0xFFFFF4E4, 0x0000038B }, + { 0x0213F0FD42CC38C4, 0x00002F4C, 0xFFFFEC0C, 0x000004C4, 0x00001E49, 0xFFFFF578, 0x00000374, 0x00001E49, 0xFFFFF578, 0x00000374 }, + { 0x0213EA94DE1C2164, 0x00002034, 0xFFFFF692, 0x0000034C, 0x000014B8, 0xFFFFFC5B, 0x00000294, 0x000014B8, 0xFFFFFC5B, 0x00000294 }, + { 0x0213F0FD42CE4924, 0x0000385F, 0xFFFFE513, 0x000005F3, 0x000024E7, 0xFFFFF053, 0x00000450, 0x000024E7, 0xFFFFF053, 0x00000450 }, + { 0x0213EA94DE1C40E4, 0x00001D70, 0xFFFFF821, 0x0000030F, 0x00001541, 0xFFFFFBB4, 0x000002B0, 0x00001541, 0xFFFFFBB4, 0x000002B0 }, + { 0x0213F0FD42D02084, 0x000034EB, 0xFFFFE7FF, 0x00000575, 0x000019B4, 0xFFFFF836, 0x00000308, 0x000019B4, 0xFFFFF836, 0x00000308 }, + { 0x0213F0FD42D050E4, 0x000037C9, 0xFFFFE5D4, 0x000005CD, 0x000026A1, 0xFFFFEF0C, 0x00000491, 0x000026A1, 0xFFFFEF0C, 0x00000491 }, + { 0x0213EA94DE121944, 0x00002918, 0xFFFFF148, 0x000003E9, 0x00001A49, 0xFFFFF94C, 0x000002CF, 0x00001A49, 0xFFFFF94C, 0x000002CF }, + { 0x0213F0FD42CA4064, 0x00002F90, 0xFFFFEAB5, 0x00000514, 0x00001707, 0xFFFFF9C7, 0x000002C4, 0x00001707, 0xFFFFF9C7, 0x000002C4 }, + { 0x0213EA94DE062064, 0x0000327E, 0xFFFFEA99, 0x000004F4, 0x0000194F, 0xFFFFF929, 0x000002DC, 0x0000194F, 0xFFFFF929, 0x000002DC }, + { 0x0213F0FD42C64084, 0x0000326F, 0xFFFFE9CF, 0x00000519, 0x00002240, 0xFFFFF299, 0x000003E7, 0x00002240, 0xFFFFF299, 0x000003E7 }, + { 0x0213EA94DE321124, 0x000022FB, 0xFFFFF4C6, 0x00000371, 0x00001506, 0xFFFFFC73, 0x00000265, 0x00001506, 0xFFFFFC73, 0x00000265 }, + { 0x0213F0FD42CA3924, 0x00003AD6, 0xFFFFE470, 0x000005FE, 0x00001F03, 0xFFFFF4F3, 0x00000387, 0x00001F03, 0xFFFFF4F3, 0x00000387 }, + { 0x0213EA94DE201124, 0x00001F11, 0xFFFFF756, 0x00000332, 0x00001666, 0xFFFFFB8A, 0x000002B2, 0x00001666, 0xFFFFFB8A, 0x000002B2 }, + { 0x0213EA94DE0238A4, 0x00002A5F, 0xFFFFEFA7, 0x00000430, 0x00001943, 0xFFFFF8C6, 0x000002F7, 0x00001943, 0xFFFFF8C6, 0x000002F7 }, + { 0x0213EA94DE1650E4, 0x0000235E, 0xFFFFF3B4, 0x000003B3, 0x00001489, 0xFFFFFBCF, 0x0000029B, 0x00001489, 0xFFFFFBCF, 0x0000029B }, + { 0x0213F0FD42CC38A4, 0x00003570, 0xFFFFE780, 0x0000058D, 0x00001B1D, 0xFFFFF767, 0x00000325, 0x00001B1D, 0xFFFFF767, 0x00000325 }, + { 0x0213EA94DE042064, 0x00003678, 0xFFFFE7C3, 0x00000569, 0x00001831, 0xFFFFF98E, 0x000002C8, 0x00001831, 0xFFFFF98E, 0x000002C8 }, + { 0x0213EA94DE201864, 0x000020B9, 0xFFFFF625, 0x0000035A, 0x000015C5, 0xFFFFFB8A, 0x000002B5, 0x000015C5, 0xFFFFFB8A, 0x000002B5 }, + { 0x0213F0FD42C63184, 0x00003985, 0xFFFFE529, 0x000005DD, 0x00002165, 0xFFFFF351, 0x000003C5, 0x00002165, 0xFFFFF351, 0x000003C5 }, + { 0x0213F0FD42D02064, 0x0000322A, 0xFFFFE99D, 0x00000535, 0x000019A1, 0xFFFFF844, 0x00000305, 0x000019A1, 0xFFFFF844, 0x00000305 }, + { 0x0213F0FD42D05104, 0x000033ED, 0xFFFFE834, 0x00000571, 0x00002094, 0xFFFFF33A, 0x000003DB, 0x00002094, 0xFFFFF33A, 0x000003DB }, + { 0x0213EA94DE2040C4, 0x00001D10, 0xFFFFF84D, 0x0000030B, 0x00001659, 0xFFFFFB0A, 0x000002CB, 0x00001659, 0xFFFFFB0A, 0x000002CB }, + { 0x0213EA94DE1C1124, 0x0000210F, 0xFFFFF644, 0x00000355, 0x00001A4A, 0xFFFFF90F, 0x00000310, 0x00001A4A, 0xFFFFF90F, 0x00000310 }, + { 0x0213EA94DE164164, 0x00001CA8, 0xFFFFF813, 0x00000316, 0x00001440, 0xFFFFFC1C, 0x0000029D, 0x00001440, 0xFFFFFC1C, 0x0000029D }, + { 0x0213EA94DE3210C4, 0x00002864, 0xFFFFF15A, 0x000003FA, 0x0000137F, 0xFFFFFD43, 0x00000248, 0x0000137F, 0xFFFFFD43, 0x00000248 }, + { 0x0213F0FD42D04184, 0x00002CDB, 0xFFFFECFD, 0x000004A7, 0x00002472, 0xFFFFF0E1, 0x00000437, 0x00002472, 0xFFFFF0E1, 0x00000437 }, + { 0x0213F0FD42CC5104, 0x00003348, 0xFFFFE8CA, 0x00000554, 0x00001E91, 0xFFFFF4D4, 0x00000392, 0x00001E91, 0xFFFFF4D4, 0x00000392 }, + { 0x0213F0FD42C64944, 0x00003989, 0xFFFFE4BB, 0x000005F8, 0x00001ACB, 0xFFFFF780, 0x00000319, 0x00001ACB, 0xFFFFF780, 0x00000319 }, + { 0x0213F0FD42CA2104, 0x00003238, 0xFFFFEA09, 0x0000051E, 0x00001F08, 0xFFFFF4F4, 0x0000038C, 0x00001F08, 0xFFFFF4F4, 0x0000038C }, + { 0x0213EA94DE120904, 0x00002453, 0xFFFFF3B0, 0x0000038D, 0x00001AED, 0xFFFFF8A2, 0x000002EA, 0x00001AED, 0xFFFFF8A2, 0x000002EA }, + { 0x0213EA94DE1C3024, 0x00002459, 0xFFFFF409, 0x000003A8, 0x000017B5, 0xFFFFFA53, 0x000002E1, 0x000017B5, 0xFFFFFA53, 0x000002E1 }, + { 0x0213EA94DE021184, 0x0000310D, 0xFFFFEB78, 0x000004D0, 0x00001DC9, 0xFFFFF5D5, 0x00000368, 0x00001DC9, 0xFFFFF5D5, 0x00000368 }, + { 0x0213EA94DE023104, 0x000031BF, 0xFFFFECA3, 0x00000498, 0x00001DC9, 0xFFFFF717, 0x00000336, 0x00001DC9, 0xFFFFF717, 0x00000336 }, + { 0x0213F0FD42CE2104, 0x00003896, 0xFFFFE5DD, 0x000005C5, 0x000023E2, 0xFFFFF1A1, 0x00000416, 0x000023E2, 0xFFFFF1A1, 0x00000416 }, + { 0x0213EA94DE323904, 0x000023CB, 0xFFFFF4C8, 0x00000372, 0x00001C33, 0xFFFFF7D5, 0x0000032A, 0x00001C33, 0xFFFFF7D5, 0x0000032A }, + { 0x0213F0FD42D020C4, 0x00002F6B, 0xFFFFEBF0, 0x000004CE, 0x00001C89, 0xFFFFF689, 0x0000034D, 0x00001C89, 0xFFFFF689, 0x0000034D }, + { 0x0213F0FD42CE3904, 0x00003E72, 0xFFFFE211, 0x0000065D, 0x0000218D, 0xFFFFF309, 0x000003DC, 0x0000218D, 0xFFFFF309, 0x000003DC }, + { 0x0213EA94DE022084, 0x00002612, 0xFFFFF2C3, 0x000003AD, 0x000019F7, 0xFFFFF891, 0x000002FE, 0x000019F7, 0xFFFFF891, 0x000002FE }, + { 0x0213EA94DE164184, 0x0000205D, 0xFFFFF59F, 0x00000372, 0x000012E6, 0xFFFFFD0A, 0x00000270, 0x000012E6, 0xFFFFFD0A, 0x00000270 }, + { 0x0213F0FD42CA2124, 0x00002ECB, 0xFFFFEC47, 0x000004BD, 0x00001936, 0xFFFFF8D9, 0x000002E4, 0x00001936, 0xFFFFF8D9, 0x000002E4 }, + { 0x0213EA94DE064904, 0x00002BDB, 0xFFFFEE6D, 0x00000458, 0x00001852, 0xFFFFF943, 0x000002D9, 0x00001852, 0xFFFFF943, 0x000002D9 }, + { 0x0213EA94DE124904, 0x00003387, 0xFFFFE958, 0x00000534, 0x00001932, 0xFFFFF8FA, 0x000002E4, 0x00001932, 0xFFFFF8FA, 0x000002E4 }, + { 0x0213EA94DE0208C4, 0x00002E3C, 0xFFFFED26, 0x00000495, 0x00001858, 0xFFFFF990, 0x000002D1, 0x00001858, 0xFFFFF990, 0x000002D1 }, + { 0x0213EA94DE022964, 0x000033B8, 0xFFFFEA5C, 0x000004F9, 0x00001BD1, 0xFFFFF76A, 0x0000032E, 0x00001BD1, 0xFFFFF76A, 0x0000032E }, + { 0x0213EA94DE062984, 0x00002BCE, 0xFFFFEEE9, 0x00000443, 0x00001982, 0xFFFFF90D, 0x000002DF, 0x00001982, 0xFFFFF90D, 0x000002DF }, + { 0x0213F0FD42D048E4, 0x00003495, 0xFFFFE7D9, 0x0000057B, 0x00001D2A, 0xFFFFF5A5, 0x00000372, 0x00001D2A, 0xFFFFF5A5, 0x00000372 }, + { 0x0213F0FD42CA38E4, 0x000034B1, 0xFFFFE88D, 0x00000556, 0x00002014, 0xFFFFF43A, 0x000003AA, 0x00002014, 0xFFFFF43A, 0x000003AA }, + { 0x0213F0FD42CC3124, 0x00002F96, 0xFFFFEC84, 0x000004AD, 0x000024A2, 0xFFFFF1CE, 0x0000040A, 0x000024A2, 0xFFFFF1CE, 0x0000040A }, + { 0x0213EA94DE161064, 0x0000203B, 0xFFFFF640, 0x00000359, 0x000014EC, 0xFFFFFC14, 0x0000029C, 0x000014EC, 0xFFFFFC14, 0x0000029C }, + { 0x0213F0FD42D02984, 0x000034E2, 0xFFFFE7B8, 0x00000582, 0x00001938, 0xFFFFF872, 0x000002FA, 0x00001938, 0xFFFFF872, 0x000002FA }, + { 0x0213EA94DE063124, 0x00002AC7, 0xFFFFF0C1, 0x000003F5, 0x00002268, 0xFFFFF39C, 0x000003C9, 0x00002268, 0xFFFFF39C, 0x000003C9 }, + { 0x0213F0FD42C63144, 0x000036F6, 0xFFFFE77F, 0x00000571, 0x000027D9, 0xFFFFEF6F, 0x00000461, 0x000027D9, 0xFFFFEF6F, 0x00000461 }, + { 0x0213EA94DE123124, 0x00002BAB, 0xFFFFF018, 0x00000419, 0x00002126, 0xFFFFF4E2, 0x0000038F, 0x00002126, 0xFFFFF4E2, 0x0000038F }, + { 0x0213EA94DE323924, 0x000028C4, 0xFFFFF161, 0x000003F8, 0x0000180C, 0xFFFFFA4B, 0x000002C8, 0x0000180C, 0xFFFFFA4B, 0x000002C8 }, + { 0x0213F0FD42CA2864, 0x00002F48, 0xFFFFEB62, 0x000004EE, 0x00001912, 0xFFFFF8C8, 0x000002EA, 0x00001912, 0xFFFFF8C8, 0x000002EA }, + { 0x0213F0FD42CE2864, 0x000032DF, 0xFFFFE911, 0x00000545, 0x00001F06, 0xFFFFF485, 0x0000039C, 0x00001F06, 0xFFFFF485, 0x0000039C }, + { 0x0213F0FD42D04144, 0x000035B8, 0xFFFFE74F, 0x00000590, 0x00001FD7, 0xFFFFF410, 0x000003AF, 0x00001FD7, 0xFFFFF410, 0x000003AF }, + { 0x0213F0FD42D050C4, 0x00003608, 0xFFFFE6D7, 0x000005A9, 0x000024A6, 0xFFFFF075, 0x00000450, 0x000024A6, 0xFFFFF075, 0x00000450 }, + { 0x0213F0FD42CA3884, 0x000030AB, 0xFFFFEAED, 0x000004F5, 0x000019EE, 0xFFFFF84E, 0x000002FC, 0x000019EE, 0xFFFFF84E, 0x000002FC }, + { 0x0213EA94DE0620C4, 0x000030C6, 0xFFFFEC92, 0x0000049E, 0x000019BB, 0xFFFFF8F1, 0x000002F3, 0x000019BB, 0xFFFFF8F1, 0x000002F3 }, + { 0x0213F0FD42C630A4, 0x00003B27, 0xFFFFE544, 0x000005C1, 0x00002697, 0xFFFFF072, 0x00000438, 0x00002697, 0xFFFFF072, 0x00000438 }, + { 0x0213EA94DE1248E4, 0x00002F23, 0xFFFFEC48, 0x000004B9, 0x0000199A, 0xFFFFF8CF, 0x000002E9, 0x0000199A, 0xFFFFF8CF, 0x000002E9 }, + { 0x0213EA94DE0629A4, 0x00002BD7, 0xFFFFEEAC, 0x00000450, 0x00001991, 0xFFFFF8F4, 0x000002E2, 0x00001991, 0xFFFFF8F4, 0x000002E2 }, + { 0x0213EA94DE022024, 0x00003210, 0xFFFFEB24, 0x000004DE, 0x00001BDF, 0xFFFFF744, 0x00000333, 0x00001BDF, 0xFFFFF744, 0x00000333 }, + { 0x0213EA94DE244144, 0x00002DDC, 0xFFFFED0D, 0x000004AC, 0x000019D0, 0xFFFFF869, 0x0000030F, 0x000019D0, 0xFFFFF869, 0x0000030F }, + { 0x0213EA94DE203964, 0x000023E6, 0xFFFFF40C, 0x000003A9, 0x000014EB, 0xFFFFFBC4, 0x000002AF, 0x000014EB, 0xFFFFFBC4, 0x000002AF }, + { 0x0213F0FD42CA29A4, 0x000030CE, 0xFFFFE9A5, 0x0000053C, 0x00001C45, 0xFFFFF60E, 0x0000035D, 0x00001C45, 0xFFFFF60E, 0x0000035D }, + { 0x0213EA94DE161084, 0x00001E89, 0xFFFFF73A, 0x00000337, 0x0000157C, 0xFFFFFBC0, 0x000002AA, 0x0000157C, 0xFFFFFBC0, 0x000002AA }, + { 0x0213F0FD42D04124, 0x000036C6, 0xFFFFE6CF, 0x000005A1, 0x00002457, 0xFFFFF11D, 0x0000042D, 0x00002457, 0xFFFFF11D, 0x0000042D }, + { 0x0213EA94DE321944, 0x00002815, 0xFFFFF19A, 0x000003F2, 0x000016D2, 0xFFFFFB40, 0x00000299, 0x000016D2, 0xFFFFFB40, 0x00000299 }, + { 0x0213EA94DE1C19A4, 0x00001FE2, 0xFFFFF660, 0x00000354, 0x000015A7, 0xFFFFFB47, 0x000002C1, 0x000015A7, 0xFFFFFB47, 0x000002C1 }, + { 0x0213EA94DE161964, 0x00002114, 0xFFFFF634, 0x00000356, 0x000016C1, 0xFFFFFB43, 0x000002B8, 0x000016C1, 0xFFFFFB43, 0x000002B8 }, + { 0x0213F0FD42CC28C4, 0x000028E3, 0xFFFFF075, 0x00000414, 0x0000203C, 0xFFFFF438, 0x000003B3, 0x0000203C, 0xFFFFF438, 0x000003B3 }, + { 0x0213EA94DE1C3924, 0x00001EEB, 0xFFFFF7BB, 0x0000031A, 0x00001580, 0xFFFFFBD7, 0x000002AD, 0x00001580, 0xFFFFFBD7, 0x000002AD }, + { 0x0213EA94DE2408C4, 0x00002BB2, 0xFFFFEE72, 0x00000470, 0x0000192C, 0xFFFFF91E, 0x000002E7, 0x0000192C, 0xFFFFF91E, 0x000002E7 }, + { 0x0213EA94DE0650E4, 0x00003A3D, 0xFFFFE49D, 0x000005F5, 0x00001A3B, 0xFFFFF7B1, 0x00000320, 0x00001A3B, 0xFFFFF7B1, 0x00000320 }, + { 0x0213F0FD42CE3164, 0x00002E93, 0xFFFFEC5A, 0x000004B4, 0x000025EB, 0xFFFFF03C, 0x0000044A, 0x000025EB, 0xFFFFF03C, 0x0000044A }, + { 0x0213F0FD42CA20C4, 0x0000331F, 0xFFFFE97A, 0x00000531, 0x00001A06, 0xFFFFF850, 0x000002FD, 0x00001A06, 0xFFFFF850, 0x000002FD }, + { 0x0213F0FD42C63964, 0x00003937, 0xFFFFE5A0, 0x000005C7, 0x0000235E, 0xFFFFF234, 0x000003F2, 0x0000235E, 0xFFFFF234, 0x000003F2 }, + { 0x0213EA94DE1E3924, 0x00001DD0, 0xFFFFF80E, 0x00000319, 0x000015C7, 0xFFFFFB91, 0x000002BC, 0x000015C7, 0xFFFFFB91, 0x000002BC }, + { 0x0213F0FD42D03964, 0x00003328, 0xFFFFE905, 0x0000054A, 0x00002054, 0xFFFFF3BF, 0x000003C0, 0x00002054, 0xFFFFF3BF, 0x000003C0 }, + { 0x0213F0FD42CC1104, 0x00002FE5, 0xFFFFEA65, 0x00000520, 0x0000188B, 0xFFFFF8A7, 0x000002F5, 0x0000188B, 0xFFFFF8A7, 0x000002F5 }, + { 0x0213F0FD42CA38A4, 0x00002ED3, 0xFFFFEC51, 0x000004B9, 0x00001888, 0xFFFFF96A, 0x000002CA, 0x00001888, 0xFFFFF96A, 0x000002CA }, + { 0x0213F0FD42D03084, 0x00002FCC, 0xFFFFEB60, 0x000004EA, 0x00001F8D, 0xFFFFF436, 0x000003B4, 0x00001F8D, 0xFFFFF436, 0x000003B4 }, + { 0x0213F0FD42CE4084, 0x0000329F, 0xFFFFE8F7, 0x0000054F, 0x000023DB, 0xFFFFF0EE, 0x0000043A, 0x000023DB, 0xFFFFF0EE, 0x0000043A }, + { 0x0213EA94DE0438A4, 0x000030B5, 0xFFFFEBB8, 0x000004C4, 0x00001AFD, 0xFFFFF781, 0x00000329, 0x00001AFD, 0xFFFFF781, 0x00000329 }, + { 0x0213EA94DE1E19A4, 0x00001BBF, 0xFFFFF8E2, 0x000002F7, 0x00001722, 0xFFFFFA85, 0x000002DB, 0x00001722, 0xFFFFFA85, 0x000002DB }, + { 0x0213EA94DE022044, 0x000030E4, 0xFFFFEBE6, 0x000004BB, 0x00001C80, 0xFFFFF6E1, 0x0000033E, 0x00001C80, 0xFFFFF6E1, 0x0000033E }, + { 0x0213EA94DE122944, 0x000030E2, 0xFFFFECD0, 0x00000492, 0x00001CE0, 0xFFFFF753, 0x0000032F, 0x00001CE0, 0xFFFFF753, 0x0000032F }, + { 0x0213EA94DE322864, 0x00002513, 0xFFFFF323, 0x000003BC, 0x00001965, 0xFFFFF93C, 0x000002F0, 0x00001965, 0xFFFFF93C, 0x000002F0 }, + { 0x0213EA94DE1610A4, 0x00002147, 0xFFFFF585, 0x0000037A, 0x000014CC, 0xFFFFFC3B, 0x00000296, 0x000014CC, 0xFFFFFC3B, 0x00000296 }, + { 0x0213EA94DE322124, 0x00002507, 0xFFFFF432, 0x0000038A, 0x00001890, 0xFFFFFA61, 0x000002C6, 0x00001890, 0xFFFFFA61, 0x000002C6 }, + { 0x0213EA94DE0638A4, 0x0000339B, 0xFFFFEA7D, 0x000004F0, 0x0000191E, 0xFFFFF944, 0x000002DF, 0x0000191E, 0xFFFFF944, 0x000002DF }, + { 0x0213F0FD42CC28A4, 0x00002842, 0xFFFFF043, 0x00000427, 0x00001988, 0xFFFFF892, 0x000002F7, 0x00001988, 0xFFFFF892, 0x000002F7 }, + { 0x0213F0FD42C618A4, 0x0000389D, 0xFFFFE5D8, 0x000005BF, 0x00001EE1, 0xFFFFF4EF, 0x00000387, 0x00001EE1, 0xFFFFF4EF, 0x00000387 }, + { 0x0213F0FD42CE3184, 0x0000396D, 0xFFFFE4D7, 0x000005F2, 0x000020DA, 0xFFFFF34E, 0x000003CD, 0x000020DA, 0xFFFFF34E, 0x000003CD }, + { 0x0213F0FD42CA3104, 0x0000355F, 0xFFFFE85A, 0x0000055F, 0x0000281F, 0xFFFFEF28, 0x0000047D, 0x0000281F, 0xFFFFEF28, 0x0000047D }, + { 0x0213EA94DE1C50E4, 0x00002284, 0xFFFFF46E, 0x00000399, 0x00001498, 0xFFFFFBE3, 0x0000029C, 0x00001498, 0xFFFFFBE3, 0x0000029C }, + { 0x0213EA94DE023944, 0x000031B6, 0xFFFFEB42, 0x000004D9, 0x00001F54, 0xFFFFF4D2, 0x00000399, 0x00001F54, 0xFFFFF4D2, 0x00000399 }, + { 0x0213F0FD42C63064, 0x000035CE, 0xFFFFE79D, 0x00000578, 0x00001C78, 0xFFFFF68C, 0x00000344, 0x00001C78, 0xFFFFF68C, 0x00000344 }, + { 0x0213EA94DE1E4964, 0x00001C0A, 0xFFFFF81B, 0x00000318, 0x00001492, 0xFFFFFBCC, 0x000002A5, 0x00001492, 0xFFFFFBCC, 0x000002A5 }, + { 0x0213EA94DE022184, 0x00003492, 0xFFFFE95C, 0x00000526, 0x00001A97, 0xFFFFF81B, 0x0000030B, 0x00001A97, 0xFFFFF81B, 0x0000030B }, + { 0x0213EA94DE163164, 0x00001E89, 0xFFFFF7D0, 0x0000031A, 0x000017A5, 0xFFFFFA99, 0x000002D9, 0x000017A5, 0xFFFFFA99, 0x000002D9 }, + { 0x0213F0FD42CA48C4, 0x00002DCC, 0xFFFFEBE0, 0x000004DE, 0x000019BA, 0xFFFFF7F5, 0x0000030D, 0x000019BA, 0xFFFFF7F5, 0x0000030D }, + { 0x0213EA94DE042984, 0x000030EF, 0xFFFFEBC1, 0x000004C0, 0x00001AA9, 0xFFFFF814, 0x0000030A, 0x00001AA9, 0xFFFFF814, 0x0000030A }, + { 0x0213EA94DE245124, 0x00002EA3, 0xFFFFEBF6, 0x000004D8, 0x00001DCF, 0xFFFFF521, 0x00000399, 0x00001DCF, 0xFFFFF521, 0x00000399 }, + { 0x0213EA94DE324164, 0x00002B5F, 0xFFFFEEA1, 0x0000046C, 0x000017EB, 0xFFFFF9C9, 0x000002D4, 0x000017EB, 0xFFFFF9C9, 0x000002D4 }, + { 0x0213EA94DE024104, 0x00002C63, 0xFFFFEE82, 0x00000455, 0x00002268, 0xFFFFF29D, 0x000003F6, 0x00002268, 0xFFFFF29D, 0x000003F6 }, + { 0x0213EA94DE121904, 0x00002B1A, 0xFFFFF016, 0x0000041C, 0x000019AA, 0xFFFFF988, 0x000002D2, 0x000019AA, 0xFFFFF988, 0x000002D2 }, + { 0x0213F0FD42CA2964, 0x0000332F, 0xFFFFE934, 0x0000053B, 0x00001E47, 0xFFFFF566, 0x00000374, 0x00001E47, 0xFFFFF566, 0x00000374 }, + { 0x0213F0FD42CA48E4, 0x00002995, 0xFFFFEEC1, 0x00000465, 0x0000178F, 0xFFFFF995, 0x000002C5, 0x0000178F, 0xFFFFF995, 0x000002C5 }, + { 0x0213EA94DE201884, 0x00001C2E, 0xFFFFF932, 0x000002E9, 0x000015C2, 0xFFFFFBC5, 0x000002AD, 0x000015C2, 0xFFFFFBC5, 0x000002AD }, + { 0x0213F0FD42C640E4, 0x00003B08, 0xFFFFE4E8, 0x000005D8, 0x0000209D, 0xFFFFF444, 0x00000398, 0x0000209D, 0xFFFFF444, 0x00000398 }, + { 0x0213EA94DE0450E4, 0x00002F1F, 0xFFFFEB74, 0x000004EB, 0x00001F4C, 0xFFFFF3D4, 0x000003CE, 0x00001F4C, 0xFFFFF3D4, 0x000003CE }, + { 0x0213EA94DE043884, 0x00003415, 0xFFFFE89F, 0x00000553, 0x0000186B, 0xFFFFF8E1, 0x000002EF, 0x0000186B, 0xFFFFF8E1, 0x000002EF }, + { 0x0213F0FD42CC10C4, 0x00003441, 0xFFFFE779, 0x0000059D, 0x000019EA, 0xFFFFF7B2, 0x0000031F, 0x000019EA, 0xFFFFF7B2, 0x0000031F }, + { 0x0213EA94DE164064, 0x00002174, 0xFFFFF546, 0x00000378, 0x00001456, 0xFFFFFC5F, 0x00000284, 0x00001456, 0xFFFFFC5F, 0x00000284 }, + { 0x0213F0FD42CE40C4, 0x00003788, 0xFFFFE61E, 0x000005BF, 0x00001DF4, 0xFFFFF562, 0x00000374, 0x00001DF4, 0xFFFFF562, 0x00000374 }, + { 0x0213EA94DE1E1844, 0x00001C41, 0xFFFFF8C1, 0x000002FC, 0x0000171E, 0xFFFFFA93, 0x000002DE, 0x0000171E, 0xFFFFFA93, 0x000002DE }, + { 0x0213F0FD42CA3864, 0x00002B15, 0xFFFFEDEC, 0x00000487, 0x000017E4, 0xFFFFF934, 0x000002DF, 0x000017E4, 0xFFFFF934, 0x000002DF }, + { 0x0213F0FD42CC3144, 0x0000327A, 0xFFFFEA71, 0x000004FF, 0x00001D96, 0xFFFFF63B, 0x00000351, 0x00001D96, 0xFFFFF63B, 0x00000351 }, + { 0x0213EA94DE1E4064, 0x000023C6, 0xFFFFF3E5, 0x000003B6, 0x000014DE, 0xFFFFFC29, 0x00000294, 0x000014DE, 0xFFFFFC29, 0x00000294 }, + { 0x0213EA94DE164944, 0x00001F96, 0xFFFFF5FA, 0x00000364, 0x00001397, 0xFFFFFC9D, 0x0000027D, 0x00001397, 0xFFFFFC9D, 0x0000027D }, + { 0x0213EA94DE063144, 0x00002B51, 0xFFFFEFB5, 0x00000420, 0x00001ACA, 0xFFFFF824, 0x0000030D, 0x00001ACA, 0xFFFFF824, 0x0000030D }, + { 0x0213EA94DE1E4944, 0x000020DB, 0xFFFFF55B, 0x0000037C, 0x0000153D, 0xFFFFFB5F, 0x000002BA, 0x0000153D, 0xFFFFFB5F, 0x000002BA }, + { 0x0213EA94DE0221A4, 0x000030BB, 0xFFFFEBDA, 0x000004BC, 0x00001B0E, 0xFFFFF7A8, 0x0000031E, 0x00001B0E, 0xFFFFF7A8, 0x0000031E }, + { 0x0213F0FD42C62904, 0x000033C4, 0xFFFFEA41, 0x000004FA, 0x000022C6, 0xFFFFF363, 0x000003BC, 0x000022C6, 0xFFFFF363, 0x000003BC }, + { 0x0213EA94DE240924, 0x00002D47, 0xFFFFEE01, 0x00000477, 0x000021CD, 0xFFFFF36E, 0x000003D6, 0x000021CD, 0xFFFFF36E, 0x000003D6 }, + { 0x0213EA94DE1E31A4, 0x00001E7B, 0xFFFFF733, 0x00000339, 0x00001668, 0xFFFFFB29, 0x000002BF, 0x00001668, 0xFFFFFB29, 0x000002BF }, + { 0x0213F0FD42CA2984, 0x00002F7E, 0xFFFFEAFF, 0x000004FC, 0x000018D4, 0xFFFFF8BE, 0x000002E8, 0x000018D4, 0xFFFFF8BE, 0x000002E8 }, + { 0x0213EA94DE3238A4, 0x00002635, 0xFFFFF2E1, 0x000003BC, 0x000017A4, 0xFFFFFA67, 0x000002C3, 0x000017A4, 0xFFFFFA67, 0x000002C3 }, + { 0x0213EA94DE1230A4, 0x000026CA, 0xFFFFF2C1, 0x000003B2, 0x00001C3E, 0xFFFFF7AE, 0x0000031F, 0x00001C3E, 0xFFFFF7AE, 0x0000031F }, + { 0x0213EA94DE1C1064, 0x00002550, 0xFFFFF380, 0x000003B5, 0x000019F5, 0xFFFFF8E7, 0x00000313, 0x000019F5, 0xFFFFF8E7, 0x00000313 }, + { 0x0213F0FD42CA4904, 0x00002FBC, 0xFFFFEAF8, 0x000004FA, 0x000018CC, 0xFFFFF8C6, 0x000002E8, 0x000018CC, 0xFFFFF8C6, 0x000002E8 }, + { 0x0213F0FD42D018E4, 0x00002FCC, 0xFFFFEB60, 0x000004EA, 0x00001EFF, 0xFFFFF4DA, 0x0000038F, 0x00001EFF, 0xFFFFF4DA, 0x0000038F }, + { 0x0213EA94DE164084, 0x000023E6, 0xFFFFF413, 0x000003A1, 0x00001544, 0xFFFFFC16, 0x0000028B, 0x00001544, 0xFFFFFC16, 0x0000028B }, + { 0x0213F0FD42CE3024, 0x00003251, 0xFFFFEAA2, 0x000004F5, 0x000025B0, 0xFFFFF0DF, 0x00000431, 0x000025B0, 0xFFFFF0DF, 0x00000431 }, + { 0x0213F0FD42D03984, 0x00002F6F, 0xFFFFEB67, 0x000004E6, 0x00002275, 0xFFFFF249, 0x000003FB, 0x00002275, 0xFFFFF249, 0x000003FB }, + { 0x0213EA94DE322964, 0x00002597, 0xFFFFF34A, 0x000003B1, 0x00001BCC, 0xFFFFF822, 0x0000031A, 0x00001BCC, 0xFFFFF822, 0x0000031A }, + { 0x0213F0FD42C63864, 0x00003B1D, 0xFFFFE40E, 0x0000060D, 0x00001F61, 0xFFFFF470, 0x0000039F, 0x00001F61, 0xFFFFF470, 0x0000039F }, + { 0x0213F0FD42C64144, 0x0000379F, 0xFFFFE6DB, 0x0000058C, 0x00002460, 0xFFFFF170, 0x00000415, 0x00002460, 0xFFFFF170, 0x00000415 }, + { 0x0213EA94DE165144, 0x00002442, 0xFFFFF2FB, 0x000003D9, 0x00001414, 0xFFFFFBDC, 0x000002A2, 0x00001414, 0xFFFFFBDC, 0x000002A2 }, + { 0x0213EA94DE0240C4, 0x00003270, 0xFFFFEA0D, 0x0000051C, 0x00001AFD, 0xFFFFF783, 0x00000328, 0x00001AFD, 0xFFFFF783, 0x00000328 }, + { 0x0213EA94DE161104, 0x00001B23, 0xFFFFF94B, 0x000002EB, 0x000015F1, 0xFFFFFB82, 0x000002B4, 0x000015F1, 0xFFFFFB82, 0x000002B4 }, + { 0x0213EA94DE323844, 0x000026AE, 0xFFFFF21A, 0x000003DB, 0x00001827, 0xFFFFFA10, 0x000002C8, 0x00001827, 0xFFFFFA10, 0x000002C8 }, + { 0x0213F0FD42CA4884, 0x00002DCF, 0xFFFFEBD8, 0x000004DB, 0x00001A75, 0xFFFFF719, 0x0000033A, 0x00001A75, 0xFFFFF719, 0x0000033A }, + { 0x0213F0FD42CE40E4, 0x00003983, 0xFFFFE500, 0x000005EA, 0x000022A6, 0xFFFFF25F, 0x000003F1, 0x000022A6, 0xFFFFF25F, 0x000003F1 }, + { 0x0213EA94DE1218C4, 0x00002AD5, 0xFFFFF07A, 0x00000406, 0x000019FB, 0xFFFFF961, 0x000002D8, 0x000019FB, 0xFFFFF961, 0x000002D8 }, + { 0x0213F0FD42CA39A4, 0x00002A43, 0xFFFFEE43, 0x00000474, 0x00001D65, 0xFFFFF538, 0x00000387, 0x00001D65, 0xFFFFF538, 0x00000387 }, + { 0x0213F0FD42C62084, 0x0000311E, 0xFFFFEAF8, 0x000004E8, 0x00001959, 0xFFFFF8E4, 0x000002DC, 0x00001959, 0xFFFFF8E4, 0x000002DC }, + { 0x0213F0FD42D031A4, 0x0000339A, 0xFFFFE8A7, 0x00000559, 0x00001A04, 0xFFFFF7E5, 0x00000311, 0x00001A04, 0xFFFFF7E5, 0x00000311 }, + { 0x0213EA94DE204144, 0x000021B3, 0xFFFFF50F, 0x00000389, 0x00001470, 0xFFFFFBF7, 0x000002A5, 0x00001470, 0xFFFFFBF7, 0x000002A5 }, + { 0x0213EA94DE021884, 0x00003417, 0xFFFFE9A6, 0x0000051D, 0x000018A4, 0xFFFFF984, 0x000002CF, 0x000018A4, 0xFFFFF984, 0x000002CF }, + { 0x0213EA94DE202984, 0x00001FED, 0xFFFFF6A2, 0x00000347, 0x00001639, 0xFFFFFB59, 0x000002BB, 0x00001639, 0xFFFFFB59, 0x000002BB }, + { 0x0213EA94DE1218A4, 0x000032D2, 0xFFFFEB18, 0x000004DC, 0x00001A01, 0xFFFFF95E, 0x000002CF, 0x00001A01, 0xFFFFF95E, 0x000002CF }, + { 0x0213F0FD42D04084, 0x00003147, 0xFFFFEA3B, 0x00000518, 0x0000241D, 0xFFFFF11C, 0x00000431, 0x0000241D, 0xFFFFF11C, 0x00000431 }, + { 0x0213EA94DE1C0904, 0x00001D44, 0xFFFFF7E7, 0x0000031A, 0x0000153F, 0xFFFFFBBC, 0x000002A9, 0x0000153F, 0xFFFFFBBC, 0x000002A9 }, + { 0x0213F0FD42CC4104, 0x00003690, 0xFFFFE6E3, 0x000005A4, 0x000018DE, 0xFFFFF908, 0x000002DD, 0x000018DE, 0xFFFFF908, 0x000002DD }, + { 0x0213F0FD42CC2184, 0x00003561, 0xFFFFE6F8, 0x000005AB, 0x000018B5, 0xFFFFF8A0, 0x000002F3, 0x000018B5, 0xFFFFF8A0, 0x000002F3 }, + { 0x0213EA94DE323124, 0x000028F4, 0xFFFFF23A, 0x000003CE, 0x00001BC6, 0xFFFFF881, 0x00000311, 0x00001BC6, 0xFFFFF881, 0x00000311 }, + { 0x0213F0FD42D03184, 0x000035D7, 0xFFFFE71C, 0x0000059B, 0x00001D49, 0xFFFFF5C8, 0x00000368, 0x00001D49, 0xFFFFF5C8, 0x00000368 }, + { 0x0213F0FD42CE18A4, 0x0000397E, 0xFFFFE4CB, 0x000005F4, 0x00001989, 0xFFFFF844, 0x000002FD, 0x00001989, 0xFFFFF844, 0x000002FD }, + { 0x0213F0FD42C62064, 0x00003BAB, 0xFFFFE332, 0x0000063F, 0x00001A69, 0xFFFFF7B9, 0x00000312, 0x00001A69, 0xFFFFF7B9, 0x00000312 }, + { 0x0213F0FD42D03064, 0x00002F26, 0xFFFFEB82, 0x000004E8, 0x00001D7D, 0xFFFFF590, 0x00000379, 0x00001D7D, 0xFFFFF590, 0x00000379 }, + { 0x0213EA94DE0631A4, 0x00002FDC, 0xFFFFEBE0, 0x000004C3, 0x00001940, 0xFFFFF8CC, 0x000002EE, 0x00001940, 0xFFFFF8CC, 0x000002EE }, + { 0x0213EA94DE1C08E4, 0x000021B2, 0xFFFFF558, 0x00000379, 0x00001643, 0xFFFFFB1C, 0x000002C3, 0x00001643, 0xFFFFFB1C, 0x000002C3 }, + { 0x0213EA94DE321904, 0x00002897, 0xFFFFF181, 0x000003F7, 0x00001990, 0xFFFFF994, 0x000002E2, 0x00001990, 0xFFFFF994, 0x000002E2 }, + { 0x0213EA94DE1E0924, 0x00001D19, 0xFFFFF829, 0x0000031A, 0x00001558, 0xFFFFFBCA, 0x000002AF, 0x00001558, 0xFFFFFBCA, 0x000002AF }, + { 0x0213EA94DE043144, 0x00003311, 0xFFFFEAD9, 0x000004E1, 0x00001BDC, 0xFFFFF79E, 0x0000031D, 0x00001BDC, 0xFFFFF79E, 0x0000031D }, + { 0x0213EA94DE1E29C4, 0x00001E54, 0xFFFFF740, 0x00000333, 0x000016A1, 0xFFFFFAF0, 0x000002C4, 0x000016A1, 0xFFFFFAF0, 0x000002C4 }, + { 0x0213F0FD42CE3964, 0x00003266, 0xFFFFE9A8, 0x00000527, 0x00002307, 0xFFFFF219, 0x000003FC, 0x00002307, 0xFFFFF219, 0x000003FC }, + { 0x0213EA94DE321144, 0x00001D1F, 0xFFFFF82B, 0x000002F0, 0x000013F0, 0xFFFFFD0B, 0x0000024E, 0x000013F0, 0xFFFFFD0B, 0x0000024E }, + { 0x0213F0FD42C648A4, 0x0000312E, 0xFFFFEA67, 0x00000502, 0x0000222A, 0xFFFFF253, 0x000003F9, 0x0000222A, 0xFFFFF253, 0x000003F9 }, + { 0x0213F0FD42CA4124, 0x000032B2, 0xFFFFE9AD, 0x00000523, 0x00001E97, 0xFFFFF527, 0x0000037F, 0x00001E97, 0xFFFFF527, 0x0000037F }, + { 0x0213EA94DE1640E4, 0x00001F6A, 0xFFFFF6FC, 0x00000338, 0x0000164B, 0xFFFFFB2C, 0x000002C2, 0x0000164B, 0xFFFFFB2C, 0x000002C2 }, + { 0x0213EA94DE0228C4, 0x00002603, 0xFFFFF386, 0x00000392, 0x00001EE0, 0xFFFFF601, 0x00000369, 0x00001EE0, 0xFFFFF601, 0x00000369 }, + { 0x0213EA94DE201164, 0x00001D0C, 0xFFFFF803, 0x00000317, 0x00001345, 0xFFFFFD52, 0x00000260, 0x00001345, 0xFFFFFD52, 0x00000260 }, + { 0x0213F0FD42CC1884, 0x0000327A, 0xFFFFE8E5, 0x0000055C, 0x00001680, 0xFFFFFA2D, 0x000002B2, 0x00001680, 0xFFFFFA2D, 0x000002B2 }, + { 0x0213F0FD42CA3964, 0x000032B8, 0xFFFFE91A, 0x0000054A, 0x00001BAB, 0xFFFFF6EC, 0x00000338, 0x00001BAB, 0xFFFFF6EC, 0x00000338 }, + { 0x0213F0FD42CC3044, 0x00002F79, 0xFFFFEB63, 0x000004EF, 0x000017BB, 0xFFFFF9B1, 0x000002CA, 0x000017BB, 0xFFFFF9B1, 0x000002CA }, + { 0x0213EA94DE0438E4, 0x00002AE5, 0xFFFFEFCB, 0x0000041D, 0x0000214A, 0xFFFFF3A7, 0x000003C7, 0x0000214A, 0xFFFFF3A7, 0x000003C7 }, + { 0x0213EA94DE322064, 0x0000212C, 0xFFFFF5BC, 0x0000034F, 0x000017ED, 0xFFFFFA4C, 0x000002C1, 0x000017ED, 0xFFFFFA4C, 0x000002C1 }, + { 0x0213EA94DE121124, 0x00002BE7, 0xFFFFEF40, 0x0000043C, 0x00001AE2, 0xFFFFF8CF, 0x000002E3, 0x00001AE2, 0xFFFFF8CF, 0x000002E3 }, + { 0x0213F0FD42D05144, 0x000032DC, 0xFFFFE90F, 0x00000549, 0x00002A2D, 0xFFFFECC9, 0x000004ED, 0x00002A2D, 0xFFFFECC9, 0x000004ED }, + { 0x0213EA94DE1618A4, 0x00001DE3, 0xFFFFF80D, 0x00000319, 0x000016FA, 0xFFFFFB42, 0x000002BC, 0x000016FA, 0xFFFFFB42, 0x000002BC }, + { 0x0213EA94DE1E2844, 0x00001F1B, 0xFFFFF6DE, 0x00000346, 0x00001502, 0xFFFFFC23, 0x00000298, 0x00001502, 0xFFFFFC23, 0x00000298 }, + { 0x0213EA94DE061864, 0x00003203, 0xFFFFEA87, 0x000004FE, 0x0000194E, 0xFFFFF8E3, 0x000002EC, 0x0000194E, 0xFFFFF8E3, 0x000002EC }, + { 0x0213F0FD42D02144, 0x0000337A, 0xFFFFE8DD, 0x00000551, 0x00001E3C, 0xFFFFF534, 0x00000385, 0x00001E3C, 0xFFFFF534, 0x00000385 }, + { 0x0213F0FD42CA4864, 0x000036F6, 0xFFFFE62A, 0x000005C5, 0x000023C0, 0xFFFFF117, 0x00000435, 0x000023C0, 0xFFFFF117, 0x00000435 }, + { 0x0213F0FD42CC2144, 0x00003125, 0xFFFFEA4E, 0x0000051A, 0x00001E6C, 0xFFFFF503, 0x0000038E, 0x00001E6C, 0xFFFFF503, 0x0000038E }, + { 0x0213EA94DE1C08A4, 0x00001CD4, 0xFFFFF82D, 0x0000030E, 0x0000156D, 0xFFFFFB64, 0x000002B8, 0x0000156D, 0xFFFFFB64, 0x000002B8 }, + { 0x0213EA94DE0240A4, 0x00002F14, 0xFFFFEC46, 0x000004B8, 0x000017F1, 0xFFFFF977, 0x000002D2, 0x000017F1, 0xFFFFF977, 0x000002D2 }, + { 0x0213EA94DE0640A4, 0x000031F1, 0xFFFFEAD4, 0x000004ED, 0x0000184C, 0xFFFFF983, 0x000002D4, 0x0000184C, 0xFFFFF983, 0x000002D4 }, + { 0x0213F0FD42D04984, 0x00002EA9, 0xFFFFEBD7, 0x000004D5, 0x0000288D, 0xFFFFEDDB, 0x000004C0, 0x0000288D, 0xFFFFEDDB, 0x000004C0 }, + { 0x0213F0FD42CA3984, 0x0000335F, 0xFFFFE82C, 0x00000579, 0x00001DBF, 0xFFFFF512, 0x0000038C, 0x00001DBF, 0xFFFFF512, 0x0000038C }, + { 0x0213EA94DE201184, 0x0000224F, 0xFFFFF4B5, 0x00000391, 0x0000138C, 0xFFFFFCC3, 0x0000027A, 0x0000138C, 0xFFFFFCC3, 0x0000027A }, + { 0x0213EA94DE1240A4, 0x0000320D, 0xFFFFEACD, 0x000004F5, 0x00001976, 0xFFFFF913, 0x000002E2, 0x00001976, 0xFFFFF913, 0x000002E2 }, + { 0x0213EA94DE202104, 0x00001BEB, 0xFFFFF99C, 0x000002E4, 0x000016A4, 0xFFFFFB77, 0x000002C3, 0x000016A4, 0xFFFFFB77, 0x000002C3 }, + { 0x0213EA94DE063044, 0x0000396E, 0xFFFFE616, 0x000005A9, 0x000018F4, 0xFFFFF91A, 0x000002E3, 0x000018F4, 0xFFFFF91A, 0x000002E3 }, + { 0x0213EA94DE022864, 0x00003251, 0xFFFFEA8E, 0x000004FA, 0x000018EF, 0xFFFFF910, 0x000002E4, 0x000018EF, 0xFFFFF910, 0x000002E4 }, + { 0x0213EA94DE1C1924, 0x00001DAF, 0xFFFFF857, 0x0000030D, 0x00001915, 0xFFFFF9D8, 0x000002F7, 0x00001915, 0xFFFFF9D8, 0x000002F7 }, + { 0x0213EA94DE2041A4, 0x000025B6, 0xFFFFF26B, 0x000003E5, 0x00001531, 0xFFFFFB68, 0x000002AF, 0x00001531, 0xFFFFFB68, 0x000002AF }, + { 0x0213EA94DE061884, 0x00002B2E, 0xFFFFEF2E, 0x00000440, 0x00001968, 0xFFFFF91A, 0x000002DF, 0x00001968, 0xFFFFF91A, 0x000002DF }, + { 0x0213EA94DE1C2064, 0x00002305, 0xFFFFF528, 0x00000377, 0x000018A4, 0xFFFFF9EB, 0x000002F0, 0x000018A4, 0xFFFFF9EB, 0x000002F0 }, + { 0x0213F0FD42CA40C4, 0x000032A1, 0xFFFFE992, 0x0000052E, 0x00001A55, 0xFFFFF826, 0x000002FE, 0x00001A55, 0xFFFFF826, 0x000002FE }, + { 0x0213EA94DE042184, 0x00002CCD, 0xFFFFEE35, 0x00000462, 0x00001B09, 0xFFFFF7E6, 0x0000030F, 0x00001B09, 0xFFFFF7E6, 0x0000030F }, + { 0x0213EA94DE323084, 0x00002602, 0xFFFFF2CF, 0x000003C5, 0x000016EE, 0xFFFFFAD4, 0x000002B4, 0x000016EE, 0xFFFFFAD4, 0x000002B4 }, + { 0x0213F0FD42D01964, 0x00003370, 0xFFFFE891, 0x00000560, 0x000017F0, 0xFFFFF930, 0x000002DF, 0x000017F0, 0xFFFFF930, 0x000002DF }, + { 0x0213F0FD42CA1884, 0x00002EDC, 0xFFFFEB6D, 0x000004EC, 0x000016E6, 0xFFFFF9ED, 0x000002BC, 0x000016E6, 0xFFFFF9ED, 0x000002BC }, + { 0x0213EA94DE1228C4, 0x00002A05, 0xFFFFF13D, 0x000003F0, 0x00002065, 0xFFFFF57B, 0x00000378, 0x00002065, 0xFFFFF57B, 0x00000378 }, + { 0x0213F0FD42CE2044, 0x00002F8A, 0xFFFFEB6E, 0x000004E4, 0x00001E3E, 0xFFFFF50E, 0x0000038D, 0x00001E3E, 0xFFFFF50E, 0x0000038D }, + { 0x0213F0FD42CA3044, 0x00002BB5, 0xFFFFED6A, 0x000004A1, 0x000017BF, 0xFFFFF937, 0x000002E5, 0x000017BF, 0xFFFFF937, 0x000002E5 }, + { 0x0213EA94DE201964, 0x0000202C, 0xFFFFF6CE, 0x0000033F, 0x000015EE, 0xFFFFFB83, 0x000002B9, 0x000015EE, 0xFFFFFB83, 0x000002B9 }, + { 0x0213EA94DE022884, 0x00002C0C, 0xFFFFEF10, 0x0000043F, 0x00001A73, 0xFFFFF83E, 0x0000030C, 0x00001A73, 0xFFFFF83E, 0x0000030C }, + { 0x0213EA94DE324104, 0x0000234F, 0xFFFFF460, 0x00000385, 0x000018C3, 0xFFFFF9A5, 0x000002DD, 0x000018C3, 0xFFFFF9A5, 0x000002DD }, + { 0x0213F0FD42CE1904, 0x00003679, 0xFFFFE704, 0x00000595, 0x00002177, 0xFFFFF31A, 0x000003D7, 0x00002177, 0xFFFFF31A, 0x000003D7 }, + { 0x0213F0FD42CA2924, 0x00003008, 0xFFFFEBB8, 0x000004D5, 0x000024FF, 0xFFFFF112, 0x00000430, 0x000024FF, 0xFFFFF112, 0x00000430 }, + { 0x0213F0FD42C641A4, 0x00003848, 0xFFFFE6A3, 0x00000594, 0x00002958, 0xFFFFEE37, 0x000004A0, 0x00002958, 0xFFFFEE37, 0x000004A0 }, + { 0x0213F0FD42CC1924, 0x00002FDF, 0xFFFFEB08, 0x000004FD, 0x00001D77, 0xFFFFF58B, 0x0000037A, 0x00001D77, 0xFFFFF58B, 0x0000037A }, + { 0x0213EA94DE063064, 0x00002EC8, 0xFFFFED41, 0x00000481, 0x00001949, 0xFFFFF91C, 0x000002DF, 0x00001949, 0xFFFFF91C, 0x000002DF }, + { 0x0213F0FD42D041A4, 0x000037C1, 0xFFFFE5BA, 0x000005D7, 0x0000252C, 0xFFFFF023, 0x00000460, 0x0000252C, 0xFFFFF023, 0x00000460 }, + { 0x0213F0FD42CE2944, 0x00003716, 0xFFFFE70C, 0x0000058A, 0x000028CC, 0xFFFFEE57, 0x0000049D, 0x000028CC, 0xFFFFEE57, 0x0000049D }, + { 0x0213F0FD42CA40E4, 0x000033D1, 0xFFFFE8E8, 0x00000547, 0x00001AB1, 0xFFFFF7E5, 0x00000309, 0x00001AB1, 0xFFFFF7E5, 0x00000309 }, + { 0x0213F0FD42CC2944, 0x00002D72, 0xFFFFED65, 0x0000048E, 0x00001E0D, 0xFFFFF5A7, 0x00000370, 0x00001E0D, 0xFFFFF5A7, 0x00000370 }, + { 0x0213EA94DE1C39A4, 0x00002292, 0xFFFFF49F, 0x00000393, 0x000017F4, 0xFFFFF9CD, 0x000002F5, 0x000017F4, 0xFFFFF9CD, 0x000002F5 }, + { 0x0213EA94DE243044, 0x000026EE, 0xFFFFF18C, 0x000003F7, 0x000018A7, 0xFFFFF95A, 0x000002E5, 0x000018A7, 0xFFFFF95A, 0x000002E5 }, + { 0x0213EA94DE042164, 0x00002F62, 0xFFFFEC9B, 0x000004A4, 0x0000194E, 0xFFFFF932, 0x000002D9, 0x0000194E, 0xFFFFF932, 0x000002D9 }, + { 0x0213EA94DE1E3984, 0x00001CE8, 0xFFFFF7FA, 0x0000031C, 0x000014CE, 0xFFFFFBD4, 0x000002AB, 0x000014CE, 0xFFFFFBD4, 0x000002AB }, + { 0x0213EA94DE1210E4, 0x00002E5A, 0xFFFFEDAB, 0x0000047C, 0x00001A82, 0xFFFFF8F7, 0x000002DE, 0x00001A82, 0xFFFFF8F7, 0x000002DE }, + { 0x0213F0FD42CC30E4, 0x00003057, 0xFFFFEC34, 0x000004B9, 0x00002296, 0xFFFFF342, 0x000003D0, 0x00002296, 0xFFFFF342, 0x000003D0 }, + { 0x0213EA94DE0418A4, 0x00002B0F, 0xFFFFEF58, 0x00000434, 0x00001BFD, 0xFFFFF721, 0x00000330, 0x00001BFD, 0xFFFFF721, 0x00000330 }, + { 0x0213EA94DE2010A4, 0x00001F01, 0xFFFFF751, 0x0000032F, 0x00001502, 0xFFFFFC3E, 0x00000296, 0x00001502, 0xFFFFFC3E, 0x00000296 }, + { 0x0213F0FD42CA3064, 0x00002FF4, 0xFFFFEAE2, 0x00000503, 0x00001B36, 0xFFFFF736, 0x00000330, 0x00001B36, 0xFFFFF736, 0x00000330 }, + { 0x0213F0FD42CE2064, 0x00003762, 0xFFFFE5AB, 0x000005DE, 0x000018CB, 0xFFFFF896, 0x000002F4, 0x000018CB, 0xFFFFF896, 0x000002F4 }, + { 0x0213F0FD42CC2064, 0x00002890, 0xFFFFEF92, 0x00000445, 0x0000191D, 0xFFFFF86F, 0x00000302, 0x0000191D, 0xFFFFF86F, 0x00000302 }, + { 0x0213EA94DE043064, 0x00002F76, 0xFFFFEC0E, 0x000004BF, 0x00001F7D, 0xFFFFF41A, 0x000003C0, 0x00001F7D, 0xFFFFF41A, 0x000003C0 }, + { 0x0213EA94DE1E08A4, 0x00001D55, 0xFFFFF7F8, 0x0000031E, 0x000015DF, 0xFFFFFB79, 0x000002B7, 0x000015DF, 0xFFFFFB79, 0x000002B7 }, + { 0x0213EA94DE204924, 0x00001FE9, 0xFFFFF64A, 0x00000353, 0x000019E8, 0xFFFFF882, 0x0000032A, 0x000019E8, 0xFFFFF882, 0x0000032A }, + { 0x0213EA94DE063964, 0x000030B5, 0xFFFFEBB8, 0x000004C4, 0x00001857, 0xFFFFF968, 0x000002D8, 0x00001857, 0xFFFFF968, 0x000002D8 }, + { 0x0213F0FD42CA28C4, 0x00003398, 0xFFFFE9A3, 0x00000524, 0x00001FF9, 0xFFFFF458, 0x000003AD, 0x00001FF9, 0xFFFFF458, 0x000003AD }, + { 0x0213F0FD42CE2964, 0x00003897, 0xFFFFE5BD, 0x000005C8, 0x00002519, 0xFFFFF0BA, 0x00000438, 0x00002519, 0xFFFFF0BA, 0x00000438 }, + { 0x0213F0FD42D04064, 0x00003234, 0xFFFFE9B1, 0x00000530, 0x000022CC, 0xFFFFF20E, 0x00000409, 0x000022CC, 0xFFFFF20E, 0x00000409 }, + { 0x0213EA94DE205104, 0x00001FD2, 0xFFFFF641, 0x00000354, 0x000017C9, 0xFFFFF9C0, 0x000002FB, 0x000017C9, 0xFFFFF9C0, 0x000002FB }, + { 0x0213F0FD42CE48E4, 0x00003234, 0xFFFFE946, 0x0000053D, 0x00002267, 0xFFFFF1F5, 0x0000040D, 0x00002267, 0xFFFFF1F5, 0x0000040D }, + { 0x0213EA94DE2029A4, 0x00002330, 0xFFFFF474, 0x00000399, 0x00001490, 0xFFFFFC67, 0x00000288, 0x00001490, 0xFFFFFC67, 0x00000288 }, + { 0x0213F0FD42D03924, 0x000032A3, 0xFFFFE9EB, 0x0000051B, 0x0000234D, 0xFFFFF23C, 0x000003F7, 0x0000234D, 0xFFFFF23C, 0x000003F7 }, + { 0x0213EA94DE200904, 0x0000217E, 0xFFFFF53A, 0x00000384, 0x00001511, 0xFFFFFBF5, 0x0000029E, 0x00001511, 0xFFFFFBF5, 0x0000029E }, + { 0x0213F0FD42CE50E4, 0x0000384F, 0xFFFFE562, 0x000005E2, 0x0000295A, 0xFFFFED53, 0x000004D3, 0x0000295A, 0xFFFFED53, 0x000004D3 }, + { 0x0213F0FD42D05124, 0x00003315, 0xFFFFE8D1, 0x00000552, 0x000025D1, 0xFFFFEFAF, 0x00000471, 0x000025D1, 0xFFFFEFAF, 0x00000471 }, + { 0x0213F0FD42C64924, 0x00004183, 0xFFFFDF61, 0x000006DA, 0x0000193C, 0xFFFFF88F, 0x000002EC, 0x0000193C, 0xFFFFF88F, 0x000002EC }, + { 0x0213EA94DE242164, 0x00002DFC, 0xFFFFEDF2, 0x0000047A, 0x00001755, 0xFFFFFAC2, 0x000002AC, 0x00001755, 0xFFFFFAC2, 0x000002AC }, + { 0x0213F0FD42CA31A4, 0x000033FE, 0xFFFFE774, 0x0000059F, 0x00001E70, 0xFFFFF492, 0x000003A0, 0x00001E70, 0xFFFFF492, 0x000003A0 }, + { 0x0213F0FD42C629A4, 0x000040D7, 0xFFFFDFB8, 0x000006CE, 0x00001AC8, 0xFFFFF773, 0x0000031D, 0x00001AC8, 0xFFFFF773, 0x0000031D }, + { 0x0213EA94DE1E1164, 0x00001D02, 0xFFFFF803, 0x00000322, 0x000015FE, 0xFFFFFB71, 0x000002BB, 0x000015FE, 0xFFFFFB71, 0x000002BB }, + { 0x0213F0FD42D02884, 0x00002EB0, 0xFFFFEC31, 0x000004C4, 0x00001B3C, 0xFFFFF73B, 0x00000330, 0x00001B3C, 0xFFFFF73B, 0x00000330 }, + { 0x0213F0FD42CA4984, 0x00002D9F, 0xFFFFECBF, 0x000004A8, 0x000022B0, 0xFFFFF23C, 0x000003F9, 0x000022B0, 0xFFFFF23C, 0x000003F9 }, + { 0x0213F0FD42CC18E4, 0x00002C6A, 0xFFFFEDAC, 0x00000488, 0x00002419, 0xFFFFF159, 0x00000427, 0x00002419, 0xFFFFF159, 0x00000427 }, + { 0x0213EA94DE1210A4, 0x00002991, 0xFFFFF06C, 0x0000040E, 0x00001AA9, 0xFFFFF8D0, 0x000002E1, 0x00001AA9, 0xFFFFF8D0, 0x000002E1 }, + { 0x0213EA94DE123904, 0x00002F8E, 0xFFFFED1B, 0x00000493, 0x00001DE4, 0xFFFFF69C, 0x00000347, 0x00001DE4, 0xFFFFF69C, 0x00000347 }, + { 0x0213EA94DE204184, 0x00002136, 0xFFFFF540, 0x0000037C, 0x000014FF, 0xFFFFFB83, 0x000002B2, 0x000014FF, 0xFFFFFB83, 0x000002B2 }, + { 0x0213EA94DE0618E4, 0x0000354C, 0xFFFFE97D, 0x0000051A, 0x00001906, 0xFFFFF965, 0x000002DD, 0x00001906, 0xFFFFF965, 0x000002DD }, + { 0x0213F0FD42C620C4, 0x0000348B, 0xFFFFE94D, 0x0000051F, 0x0000285B, 0xFFFFEF1A, 0x00000473, 0x0000285B, 0xFFFFEF1A, 0x00000473 }, + { 0x0213EA94DE3218A4, 0x000026E6, 0xFFFFF24E, 0x000003D6, 0x0000141F, 0xFFFFFCCE, 0x00000260, 0x0000141F, 0xFFFFFCCE, 0x00000260 }, + { 0x0213F0FD42C64164, 0x00003CED, 0xFFFFE2A5, 0x0000064E, 0x00002060, 0xFFFFF3E0, 0x000003B0, 0x00002060, 0xFFFFF3E0, 0x000003B0 }, + { 0x0213EA94DE021084, 0x000029D4, 0xFFFFEFF7, 0x00000426, 0x00001976, 0xFFFFF8E1, 0x000002EE, 0x00001976, 0xFFFFF8E1, 0x000002EE }, + { 0x0213F0FD42CA40A4, 0x00003767, 0xFFFFE601, 0x000005CC, 0x00001D22, 0xFFFFF5F4, 0x00000361, 0x00001D22, 0xFFFFF5F4, 0x00000361 }, + { 0x0213F0FD42C650C4, 0x00003CE8, 0xFFFFE2E8, 0x00000637, 0x0000232C, 0xFFFFF1E7, 0x00000405, 0x0000232C, 0xFFFFF1E7, 0x00000405 }, + { 0x0213EA94DE201064, 0x000023A8, 0xFFFFF4CD, 0x00000386, 0x00001944, 0xFFFFF983, 0x00000300, 0x00001944, 0xFFFFF983, 0x00000300 }, + { 0x0213F0FD42CC30A4, 0x00003451, 0xFFFFE8B9, 0x00000551, 0x00001AD7, 0xFFFFF7BF, 0x00000318, 0x00001AD7, 0xFFFFF7BF, 0x00000318 }, + { 0x0213F0FD42CE2984, 0x0000381B, 0xFFFFE5A0, 0x000005D0, 0x00001E0F, 0xFFFFF521, 0x00000382, 0x00001E0F, 0xFFFFF521, 0x00000382 }, + { 0x0213EA94DE2038C4, 0x000023A4, 0xFFFFF4A6, 0x00000394, 0x0000171F, 0xFFFFFABB, 0x000002D9, 0x0000171F, 0xFFFFFABB, 0x000002D9 }, + { 0x0213F0FD42C620A4, 0x00003C2B, 0xFFFFE447, 0x000005F0, 0x0000207F, 0xFFFFF44E, 0x0000039A, 0x0000207F, 0xFFFFF44E, 0x0000039A }, + { 0x0213F0FD42CC3984, 0x00002F07, 0xFFFFEB70, 0x000004E9, 0x00001765, 0xFFFFF9A5, 0x000002C6, 0x00001765, 0xFFFFF9A5, 0x000002C6 }, + { 0x0213F0FD42C62984, 0x00003A01, 0xFFFFE4E0, 0x000005E7, 0x0000227A, 0xFFFFF292, 0x000003E5, 0x0000227A, 0xFFFFF292, 0x000003E5 }, + { 0x0213F0FD42CE20A4, 0x0000376E, 0xFFFFE686, 0x000005A6, 0x00001FCF, 0xFFFFF43B, 0x000003A8, 0x00001FCF, 0xFFFFF43B, 0x000003A8 }, + { 0x0213F0FFEF5A4984, 0x0000485F, 0xFFFFDCC1, 0x00000713, 0x00002CF8, 0xFFFFEC45, 0x000004DA, 0x00002CF8, 0xFFFFEC45, 0x000004DA }, + { 0x0213F0FFEF5C3184, 0x0000331C, 0xFFFFE8FF, 0x00000541, 0x00002366, 0xFFFFF19D, 0x00000411, 0x00002366, 0xFFFFF19D, 0x00000411 }, + { 0x0213F0FFEF643864, 0x00003CF3, 0xFFFFE15A, 0x00000694, 0x00002FB3, 0xFFFFE827, 0x000005B9, 0x00002FB3, 0xFFFFE827, 0x000005B9 }, + { 0x0213EA94DE321104, 0x000023F3, 0xFFFFF3EA, 0x0000039A, 0x00001345, 0xFFFFFD6B, 0x00000241, 0x00001345, 0xFFFFFD6B, 0x00000241 }, + { 0x0213F0FFEF5C28A4, 0x000038C0, 0xFFFFE58A, 0x000005CC, 0x000023CA, 0xFFFFF1AA, 0x00000408, 0x000023CA, 0xFFFFF1AA, 0x00000408 }, + { 0x0213F0FFEF662944, 0x00004976, 0xFFFFDD6A, 0x000006D7, 0x000033C6, 0xFFFFE8EB, 0x0000054D, 0x000033C6, 0xFFFFE8EB, 0x0000054D }, + { 0x0213F0FFEF644904, 0x00004049, 0xFFFFDF6D, 0x000006D8, 0x00003129, 0xFFFFE716, 0x000005E9, 0x00003129, 0xFFFFE716, 0x000005E9 }, + { 0x0213F0FFEF661164, 0x000046C2, 0xFFFFDCEB, 0x0000071C, 0x00002E6D, 0xFFFFEA8F, 0x0000052E, 0x00002E6D, 0xFFFFEA8F, 0x0000052E }, + { 0x0213F0FFEF6238A4, 0x00004080, 0xFFFFE1E1, 0x0000063A, 0x0000396D, 0xFFFFE40A, 0x0000062C, 0x0000396D, 0xFFFFE40A, 0x0000062C }, + { 0x0213F0FFEF5E2124, 0x00003DE0, 0xFFFFE358, 0x0000060C, 0x00002AA2, 0xFFFFEDBF, 0x000004A0, 0x00002AA2, 0xFFFFEDBF, 0x000004A0 }, + { 0x0213F0FFEF5E3144, 0x00003FC0, 0xFFFFE2A1, 0x0000061A, 0x000027D8, 0xFFFFEFEC, 0x0000043A, 0x000027D8, 0xFFFFEFEC, 0x0000043A }, + { 0x0213F0FFEF661924, 0x00003FBF, 0xFFFFE2F5, 0x00000603, 0x000032D7, 0xFFFFE900, 0x00000552, 0x000032D7, 0xFFFFE900, 0x00000552 }, + { 0x0213F0FFEF5C10E4, 0x000035EE, 0xFFFFE6CA, 0x000005A2, 0x0000247C, 0xFFFFF088, 0x00000446, 0x0000247C, 0xFFFFF088, 0x00000446 }, + { 0x0213F0FFEF643884, 0x000039C8, 0xFFFFE3AE, 0x0000062A, 0x000028AF, 0xFFFFED24, 0x000004DF, 0x000028AF, 0xFFFFED24, 0x000004DF }, + { 0x0213F0FFEF5C2884, 0x00003BDE, 0xFFFFE33B, 0x00000632, 0x00001B6C, 0xFFFFF720, 0x00000326, 0x00001B6C, 0xFFFFF720, 0x00000326 }, + { 0x0213F0FFEF7210A4, 0x00003818, 0xFFFFE57D, 0x000005D4, 0x000020EF, 0xFFFFF327, 0x000003CE, 0x000020EF, 0xFFFFF327, 0x000003CE }, + { 0x0213F0FFEF5E19A4, 0x000038DA, 0xFFFFE561, 0x000005D3, 0x0000297D, 0xFFFFED6D, 0x000004C5, 0x0000297D, 0xFFFFED6D, 0x000004C5 }, + { 0x0213F0FFEF684884, 0x000027AC, 0xFFFFF0CE, 0x00000417, 0x00001F5F, 0xFFFFF484, 0x000003B2, 0x00001F5F, 0xFFFFF484, 0x000003B2 }, + { 0x0213F0FFEF6648A4, 0x00003F02, 0xFFFFE222, 0x00000643, 0x000026D4, 0xFFFFF000, 0x00000443, 0x000026D4, 0xFFFFF000, 0x00000443 }, + { 0x0213F0FFEF624164, 0x00004303, 0xFFFFDFE3, 0x00000690, 0x0000312C, 0xFFFFE912, 0x00000561, 0x0000312C, 0xFFFFE912, 0x00000561 }, + { 0x0213F0FFEF600904, 0x000039E5, 0xFFFFE31F, 0x00000657, 0x00001D23, 0xFFFFF51F, 0x00000386, 0x00001D23, 0xFFFFF51F, 0x00000386 }, + { 0x0213F0FFEF661144, 0x000041FA, 0xFFFFE01B, 0x00000697, 0x00002767, 0xFFFFEF90, 0x00000455, 0x00002767, 0xFFFFEF90, 0x00000455 }, + { 0x0213F0FFEF6830A4, 0x00002888, 0xFFFFF11C, 0x00000403, 0x00001864, 0xFFFFF9D8, 0x000002D3, 0x00001864, 0xFFFFF9D8, 0x000002D3 }, + { 0x0213EA94DE201864, 0x0000215C, 0xFFFFF5B6, 0x0000036D, 0x000015C5, 0xFFFFFB8A, 0x000002B5, 0x000015C5, 0xFFFFFB8A, 0x000002B5 }, + { 0x0213F0FFEF683984, 0x00002FAF, 0xFFFFEC27, 0x000004CA, 0x00002184, 0xFFFFF39C, 0x000003CD, 0x00002184, 0xFFFFF39C, 0x000003CD }, + { 0x0213F0FFEF5E10C4, 0x00004ACE, 0xFFFFD9A3, 0x000007BC, 0x00001A5D, 0xFFFFF7F6, 0x000002FC, 0x00001A5D, 0xFFFFF7F6, 0x000002FC }, + { 0x0213F0FFEF5A3044, 0x00003763, 0xFFFFE797, 0x0000055F, 0x000029B5, 0xFFFFEEA1, 0x00000474, 0x000029B5, 0xFFFFEEA1, 0x00000474 }, + { 0x0213F0FFEF5E3164, 0x00003832, 0xFFFFE6F9, 0x00000575, 0x00002C99, 0xFFFFEC42, 0x000004E3, 0x00002C99, 0xFFFFEC42, 0x000004E3 }, + { 0x0213F0FFEF604164, 0x000041C9, 0xFFFFDE33, 0x0000071E, 0x0000199D, 0xFFFFF808, 0x000002F9, 0x0000199D, 0xFFFFF808, 0x000002F9 }, + { 0x0213F0FFEF641164, 0x0000474A, 0xFFFFD96E, 0x00000802, 0x00002A30, 0xFFFFEB57, 0x0000053F, 0x00002A30, 0xFFFFEB57, 0x0000053F }, + { 0x0213F0FFEF5C31C4, 0x0000312F, 0xFFFFEA6A, 0x00000508, 0x000029D3, 0xFFFFED38, 0x000004D3, 0x000029D3, 0xFFFFED38, 0x000004D3 }, + { 0x0213F0FFEF7210C4, 0x00003BD6, 0xFFFFE2E7, 0x00000644, 0x00002093, 0xFFFFF37B, 0x000003BD, 0x00002093, 0xFFFFF37B, 0x000003BD }, + { 0x0213F0FFEF6840E4, 0x00002F94, 0xFFFFECD4, 0x000004A3, 0x00002196, 0xFFFFF40B, 0x000003B5, 0x00002196, 0xFFFFF40B, 0x000003B5 }, + { 0x0213F0FFEF5E1944, 0x0000369B, 0xFFFFE762, 0x00000571, 0x00002726, 0xFFFFEF99, 0x00000459, 0x00002726, 0xFFFFEF99, 0x00000459 }, + { 0x0213F0FFEF642064, 0x00003F57, 0xFFFFDF47, 0x000006F4, 0x00002E5F, 0xFFFFE8AE, 0x000005AB, 0x00002E5F, 0xFFFFE8AE, 0x000005AB }, + { 0x0213EA94DE0A40C4, 0x00004313, 0xFFFFDD81, 0x0000072D, 0x00002468, 0xFFFFF068, 0x00000440, 0x00002468, 0xFFFFF068, 0x00000440 }, + { 0x0213F0FFEF683044, 0x00002A35, 0xFFFFEFA8, 0x00000441, 0x00001F3F, 0xFFFFF4F3, 0x000003A0, 0x00001F3F, 0xFFFFF4F3, 0x000003A0 }, + { 0x0213F0FFEF6630A4, 0x00003E33, 0xFFFFE4B0, 0x000005AF, 0x00002802, 0xFFFFF092, 0x00000412, 0x00002802, 0xFFFFF092, 0x00000412 }, + { 0x0213EA94DE323904, 0x00002815, 0xFFFFF20E, 0x000003DD, 0x00001C33, 0xFFFFF7D5, 0x0000032A, 0x00001C33, 0xFFFFF7D5, 0x0000032A }, + { 0x0213F0FFEF5A2184, 0x00003CC2, 0xFFFFE43E, 0x000005DE, 0x00002C16, 0xFFFFECED, 0x000004BA, 0x00002C16, 0xFFFFECED, 0x000004BA }, + { 0x0213F0FFEF5C4084, 0x00003CFA, 0xFFFFE1EE, 0x00000673, 0x00001F7D, 0xFFFFF402, 0x000003AE, 0x00001F7D, 0xFFFFF402, 0x000003AE }, + { 0x0213F0FFEF622104, 0x0000486E, 0xFFFFDD43, 0x000006EE, 0x000036F0, 0xFFFFE609, 0x000005D5, 0x000036F0, 0xFFFFE609, 0x000005D5 }, + { 0x0213F0FFEF5C4964, 0x000039FE, 0xFFFFE41F, 0x00000613, 0x0000266C, 0xFFFFEF35, 0x0000047D, 0x0000266C, 0xFFFFEF35, 0x0000047D }, + { 0x0213EA94DE123124, 0x00002EA4, 0xFFFFEE3B, 0x00000462, 0x00002126, 0xFFFFF4E2, 0x0000038F, 0x00002126, 0xFFFFF4E2, 0x0000038F }, + { 0x0213F0FFEF683944, 0x00002D2E, 0xFFFFEE7B, 0x00000462, 0x0000229D, 0xFFFFF363, 0x000003D4, 0x0000229D, 0xFFFFF363, 0x000003D4 }, + { 0x0213F0FFEF5E2844, 0x0000375C, 0xFFFFE695, 0x0000059D, 0x00002319, 0xFFFFF237, 0x000003EE, 0x00002319, 0xFFFFF237, 0x000003EE }, + { 0x0213F0FFEF7250C4, 0x00004522, 0xFFFFDC71, 0x0000075E, 0x0000247E, 0xFFFFF0A0, 0x0000043C, 0x0000247E, 0xFFFFF0A0, 0x0000043C }, + { 0x0213EA94DE1248E4, 0x00002E58, 0xFFFFECB9, 0x000004A9, 0x0000199A, 0xFFFFF8CF, 0x000002E9, 0x0000199A, 0xFFFFF8CF, 0x000002E9 }, + { 0x0213F0FFEF6438E4, 0x00003791, 0xFFFFE5FE, 0x000005B6, 0x000029F5, 0xFFFFED0D, 0x000004CD, 0x000029F5, 0xFFFFED0D, 0x000004CD }, + { 0x0213EA94DE244144, 0x00002E9E, 0xFFFFEC8D, 0x000004C1, 0x000019D0, 0xFFFFF869, 0x0000030F, 0x000019D0, 0xFFFFF869, 0x0000030F }, + { 0x0213EA94DE203964, 0x0000237C, 0xFFFFF435, 0x000003A6, 0x000014EB, 0xFFFFFBC4, 0x000002AF, 0x000014EB, 0xFFFFFBC4, 0x000002AF }, + { 0x0213F0FFEF662924, 0x00003FE5, 0xFFFFE4A2, 0x000005A0, 0x00003416, 0xFFFFE995, 0x00000523, 0x00003416, 0xFFFFE995, 0x00000523 }, + { 0x0213F0FFEF5C0924, 0x00002B27, 0xFFFFED51, 0x000004A5, 0x000025D1, 0xFFFFEF18, 0x00000492, 0x000025D1, 0xFFFFEF18, 0x00000492 }, + { 0x0213F0FFEF684904, 0x00002D77, 0xFFFFED79, 0x00000494, 0x00002196, 0xFFFFF352, 0x000003DE, 0x00002196, 0xFFFFF352, 0x000003DE }, + { 0x0213F0FFEF5C20C4, 0x00003750, 0xFFFFE6AC, 0x00000596, 0x00002524, 0xFFFFF0B5, 0x00000431, 0x00002524, 0xFFFFF0B5, 0x00000431 }, + { 0x0213EA94DE122944, 0x00002896, 0xFFFFF1BB, 0x000003D9, 0x00001CE0, 0xFFFFF753, 0x0000032F, 0x00001CE0, 0xFFFFF753, 0x0000032F }, + { 0x0213F0FFEF641984, 0x00003CA7, 0xFFFFE0F7, 0x000006B1, 0x00002CB8, 0xFFFFE9AB, 0x00000587, 0x00002CB8, 0xFFFFE9AB, 0x00000587 }, + { 0x0213EA94DE322864, 0x00002513, 0xFFFFF323, 0x000003BC, 0x00001965, 0xFFFFF93C, 0x000002F0, 0x00001965, 0xFFFFF93C, 0x000002F0 }, + { 0x0213F0FFEF662164, 0x00003914, 0xFFFFE683, 0x00000586, 0x00003120, 0xFFFFE9A6, 0x00000543, 0x00003120, 0xFFFFE9A6, 0x00000543 }, + { 0x0213F0FFEF643904, 0x000040D0, 0xFFFFE007, 0x000006AC, 0x00002B9E, 0xFFFFEBF5, 0x000004FB, 0x00002B9E, 0xFFFFEBF5, 0x000004FB }, + { 0x0213F0FFEF5A4884, 0x00004412, 0xFFFFDF5F, 0x000006A9, 0x00002A9E, 0xFFFFEDCE, 0x00000498, 0x00002A9E, 0xFFFFEDCE, 0x00000498 }, + { 0x0213F0FFEF624884, 0x000042A6, 0xFFFFDFEF, 0x00000696, 0x00002E65, 0xFFFFEAAE, 0x00000529, 0x00002E65, 0xFFFFEAAE, 0x00000529 }, + { 0x0213EA94DE322124, 0x000022E8, 0xFFFFF565, 0x0000035F, 0x00001890, 0xFFFFFA61, 0x000002C6, 0x00001890, 0xFFFFFA61, 0x000002C6 }, + { 0x0213F0FFEF6239A4, 0x00004637, 0xFFFFDDD8, 0x000006E9, 0x0000349D, 0xFFFFE6C8, 0x000005C7, 0x0000349D, 0xFFFFE6C8, 0x000005C7 }, + { 0x0213EA94DE263904, 0x00004686, 0xFFFFDC58, 0x0000073D, 0x00003972, 0xFFFFE27B, 0x0000068E, 0x00003972, 0xFFFFE27B, 0x0000068E }, + { 0x0213F0FFEF6808E4, 0x00002B35, 0xFFFFEE9C, 0x0000046C, 0x00001F5B, 0xFFFFF4A3, 0x000003A9, 0x00001F5B, 0xFFFFF4A3, 0x000003A9 }, + { 0x0213F0FFEF724144, 0x00003AC9, 0xFFFFE3B2, 0x0000061B, 0x000023A1, 0xFFFFF170, 0x0000040F, 0x000023A1, 0xFFFFF170, 0x0000040F }, + { 0x0213F0FFEF5E1884, 0x00003C50, 0xFFFFE37E, 0x00000617, 0x0000218F, 0xFFFFF339, 0x000003C4, 0x0000218F, 0xFFFFF339, 0x000003C4 }, + { 0x0213F0FFEF663044, 0x00003793, 0xFFFFE761, 0x0000055D, 0x000029C7, 0xFFFFEE03, 0x00000496, 0x000029C7, 0xFFFFEE03, 0x00000496 }, + { 0x0213F0FFEF6438A4, 0x000040B5, 0xFFFFDF78, 0x000006DA, 0x00002DED, 0xFFFFEA20, 0x00000551, 0x00002DED, 0xFFFFEA20, 0x00000551 }, + { 0x0213F0FFEF601144, 0x000039D6, 0xFFFFE37D, 0x0000063C, 0x00001AED, 0xFFFFF6E2, 0x00000331, 0x00001AED, 0xFFFFF6E2, 0x00000331 }, + { 0x0213F0FFEF662144, 0x0000431F, 0xFFFFE09B, 0x0000066A, 0x00002BDF, 0xFFFFED93, 0x00000496, 0x00002BDF, 0xFFFFED93, 0x00000496 }, + { 0x0213F0FFEF623864, 0x00004887, 0xFFFFDC65, 0x00000721, 0x00003669, 0xFFFFE5C4, 0x000005E9, 0x00003669, 0xFFFFE5C4, 0x000005E9 }, + { 0x0213F0FFEF640924, 0x00004120, 0xFFFFDDAE, 0x00000748, 0x0000303B, 0xFFFFE70D, 0x000005FC, 0x0000303B, 0xFFFFE70D, 0x000005FC }, + { 0x0213F0FFEF5E28A4, 0x0000415D, 0xFFFFE0BE, 0x0000067B, 0x00002FA7, 0xFFFFEA28, 0x00000538, 0x00002FA7, 0xFFFFEA28, 0x00000538 }, + { 0x0213F0FFEF681904, 0x00002B12, 0xFFFFEFF9, 0x00000428, 0x00001DDA, 0xFFFFF693, 0x00000356, 0x00001DDA, 0xFFFFF693, 0x00000356 }, + { 0x0213F0FFEF5E3184, 0x00003ED3, 0xFFFFE28D, 0x0000062D, 0x00002B00, 0xFFFFED4E, 0x000004B3, 0x00002B00, 0xFFFFED4E, 0x000004B3 }, + { 0x0213F0FFEF6250A4, 0x00004218, 0xFFFFE039, 0x0000068F, 0x00002F84, 0xFFFFEA0C, 0x00000541, 0x00002F84, 0xFFFFEA0C, 0x00000541 }, + { 0x0213F0FFEF5A3844, 0x00003FF5, 0xFFFFE2A3, 0x00000617, 0x00003017, 0xFFFFEA7A, 0x00000520, 0x00003017, 0xFFFFEA7A, 0x00000520 }, + { 0x0213F0FFEF5A08A4, 0x00004304, 0xFFFFDFCC, 0x0000069E, 0x00002E0C, 0xFFFFEB51, 0x00000505, 0x00002E0C, 0xFFFFEB51, 0x00000505 }, + { 0x0213F0FFEF641944, 0x00003D3A, 0xFFFFE17F, 0x00000687, 0x0000284C, 0xFFFFED83, 0x000004CD, 0x0000284C, 0xFFFFED83, 0x000004CD }, + { 0x0213F0FFEF5E40A4, 0x000042F5, 0xFFFFDF76, 0x000006B2, 0x000027B6, 0xFFFFEF72, 0x00000455, 0x000027B6, 0xFFFFEF72, 0x00000455 }, + { 0x0213F0FFEF5C38C4, 0x00004267, 0xFFFFDF29, 0x000006D5, 0x0000298F, 0xFFFFEDBD, 0x000004AC, 0x0000298F, 0xFFFFEDBD, 0x000004AC }, + { 0x0213EA94DE240924, 0x0000303E, 0xFFFFEC00, 0x000004CB, 0x000021CD, 0xFFFFF36E, 0x000003D6, 0x000021CD, 0xFFFFF36E, 0x000003D6 }, + { 0x0213F0FFEF5E28C4, 0x00003127, 0xFFFFEBDB, 0x000004A6, 0x00002E95, 0xFFFFEB78, 0x000004F3, 0x00002E95, 0xFFFFEB78, 0x000004F3 }, + { 0x0213EA94DE1C1064, 0x00002655, 0xFFFFF2D9, 0x000003CF, 0x000019F5, 0xFFFFF8E7, 0x00000313, 0x000019F5, 0xFFFFF8E7, 0x00000313 }, + { 0x0213EA94DE164084, 0x00002372, 0xFFFFF449, 0x0000039B, 0x00001544, 0xFFFFFC16, 0x0000028B, 0x00001544, 0xFFFFFC16, 0x0000028B }, + { 0x0213F0FFEF6628C4, 0x0000348E, 0xFFFFEB20, 0x000004B2, 0x00002BE8, 0xFFFFEE80, 0x00000467, 0x00002BE8, 0xFFFFEE80, 0x00000467 }, + { 0x0213F0FFEF5E1104, 0x00004092, 0xFFFFE073, 0x0000069B, 0x00002061, 0xFFFFF403, 0x000003A0, 0x00002061, 0xFFFFF403, 0x000003A0 }, + { 0x0213F0FFEF7220E4, 0x000039D1, 0xFFFFE55D, 0x000005CC, 0x000025CB, 0xFFFFF0C0, 0x00000428, 0x000025CB, 0xFFFFF0C0, 0x00000428 }, + { 0x0213F0FFEF5E4884, 0x000042AA, 0xFFFFDF68, 0x000006C2, 0x0000290B, 0xFFFFEE78, 0x00000485, 0x0000290B, 0xFFFFEE78, 0x00000485 }, + { 0x0213F0FFEF7218C4, 0x0000356F, 0xFFFFE7AC, 0x0000056E, 0x00001BE8, 0xFFFFF6E3, 0x0000032A, 0x00001BE8, 0xFFFFF6E3, 0x0000032A }, + { 0x0213F0FFEF5E1144, 0x00003525, 0xFFFFE7FF, 0x0000055D, 0x0000242C, 0xFFFFF12E, 0x0000041D, 0x0000242C, 0xFFFFF12E, 0x0000041D }, + { 0x0213F0FFEF5C48C4, 0x00003360, 0xFFFFE895, 0x00000550, 0x00002175, 0xFFFFF29E, 0x000003E9, 0x00002175, 0xFFFFF29E, 0x000003E9 }, + { 0x0213F0FFEF6440A4, 0x00003C94, 0xFFFFE1C4, 0x0000067E, 0x00002E28, 0xFFFFE964, 0x0000057F, 0x00002E28, 0xFFFFE964, 0x0000057F }, + { 0x0213F0FFEF724124, 0x0000431C, 0xFFFFDE4B, 0x000006FF, 0x00002270, 0xFFFFF268, 0x000003E5, 0x00002270, 0xFFFFF268, 0x000003E5 }, + { 0x0213EA94DE1218C4, 0x00002B67, 0xFFFFF01D, 0x00000414, 0x000019FB, 0xFFFFF961, 0x000002D8, 0x000019FB, 0xFFFFF961, 0x000002D8 }, + { 0x0213F0FFEF5E3984, 0x0000400B, 0xFFFFE13D, 0x0000066F, 0x000024F3, 0xFFFFF125, 0x00000417, 0x000024F3, 0xFFFFF125, 0x00000417 }, + { 0x0213F0FFEF5A20A4, 0x00004460, 0xFFFFE00E, 0x0000067B, 0x000023DF, 0xFFFFF2E6, 0x000003BB, 0x000023DF, 0xFFFFF2E6, 0x000003BB }, + { 0x0213F0FFEF641864, 0x00003AFB, 0xFFFFE2C5, 0x00000650, 0x00002D46, 0xFFFFE9C4, 0x00000571, 0x00002D46, 0xFFFFE9C4, 0x00000571 }, + { 0x0213F0FFEF622924, 0x00005482, 0xFFFFD5BC, 0x0000081A, 0x00003250, 0xFFFFE961, 0x00000541, 0x00003250, 0xFFFFE961, 0x00000541 }, + { 0x0213F0FFEF5C2944, 0x00003D27, 0xFFFFE2FA, 0x00000632, 0x00002A4D, 0xFFFFED6A, 0x000004BB, 0x00002A4D, 0xFFFFED6A, 0x000004BB }, + { 0x0213F0FFEF6018A4, 0x00003E03, 0xFFFFE142, 0x00000690, 0x00001E08, 0xFFFFF555, 0x0000036C, 0x00001E08, 0xFFFFF555, 0x0000036C }, + { 0x0213F0FFEF5C2064, 0x000031B5, 0xFFFFE97D, 0x00000535, 0x0000232E, 0xFFFFF166, 0x00000422, 0x0000232E, 0xFFFFF166, 0x00000422 }, + { 0x0213F0FFEF5E18E4, 0x00003753, 0xFFFFE724, 0x00000575, 0x0000281A, 0xFFFFEF1A, 0x0000046B, 0x0000281A, 0xFFFFEF1A, 0x0000046B }, + { 0x0213EA94DE204144, 0x00002071, 0xFFFFF5C9, 0x0000036F, 0x00001470, 0xFFFFFBF7, 0x000002A5, 0x00001470, 0xFFFFFBF7, 0x000002A5 }, + { 0x0213F0FFEF683144, 0x00002799, 0xFFFFF223, 0x000003CF, 0x00001CD3, 0xFFFFF74A, 0x00000333, 0x00001CD3, 0xFFFFF74A, 0x00000333 }, + { 0x0213F0FFEF6610C4, 0x000040DF, 0xFFFFE11C, 0x00000664, 0x000031D4, 0xFFFFE8BC, 0x0000056F, 0x000031D4, 0xFFFFE8BC, 0x0000056F }, + { 0x0213F0FFEF6440C4, 0x00003A4D, 0xFFFFE3A6, 0x00000627, 0x00002871, 0xFFFFEDA0, 0x000004C0, 0x00002871, 0xFFFFEDA0, 0x000004C0 }, + { 0x0213F0FFEF681984, 0x00002AF9, 0xFFFFEED7, 0x00000464, 0x0000219B, 0xFFFFF368, 0x000003D6, 0x0000219B, 0xFFFFF368, 0x000003D6 }, + { 0x0213EA94DE323124, 0x000026D5, 0xFFFFF36C, 0x000003A3, 0x00001BC6, 0xFFFFF881, 0x00000311, 0x00001BC6, 0xFFFFF881, 0x00000311 }, + { 0x0213F0FFEF5E2044, 0x0000325D, 0xFFFFEA07, 0x0000050B, 0x000026D1, 0xFFFFEFB3, 0x0000045A, 0x000026D1, 0xFFFFEFB3, 0x0000045A }, + { 0x0213F0FFEF682864, 0x00002F75, 0xFFFFEC64, 0x000004BE, 0x00001EEB, 0xFFFFF559, 0x00000386, 0x00001EEB, 0xFFFFF559, 0x00000386 }, + { 0x0213F0FFEF5A38A4, 0x00003C2F, 0xFFFFE541, 0x000005A3, 0x000025B6, 0xFFFFF16F, 0x000003FA, 0x000025B6, 0xFFFFF16F, 0x000003FA }, + { 0x0213F0FFEF684924, 0x00002BC2, 0xFFFFEE89, 0x0000046A, 0x00001D04, 0xFFFFF651, 0x00000361, 0x00001D04, 0xFFFFF651, 0x00000361 }, + { 0x0213F0FFEF6829A4, 0x00002DD0, 0xFFFFED40, 0x0000049F, 0x00001C8C, 0xFFFFF6B3, 0x00000353, 0x00001C8C, 0xFFFFF6B3, 0x00000353 }, + { 0x0213EA94DE1C08E4, 0x000021ED, 0xFFFFF530, 0x00000380, 0x00001643, 0xFFFFFB1C, 0x000002C3, 0x00001643, 0xFFFFFB1C, 0x000002C3 }, + { 0x0213EA94DE321904, 0x000028C7, 0xFFFFF160, 0x000003FD, 0x00001990, 0xFFFFF994, 0x000002E2, 0x00001990, 0xFFFFF994, 0x000002E2 }, + { 0x0213F0FFEF6610A4, 0x0000431C, 0xFFFFDF9D, 0x000006A3, 0x000034A6, 0xFFFFE6B0, 0x000005C9, 0x000034A6, 0xFFFFE6B0, 0x000005C9 }, + { 0x0213EA94DE2630A4, 0x00004115, 0xFFFFE0D6, 0x00000667, 0x000031AD, 0xFFFFE850, 0x00000585, 0x000031AD, 0xFFFFE850, 0x00000585 }, + { 0x0213F0FFEF643924, 0x0000424A, 0xFFFFDEEC, 0x000006E1, 0x0000346A, 0xFFFFE5EA, 0x00000602, 0x0000346A, 0xFFFFE5EA, 0x00000602 }, + { 0x0213F0FFEF661984, 0x00004990, 0xFFFFDAFA, 0x00000771, 0x00002A9C, 0xFFFFED37, 0x000004BC, 0x00002A9C, 0xFFFFED37, 0x000004BC }, + { 0x0213F0FFEF6428A4, 0x00003858, 0xFFFFE568, 0x000005D2, 0x00003030, 0xFFFFE8B0, 0x0000058E, 0x00003030, 0xFFFFE8B0, 0x0000058E }, + { 0x0213F0FFEF684164, 0x00001EDC, 0xFFFFF6CD, 0x00000322, 0x00001FCA, 0xFFFFF4BD, 0x0000039E, 0x00001FCA, 0xFFFFF4BD, 0x0000039E }, + { 0x0213F0FFEF662124, 0x00004C88, 0xFFFFDBA3, 0x0000071B, 0x000030C4, 0xFFFFEAFD, 0x000004F7, 0x000030C4, 0xFFFFEAFD, 0x000004F7 }, + { 0x0213F0FFEF680904, 0x00002B9A, 0xFFFFEE41, 0x0000047D, 0x00002131, 0xFFFFF344, 0x000003E5, 0x00002131, 0xFFFFF344, 0x000003E5 }, + { 0x0213F0FFEF623984, 0x00003E4B, 0xFFFFE33C, 0x000005FA, 0x00003877, 0xFFFFE437, 0x0000062E, 0x00003877, 0xFFFFE437, 0x0000062E }, + { 0x0213EA94DE322064, 0x00002376, 0xFFFFF444, 0x0000038A, 0x000017ED, 0xFFFFFA4C, 0x000002C1, 0x000017ED, 0xFFFFFA4C, 0x000002C1 }, + { 0x0213F0FFEF661084, 0x00004517, 0xFFFFDDF4, 0x000006F2, 0x000030DC, 0xFFFFE8EF, 0x00000571, 0x000030DC, 0xFFFFE8EF, 0x00000571 }, + { 0x0213F0FFEF681944, 0x0000270C, 0xFFFFF1F3, 0x000003DF, 0x0000207B, 0xFFFFF474, 0x000003AD, 0x0000207B, 0xFFFFF474, 0x000003AD }, + { 0x0213F0FFEF645144, 0x00004086, 0xFFFFDF39, 0x000006E3, 0x00002A24, 0xFFFFEC2B, 0x000004FF, 0x00002A24, 0xFFFFEC2B, 0x000004FF }, + { 0x0213F0FFEF5C3124, 0x00003BDE, 0xFFFFE45E, 0x000005EB, 0x00002CD5, 0xFFFFEC45, 0x000004DD, 0x00002CD5, 0xFFFFEC45, 0x000004DD }, + { 0x0213F0FFEF7230E4, 0x00003803, 0xFFFFE714, 0x00000579, 0x0000288A, 0xFFFFEF21, 0x0000046B, 0x0000288A, 0xFFFFEF21, 0x0000046B }, + { 0x0213F0FFEF601104, 0x00003F50, 0xFFFFE002, 0x000006CD, 0x00001AD4, 0xFFFFF72E, 0x0000031F, 0x00001AD4, 0xFFFFF72E, 0x0000031F }, + { 0x0213F0FFEF6820E4, 0x00002968, 0xFFFFF100, 0x00000402, 0x00001FB5, 0xFFFFF57C, 0x0000037F, 0x00001FB5, 0xFFFFF57C, 0x0000037F }, + { 0x0213F0FFEF662104, 0x00004283, 0xFFFFE2A7, 0x000005F5, 0x00003165, 0xFFFFEB0C, 0x000004EC, 0x00003165, 0xFFFFEB0C, 0x000004EC }, + { 0x0213F0FFEF6431A4, 0x00004253, 0xFFFFDDA8, 0x00000732, 0x00002E5C, 0xFFFFE90A, 0x00000593, 0x00002E5C, 0xFFFFE90A, 0x00000593 }, + { 0x0213F0FFEF5C50A4, 0x00003551, 0xFFFFE756, 0x0000058D, 0x000029A7, 0xFFFFED0C, 0x000004DE, 0x000029A7, 0xFFFFED0C, 0x000004DE }, + { 0x0213F0FFEF6428C4, 0x00003728, 0xFFFFE604, 0x000005C4, 0x00002832, 0xFFFFEE64, 0x00000493, 0x00002832, 0xFFFFEE64, 0x00000493 }, + { 0x0213F0FFEF623964, 0x00004796, 0xFFFFDCC8, 0x00000715, 0x000032AB, 0xFFFFE848, 0x0000057C, 0x000032AB, 0xFFFFE848, 0x0000057C }, + { 0x0213F0FFEF6210C4, 0x000049DF, 0xFFFFDB24, 0x0000075F, 0x00003076, 0xFFFFE967, 0x0000055C, 0x00003076, 0xFFFFE967, 0x0000055C }, + { 0x0213F0FFEF721104, 0x00003F13, 0xFFFFE099, 0x000006A8, 0x00002279, 0xFFFFF226, 0x000003F3, 0x00002279, 0xFFFFF226, 0x000003F3 }, + { 0x0213F0FFEF6430A4, 0x00003E03, 0xFFFFE19F, 0x00000674, 0x00002D66, 0xFFFFEAA7, 0x00000537, 0x00002D66, 0xFFFFEAA7, 0x00000537 }, + { 0x0213F0FFEF5C4104, 0x000037DA, 0xFFFFE63F, 0x000005A7, 0x00002543, 0xFFFFF0A0, 0x00000431, 0x00002543, 0xFFFFF0A0, 0x00000431 }, + { 0x0213F0FFEF624944, 0x00003D82, 0xFFFFE3F5, 0x000005D9, 0x0000332F, 0xFFFFE834, 0x00000577, 0x0000332F, 0xFFFFE834, 0x00000577 }, + { 0x0213EA94DE1228C4, 0x00002915, 0xFFFFF1E0, 0x000003D4, 0x00002065, 0xFFFFF57B, 0x00000378, 0x00002065, 0xFFFFF57B, 0x00000378 }, + { 0x0213F0FFEF5E4904, 0x000036FC, 0xFFFFE72D, 0x00000577, 0x00002811, 0xFFFFEF30, 0x00000464, 0x00002811, 0xFFFFEF30, 0x00000464 }, + { 0x0213F0FFEF623184, 0x00004767, 0xFFFFDD30, 0x000006FD, 0x00003703, 0xFFFFE564, 0x000005F8, 0x00003703, 0xFFFFE564, 0x000005F8 }, + { 0x0213F0FFEF603184, 0x00003094, 0xFFFFEAA9, 0x000004F5, 0x000022E7, 0xFFFFF200, 0x000003FB, 0x000022E7, 0xFFFFF200, 0x000003FB }, + { 0x0213F0FFEF641144, 0x00003EF0, 0xFFFFDF83, 0x000006ED, 0x00002A27, 0xFFFFEB7C, 0x00000537, 0x00002A27, 0xFFFFEB7C, 0x00000537 }, + { 0x0213F0FFEF681124, 0x0000243C, 0xFFFFF358, 0x000003AC, 0x00001DC4, 0xFFFFF5E9, 0x00000372, 0x00001DC4, 0xFFFFF5E9, 0x00000372 }, + { 0x0213F0FFEF722144, 0x0000284B, 0xFFFFF036, 0x0000040F, 0x00001FCD, 0xFFFFF445, 0x00000395, 0x00001FCD, 0xFFFFF445, 0x00000395 }, + { 0x0213F0FFEF6840C4, 0x00002611, 0xFFFFF285, 0x000003C7, 0x00001CFE, 0xFFFFF6A0, 0x00000355, 0x00001CFE, 0xFFFFF6A0, 0x00000355 }, + { 0x0213EA94DE1C39A4, 0x00002292, 0xFFFFF49F, 0x00000393, 0x000017F4, 0xFFFFF9CD, 0x000002F5, 0x000017F4, 0xFFFFF9CD, 0x000002F5 }, + { 0x0213F0FFEF5E38A4, 0x000037F3, 0xFFFFE68D, 0x00000590, 0x00002443, 0xFFFFF1AD, 0x000003FA, 0x00002443, 0xFFFFF1AD, 0x000003FA }, + { 0x0213F0FFEF682144, 0x00002C01, 0xFFFFEF3F, 0x00000444, 0x0000210A, 0xFFFFF475, 0x000003A7, 0x0000210A, 0xFFFFF475, 0x000003A7 }, + { 0x0213EA94DE1210E4, 0x00002C0E, 0xFFFFEF0F, 0x00000446, 0x00001A82, 0xFFFFF8F7, 0x000002DE, 0x00001A82, 0xFFFFF8F7, 0x000002DE }, + { 0x0213F0FFEF5E20C4, 0x00003FA6, 0xFFFFE20A, 0x0000063F, 0x00002E29, 0xFFFFEB21, 0x00000510, 0x00002E29, 0xFFFFEB21, 0x00000510 }, + { 0x0213F0FFEF5C2164, 0x00003BCD, 0xFFFFE31B, 0x0000063C, 0x000019AF, 0xFFFFF83D, 0x000002F8, 0x000019AF, 0xFFFFF83D, 0x000002F8 }, + { 0x0213F0FFEF664164, 0x000044C8, 0xFFFFDF08, 0x000006B0, 0x00002E2E, 0xFFFFEB62, 0x000004FD, 0x00002E2E, 0xFFFFEB62, 0x000004FD }, + { 0x0213F0FFEF5C1884, 0x00003790, 0xFFFFE571, 0x000005E3, 0x00002042, 0xFFFFF35D, 0x000003CF, 0x00002042, 0xFFFFF35D, 0x000003CF }, + { 0x0213F0FFEF6050E4, 0x000038AC, 0xFFFFE46C, 0x00000609, 0x0000215E, 0xFFFFF22D, 0x00000403, 0x0000215E, 0xFFFFF22D, 0x00000403 }, + { 0x0213F0FFEF5E29A4, 0x00003A1E, 0xFFFFE536, 0x000005C9, 0x000024F3, 0xFFFFF11A, 0x0000041B, 0x000024F3, 0xFFFFF11A, 0x0000041B }, + { 0x0213F0FFEF6650E4, 0x0000431A, 0xFFFFDF1B, 0x000006C5, 0x00002F34, 0xFFFFEA02, 0x00000545, 0x00002F34, 0xFFFFEA02, 0x00000545 }, + { 0x0213F0FFEF641904, 0x000042DC, 0xFFFFDE28, 0x0000070C, 0x00003B53, 0xFFFFE0EA, 0x000006E2, 0x00003B53, 0xFFFFE0EA, 0x000006E2 }, + { 0x0213F0FFEF683164, 0x0000264B, 0xFFFFF29A, 0x000003C4, 0x000021D0, 0xFFFFF3CE, 0x000003C4, 0x000021D0, 0xFFFFF3CE, 0x000003C4 }, + { 0x0213F0FFEF5A4064, 0x00004225, 0xFFFFE0E8, 0x00000665, 0x00002B53, 0xFFFFED89, 0x0000049F, 0x00002B53, 0xFFFFED89, 0x0000049F }, + { 0x0213EA94DE204924, 0x00001FCC, 0xFFFFF63F, 0x00000358, 0x000019E8, 0xFFFFF882, 0x0000032A, 0x000019E8, 0xFFFFF882, 0x0000032A }, + { 0x0213F0FFEF6240A4, 0x000045E0, 0xFFFFDDD0, 0x000006ED, 0x00003193, 0xFFFFE8BD, 0x00000572, 0x00003193, 0xFFFFE8BD, 0x00000572 }, + { 0x0213F0FFEF683924, 0x000024FC, 0xFFFFF366, 0x000003A6, 0x00001FE8, 0xFFFFF509, 0x00000394, 0x00001FE8, 0xFFFFF509, 0x00000394 }, + { 0x0213F0FFEF5C4884, 0x0000378F, 0xFFFFE54B, 0x000005F1, 0x00001C9B, 0xFFFFF5C7, 0x00000368, 0x00001C9B, 0xFFFFF5C7, 0x00000368 }, + { 0x0213F0FFEF6418A4, 0x00003CF3, 0xFFFFE15A, 0x00000694, 0x00002CDD, 0xFFFFEA44, 0x00000557, 0x00002CDD, 0xFFFFEA44, 0x00000557 }, + { 0x0213EA94DE200904, 0x000021EC, 0xFFFFF4F4, 0x0000038F, 0x00001511, 0xFFFFFBF5, 0x0000029E, 0x00001511, 0xFFFFFBF5, 0x0000029E }, + { 0x0213F0FFEF6010A4, 0x00003C8A, 0xFFFFE1C1, 0x00000685, 0x000019C7, 0xFFFFF7E2, 0x00000301, 0x000019C7, 0xFFFFF7E2, 0x00000301 }, + { 0x0213F0FFEF5E2064, 0x00003908, 0xFFFFE5C7, 0x000005B3, 0x00002793, 0xFFFFEF46, 0x00000465, 0x00002793, 0xFFFFEF46, 0x00000465 }, + { 0x0213F0FFEF605104, 0x000040A3, 0xFFFFDE61, 0x00000725, 0x00002077, 0xFFFFF2CE, 0x000003E8, 0x00002077, 0xFFFFF2CE, 0x000003E8 }, + { 0x0213F0FFEF664144, 0x00003DCA, 0xFFFFE34D, 0x00000608, 0x00002D66, 0xFFFFEBDF, 0x000004E8, 0x00002D66, 0xFFFFEBDF, 0x000004E8 }, + { 0x0213F0FFEF5E50C4, 0x00003085, 0xFFFFEB70, 0x000004C8, 0x000029B1, 0xFFFFEDD9, 0x000004A5, 0x000029B1, 0xFFFFEDD9, 0x000004A5 }, + { 0x0213EA94DE083884, 0x00004C73, 0xFFFFD676, 0x0000086C, 0x0000280A, 0xFFFFED89, 0x000004C2, 0x0000280A, 0xFFFFED89, 0x000004C2 }, + { 0x0213EA94DE242164, 0x00002CE5, 0xFFFFEE8C, 0x00000466, 0x00001755, 0xFFFFFAC2, 0x000002AC, 0x00001755, 0xFFFFFAC2, 0x000002AC }, + { 0x0213F0FFEF621124, 0x0000489F, 0xFFFFDBF1, 0x0000073E, 0x0000332D, 0xFFFFE786, 0x000005AD, 0x0000332D, 0xFFFFE786, 0x000005AD }, + { 0x0213F0FFEF602864, 0x00003D09, 0xFFFFE193, 0x00000689, 0x00001E82, 0xFFFFF4C0, 0x00000386, 0x00001E82, 0xFFFFF4C0, 0x00000386 }, + { 0x0213F0FFEF644104, 0x00003E4C, 0xFFFFE131, 0x00000689, 0x00002F4E, 0xFFFFE925, 0x0000057B, 0x00002F4E, 0xFFFFE925, 0x0000057B }, + { 0x0213F0FFEF5A4084, 0x00003B31, 0xFFFFE53F, 0x000005B3, 0x0000248A, 0xFFFFF211, 0x000003DF, 0x0000248A, 0xFFFFF211, 0x000003DF }, + { 0x0213F0FFEF644124, 0x000038DD, 0xFFFFE54A, 0x000005C9, 0x00002B6D, 0xFFFFEBDF, 0x00000502, 0x00002B6D, 0xFFFFEBDF, 0x00000502 }, + { 0x0213F0FFEF684064, 0x00002698, 0xFFFFF1A8, 0x000003F2, 0x00002163, 0xFFFFF34B, 0x000003E3, 0x00002163, 0xFFFFF34B, 0x000003E3 }, + { 0x0213EA94DE201064, 0x000023A8, 0xFFFFF4CD, 0x00000386, 0x00001944, 0xFFFFF983, 0x00000300, 0x00001944, 0xFFFFF983, 0x00000300 }, + { 0x0213F0FFEF6418C4, 0x00003EAF, 0xFFFFE0C3, 0x000006A0, 0x000030AB, 0xFFFFE829, 0x000005A6, 0x000030AB, 0xFFFFE829, 0x000005A6 }, + { 0x0213F0FFEF684944, 0x00002E89, 0xFFFFECA6, 0x000004B6, 0x00001FA0, 0xFFFFF4A8, 0x000003A3, 0x00001FA0, 0xFFFFF4A8, 0x000003A3 }, + { 0x0213F0FFEF6828A4, 0x000028A4, 0xFFFFF112, 0x00000402, 0x00001F7C, 0xFFFFF545, 0x0000038A, 0x00001F7C, 0xFFFFF545, 0x0000038A }, + { 0x0213F0FFEF6650A4, 0x00004135, 0xFFFFDFA2, 0x000006C5, 0x0000324C, 0xFFFFE7AA, 0x000005AF, 0x0000324C, 0xFFFFE7AA, 0x000005AF }, + { 0x0213EA94DE2038C4, 0x00002012, 0xFFFFF693, 0x00000352, 0x0000171F, 0xFFFFFABB, 0x000002D9, 0x0000171F, 0xFFFFFABB, 0x000002D9 }, + { 0x0213F0FFEF643084, 0x00003D7C, 0xFFFFE1BC, 0x00000671, 0x00002A45, 0xFFFFEC84, 0x000004EC, 0x00002A45, 0xFFFFEC84, 0x000004EC }, + { 0x0213F0FFEF723064, 0x00004172, 0xFFFFDF58, 0x000006DA, 0x00002504, 0xFFFFF0A6, 0x00000431, 0x00002504, 0xFFFFF0A6, 0x00000431 }, + { 0x0213F0FE99281944, 0x000029C7, 0xFFFFF087, 0x00000414, 0x00001DCB, 0xFFFFF675, 0x0000035F, 0x00001DCB, 0xFFFFF675, 0x0000035F }, + { 0x0213F0FE992A29A4, 0x000027F0, 0xFFFFF05A, 0x00000432, 0x00001707, 0xFFFFFA0E, 0x000002D1, 0x00001707, 0xFFFFFA0E, 0x000002D1 }, + { 0x0213F0FE99222144, 0x00003279, 0xFFFFE9F7, 0x00000511, 0x00001B5E, 0xFFFFF787, 0x00000317, 0x00001B5E, 0xFFFFF787, 0x00000317 }, + { 0x0213F0FE99322184, 0x000030A5, 0xFFFFEABC, 0x000004FF, 0x000019D1, 0xFFFFF83C, 0x00000304, 0x000019D1, 0xFFFFF83C, 0x00000304 }, + { 0x0213F0FE99282844, 0x0000283B, 0xFFFFF122, 0x00000402, 0x000019C2, 0xFFFFF8E9, 0x000002FB, 0x000019C2, 0xFFFFF8E9, 0x000002FB }, + { 0x0213F0FE992C2084, 0x00003376, 0xFFFFE9E1, 0x00000510, 0x000021A7, 0xFFFFF39F, 0x000003BF, 0x000021A7, 0xFFFFF39F, 0x000003BF }, + { 0x0213F0FE993218C4, 0x000031D2, 0xFFFFEA9C, 0x000004FC, 0x00001F66, 0xFFFFF4E4, 0x00000390, 0x00001F66, 0xFFFFF4E4, 0x00000390 }, + { 0x0213F0FE991A3864, 0x00003006, 0xFFFFEB18, 0x000004F2, 0x000019B3, 0xFFFFF84E, 0x00000301, 0x000019B3, 0xFFFFF84E, 0x00000301 }, + { 0x0213F0FE993039A4, 0x0000364F, 0xFFFFE81F, 0x00000556, 0x00002AC9, 0xFFFFED87, 0x000004BD, 0x00002AC9, 0xFFFFED87, 0x000004BD }, + { 0x0213F0FE992E3844, 0x00003043, 0xFFFFEBAE, 0x000004CD, 0x00001B0C, 0xFFFFF7ED, 0x0000030C, 0x00001B0C, 0xFFFFF7ED, 0x0000030C }, + { 0x0213F0FE993048A4, 0x000037CE, 0xFFFFE69E, 0x00000596, 0x0000276B, 0xFFFFEF65, 0x0000046E, 0x0000276B, 0xFFFFEF65, 0x0000046E }, + { 0x0213F0FE992C3104, 0x00003063, 0xFFFFED5E, 0x0000046F, 0x000024AE, 0xFFFFF2C4, 0x000003D8, 0x000024AE, 0xFFFFF2C4, 0x000003D8 }, + { 0x0213F0FE992E08A4, 0x00002F5D, 0xFFFFEBDC, 0x000004D3, 0x00001EDB, 0xFFFFF50F, 0x0000038E, 0x00001EDB, 0xFFFFF50F, 0x0000038E }, + { 0x0213F0FE992E48A4, 0x00003148, 0xFFFFEA9A, 0x000004FB, 0x0000192D, 0xFFFFF8E9, 0x000002DF, 0x0000192D, 0xFFFFF8E9, 0x000002DF }, + { 0x0213F0FE992C2064, 0x00003682, 0xFFFFE7E4, 0x0000055C, 0x0000250E, 0xFFFFF150, 0x0000041A, 0x0000250E, 0xFFFFF150, 0x0000041A }, + { 0x0213F0FE992A2084, 0x0000284E, 0xFFFFF15A, 0x000003F8, 0x00001CE2, 0xFFFFF6F9, 0x0000034F, 0x00001CE2, 0xFFFFF6F9, 0x0000034F }, + { 0x0213F0FE993018A4, 0x00003171, 0xFFFFEAE9, 0x000004ED, 0x00001F40, 0xFFFFF513, 0x00000384, 0x00001F40, 0xFFFFF513, 0x00000384 }, + { 0x0213F0FE99323044, 0x000031BD, 0xFFFFEA64, 0x0000050A, 0x00001EFD, 0xFFFFF4F7, 0x00000390, 0x00001EFD, 0xFFFFF4F7, 0x00000390 }, + { 0x0213F0FE992E50E4, 0x00003050, 0xFFFFEB29, 0x000004EA, 0x000019B3, 0xFFFFF878, 0x000002F9, 0x000019B3, 0xFFFFF878, 0x000002F9 }, + { 0x0213F0FE992C1904, 0x00003400, 0xFFFFE9A0, 0x0000051A, 0x00002460, 0xFFFFF1DA, 0x00000409, 0x00002460, 0xFFFFF1DA, 0x00000409 }, + { 0x0213F0FE992C4884, 0x000034A1, 0xFFFFE86F, 0x00000558, 0x0000255D, 0xFFFFF09E, 0x00000443, 0x0000255D, 0xFFFFF09E, 0x00000443 }, + { 0x0213F0FE992E48E4, 0x00003103, 0xFFFFEAD7, 0x000004F0, 0x00001896, 0xFFFFF95A, 0x000002CC, 0x00001896, 0xFFFFF95A, 0x000002CC }, + { 0x0213F0FE993018E4, 0x00003120, 0xFFFFEB9E, 0x000004CB, 0x000021E8, 0xFFFFF3A2, 0x000003C1, 0x000021E8, 0xFFFFF3A2, 0x000003C1 }, + { 0x0213F0FE991C50E4, 0x00003558, 0xFFFFE812, 0x00000565, 0x0000256E, 0xFFFFF097, 0x00000447, 0x0000256E, 0xFFFFF097, 0x00000447 }, + { 0x0213F0FE991A2844, 0x00002DA8, 0xFFFFECA8, 0x000004B7, 0x0000180B, 0xFFFFF96D, 0x000002D8, 0x0000180B, 0xFFFFF96D, 0x000002D8 }, + { 0x0213F0FE992E3064, 0x00003232, 0xFFFFEA66, 0x000004FF, 0x00001DDE, 0xFFFFF5FE, 0x0000035A, 0x00001DDE, 0xFFFFF5FE, 0x0000035A }, + { 0x0213F0FE993050E4, 0x000034D2, 0xFFFFE89F, 0x00000548, 0x0000246C, 0xFFFFF17F, 0x00000418, 0x0000246C, 0xFFFFF17F, 0x00000418 }, + { 0x0213F0FE99304904, 0x000033EC, 0xFFFFE954, 0x0000052A, 0x00002323, 0xFFFFF279, 0x000003EE, 0x00002323, 0xFFFFF279, 0x000003EE }, + { 0x0213F0FE99303884, 0x000033AA, 0xFFFFE955, 0x0000052D, 0x0000229F, 0xFFFFF2B2, 0x000003E7, 0x0000229F, 0xFFFFF2B2, 0x000003E7 }, + { 0x0213F0FE99324964, 0x00003258, 0xFFFFE9AA, 0x0000052A, 0x00001D5F, 0xFFFFF5D1, 0x0000036B, 0x00001D5F, 0xFFFFF5D1, 0x0000036B }, + { 0x0213F0FE993029A4, 0x0000323A, 0xFFFFEA5F, 0x00000504, 0x00002108, 0xFFFFF3D5, 0x000003BA, 0x00002108, 0xFFFFF3D5, 0x000003BA }, + { 0x0213F0FE992C2184, 0x00003216, 0xFFFFEA6B, 0x000004FF, 0x00001D6E, 0xFFFFF640, 0x00000350, 0x00001D6E, 0xFFFFF640, 0x00000350 }, + { 0x0213F0FE993210E4, 0x000030C5, 0xFFFFEAC4, 0x000004FC, 0x00001924, 0xFFFFF8C2, 0x000002EE, 0x00001924, 0xFFFFF8C2, 0x000002EE }, + { 0x0213F0FE99305104, 0x000032BB, 0xFFFFE9F1, 0x00000515, 0x00002211, 0xFFFFF31B, 0x000003D5, 0x00002211, 0xFFFFF31B, 0x000003D5 }, + { 0x0213F0FE993048C4, 0x0000352C, 0xFFFFE85B, 0x00000553, 0x00002410, 0xFFFFF1B4, 0x0000040F, 0x00002410, 0xFFFFF1B4, 0x0000040F }, + { 0x0213F0FE992238C4, 0x000036A0, 0xFFFFE7E8, 0x0000055D, 0x00002901, 0xFFFFEEB8, 0x00000489, 0x00002901, 0xFFFFEEB8, 0x00000489 }, + { 0x0213F0FE992C3044, 0x00003340, 0xFFFFE9D9, 0x00000516, 0x00002332, 0xFFFFF27A, 0x000003F0, 0x00002332, 0xFFFFF27A, 0x000003F0 }, + { 0x0213F0FE991A38A4, 0x00003564, 0xFFFFE86D, 0x0000054E, 0x00002613, 0xFFFFF07C, 0x00000444, 0x00002613, 0xFFFFF07C, 0x00000444 }, + { 0x0213F0FE99280904, 0x00002AD1, 0xFFFFEF0B, 0x0000045C, 0x00001DEA, 0xFFFFF5C8, 0x00000381, 0x00001DEA, 0xFFFFF5C8, 0x00000381 }, + { 0x0213F0FE992220E4, 0x000035B0, 0xFFFFE846, 0x00000555, 0x000027BE, 0xFFFFEF5D, 0x00000474, 0x000027BE, 0xFFFFEF5D, 0x00000474 }, + { 0x0213F0FE992238A4, 0x000032C4, 0xFFFFEA48, 0x00000502, 0x000022C6, 0xFFFFF2DF, 0x000003DE, 0x000022C6, 0xFFFFF2DF, 0x000003DE }, + { 0x0213F0FE993008C4, 0x00003036, 0xFFFFEB0D, 0x000004F9, 0x00001FE8, 0xFFFFF41A, 0x000003BC, 0x00001FE8, 0xFFFFF41A, 0x000003BC }, + { 0x0213F0FE991A0904, 0x000030F8, 0xFFFFEA13, 0x00000524, 0x00001B6A, 0xFFFFF6C9, 0x0000034A, 0x00001B6A, 0xFFFFF6C9, 0x0000034A }, + { 0x0213F0FE993010A4, 0x00002EE2, 0xFFFFEC0C, 0x000004CB, 0x00001A39, 0xFFFFF814, 0x0000030F, 0x00001A39, 0xFFFFF814, 0x0000030F }, + { 0x0213F0FE991C3184, 0x00003457, 0xFFFFE924, 0x0000052A, 0x00001E9D, 0xFFFFF59C, 0x00000363, 0x00001E9D, 0xFFFFF59C, 0x00000363 }, + { 0x0213F0FE99322844, 0x000030BF, 0xFFFFEB18, 0x000004ED, 0x00001D37, 0xFFFFF636, 0x0000035C, 0x00001D37, 0xFFFFF636, 0x0000035C }, + { 0x0213F0FE992E4084, 0x000031AF, 0xFFFFEA75, 0x000004FE, 0x000019F2, 0xFFFFF87A, 0x000002F0, 0x000019F2, 0xFFFFF87A, 0x000002F0 }, + { 0x0213F0FE99302884, 0x00003642, 0xFFFFE85B, 0x00000547, 0x00002975, 0xFFFFEE98, 0x0000048B, 0x00002975, 0xFFFFEE98, 0x0000048B }, + { 0x0213F0FE992E2884, 0x00002E8B, 0xFFFFED1E, 0x0000048E, 0x000019C1, 0xFFFFF917, 0x000002D6, 0x000019C1, 0xFFFFF917, 0x000002D6 }, + { 0x0213F0FE993241A4, 0x000033D9, 0xFFFFE8E1, 0x00000548, 0x0000224B, 0xFFFFF298, 0x000003F4, 0x0000224B, 0xFFFFF298, 0x000003F4 }, + { 0x0213F0FE992E28C4, 0x000032BC, 0xFFFFEB0F, 0x000004D6, 0x00002488, 0xFFFFF240, 0x000003F2, 0x00002488, 0xFFFFF240, 0x000003F2 }, + { 0x0213F0FE99304944, 0x000035FD, 0xFFFFE838, 0x00000553, 0x00002762, 0xFFFFEFBC, 0x00000460, 0x00002762, 0xFFFFEFBC, 0x00000460 }, + { 0x0213F0FE992818A4, 0x0000268B, 0xFFFFF263, 0x000003D1, 0x00001914, 0xFFFFF977, 0x000002E8, 0x00001914, 0xFFFFF977, 0x000002E8 }, + { 0x0213F0FE992C3184, 0x0000330B, 0xFFFFEA1E, 0x00000505, 0x000020B1, 0xFFFFF44D, 0x0000039E, 0x000020B1, 0xFFFFF44D, 0x0000039E }, + { 0x0213F0FE99222084, 0x0000326E, 0xFFFFEA26, 0x00000508, 0x00001C17, 0xFFFFF722, 0x00000328, 0x00001C17, 0xFFFFF722, 0x00000328 }, + { 0x0213F0FE992A31A4, 0x00002A3F, 0xFFFFEEE8, 0x0000046D, 0x00001B2B, 0xFFFFF737, 0x0000034D, 0x00001B2B, 0xFFFFF737, 0x0000034D }, + { 0x0213F0FE992C4064, 0x00003732, 0xFFFFE765, 0x00000574, 0x00002A6D, 0xFFFFEDA8, 0x000004B7, 0x00002A6D, 0xFFFFEDA8, 0x000004B7 }, + { 0x0213F0FE99300924, 0x000034D3, 0xFFFFE827, 0x00000569, 0x000027AA, 0xFFFFEEE7, 0x00000492, 0x000027AA, 0xFFFFEEE7, 0x00000492 }, + { 0x0213F0FE992E40C4, 0x00003306, 0xFFFFEA39, 0x000004FC, 0x00001DCC, 0xFFFFF655, 0x00000344, 0x00001DCC, 0xFFFFF655, 0x00000344 }, + { 0x0213F0FE99282044, 0x00002A48, 0xFFFFEFCA, 0x00000439, 0x00001DED, 0xFFFFF60D, 0x00000375, 0x00001DED, 0xFFFFF60D, 0x00000375 }, + { 0x0213F0FE993038C4, 0x000033A3, 0xFFFFEA36, 0x000004F9, 0x0000247C, 0xFFFFF21F, 0x000003F4, 0x0000247C, 0xFFFFF21F, 0x000003F4 }, + { 0x0213F0FE992C3164, 0x0000311B, 0xFFFFEB76, 0x000004D1, 0x00001EB1, 0xFFFFF5B6, 0x00000366, 0x00001EB1, 0xFFFFF5B6, 0x00000366 }, + { 0x0213F0FE99324164, 0x00003307, 0xFFFFE97F, 0x0000052A, 0x00001E76, 0xFFFFF54D, 0x0000037C, 0x00001E76, 0xFFFFF54D, 0x0000037C }, + { 0x0213F0FE991C2144, 0x0000344B, 0xFFFFE9C5, 0x00000509, 0x000020D6, 0xFFFFF486, 0x0000038F, 0x000020D6, 0xFFFFF486, 0x0000038F }, + { 0x0213F0FE992C3144, 0x000034B9, 0xFFFFEA0B, 0x000004F7, 0x000027B3, 0xFFFFF057, 0x0000043A, 0x000027B3, 0xFFFFF057, 0x0000043A }, + { 0x0213F0FE99301964, 0x00003360, 0xFFFFE984, 0x00000527, 0x00002238, 0xFFFFF2EE, 0x000003E0, 0x00002238, 0xFFFFF2EE, 0x000003E0 }, + { 0x0213F0FE99302124, 0x0000315C, 0xFFFFEC05, 0x000004B1, 0x000023C8, 0xFFFFF2CC, 0x000003DE, 0x000023C8, 0xFFFFF2CC, 0x000003DE }, + { 0x0213F0FE992C2864, 0x0000389B, 0xFFFFE6D5, 0x00000582, 0x00002C6C, 0xFFFFEC92, 0x000004DE, 0x00002C6C, 0xFFFFEC92, 0x000004DE }, + { 0x0213F0FE992E1124, 0x00003058, 0xFFFFEB30, 0x000004E6, 0x000019B5, 0xFFFFF88B, 0x000002F1, 0x000019B5, 0xFFFFF88B, 0x000002F1 }, + { 0x0213F0FE992E0904, 0x00002F69, 0xFFFFEB4A, 0x000004F1, 0x00001B82, 0xFFFFF6EC, 0x00000341, 0x00001B82, 0xFFFFF6EC, 0x00000341 }, + { 0x0213F0FE991A18E4, 0x000031EB, 0xFFFFEA64, 0x00000508, 0x00002059, 0xFFFFF427, 0x000003B0, 0x00002059, 0xFFFFF427, 0x000003B0 }, + { 0x0213F0FE99224124, 0x000033E2, 0xFFFFE94D, 0x0000052A, 0x000020BF, 0xFFFFF40B, 0x000003AB, 0x000020BF, 0xFFFFF40B, 0x000003AB }, + { 0x0213F0FE99283184, 0x00002AF9, 0xFFFFEFE9, 0x00000427, 0x00001F72, 0xFFFFF57A, 0x00000383, 0x00001F72, 0xFFFFF57A, 0x00000383 }, + { 0x0213F0FE992C2824, 0x00003282, 0xFFFFEA88, 0x000004FA, 0x00002561, 0xFFFFF126, 0x0000042B, 0x00002561, 0xFFFFF126, 0x0000042B }, + { 0x0213F0FE993010E4, 0x0000308A, 0xFFFFEB5D, 0x000004E0, 0x00001E83, 0xFFFFF577, 0x00000378, 0x00001E83, 0xFFFFF577, 0x00000378 }, + { 0x0213F0FE99324884, 0x0000336E, 0xFFFFE8C8, 0x00000553, 0x0000217C, 0xFFFFF2E1, 0x000003EB, 0x0000217C, 0xFFFFF2E1, 0x000003EB }, + { 0x0213F0FE991A2164, 0x000034A9, 0xFFFFE838, 0x00000561, 0x000020CE, 0xFFFFF38A, 0x000003C7, 0x000020CE, 0xFFFFF38A, 0x000003C7 }, + { 0x0213F0FE99222184, 0x00003152, 0xFFFFE9EB, 0x00000522, 0x00001755, 0xFFFFF9A9, 0x000002C6, 0x00001755, 0xFFFFF9A9, 0x000002C6 }, + { 0x0213F0FE99281884, 0x0000286E, 0xFFFFF136, 0x000003FD, 0x00001BAB, 0xFFFFF7C3, 0x0000032C, 0x00001BAB, 0xFFFFF7C3, 0x0000032C }, + { 0x0213F0FE99300944, 0x0000316B, 0xFFFFEA02, 0x00000528, 0x00002247, 0xFFFFF24E, 0x00000408, 0x00002247, 0xFFFFF24E, 0x00000408 }, + { 0x0213F0FE992C08E4, 0x000034CF, 0xFFFFE83D, 0x00000562, 0x00002458, 0xFFFFF130, 0x00000430, 0x00002458, 0xFFFFF130, 0x00000430 }, + { 0x0213F0FE992C2984, 0x00003352, 0xFFFFE9D1, 0x00000515, 0x0000212A, 0xFFFFF3DC, 0x000003B4, 0x0000212A, 0xFFFFF3DC, 0x000003B4 }, + { 0x0213F0FE992840A4, 0x00002946, 0xFFFFF09B, 0x00000415, 0x00001DC9, 0xFFFFF650, 0x00000366, 0x00001DC9, 0xFFFFF650, 0x00000366 }, + { 0x0213F0FE99301124, 0x00003080, 0xFFFFEB47, 0x000004E1, 0x00001BD5, 0xFFFFF73B, 0x00000329, 0x00001BD5, 0xFFFFF73B, 0x00000329 }, + { 0x0213F0FE991A1884, 0x00002FBD, 0xFFFFEB7B, 0x000004DD, 0x000017FC, 0xFFFFF99E, 0x000002C7, 0x000017FC, 0xFFFFF99E, 0x000002C7 }, + { 0x0213F0FE99281124, 0x00002A28, 0xFFFFF032, 0x0000041F, 0x00001B19, 0xFFFFF83A, 0x00000312, 0x00001B19, 0xFFFFF83A, 0x00000312 }, + { 0x0213F0FE992240C4, 0x00003420, 0xFFFFE936, 0x00000530, 0x000023C2, 0xFFFFF203, 0x00000406, 0x000023C2, 0xFFFFF203, 0x00000406 }, + { 0x0213F0FE99301144, 0x00002F7C, 0xFFFFEBBA, 0x000004D1, 0x0000185D, 0xFFFFF975, 0x000002CA, 0x0000185D, 0xFFFFF975, 0x000002CA }, + { 0x0213F0FE992E2044, 0x00002C51, 0xFFFFEE3B, 0x0000046F, 0x000019AA, 0xFFFFF8DD, 0x000002ED, 0x000019AA, 0xFFFFF8DD, 0x000002ED }, + { 0x0213F0FE991A4144, 0x000033D6, 0xFFFFE8F2, 0x0000053D, 0x00001D73, 0xFFFFF5FB, 0x0000035B, 0x00001D73, 0xFFFFF5FB, 0x0000035B }, + { 0x0213F0FE99323084, 0x000031D9, 0xFFFFEAF7, 0x000004E4, 0x00001EBD, 0xFFFFF5A6, 0x00000368, 0x00001EBD, 0xFFFFF5A6, 0x00000368 }, + { 0x0213F0FE991A20A4, 0x00003386, 0xFFFFE9CE, 0x00000515, 0x00002422, 0xFFFFF1F3, 0x00000405, 0x00002422, 0xFFFFF1F3, 0x00000405 }, + { 0x0213F0FE992C50E4, 0x000032FB, 0xFFFFE9BC, 0x00000520, 0x00002301, 0xFFFFF267, 0x000003F7, 0x00002301, 0xFFFFF267, 0x000003F7 }, + { 0x0213F0FE99322924, 0x000032C2, 0xFFFFEAC0, 0x000004EA, 0x0000250F, 0xFFFFF1A2, 0x00000413, 0x0000250F, 0xFFFFF1A2, 0x00000413 }, + { 0x0213F0FE991C2944, 0x00003722, 0xFFFFE8A6, 0x00000527, 0x000026E4, 0xFFFFF0F5, 0x0000041C, 0x000026E4, 0xFFFFF0F5, 0x0000041C }, + { 0x0213F0FE992C48C4, 0x000035A4, 0xFFFFE822, 0x00000558, 0x000022F2, 0xFFFFF288, 0x000003E8, 0x000022F2, 0xFFFFF288, 0x000003E8 }, + { 0x0213F0FE99280924, 0x00002CD1, 0xFFFFEDC6, 0x0000048C, 0x00001EAF, 0xFFFFF53D, 0x00000396, 0x00001EAF, 0xFFFFF53D, 0x00000396 }, + { 0x0213F0FE99301164, 0x00003156, 0xFFFFEA60, 0x0000050B, 0x00001BBC, 0xFFFFF704, 0x00000335, 0x00001BBC, 0xFFFFF704, 0x00000335 }, + { 0x0213F0FE992C5104, 0x000034A1, 0xFFFFE8C0, 0x00000544, 0x00002528, 0xFFFFF105, 0x0000042C, 0x00002528, 0xFFFFF105, 0x0000042C }, + { 0x0213F0FE99323064, 0x000032CE, 0xFFFFE9D3, 0x00000520, 0x000021FF, 0xFFFFF2FD, 0x000003E4, 0x000021FF, 0xFFFFF2FD, 0x000003E4 }, + { 0x0213F0FE991A50A4, 0x000034A0, 0xFFFFE823, 0x0000056D, 0x0000256F, 0xFFFFF047, 0x0000045A, 0x0000256F, 0xFFFFF047, 0x0000045A }, + { 0x0213F0FE99303944, 0x00003109, 0xFFFFEBD6, 0x000004BF, 0x000022D4, 0xFFFFF32D, 0x000003D0, 0x000022D4, 0xFFFFF32D, 0x000003D0 }, + { 0x0213F0FE992C1164, 0x000030B7, 0xFFFFEAF0, 0x000004F3, 0x00001AEC, 0xFFFFF7A9, 0x0000031B, 0x00001AEC, 0xFFFFF7A9, 0x0000031B }, + { 0x0213F0FE992C39A4, 0x00003078, 0xFFFFEBA4, 0x000004CF, 0x00001E7A, 0xFFFFF5AF, 0x0000036B, 0x00001E7A, 0xFFFFF5AF, 0x0000036B }, + { 0x0213F0FE99304124, 0x00003442, 0xFFFFE998, 0x00000518, 0x000025EA, 0xFFFFF0F3, 0x0000042B, 0x000025EA, 0xFFFFF0F3, 0x0000042B }, + { 0x0213F0FE993021A4, 0x000031CB, 0xFFFFEA80, 0x00000501, 0x000020A3, 0xFFFFF403, 0x000003B2, 0x000020A3, 0xFFFFF403, 0x000003B2 }, + { 0x0213F0FE992A2984, 0x00002947, 0xFFFFF018, 0x00000433, 0x00001BA5, 0xFFFFF75C, 0x00000340, 0x00001BA5, 0xFFFFF75C, 0x00000340 }, + { 0x0213F0FE992C3984, 0x000033F9, 0xFFFFE99D, 0x00000518, 0x00002231, 0xFFFFF358, 0x000003C5, 0x00002231, 0xFFFFF358, 0x000003C5 }, + { 0x0213F0FE99321124, 0x00003131, 0xFFFFEA45, 0x00000513, 0x00001973, 0xFFFFF85E, 0x00000301, 0x00001973, 0xFFFFF85E, 0x00000301 }, + { 0x0213F0FE991C29A4, 0x00003571, 0xFFFFE8AC, 0x00000539, 0x00002049, 0xFFFFF49C, 0x0000038D, 0x00002049, 0xFFFFF49C, 0x0000038D }, + { 0x0213F0FE992E3864, 0x0000309E, 0xFFFFEB1D, 0x000004E8, 0x000019ED, 0xFFFFF86E, 0x000002F8, 0x000019ED, 0xFFFFF86E, 0x000002F8 }, + { 0x0213F0FE99302984, 0x00003091, 0xFFFFEB9B, 0x000004CC, 0x00001D2C, 0xFFFFF6A2, 0x0000033D, 0x00001D2C, 0xFFFFF6A2, 0x0000033D }, + { 0x0213F0FE993008E4, 0x00003069, 0xFFFFEAFD, 0x000004F8, 0x00001E82, 0xFFFFF51C, 0x0000038D, 0x00001E82, 0xFFFFF51C, 0x0000038D }, + { 0x0213F0FE992210A4, 0x00003459, 0xFFFFE7F2, 0x00000572, 0x00001DA7, 0xFFFFF552, 0x0000037F, 0x00001DA7, 0xFFFFF552, 0x0000037F }, + { 0x0213F0FE99321104, 0x0000304B, 0xFFFFEAFB, 0x000004F4, 0x0000191E, 0xFFFFF8BD, 0x000002EE, 0x0000191E, 0xFFFFF8BD, 0x000002EE }, + { 0x0213F0FE993020C4, 0x0000346E, 0xFFFFEA07, 0x000004FD, 0x00002767, 0xFFFFF058, 0x00000440, 0x00002767, 0xFFFFF058, 0x00000440 }, + { 0x0213F0FE992E3084, 0x000030B5, 0xFFFFEBC1, 0x000004C1, 0x00001B3C, 0xFFFFF818, 0x000002FD, 0x00001B3C, 0xFFFFF818, 0x000002FD }, + { 0x0213F0FE99300904, 0x0000321F, 0xFFFFE9EA, 0x00000524, 0x00002380, 0xFFFFF1C2, 0x0000041A, 0x00002380, 0xFFFFF1C2, 0x0000041A }, + { 0x0213F0FE992E3044, 0x000030DF, 0xFFFFEB37, 0x000004E2, 0x00001E3C, 0xFFFFF5BB, 0x00000369, 0x00001E3C, 0xFFFFF5BB, 0x00000369 }, + { 0x0213F0FE992848A4, 0x000027E0, 0xFFFFF0E2, 0x00000416, 0x00001A6A, 0xFFFFF820, 0x00000321, 0x00001A6A, 0xFFFFF820, 0x00000321 }, + { 0x0213F0FE991A1084, 0x00002FA1, 0xFFFFEB63, 0x000004E7, 0x0000196B, 0xFFFFF880, 0x000002FB, 0x0000196B, 0xFFFFF880, 0x000002FB }, + { 0x0213F0FE991C1084, 0x0000310C, 0xFFFFEAAF, 0x000004FC, 0x000019EF, 0xFFFFF850, 0x000002FD, 0x000019EF, 0xFFFFF850, 0x000002FD }, + { 0x0213F0FE99323904, 0x0000334A, 0xFFFFEA07, 0x0000050B, 0x00002380, 0xFFFFF26F, 0x000003F0, 0x00002380, 0xFFFFF26F, 0x000003F0 }, + { 0x0213F0FE99302944, 0x00002FF9, 0xFFFFECDC, 0x00000492, 0x00002297, 0xFFFFF394, 0x000003BF, 0x00002297, 0xFFFFF394, 0x000003BF }, + { 0x0213F0FE992C2164, 0x0000354B, 0xFFFFE894, 0x00000546, 0x000024C4, 0xFFFFF16C, 0x0000041B, 0x000024C4, 0xFFFFF16C, 0x0000041B }, + { 0x0213F0FE99220924, 0x00003245, 0xFFFFE92F, 0x00000544, 0x00001829, 0xFFFFF8F1, 0x000002EA, 0x00001829, 0xFFFFF8F1, 0x000002EA }, + { 0x0213F0FE992E4884, 0x0000302F, 0xFFFFEB51, 0x000004E3, 0x0000199F, 0xFFFFF894, 0x000002F4, 0x0000199F, 0xFFFFF894, 0x000002F4 }, + { 0x0213F0FE992E18C4, 0x00002F54, 0xFFFFEC86, 0x000004A6, 0x00001A6F, 0xFFFFF891, 0x000002EC, 0x00001A6F, 0xFFFFF891, 0x000002EC }, + { 0x0213F0FE99284164, 0x00002908, 0xFFFFF0D8, 0x0000040A, 0x00001C9B, 0xFFFFF729, 0x00000342, 0x00001C9B, 0xFFFFF729, 0x00000342 }, + { 0x0213F0FE99302964, 0x000031D9, 0xFFFFEB40, 0x000004D7, 0x000023F5, 0xFFFFF259, 0x000003F4, 0x000023F5, 0xFFFFF259, 0x000003F4 }, + { 0x0213F0FE993048E4, 0x000034C8, 0xFFFFE8C6, 0x0000053F, 0x00002313, 0xFFFFF280, 0x000003EC, 0x00002313, 0xFFFFF280, 0x000003EC }, + { 0x0213F0FE993050C4, 0x000037D1, 0xFFFFE6A1, 0x0000059C, 0x00002C6A, 0xFFFFEBFF, 0x00000504, 0x00002C6A, 0xFFFFEBFF, 0x00000504 }, + { 0x0213F0FE99321964, 0x000030E9, 0xFFFFEA6B, 0x0000050F, 0x00001A2D, 0xFFFFF7DF, 0x00000316, 0x00001A2D, 0xFFFFF7DF, 0x00000316 }, + { 0x0213F0FE99302084, 0x0000323D, 0xFFFFEA95, 0x000004F4, 0x00001ED2, 0xFFFFF584, 0x0000036C, 0x00001ED2, 0xFFFFF584, 0x0000036C }, + { 0x0213F0FE992C3024, 0x000033D6, 0xFFFFE9DB, 0x00000510, 0x000027A7, 0xFFFFEFC7, 0x0000045E, 0x000027A7, 0xFFFFEFC7, 0x0000045E }, + { 0x0213F0FE991C3164, 0x00003444, 0xFFFFE98A, 0x00000517, 0x000020FD, 0xFFFFF43F, 0x0000039D, 0x000020FD, 0xFFFFF43F, 0x0000039D }, + { 0x0213F0FE992808E4, 0x00002987, 0xFFFFEFA1, 0x0000044B, 0x00001B06, 0xFFFFF788, 0x0000033C, 0x00001B06, 0xFFFFF788, 0x0000033C }, + { 0x0213F0FE992C28E4, 0x0000311D, 0xFFFFED20, 0x00000474, 0x000025DA, 0xFFFFF223, 0x000003F0, 0x000025DA, 0xFFFFF223, 0x000003F0 }, + { 0x0213F0FE992C1124, 0x000032A2, 0xFFFFEA0A, 0x0000050D, 0x00001D48, 0xFFFFF659, 0x0000034A, 0x00001D48, 0xFFFFF659, 0x0000034A }, + { 0x0213F0FE992208E4, 0x00003110, 0xFFFFE9EA, 0x00000529, 0x00001786, 0xFFFFF958, 0x000002DB, 0x00001786, 0xFFFFF958, 0x000002DB }, + { 0x0213F0FE992821A4, 0x000027F2, 0xFFFFF174, 0x000003F7, 0x00001C7A, 0xFFFFF72A, 0x00000348, 0x00001C7A, 0xFFFFF72A, 0x00000348 }, + { 0x0213F0FE991C10E4, 0x000031DB, 0xFFFFEA7D, 0x000004FB, 0x000019C4, 0xFFFFF8B1, 0x000002E6, 0x000019C4, 0xFFFFF8B1, 0x000002E6 }, + { 0x0213F0FE992C1104, 0x00003158, 0xFFFFEAAC, 0x000004FA, 0x00001BC1, 0xFFFFF737, 0x0000032B, 0x00001BC1, 0xFFFFF737, 0x0000032B }, + { 0x0213F0FE993010C4, 0x00002F36, 0xFFFFEBF9, 0x000004CA, 0x00001A2A, 0xFFFFF83F, 0x00000303, 0x00001A2A, 0xFFFFF83F, 0x00000303 }, + { 0x0213F0FE993238A4, 0x000032B4, 0xFFFFEA72, 0x000004FA, 0x000021FF, 0xFFFFF378, 0x000003C5, 0x000021FF, 0xFFFFF378, 0x000003C5 }, + { 0x0213F0FE99303164, 0x00003262, 0xFFFFEAFA, 0x000004DF, 0x00002441, 0xFFFFF237, 0x000003F6, 0x00002441, 0xFFFFF237, 0x000003F6 }, + { 0x0213F0FE99303924, 0x0000336A, 0xFFFFEAFB, 0x000004D1, 0x00002746, 0xFFFFF0B8, 0x0000042B, 0x00002746, 0xFFFFF0B8, 0x0000042B }, + { 0x0213F0FE991A4084, 0x000032E5, 0xFFFFE923, 0x00000541, 0x00001DF0, 0xFFFFF552, 0x00000380, 0x00001DF0, 0xFFFFF552, 0x00000380 }, + { 0x0213F0FE99304064, 0x000035D1, 0xFFFFE80B, 0x0000055F, 0x00002780, 0xFFFFEF74, 0x0000046F, 0x00002780, 0xFFFFEF74, 0x0000046F }, + { 0x0213F0FE993028A4, 0x000033EC, 0xFFFFEA48, 0x000004F4, 0x0000269F, 0xFFFFF0D8, 0x0000042A, 0x0000269F, 0xFFFFF0D8, 0x0000042A }, + { 0x0213F0FE99323884, 0x000030C4, 0xFFFFEB39, 0x000004E2, 0x00001B44, 0xFFFFF7AA, 0x00000318, 0x00001B44, 0xFFFFF7AA, 0x00000318 }, + { 0x0213F0FE99281144, 0x00002926, 0xFFFFF0AF, 0x0000040E, 0x0000194E, 0xFFFFF959, 0x000002E2, 0x0000194E, 0xFFFFF959, 0x000002E2 }, + { 0x0213F0FE992C10C4, 0x00003141, 0xFFFFEAAF, 0x000004F6, 0x00001864, 0xFFFFF97C, 0x000002C6, 0x00001864, 0xFFFFF97C, 0x000002C6 }, + { 0x0213F0FE99301064, 0x000030B2, 0xFFFFEB7C, 0x000004DB, 0x000022CE, 0xFFFFF2B5, 0x000003F0, 0x000022CE, 0xFFFFF2B5, 0x000003F0 }, + { 0x0213F0FE99301944, 0x0000318C, 0xFFFFEAC7, 0x000004F6, 0x00002113, 0xFFFFF3CA, 0x000003BD, 0x00002113, 0xFFFFF3CA, 0x000003BD }, + { 0x0213F0FE992E1104, 0x00002FD2, 0xFFFFEB8F, 0x000004D9, 0x00001996, 0xFFFFF89F, 0x000002F1, 0x00001996, 0xFFFFF89F, 0x000002F1 }, + { 0x0213F0FE991A28A4, 0x0000310D, 0xFFFFEB25, 0x000004E7, 0x00001F67, 0xFFFFF4EF, 0x0000038E, 0x00001F67, 0xFFFFF4EF, 0x0000038E }, + { 0x0213F0FE992A4964, 0x00002BBC, 0xFFFFEE68, 0x00000477, 0x00002050, 0xFFFFF41D, 0x000003C8, 0x00002050, 0xFFFFF41D, 0x000003C8 }, + { 0x0213F0FE99302104, 0x00003096, 0xFFFFECED, 0x00000486, 0x000024C9, 0xFFFFF278, 0x000003E7, 0x000024C9, 0xFFFFF278, 0x000003E7 }, + { 0x0213F0FE992C10A4, 0x00003401, 0xFFFFE8F1, 0x0000053C, 0x00001E75, 0xFFFFF55C, 0x00000376, 0x00001E75, 0xFFFFF55C, 0x00000376 }, + { 0x0213F0FE99302844, 0x0000319E, 0xFFFFEAB1, 0x000004F8, 0x00001EA3, 0xFFFFF567, 0x00000378, 0x00001EA3, 0xFFFFF567, 0x00000378 }, + { 0x0213F0FE99322964, 0x000030FD, 0xFFFFEB4C, 0x000004DB, 0x00001CA6, 0xFFFFF6E8, 0x00000335, 0x00001CA6, 0xFFFFF6E8, 0x00000335 }, + { 0x0213F0FE992E40A4, 0x000030D6, 0xFFFFEB1A, 0x000004E4, 0x00001A0D, 0xFFFFF87D, 0x000002EF, 0x00001A0D, 0xFFFFF87D, 0x000002EF }, + { 0x0213F0FE992C2124, 0x0000324B, 0xFFFFEB17, 0x000004D9, 0x00002225, 0xFFFFF3A8, 0x000003BA, 0x00002225, 0xFFFFF3A8, 0x000003BA }, + { 0x0213F0FE99284084, 0x00002A00, 0xFFFFF02E, 0x00000424, 0x00001E21, 0xFFFFF61D, 0x0000036C, 0x00001E21, 0xFFFFF61D, 0x0000036C }, + { 0x0213F0FE992A48A4, 0x000029CF, 0xFFFFEF53, 0x00000457, 0x00001B11, 0xFFFFF772, 0x0000033D, 0x00001B11, 0xFFFFF772, 0x0000033D }, + { 0x0213F0FE991A30A4, 0x000032A1, 0xFFFFEA63, 0x000004FB, 0x00001F83, 0xFFFFF516, 0x0000037E, 0x00001F83, 0xFFFFF516, 0x0000037E }, + { 0x0213F0FE992E20C4, 0x0000305C, 0xFFFFEC14, 0x000004B5, 0x00001D0B, 0xFFFFF6ED, 0x00000332, 0x00001D0B, 0xFFFFF6ED, 0x00000332 }, + { 0x0213F0FE992C1064, 0x00003467, 0xFFFFE8D5, 0x00000543, 0x0000243F, 0xFFFFF190, 0x00000418, 0x0000243F, 0xFFFFF190, 0x00000418 }, + { 0x0213F0FE992A2064, 0x00002796, 0xFFFFF133, 0x00000409, 0x00001903, 0xFFFFF91C, 0x000002FC, 0x00001903, 0xFFFFF91C, 0x000002FC }, + { 0x0213F0FE99302164, 0x000031F6, 0xFFFFEAB7, 0x000004F5, 0x000022B9, 0xFFFFF2D0, 0x000003E6, 0x000022B9, 0xFFFFF2D0, 0x000003E6 }, + { 0x0213F0FE992E5104, 0x00003196, 0xFFFFEA76, 0x00000503, 0x00001CC5, 0xFFFFF67D, 0x0000034A, 0x00001CC5, 0xFFFFF67D, 0x0000034A }, + { 0x0213F0FE99321144, 0x00002F9E, 0xFFFFEAD9, 0x00000505, 0x000017C1, 0xFFFFF93D, 0x000002DF, 0x000017C1, 0xFFFFF93D, 0x000002DF }, + { 0x0213F0FE992E2124, 0x00002FBC, 0xFFFFEC75, 0x000004A8, 0x00001D6D, 0xFFFFF6AC, 0x0000033D, 0x00001D6D, 0xFFFFF6AC, 0x0000033D }, + { 0x0213F0FE992C38A4, 0x00003541, 0xFFFFE921, 0x00000524, 0x00002662, 0xFFFFF0CB, 0x0000042B, 0x00002662, 0xFFFFF0CB, 0x0000042B }, + { 0x0213F0FE992A21A4, 0x00002953, 0xFFFFEF76, 0x00000459, 0x00001C05, 0xFFFFF6A0, 0x00000368, 0x00001C05, 0xFFFFF6A0, 0x00000368 }, + { 0x0213F0FE992C4924, 0x000034BC, 0xFFFFE8DD, 0x00000536, 0x0000210E, 0xFFFFF3F4, 0x000003A8, 0x0000210E, 0xFFFFF3F4, 0x000003A8 }, + { 0x0213F0FE992C29A4, 0x000034BE, 0xFFFFE916, 0x0000052F, 0x000024A1, 0xFFFFF1A6, 0x00000410, 0x000024A1, 0xFFFFF1A6, 0x00000410 }, + { 0x0213F0FE99304964, 0x000037B5, 0xFFFFE7A9, 0x0000055B, 0x000028A1, 0xFFFFEF51, 0x00000467, 0x000028A1, 0xFFFFEF51, 0x00000467 }, + { 0x0213F0FE99301104, 0x00002FC5, 0xFFFFEBBE, 0x000004D1, 0x00001BA5, 0xFFFFF757, 0x00000328, 0x00001BA5, 0xFFFFF757, 0x00000328 }, + { 0x0213F0FE993040A4, 0x000033CB, 0xFFFFE944, 0x0000052B, 0x00001FBE, 0xFFFFF4B1, 0x0000038C, 0x00001FBE, 0xFFFFF4B1, 0x0000038C }, + { 0x0213F0FE99301844, 0x000030AE, 0xFFFFEBA0, 0x000004D3, 0x00002268, 0xFFFFF316, 0x000003DD, 0x00002268, 0xFFFFF316, 0x000003DD }, + { 0x0213F0FE992C20A4, 0x00002F90, 0xFFFFEC5A, 0x000004B0, 0x00001C3A, 0xFFFFF752, 0x00000323, 0x00001C3A, 0xFFFFF752, 0x00000323 }, + { 0x0213F0FE992E38E4, 0x00003113, 0xFFFFEB91, 0x000004C8, 0x00001E3C, 0xFFFFF623, 0x0000034E, 0x00001E3C, 0xFFFFF623, 0x0000034E }, + { 0x0213F0FE99323984, 0x0000330B, 0xFFFFE94B, 0x00000539, 0x000020E7, 0xFFFFF37E, 0x000003CD, 0x000020E7, 0xFFFFF37E, 0x000003CD }, + { 0x0213F0FE992E2864, 0x000031D1, 0xFFFFEACB, 0x000004ED, 0x00001E82, 0xFFFFF5B2, 0x00000365, 0x00001E82, 0xFFFFF5B2, 0x00000365 }, + { 0x0213F0FE992A3984, 0x00002CD5, 0xFFFFEDC1, 0x0000048D, 0x000020F8, 0xFFFFF3C1, 0x000003D1, 0x000020F8, 0xFFFFF3C1, 0x000003D1 }, + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; int pp_override_get_default_fuse_value(uint64_t key, @@ -1244,20 +1244,9 @@ int pp_override_get_default_fuse_value(uint64_t key, { const struct phm_fuses_default *list = vega10_fuses_default; uint32_t i; - uint64_t temp_serial_numer; - uint32_t bit; - const char *temp; - for (i = 0; list[i].key != NULL; i++) { - temp = list[i].key; - temp_serial_numer = 0; - do { - bit = *temp=='1'? 1 : 0; - temp_serial_numer = (temp_serial_numer <<1 ) | bit; - temp++; - } while (*temp); - - if (key == temp_serial_numer) { + for (i = 0; list[i].key != 0; i++) { + if (key == list[i].key) { result->key = list[i].key; result->VFT2_m1 = list[i].VFT2_m1; result->VFT2_m2 = list[i].VFT2_m2; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h index 22e2dd0b49b4..c6ba0d64cfb7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_overdriver.h @@ -28,7 +28,7 @@ #include struct phm_fuses_default { - const char *key; + uint64_t key; uint32_t VFT2_m1; uint32_t VFT2_m2; uint32_t VFT2_b; -- cgit v1.2.3 From 45b19706a45f201ecbfc2d6fdc5ae4ec9d7ea2b9 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 28 Sep 2017 11:35:52 +0100 Subject: drm/amd/powerplay: fix spelling mistake: "dividable" -> "divisible" Trivial fix to spelling mistakes in pr_err error message and ASSERT messages. Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c index 8fb0aa027b54..0017b9e62404 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c @@ -2331,7 +2331,7 @@ static int ci_load_smc_ucode(struct pp_hwmgr *hwmgr) PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); if (0 != byte_count) { - pr_err("SMC size must be dividable by 4\n"); + pr_err("SMC size must be divisible by 4\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c index 78aa1122eacc..a778e174ba01 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c @@ -108,7 +108,7 @@ static int iceland_upload_smc_firmware_data(struct pp_hwmgr *hwmgr, PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); - PP_ASSERT_WITH_CODE((0 == byte_count), "SMC size must be dividable by 4.", return -EINVAL); + PP_ASSERT_WITH_CODE((0 == byte_count), "SMC size must be divisible by 4.", return -EINVAL); return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c index 2ae05bbdb974..c997117f2461 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c @@ -513,7 +513,7 @@ static int smu7_upload_smc_firmware_data(struct pp_hwmgr *hwmgr, uint32_t length PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 0); - PP_ASSERT_WITH_CODE((0 == byte_count), "SMC size must be dividable by 4.", return -EINVAL); + PP_ASSERT_WITH_CODE((0 == byte_count), "SMC size must be divisible by 4.", return -EINVAL); return 0; } -- cgit v1.2.3 From 1bab0fc01b84c1aa8a65a1f1de885e1faab48264 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 20 Sep 2017 11:38:19 -0400 Subject: drm/amd/chash: Fix typo Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/lib/chash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/lib/chash.c b/drivers/gpu/drm/amd/lib/chash.c index e07e6f3030d6..b8e45f356a1c 100644 --- a/drivers/gpu/drm/amd/lib/chash.c +++ b/drivers/gpu/drm/amd/lib/chash.c @@ -223,8 +223,8 @@ static int chash_table_check(struct __chash_table *table) static void chash_iter_relocate(struct chash_iter dst, struct chash_iter src) { BUG_ON(src.table == dst.table && src.slot == dst.slot); - BUG_ON(src.table->key_size != src.table->key_size); - BUG_ON(src.table->value_size != src.table->value_size); + BUG_ON(src.table->key_size != dst.table->key_size); + BUG_ON(src.table->value_size != dst.table->value_size); if (dst.table->key_size == 4) dst.table->keys32[dst.slot] = src.table->keys32[src.slot]; -- cgit v1.2.3 From c98171ccf6580407d07a3b5dc8188ce9e1f4f7ca Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Thu, 21 Sep 2017 16:26:41 -0400 Subject: drm/amdgpu: Handle GPUVM fault storms When many wavefronts cause VM faults at the same time, it can overwhelm the interrupt handler and cause IH ring overflows before the driver can notify or kill the faulting application. As a workaround I'm introducing limited per-VM fault credit. After that number of VM faults have occurred, further VM faults are filtered out at the prescreen stage of processing. This depends on the PASID in the interrupt packet, so it currently only works for KFD contexts. Signed-off-by: Felix Kuehling Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 7 ++++++- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 19 +++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 19 +++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 19 +++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 19 +++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 11 +++++++---- 7 files changed, 112 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 8fcc743dfa86..c91d5c7a273d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2682,6 +2682,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, } INIT_KFIFO(vm->faults); + vm->fault_credit = 16; return 0; @@ -2775,6 +2776,36 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) amdgpu_vm_free_reserved_vmid(adev, vm, i); } +/** + * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID + * + * @adev: amdgpu_device pointer + * @pasid: PASID do identify the VM + * + * This function is expected to be called in interrupt context. Returns + * true if there was fault credit, false otherwise + */ +bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, + unsigned int pasid) +{ + struct amdgpu_vm *vm; + + spin_lock(&adev->vm_manager.pasid_lock); + vm = idr_find(&adev->vm_manager.pasid_idr, pasid); + spin_unlock(&adev->vm_manager.pasid_lock); + if (!vm) + /* VM not found, can't track fault credit */ + return true; + + /* No lock needed. only accessed by IRQ handler */ + if (!vm->fault_credit) + /* Too many faults in this VM */ + return false; + + vm->fault_credit--; + return true; +} + /** * amdgpu_vm_manager_init - init the VM manager * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 447ed6e7e586..66efbc2e43af 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -165,8 +165,11 @@ struct amdgpu_vm { /* Flag to indicate ATS support from PTE for GFX9 */ bool pte_support_ats; - /* Up to 128 pending page faults */ + /* Up to 128 pending retry page faults */ DECLARE_KFIFO(faults, u64, 128); + + /* Limit non-retry fault storms */ + unsigned int fault_credit; }; struct amdgpu_vm_id { @@ -244,6 +247,8 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev); int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int vm_context, unsigned int pasid); void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); +bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, + unsigned int pasid); void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, struct list_head *validated, struct amdgpu_bo_list_entry *entry); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index 07d3d895da10..a870b354e3f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -237,8 +237,23 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) */ static bool cik_ih_prescreen_iv(struct amdgpu_device *adev) { - /* Process all interrupts */ - return true; + u32 ring_index = adev->irq.ih.rptr >> 2; + u16 pasid; + + switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { + case 146: + case 147: + pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; + if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) + return true; + break; + default: + /* Not a VM fault */ + return true; + } + + adev->irq.ih.rptr += 16; + return false; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c index b6cdf4afaf46..fa61d649bb44 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c @@ -216,8 +216,23 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev) */ static bool cz_ih_prescreen_iv(struct amdgpu_device *adev) { - /* Process all interrupts */ - return true; + u32 ring_index = adev->irq.ih.rptr >> 2; + u16 pasid; + + switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { + case 146: + case 147: + pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; + if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) + return true; + break; + default: + /* Not a VM fault */ + return true; + } + + adev->irq.ih.rptr += 16; + return false; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c index 65ed6d3a8f05..bd592cb39f37 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c @@ -216,8 +216,23 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev) */ static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev) { - /* Process all interrupts */ - return true; + u32 ring_index = adev->irq.ih.rptr >> 2; + u16 pasid; + + switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { + case 146: + case 147: + pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; + if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) + return true; + break; + default: + /* Not a VM fault */ + return true; + } + + adev->irq.ih.rptr += 16; + return false; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index 5ed00692618e..aa4e320e31f8 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -227,8 +227,23 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev) */ static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev) { - /* Process all interrupts */ - return true; + u32 ring_index = adev->irq.ih.rptr >> 2; + u16 pasid; + + switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { + case 146: + case 147: + pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; + if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) + return true; + break; + default: + /* Not a VM fault */ + return true; + } + + adev->irq.ih.rptr += 16; + return false; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index a3b30d84dbb3..697325737ba8 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -260,15 +260,18 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev) return true; } - /* Not a retry fault */ - if (!(dw5 & 0x80)) - return true; - pasid = dw3 & 0xffff; /* No PASID, can't identify faulting process */ if (!pasid) return true; + /* Not a retry fault, check fault credit */ + if (!(dw5 & 0x80)) { + if (!amdgpu_vm_pasid_fault_credit(adev, pasid)) + goto ignore_iv; + return true; + } + addr = ((u64)(dw5 & 0xf) << 44) | ((u64)dw4 << 12); key = AMDGPU_VM_FAULT(pasid, addr); r = amdgpu_ih_add_fault(adev, key); -- cgit v1.2.3 From d2f52ac800fec229f2931603e8b7fb9c5ade7aa7 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 22 Sep 2017 17:47:27 +0800 Subject: drm/amdgpu: move common pm sysfs code to amdgpu_device.c Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 7 +------ drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 1 - drivers/gpu/drm/amd/amdgpu/kv_dpm.c | 7 ------- drivers/gpu/drm/amd/amdgpu/si_dpm.c | 6 ------ 6 files changed, 13 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index fc0c1cde69ae..284d5c82d926 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -56,6 +56,7 @@ #include "amdgpu_vf_error.h" #include "amdgpu_amdkfd.h" +#include "amdgpu_pm.h" MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); @@ -2216,6 +2217,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, amdgpu_fbdev_init(adev); + r = amdgpu_pm_sysfs_init(adev); + if (r) + DRM_ERROR("registering pm debugfs failed (%d).\n", r); + r = amdgpu_gem_debugfs_init(adev); if (r) DRM_ERROR("registering gem debugfs failed (%d).\n", r); @@ -2312,6 +2317,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) iounmap(adev->rmmio); adev->rmmio = NULL; amdgpu_doorbell_fini(adev); + amdgpu_pm_sysfs_fini(adev); amdgpu_debugfs_regs_cleanup(adev); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index f6ce52956e6d..274886cedb66 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1317,6 +1317,9 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) if (adev->pm.sysfs_initialized) return 0; + if (adev->pm.dpm_enabled == 0) + return 0; + if (adev->powerplay.pp_funcs->get_temperature == NULL) return 0; @@ -1417,6 +1420,9 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) { + if (adev->pm.dpm_enabled == 0) + return; + if (adev->pm.int_hwmon_dev) hwmon_device_unregister(adev->pm.int_hwmon_dev); device_remove_file(adev->dev, &dev_attr_power_dpm_state); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 2d2f0960b025..1ad632388c95 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -137,10 +137,8 @@ static int amdgpu_pp_late_init(void *handle) ret = adev->powerplay.ip_funcs->late_init( adev->powerplay.pp_handle); - if (adev->pp_enabled && adev->pm.dpm_enabled) { - amdgpu_pm_sysfs_init(adev); + if (adev->pp_enabled && adev->pm.dpm_enabled) amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_COMPLETE_INIT, NULL, NULL); - } return ret; } @@ -199,9 +197,6 @@ static int amdgpu_pp_hw_fini(void *handle) int ret = 0; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->pp_enabled && adev->pm.dpm_enabled) - amdgpu_pm_sysfs_fini(adev); - if (adev->powerplay.ip_funcs->hw_fini) ret = adev->powerplay.ip_funcs->hw_fini( adev->powerplay.pp_handle); diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 68ce1bdaf2fc..68b505c768ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -6365,7 +6365,6 @@ static int ci_dpm_sw_fini(void *handle) flush_work(&adev->pm.dpm.thermal.work); mutex_lock(&adev->pm.mutex); - amdgpu_pm_sysfs_fini(adev); ci_dpm_fini(adev); mutex_unlock(&adev->pm.mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index b57399a462c2..f33d1ffdb20b 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -2969,16 +2969,10 @@ static int kv_dpm_late_init(void *handle) { /* powerdown unused blocks for now */ struct amdgpu_device *adev = (struct amdgpu_device *)handle; - int ret; if (!amdgpu_dpm) return 0; - /* init the sysfs and debugfs files late */ - ret = amdgpu_pm_sysfs_init(adev); - if (ret) - return ret; - kv_dpm_powergate_acp(adev, true); kv_dpm_powergate_samu(adev, true); @@ -3040,7 +3034,6 @@ static int kv_dpm_sw_fini(void *handle) flush_work(&adev->pm.dpm.thermal.work); mutex_lock(&adev->pm.mutex); - amdgpu_pm_sysfs_fini(adev); kv_dpm_fini(adev); mutex_unlock(&adev->pm.mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 9b8db6046271..51fd0c9a20a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -7604,11 +7604,6 @@ static int si_dpm_late_init(void *handle) if (!amdgpu_dpm) return 0; - /* init the sysfs and debugfs files late */ - ret = amdgpu_pm_sysfs_init(adev); - if (ret) - return ret; - ret = si_set_temperature_range(adev); if (ret) return ret; @@ -7764,7 +7759,6 @@ static int si_dpm_sw_fini(void *handle) flush_work(&adev->pm.dpm.thermal.work); mutex_lock(&adev->pm.mutex); - amdgpu_pm_sysfs_fini(adev); si_dpm_fini(adev); mutex_unlock(&adev->pm.mutex); -- cgit v1.2.3 From 46967c221fa9d06f4ddf168fbcf16fd9216dd574 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 22 Sep 2017 18:03:59 +0800 Subject: drm/amdgpu: move amdgpu_ucode_init_bo to amdgpu_device.c Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 5 ----- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 9 --------- 3 files changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 284d5c82d926..1949d8aedf49 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1604,6 +1604,7 @@ static int amdgpu_init(struct amdgpu_device *adev) return r; } adev->ip_blocks[i].status.sw = true; + /* need to do gmc hw init early so we can allocate gpu mem */ if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { r = amdgpu_vram_scratch_init(adev); @@ -1634,6 +1635,11 @@ static int amdgpu_init(struct amdgpu_device *adev) } } + mutex_lock(&adev->firmware.mutex); + if (amdgpu_ucode_init_bo(adev)) + adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT; + mutex_unlock(&adev->firmware.mutex); + for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.sw) continue; @@ -1769,6 +1775,8 @@ static int amdgpu_fini(struct amdgpu_device *adev) adev->ip_blocks[i].status.hw = false; } + if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) + amdgpu_ucode_fini_bo(adev); for (i = adev->num_ip_blocks - 1; i >= 0; i--) { if (!adev->ip_blocks[i].status.sw) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 1ad632388c95..c05e5a86e7cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -174,8 +174,6 @@ static int amdgpu_pp_hw_init(void *handle) int ret = 0; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->pp_enabled && adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) - amdgpu_ucode_init_bo(adev); if (adev->powerplay.ip_funcs->hw_init) ret = adev->powerplay.ip_funcs->hw_init( @@ -201,9 +199,6 @@ static int amdgpu_pp_hw_fini(void *handle) ret = adev->powerplay.ip_funcs->hw_fini( adev->powerplay.pp_handle); - if (adev->pp_enabled && adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) - amdgpu_ucode_fini_bo(adev); - return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 447d446b5015..f1035a689d35 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -411,13 +411,6 @@ static int psp_hw_init(void *handle) return 0; mutex_lock(&adev->firmware.mutex); - /* - * This sequence is just used on hw_init only once, no need on - * resume. - */ - ret = amdgpu_ucode_init_bo(adev); - if (ret) - goto failed; ret = psp_load_fw(adev); if (ret) { @@ -442,8 +435,6 @@ static int psp_hw_fini(void *handle) if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) return 0; - amdgpu_ucode_fini_bo(adev); - psp_ring_destroy(psp, PSP_RING_TYPE__KM); amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); -- cgit v1.2.3 From d04f257635a2f4fd74fcd7543a9337daeb40dea1 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 25 Sep 2017 17:34:00 +0800 Subject: drm/amd/powerplay: fix memory leak in powerplay cgs device not free. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 9 ++++++--- drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index c05e5a86e7cc..2ed81cdb8320 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -45,7 +45,7 @@ static int amdgpu_create_pp_handle(struct amdgpu_device *adev) pp_init.chip_id = adev->asic_type; pp_init.pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false; pp_init.feature_mask = amdgpu_pp_feature_mask; - pp_init.device = amdgpu_cgs_create_device(adev); + pp_init.device = amd_pp->cgs_device; ret = amd_powerplay_create(&pp_init, &(amd_pp->pp_handle)); if (ret) return -EINVAL; @@ -74,6 +74,7 @@ static int amdgpu_pp_early_init(void *handle) case CHIP_VEGA10: case CHIP_RAVEN: adev->pp_enabled = true; + amd_pp->cgs_device = amdgpu_cgs_create_device(adev); if (amdgpu_create_pp_handle(adev)) return -EINVAL; amd_pp->ip_funcs = &pp_ip_funcs; @@ -97,7 +98,7 @@ static int amdgpu_pp_early_init(void *handle) amd_pp->ip_funcs = &ci_dpm_ip_funcs; amd_pp->pp_funcs = &ci_dpm_funcs; } else { - adev->pp_enabled = true; + amd_pp->cgs_device = amdgpu_cgs_create_device(adev); if (amdgpu_create_pp_handle(adev)) return -EINVAL; amd_pp->ip_funcs = &pp_ip_funcs; @@ -211,8 +212,10 @@ static void amdgpu_pp_late_fini(void *handle) adev->powerplay.pp_handle); - if (adev->pp_enabled) + if (adev->pp_enabled) { amd_powerplay_destroy(adev->powerplay.pp_handle); + amdgpu_cgs_destroy_device(adev->powerplay.cgs_device); + } } static int amdgpu_pp_suspend(void *handle) diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 435da2647727..437d78558a0b 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -268,6 +268,7 @@ struct pp_display_clock_request { state << PP_STATE_SHIFT) struct amd_powerplay { + struct cgs_device *cgs_device; void *pp_handle; const struct amd_ip_funcs *ip_funcs; const struct amd_pm_funcs *pp_funcs; -- cgit v1.2.3 From 790d84fdc9826500c88abfca0f3f86e96153bd4e Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 25 Sep 2017 17:50:13 +0800 Subject: drm/amdgpu: delete dead code about fw load check Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 60 ++++++++-------------------------- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 20 +++--------- drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 21 +++--------- 3 files changed, 23 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index dfc10b1baea0..e04de7a81592 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -4132,18 +4132,12 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev) gfx_v8_0_rlc_reset(adev); gfx_v8_0_init_pg(adev); - if (!adev->pp_enabled) { - if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { - /* legacy rlc firmware loading */ - r = gfx_v8_0_rlc_load_microcode(adev); - if (r) - return r; - } else { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_RLC_G); - if (r) - return -EINVAL; - } + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { + /* legacy rlc firmware loading */ + r = gfx_v8_0_rlc_load_microcode(adev); + if (r) + return r; } gfx_v8_0_rlc_start(adev); @@ -4959,43 +4953,15 @@ static int gfx_v8_0_cp_resume(struct amdgpu_device *adev) if (!(adev->flags & AMD_IS_APU)) gfx_v8_0_enable_gui_idle_interrupt(adev, false); - if (!adev->pp_enabled) { - if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { /* legacy firmware loading */ - r = gfx_v8_0_cp_gfx_load_microcode(adev); - if (r) - return r; + r = gfx_v8_0_cp_gfx_load_microcode(adev); + if (r) + return r; - r = gfx_v8_0_cp_compute_load_microcode(adev); - if (r) - return r; - } else { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_CE); - if (r) - return -EINVAL; - - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_PFP); - if (r) - return -EINVAL; - - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_ME); - if (r) - return -EINVAL; - - if (adev->asic_type == CHIP_TOPAZ) { - r = gfx_v8_0_cp_compute_load_microcode(adev); - if (r) - return r; - } else { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_MEC1); - if (r) - return -EINVAL; - } - } + r = gfx_v8_0_cp_compute_load_microcode(adev); + if (r) + return r; } r = gfx_v8_0_cp_gfx_resume(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index acdee3a4602c..67f375bfe452 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -561,21 +561,11 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) { int r; - if (!adev->pp_enabled) { - if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { - r = sdma_v2_4_load_microcode(adev); - if (r) - return r; - } else { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_SDMA0); - if (r) - return -EINVAL; - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_SDMA1); - if (r) - return -EINVAL; - } + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { + r = sdma_v2_4_load_microcode(adev); + if (r) + return r; } /* halt the engine before programing */ diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 72f31cc7df00..6d06f8eb659f 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -819,23 +819,12 @@ static int sdma_v3_0_load_microcode(struct amdgpu_device *adev) */ static int sdma_v3_0_start(struct amdgpu_device *adev) { - int r, i; + int r; - if (!adev->pp_enabled) { - if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { - r = sdma_v3_0_load_microcode(adev); - if (r) - return r; - } else { - for (i = 0; i < adev->sdma.num_instances; i++) { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - (i == 0) ? - AMDGPU_UCODE_ID_SDMA0 : - AMDGPU_UCODE_ID_SDMA1); - if (r) - return -EINVAL; - } - } + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { + r = sdma_v3_0_load_microcode(adev); + if (r) + return r; } /* disable sdma engine before programing it */ -- cgit v1.2.3 From 6d07fe7bcae57ee73d87766b6cd1e026d3fee85d Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 25 Sep 2017 18:51:50 +0800 Subject: drm/amdgpu: delete pp_enable in adev amdgpu not care powerplay or dpm is enabled. just check ip functions and pp functions Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 77 ++++++++++++--------------- drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 7 +-- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 18 ++++++- 4 files changed, 53 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 005b9823e468..0725ab940f49 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1525,7 +1525,6 @@ struct amdgpu_device { /* powerplay */ struct amd_powerplay powerplay; - bool pp_enabled; bool pp_force_state_enabled; /* dpm */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 274886cedb66..a59e04f3eeba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -64,10 +64,6 @@ static const struct cg_flag_name clocks[] = { void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev) { - if (adev->pp_enabled) - /* TODO */ - return; - if (adev->pm.dpm_enabled) { mutex_lock(&adev->pm.mutex); if (power_supply_is_system_supplied() > 0) @@ -118,7 +114,7 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev, goto fail; } - if (adev->pp_enabled) { + if (adev->powerplay.pp_funcs->dispatch_tasks) { amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_ENABLE_USER_STATE, &state, NULL); } else { mutex_lock(&adev->pm.mutex); @@ -303,7 +299,8 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, if (strlen(buf) == 1) adev->pp_force_state_enabled = false; - else if (adev->pp_enabled) { + else if (adev->powerplay.pp_funcs->dispatch_tasks && + adev->powerplay.pp_funcs->get_pp_num_states) { struct pp_states_info data; ret = kstrtoul(buf, 0, &idx); @@ -531,7 +528,7 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, if (adev->powerplay.pp_funcs->set_sclk_od) amdgpu_dpm_set_sclk_od(adev, (uint32_t)value); - if (adev->pp_enabled) { + if (adev->powerplay.pp_funcs->dispatch_tasks) { amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL, NULL); } else { adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; @@ -575,7 +572,7 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, if (adev->powerplay.pp_funcs->set_mclk_od) amdgpu_dpm_set_mclk_od(adev, (uint32_t)value); - if (adev->pp_enabled) { + if (adev->powerplay.pp_funcs->dispatch_tasks) { amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL, NULL); } else { adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; @@ -959,9 +956,6 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) return 0; - if (adev->pp_enabled) - return effective_mode; - /* Skip fan attributes if fan is not present */ if (adev->pm.no_fan && (attr == &sensor_dev_attr_pwm1.dev_attr.attr || @@ -1344,27 +1338,26 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) return ret; } - if (adev->pp_enabled) { - ret = device_create_file(adev->dev, &dev_attr_pp_num_states); - if (ret) { - DRM_ERROR("failed to create device file pp_num_states\n"); - return ret; - } - ret = device_create_file(adev->dev, &dev_attr_pp_cur_state); - if (ret) { - DRM_ERROR("failed to create device file pp_cur_state\n"); - return ret; - } - ret = device_create_file(adev->dev, &dev_attr_pp_force_state); - if (ret) { - DRM_ERROR("failed to create device file pp_force_state\n"); - return ret; - } - ret = device_create_file(adev->dev, &dev_attr_pp_table); - if (ret) { - DRM_ERROR("failed to create device file pp_table\n"); - return ret; - } + + ret = device_create_file(adev->dev, &dev_attr_pp_num_states); + if (ret) { + DRM_ERROR("failed to create device file pp_num_states\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_cur_state); + if (ret) { + DRM_ERROR("failed to create device file pp_cur_state\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_force_state); + if (ret) { + DRM_ERROR("failed to create device file pp_force_state\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_table); + if (ret) { + DRM_ERROR("failed to create device file pp_table\n"); + return ret; } ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); @@ -1427,12 +1420,12 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) hwmon_device_unregister(adev->pm.int_hwmon_dev); device_remove_file(adev->dev, &dev_attr_power_dpm_state); device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level); - if (adev->pp_enabled) { - device_remove_file(adev->dev, &dev_attr_pp_num_states); - device_remove_file(adev->dev, &dev_attr_pp_cur_state); - device_remove_file(adev->dev, &dev_attr_pp_force_state); - device_remove_file(adev->dev, &dev_attr_pp_table); - } + + device_remove_file(adev->dev, &dev_attr_pp_num_states); + device_remove_file(adev->dev, &dev_attr_pp_cur_state); + device_remove_file(adev->dev, &dev_attr_pp_force_state); + device_remove_file(adev->dev, &dev_attr_pp_table); + device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); @@ -1463,7 +1456,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) amdgpu_fence_wait_empty(ring); } - if (adev->pp_enabled) { + if (adev->powerplay.pp_funcs->dispatch_tasks) { amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL, NULL); } else { mutex_lock(&adev->pm.mutex); @@ -1598,15 +1591,15 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data) if ((adev->flags & AMD_IS_PX) && (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) { seq_printf(m, "PX asic powered off\n"); - } else if (adev->pp_enabled) { - return amdgpu_debugfs_pm_info_pp(m, adev); - } else { + } else if (adev->powerplay.pp_funcs->debugfs_print_current_performance_level) { mutex_lock(&adev->pm.mutex); if (adev->powerplay.pp_funcs->debugfs_print_current_performance_level) adev->powerplay.pp_funcs->debugfs_print_current_performance_level(adev, m); else seq_printf(m, "Debugfs support not implemented for this asic\n"); mutex_unlock(&adev->pm.mutex); + } else { + return amdgpu_debugfs_pm_info_pp(m, adev); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 2ed81cdb8320..eb886654ce44 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -59,7 +59,6 @@ static int amdgpu_pp_early_init(void *handle) int ret = 0; amd_pp = &(adev->powerplay); - adev->pp_enabled = false; amd_pp->pp_handle = (void *)adev; switch (adev->asic_type) { @@ -73,7 +72,6 @@ static int amdgpu_pp_early_init(void *handle) case CHIP_STONEY: case CHIP_VEGA10: case CHIP_RAVEN: - adev->pp_enabled = true; amd_pp->cgs_device = amdgpu_cgs_create_device(adev); if (amdgpu_create_pp_handle(adev)) return -EINVAL; @@ -138,9 +136,6 @@ static int amdgpu_pp_late_init(void *handle) ret = adev->powerplay.ip_funcs->late_init( adev->powerplay.pp_handle); - if (adev->pp_enabled && adev->pm.dpm_enabled) - amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_COMPLETE_INIT, NULL, NULL); - return ret; } @@ -212,7 +207,7 @@ static void amdgpu_pp_late_fini(void *handle) adev->powerplay.pp_handle); - if (adev->pp_enabled) { + if (adev->powerplay.cgs_device) { amd_powerplay_destroy(adev->powerplay.pp_handle); amdgpu_cgs_destroy_device(adev->powerplay.cgs_device); } diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 9f3f3b8cf64f..5c7415e8fd0e 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -30,6 +30,9 @@ #include "pp_instance.h" #include "power_state.h" +static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, + void *input, void *output); + static inline int pp_check(struct pp_instance *handle) { if (handle == NULL || handle->pp_valid != PP_VALID) @@ -146,6 +149,19 @@ static int pp_hw_fini(void *handle) return 0; } +static int pp_late_init(void *handle) +{ + struct pp_instance *pp_handle = (struct pp_instance *)handle; + int ret = 0; + + ret = pp_check(pp_handle); + if (ret == 0) + pp_dpm_dispatch_tasks(pp_handle, + AMD_PP_TASK_COMPLETE_INIT, NULL, NULL); + + return 0; +} + static bool pp_is_idle(void *handle) { return false; @@ -254,7 +270,7 @@ static int pp_resume(void *handle) const struct amd_ip_funcs pp_ip_funcs = { .name = "powerplay", .early_init = pp_early_init, - .late_init = NULL, + .late_init = pp_late_init, .sw_init = pp_sw_init, .sw_fini = pp_sw_fini, .hw_init = pp_hw_init, -- cgit v1.2.3 From ba89a3ec61bde7d37225edf01f9e3c0c81de7f0f Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 25 Sep 2017 20:45:52 +0800 Subject: drm/amdgpu: add cgs interface to register pp handle Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/amd/include/cgs_common.h | 8 ++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 383204e911a4..a7afe553e0a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -42,6 +42,28 @@ struct amdgpu_cgs_device { struct amdgpu_device *adev = \ ((struct amdgpu_cgs_device *)cgs_device)->adev +static void *amdgpu_cgs_register_pp_handle(struct cgs_device *cgs_device, + int (*call_back_func)(struct amd_pp_init *, void **)) +{ + CGS_FUNC_ADEV; + struct amd_pp_init pp_init; + struct amd_powerplay *amd_pp; + + if (call_back_func == NULL) + return NULL; + + amd_pp = &(adev->powerplay); + pp_init.chip_family = adev->family; + pp_init.chip_id = adev->asic_type; + pp_init.pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false; + pp_init.feature_mask = amdgpu_pp_feature_mask; + pp_init.device = cgs_device; + if (call_back_func(&pp_init, &(amd_pp->pp_handle))) + return NULL; + + return adev->powerplay.pp_handle; +} + static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, enum cgs_gpu_mem_type type, uint64_t size, uint64_t align, @@ -1179,6 +1201,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled, .enter_safe_mode = amdgpu_cgs_enter_safe_mode, .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx, + .register_pp_handle = amdgpu_cgs_register_pp_handle, }; static const struct cgs_os_ops amdgpu_cgs_os_ops = { diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h index 030b14649c4e..675988d56392 100644 --- a/drivers/gpu/drm/amd/include/cgs_common.h +++ b/drivers/gpu/drm/amd/include/cgs_common.h @@ -423,6 +423,10 @@ typedef int (*cgs_enter_safe_mode)(struct cgs_device *cgs_device, bool en); typedef void (*cgs_lock_grbm_idx)(struct cgs_device *cgs_device, bool lock); +struct amd_pp_init; +typedef void* (*cgs_register_pp_handle)(struct cgs_device *cgs_device, + int (*call_back_func)(struct amd_pp_init *, void **)); + struct cgs_ops { /* memory management calls (similar to KFD interface) */ cgs_alloc_gpu_mem_t alloc_gpu_mem; @@ -459,6 +463,7 @@ struct cgs_ops { cgs_is_virtualization_enabled_t is_virtualization_enabled; cgs_enter_safe_mode enter_safe_mode; cgs_lock_grbm_idx lock_grbm_idx; + cgs_register_pp_handle register_pp_handle; }; struct cgs_os_ops; /* To be define in OS-specific CGS header */ @@ -537,4 +542,7 @@ struct cgs_device #define cgs_lock_grbm_idx(cgs_device, lock) \ CGS_CALL(lock_grbm_idx, cgs_device, lock) +#define cgs_register_pp_handle(cgs_device, call_back_func) \ + CGS_CALL(register_pp_handle, cgs_device, call_back_func) + #endif /* _CGS_COMMON_H */ -- cgit v1.2.3 From 139a285f8124577ed816f63d9e950b01dfaa5401 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 25 Sep 2017 20:46:37 +0800 Subject: drm/amdgpu: create powerplay by cgs interface Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 30 +------- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 84 +++++++++++++---------- drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 5 -- 3 files changed, 51 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index eb886654ce44..1649b1e3f23d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -34,24 +34,6 @@ #include "cik_dpm.h" #include "vi_dpm.h" -static int amdgpu_create_pp_handle(struct amdgpu_device *adev) -{ - struct amd_pp_init pp_init; - struct amd_powerplay *amd_pp; - int ret; - - amd_pp = &(adev->powerplay); - pp_init.chip_family = adev->family; - pp_init.chip_id = adev->asic_type; - pp_init.pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false; - pp_init.feature_mask = amdgpu_pp_feature_mask; - pp_init.device = amd_pp->cgs_device; - ret = amd_powerplay_create(&pp_init, &(amd_pp->pp_handle)); - if (ret) - return -EINVAL; - return 0; -} - static int amdgpu_pp_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -73,8 +55,6 @@ static int amdgpu_pp_early_init(void *handle) case CHIP_VEGA10: case CHIP_RAVEN: amd_pp->cgs_device = amdgpu_cgs_create_device(adev); - if (amdgpu_create_pp_handle(adev)) - return -EINVAL; amd_pp->ip_funcs = &pp_ip_funcs; amd_pp->pp_funcs = &pp_dpm_funcs; break; @@ -97,8 +77,6 @@ static int amdgpu_pp_early_init(void *handle) amd_pp->pp_funcs = &ci_dpm_funcs; } else { amd_pp->cgs_device = amdgpu_cgs_create_device(adev); - if (amdgpu_create_pp_handle(adev)) - return -EINVAL; amd_pp->ip_funcs = &pp_ip_funcs; amd_pp->pp_funcs = &pp_dpm_funcs; } @@ -117,7 +95,8 @@ static int amdgpu_pp_early_init(void *handle) if (adev->powerplay.ip_funcs->early_init) ret = adev->powerplay.ip_funcs->early_init( - adev->powerplay.pp_handle); + amd_pp->cgs_device ? amd_pp->cgs_device : + amd_pp->pp_handle); if (ret == PP_DPM_DISABLED) { adev->pm.dpm_enabled = false; @@ -206,11 +185,8 @@ static void amdgpu_pp_late_fini(void *handle) adev->powerplay.ip_funcs->late_fini( adev->powerplay.pp_handle); - - if (adev->powerplay.cgs_device) { - amd_powerplay_destroy(adev->powerplay.pp_handle); + if (adev->powerplay.cgs_device) amdgpu_cgs_destroy_device(adev->powerplay.cgs_device); - } } static int amdgpu_pp_suspend(void *handle) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 5c7415e8fd0e..488347a11f01 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -50,10 +50,50 @@ static inline int pp_check(struct pp_instance *handle) return 0; } +static int amd_powerplay_create(struct amd_pp_init *pp_init, + void **handle) +{ + struct pp_instance *instance; + + if (pp_init == NULL || handle == NULL) + return -EINVAL; + + instance = kzalloc(sizeof(struct pp_instance), GFP_KERNEL); + if (instance == NULL) + return -ENOMEM; + + instance->pp_valid = PP_VALID; + instance->chip_family = pp_init->chip_family; + instance->chip_id = pp_init->chip_id; + instance->pm_en = pp_init->pm_en; + instance->feature_mask = pp_init->feature_mask; + instance->device = pp_init->device; + mutex_init(&instance->pp_lock); + *handle = instance; + return 0; +} + +static int amd_powerplay_destroy(void *handle) +{ + struct pp_instance *instance = (struct pp_instance *)handle; + + kfree(instance->hwmgr); + instance->hwmgr = NULL; + + kfree(instance); + instance = NULL; + return 0; +} + static int pp_early_init(void *handle) { int ret; - struct pp_instance *pp_handle = (struct pp_instance *)handle; + struct pp_instance *pp_handle = NULL; + + pp_handle = cgs_register_pp_handle(handle, amd_powerplay_create); + + if (!pp_handle) + return -EINVAL; ret = hwmgr_early_init(pp_handle); if (ret) @@ -162,6 +202,12 @@ static int pp_late_init(void *handle) return 0; } +static void pp_late_fini(void *handle) +{ + amd_powerplay_destroy(handle); +} + + static bool pp_is_idle(void *handle) { return false; @@ -275,6 +321,7 @@ const struct amd_ip_funcs pp_ip_funcs = { .sw_fini = pp_sw_fini, .hw_init = pp_hw_init, .hw_fini = pp_hw_fini, + .late_fini = pp_late_fini, .suspend = pp_suspend, .resume = pp_resume, .is_idle = pp_is_idle, @@ -1138,41 +1185,6 @@ const struct amd_pm_funcs pp_dpm_funcs = { .switch_power_profile = pp_dpm_switch_power_profile, }; -int amd_powerplay_create(struct amd_pp_init *pp_init, - void **handle) -{ - struct pp_instance *instance; - - if (pp_init == NULL || handle == NULL) - return -EINVAL; - - instance = kzalloc(sizeof(struct pp_instance), GFP_KERNEL); - if (instance == NULL) - return -ENOMEM; - - instance->pp_valid = PP_VALID; - instance->chip_family = pp_init->chip_family; - instance->chip_id = pp_init->chip_id; - instance->pm_en = pp_init->pm_en; - instance->feature_mask = pp_init->feature_mask; - instance->device = pp_init->device; - mutex_init(&instance->pp_lock); - *handle = instance; - return 0; -} - -int amd_powerplay_destroy(void *handle) -{ - struct pp_instance *instance = (struct pp_instance *)handle; - - kfree(instance->hwmgr); - instance->hwmgr = NULL; - - kfree(instance); - instance = NULL; - return 0; -} - int amd_powerplay_reset(void *handle) { struct pp_instance *instance = (struct pp_instance *)handle; diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 437d78558a0b..916b6c420ea4 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -274,11 +274,6 @@ struct amd_powerplay { const struct amd_pm_funcs *pp_funcs; }; -int amd_powerplay_create(struct amd_pp_init *pp_init, - void **handle); - -int amd_powerplay_destroy(void *handle); - int amd_powerplay_reset(void *handle); int amd_powerplay_display_configuration_change(void *handle, -- cgit v1.2.3 From ce440e3a0caa7580f74aa27e573e1a9777d91522 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 25 Sep 2017 21:18:19 +0800 Subject: drm/amd/powerplay: change dmesg log level in powerplay Use pr_debug to prevent spamming unimportant dmesg. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 73bb99d62a44..189f3b54a385 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -704,7 +704,7 @@ static int cz_update_sclk_limit(struct pp_hwmgr *hwmgr) clock = hwmgr->display_config.min_core_set_clock; if (clock == 0) - pr_info("min_core_set_clock not set\n"); + pr_debug("min_core_set_clock not set\n"); if (cz_hwmgr->sclk_dpm.hard_min_clk != clock) { cz_hwmgr->sclk_dpm.hard_min_clk = clock; -- cgit v1.2.3 From c4f1b9fcfa1137440b4147e9f9e1dd6fec850887 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 22 Sep 2017 14:33:24 +0800 Subject: drm/amdgpu: add comments in struct amd_pm_funcs define Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/amd_shared.h | 51 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 20457bb5a906..5be1fb977810 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -262,38 +262,44 @@ enum amd_pp_task; struct pp_states_info; struct amd_pm_funcs { - int (*get_temperature)(void *handle); +/* export for dpm on ci and si */ int (*pre_set_power_state)(void *handle); int (*set_power_state)(void *handle); void (*post_set_power_state)(void *handle); void (*display_configuration_changed)(void *handle); - u32 (*get_sclk)(void *handle, bool low); - u32 (*get_mclk)(void *handle, bool low); void (*print_power_state)(void *handle, void *ps); - void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m); - int (*force_performance_level)(void *handle, enum amd_dpm_forced_level level); bool (*vblank_too_short)(void *handle); - void (*powergate_uvd)(void *handle, bool gate); - void (*powergate_vce)(void *handle, bool gate); void (*enable_bapm)(void *handle, bool enable); + int (*check_state_equal)(void *handle, + void *cps, + void *rps, + bool *equal); +/* export for sysfs */ + int (*get_temperature)(void *handle); void (*set_fan_control_mode)(void *handle, u32 mode); u32 (*get_fan_control_mode)(void *handle); int (*set_fan_speed_percent)(void *handle, u32 speed); int (*get_fan_speed_percent)(void *handle, u32 *speed); int (*force_clock_level)(void *handle, enum pp_clock_type type, uint32_t mask); int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); + int (*force_performance_level)(void *handle, enum amd_dpm_forced_level level); + int (*get_sclk_od)(void *handle); int (*set_sclk_od)(void *handle, uint32_t value); int (*get_mclk_od)(void *handle); int (*set_mclk_od)(void *handle, uint32_t value); - int (*check_state_equal)(void *handle, - void *cps, - void *rps, - bool *equal); - int (*read_sensor)(void *handle, int idx, void *value, - int *size); - struct amd_vce_state* (*get_vce_clock_state)(void *handle, u32 idx); + int (*read_sensor)(void *handle, int idx, void *value, int *size); + + enum amd_dpm_forced_level (*get_performance_level)(void *handle); + enum amd_pm_state_type (*get_current_power_state)(void *handle); + + int (*get_fan_speed_rpm)(void *handle, uint32_t *rpm); + int (*get_pp_num_states)(void *handle, struct pp_states_info *data); + int (*get_pp_table)(void *handle, char **table); + int (*set_pp_table)(void *handle, const char *buf, size_t size); + void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m); + int (*reset_power_profile_state)(void *handle, struct amd_pp_profile *request); int (*get_power_profile_state)(void *handle, @@ -302,16 +308,17 @@ struct amd_pm_funcs { struct amd_pp_profile *request); int (*switch_power_profile)(void *handle, enum amd_pp_profile_type type); - int (*load_firmware)(void *handle); - int (*wait_for_fw_loading_complete)(void *handle); - enum amd_dpm_forced_level (*get_performance_level)(void *handle); - enum amd_pm_state_type (*get_current_power_state)(void *handle); +/* export to amdgpu */ + void (*powergate_uvd)(void *handle, bool gate); + void (*powergate_vce)(void *handle, bool gate); + struct amd_vce_state* (*get_vce_clock_state)(void *handle, u32 idx); int (*dispatch_tasks)(void *handle, enum amd_pp_task task_id, void *input, void *output); - int (*get_fan_speed_rpm)(void *handle, uint32_t *rpm); - int (*get_pp_num_states)(void *handle, struct pp_states_info *data); - int (*get_pp_table)(void *handle, char **table); - int (*set_pp_table)(void *handle, const char *buf, size_t size); + int (*load_firmware)(void *handle); + int (*wait_for_fw_loading_complete)(void *handle); +/* export to DC */ + u32 (*get_sclk)(void *handle, bool low); + u32 (*get_mclk)(void *handle, bool low); }; -- cgit v1.2.3 From c6c5b324383d00731abd438e7c378b351add569b Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 22 Sep 2017 14:38:45 +0800 Subject: drm/amd/powerplay: export new interfaces in amd_pm_funcs Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/amd_shared.h | 37 +++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 5be1fb977810..de6fc2731b98 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -257,9 +257,18 @@ struct amd_ip_funcs { void (*get_clockgating_state)(void *handle, u32 *flags); }; -enum amd_pp_task; +enum amd_pp_task; +enum amd_pp_clock_type; struct pp_states_info; +struct amd_pp_simple_clock_info; +struct amd_pp_display_configuration; +struct amd_pp_clock_info; +struct pp_display_clock_request; +struct pp_wm_sets_with_clock_ranges_soc15; +struct pp_clock_levels_with_voltage; +struct pp_clock_levels_with_latency; +struct amd_pp_clocks; struct amd_pm_funcs { /* export for dpm on ci and si */ @@ -283,17 +292,13 @@ struct amd_pm_funcs { int (*force_clock_level)(void *handle, enum pp_clock_type type, uint32_t mask); int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); int (*force_performance_level)(void *handle, enum amd_dpm_forced_level level); - int (*get_sclk_od)(void *handle); int (*set_sclk_od)(void *handle, uint32_t value); int (*get_mclk_od)(void *handle); int (*set_mclk_od)(void *handle, uint32_t value); - int (*read_sensor)(void *handle, int idx, void *value, int *size); - enum amd_dpm_forced_level (*get_performance_level)(void *handle); enum amd_pm_state_type (*get_current_power_state)(void *handle); - int (*get_fan_speed_rpm)(void *handle, uint32_t *rpm); int (*get_pp_num_states)(void *handle, struct pp_states_info *data); int (*get_pp_table)(void *handle, char **table); @@ -316,9 +321,31 @@ struct amd_pm_funcs { void *input, void *output); int (*load_firmware)(void *handle); int (*wait_for_fw_loading_complete)(void *handle); + int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id); /* export to DC */ u32 (*get_sclk)(void *handle, bool low); u32 (*get_mclk)(void *handle, bool low); + int (*display_configuration_change)(void *handle, + const struct amd_pp_display_configuration *input); + int (*get_display_power_level)(void *handle, + struct amd_pp_simple_clock_info *output); + int (*get_current_clocks)(void *handle, + struct amd_pp_clock_info *clocks); + int (*get_clock_by_type)(void *handle, + enum amd_pp_clock_type type, + struct amd_pp_clocks *clocks); + int (*get_clock_by_type_with_latency)(void *handle, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_latency *clocks); + int (*get_clock_by_type_with_voltage)(void *handle, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_voltage *clocks); + int (*set_watermarks_for_clocks_ranges)(void *handle, + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); + int (*display_clock_voltage_request)(void *handle, + struct pp_display_clock_request *clock); + int (*get_display_mode_validation_clocks)(void *handle, + struct amd_pp_simple_clock_info *clocks); }; -- cgit v1.2.3 From 20a3a71da542974a7ba30b121c5f81b83579c828 Mon Sep 17 00:00:00 2001 From: Horace Chen Date: Wed, 27 Sep 2017 16:13:17 +0800 Subject: drm/amdgpu: Add a new flag for SR-IOV to share memory between PF & VF Add ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION to identify whether driver need to reserve VRAM for SR-IOV shared memory. Signed-off-by: Horace Chen Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/atombios.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/include/atombios.h b/drivers/gpu/drm/amd/include/atombios.h index 181a2c3c6362..f696bbb643ef 100644 --- a/drivers/gpu/drm/amd/include/atombios.h +++ b/drivers/gpu/drm/amd/include/atombios.h @@ -4292,6 +4292,7 @@ typedef struct _ATOM_DPCD_INFO #define ATOM_VRAM_OPERATION_FLAGS_SHIFT 30 #define ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION 0x1 #define ATOM_VRAM_BLOCK_NEEDS_RESERVATION 0x0 +#define ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION 0x2 /***********************************************************************************/ // Structure used in VRAM_UsageByFirmwareTable -- cgit v1.2.3 From 4fc0870d7e462fe3b86e0f938ae75ce884728c7d Mon Sep 17 00:00:00 2001 From: Christophe Lombard Date: Tue, 26 Sep 2017 10:15:21 +0200 Subject: cxl: Fix memory page not handled The in-kernel 'library' API can be called by drivers to help interaction with an IBM XSL on a POWER9 system. The cxllib_handle_fault() API is used to handle memory fault. All memory pages of the specified buffer have to be handled but under certain conditions,the last page may not be touched, and the address the adapter is trying to access is never sent to the kernel for resolution. This patch reworks start address of the loop with an address aligned on the page size. In this context, the last page is not missed. Signed-off-by: Christophe Lombard Acked-by: Frederic Barrat Acked-by: Andrew Donnellan Fixes: 3ced8d730063 ("cxl: Export library to support IBM XSL"); Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxllib.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c index 5dba23ca2e5f..dc9bc1807fdf 100644 --- a/drivers/misc/cxl/cxllib.c +++ b/drivers/misc/cxl/cxllib.c @@ -219,8 +219,17 @@ int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags) down_read(&mm->mmap_sem); - for (dar = addr; dar < addr + size; dar += page_size) { - if (!vma || dar < vma->vm_start || dar > vma->vm_end) { + vma = find_vma(mm, addr); + if (!vma) { + pr_err("Can't find vma for addr %016llx\n", addr); + rc = -EFAULT; + goto out; + } + /* get the size of the pages allocated */ + page_size = vma_kernel_pagesize(vma); + + for (dar = (addr & ~(page_size - 1)); dar < (addr + size); dar += page_size) { + if (dar < vma->vm_start || dar >= vma->vm_end) { vma = find_vma(mm, addr); if (!vma) { pr_err("Can't find vma for addr %016llx\n", addr); -- cgit v1.2.3 From e18063e88bd579c479a2b45820be6c4625f841c3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 29 Sep 2017 13:50:38 +0300 Subject: drm/i915: Update DRIVER_DATE to 20170929 Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8e4280838f14..7ca11318ac69 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -80,8 +80,8 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20170907" -#define DRIVER_TIMESTAMP 1504772900 +#define DRIVER_DATE "20170929" +#define DRIVER_TIMESTAMP 1506682238 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions -- cgit v1.2.3 From 60456d5c2d25cbe91cd0747d12ec9d909bf8d5b9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 26 Sep 2017 16:34:09 +0100 Subject: drm/i915/selftests: Replace wmb() with i915_gem_chipset_flush() Currently, we are being fairly lazy and only using a wmb() following an update to an active batch. Previously, we have found that to be insufficient to ensure that a write from the CPU reaches memory in a timely fashion, and in some caches we may need to flush a chipset cache. To that end, we have i915_gem_chipset_flush() so use it. Suggested-by: Mika Kuoppala Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20170926153409.7928-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/selftests/i915_gem_request.c | 10 +++++++--- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 7 +++++-- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c b/drivers/gpu/drm/i915/selftests/i915_gem_request.c index 6664cb2eb0b8..78b9f811707f 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c @@ -418,7 +418,10 @@ static struct i915_vma *empty_batch(struct drm_i915_private *i915) err = PTR_ERR(cmd); goto err; } + *cmd = MI_BATCH_BUFFER_END; + i915_gem_chipset_flush(i915); + i915_gem_object_unpin_map(obj); err = i915_gem_object_set_to_gtt_domain(obj, false); @@ -605,8 +608,8 @@ static struct i915_vma *recursive_batch(struct drm_i915_private *i915) *cmd++ = lower_32_bits(vma->node.start); } *cmd++ = MI_BATCH_BUFFER_END; /* terminate early in case of error */ + i915_gem_chipset_flush(i915); - wmb(); i915_gem_object_unpin_map(obj); return vma; @@ -625,7 +628,7 @@ static int recursive_batch_resolve(struct i915_vma *batch) return PTR_ERR(cmd); *cmd = MI_BATCH_BUFFER_END; - wmb(); + i915_gem_chipset_flush(batch->vm->i915); i915_gem_object_unpin_map(batch->obj); @@ -858,7 +861,8 @@ out_request: I915_MAP_WC); if (!IS_ERR(cmd)) { *cmd = MI_BATCH_BUFFER_END; - wmb(); + i915_gem_chipset_flush(i915); + i915_gem_object_unpin_map(request[id]->batch->obj); } diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index 377c1de766ce..08159b268893 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -165,6 +165,7 @@ static int emit_recurse_batch(struct hang *h, *batch++ = lower_32_bits(vma->node.start); } *batch++ = MI_BATCH_BUFFER_END; /* not reached */ + i915_gem_chipset_flush(h->i915); flags = 0; if (INTEL_GEN(vm->i915) <= 5) @@ -231,7 +232,7 @@ static u32 hws_seqno(const struct hang *h, static void hang_fini(struct hang *h) { *h->batch = MI_BATCH_BUFFER_END; - wmb(); + i915_gem_chipset_flush(h->i915); i915_gem_object_unpin_map(h->obj); i915_gem_object_put(h->obj); @@ -275,6 +276,8 @@ static int igt_hang_sanitycheck(void *arg) i915_gem_request_get(rq); *h.batch = MI_BATCH_BUFFER_END; + i915_gem_chipset_flush(i915); + __i915_add_request(rq, true); timeout = i915_wait_request(rq, @@ -765,7 +768,7 @@ static int igt_reset_queue(void *arg) pr_info("%s: Completed %d resets\n", engine->name, count); *h.batch = MI_BATCH_BUFFER_END; - wmb(); + i915_gem_chipset_flush(i915); i915_gem_request_put(prev); } -- cgit v1.2.3 From 269e6ea95311130f75c4eb21bf1797a4cadfb82d Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Fri, 29 Sep 2017 10:28:36 +0530 Subject: drm/i915: Move i915_gem_restore_fences to i915_gem_resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i915_gem_restore_fences is GEM resumption task hence it is moved to i915_gem_resume from i915_restore_state. Signed-off-by: Sagar Arun Kamble Cc: Michal Wajdeczko Cc: Michał Winiarski Cc: Chris Wilson Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1506661116-12106-1-git-send-email-sagar.a.kamble@intel.com Reviewed-by: Michal Wajdeczko Reviewed-by: Joonas Lahtinen Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/i915_suspend.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 73eeb6b1f1cd..ab8c6946fea4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4595,6 +4595,7 @@ void i915_gem_resume(struct drm_i915_private *dev_priv) mutex_lock(&dev->struct_mutex); i915_gem_restore_gtt_mappings(dev_priv); + i915_gem_restore_fences(dev_priv); /* As we didn't flush the kernel context before suspend, we cannot * guarantee that the context image is complete. So let's just reset diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 5c86925a0294..8f3aa4dc0c98 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -108,8 +108,6 @@ int i915_restore_state(struct drm_i915_private *dev_priv) mutex_lock(&dev_priv->drm.struct_mutex); - i915_gem_restore_fences(dev_priv); - if (IS_GEN4(dev_priv)) pci_write_config_word(pdev, GCDGMBUS, dev_priv->regfile.saveGCDGMBUS); -- cgit v1.2.3 From 7e4992ac045ccdef9d5a0b4800ee8da43b5a809a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Sep 2017 20:38:59 +0100 Subject: drm/i915/execlists: Move request unwinding to a separate function In the future, we will want to unwind requests following a preemption point. This requires the same steps as for unwinding upon a reset, so extract the existing code to a separate function for later use. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170928193910.17988-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 54 +++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 61cac26a8b05..cbac2fff8e4d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -210,6 +210,7 @@ #define EXECLISTS_REQUEST_SIZE 64 /* bytes */ #define WA_TAIL_DWORDS 2 +#define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS) static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, struct intel_engine_cs *engine); @@ -348,6 +349,37 @@ find_priolist: return ptr_pack_bits(p, first, 1); } +static void unwind_wa_tail(struct drm_i915_gem_request *rq) +{ + rq->tail = intel_ring_wrap(rq->ring, rq->wa_tail - WA_TAIL_BYTES); + assert_ring_tail_valid(rq->ring, rq->tail); +} + +static void unwind_incomplete_requests(struct intel_engine_cs *engine) +{ + struct drm_i915_gem_request *rq, *rn; + + lockdep_assert_held(&engine->timeline->lock); + + list_for_each_entry_safe_reverse(rq, rn, + &engine->timeline->requests, + link) { + struct i915_priolist *p; + + if (i915_gem_request_completed(rq)) + return; + + __i915_gem_request_unsubmit(rq); + unwind_wa_tail(rq); + + p = lookup_priolist(engine, + &rq->priotree, + rq->priotree.priority); + list_add(&rq->priotree.link, + &ptr_mask_bits(p, 1)->requests); + } +} + static inline void execlists_context_status_change(struct drm_i915_gem_request *rq, unsigned long status) @@ -1382,7 +1414,6 @@ static void reset_common_ring(struct intel_engine_cs *engine, struct drm_i915_gem_request *request) { struct intel_engine_execlists * const execlists = &engine->execlists; - struct drm_i915_gem_request *rq, *rn; struct intel_context *ce; unsigned long flags; @@ -1400,21 +1431,7 @@ static void reset_common_ring(struct intel_engine_cs *engine, execlist_cancel_port_requests(execlists); /* Push back any incomplete requests for replay after the reset. */ - list_for_each_entry_safe_reverse(rq, rn, - &engine->timeline->requests, link) { - struct i915_priolist *p; - - if (i915_gem_request_completed(rq)) - break; - - __i915_gem_request_unsubmit(rq); - - p = lookup_priolist(engine, - &rq->priotree, - rq->priotree.priority); - list_add(&rq->priotree.link, - &ptr_mask_bits(p, 1)->requests); - } + unwind_incomplete_requests(engine); spin_unlock_irqrestore(&engine->timeline->lock, flags); @@ -1451,10 +1468,7 @@ static void reset_common_ring(struct intel_engine_cs *engine, intel_ring_update_space(request->ring); /* Reset WaIdleLiteRestore:bdw,skl as well */ - request->tail = - intel_ring_wrap(request->ring, - request->wa_tail - WA_TAIL_DWORDS*sizeof(u32)); - assert_ring_tail_valid(request->ring, request->tail); + unwind_wa_tail(request); } static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req) -- cgit v1.2.3 From 7d1ea609f67a7d17c287ffdc008c79e0e91bc581 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Sep 2017 20:39:00 +0100 Subject: drm/i915: Give the invalid priority a magic name We use INT_MIN to denote the priority of a request that has not been submitted to the scheduler; we treat INT_MIN as an invalid priority and initialise the request to it. Give the value a name so it stands out. Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170928193910.17988-3-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala Reviewed-by: Joonas Lahtinen signalers_list); INIT_LIST_HEAD(&pt->waiters_list); INIT_LIST_HEAD(&pt->link); - pt->priority = INT_MIN; + pt->priority = I915_PRIORITY_INVALID; } static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno) diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h index 96eb52471dad..6b9e992d01de 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.h +++ b/drivers/gpu/drm/i915/i915_gem_request.h @@ -72,6 +72,7 @@ struct i915_priotree { #define I915_PRIORITY_MAX 1024 #define I915_PRIORITY_NORMAL 0 #define I915_PRIORITY_MIN (-I915_PRIORITY_MAX) +#define I915_PRIORITY_INVALID INT_MIN }; struct i915_gem_capture_list { diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cbac2fff8e4d..303bb2c0b3ce 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -863,6 +863,8 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) struct i915_dependency stack; LIST_HEAD(dfs); + GEM_BUG_ON(prio == I915_PRIORITY_INVALID); + if (prio <= READ_ONCE(request->priotree.priority)) return; @@ -911,7 +913,7 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) * execlists_submit_request()), we can set our own priority and skip * acquiring the engine locks. */ - if (request->priotree.priority == INT_MIN) { + if (request->priotree.priority == I915_PRIORITY_INVALID) { GEM_BUG_ON(!list_empty(&request->priotree.link)); request->priotree.priority = prio; if (stack.dfs_link.next == stack.dfs_link.prev) -- cgit v1.2.3 From 097a94815fb61ba4f184b3efd8f4e158116956d0 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Thu, 28 Sep 2017 20:39:01 +0100 Subject: drm/i915/execlists: Cache the last priolist lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid the repeated rbtree lookup for each request as we unwind them by tracking the last priolist. v2: Fix up my unhelpful suggestion of using default_priolist. Signed-off-by: Michał Winiarski Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20170928193910.17988-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 303bb2c0b3ce..7d6da130b184 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -358,25 +358,31 @@ static void unwind_wa_tail(struct drm_i915_gem_request *rq) static void unwind_incomplete_requests(struct intel_engine_cs *engine) { struct drm_i915_gem_request *rq, *rn; + struct i915_priolist *uninitialized_var(p); + int last_prio = I915_PRIORITY_INVALID; lockdep_assert_held(&engine->timeline->lock); list_for_each_entry_safe_reverse(rq, rn, &engine->timeline->requests, link) { - struct i915_priolist *p; - if (i915_gem_request_completed(rq)) return; __i915_gem_request_unsubmit(rq); unwind_wa_tail(rq); - p = lookup_priolist(engine, - &rq->priotree, - rq->priotree.priority); - list_add(&rq->priotree.link, - &ptr_mask_bits(p, 1)->requests); + GEM_BUG_ON(rq->priotree.priority == I915_PRIORITY_INVALID); + if (rq->priotree.priority != last_prio) { + p = lookup_priolist(engine, + &rq->priotree, + rq->priotree.priority); + p = ptr_mask_bits(p, 1); + + last_prio = rq->priotree.priority; + } + + list_add(&rq->priotree.link, &p->requests); } } -- cgit v1.2.3 From 04eae427406ef6af9b05bd631e235f4a509666b1 Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Fri, 29 Sep 2017 08:25:01 -0500 Subject: RDMA/iwpm: Properly mark end of NL messages Commit 1a1c116f3dcf removes nlmsg_len calculation in ibnl_put_attr causing netlink messages to be rejected due to incorrect length. Add nlmsg_end after all attributes are appended to calculate the nlmsg_len. Fixes: 1a1c116f3dcf ("RDMA/netlink: Simplify the put_msg and put_attr") Signed-off-by: Shiraz Saleem Signed-off-by: Tatyana Nikolova Reviewed-by: Leon Romanovsky Signed-off-by: Doug Ledford --- drivers/infiniband/core/iwpm_msg.c | 8 ++++++++ drivers/infiniband/core/iwpm_util.c | 5 +++++ 2 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index 30825bb9b8e9..8861c052155a 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c @@ -100,6 +100,8 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) if (ret) goto pid_query_error; + nlmsg_end(skb, nlh); + pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n", __func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name); @@ -170,6 +172,8 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR); if (ret) goto add_mapping_error; + + nlmsg_end(skb, nlh); nlmsg_request->req_buffer = pm_msg; ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); @@ -246,6 +250,8 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR); if (ret) goto query_mapping_error; + + nlmsg_end(skb, nlh); nlmsg_request->req_buffer = pm_msg; ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); @@ -308,6 +314,8 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) if (ret) goto remove_mapping_error; + nlmsg_end(skb, nlh); + ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); if (ret) { skb = NULL; /* skb is freed in the netlink send-op handling */ diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index c81c55942626..3c4faadb8cdd 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -597,6 +597,9 @@ static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid) &mapping_num, IWPM_NLA_MAPINFO_SEND_NUM); if (ret) goto mapinfo_num_error; + + nlmsg_end(skb, nlh); + ret = rdma_nl_unicast(skb, iwpm_pid); if (ret) { skb = NULL; @@ -678,6 +681,8 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid) if (ret) goto send_mapping_info_unlock; + nlmsg_end(skb, nlh); + iwpm_print_sockaddr(&map_info->local_sockaddr, "send_mapping_info: Local sockaddr:"); iwpm_print_sockaddr(&map_info->mapped_sockaddr, -- cgit v1.2.3 From d81a2209498b6349a33f8741ca5a062dde84c043 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 10:12:53 +1000 Subject: amdgfx/gfx: don't use static objects for ce/de meta. (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This isn't safe if we have multiple GPUs plugged in, since there is only one copy of this struct in the bss, just allocate on stack, it's 40/108 bytes which should be safe. Reviewed-by: Christian König Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index e04de7a81592..1640dd796618 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -7042,7 +7042,7 @@ static void gfx_v8_0_ring_emit_ce_meta(struct amdgpu_ring *ring) { uint64_t ce_payload_addr; int cnt_ce; - static union { + union { struct vi_ce_ib_state regular; struct vi_ce_ib_state_chained_ib chained; } ce_payload = {}; @@ -7071,7 +7071,7 @@ static void gfx_v8_0_ring_emit_de_meta(struct amdgpu_ring *ring) { uint64_t de_payload_addr, gds_addr, csa_addr; int cnt_de; - static union { + union { struct vi_de_ib_state regular; struct vi_de_ib_state_chained_ib chained; } de_payload = {}; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index deeaee1457ef..508efc8ceb66 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -3806,7 +3806,7 @@ static void gfx_v9_ring_emit_sb(struct amdgpu_ring *ring) static void gfx_v9_0_ring_emit_ce_meta(struct amdgpu_ring *ring) { - static struct v9_ce_ib_state ce_payload = {0}; + struct v9_ce_ib_state ce_payload = {0}; uint64_t csa_addr; int cnt; @@ -3825,7 +3825,7 @@ static void gfx_v9_0_ring_emit_ce_meta(struct amdgpu_ring *ring) static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring) { - static struct v9_de_ib_state de_payload = {0}; + struct v9_de_ib_state de_payload = {0}; uint64_t csa_addr, gds_addr; int cnt; -- cgit v1.2.3 From ce27643cc0f56f7a70de17c2ef54541ad4252c1a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 11:12:30 +1000 Subject: amdgpu/pp: use array_size to size the pwrvirus tables. This avoids fragile hardcoding of array size. Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h | 3 +-- drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h | 5 +---- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h b/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h index 243de293a3ef..e202e567faf4 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h +++ b/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h @@ -35,8 +35,7 @@ struct PWR_Command_Table }; typedef struct PWR_Command_Table PWR_Command_Table; -#define PWR_VIRUS_TABLE_SIZE 10243 -static const PWR_Command_Table PwrVirusTable[PWR_VIRUS_TABLE_SIZE] = +static const PWR_Command_Table PwrVirusTable[] = { { 0x100100b6, mmPCIE_INDEX }, { 0x00000000, mmPCIE_DATA }, diff --git a/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h b/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h index 76039860580d..8edd3e7860b7 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h +++ b/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h @@ -36,10 +36,7 @@ struct PWR_Command_Table { typedef struct PWR_Command_Table PWR_Command_Table; - -#define PWR_VIRUS_TABLE_SIZE 10031 - -static const PWR_Command_Table pwr_virus_table[PWR_VIRUS_TABLE_SIZE] = { +static const PWR_Command_Table pwr_virus_table[] = { { 0x00000000, mmRLC_CNTL }, { 0x00000002, mmRLC_SRM_CNTL }, { 0x15000000, mmCP_ME_CNTL }, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 3820fe8f944a..289006b8d421 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -167,7 +167,7 @@ static int fiji_setup_pwr_virus(struct pp_hwmgr *hwmgr) const PWR_Command_Table *pvirus = PwrVirusTable; - for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) { + for (i = 0; i < ARRAY_SIZE(PwrVirusTable); i++) { reg = pvirus->reg; data = pvirus->data; if (reg != 0xffffffff) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index b73b2b445cee..f039320fa794 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -68,7 +68,7 @@ static int polaris10_setup_pwr_virus(struct pp_hwmgr *hwmgr) const PWR_Command_Table *pvirus = pwr_virus_table; - for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) { + for (i = 0; i < ARRAY_SIZE(pwr_virus_table); i++) { reg = pvirus->reg; data = pvirus->data; if (reg != 0xffffffff) { -- cgit v1.2.3 From 6cdb91e28128595c1e2b7d0fa1ead30dc34ff15c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 10:39:30 +1000 Subject: amdgpu/pp: constify soft_dummy_pp_table. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c index 485f7ebdc754..afae32ee2b0d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c @@ -790,7 +790,7 @@ static const ATOM_PPLIB_STATE_V2 *get_state_entry_v2( return pstate; } -static unsigned char soft_dummy_pp_table[] = { +static const unsigned char soft_dummy_pp_table[] = { 0xe1, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x88, 0x00, 0x00, 0x9e, 0x00, 0x17, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, -- cgit v1.2.3 From 35b31f7c6464480b10f3a54c9a35699e02f17ae8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 10:08:01 +1000 Subject: amdgpu/soc15: make the pcie index/data registers constant. These don't seem to change at runtime, and the initialisers are constant data. This could be improved by not selecting the apu/non-apu path on each pcie read/write access. Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h | 2 +- drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h | 2 +- drivers/gpu/drm/amd/amdgpu/soc15.c | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c index 045988b18bc3..7723d7bccb96 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c @@ -216,7 +216,10 @@ void nbio_v6_1_get_clockgating_state(struct amdgpu_device *adev, u32 *flags) } struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; -struct nbio_pcie_index_data nbio_v6_1_pcie_index_data; +const struct nbio_pcie_index_data nbio_v6_1_pcie_index_data = { + .index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX), + .data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA), +}; int nbio_v6_1_init(struct amdgpu_device *adev) { @@ -235,9 +238,6 @@ int nbio_v6_1_init(struct amdgpu_device *adev) nbio_v6_1_hdp_flush_reg.ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK; nbio_v6_1_hdp_flush_reg.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK; - nbio_v6_1_pcie_index_data.index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX); - nbio_v6_1_pcie_index_data.data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h index 686e4b4d296a..c5ca1e47763c 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h @@ -27,7 +27,7 @@ #include "soc15_common.h" extern struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; -extern struct nbio_pcie_index_data nbio_v6_1_pcie_index_data; +extern const struct nbio_pcie_index_data nbio_v6_1_pcie_index_data; int nbio_v6_1_init(struct amdgpu_device *adev); u32 nbio_v6_1_get_atombios_scratch_regs(struct amdgpu_device *adev, uint32_t idx); diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c index 11b70d601922..b932b780dd32 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c @@ -186,7 +186,10 @@ void nbio_v7_0_ih_control(struct amdgpu_device *adev) } struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; -struct nbio_pcie_index_data nbio_v7_0_pcie_index_data; +const struct nbio_pcie_index_data nbio_v7_0_pcie_index_data = { + .index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX2), + .data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA2) +}; int nbio_v7_0_init(struct amdgpu_device *adev) { @@ -205,8 +208,5 @@ int nbio_v7_0_init(struct amdgpu_device *adev) nbio_v7_0_hdp_flush_reg.ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK; nbio_v7_0_hdp_flush_reg.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK; - nbio_v7_0_pcie_index_data.index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX2); - nbio_v7_0_pcie_index_data.data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA2); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h index 054ff49427e6..21bad0098bf6 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h @@ -27,7 +27,7 @@ #include "soc15_common.h" extern struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; -extern struct nbio_pcie_index_data nbio_v7_0_pcie_index_data; +extern const struct nbio_pcie_index_data nbio_v7_0_pcie_index_data; int nbio_v7_0_init(struct amdgpu_device *adev); u32 nbio_v7_0_get_atombios_scratch_regs(struct amdgpu_device *adev, uint32_t idx); diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 245a18aeb389..dd5cbf37abc4 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -101,7 +101,7 @@ static u32 soc15_pcie_rreg(struct amdgpu_device *adev, u32 reg) { unsigned long flags, address, data; u32 r; - struct nbio_pcie_index_data *nbio_pcie_id; + const struct nbio_pcie_index_data *nbio_pcie_id; if (adev->flags & AMD_IS_APU) nbio_pcie_id = &nbio_v7_0_pcie_index_data; @@ -122,7 +122,7 @@ static u32 soc15_pcie_rreg(struct amdgpu_device *adev, u32 reg) static void soc15_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) { unsigned long flags, address, data; - struct nbio_pcie_index_data *nbio_pcie_id; + const struct nbio_pcie_index_data *nbio_pcie_id; if (adev->flags & AMD_IS_APU) nbio_pcie_id = &nbio_v7_0_pcie_index_data; -- cgit v1.2.3 From c6622f3afcb4da90e2600ee98e91a8a5640f7a27 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 10:47:43 +1000 Subject: amdgpu/nbio: use constant nbio_hdp_flush_reg structs. This removes the init path as well, since the init path just did some constant init of some structs. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c | 38 +++++++++++++++------------------- drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h | 2 +- drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c | 38 +++++++++++++++------------------- drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h | 2 +- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/soc15.c | 15 -------------- 7 files changed, 38 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 508efc8ceb66..99a5b3b92e8e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -3583,7 +3583,7 @@ static void gfx_v9_0_ring_set_wptr_gfx(struct amdgpu_ring *ring) static void gfx_v9_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) { u32 ref_and_mask, reg_mem_engine; - struct nbio_hdp_flush_reg *nbio_hf_reg; + const struct nbio_hdp_flush_reg *nbio_hf_reg; if (ring->adev->flags & AMD_IS_APU) nbio_hf_reg = &nbio_v7_0_hdp_flush_reg; diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c index 7723d7bccb96..904a1bab9b9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c @@ -215,32 +215,28 @@ void nbio_v6_1_get_clockgating_state(struct amdgpu_device *adev, u32 *flags) *flags |= AMD_CG_SUPPORT_BIF_LS; } -struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; +const struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg = { + .hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_REQ), + .hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_DONE), + .ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK, + .ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK, + .ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK, + .ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK, + .ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK, + .ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK, + .ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK, + .ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK, + .ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK, + .ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK, + .ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK, + .ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK +}; + const struct nbio_pcie_index_data nbio_v6_1_pcie_index_data = { .index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX), .data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA), }; -int nbio_v6_1_init(struct amdgpu_device *adev) -{ - nbio_v6_1_hdp_flush_reg.hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_REQ); - nbio_v6_1_hdp_flush_reg.hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_DONE); - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK; - nbio_v6_1_hdp_flush_reg.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK; - - return 0; -} - void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev) { uint32_t reg; diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h index c5ca1e47763c..14ca8d45a46c 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h @@ -26,7 +26,7 @@ #include "soc15_common.h" -extern struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; +extern const struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; extern const struct nbio_pcie_index_data nbio_v6_1_pcie_index_data; int nbio_v6_1_init(struct amdgpu_device *adev); u32 nbio_v6_1_get_atombios_scratch_regs(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c index b932b780dd32..f802b973410a 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c @@ -185,28 +185,24 @@ void nbio_v7_0_ih_control(struct amdgpu_device *adev) WREG32_SOC15(NBIO, 0, mmINTERRUPT_CNTL, interrupt_cntl); } -struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; +const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = { + .hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_REQ), + .hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_DONE), + .ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK, + .ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK, + .ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK, + .ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK, + .ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK, + .ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK, + .ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK, + .ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK, + .ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK, + .ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK, + .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK, + .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK, +}; + const struct nbio_pcie_index_data nbio_v7_0_pcie_index_data = { .index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX2), .data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA2) }; - -int nbio_v7_0_init(struct amdgpu_device *adev) -{ - nbio_v7_0_hdp_flush_reg.hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_REQ); - nbio_v7_0_hdp_flush_reg.hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_DONE); - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK; - nbio_v7_0_hdp_flush_reg.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK; - - return 0; -} diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h index 21bad0098bf6..df8fa90f40d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h @@ -26,7 +26,7 @@ #include "soc15_common.h" -extern struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; +extern const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; extern const struct nbio_pcie_index_data nbio_v7_0_pcie_index_data; int nbio_v7_0_init(struct amdgpu_device *adev); u32 nbio_v7_0_get_atombios_scratch_regs(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index c26d205ff3bf..46009db3d195 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -371,7 +371,7 @@ static void sdma_v4_0_ring_emit_ib(struct amdgpu_ring *ring, static void sdma_v4_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) { u32 ref_and_mask = 0; - struct nbio_hdp_flush_reg *nbio_hf_reg; + const struct nbio_hdp_flush_reg *nbio_hf_reg; if (ring->adev->flags & AMD_IS_APU) nbio_hf_reg = &nbio_v7_0_hdp_flush_reg; diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index dd5cbf37abc4..1c006ba9d826 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -604,21 +604,6 @@ static int soc15_common_early_init(void *handle) (amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_PSP))) psp_enabled = true; - /* - * nbio need be used for both sdma and gfx9, but only - * initializes once - */ - switch(adev->asic_type) { - case CHIP_VEGA10: - nbio_v6_1_init(adev); - break; - case CHIP_RAVEN: - nbio_v7_0_init(adev); - break; - default: - return -EINVAL; - } - adev->rev_id = soc15_get_rev_id(adev); adev->external_rev_id = 0xFF; switch (adev->asic_type) { -- cgit v1.2.3 From 6f5c2f9d3c5c335ae86203f9548e1a861bdd154a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 12:15:46 +1000 Subject: amdgpu/pp: rewrite polaris pwrvirus upload code. This reduces the pwrvirus table size by 30k, by moving the sequences of writes to the data register into blocks. Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h | 10797 +++---------------- .../drm/amd/powerplay/smumgr/polaris10_smumgr.c | 37 +- 2 files changed, 1285 insertions(+), 9549 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h b/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h index 8edd3e7860b7..6a53b7e74ccd 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h +++ b/drivers/gpu/drm/amd/powerplay/inc/polaris10_pwrvirus.h @@ -36,7 +36,16 @@ struct PWR_Command_Table { typedef struct PWR_Command_Table PWR_Command_Table; -static const PWR_Command_Table pwr_virus_table[] = { +struct PWR_DFY_Section { + uint32_t dfy_cntl; + uint32_t dfy_addr_hi, dfy_addr_lo; + uint32_t dfy_size; + uint32_t dfy_data[]; +}; + +typedef struct PWR_DFY_Section PWR_DFY_Section; + +static const PWR_Command_Table pwr_virus_table_pre[] = { { 0x00000000, mmRLC_CNTL }, { 0x00000002, mmRLC_SRM_CNTL }, { 0x15000000, mmCP_ME_CNTL }, @@ -242,9544 +251,1254 @@ static const PWR_Command_Table pwr_virus_table[] = { { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x540fe800, mmCP_DFY_ADDR_LO }, - { 0x7e000200, mmCP_DFY_DATA_0 }, - { 0x7e020201, mmCP_DFY_DATA_0 }, - { 0x7e040204, mmCP_DFY_DATA_0 }, - { 0x7e060205, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000005, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54106f00, mmCP_DFY_DATA_0 }, - { 0x000400b4, mmCP_DFY_DATA_0 }, - { 0x00004000, mmCP_DFY_DATA_0 }, - { 0x00804fac, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x540fef00, mmCP_DFY_ADDR_LO }, - { 0xc0031502, mmCP_DFY_DATA_0 }, - { 0x00001e00, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x540ff000, mmCP_DFY_ADDR_LO }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x80000145, mmCP_DFY_DATA_0 }, - { 0x94800001, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0x95400001, mmCP_DFY_DATA_0 }, - { 0x95800001, mmCP_DFY_DATA_0 }, - { 0xdc810000, mmCP_DFY_DATA_0 }, - { 0xdcc10000, mmCP_DFY_DATA_0 }, - { 0xdd010000, mmCP_DFY_DATA_0 }, - { 0xdd410000, mmCP_DFY_DATA_0 }, - { 0xdd810000, mmCP_DFY_DATA_0 }, - { 0xc4080061, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8000003, mmCP_DFY_DATA_0 }, - { 0xc40c0001, mmCP_DFY_DATA_0 }, - { 0x24ccffff, mmCP_DFY_DATA_0 }, - { 0x3cd08000, mmCP_DFY_DATA_0 }, - { 0x9500fffd, mmCP_DFY_DATA_0 }, - { 0x1cd0ffcf, mmCP_DFY_DATA_0 }, - { 0x7d018001, mmCP_DFY_DATA_0 }, - { 0xc4140004, mmCP_DFY_DATA_0 }, - { 0x050c0019, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x84c00000, mmCP_DFY_DATA_0 }, - { 0x80000023, mmCP_DFY_DATA_0 }, - { 0x80000067, mmCP_DFY_DATA_0 }, - { 0x8000006a, mmCP_DFY_DATA_0 }, - { 0x8000006d, mmCP_DFY_DATA_0 }, - { 0x80000079, mmCP_DFY_DATA_0 }, - { 0x80000084, mmCP_DFY_DATA_0 }, - { 0x8000008f, mmCP_DFY_DATA_0 }, - { 0x80000099, mmCP_DFY_DATA_0 }, - { 0x800000a0, mmCP_DFY_DATA_0 }, - { 0x800000af, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0xc4080007, mmCP_DFY_DATA_0 }, - { 0x388c0001, mmCP_DFY_DATA_0 }, - { 0x08880002, mmCP_DFY_DATA_0 }, - { 0x04100003, mmCP_DFY_DATA_0 }, - { 0x94c00005, mmCP_DFY_DATA_0 }, - { 0x98800003, mmCP_DFY_DATA_0 }, - { 0x04100004, mmCP_DFY_DATA_0 }, - { 0x8000002d, mmCP_DFY_DATA_0 }, - { 0x04100005, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0000, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x28080001, mmCP_DFY_DATA_0 }, - { 0xcc000004, mmCP_DFY_DATA_0 }, - { 0x7d808001, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0xcc800005, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcd013278, mmCP_DFY_DATA_0 }, - { 0xc4113278, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0x24cc0700, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc4113255, mmCP_DFY_DATA_0 }, - { 0xcd01324f, mmCP_DFY_DATA_0 }, - { 0xc4113254, mmCP_DFY_DATA_0 }, - { 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0x10cc0014, mmCP_DFY_DATA_0 }, - { 0x1d10c017, mmCP_DFY_DATA_0 }, - { 0x7d0d000a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd0130b7, mmCP_DFY_DATA_0 }, - { 0x14cc0010, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0x8000005d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14d00011, mmCP_DFY_DATA_0 }, - { 0x9500fffe, mmCP_DFY_DATA_0 }, - { 0xdc030000, mmCP_DFY_DATA_0 }, - { 0xd800000c, mmCP_DFY_DATA_0 }, - { 0xd800000d, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01b10, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc00e0080, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0xc00e0800, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0x04100006, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0000, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x280c0008, mmCP_DFY_DATA_0 }, - { 0xccc00052, mmCP_DFY_DATA_0 }, - { 0xd8000021, mmCP_DFY_DATA_0 }, - { 0x28180039, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0x04100007, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0001, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x280c0010, mmCP_DFY_DATA_0 }, - { 0xccc00052, mmCP_DFY_DATA_0 }, - { 0x28180039, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0x04100008, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0003, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x280c0020, mmCP_DFY_DATA_0 }, - { 0xccc00052, mmCP_DFY_DATA_0 }, - { 0x28180039, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0xdc030000, mmCP_DFY_DATA_0 }, - { 0xd8000069, mmCP_DFY_DATA_0 }, - { 0x28080001, mmCP_DFY_DATA_0 }, - { 0xc428000d, mmCP_DFY_DATA_0 }, - { 0x7ca88004, mmCP_DFY_DATA_0 }, - { 0xcc800079, mmCP_DFY_DATA_0 }, - { 0x04280001, mmCP_DFY_DATA_0 }, - { 0xcc00006f, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0x04100010, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0xccc00078, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x28180080, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xcd013278, mmCP_DFY_DATA_0 }, - { 0xc4113278, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0xc4113254, mmCP_DFY_DATA_0 }, - { 0x1d10c017, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0xcd0130b7, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0x95c00001, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0x96400001, mmCP_DFY_DATA_0 }, - { 0x96800001, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x97400001, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x97c00001, mmCP_DFY_DATA_0 }, - { 0xdc810000, mmCP_DFY_DATA_0 }, - { 0xc40c000c, mmCP_DFY_DATA_0 }, - { 0xcd4c0380, mmCP_DFY_DATA_0 }, - { 0xcdcc0388, mmCP_DFY_DATA_0 }, - { 0x55dc0020, mmCP_DFY_DATA_0 }, - { 0xcdcc038c, mmCP_DFY_DATA_0 }, - { 0xce0c0390, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce0c0394, mmCP_DFY_DATA_0 }, - { 0xce4c0398, mmCP_DFY_DATA_0 }, - { 0x56640020, mmCP_DFY_DATA_0 }, - { 0xce4c039c, mmCP_DFY_DATA_0 }, - { 0xce8c03a0, mmCP_DFY_DATA_0 }, - { 0x56a80020, mmCP_DFY_DATA_0 }, - { 0xce8c03a4, mmCP_DFY_DATA_0 }, - { 0xcecc03a8, mmCP_DFY_DATA_0 }, - { 0x56ec0020, mmCP_DFY_DATA_0 }, - { 0xcecc03ac, mmCP_DFY_DATA_0 }, - { 0xcf0c03b0, mmCP_DFY_DATA_0 }, - { 0x57300020, mmCP_DFY_DATA_0 }, - { 0xcf0c03b4, mmCP_DFY_DATA_0 }, - { 0xcf4c03b8, mmCP_DFY_DATA_0 }, - { 0x57740020, mmCP_DFY_DATA_0 }, - { 0xcf4c03bc, mmCP_DFY_DATA_0 }, - { 0xcf8c03c0, mmCP_DFY_DATA_0 }, - { 0x57b80020, mmCP_DFY_DATA_0 }, - { 0xcf8c03c4, mmCP_DFY_DATA_0 }, - { 0xcfcc03c8, mmCP_DFY_DATA_0 }, - { 0x57fc0020, mmCP_DFY_DATA_0 }, - { 0xcfcc03cc, mmCP_DFY_DATA_0 }, - { 0xd9000033, mmCP_DFY_DATA_0 }, - { 0xc41c0009, mmCP_DFY_DATA_0 }, - { 0x25dc0010, mmCP_DFY_DATA_0 }, - { 0x95c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc41c000c, mmCP_DFY_DATA_0 }, - { 0x05dc002f, mmCP_DFY_DATA_0 }, - { 0xcdc12009, mmCP_DFY_DATA_0 }, - { 0xc41d200a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc012009, mmCP_DFY_DATA_0 }, - { 0xd9000034, mmCP_DFY_DATA_0 }, - { 0x25e01c00, mmCP_DFY_DATA_0 }, - { 0x12200013, mmCP_DFY_DATA_0 }, - { 0x25e40300, mmCP_DFY_DATA_0 }, - { 0x12640008, mmCP_DFY_DATA_0 }, - { 0x25e800c0, mmCP_DFY_DATA_0 }, - { 0x12a80002, mmCP_DFY_DATA_0 }, - { 0x25ec003f, mmCP_DFY_DATA_0 }, - { 0x7e25c00a, mmCP_DFY_DATA_0 }, - { 0x7eae400a, mmCP_DFY_DATA_0 }, - { 0x7de5c00a, mmCP_DFY_DATA_0 }, - { 0xddc10000, mmCP_DFY_DATA_0 }, - { 0xc02ee000, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0xc40c005f, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x24d000ff, mmCP_DFY_DATA_0 }, - { 0x31100006, mmCP_DFY_DATA_0 }, - { 0x9500007b, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xdc1c0000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1c200, mmCP_DFY_DATA_0 }, - { 0xc40c000c, mmCP_DFY_DATA_0 }, - { 0xc4df0388, mmCP_DFY_DATA_0 }, - { 0xc4d7038c, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d5dc01a, mmCP_DFY_DATA_0 }, - { 0xc4e30390, mmCP_DFY_DATA_0 }, - { 0xc4d70394, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d62001a, mmCP_DFY_DATA_0 }, - { 0xc4e70398, mmCP_DFY_DATA_0 }, - { 0xc4d7039c, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d66401a, mmCP_DFY_DATA_0 }, - { 0xc4eb03a0, mmCP_DFY_DATA_0 }, - { 0xc4d703a4, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d6a801a, mmCP_DFY_DATA_0 }, - { 0xc4ef03a8, mmCP_DFY_DATA_0 }, - { 0xc4d703ac, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d6ec01a, mmCP_DFY_DATA_0 }, - { 0xc4f303b0, mmCP_DFY_DATA_0 }, - { 0xc4d703b4, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d73001a, mmCP_DFY_DATA_0 }, - { 0xc4f703b8, mmCP_DFY_DATA_0 }, - { 0xc4d703bc, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d77401a, mmCP_DFY_DATA_0 }, - { 0xc4fb03c0, mmCP_DFY_DATA_0 }, - { 0xc4d703c4, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d7b801a, mmCP_DFY_DATA_0 }, - { 0xc4ff03c8, mmCP_DFY_DATA_0 }, - { 0xc4d703cc, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d7fc01a, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0xcc800013, mmCP_DFY_DATA_0 }, - { 0xc4d70380, mmCP_DFY_DATA_0 }, - { 0xc4080001, mmCP_DFY_DATA_0 }, - { 0x1c88001c, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0xc40c0083, mmCP_DFY_DATA_0 }, - { 0x94c00010, mmCP_DFY_DATA_0 }, - { 0xdc0e0000, mmCP_DFY_DATA_0 }, - { 0x94c0000e, mmCP_DFY_DATA_0 }, - { 0xc40c0082, mmCP_DFY_DATA_0 }, - { 0x24d00001, mmCP_DFY_DATA_0 }, - { 0x9900000b, mmCP_DFY_DATA_0 }, - { 0x18cc01e3, mmCP_DFY_DATA_0 }, - { 0x3cd00004, mmCP_DFY_DATA_0 }, - { 0x95000008, mmCP_DFY_DATA_0 }, - { 0xc40c0085, mmCP_DFY_DATA_0 }, - { 0x18cc006a, mmCP_DFY_DATA_0 }, - { 0x98c00005, mmCP_DFY_DATA_0 }, - { 0xc40c0082, mmCP_DFY_DATA_0 }, - { 0x18cc01e3, mmCP_DFY_DATA_0 }, - { 0x3cd00004, mmCP_DFY_DATA_0 }, - { 0x9900fffa, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0xcc800004, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4080001, mmCP_DFY_DATA_0 }, - { 0x1c88001c, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0xcc800004, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400051, mmCP_DFY_DATA_0 }, - { 0xc428000c, mmCP_DFY_DATA_0 }, - { 0x04180018, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a80001f, mmCP_DFY_DATA_0 }, - { 0x9a40001e, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4293265, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x1aac0027, mmCP_DFY_DATA_0 }, - { 0x2aa80080, mmCP_DFY_DATA_0 }, - { 0xce813265, mmCP_DFY_DATA_0 }, - { 0x9ac00017, mmCP_DFY_DATA_0 }, - { 0xd80002f1, mmCP_DFY_DATA_0 }, - { 0x04080002, mmCP_DFY_DATA_0 }, - { 0x08880001, mmCP_DFY_DATA_0 }, - { 0xd8080250, mmCP_DFY_DATA_0 }, - { 0xd8080258, mmCP_DFY_DATA_0 }, - { 0xd8080230, mmCP_DFY_DATA_0 }, - { 0xd8080238, mmCP_DFY_DATA_0 }, - { 0xd8080240, mmCP_DFY_DATA_0 }, - { 0xd8080248, mmCP_DFY_DATA_0 }, - { 0xd8080268, mmCP_DFY_DATA_0 }, - { 0xd8080270, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0xd8080228, mmCP_DFY_DATA_0 }, - { 0xd8000367, mmCP_DFY_DATA_0 }, - { 0x9880fff3, mmCP_DFY_DATA_0 }, - { 0x04080010, mmCP_DFY_DATA_0 }, - { 0x08880001, mmCP_DFY_DATA_0 }, - { 0xd80c0309, mmCP_DFY_DATA_0 }, - { 0xd80c0319, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x9880fffc, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc00e0100, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8000016e, mmCP_DFY_DATA_0 }, - { 0xc4180032, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x95800001, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d0003f, mmCP_DFY_DATA_0 }, - { 0x24d4001f, mmCP_DFY_DATA_0 }, - { 0x24d80001, mmCP_DFY_DATA_0 }, - { 0x155c0001, mmCP_DFY_DATA_0 }, - { 0x05e80180, mmCP_DFY_DATA_0 }, - { 0x9900000b, mmCP_DFY_DATA_0 }, - { 0x202c003d, mmCP_DFY_DATA_0 }, - { 0xcd800010, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0xc42d325b, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0x80000bfc, mmCP_DFY_DATA_0 }, - { 0x800012e9, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xc410001b, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0xd8000031, mmCP_DFY_DATA_0 }, - { 0x9900091a, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x24d000ff, mmCP_DFY_DATA_0 }, - { 0x05280196, mmCP_DFY_DATA_0 }, - { 0x18d4fe04, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x800001b4, mmCP_DFY_DATA_0 }, - { 0x8000032b, mmCP_DFY_DATA_0 }, - { 0x80000350, mmCP_DFY_DATA_0 }, - { 0x80000352, mmCP_DFY_DATA_0 }, - { 0x8000035f, mmCP_DFY_DATA_0 }, - { 0x80000701, mmCP_DFY_DATA_0 }, - { 0x8000047c, mmCP_DFY_DATA_0 }, - { 0x8000019f, mmCP_DFY_DATA_0 }, - { 0x80000800, mmCP_DFY_DATA_0 }, - { 0xc419325b, mmCP_DFY_DATA_0 }, - { 0x1d98001f, mmCP_DFY_DATA_0 }, - { 0xcd81325b, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0xc4140004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04100002, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0002, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0xc43c0044, mmCP_DFY_DATA_0 }, - { 0x27fc0003, mmCP_DFY_DATA_0 }, - { 0x9bc00002, mmCP_DFY_DATA_0 }, - { 0x97c00006, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x7d40c001, mmCP_DFY_DATA_0 }, - { 0xd8400028, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xd9400036, mmCP_DFY_DATA_0 }, - { 0xc4193256, mmCP_DFY_DATA_0 }, - { 0xc41d3254, mmCP_DFY_DATA_0 }, - { 0x15540008, mmCP_DFY_DATA_0 }, - { 0xcd400009, mmCP_DFY_DATA_0 }, - { 0xcd40005b, mmCP_DFY_DATA_0 }, - { 0xcd40005e, mmCP_DFY_DATA_0 }, - { 0xcd40005d, mmCP_DFY_DATA_0 }, - { 0xd840006d, mmCP_DFY_DATA_0 }, - { 0xc421325a, mmCP_DFY_DATA_0 }, - { 0xc42d3249, mmCP_DFY_DATA_0 }, - { 0x11540015, mmCP_DFY_DATA_0 }, - { 0x19a4003c, mmCP_DFY_DATA_0 }, - { 0x1998003f, mmCP_DFY_DATA_0 }, - { 0x1af0007d, mmCP_DFY_DATA_0 }, - { 0x11dc000b, mmCP_DFY_DATA_0 }, - { 0x1264001f, mmCP_DFY_DATA_0 }, - { 0x15dc000d, mmCP_DFY_DATA_0 }, - { 0x7d65400a, mmCP_DFY_DATA_0 }, - { 0x13300018, mmCP_DFY_DATA_0 }, - { 0x1a38003f, mmCP_DFY_DATA_0 }, - { 0x7dd5c00a, mmCP_DFY_DATA_0 }, - { 0x7df1c00a, mmCP_DFY_DATA_0 }, - { 0xcd800045, mmCP_DFY_DATA_0 }, - { 0xcdc00100, mmCP_DFY_DATA_0 }, - { 0xc411326a, mmCP_DFY_DATA_0 }, - { 0xc415326b, mmCP_DFY_DATA_0 }, - { 0xc419326c, mmCP_DFY_DATA_0 }, - { 0xc41d326d, mmCP_DFY_DATA_0 }, - { 0xc425326e, mmCP_DFY_DATA_0 }, - { 0xc4293279, mmCP_DFY_DATA_0 }, - { 0xce800077, mmCP_DFY_DATA_0 }, - { 0xcd000056, mmCP_DFY_DATA_0 }, - { 0xcd400057, mmCP_DFY_DATA_0 }, - { 0xcd800058, mmCP_DFY_DATA_0 }, - { 0xcdc00059, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x259c8000, mmCP_DFY_DATA_0 }, - { 0x99c00004, mmCP_DFY_DATA_0 }, - { 0xce40005a, mmCP_DFY_DATA_0 }, - { 0x29988000, mmCP_DFY_DATA_0 }, - { 0xcd813265, mmCP_DFY_DATA_0 }, - { 0xc4113248, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0xcd000073, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0xc411326f, mmCP_DFY_DATA_0 }, - { 0x17300019, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x25140fff, mmCP_DFY_DATA_0 }, - { 0x95400007, mmCP_DFY_DATA_0 }, - { 0xd800003a, mmCP_DFY_DATA_0 }, - { 0x8c001b6d, mmCP_DFY_DATA_0 }, - { 0xc4153279, mmCP_DFY_DATA_0 }, - { 0xcd400077, mmCP_DFY_DATA_0 }, - { 0xcd00005f, mmCP_DFY_DATA_0 }, - { 0xd8000075, mmCP_DFY_DATA_0 }, - { 0x26f00001, mmCP_DFY_DATA_0 }, - { 0x15100010, mmCP_DFY_DATA_0 }, - { 0x7d190004, mmCP_DFY_DATA_0 }, - { 0xcd000035, mmCP_DFY_DATA_0 }, - { 0x97000035, mmCP_DFY_DATA_0 }, - { 0x1af07fe8, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcf00000d, mmCP_DFY_DATA_0 }, - { 0xcf00000a, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x04340022, mmCP_DFY_DATA_0 }, - { 0x07740001, mmCP_DFY_DATA_0 }, - { 0x04300010, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0xd4412e01, mmCP_DFY_DATA_0 }, - { 0x0434001e, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xdf030000, mmCP_DFY_DATA_0 }, - { 0xd4412e40, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc41c030, mmCP_DFY_DATA_0 }, - { 0xcc41c031, mmCP_DFY_DATA_0 }, - { 0xc43dc031, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x04343000, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0xcf413267, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7dd1c01a, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0x45dc0160, mmCP_DFY_DATA_0 }, - { 0xc810001f, mmCP_DFY_DATA_0 }, - { 0x1b4c0057, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x7f4f400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x55180020, mmCP_DFY_DATA_0 }, - { 0x2198003f, mmCP_DFY_DATA_0 }, - { 0xd1c00025, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xcd000026, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9bc00001, mmCP_DFY_DATA_0 }, - { 0x248dfffe, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xccc12e00, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x1af4007d, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0x33740003, mmCP_DFY_DATA_0 }, - { 0x26d80001, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x1ae8003e, mmCP_DFY_DATA_0 }, - { 0x9680000c, mmCP_DFY_DATA_0 }, - { 0xc4253277, mmCP_DFY_DATA_0 }, - { 0x26680001, mmCP_DFY_DATA_0 }, - { 0x96800009, mmCP_DFY_DATA_0 }, - { 0x2a640002, mmCP_DFY_DATA_0 }, - { 0xce413277, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc4253348, mmCP_DFY_DATA_0 }, - { 0xce413348, mmCP_DFY_DATA_0 }, - { 0xc4253348, mmCP_DFY_DATA_0 }, - { 0x96400001, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9b400003, mmCP_DFY_DATA_0 }, - { 0x958000d8, mmCP_DFY_DATA_0 }, - { 0x80000315, mmCP_DFY_DATA_0 }, - { 0xc4253277, mmCP_DFY_DATA_0 }, - { 0x04303000, mmCP_DFY_DATA_0 }, - { 0x26680001, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x96800041, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x1714000c, mmCP_DFY_DATA_0 }, - { 0x25540800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x459801b0, mmCP_DFY_DATA_0 }, - { 0x7d77400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x04240010, mmCP_DFY_DATA_0 }, - { 0x199c01e2, mmCP_DFY_DATA_0 }, - { 0x7e5e4002, mmCP_DFY_DATA_0 }, - { 0x3e5c0004, mmCP_DFY_DATA_0 }, - { 0x3e540002, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0x95c00006, mmCP_DFY_DATA_0 }, - { 0xc80c0011, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x54d00020, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0x80000282, mmCP_DFY_DATA_0 }, - { 0x95400015, mmCP_DFY_DATA_0 }, - { 0xc80c0011, mmCP_DFY_DATA_0 }, - { 0x0a640002, mmCP_DFY_DATA_0 }, - { 0x041c0001, mmCP_DFY_DATA_0 }, - { 0x45980008, mmCP_DFY_DATA_0 }, - { 0x54d00020, mmCP_DFY_DATA_0 }, - { 0x96400004, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0x041c0000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0x99c00003, mmCP_DFY_DATA_0 }, - { 0xc8180011, mmCP_DFY_DATA_0 }, - { 0x80000282, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0x80000282, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xc80c0011, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1334e, mmCP_DFY_DATA_0 }, - { 0xcd01334f, mmCP_DFY_DATA_0 }, - { 0xcd413350, mmCP_DFY_DATA_0 }, - { 0xcd813351, mmCP_DFY_DATA_0 }, - { 0xd881334d, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4193273, mmCP_DFY_DATA_0 }, - { 0xc41d3275, mmCP_DFY_DATA_0 }, - { 0xc40d3271, mmCP_DFY_DATA_0 }, - { 0xc4113270, mmCP_DFY_DATA_0 }, - { 0xc4153274, mmCP_DFY_DATA_0 }, - { 0x50cc0020, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0x7cdcc011, mmCP_DFY_DATA_0 }, - { 0x05900008, mmCP_DFY_DATA_0 }, - { 0xcd00006a, mmCP_DFY_DATA_0 }, - { 0xcdc0006b, mmCP_DFY_DATA_0 }, - { 0xc41d3272, mmCP_DFY_DATA_0 }, - { 0x7d594002, mmCP_DFY_DATA_0 }, - { 0x54d00020, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xccc12e23, mmCP_DFY_DATA_0 }, - { 0xcd012e24, mmCP_DFY_DATA_0 }, - { 0xcdc12e25, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x15540002, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x1b340057, mmCP_DFY_DATA_0 }, - { 0x1b280213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x45980198, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x7f2b000a, mmCP_DFY_DATA_0 }, - { 0x55e40020, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcd40000d, mmCP_DFY_DATA_0 }, - { 0xcd40000a, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x20cc003c, mmCP_DFY_DATA_0 }, - { 0xccc13249, mmCP_DFY_DATA_0 }, - { 0xc4113274, mmCP_DFY_DATA_0 }, - { 0xdd430000, mmCP_DFY_DATA_0 }, - { 0xc01e0001, mmCP_DFY_DATA_0 }, - { 0x29dc0002, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0xd8000036, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0x2d540002, mmCP_DFY_DATA_0 }, - { 0x95400022, mmCP_DFY_DATA_0 }, - { 0x078c0000, mmCP_DFY_DATA_0 }, - { 0x07d40000, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001239, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x04f80000, mmCP_DFY_DATA_0 }, - { 0x057c0000, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc414000d, mmCP_DFY_DATA_0 }, - { 0xc41c0019, mmCP_DFY_DATA_0 }, - { 0x7dd5c005, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0xd840007c, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0xd8400069, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c018a6, mmCP_DFY_DATA_0 }, - { 0xd4412e22, mmCP_DFY_DATA_0 }, - { 0xd800007c, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c018a2, mmCP_DFY_DATA_0 }, - { 0x95c00007, mmCP_DFY_DATA_0 }, - { 0xc40c0019, mmCP_DFY_DATA_0 }, - { 0x7cd4c005, mmCP_DFY_DATA_0 }, - { 0x24cc0001, mmCP_DFY_DATA_0 }, - { 0x94c00008, mmCP_DFY_DATA_0 }, - { 0x9680fffc, mmCP_DFY_DATA_0 }, - { 0x800002e3, mmCP_DFY_DATA_0 }, - { 0xc40c0057, mmCP_DFY_DATA_0 }, - { 0x7cd0c002, mmCP_DFY_DATA_0 }, - { 0x94c00003, mmCP_DFY_DATA_0 }, - { 0x9680fffd, mmCP_DFY_DATA_0 }, - { 0x800002e3, mmCP_DFY_DATA_0 }, - { 0xd8000069, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcd013273, mmCP_DFY_DATA_0 }, - { 0xcd013275, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc414005e, mmCP_DFY_DATA_0 }, - { 0x9540188f, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0xc013cfff, mmCP_DFY_DATA_0 }, - { 0x7cd0c009, mmCP_DFY_DATA_0 }, - { 0xccc13249, mmCP_DFY_DATA_0 }, - { 0x9680000b, mmCP_DFY_DATA_0 }, - { 0xc40c0077, mmCP_DFY_DATA_0 }, - { 0x38d00001, mmCP_DFY_DATA_0 }, - { 0x99000006, mmCP_DFY_DATA_0 }, - { 0x04cc0002, mmCP_DFY_DATA_0 }, - { 0xdcc30000, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01882, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd800000d, mmCP_DFY_DATA_0 }, - { 0x80000304, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0xd840002f, mmCP_DFY_DATA_0 }, - { 0xc41c0015, mmCP_DFY_DATA_0 }, - { 0x95c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400030, mmCP_DFY_DATA_0 }, - { 0xc41c0016, mmCP_DFY_DATA_0 }, - { 0x95c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8000030, mmCP_DFY_DATA_0 }, - { 0xc41c0016, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xd800002f, mmCP_DFY_DATA_0 }, - { 0xc41c0015, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x49980198, mmCP_DFY_DATA_0 }, - { 0x55e40020, mmCP_DFY_DATA_0 }, - { 0x459801a0, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x04302000, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x96800004, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0xd8000036, mmCP_DFY_DATA_0 }, - { 0x80000329, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcc812e00, mmCP_DFY_DATA_0 }, - { 0x04302000, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0xc4193256, mmCP_DFY_DATA_0 }, - { 0xc42d3249, mmCP_DFY_DATA_0 }, - { 0x16ec001f, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x1998003e, mmCP_DFY_DATA_0 }, - { 0xcec00031, mmCP_DFY_DATA_0 }, - { 0xd8000036, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0x97800004, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xce00000a, mmCP_DFY_DATA_0 }, - { 0x1a18003e, mmCP_DFY_DATA_0 }, - { 0xcd800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0x7d43c001, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4093249, mmCP_DFY_DATA_0 }, - { 0x1888003e, mmCP_DFY_DATA_0 }, - { 0x94800015, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0xc419324c, mmCP_DFY_DATA_0 }, - { 0x259c0001, mmCP_DFY_DATA_0 }, - { 0x1598001f, mmCP_DFY_DATA_0 }, - { 0x95c0000d, mmCP_DFY_DATA_0 }, - { 0x9580000c, mmCP_DFY_DATA_0 }, - { 0x99000003, mmCP_DFY_DATA_0 }, - { 0xd8400036, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14d80011, mmCP_DFY_DATA_0 }, - { 0x24dc00ff, mmCP_DFY_DATA_0 }, - { 0x31e00002, mmCP_DFY_DATA_0 }, - { 0x31dc0003, mmCP_DFY_DATA_0 }, - { 0x9580fff0, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0x99c00002, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0x94800004, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95801827, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8800036, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8c00036, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xc4180014, mmCP_DFY_DATA_0 }, - { 0x9580ffff, mmCP_DFY_DATA_0 }, - { 0xd840002f, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14dc0011, mmCP_DFY_DATA_0 }, - { 0x95c0fffe, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd800006d, mmCP_DFY_DATA_0 }, - { 0xc41d3246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51dc0020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0xd8400028, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc420000b, mmCP_DFY_DATA_0 }, - { 0x32200002, mmCP_DFY_DATA_0 }, - { 0x9a0000ad, mmCP_DFY_DATA_0 }, - { 0x04200032, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0xde030000, mmCP_DFY_DATA_0 }, - { 0xd8400033, mmCP_DFY_DATA_0 }, - { 0x04080000, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0002, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xc42c0015, mmCP_DFY_DATA_0 }, - { 0x96c0ffff, mmCP_DFY_DATA_0 }, - { 0xd800002e, mmCP_DFY_DATA_0 }, - { 0xc42d3249, mmCP_DFY_DATA_0 }, - { 0x1af4003e, mmCP_DFY_DATA_0 }, - { 0x9740004d, mmCP_DFY_DATA_0 }, - { 0xc428000d, mmCP_DFY_DATA_0 }, - { 0xc4080060, mmCP_DFY_DATA_0 }, - { 0x7ca88005, mmCP_DFY_DATA_0 }, - { 0x24880001, mmCP_DFY_DATA_0 }, - { 0x7f4b4009, mmCP_DFY_DATA_0 }, - { 0x97400046, mmCP_DFY_DATA_0 }, - { 0xc4313274, mmCP_DFY_DATA_0 }, - { 0xc4100057, mmCP_DFY_DATA_0 }, - { 0x7d33400c, mmCP_DFY_DATA_0 }, - { 0x97400009, mmCP_DFY_DATA_0 }, - { 0x28240100, mmCP_DFY_DATA_0 }, - { 0x7e6a4004, mmCP_DFY_DATA_0 }, - { 0xce400079, mmCP_DFY_DATA_0 }, - { 0x1eecffdd, mmCP_DFY_DATA_0 }, - { 0xcec13249, mmCP_DFY_DATA_0 }, - { 0xcf013273, mmCP_DFY_DATA_0 }, - { 0xcf013275, mmCP_DFY_DATA_0 }, - { 0x800003c3, mmCP_DFY_DATA_0 }, - { 0xc429326f, mmCP_DFY_DATA_0 }, - { 0x1aa80030, mmCP_DFY_DATA_0 }, - { 0x96800006, mmCP_DFY_DATA_0 }, - { 0x28240001, mmCP_DFY_DATA_0 }, - { 0xc428000d, mmCP_DFY_DATA_0 }, - { 0x06a80008, mmCP_DFY_DATA_0 }, - { 0x7e6a8004, mmCP_DFY_DATA_0 }, - { 0xce800035, mmCP_DFY_DATA_0 }, - { 0xc41d3272, mmCP_DFY_DATA_0 }, - { 0x25cc0001, mmCP_DFY_DATA_0 }, - { 0x10cc0004, mmCP_DFY_DATA_0 }, - { 0x19e80042, mmCP_DFY_DATA_0 }, - { 0x25dc0006, mmCP_DFY_DATA_0 }, - { 0x11dc0001, mmCP_DFY_DATA_0 }, - { 0x7e8e800a, mmCP_DFY_DATA_0 }, - { 0x7de9c00a, mmCP_DFY_DATA_0 }, - { 0xc40d3271, mmCP_DFY_DATA_0 }, - { 0xc4293270, mmCP_DFY_DATA_0 }, - { 0x50cc0020, mmCP_DFY_DATA_0 }, - { 0x7ce8c01a, mmCP_DFY_DATA_0 }, - { 0x7cd30011, mmCP_DFY_DATA_0 }, - { 0x11e80007, mmCP_DFY_DATA_0 }, - { 0x2aa80000, mmCP_DFY_DATA_0 }, - { 0xce80001c, mmCP_DFY_DATA_0 }, - { 0xd300001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x1b30003f, mmCP_DFY_DATA_0 }, - { 0x33300000, mmCP_DFY_DATA_0 }, - { 0xc4240059, mmCP_DFY_DATA_0 }, - { 0x1660001f, mmCP_DFY_DATA_0 }, - { 0x7e320009, mmCP_DFY_DATA_0 }, - { 0xc0328000, mmCP_DFY_DATA_0 }, - { 0x7e72400a, mmCP_DFY_DATA_0 }, - { 0x0430000c, mmCP_DFY_DATA_0 }, - { 0x9a000002, mmCP_DFY_DATA_0 }, - { 0x04300008, mmCP_DFY_DATA_0 }, - { 0xc02ac000, mmCP_DFY_DATA_0 }, - { 0x7d310002, mmCP_DFY_DATA_0 }, - { 0x17300002, mmCP_DFY_DATA_0 }, - { 0x2aa87600, mmCP_DFY_DATA_0 }, - { 0x7cd0c011, mmCP_DFY_DATA_0 }, - { 0xcdc00024, mmCP_DFY_DATA_0 }, - { 0xd0c00025, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0x04280222, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc4280058, mmCP_DFY_DATA_0 }, - { 0x22ec003d, mmCP_DFY_DATA_0 }, - { 0xcec13249, mmCP_DFY_DATA_0 }, - { 0xcd013273, mmCP_DFY_DATA_0 }, - { 0xce813275, mmCP_DFY_DATA_0 }, - { 0xd800007b, mmCP_DFY_DATA_0 }, - { 0xc8380018, mmCP_DFY_DATA_0 }, - { 0x57b00020, mmCP_DFY_DATA_0 }, - { 0x04343108, mmCP_DFY_DATA_0 }, - { 0xc429325d, mmCP_DFY_DATA_0 }, - { 0x040c3000, mmCP_DFY_DATA_0 }, - { 0x13740008, mmCP_DFY_DATA_0 }, - { 0x2374007e, mmCP_DFY_DATA_0 }, - { 0x32a80003, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x18ec0057, mmCP_DFY_DATA_0 }, - { 0x18e40213, mmCP_DFY_DATA_0 }, - { 0x18cc0199, mmCP_DFY_DATA_0 }, - { 0x7cecc00a, mmCP_DFY_DATA_0 }, - { 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { 0x94800003, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x800003e7, mmCP_DFY_DATA_0 }, - { 0x04200022, mmCP_DFY_DATA_0 }, - { 0xde030000, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x04200010, mmCP_DFY_DATA_0 }, - { 0xde030000, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0x45980104, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xcf800026, mmCP_DFY_DATA_0 }, - { 0xcf000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x49980104, mmCP_DFY_DATA_0 }, - { 0x9a80000a, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x45980168, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x800003f2, mmCP_DFY_DATA_0 }, - { 0x8c000448, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x040c2000, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0xd8400030, mmCP_DFY_DATA_0 }, - { 0xc42c0016, mmCP_DFY_DATA_0 }, - { 0x96c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8000030, mmCP_DFY_DATA_0 }, - { 0xc42c0016, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xd800002f, mmCP_DFY_DATA_0 }, - { 0xc42c0015, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400034, mmCP_DFY_DATA_0 }, - { 0xc4300025, mmCP_DFY_DATA_0 }, - { 0xc4340024, mmCP_DFY_DATA_0 }, - { 0xc4380081, mmCP_DFY_DATA_0 }, - { 0xcf813279, mmCP_DFY_DATA_0 }, - { 0xcf41326e, mmCP_DFY_DATA_0 }, - { 0xcf01326d, mmCP_DFY_DATA_0 }, - { 0x94c0000d, mmCP_DFY_DATA_0 }, - { 0x254c0700, mmCP_DFY_DATA_0 }, - { 0xc424001e, mmCP_DFY_DATA_0 }, - { 0x10cc0010, mmCP_DFY_DATA_0 }, - { 0x1a641fe8, mmCP_DFY_DATA_0 }, - { 0x28cc0726, mmCP_DFY_DATA_0 }, - { 0x2a640200, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1237b, mmCP_DFY_DATA_0 }, - { 0x2264003f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8813260, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0xc4240033, mmCP_DFY_DATA_0 }, - { 0xc4280034, mmCP_DFY_DATA_0 }, - { 0xd9000036, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x96400006, mmCP_DFY_DATA_0 }, - { 0xde430000, mmCP_DFY_DATA_0 }, - { 0xce40000c, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01755, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x9680000a, mmCP_DFY_DATA_0 }, - { 0xce80000a, mmCP_DFY_DATA_0 }, - { 0x06a80002, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xde830000, mmCP_DFY_DATA_0 }, - { 0xce80000d, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c0174c, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xc4393265, mmCP_DFY_DATA_0 }, - { 0x2bb80040, mmCP_DFY_DATA_0 }, - { 0xd8400032, mmCP_DFY_DATA_0 }, - { 0xcf813265, mmCP_DFY_DATA_0 }, - { 0xc4200012, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xc4100044, mmCP_DFY_DATA_0 }, - { 0x19180024, mmCP_DFY_DATA_0 }, - { 0xc8100072, mmCP_DFY_DATA_0 }, - { 0x551c003f, mmCP_DFY_DATA_0 }, - { 0x99c00003, mmCP_DFY_DATA_0 }, - { 0x95800010, mmCP_DFY_DATA_0 }, - { 0x8000043d, mmCP_DFY_DATA_0 }, - { 0xc00c8000, mmCP_DFY_DATA_0 }, - { 0xd840006c, mmCP_DFY_DATA_0 }, - { 0x28200000, mmCP_DFY_DATA_0 }, - { 0x8000043f, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0x282000f0, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc4113255, mmCP_DFY_DATA_0 }, - { 0xcd01324f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0xce000053, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x195c00e8, mmCP_DFY_DATA_0 }, - { 0xc4100004, mmCP_DFY_DATA_0 }, - { 0x2555fff0, mmCP_DFY_DATA_0 }, - { 0xc0360001, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0x29540001, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0x04280004, mmCP_DFY_DATA_0 }, - { 0xc420000b, mmCP_DFY_DATA_0 }, - { 0x32200002, mmCP_DFY_DATA_0 }, - { 0x9a000009, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0xc5e124dc, mmCP_DFY_DATA_0 }, - { 0x0aa80001, mmCP_DFY_DATA_0 }, - { 0x7ef6c001, mmCP_DFY_DATA_0 }, - { 0x7e624001, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0x9a80fff9, mmCP_DFY_DATA_0 }, - { 0xc02ee000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x2555fff0, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0xc42d3255, mmCP_DFY_DATA_0 }, - { 0xc4353259, mmCP_DFY_DATA_0 }, - { 0xd8013260, mmCP_DFY_DATA_0 }, - { 0x45980158, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x49980158, mmCP_DFY_DATA_0 }, - { 0x45980170, mmCP_DFY_DATA_0 }, - { 0xc4200012, mmCP_DFY_DATA_0 }, - { 0x16200010, mmCP_DFY_DATA_0 }, - { 0x9a00fffe, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xc429324f, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcd000008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x7d43c001, mmCP_DFY_DATA_0 }, - { 0x195400e8, mmCP_DFY_DATA_0 }, - { 0x1154000a, mmCP_DFY_DATA_0 }, - { 0x18dc00e8, mmCP_DFY_DATA_0 }, - { 0x05e80488, mmCP_DFY_DATA_0 }, - { 0x18d0006c, mmCP_DFY_DATA_0 }, - { 0x18f807f0, mmCP_DFY_DATA_0 }, - { 0x18e40077, mmCP_DFY_DATA_0 }, - { 0x18ec0199, mmCP_DFY_DATA_0 }, - { 0x7e6e400a, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000048e, mmCP_DFY_DATA_0 }, - { 0x80000494, mmCP_DFY_DATA_0 }, - { 0x800004de, mmCP_DFY_DATA_0 }, - { 0x80000685, mmCP_DFY_DATA_0 }, - { 0x80000686, mmCP_DFY_DATA_0 }, - { 0x800006ac, mmCP_DFY_DATA_0 }, - { 0x1ccc001f, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4293254, mmCP_DFY_DATA_0 }, - { 0x1264000a, mmCP_DFY_DATA_0 }, - { 0xc4300004, mmCP_DFY_DATA_0 }, - { 0x7d79400a, mmCP_DFY_DATA_0 }, - { 0x7e7a400a, mmCP_DFY_DATA_0 }, - { 0x52a8001e, mmCP_DFY_DATA_0 }, - { 0x15180001, mmCP_DFY_DATA_0 }, - { 0x7d69401a, mmCP_DFY_DATA_0 }, - { 0x202c007d, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x95000008, mmCP_DFY_DATA_0 }, - { 0x95800028, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x1aec0028, mmCP_DFY_DATA_0 }, - { 0xc40d325c, mmCP_DFY_DATA_0 }, - { 0x800004cc, mmCP_DFY_DATA_0 }, - { 0xc42d3256, mmCP_DFY_DATA_0 }, - { 0xc419324e, mmCP_DFY_DATA_0 }, - { 0x26e8003f, mmCP_DFY_DATA_0 }, - { 0x1aec003e, mmCP_DFY_DATA_0 }, - { 0x12f4000e, mmCP_DFY_DATA_0 }, - { 0xc41d324d, mmCP_DFY_DATA_0 }, - { 0xc40d324f, mmCP_DFY_DATA_0 }, - { 0x7d75401a, mmCP_DFY_DATA_0 }, - { 0x04100002, mmCP_DFY_DATA_0 }, - { 0x7d290004, mmCP_DFY_DATA_0 }, - { 0x7f8f4001, mmCP_DFY_DATA_0 }, - { 0x7f52800f, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x50e00002, mmCP_DFY_DATA_0 }, - { 0x51980008, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x800004d1, mmCP_DFY_DATA_0 }, - { 0x7d0dc002, mmCP_DFY_DATA_0 }, - { 0x6665fc00, mmCP_DFY_DATA_0 }, - { 0x7e5e401a, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x7da1c011, mmCP_DFY_DATA_0 }, - { 0xd140000b, mmCP_DFY_DATA_0 }, - { 0xd1c00002, mmCP_DFY_DATA_0 }, - { 0x2a644000, mmCP_DFY_DATA_0 }, - { 0xce400002, mmCP_DFY_DATA_0 }, - { 0x7f534002, mmCP_DFY_DATA_0 }, - { 0x6665fc00, mmCP_DFY_DATA_0 }, - { 0x7e76401a, mmCP_DFY_DATA_0 }, - { 0xd1800002, mmCP_DFY_DATA_0 }, - { 0xce400002, mmCP_DFY_DATA_0 }, - { 0x800004d7, mmCP_DFY_DATA_0 }, - { 0xc42d325a, mmCP_DFY_DATA_0 }, - { 0xc4193258, mmCP_DFY_DATA_0 }, - { 0x1aec003e, mmCP_DFY_DATA_0 }, - { 0xc41d3257, mmCP_DFY_DATA_0 }, - { 0xc4213259, mmCP_DFY_DATA_0 }, - { 0x12f4000e, mmCP_DFY_DATA_0 }, - { 0x7d75401a, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x52200002, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x7da1c011, mmCP_DFY_DATA_0 }, - { 0xd140000b, mmCP_DFY_DATA_0 }, - { 0xd1c00002, mmCP_DFY_DATA_0 }, - { 0x2a644000, mmCP_DFY_DATA_0 }, - { 0xce400002, mmCP_DFY_DATA_0 }, - { 0x202c003d, mmCP_DFY_DATA_0 }, - { 0xcf000008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0xc42d325b, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4193260, mmCP_DFY_DATA_0 }, - { 0x259c0007, mmCP_DFY_DATA_0 }, - { 0x15980004, mmCP_DFY_DATA_0 }, - { 0x05e804e3, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x800004e7, mmCP_DFY_DATA_0 }, - { 0x800004f0, mmCP_DFY_DATA_0 }, - { 0x80000505, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc435325d, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0x277401ef, mmCP_DFY_DATA_0 }, - { 0xcf41325d, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0x9640fff4, mmCP_DFY_DATA_0 }, - { 0x17e00008, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xd84131db, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xcd800009, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc42d325b, mmCP_DFY_DATA_0 }, - { 0x1b301ff8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0x26edf000, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0xd8413260, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x05a80507, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000050c, mmCP_DFY_DATA_0 }, - { 0x80000528, mmCP_DFY_DATA_0 }, - { 0x8000057d, mmCP_DFY_DATA_0 }, - { 0x800005c2, mmCP_DFY_DATA_0 }, - { 0x800005f3, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9a400012, mmCP_DFY_DATA_0 }, - { 0x1bd400e8, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xcd40005e, mmCP_DFY_DATA_0 }, - { 0xc41c004d, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x99c0000c, mmCP_DFY_DATA_0 }, - { 0xc4100019, mmCP_DFY_DATA_0 }, - { 0x7d150005, mmCP_DFY_DATA_0 }, - { 0x25100001, mmCP_DFY_DATA_0 }, - { 0x99000008, mmCP_DFY_DATA_0 }, - { 0x8c00063b, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0x2511fffd, mmCP_DFY_DATA_0 }, - { 0xcd013277, mmCP_DFY_DATA_0 }, - { 0xd801326f, mmCP_DFY_DATA_0 }, - { 0x80000624, mmCP_DFY_DATA_0 }, - { 0x04240012, mmCP_DFY_DATA_0 }, - { 0x1be00fe4, mmCP_DFY_DATA_0 }, - { 0xce413260, mmCP_DFY_DATA_0 }, - { 0xce000066, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400068, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9a400013, mmCP_DFY_DATA_0 }, - { 0x1bd400e8, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xcd40005e, mmCP_DFY_DATA_0 }, - { 0xc41c004d, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x99c0000d, mmCP_DFY_DATA_0 }, - { 0xc4100019, mmCP_DFY_DATA_0 }, - { 0x7d150005, mmCP_DFY_DATA_0 }, - { 0x25100001, mmCP_DFY_DATA_0 }, - { 0x99000009, mmCP_DFY_DATA_0 }, - { 0xd8400067, mmCP_DFY_DATA_0 }, - { 0x8c00063b, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0x2511fffd, mmCP_DFY_DATA_0 }, - { 0xcd013277, mmCP_DFY_DATA_0 }, - { 0xd801326f, mmCP_DFY_DATA_0 }, - { 0x80000624, mmCP_DFY_DATA_0 }, - { 0x1bd400e8, mmCP_DFY_DATA_0 }, - { 0xc42c0060, mmCP_DFY_DATA_0 }, - { 0x7ed6c005, mmCP_DFY_DATA_0 }, - { 0x26ec0001, mmCP_DFY_DATA_0 }, - { 0xc4113271, mmCP_DFY_DATA_0 }, - { 0xc4153270, mmCP_DFY_DATA_0 }, - { 0xc4193272, mmCP_DFY_DATA_0 }, - { 0xc41d3273, mmCP_DFY_DATA_0 }, - { 0x04280022, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d51401a, mmCP_DFY_DATA_0 }, - { 0xc4113274, mmCP_DFY_DATA_0 }, - { 0xc4213275, mmCP_DFY_DATA_0 }, - { 0xc4253276, mmCP_DFY_DATA_0 }, - { 0xc4313248, mmCP_DFY_DATA_0 }, - { 0xd1400061, mmCP_DFY_DATA_0 }, - { 0x2730000f, mmCP_DFY_DATA_0 }, - { 0x13300010, mmCP_DFY_DATA_0 }, - { 0x7db1800a, mmCP_DFY_DATA_0 }, - { 0xcd800060, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0x05dc0008, mmCP_DFY_DATA_0 }, - { 0xcdc00062, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xcd000063, mmCP_DFY_DATA_0 }, - { 0xce000064, mmCP_DFY_DATA_0 }, - { 0xce400065, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0xce813260, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc820001f, mmCP_DFY_DATA_0 }, - { 0x1b700057, mmCP_DFY_DATA_0 }, - { 0x1b680213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x46ec0188, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0x17e00008, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x26e01000, mmCP_DFY_DATA_0 }, - { 0x9a00fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd9c131fc, mmCP_DFY_DATA_0 }, - { 0xcd800009, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0x29dc0001, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0x191807e4, mmCP_DFY_DATA_0 }, - { 0x192007ec, mmCP_DFY_DATA_0 }, - { 0x95400004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9580000e, mmCP_DFY_DATA_0 }, - { 0x09980001, mmCP_DFY_DATA_0 }, - { 0x041c0001, mmCP_DFY_DATA_0 }, - { 0x95800005, mmCP_DFY_DATA_0 }, - { 0x09980001, mmCP_DFY_DATA_0 }, - { 0x51dc0001, mmCP_DFY_DATA_0 }, - { 0x69dc0001, mmCP_DFY_DATA_0 }, - { 0x9980fffd, mmCP_DFY_DATA_0 }, - { 0x7de20014, mmCP_DFY_DATA_0 }, - { 0x561c0020, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xce013344, mmCP_DFY_DATA_0 }, - { 0xcdc13345, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x95400022, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425334d, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9640fffe, mmCP_DFY_DATA_0 }, - { 0xc419334e, mmCP_DFY_DATA_0 }, - { 0xc41d334f, mmCP_DFY_DATA_0 }, - { 0xc4213350, mmCP_DFY_DATA_0 }, - { 0xc4253351, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x1b680057, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x46ec01b0, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x04280032, mmCP_DFY_DATA_0 }, - { 0xce813260, mmCP_DFY_DATA_0 }, - { 0xd8800068, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x2010007d, mmCP_DFY_DATA_0 }, - { 0xcd01325b, mmCP_DFY_DATA_0 }, - { 0xc411325b, mmCP_DFY_DATA_0 }, - { 0x1910003e, mmCP_DFY_DATA_0 }, - { 0x9500fffe, mmCP_DFY_DATA_0 }, - { 0x04100040, mmCP_DFY_DATA_0 }, - { 0xcd00001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc410000f, mmCP_DFY_DATA_0 }, - { 0x9900ffff, mmCP_DFY_DATA_0 }, - { 0x04100060, mmCP_DFY_DATA_0 }, - { 0xcd00001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc410000f, mmCP_DFY_DATA_0 }, - { 0x9900ffff, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x2010003d, mmCP_DFY_DATA_0 }, - { 0xcd01325b, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0x191807e4, mmCP_DFY_DATA_0 }, - { 0x9540000b, mmCP_DFY_DATA_0 }, - { 0x2511fffd, mmCP_DFY_DATA_0 }, - { 0xcd013277, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x95800005, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8013344, mmCP_DFY_DATA_0 }, - { 0xd8013345, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4180050, mmCP_DFY_DATA_0 }, - { 0xc41c0052, mmCP_DFY_DATA_0 }, - { 0x04280042, mmCP_DFY_DATA_0 }, - { 0xcd813273, mmCP_DFY_DATA_0 }, - { 0xcdc13275, mmCP_DFY_DATA_0 }, - { 0xce813260, mmCP_DFY_DATA_0 }, - { 0xd9000068, mmCP_DFY_DATA_0 }, - { 0xd8400067, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x07d40000, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c00124f, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x057c0000, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x1b680057, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0xc820001f, mmCP_DFY_DATA_0 }, - { 0x46ec0190, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc4153249, mmCP_DFY_DATA_0 }, - { 0x2154003d, mmCP_DFY_DATA_0 }, - { 0xc41c0019, mmCP_DFY_DATA_0 }, - { 0x1bd800e8, mmCP_DFY_DATA_0 }, - { 0x7dd9c005, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xcd80005e, mmCP_DFY_DATA_0 }, - { 0xc420004d, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x11dc0010, mmCP_DFY_DATA_0 }, - { 0x7e1e000a, mmCP_DFY_DATA_0 }, - { 0xcd413249, mmCP_DFY_DATA_0 }, - { 0xce01326f, mmCP_DFY_DATA_0 }, - { 0x28340001, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7f598004, mmCP_DFY_DATA_0 }, - { 0xcd800035, mmCP_DFY_DATA_0 }, - { 0x1be800e8, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xce80005e, mmCP_DFY_DATA_0 }, - { 0xd801327a, mmCP_DFY_DATA_0 }, - { 0xd800005f, mmCP_DFY_DATA_0 }, - { 0xd8000075, mmCP_DFY_DATA_0 }, - { 0xd800007f, mmCP_DFY_DATA_0 }, - { 0xc424004c, mmCP_DFY_DATA_0 }, - { 0xce41326e, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x28240100, mmCP_DFY_DATA_0 }, - { 0x7e6a4004, mmCP_DFY_DATA_0 }, - { 0xce400079, mmCP_DFY_DATA_0 }, - { 0xc435325d, mmCP_DFY_DATA_0 }, - { 0x277401ef, mmCP_DFY_DATA_0 }, - { 0x04240020, mmCP_DFY_DATA_0 }, - { 0xce41325e, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xd8013260, mmCP_DFY_DATA_0 }, - { 0xcf41325d, mmCP_DFY_DATA_0 }, - { 0xda000068, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0x29dc0001, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0x9540002d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425334d, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9640fffe, mmCP_DFY_DATA_0 }, - { 0xc419334e, mmCP_DFY_DATA_0 }, - { 0xc41d334f, mmCP_DFY_DATA_0 }, - { 0xc4213350, mmCP_DFY_DATA_0 }, - { 0xc4253351, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x1b680057, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x46ec01b0, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc430000b, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0x9b000010, mmCP_DFY_DATA_0 }, - { 0x1be000e8, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0xc0360001, mmCP_DFY_DATA_0 }, - { 0x04280004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0xc63124dc, mmCP_DFY_DATA_0 }, - { 0x0aa80001, mmCP_DFY_DATA_0 }, - { 0x7ef6c001, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x9a80fff9, mmCP_DFY_DATA_0 }, - { 0xc02ee000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4253260, mmCP_DFY_DATA_0 }, - { 0x7fc14001, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x98c00005, mmCP_DFY_DATA_0 }, - { 0x194c1c03, mmCP_DFY_DATA_0 }, - { 0xccc0003b, mmCP_DFY_DATA_0 }, - { 0xc40c002d, mmCP_DFY_DATA_0 }, - { 0x80000697, mmCP_DFY_DATA_0 }, - { 0xc420004a, mmCP_DFY_DATA_0 }, - { 0x194c00e8, mmCP_DFY_DATA_0 }, - { 0xccc0005e, mmCP_DFY_DATA_0 }, - { 0xc40c004c, mmCP_DFY_DATA_0 }, - { 0xc431326d, mmCP_DFY_DATA_0 }, - { 0x27301fff, mmCP_DFY_DATA_0 }, - { 0xce00005e, mmCP_DFY_DATA_0 }, - { 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c00008, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0x1b301ff8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x25100007, mmCP_DFY_DATA_0 }, - { 0x31100005, mmCP_DFY_DATA_0 }, - { 0x9900008e, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x8000075e, mmCP_DFY_DATA_0 }, - { 0x202c007d, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0xc4293265, mmCP_DFY_DATA_0 }, - { 0xc4353254, mmCP_DFY_DATA_0 }, - { 0x26a9feff, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x1374000b, mmCP_DFY_DATA_0 }, - { 0xc40c000d, mmCP_DFY_DATA_0 }, - { 0xd8000009, mmCP_DFY_DATA_0 }, - { 0x1774000d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc41d30b8, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x95c00008, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xccc00009, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xce813265, mmCP_DFY_DATA_0 }, - { 0xcf400100, mmCP_DFY_DATA_0 }, - { 0xc00ac006, mmCP_DFY_DATA_0 }, - { 0xc00e0000, mmCP_DFY_DATA_0 }, - { 0x28880700, mmCP_DFY_DATA_0 }, - { 0x28cc0014, mmCP_DFY_DATA_0 }, - { 0x8c0006de, mmCP_DFY_DATA_0 }, - { 0x14cc0010, mmCP_DFY_DATA_0 }, - { 0x30d4000f, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x10cc0010, mmCP_DFY_DATA_0 }, - { 0x28cc0014, mmCP_DFY_DATA_0 }, - { 0x99400009, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc41530b8, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x19980028, mmCP_DFY_DATA_0 }, - { 0x99400003, mmCP_DFY_DATA_0 }, - { 0x99800002, mmCP_DFY_DATA_0 }, - { 0x800006c8, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x15600008, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xc8380023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x7fa38011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x282c2002, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0xcec00013, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x042c0008, mmCP_DFY_DATA_0 }, - { 0xd3800025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x202400d0, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0x28240006, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x9a800004, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x24d8003f, mmCP_DFY_DATA_0 }, - { 0xd840003c, mmCP_DFY_DATA_0 }, - { 0xcec0003a, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcd81a2a4, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc41d325d, mmCP_DFY_DATA_0 }, - { 0x25dc0007, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x94c0000a, mmCP_DFY_DATA_0 }, - { 0xc420004a, mmCP_DFY_DATA_0 }, - { 0x194c00e8, mmCP_DFY_DATA_0 }, - { 0xccc0005e, mmCP_DFY_DATA_0 }, - { 0xc40c004c, mmCP_DFY_DATA_0 }, - { 0xc431326d, mmCP_DFY_DATA_0 }, - { 0x27301fff, mmCP_DFY_DATA_0 }, - { 0xce00005e, mmCP_DFY_DATA_0 }, - { 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { 0x80000712, mmCP_DFY_DATA_0 }, - { 0x194c1c03, mmCP_DFY_DATA_0 }, - { 0xccc0003b, mmCP_DFY_DATA_0 }, - { 0xc40c002d, mmCP_DFY_DATA_0 }, - { 0x05e80714, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000071c, mmCP_DFY_DATA_0 }, - { 0x80000720, mmCP_DFY_DATA_0 }, - { 0x80000747, mmCP_DFY_DATA_0 }, - { 0x8000071d, mmCP_DFY_DATA_0 }, - { 0x800007c4, mmCP_DFY_DATA_0 }, - { 0x80000732, mmCP_DFY_DATA_0 }, - { 0x80000745, mmCP_DFY_DATA_0 }, - { 0x80000744, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x98c00006, mmCP_DFY_DATA_0 }, - { 0x8000072e, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c0000c, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4253265, mmCP_DFY_DATA_0 }, - { 0x2a64008c, mmCP_DFY_DATA_0 }, - { 0xce413265, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0x1b301fe8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0xd8013260, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0x8000075e, mmCP_DFY_DATA_0 }, - { 0x98c0fff1, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c00002, mmCP_DFY_DATA_0 }, - { 0x80000723, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc41f02f1, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0xd8013247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0x80000743, mmCP_DFY_DATA_0 }, - { 0xd8813247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0xc4100004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcd000008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0x98c0ffde, mmCP_DFY_DATA_0 }, - { 0x8000072e, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c00012, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x15600008, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd84131db, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0xcd800009, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0x1b301ff8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8413260, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x041c3000, mmCP_DFY_DATA_0 }, - { 0xcdc13267, mmCP_DFY_DATA_0 }, - { 0xc41d3267, mmCP_DFY_DATA_0 }, - { 0xc41d3265, mmCP_DFY_DATA_0 }, - { 0x25dc8000, mmCP_DFY_DATA_0 }, - { 0x95c00007, mmCP_DFY_DATA_0 }, - { 0xc41c004a, mmCP_DFY_DATA_0 }, - { 0x195800e8, mmCP_DFY_DATA_0 }, - { 0xcd80005e, mmCP_DFY_DATA_0 }, - { 0xc418004c, mmCP_DFY_DATA_0 }, - { 0xcd81326e, mmCP_DFY_DATA_0 }, - { 0xcdc0005e, mmCP_DFY_DATA_0 }, - { 0xc41d3265, mmCP_DFY_DATA_0 }, - { 0x25dd7fff, mmCP_DFY_DATA_0 }, - { 0xcdc13265, mmCP_DFY_DATA_0 }, - { 0xc41d3246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x51e00020, mmCP_DFY_DATA_0 }, - { 0x7e1a001a, mmCP_DFY_DATA_0 }, - { 0x46200200, mmCP_DFY_DATA_0 }, - { 0x04283247, mmCP_DFY_DATA_0 }, - { 0x04300033, mmCP_DFY_DATA_0 }, - { 0x1af80057, mmCP_DFY_DATA_0 }, - { 0x1af40213, mmCP_DFY_DATA_0 }, - { 0x042c000c, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f6f400a, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2000025, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xc6990000, mmCP_DFY_DATA_0 }, - { 0x329c325d, mmCP_DFY_DATA_0 }, - { 0x99c00008, mmCP_DFY_DATA_0 }, - { 0x329c3269, mmCP_DFY_DATA_0 }, - { 0x99c00006, mmCP_DFY_DATA_0 }, - { 0x329c3267, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0xc01defff, mmCP_DFY_DATA_0 }, - { 0x7d9d8009, mmCP_DFY_DATA_0 }, - { 0x8000078a, mmCP_DFY_DATA_0 }, - { 0x25980000, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0x9b00fff2, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc43c0012, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0xc03e7ff0, mmCP_DFY_DATA_0 }, - { 0x7f3f0009, mmCP_DFY_DATA_0 }, - { 0xcf01325a, mmCP_DFY_DATA_0 }, - { 0xc4313249, mmCP_DFY_DATA_0 }, - { 0x1f30001f, mmCP_DFY_DATA_0 }, - { 0xcf013249, mmCP_DFY_DATA_0 }, - { 0xc03e4000, mmCP_DFY_DATA_0 }, - { 0xcfc13254, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8013254, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0xd801324f, mmCP_DFY_DATA_0 }, - { 0xd8013255, mmCP_DFY_DATA_0 }, - { 0xd8013247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0x1b300028, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001219, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x9900000d, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0x9700000b, mmCP_DFY_DATA_0 }, - { 0xc43d30b5, mmCP_DFY_DATA_0 }, - { 0x1bf0003a, mmCP_DFY_DATA_0 }, - { 0x9b000b80, mmCP_DFY_DATA_0 }, - { 0x203c003a, mmCP_DFY_DATA_0 }, - { 0xc430000e, mmCP_DFY_DATA_0 }, - { 0x27300700, mmCP_DFY_DATA_0 }, - { 0x13300014, mmCP_DFY_DATA_0 }, - { 0x2b300001, mmCP_DFY_DATA_0 }, - { 0xcf0130b7, mmCP_DFY_DATA_0 }, - { 0xcfc130b5, mmCP_DFY_DATA_0 }, - { 0x46200008, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2000025, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0x9bc00001, mmCP_DFY_DATA_0 }, - { 0xccc00010, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4080007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0xc4193260, mmCP_DFY_DATA_0 }, - { 0x259c0003, mmCP_DFY_DATA_0 }, - { 0x31dc0003, mmCP_DFY_DATA_0 }, - { 0x95c00014, mmCP_DFY_DATA_0 }, - { 0x040c3000, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x18ec0057, mmCP_DFY_DATA_0 }, - { 0x18e40213, mmCP_DFY_DATA_0 }, - { 0x18cc0199, mmCP_DFY_DATA_0 }, - { 0x7cecc00a, mmCP_DFY_DATA_0 }, - { 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x8c000448, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x040c2000, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0xcc800010, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc418000b, mmCP_DFY_DATA_0 }, - { 0x31980002, mmCP_DFY_DATA_0 }, - { 0x041c0000, mmCP_DFY_DATA_0 }, - { 0x9980001c, mmCP_DFY_DATA_0 }, - { 0x19580066, mmCP_DFY_DATA_0 }, - { 0x15600008, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0xc0120001, mmCP_DFY_DATA_0 }, - { 0x11980003, mmCP_DFY_DATA_0 }, - { 0x04240004, mmCP_DFY_DATA_0 }, - { 0x7da18001, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1c200, mmCP_DFY_DATA_0 }, - { 0xc41d24db, mmCP_DFY_DATA_0 }, - { 0x7cd0c001, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0x7dd9c005, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0x99c00002, mmCP_DFY_DATA_0 }, - { 0x9a40fff8, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x9580137b, mmCP_DFY_DATA_0 }, - { 0xc00ee000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1c200, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd840004f, mmCP_DFY_DATA_0 }, - { 0xc4113269, mmCP_DFY_DATA_0 }, - { 0x19080070, mmCP_DFY_DATA_0 }, - { 0x190c00e8, mmCP_DFY_DATA_0 }, - { 0x2510003f, mmCP_DFY_DATA_0 }, - { 0x2518000f, mmCP_DFY_DATA_0 }, - { 0xcd813268, mmCP_DFY_DATA_0 }, - { 0x05a80809, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000080e, mmCP_DFY_DATA_0 }, - { 0x8000080f, mmCP_DFY_DATA_0 }, - { 0x80000898, mmCP_DFY_DATA_0 }, - { 0x80000946, mmCP_DFY_DATA_0 }, - { 0x800009e1, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x04a80811, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000815, mmCP_DFY_DATA_0 }, - { 0x80000834, mmCP_DFY_DATA_0 }, - { 0x8000085e, mmCP_DFY_DATA_0 }, - { 0x8000085e, mmCP_DFY_DATA_0 }, - { 0x04341001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc42d3045, mmCP_DFY_DATA_0 }, - { 0xcec1c091, mmCP_DFY_DATA_0 }, - { 0x31300021, mmCP_DFY_DATA_0 }, - { 0x9700000b, mmCP_DFY_DATA_0 }, - { 0xd84002f1, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xc4293059, mmCP_DFY_DATA_0 }, - { 0x56a8001f, mmCP_DFY_DATA_0 }, - { 0x7f2b000a, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x9b000241, mmCP_DFY_DATA_0 }, - { 0x8000084a, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc43130b6, mmCP_DFY_DATA_0 }, - { 0x9b000003, mmCP_DFY_DATA_0 }, - { 0xc02f0001, mmCP_DFY_DATA_0 }, - { 0xcec130b6, mmCP_DFY_DATA_0 }, - { 0xc4252087, mmCP_DFY_DATA_0 }, - { 0x5668001a, mmCP_DFY_DATA_0 }, - { 0x26a80005, mmCP_DFY_DATA_0 }, - { 0x9a80fffd, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd80130b6, mmCP_DFY_DATA_0 }, - { 0x8000084a, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04341001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc431ecaa, mmCP_DFY_DATA_0 }, - { 0x27300080, mmCP_DFY_DATA_0 }, - { 0x9b000010, mmCP_DFY_DATA_0 }, - { 0xc02e0001, mmCP_DFY_DATA_0 }, - { 0xcec130b6, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd80130b6, mmCP_DFY_DATA_0 }, - { 0x31300021, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xd84002f1, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xc4293059, mmCP_DFY_DATA_0 }, - { 0x56a8001f, mmCP_DFY_DATA_0 }, - { 0x7f2b000a, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x9b00021d, mmCP_DFY_DATA_0 }, - { 0xdd410000, mmCP_DFY_DATA_0 }, - { 0x040c0005, mmCP_DFY_DATA_0 }, - { 0xd84802e9, mmCP_DFY_DATA_0 }, - { 0x8c001a41, mmCP_DFY_DATA_0 }, - { 0xc43b02f1, mmCP_DFY_DATA_0 }, - { 0x9b800006, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xcec80278, mmCP_DFY_DATA_0 }, - { 0x56f00020, mmCP_DFY_DATA_0 }, - { 0xcf080280, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8813247, mmCP_DFY_DATA_0 }, - { 0xd80802e9, mmCP_DFY_DATA_0 }, - { 0x8000085e, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x31100011, mmCP_DFY_DATA_0 }, - { 0x950001fa, mmCP_DFY_DATA_0 }, - { 0xc02e0001, mmCP_DFY_DATA_0 }, - { 0x2aec0008, mmCP_DFY_DATA_0 }, - { 0xc01c0020, mmCP_DFY_DATA_0 }, - { 0xc0180001, mmCP_DFY_DATA_0 }, - { 0xc00c0007, mmCP_DFY_DATA_0 }, - { 0x11a40006, mmCP_DFY_DATA_0 }, - { 0x7de6000a, mmCP_DFY_DATA_0 }, - { 0x10e40008, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x7e2e000a, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0xc4113254, mmCP_DFY_DATA_0 }, - { 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { 0x2110003e, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0xd801324f, mmCP_DFY_DATA_0 }, - { 0xd8013255, mmCP_DFY_DATA_0 }, - { 0x1d10ff9e, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0xd8013247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0xd801325e, mmCP_DFY_DATA_0 }, - { 0xc0245301, mmCP_DFY_DATA_0 }, - { 0xce413249, mmCP_DFY_DATA_0 }, - { 0xd801325f, mmCP_DFY_DATA_0 }, - { 0xc425326c, mmCP_DFY_DATA_0 }, - { 0xc0121fff, mmCP_DFY_DATA_0 }, - { 0x29108eff, mmCP_DFY_DATA_0 }, - { 0x7e524009, mmCP_DFY_DATA_0 }, - { 0xce41326c, mmCP_DFY_DATA_0 }, - { 0xc425325a, mmCP_DFY_DATA_0 }, - { 0xc0127ff0, mmCP_DFY_DATA_0 }, - { 0x7e524009, mmCP_DFY_DATA_0 }, - { 0xce41325a, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0xc0131fff, mmCP_DFY_DATA_0 }, - { 0x7e524009, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0xd801326d, mmCP_DFY_DATA_0 }, - { 0xd801326e, mmCP_DFY_DATA_0 }, - { 0xd8013279, mmCP_DFY_DATA_0 }, - { 0x94c00003, mmCP_DFY_DATA_0 }, - { 0x08cc0001, mmCP_DFY_DATA_0 }, - { 0x80000866, mmCP_DFY_DATA_0 }, - { 0xc00c0007, mmCP_DFY_DATA_0 }, - { 0x95800003, mmCP_DFY_DATA_0 }, - { 0x09980001, mmCP_DFY_DATA_0 }, - { 0x80000866, mmCP_DFY_DATA_0 }, - { 0xc0100010, mmCP_DFY_DATA_0 }, - { 0x7dd2400c, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xc0180003, mmCP_DFY_DATA_0 }, - { 0x7dd1c002, mmCP_DFY_DATA_0 }, - { 0x80000866, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x04a8089a, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000089e, mmCP_DFY_DATA_0 }, - { 0x800008fa, mmCP_DFY_DATA_0 }, - { 0x80000945, mmCP_DFY_DATA_0 }, - { 0x80000945, mmCP_DFY_DATA_0 }, - { 0x31300022, mmCP_DFY_DATA_0 }, - { 0x97000007, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d91801a, mmCP_DFY_DATA_0 }, - { 0x459801e0, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x2738000f, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8300011, mmCP_DFY_DATA_0 }, - { 0x97000036, mmCP_DFY_DATA_0 }, - { 0x45980008, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8340011, mmCP_DFY_DATA_0 }, - { 0x9740002f, mmCP_DFY_DATA_0 }, - { 0xc43c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x13b80001, mmCP_DFY_DATA_0 }, - { 0xc79d3300, mmCP_DFY_DATA_0 }, - { 0xc7a13301, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xd8393300, mmCP_DFY_DATA_0 }, - { 0xc0260001, mmCP_DFY_DATA_0 }, - { 0xce793301, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x964012a4, mmCP_DFY_DATA_0 }, - { 0x7c028009, mmCP_DFY_DATA_0 }, - { 0x9740001c, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x99800004, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x06a80400, mmCP_DFY_DATA_0 }, - { 0x800008d2, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0x29640001, mmCP_DFY_DATA_0 }, - { 0xce40001a, mmCP_DFY_DATA_0 }, - { 0x242c0000, mmCP_DFY_DATA_0 }, - { 0x06ec0400, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x9980fffd, mmCP_DFY_DATA_0 }, - { 0xc02620c0, mmCP_DFY_DATA_0 }, - { 0xce41c078, mmCP_DFY_DATA_0 }, - { 0xce81c080, mmCP_DFY_DATA_0 }, - { 0xcc01c081, mmCP_DFY_DATA_0 }, - { 0xcf01c082, mmCP_DFY_DATA_0 }, - { 0x57240020, mmCP_DFY_DATA_0 }, - { 0xce41c083, mmCP_DFY_DATA_0 }, - { 0xc0260400, mmCP_DFY_DATA_0 }, - { 0x7e6e400a, mmCP_DFY_DATA_0 }, - { 0xce41c084, mmCP_DFY_DATA_0 }, - { 0x7eae8001, mmCP_DFY_DATA_0 }, - { 0x7f2f0011, mmCP_DFY_DATA_0 }, - { 0x800008d2, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xcdf93300, mmCP_DFY_DATA_0 }, - { 0xce393301, mmCP_DFY_DATA_0 }, - { 0xcfc00008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc43c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xcfc00008, mmCP_DFY_DATA_0 }, - { 0x80000903, mmCP_DFY_DATA_0 }, - { 0x31240022, mmCP_DFY_DATA_0 }, - { 0x96400008, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x7ec30011, mmCP_DFY_DATA_0 }, - { 0x32f80000, mmCP_DFY_DATA_0 }, - { 0x9b800011, mmCP_DFY_DATA_0 }, - { 0x043c0020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x67180001, mmCP_DFY_DATA_0 }, - { 0x0bfc0001, mmCP_DFY_DATA_0 }, - { 0x57300001, mmCP_DFY_DATA_0 }, - { 0x95800006, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x9a400003, mmCP_DFY_DATA_0 }, - { 0xd981325d, mmCP_DFY_DATA_0 }, - { 0x80000915, mmCP_DFY_DATA_0 }, - { 0xd9c1325d, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9bc0fff6, mmCP_DFY_DATA_0 }, - { 0x7f818001, mmCP_DFY_DATA_0 }, - { 0x8c001606, mmCP_DFY_DATA_0 }, - { 0x7d838001, mmCP_DFY_DATA_0 }, - { 0x94800010, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc41d3259, mmCP_DFY_DATA_0 }, - { 0xc421325a, mmCP_DFY_DATA_0 }, - { 0x16240014, mmCP_DFY_DATA_0 }, - { 0x12640014, mmCP_DFY_DATA_0 }, - { 0x1a2801f0, mmCP_DFY_DATA_0 }, - { 0x12a80010, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0x7e2a000a, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x7e5e400a, mmCP_DFY_DATA_0 }, - { 0x9b800002, mmCP_DFY_DATA_0 }, - { 0x2264003f, mmCP_DFY_DATA_0 }, - { 0xce41325a, mmCP_DFY_DATA_0 }, - { 0xd8013259, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x8c00075e, mmCP_DFY_DATA_0 }, - { 0xc4af0228, mmCP_DFY_DATA_0 }, - { 0x043c0000, mmCP_DFY_DATA_0 }, - { 0x66d80001, mmCP_DFY_DATA_0 }, - { 0x95800010, mmCP_DFY_DATA_0 }, - { 0x04300002, mmCP_DFY_DATA_0 }, - { 0x1330000d, mmCP_DFY_DATA_0 }, - { 0x13f40014, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x04380040, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380060, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x07fc0001, mmCP_DFY_DATA_0 }, - { 0x56ec0001, mmCP_DFY_DATA_0 }, - { 0x33e80010, mmCP_DFY_DATA_0 }, - { 0x9680ffec, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x04a80948, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000094c, mmCP_DFY_DATA_0 }, - { 0x8000099b, mmCP_DFY_DATA_0 }, - { 0x800009e0, mmCP_DFY_DATA_0 }, - { 0x800009e0, mmCP_DFY_DATA_0 }, - { 0xc43c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d91801a, mmCP_DFY_DATA_0 }, - { 0x459801e0, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x2738000f, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8300011, mmCP_DFY_DATA_0 }, - { 0x97000033, mmCP_DFY_DATA_0 }, - { 0x45980008, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8340011, mmCP_DFY_DATA_0 }, - { 0x9740002c, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x13b80001, mmCP_DFY_DATA_0 }, - { 0xc79d3300, mmCP_DFY_DATA_0 }, - { 0xc7a13301, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xd8393300, mmCP_DFY_DATA_0 }, - { 0xc0260001, mmCP_DFY_DATA_0 }, - { 0xce793301, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x964011fe, mmCP_DFY_DATA_0 }, - { 0x7c028009, mmCP_DFY_DATA_0 }, - { 0x9740001c, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x99800004, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x06a80400, mmCP_DFY_DATA_0 }, - { 0x80000978, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0x29640001, mmCP_DFY_DATA_0 }, - { 0xce40001a, mmCP_DFY_DATA_0 }, - { 0x242c0000, mmCP_DFY_DATA_0 }, - { 0x06ec0400, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x9980fffd, mmCP_DFY_DATA_0 }, - { 0xc0260010, mmCP_DFY_DATA_0 }, - { 0xce41c078, mmCP_DFY_DATA_0 }, - { 0xcf01c080, mmCP_DFY_DATA_0 }, - { 0x57240020, mmCP_DFY_DATA_0 }, - { 0xce41c081, mmCP_DFY_DATA_0 }, - { 0xce81c082, mmCP_DFY_DATA_0 }, - { 0xcc01c083, mmCP_DFY_DATA_0 }, - { 0xc0260800, mmCP_DFY_DATA_0 }, - { 0x7e6e400a, mmCP_DFY_DATA_0 }, - { 0xce41c084, mmCP_DFY_DATA_0 }, - { 0x7eae8001, mmCP_DFY_DATA_0 }, - { 0x7f2f0011, mmCP_DFY_DATA_0 }, - { 0x80000978, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xcdf93300, mmCP_DFY_DATA_0 }, - { 0xce393301, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xcfc00008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7dda801a, mmCP_DFY_DATA_0 }, - { 0x7d41c001, mmCP_DFY_DATA_0 }, - { 0x7e838011, mmCP_DFY_DATA_0 }, - { 0xd84802e9, mmCP_DFY_DATA_0 }, - { 0x8c001802, mmCP_DFY_DATA_0 }, - { 0x469c0390, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4200011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4240011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4280011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc42c0011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4380011, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x8c0014df, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x31280014, mmCP_DFY_DATA_0 }, - { 0xce8802ef, mmCP_DFY_DATA_0 }, - { 0x9a800062, mmCP_DFY_DATA_0 }, - { 0x31280034, mmCP_DFY_DATA_0 }, - { 0x9a800060, mmCP_DFY_DATA_0 }, - { 0x04a809e8, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x800009ec, mmCP_DFY_DATA_0 }, - { 0x80000a45, mmCP_DFY_DATA_0 }, - { 0x80000a59, mmCP_DFY_DATA_0 }, - { 0x80000a59, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d91801a, mmCP_DFY_DATA_0 }, - { 0x45980400, mmCP_DFY_DATA_0 }, - { 0xc4b30258, mmCP_DFY_DATA_0 }, - { 0xc4a70250, mmCP_DFY_DATA_0 }, - { 0x53300020, mmCP_DFY_DATA_0 }, - { 0x7e72401a, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0x042c0020, mmCP_DFY_DATA_0 }, - { 0x66740001, mmCP_DFY_DATA_0 }, - { 0x97400041, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04383000, mmCP_DFY_DATA_0 }, - { 0xcf813267, mmCP_DFY_DATA_0 }, - { 0xc4393267, mmCP_DFY_DATA_0 }, - { 0x9b800001, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x1b38007e, mmCP_DFY_DATA_0 }, - { 0x33b40003, mmCP_DFY_DATA_0 }, - { 0x9b400003, mmCP_DFY_DATA_0 }, - { 0x4598001c, mmCP_DFY_DATA_0 }, - { 0x9740002f, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc40c0011, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4100011, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002eb, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002ec, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002ed, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002ee, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04382000, mmCP_DFY_DATA_0 }, - { 0xcf813267, mmCP_DFY_DATA_0 }, - { 0xd84802e9, mmCP_DFY_DATA_0 }, - { 0x8c001715, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04382000, mmCP_DFY_DATA_0 }, - { 0xcf813267, mmCP_DFY_DATA_0 }, - { 0x56640001, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x9ac0ffbc, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04341001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x94800005, mmCP_DFY_DATA_0 }, - { 0xc431ecaa, mmCP_DFY_DATA_0 }, - { 0x27300080, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000a55, mmCP_DFY_DATA_0 }, - { 0xc43130b6, mmCP_DFY_DATA_0 }, - { 0x233c0032, mmCP_DFY_DATA_0 }, - { 0xcfc130b6, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcf0130b6, mmCP_DFY_DATA_0 }, - { 0xc49302ef, mmCP_DFY_DATA_0 }, - { 0x99000003, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8413247, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04180001, mmCP_DFY_DATA_0 }, - { 0x5198001f, mmCP_DFY_DATA_0 }, - { 0xcd813268, mmCP_DFY_DATA_0 }, - { 0xc4193269, mmCP_DFY_DATA_0 }, - { 0x2598000f, mmCP_DFY_DATA_0 }, - { 0x9980fffe, mmCP_DFY_DATA_0 }, - { 0xd80002f1, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8013268, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04380001, mmCP_DFY_DATA_0 }, - { 0x53b8001f, mmCP_DFY_DATA_0 }, - { 0x7db9801a, mmCP_DFY_DATA_0 }, - { 0xcd813268, mmCP_DFY_DATA_0 }, - { 0x80000a5e, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01106, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcc412e01, mmCP_DFY_DATA_0 }, - { 0xcc412e02, mmCP_DFY_DATA_0 }, - { 0xcc412e03, mmCP_DFY_DATA_0 }, - { 0xcc412e00, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c010fd, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50640020, mmCP_DFY_DATA_0 }, - { 0x7ce4c01a, mmCP_DFY_DATA_0 }, - { 0xd0c00072, mmCP_DFY_DATA_0 }, - { 0xc80c0072, mmCP_DFY_DATA_0 }, - { 0x58e801fc, mmCP_DFY_DATA_0 }, - { 0x12a80009, mmCP_DFY_DATA_0 }, - { 0x2aa80000, mmCP_DFY_DATA_0 }, - { 0xd0c0001e, mmCP_DFY_DATA_0 }, - { 0xce80001c, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc424000f, mmCP_DFY_DATA_0 }, - { 0x9a40ffff, mmCP_DFY_DATA_0 }, - { 0x04240010, mmCP_DFY_DATA_0 }, - { 0x18dc01e2, mmCP_DFY_DATA_0 }, - { 0x7e5e4002, mmCP_DFY_DATA_0 }, - { 0x3e5c0003, mmCP_DFY_DATA_0 }, - { 0x3e540002, mmCP_DFY_DATA_0 }, - { 0x95c00006, mmCP_DFY_DATA_0 }, - { 0xc8180011, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0x55140020, mmCP_DFY_DATA_0 }, - { 0x80000aa2, mmCP_DFY_DATA_0 }, - { 0x9540000a, mmCP_DFY_DATA_0 }, - { 0xc8180011, mmCP_DFY_DATA_0 }, - { 0x44cc0008, mmCP_DFY_DATA_0 }, - { 0x55900020, mmCP_DFY_DATA_0 }, - { 0xd0c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc424000f, mmCP_DFY_DATA_0 }, - { 0x9a40ffff, mmCP_DFY_DATA_0 }, - { 0xc4140011, mmCP_DFY_DATA_0 }, - { 0x80000aa2, mmCP_DFY_DATA_0 }, - { 0x44cc0004, mmCP_DFY_DATA_0 }, - { 0xc4180011, mmCP_DFY_DATA_0 }, - { 0xd0c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc424000f, mmCP_DFY_DATA_0 }, - { 0x9a40ffff, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0x55140020, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcd812e01, mmCP_DFY_DATA_0 }, - { 0xcd012e02, mmCP_DFY_DATA_0 }, - { 0xcd412e03, mmCP_DFY_DATA_0 }, - { 0xcc412e00, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc4253249, mmCP_DFY_DATA_0 }, - { 0x2264003f, mmCP_DFY_DATA_0 }, - { 0xce413249, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc4253249, mmCP_DFY_DATA_0 }, - { 0x96400001, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xc410001a, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0xc4140028, mmCP_DFY_DATA_0 }, - { 0x95000005, mmCP_DFY_DATA_0 }, - { 0x1e64001f, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce413249, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x14d00010, mmCP_DFY_DATA_0 }, - { 0xc4180030, mmCP_DFY_DATA_0 }, - { 0xc41c0007, mmCP_DFY_DATA_0 }, - { 0x99000004, mmCP_DFY_DATA_0 }, - { 0x99400009, mmCP_DFY_DATA_0 }, - { 0x9980000c, mmCP_DFY_DATA_0 }, - { 0x80000ab1, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xc420001c, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0x9a0010ac, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xd880003f, mmCP_DFY_DATA_0 }, - { 0x95c00002, mmCP_DFY_DATA_0 }, - { 0xd8c0003f, mmCP_DFY_DATA_0 }, - { 0x80001082, mmCP_DFY_DATA_0 }, - { 0xd8800040, mmCP_DFY_DATA_0 }, - { 0x95c00002, mmCP_DFY_DATA_0 }, - { 0xd8c00040, mmCP_DFY_DATA_0 }, - { 0x800010de, mmCP_DFY_DATA_0 }, - { 0xc010ffff, mmCP_DFY_DATA_0 }, - { 0x18d403f7, mmCP_DFY_DATA_0 }, - { 0x7d0cc009, mmCP_DFY_DATA_0 }, - { 0xc41b0367, mmCP_DFY_DATA_0 }, - { 0x7d958004, mmCP_DFY_DATA_0 }, - { 0x7d85800a, mmCP_DFY_DATA_0 }, - { 0xdc1e0000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d001fc, mmCP_DFY_DATA_0 }, - { 0x05280adc, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000af1, mmCP_DFY_DATA_0 }, - { 0x80000adf, mmCP_DFY_DATA_0 }, - { 0x80000ae7, mmCP_DFY_DATA_0 }, - { 0x8c000ace, mmCP_DFY_DATA_0 }, - { 0xd8c00013, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd8d2000, mmCP_DFY_DATA_0 }, - { 0x99c00010, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x18d803f7, mmCP_DFY_DATA_0 }, - { 0xc010ffff, mmCP_DFY_DATA_0 }, - { 0x7d0cc009, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0x11940014, mmCP_DFY_DATA_0 }, - { 0x29544001, mmCP_DFY_DATA_0 }, - { 0x9a400002, mmCP_DFY_DATA_0 }, - { 0x29544003, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x80000af4, mmCP_DFY_DATA_0 }, - { 0xd8c00013, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd44d2000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0xd8c00013, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd44dc000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d0003c, mmCP_DFY_DATA_0 }, - { 0x95000006, mmCP_DFY_DATA_0 }, - { 0x8c000ace, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcd8d2c00, mmCP_DFY_DATA_0 }, - { 0x99c00003, mmCP_DFY_DATA_0 }, - { 0x80000b0a, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xd44d2c00, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x28148004, mmCP_DFY_DATA_0 }, - { 0x24d800ff, mmCP_DFY_DATA_0 }, - { 0xccc00019, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd4593240, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c0105e, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x50540020, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x2198003f, mmCP_DFY_DATA_0 }, - { 0x199c0034, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x95c00028, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc42d324f, mmCP_DFY_DATA_0 }, - { 0xc4313255, mmCP_DFY_DATA_0 }, - { 0x7ef3400c, mmCP_DFY_DATA_0 }, - { 0x9b400021, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x14e80001, mmCP_DFY_DATA_0 }, - { 0x9a8000af, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x041c0002, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0xccc00010, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01043, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x50540020, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x18a01fe8, mmCP_DFY_DATA_0 }, - { 0x3620005c, mmCP_DFY_DATA_0 }, - { 0x9a00000e, mmCP_DFY_DATA_0 }, - { 0x2464003f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc6290ce7, mmCP_DFY_DATA_0 }, - { 0x16ac001f, mmCP_DFY_DATA_0 }, - { 0x96c00004, mmCP_DFY_DATA_0 }, - { 0x26ac003f, mmCP_DFY_DATA_0 }, - { 0x7ee6c00d, mmCP_DFY_DATA_0 }, - { 0x96c00005, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x2620000f, mmCP_DFY_DATA_0 }, - { 0x9a00fff8, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xce000367, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x9640102e, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x199c0037, mmCP_DFY_DATA_0 }, - { 0x19a00035, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x95c0005d, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xc42d3256, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0x16f8001f, mmCP_DFY_DATA_0 }, - { 0x9780000d, mmCP_DFY_DATA_0 }, - { 0xc4253248, mmCP_DFY_DATA_0 }, - { 0xc035f0ff, mmCP_DFY_DATA_0 }, - { 0x7e764009, mmCP_DFY_DATA_0 }, - { 0x19b401f8, mmCP_DFY_DATA_0 }, - { 0x13740008, mmCP_DFY_DATA_0 }, - { 0x7e76400a, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce413248, mmCP_DFY_DATA_0 }, - { 0xcf01325a, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xd1000072, mmCP_DFY_DATA_0 }, - { 0xc8100072, mmCP_DFY_DATA_0 }, - { 0x55140020, mmCP_DFY_DATA_0 }, - { 0x199c0034, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0x9b800004, mmCP_DFY_DATA_0 }, - { 0x1ae4003e, mmCP_DFY_DATA_0 }, - { 0xce400008, mmCP_DFY_DATA_0 }, - { 0x80000b7c, mmCP_DFY_DATA_0 }, - { 0xc4353254, mmCP_DFY_DATA_0 }, - { 0x16a80008, mmCP_DFY_DATA_0 }, - { 0x1aec003c, mmCP_DFY_DATA_0 }, - { 0x19a4003f, mmCP_DFY_DATA_0 }, - { 0x12a80015, mmCP_DFY_DATA_0 }, - { 0x12ec001f, mmCP_DFY_DATA_0 }, - { 0x1374000b, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc02e4000, mmCP_DFY_DATA_0 }, - { 0x1774000d, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xce400008, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0xc43d3248, mmCP_DFY_DATA_0 }, - { 0x1bfc01e8, mmCP_DFY_DATA_0 }, - { 0x13fc0018, mmCP_DFY_DATA_0 }, - { 0x7dbd800a, mmCP_DFY_DATA_0 }, - { 0x1d98ff15, mmCP_DFY_DATA_0 }, - { 0x592c00fc, mmCP_DFY_DATA_0 }, - { 0xcd80000a, mmCP_DFY_DATA_0 }, - { 0x12e00016, mmCP_DFY_DATA_0 }, - { 0x7da1800a, mmCP_DFY_DATA_0 }, - { 0x592c007e, mmCP_DFY_DATA_0 }, - { 0x12e00015, mmCP_DFY_DATA_0 }, - { 0x7da1800a, mmCP_DFY_DATA_0 }, - { 0xd1000001, mmCP_DFY_DATA_0 }, - { 0xcd800001, mmCP_DFY_DATA_0 }, - { 0x11a0000c, mmCP_DFY_DATA_0 }, - { 0x1264001e, mmCP_DFY_DATA_0 }, - { 0x1620000c, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x7e32000a, mmCP_DFY_DATA_0 }, - { 0x12e4001b, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x5924007e, mmCP_DFY_DATA_0 }, - { 0x12640017, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x19a4003c, mmCP_DFY_DATA_0 }, - { 0x12640018, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xce01325a, mmCP_DFY_DATA_0 }, - { 0xcd013257, mmCP_DFY_DATA_0 }, - { 0xcd413258, mmCP_DFY_DATA_0 }, - { 0xc429325a, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c00fdb, mmCP_DFY_DATA_0 }, - { 0x96800001, mmCP_DFY_DATA_0 }, - { 0x95c00003, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x9780f5ca, mmCP_DFY_DATA_0 }, - { 0xcf400100, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001219, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0xccc00010, mmCP_DFY_DATA_0 }, - { 0x8c001b6d, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc42d324e, mmCP_DFY_DATA_0 }, - { 0xc431324d, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc435324f, mmCP_DFY_DATA_0 }, - { 0xc4293256, mmCP_DFY_DATA_0 }, - { 0x52ec0008, mmCP_DFY_DATA_0 }, - { 0x07740003, mmCP_DFY_DATA_0 }, - { 0x04240002, mmCP_DFY_DATA_0 }, - { 0x269c003f, mmCP_DFY_DATA_0 }, - { 0x7e5e4004, mmCP_DFY_DATA_0 }, - { 0x7f67000f, mmCP_DFY_DATA_0 }, - { 0x97000003, mmCP_DFY_DATA_0 }, - { 0x7f674002, mmCP_DFY_DATA_0 }, - { 0x0b740001, mmCP_DFY_DATA_0 }, - { 0x53740002, mmCP_DFY_DATA_0 }, - { 0x7ef6c011, mmCP_DFY_DATA_0 }, - { 0x1ab42010, mmCP_DFY_DATA_0 }, - { 0x1ab8c006, mmCP_DFY_DATA_0 }, - { 0x16a8000c, mmCP_DFY_DATA_0 }, - { 0x26a80800, mmCP_DFY_DATA_0 }, - { 0x2b740000, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0xcf40001c, mmCP_DFY_DATA_0 }, - { 0xd2c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4180011, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0x8c000bec, mmCP_DFY_DATA_0 }, - { 0x80000b47, mmCP_DFY_DATA_0 }, - { 0xc42c001d, mmCP_DFY_DATA_0 }, - { 0xc4313256, mmCP_DFY_DATA_0 }, - { 0x1b34060b, mmCP_DFY_DATA_0 }, - { 0x1b300077, mmCP_DFY_DATA_0 }, - { 0x7f370009, mmCP_DFY_DATA_0 }, - { 0x13300017, mmCP_DFY_DATA_0 }, - { 0x04340100, mmCP_DFY_DATA_0 }, - { 0x26ec00ff, mmCP_DFY_DATA_0 }, - { 0xc03a8004, mmCP_DFY_DATA_0 }, - { 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { 0x7f3b000a, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc40c0032, mmCP_DFY_DATA_0 }, - { 0xc410001d, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc415325b, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x18580037, mmCP_DFY_DATA_0 }, - { 0x251000ff, mmCP_DFY_DATA_0 }, - { 0xc421325d, mmCP_DFY_DATA_0 }, - { 0x262001ef, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x99800004, mmCP_DFY_DATA_0 }, - { 0x7d15400a, mmCP_DFY_DATA_0 }, - { 0xcd41325b, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x1d54001f, mmCP_DFY_DATA_0 }, - { 0xcd41325b, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc428000b, mmCP_DFY_DATA_0 }, - { 0xc42c000c, mmCP_DFY_DATA_0 }, - { 0x12a80001, mmCP_DFY_DATA_0 }, - { 0x26a80004, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0xc4340028, mmCP_DFY_DATA_0 }, - { 0x14f00010, mmCP_DFY_DATA_0 }, - { 0xc4380030, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xcd280200, mmCP_DFY_DATA_0 }, - { 0xcd680208, mmCP_DFY_DATA_0 }, - { 0xcda80210, mmCP_DFY_DATA_0 }, - { 0x9b00000c, mmCP_DFY_DATA_0 }, - { 0x9b400014, mmCP_DFY_DATA_0 }, - { 0x9b800017, mmCP_DFY_DATA_0 }, - { 0xc428000b, mmCP_DFY_DATA_0 }, - { 0xc42c000c, mmCP_DFY_DATA_0 }, - { 0x12a80001, mmCP_DFY_DATA_0 }, - { 0x26a80004, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc6930200, mmCP_DFY_DATA_0 }, - { 0xc6970208, mmCP_DFY_DATA_0 }, - { 0xc69b0210, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b000005, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd900003f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd940003f, mmCP_DFY_DATA_0 }, - { 0x80001082, mmCP_DFY_DATA_0 }, - { 0xd9000040, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd9400040, mmCP_DFY_DATA_0 }, - { 0x800010de, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14fc0011, mmCP_DFY_DATA_0 }, - { 0x24f800ff, mmCP_DFY_DATA_0 }, - { 0x33b80001, mmCP_DFY_DATA_0 }, - { 0x97c0fffc, mmCP_DFY_DATA_0 }, - { 0x9b800007, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0x7d83c001, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4093249, mmCP_DFY_DATA_0 }, - { 0x1888003e, mmCP_DFY_DATA_0 }, - { 0x94800020, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0x9a400009, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc419324c, mmCP_DFY_DATA_0 }, - { 0x259c0001, mmCP_DFY_DATA_0 }, - { 0x1598001f, mmCP_DFY_DATA_0 }, - { 0x95c00016, mmCP_DFY_DATA_0 }, - { 0x95800015, mmCP_DFY_DATA_0 }, - { 0x99000003, mmCP_DFY_DATA_0 }, - { 0xd8400036, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14d80011, mmCP_DFY_DATA_0 }, - { 0x24e000ff, mmCP_DFY_DATA_0 }, - { 0x321c0002, mmCP_DFY_DATA_0 }, - { 0x32200001, mmCP_DFY_DATA_0 }, - { 0x9580ffee, mmCP_DFY_DATA_0 }, - { 0x99c00014, mmCP_DFY_DATA_0 }, - { 0x96000004, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x04140001, mmCP_DFY_DATA_0 }, - { 0x80000c30, mmCP_DFY_DATA_0 }, - { 0x9480000a, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95800f29, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x94800004, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95800f23, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0x99400002, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x94800004, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95800f1a, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0xd8800036, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x041c0003, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xc40c0077, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x9600f502, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x98c0f500, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0x9a000f05, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0xc42d3256, mmCP_DFY_DATA_0 }, - { 0x1f30001f, mmCP_DFY_DATA_0 }, - { 0x16e4001f, mmCP_DFY_DATA_0 }, - { 0xcf01325a, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x9640f4f4, mmCP_DFY_DATA_0 }, - { 0xc434000b, mmCP_DFY_DATA_0 }, - { 0x33740002, mmCP_DFY_DATA_0 }, - { 0x9b40f4f1, mmCP_DFY_DATA_0 }, - { 0xc4353254, mmCP_DFY_DATA_0 }, - { 0x16a80008, mmCP_DFY_DATA_0 }, - { 0x1aec003c, mmCP_DFY_DATA_0 }, - { 0x12a80015, mmCP_DFY_DATA_0 }, - { 0x12ec001f, mmCP_DFY_DATA_0 }, - { 0x1374000b, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc02e4000, mmCP_DFY_DATA_0 }, - { 0x1774000d, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0xcf400100, mmCP_DFY_DATA_0 }, - { 0x12780001, mmCP_DFY_DATA_0 }, - { 0x2bb80001, mmCP_DFY_DATA_0 }, - { 0xc00ac005, mmCP_DFY_DATA_0 }, - { 0xc00e0002, mmCP_DFY_DATA_0 }, - { 0x28cc8000, mmCP_DFY_DATA_0 }, - { 0x28884900, mmCP_DFY_DATA_0 }, - { 0x28cc0014, mmCP_DFY_DATA_0 }, - { 0x80000ff3, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x17fc0001, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x96400ee1, mmCP_DFY_DATA_0 }, - { 0xcc41c40a, mmCP_DFY_DATA_0 }, - { 0xcc41c40c, mmCP_DFY_DATA_0 }, - { 0xcc41c40d, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x24d0007f, mmCP_DFY_DATA_0 }, - { 0x15580010, mmCP_DFY_DATA_0 }, - { 0x255400ff, mmCP_DFY_DATA_0 }, - { 0xcd01c411, mmCP_DFY_DATA_0 }, - { 0xcd81c40f, mmCP_DFY_DATA_0 }, - { 0xcd41c40e, mmCP_DFY_DATA_0 }, - { 0xcc41c410, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x04200000, mmCP_DFY_DATA_0 }, - { 0x18e80033, mmCP_DFY_DATA_0 }, - { 0x18ec0034, mmCP_DFY_DATA_0 }, - { 0xcc41c414, mmCP_DFY_DATA_0 }, - { 0xcc41c415, mmCP_DFY_DATA_0 }, - { 0xcd81c413, mmCP_DFY_DATA_0 }, - { 0xcd41c412, mmCP_DFY_DATA_0 }, - { 0x18dc0032, mmCP_DFY_DATA_0 }, - { 0x7c030011, mmCP_DFY_DATA_0 }, - { 0x7c038011, mmCP_DFY_DATA_0 }, - { 0x95c00027, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xc431c417, mmCP_DFY_DATA_0 }, - { 0xc435c416, mmCP_DFY_DATA_0 }, - { 0x96800004, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xc439c419, mmCP_DFY_DATA_0 }, - { 0xc43dc418, mmCP_DFY_DATA_0 }, - { 0xc41c000e, mmCP_DFY_DATA_0 }, - { 0x29dc0008, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xcf413261, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xcf013262, mmCP_DFY_DATA_0 }, - { 0x96800004, mmCP_DFY_DATA_0 }, - { 0xcfc13263, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xcf813264, mmCP_DFY_DATA_0 }, - { 0x18dc0030, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x95c00017, mmCP_DFY_DATA_0 }, - { 0x17fc0001, mmCP_DFY_DATA_0 }, - { 0x9ac00005, mmCP_DFY_DATA_0 }, - { 0x7d77000c, mmCP_DFY_DATA_0 }, - { 0x9bc00015, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0x80000cd6, mmCP_DFY_DATA_0 }, - { 0x51b80020, mmCP_DFY_DATA_0 }, - { 0x53300020, mmCP_DFY_DATA_0 }, - { 0x7f97801a, mmCP_DFY_DATA_0 }, - { 0x7f37001a, mmCP_DFY_DATA_0 }, - { 0x7f3b000c, mmCP_DFY_DATA_0 }, - { 0x9bc0000d, mmCP_DFY_DATA_0 }, - { 0x97800002, mmCP_DFY_DATA_0 }, - { 0x80000cd6, mmCP_DFY_DATA_0 }, - { 0x9a000018, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x28200001, mmCP_DFY_DATA_0 }, - { 0x80000ca7, mmCP_DFY_DATA_0 }, - { 0x18dc0031, mmCP_DFY_DATA_0 }, - { 0x95c00003, mmCP_DFY_DATA_0 }, - { 0xc435c40b, mmCP_DFY_DATA_0 }, - { 0x9740fffd, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc4280032, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x800012c2, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0xc43d3256, mmCP_DFY_DATA_0 }, - { 0x1bf0060b, mmCP_DFY_DATA_0 }, - { 0x1bfc0077, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x80000cf4, mmCP_DFY_DATA_0 }, - { 0xc43d325a, mmCP_DFY_DATA_0 }, - { 0x1bfc0677, mmCP_DFY_DATA_0 }, - { 0x13fc0017, mmCP_DFY_DATA_0 }, - { 0x04300100, mmCP_DFY_DATA_0 }, - { 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xc032800b, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d42011, mmCP_DFY_DATA_0 }, - { 0x17fc0001, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x24cc007f, mmCP_DFY_DATA_0 }, - { 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc428005e, mmCP_DFY_DATA_0 }, - { 0x96800e6c, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x596001fc, mmCP_DFY_DATA_0 }, - { 0x12200009, mmCP_DFY_DATA_0 }, - { 0x7ce0c00a, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x505c0020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x50600020, mmCP_DFY_DATA_0 }, - { 0x7de1c01a, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xccc0001b, mmCP_DFY_DATA_0 }, - { 0xd140001d, mmCP_DFY_DATA_0 }, - { 0xd180001f, mmCP_DFY_DATA_0 }, - { 0xd1c00020, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x95000010, mmCP_DFY_DATA_0 }, - { 0x04300000, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8240010, mmCP_DFY_DATA_0 }, - { 0x7e5e800c, mmCP_DFY_DATA_0 }, - { 0x9bc00015, mmCP_DFY_DATA_0 }, - { 0x9a80000c, mmCP_DFY_DATA_0 }, - { 0x9b000024, mmCP_DFY_DATA_0 }, - { 0x28300001, mmCP_DFY_DATA_0 }, - { 0x122c0004, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x80000d1f, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8240010, mmCP_DFY_DATA_0 }, - { 0x566c0020, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce413261, mmCP_DFY_DATA_0 }, - { 0xcec13262, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc4340032, mmCP_DFY_DATA_0 }, - { 0x2b740008, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x96800005, mmCP_DFY_DATA_0 }, - { 0x566c0020, mmCP_DFY_DATA_0 }, - { 0xce413261, mmCP_DFY_DATA_0 }, - { 0xcec13262, mmCP_DFY_DATA_0 }, - { 0x800012c2, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0xc43d3256, mmCP_DFY_DATA_0 }, - { 0x1bf0060b, mmCP_DFY_DATA_0 }, - { 0x1bfc0077, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x80000d57, mmCP_DFY_DATA_0 }, - { 0xc43d325a, mmCP_DFY_DATA_0 }, - { 0x1bfc0677, mmCP_DFY_DATA_0 }, - { 0x13fc0017, mmCP_DFY_DATA_0 }, - { 0x04300100, mmCP_DFY_DATA_0 }, - { 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xc0328009, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4253246, mmCP_DFY_DATA_0 }, - { 0xc4113245, mmCP_DFY_DATA_0 }, - { 0x04143000, mmCP_DFY_DATA_0 }, - { 0xcd413267, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e51001a, mmCP_DFY_DATA_0 }, - { 0xc4153267, mmCP_DFY_DATA_0 }, - { 0x7d2d0011, mmCP_DFY_DATA_0 }, - { 0x19640057, mmCP_DFY_DATA_0 }, - { 0x19580213, mmCP_DFY_DATA_0 }, - { 0x19600199, mmCP_DFY_DATA_0 }, - { 0x7da6400a, mmCP_DFY_DATA_0 }, - { 0x7e26400a, mmCP_DFY_DATA_0 }, - { 0xd1000025, mmCP_DFY_DATA_0 }, - { 0xce400024, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x04142000, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcd413267, mmCP_DFY_DATA_0 }, - { 0xc4153267, mmCP_DFY_DATA_0 }, - { 0x99400001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x18d40030, mmCP_DFY_DATA_0 }, - { 0x18d80034, mmCP_DFY_DATA_0 }, - { 0x05280d83, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0x7c424001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000d8a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x80000d95, mmCP_DFY_DATA_0 }, - { 0x80000db1, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x80000d95, mmCP_DFY_DATA_0 }, - { 0x80000dbc, mmCP_DFY_DATA_0 }, - { 0x11540010, mmCP_DFY_DATA_0 }, - { 0x7e010001, mmCP_DFY_DATA_0 }, - { 0x8c00187c, mmCP_DFY_DATA_0 }, - { 0x7d75400a, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd4610000, mmCP_DFY_DATA_0 }, - { 0x9580f3d8, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8000016, mmCP_DFY_DATA_0 }, - { 0x526c0020, mmCP_DFY_DATA_0 }, - { 0x18e80058, mmCP_DFY_DATA_0 }, - { 0x7e2ec01a, mmCP_DFY_DATA_0 }, - { 0xd2c00072, mmCP_DFY_DATA_0 }, - { 0xc82c0072, mmCP_DFY_DATA_0 }, - { 0x5ae0073a, mmCP_DFY_DATA_0 }, - { 0x7ea2800a, mmCP_DFY_DATA_0 }, - { 0x9940000a, mmCP_DFY_DATA_0 }, - { 0xce800024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9580f3c6, mmCP_DFY_DATA_0 }, - { 0xc4380012, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xdc3a0000, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0xce800024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xcc400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9b80fffb, mmCP_DFY_DATA_0 }, - { 0x9980fff5, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc02a0001, mmCP_DFY_DATA_0 }, - { 0x2aa80001, mmCP_DFY_DATA_0 }, - { 0x16200002, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce01c405, mmCP_DFY_DATA_0 }, - { 0xd441c406, mmCP_DFY_DATA_0 }, - { 0x9580f3b1, mmCP_DFY_DATA_0 }, - { 0xc439c409, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a40000b, mmCP_DFY_DATA_0 }, - { 0x11540010, mmCP_DFY_DATA_0 }, - { 0x29540002, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd4610000, mmCP_DFY_DATA_0 }, - { 0x9580f3a5, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c00da7, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50500020, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0xd0c00072, mmCP_DFY_DATA_0 }, - { 0xc8280072, mmCP_DFY_DATA_0 }, - { 0x5aac007e, mmCP_DFY_DATA_0 }, - { 0x12d80017, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7d9d800a, mmCP_DFY_DATA_0 }, - { 0x56a00020, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0x7da1800a, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7e82400a, mmCP_DFY_DATA_0 }, - { 0x7e58c01a, mmCP_DFY_DATA_0 }, - { 0x19d4003d, mmCP_DFY_DATA_0 }, - { 0x28182002, mmCP_DFY_DATA_0 }, - { 0x99400030, mmCP_DFY_DATA_0 }, - { 0x8c00104f, mmCP_DFY_DATA_0 }, - { 0xc430000d, mmCP_DFY_DATA_0 }, - { 0xc4340035, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc8140023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0xc011000f, mmCP_DFY_DATA_0 }, - { 0xc4240004, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x7c908009, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x7d614011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7ca4800a, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x7cb0800a, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0x20880188, mmCP_DFY_DATA_0 }, - { 0x54ec0020, mmCP_DFY_DATA_0 }, - { 0x7cb4800a, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x04380008, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x20240090, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0x28240004, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x9a800005, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xd8000016, mmCP_DFY_DATA_0 }, - { 0xcf80003a, mmCP_DFY_DATA_0 }, - { 0xd901a2a4, mmCP_DFY_DATA_0 }, - { 0x80001037, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x1624001f, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0xd841325f, mmCP_DFY_DATA_0 }, - { 0xd8800033, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0004, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8000039, mmCP_DFY_DATA_0 }, - { 0xd0c00038, mmCP_DFY_DATA_0 }, - { 0xc43c0022, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0xc429325f, mmCP_DFY_DATA_0 }, - { 0x26ac0001, mmCP_DFY_DATA_0 }, - { 0x9ac0fffe, mmCP_DFY_DATA_0 }, - { 0x26ac0002, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0xd8800033, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x1b301ff0, mmCP_DFY_DATA_0 }, - { 0x2b300300, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x9680000b, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0004, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400039, mmCP_DFY_DATA_0 }, - { 0xd0c00038, mmCP_DFY_DATA_0 }, - { 0xc43c0022, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0x8c0001a2, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0x24b00008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x18ac0024, mmCP_DFY_DATA_0 }, - { 0x2b304000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4113249, mmCP_DFY_DATA_0 }, - { 0x1910003e, mmCP_DFY_DATA_0 }, - { 0x99000002, mmCP_DFY_DATA_0 }, - { 0xd840003d, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0xcf01326c, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x12a80014, mmCP_DFY_DATA_0 }, - { 0x2220003f, mmCP_DFY_DATA_0 }, - { 0x7e2a000a, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xce01326c, mmCP_DFY_DATA_0 }, - { 0xd8800033, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0004, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8000039, mmCP_DFY_DATA_0 }, - { 0xd0c00038, mmCP_DFY_DATA_0 }, - { 0xc43c0022, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18dc003d, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0x041c0001, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x18d40030, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x18fc0034, mmCP_DFY_DATA_0 }, - { 0x24e8000f, mmCP_DFY_DATA_0 }, - { 0x06a80e71, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000edd, mmCP_DFY_DATA_0 }, - { 0x80000e91, mmCP_DFY_DATA_0 }, - { 0x80000e91, mmCP_DFY_DATA_0 }, - { 0x80000ea1, mmCP_DFY_DATA_0 }, - { 0x80000eaa, mmCP_DFY_DATA_0 }, - { 0x80000e7c, mmCP_DFY_DATA_0 }, - { 0x80000e7f, mmCP_DFY_DATA_0 }, - { 0x80000e7f, mmCP_DFY_DATA_0 }, - { 0x80000e87, mmCP_DFY_DATA_0 }, - { 0x80000e8f, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x51dc0020, mmCP_DFY_DATA_0 }, - { 0x7d9e001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0xc420000e, mmCP_DFY_DATA_0 }, - { 0x2a200008, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0xc4213262, mmCP_DFY_DATA_0 }, - { 0xc4253261, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0xc420000e, mmCP_DFY_DATA_0 }, - { 0x2a200008, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0xc4213264, mmCP_DFY_DATA_0 }, - { 0xc4253263, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0xc820001f, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0x18e82005, mmCP_DFY_DATA_0 }, - { 0x51e00020, mmCP_DFY_DATA_0 }, - { 0x2aa80000, mmCP_DFY_DATA_0 }, - { 0x7da1801a, mmCP_DFY_DATA_0 }, - { 0xd1800072, mmCP_DFY_DATA_0 }, - { 0xc8180072, mmCP_DFY_DATA_0 }, - { 0x59a001fc, mmCP_DFY_DATA_0 }, - { 0x12200009, mmCP_DFY_DATA_0 }, - { 0x7ea2800a, mmCP_DFY_DATA_0 }, - { 0xce80001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8200011, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0x15980002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd81c400, mmCP_DFY_DATA_0 }, - { 0xc421c401, mmCP_DFY_DATA_0 }, - { 0x95400041, mmCP_DFY_DATA_0 }, - { 0xc425c401, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0x31ac2580, mmCP_DFY_DATA_0 }, - { 0x9ac00011, mmCP_DFY_DATA_0 }, - { 0x31ac260c, mmCP_DFY_DATA_0 }, - { 0x9ac0000f, mmCP_DFY_DATA_0 }, - { 0x31ac0800, mmCP_DFY_DATA_0 }, - { 0x9ac0000d, mmCP_DFY_DATA_0 }, - { 0x31ac0828, mmCP_DFY_DATA_0 }, - { 0x9ac0000b, mmCP_DFY_DATA_0 }, - { 0x31ac2440, mmCP_DFY_DATA_0 }, - { 0x9ac00009, mmCP_DFY_DATA_0 }, - { 0x31ac2390, mmCP_DFY_DATA_0 }, - { 0x9ac00007, mmCP_DFY_DATA_0 }, - { 0x31ac0093, mmCP_DFY_DATA_0 }, - { 0x9ac00005, mmCP_DFY_DATA_0 }, - { 0x31ac31dc, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x31ac31e6, mmCP_DFY_DATA_0 }, - { 0x96c00004, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x80000ede, mmCP_DFY_DATA_0 }, - { 0x39ac7c06, mmCP_DFY_DATA_0 }, - { 0x3db07c00, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39acc337, mmCP_DFY_DATA_0 }, - { 0x3db0c330, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39acc335, mmCP_DFY_DATA_0 }, - { 0x3db0c336, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39ac9002, mmCP_DFY_DATA_0 }, - { 0x3db09001, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39ac9012, mmCP_DFY_DATA_0 }, - { 0x3db09011, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39acec70, mmCP_DFY_DATA_0 }, - { 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc5a10000, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0x05980001, mmCP_DFY_DATA_0 }, - { 0xc5a50000, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x05280eea, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000ef1, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x80000efe, mmCP_DFY_DATA_0 }, - { 0x80000f11, mmCP_DFY_DATA_0 }, - { 0x80000f2e, mmCP_DFY_DATA_0 }, - { 0x80000efe, mmCP_DFY_DATA_0 }, - { 0x80000f1f, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0x05980001, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x97c0f26f, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x51ec0020, mmCP_DFY_DATA_0 }, - { 0x18e80058, mmCP_DFY_DATA_0 }, - { 0x7daec01a, mmCP_DFY_DATA_0 }, - { 0xd2c00072, mmCP_DFY_DATA_0 }, - { 0xc82c0072, mmCP_DFY_DATA_0 }, - { 0x5af8073a, mmCP_DFY_DATA_0 }, - { 0x7eba800a, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xce800024, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0x95400003, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x97c0f25c, mmCP_DFY_DATA_0 }, - { 0xc4380012, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc02a0001, mmCP_DFY_DATA_0 }, - { 0x2aa80001, mmCP_DFY_DATA_0 }, - { 0x15980002, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xcd81c405, mmCP_DFY_DATA_0 }, - { 0xce01c406, mmCP_DFY_DATA_0 }, - { 0x95400003, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xce41c406, mmCP_DFY_DATA_0 }, - { 0x97c0f24e, mmCP_DFY_DATA_0 }, - { 0xc439c409, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a40f247, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0x95400004, mmCP_DFY_DATA_0 }, - { 0x05980001, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0x97c0f240, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x31ac2580, mmCP_DFY_DATA_0 }, - { 0x9ac00011, mmCP_DFY_DATA_0 }, - { 0x31ac260c, mmCP_DFY_DATA_0 }, - { 0x9ac0000f, mmCP_DFY_DATA_0 }, - { 0x31ac0800, mmCP_DFY_DATA_0 }, - { 0x9ac0000d, mmCP_DFY_DATA_0 }, - { 0x31ac0828, mmCP_DFY_DATA_0 }, - { 0x9ac0000b, mmCP_DFY_DATA_0 }, - { 0x31ac2440, mmCP_DFY_DATA_0 }, - { 0x9ac00009, mmCP_DFY_DATA_0 }, - { 0x31ac2390, mmCP_DFY_DATA_0 }, - { 0x9ac00007, mmCP_DFY_DATA_0 }, - { 0x31ac0093, mmCP_DFY_DATA_0 }, - { 0x9ac00005, mmCP_DFY_DATA_0 }, - { 0x31ac31dc, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x31ac31e6, mmCP_DFY_DATA_0 }, - { 0x96c00004, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x80000ef2, mmCP_DFY_DATA_0 }, - { 0x39ac7c06, mmCP_DFY_DATA_0 }, - { 0x3db07c00, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39acc337, mmCP_DFY_DATA_0 }, - { 0x3db0c330, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39acc335, mmCP_DFY_DATA_0 }, - { 0x3db0c336, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39acec70, mmCP_DFY_DATA_0 }, - { 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39ac9002, mmCP_DFY_DATA_0 }, - { 0x3db09002, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39ac9012, mmCP_DFY_DATA_0 }, - { 0x3db09012, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x80000ef1, mmCP_DFY_DATA_0 }, - { 0xc40c0006, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x95c00001, mmCP_DFY_DATA_0 }, - { 0xc434000e, mmCP_DFY_DATA_0 }, - { 0x2b740008, mmCP_DFY_DATA_0 }, - { 0x2b780001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd8c1325e, mmCP_DFY_DATA_0 }, - { 0xcf80001a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x7c034001, mmCP_DFY_DATA_0 }, - { 0x7c038001, mmCP_DFY_DATA_0 }, - { 0x18e0007d, mmCP_DFY_DATA_0 }, - { 0x32240003, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0x32240000, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xcd01c080, mmCP_DFY_DATA_0 }, - { 0xcd41c081, mmCP_DFY_DATA_0 }, - { 0x80000f88, mmCP_DFY_DATA_0 }, - { 0x51640020, mmCP_DFY_DATA_0 }, - { 0x7e52401a, mmCP_DFY_DATA_0 }, - { 0xd2400072, mmCP_DFY_DATA_0 }, - { 0xc8280072, mmCP_DFY_DATA_0 }, - { 0xce81c080, mmCP_DFY_DATA_0 }, - { 0x56ac0020, mmCP_DFY_DATA_0 }, - { 0x26f0ffff, mmCP_DFY_DATA_0 }, - { 0xcf01c081, mmCP_DFY_DATA_0 }, - { 0x1af000fc, mmCP_DFY_DATA_0 }, - { 0x1334000a, mmCP_DFY_DATA_0 }, - { 0x24e02000, mmCP_DFY_DATA_0 }, - { 0x7f63400a, mmCP_DFY_DATA_0 }, - { 0x18e00074, mmCP_DFY_DATA_0 }, - { 0x32240003, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0x32240000, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xcd81c082, mmCP_DFY_DATA_0 }, - { 0xcdc1c083, mmCP_DFY_DATA_0 }, - { 0x80000f9d, mmCP_DFY_DATA_0 }, - { 0x51e40020, mmCP_DFY_DATA_0 }, - { 0x7e5a401a, mmCP_DFY_DATA_0 }, - { 0xd2400072, mmCP_DFY_DATA_0 }, - { 0xc8280072, mmCP_DFY_DATA_0 }, - { 0xce81c082, mmCP_DFY_DATA_0 }, - { 0x56ac0020, mmCP_DFY_DATA_0 }, - { 0x26f0ffff, mmCP_DFY_DATA_0 }, - { 0xcf01c083, mmCP_DFY_DATA_0 }, - { 0x1af000fc, mmCP_DFY_DATA_0 }, - { 0x13380016, mmCP_DFY_DATA_0 }, - { 0x18e00039, mmCP_DFY_DATA_0 }, - { 0x12200019, mmCP_DFY_DATA_0 }, - { 0x7fa3800a, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x18e0007d, mmCP_DFY_DATA_0 }, - { 0x1220001d, mmCP_DFY_DATA_0 }, - { 0x7fa3800a, mmCP_DFY_DATA_0 }, - { 0x18e00074, mmCP_DFY_DATA_0 }, - { 0x12200014, mmCP_DFY_DATA_0 }, - { 0x7fa3800a, mmCP_DFY_DATA_0 }, - { 0xcf81c078, mmCP_DFY_DATA_0 }, - { 0xcfc1c084, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18dc003d, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0x041c0000, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x31140005, mmCP_DFY_DATA_0 }, - { 0x99400003, mmCP_DFY_DATA_0 }, - { 0x31140006, mmCP_DFY_DATA_0 }, - { 0x95400002, mmCP_DFY_DATA_0 }, - { 0x8c00104f, mmCP_DFY_DATA_0 }, - { 0x05280fb7, mmCP_DFY_DATA_0 }, - { 0x28140002, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000fbe, mmCP_DFY_DATA_0 }, - { 0x80000fbe, mmCP_DFY_DATA_0 }, - { 0x80000fc2, mmCP_DFY_DATA_0 }, - { 0x80000fbe, mmCP_DFY_DATA_0 }, - { 0x80000fd1, mmCP_DFY_DATA_0 }, - { 0x80000ff2, mmCP_DFY_DATA_0 }, - { 0x80000ff2, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x18e80039, mmCP_DFY_DATA_0 }, - { 0x52a8003b, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x7d69401a, mmCP_DFY_DATA_0 }, - { 0xc41c0017, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xd140004b, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc414000d, mmCP_DFY_DATA_0 }, - { 0x04180001, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0x7d958004, mmCP_DFY_DATA_0 }, - { 0xcd800035, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3249, mmCP_DFY_DATA_0 }, - { 0x1bfc003e, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0xc4100019, mmCP_DFY_DATA_0 }, - { 0x7d150005, mmCP_DFY_DATA_0 }, - { 0x25100001, mmCP_DFY_DATA_0 }, - { 0x9500000b, mmCP_DFY_DATA_0 }, - { 0x97c0fffc, mmCP_DFY_DATA_0 }, - { 0xc4180021, mmCP_DFY_DATA_0 }, - { 0x159c0011, mmCP_DFY_DATA_0 }, - { 0x259800ff, mmCP_DFY_DATA_0 }, - { 0x31a00003, mmCP_DFY_DATA_0 }, - { 0x31a40001, mmCP_DFY_DATA_0 }, - { 0x7e25800a, mmCP_DFY_DATA_0 }, - { 0x95c0fff5, mmCP_DFY_DATA_0 }, - { 0x9580fff4, mmCP_DFY_DATA_0 }, - { 0x80000fef, mmCP_DFY_DATA_0 }, - { 0xc411326f, mmCP_DFY_DATA_0 }, - { 0x1d100010, mmCP_DFY_DATA_0 }, - { 0xcd01326f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x04380000, mmCP_DFY_DATA_0 }, - { 0xc430000d, mmCP_DFY_DATA_0 }, - { 0xc8140023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0xc011000f, mmCP_DFY_DATA_0 }, - { 0xc4240004, mmCP_DFY_DATA_0 }, - { 0x33b40003, mmCP_DFY_DATA_0 }, - { 0x97400003, mmCP_DFY_DATA_0 }, - { 0xc0340008, mmCP_DFY_DATA_0 }, - { 0x80000ffe, mmCP_DFY_DATA_0 }, - { 0xc4340035, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x7c908009, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x7d614011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7ca4800a, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x7cb0800a, mmCP_DFY_DATA_0 }, - { 0x282c2002, mmCP_DFY_DATA_0 }, - { 0x208801a8, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0x7cb4800a, mmCP_DFY_DATA_0 }, - { 0xcec00013, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x042c0008, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x20240030, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0x9b800013, mmCP_DFY_DATA_0 }, - { 0xcc400026, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x28340000, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x507c0020, mmCP_DFY_DATA_0 }, - { 0x7d7d401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x557c0020, mmCP_DFY_DATA_0 }, - { 0x28342002, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcd400026, mmCP_DFY_DATA_0 }, - { 0xcfc00026, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0x9a80000e, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a80000b, mmCP_DFY_DATA_0 }, - { 0x8000102f, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x9a800005, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x1cccfe08, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcec0003a, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3249, mmCP_DFY_DATA_0 }, - { 0x1bfc003e, mmCP_DFY_DATA_0 }, - { 0x9bc00007, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x16a80008, mmCP_DFY_DATA_0 }, - { 0xce800009, mmCP_DFY_DATA_0 }, - { 0xc42c005e, mmCP_DFY_DATA_0 }, - { 0x96c00b33, mmCP_DFY_DATA_0 }, - { 0xd840003c, mmCP_DFY_DATA_0 }, - { 0xc4200025, mmCP_DFY_DATA_0 }, - { 0x7da2400f, mmCP_DFY_DATA_0 }, - { 0x7da28002, mmCP_DFY_DATA_0 }, - { 0x7e1ac002, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0x7d2ac002, mmCP_DFY_DATA_0 }, - { 0x3ef40010, mmCP_DFY_DATA_0 }, - { 0x9b40f11d, mmCP_DFY_DATA_0 }, - { 0x04380030, mmCP_DFY_DATA_0 }, - { 0xcf81325e, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xde410000, mmCP_DFY_DATA_0 }, - { 0xdcc10000, mmCP_DFY_DATA_0 }, - { 0xdd010000, mmCP_DFY_DATA_0 }, - { 0xdd410000, mmCP_DFY_DATA_0 }, - { 0xdd810000, mmCP_DFY_DATA_0 }, - { 0xddc10000, mmCP_DFY_DATA_0 }, - { 0xde010000, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x7c024001, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc8100086, mmCP_DFY_DATA_0 }, - { 0x5510003f, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x99000011, mmCP_DFY_DATA_0 }, - { 0x80001075, mmCP_DFY_DATA_0 }, - { 0x9900000c, mmCP_DFY_DATA_0 }, - { 0xc40c0026, mmCP_DFY_DATA_0 }, - { 0xc4100081, mmCP_DFY_DATA_0 }, - { 0xc4140025, mmCP_DFY_DATA_0 }, - { 0x7d15800f, mmCP_DFY_DATA_0 }, - { 0x7d15c002, mmCP_DFY_DATA_0 }, - { 0x7d520002, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x7cde0002, mmCP_DFY_DATA_0 }, - { 0x3e20001a, mmCP_DFY_DATA_0 }, - { 0x9a000009, mmCP_DFY_DATA_0 }, - { 0x040c0030, mmCP_DFY_DATA_0 }, - { 0xccc1325e, mmCP_DFY_DATA_0 }, - { 0x80001071, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c00b01, mmCP_DFY_DATA_0 }, - { 0x04240001, mmCP_DFY_DATA_0 }, - { 0xdc200000, mmCP_DFY_DATA_0 }, - { 0xdc1c0000, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0x96400004, mmCP_DFY_DATA_0 }, - { 0xdc240000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xdc240000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcc40003f, mmCP_DFY_DATA_0 }, - { 0xd8c00010, mmCP_DFY_DATA_0 }, - { 0xc4080029, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x18a400e5, mmCP_DFY_DATA_0 }, - { 0x12500009, mmCP_DFY_DATA_0 }, - { 0x248c0008, mmCP_DFY_DATA_0 }, - { 0x94c00006, mmCP_DFY_DATA_0 }, - { 0x200c006d, mmCP_DFY_DATA_0 }, - { 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { 0xccc1326c, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x200c0228, mmCP_DFY_DATA_0 }, - { 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { 0xccc1326c, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xc40c002a, mmCP_DFY_DATA_0 }, - { 0xc410002b, mmCP_DFY_DATA_0 }, - { 0x18881fe8, mmCP_DFY_DATA_0 }, - { 0x18d4072c, mmCP_DFY_DATA_0 }, - { 0x18cc00d1, mmCP_DFY_DATA_0 }, - { 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { 0x3094000d, mmCP_DFY_DATA_0 }, - { 0x38d80000, mmCP_DFY_DATA_0 }, - { 0x311c0003, mmCP_DFY_DATA_0 }, - { 0x99400006, mmCP_DFY_DATA_0 }, - { 0x30940007, mmCP_DFY_DATA_0 }, - { 0x1620001f, mmCP_DFY_DATA_0 }, - { 0x9940001d, mmCP_DFY_DATA_0 }, - { 0x9a000023, mmCP_DFY_DATA_0 }, - { 0x800010c4, mmCP_DFY_DATA_0 }, - { 0x9580001a, mmCP_DFY_DATA_0 }, - { 0x99c00019, mmCP_DFY_DATA_0 }, - { 0xccc00041, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0xc418002c, mmCP_DFY_DATA_0 }, - { 0x9940000d, mmCP_DFY_DATA_0 }, - { 0x259c007f, mmCP_DFY_DATA_0 }, - { 0x95c00013, mmCP_DFY_DATA_0 }, - { 0x19a00030, mmCP_DFY_DATA_0 }, - { 0xcdc0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xd8400022, mmCP_DFY_DATA_0 }, - { 0xc430000f, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x9a000012, mmCP_DFY_DATA_0 }, - { 0xd8400023, mmCP_DFY_DATA_0 }, - { 0x800010cb, mmCP_DFY_DATA_0 }, - { 0x199c0fe8, mmCP_DFY_DATA_0 }, - { 0xcdc0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xd8400023, mmCP_DFY_DATA_0 }, - { 0xc430000f, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x800010cb, mmCP_DFY_DATA_0 }, - { 0xd8c00010, mmCP_DFY_DATA_0 }, - { 0xd8000022, mmCP_DFY_DATA_0 }, - { 0xd8000023, mmCP_DFY_DATA_0 }, - { 0xc430005e, mmCP_DFY_DATA_0 }, - { 0x97000aac, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0xc434002e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0x2020002c, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xce01326c, mmCP_DFY_DATA_0 }, - { 0x17780001, mmCP_DFY_DATA_0 }, - { 0x27740001, mmCP_DFY_DATA_0 }, - { 0x07a810d8, mmCP_DFY_DATA_0 }, - { 0xcf400010, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0x80000bfc, mmCP_DFY_DATA_0 }, - { 0x800012e9, mmCP_DFY_DATA_0 }, - { 0x8000104c, mmCP_DFY_DATA_0 }, - { 0xcc400040, mmCP_DFY_DATA_0 }, - { 0xd8800010, mmCP_DFY_DATA_0 }, - { 0xc4180032, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x200c007d, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325b, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x28240007, mmCP_DFY_DATA_0 }, - { 0xde430000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0x24b00008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x98c00002, mmCP_DFY_DATA_0 }, - { 0xd840003d, mmCP_DFY_DATA_0 }, - { 0x2b304000, mmCP_DFY_DATA_0 }, - { 0xcf01326c, mmCP_DFY_DATA_0 }, - { 0xc431326c, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x192400fd, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x06681110, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0x18ac0024, mmCP_DFY_DATA_0 }, - { 0x19180070, mmCP_DFY_DATA_0 }, - { 0x19100078, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x18f40058, mmCP_DFY_DATA_0 }, - { 0x5978073a, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80001117, mmCP_DFY_DATA_0 }, - { 0x80001118, mmCP_DFY_DATA_0 }, - { 0x80001122, mmCP_DFY_DATA_0 }, - { 0x8000112d, mmCP_DFY_DATA_0 }, - { 0x80001130, mmCP_DFY_DATA_0 }, - { 0x80001133, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000117b, mmCP_DFY_DATA_0 }, - { 0x24ec0f00, mmCP_DFY_DATA_0 }, - { 0x32ec0600, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xc4300006, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x8000117b, mmCP_DFY_DATA_0 }, - { 0x24ec0f00, mmCP_DFY_DATA_0 }, - { 0x32ec0600, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xc4300006, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x8000117b, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0x80001122, mmCP_DFY_DATA_0 }, - { 0xc81c0020, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0x80001122, mmCP_DFY_DATA_0 }, - { 0x8c00116b, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc02a0200, mmCP_DFY_DATA_0 }, - { 0x7e8e8009, mmCP_DFY_DATA_0 }, - { 0x22a8003d, mmCP_DFY_DATA_0 }, - { 0x22a80074, mmCP_DFY_DATA_0 }, - { 0x2774001c, mmCP_DFY_DATA_0 }, - { 0x13740014, mmCP_DFY_DATA_0 }, - { 0x7eb6800a, mmCP_DFY_DATA_0 }, - { 0x25ecffff, mmCP_DFY_DATA_0 }, - { 0x55700020, mmCP_DFY_DATA_0 }, - { 0x15f40010, mmCP_DFY_DATA_0 }, - { 0x13740002, mmCP_DFY_DATA_0 }, - { 0x275c001f, mmCP_DFY_DATA_0 }, - { 0x95c00027, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0x7f41c001, mmCP_DFY_DATA_0 }, - { 0x15dc0002, mmCP_DFY_DATA_0 }, - { 0x39e00008, mmCP_DFY_DATA_0 }, - { 0x25dc0007, mmCP_DFY_DATA_0 }, - { 0x7dc1c01e, mmCP_DFY_DATA_0 }, - { 0x05dc0001, mmCP_DFY_DATA_0 }, - { 0x96000004, mmCP_DFY_DATA_0 }, - { 0x05e40008, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001168, mmCP_DFY_DATA_0 }, - { 0x7dc2001e, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x05e40008, mmCP_DFY_DATA_0 }, - { 0x7e62000e, mmCP_DFY_DATA_0 }, - { 0x9a000004, mmCP_DFY_DATA_0 }, - { 0x7da58001, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001165, mmCP_DFY_DATA_0 }, - { 0x7dc2001e, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x7e1a0001, mmCP_DFY_DATA_0 }, - { 0x05cc0008, mmCP_DFY_DATA_0 }, - { 0x7e0d000e, mmCP_DFY_DATA_0 }, - { 0x95000007, mmCP_DFY_DATA_0 }, - { 0x7e02401e, mmCP_DFY_DATA_0 }, - { 0x06640001, mmCP_DFY_DATA_0 }, - { 0x06640008, mmCP_DFY_DATA_0 }, - { 0x05d80008, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001168, mmCP_DFY_DATA_0 }, - { 0x7dc2401e, mmCP_DFY_DATA_0 }, - { 0x06640001, mmCP_DFY_DATA_0 }, - { 0x7da58001, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x05e00008, mmCP_DFY_DATA_0 }, - { 0x7da2000c, mmCP_DFY_DATA_0 }, - { 0x9600ffe6, mmCP_DFY_DATA_0 }, - { 0x17640002, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xc4200006, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x8c00116b, mmCP_DFY_DATA_0 }, - { 0xc420000e, mmCP_DFY_DATA_0 }, - { 0x2a200001, mmCP_DFY_DATA_0 }, - { 0xce00001a, mmCP_DFY_DATA_0 }, - { 0xce81c078, mmCP_DFY_DATA_0 }, - { 0xcec1c080, mmCP_DFY_DATA_0 }, - { 0xcc01c081, mmCP_DFY_DATA_0 }, - { 0xcd41c082, mmCP_DFY_DATA_0 }, - { 0xcf01c083, mmCP_DFY_DATA_0 }, - { 0x12640002, mmCP_DFY_DATA_0 }, - { 0x22640435, mmCP_DFY_DATA_0 }, - { 0xce41c084, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x0528117e, mmCP_DFY_DATA_0 }, - { 0x312c0003, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x80001185, mmCP_DFY_DATA_0 }, - { 0x80001182, mmCP_DFY_DATA_0 }, - { 0x80001182, mmCP_DFY_DATA_0 }, - { 0xc4300012, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0x9ac0000c, mmCP_DFY_DATA_0 }, - { 0xc03a0400, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x15980008, mmCP_DFY_DATA_0 }, - { 0x1198001c, mmCP_DFY_DATA_0 }, - { 0x7d81c00a, mmCP_DFY_DATA_0 }, - { 0xcdc130b7, mmCP_DFY_DATA_0 }, - { 0xcf8130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x04240008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0xc41c0049, mmCP_DFY_DATA_0 }, - { 0x19a000e8, mmCP_DFY_DATA_0 }, - { 0x29a80008, mmCP_DFY_DATA_0 }, - { 0x7de2c00c, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc421325e, mmCP_DFY_DATA_0 }, - { 0x26200010, mmCP_DFY_DATA_0 }, - { 0xc415326d, mmCP_DFY_DATA_0 }, - { 0x9a000006, mmCP_DFY_DATA_0 }, - { 0xc420007d, mmCP_DFY_DATA_0 }, - { 0x96000004, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xce40003e, mmCP_DFY_DATA_0 }, - { 0x800011a3, mmCP_DFY_DATA_0 }, - { 0x7d654001, mmCP_DFY_DATA_0 }, - { 0xcd41326d, mmCP_DFY_DATA_0 }, - { 0x7c020001, mmCP_DFY_DATA_0 }, - { 0x96000005, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0xc4240081, mmCP_DFY_DATA_0 }, - { 0xc4140025, mmCP_DFY_DATA_0 }, - { 0x800011b6, mmCP_DFY_DATA_0 }, - { 0xc4253279, mmCP_DFY_DATA_0 }, - { 0xc415326d, mmCP_DFY_DATA_0 }, - { 0xc431326c, mmCP_DFY_DATA_0 }, - { 0x2730003f, mmCP_DFY_DATA_0 }, - { 0x3b380006, mmCP_DFY_DATA_0 }, - { 0x97800004, mmCP_DFY_DATA_0 }, - { 0x3f38000b, mmCP_DFY_DATA_0 }, - { 0x9b800004, mmCP_DFY_DATA_0 }, - { 0x800011b4, mmCP_DFY_DATA_0 }, - { 0x04300006, mmCP_DFY_DATA_0 }, - { 0x800011b4, mmCP_DFY_DATA_0 }, - { 0x0430000b, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x7fb10004, mmCP_DFY_DATA_0 }, - { 0x7e57000f, mmCP_DFY_DATA_0 }, - { 0x7e578002, mmCP_DFY_DATA_0 }, - { 0x7d67c002, mmCP_DFY_DATA_0 }, - { 0x0be40001, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x7d3a4002, mmCP_DFY_DATA_0 }, - { 0x202c002c, mmCP_DFY_DATA_0 }, - { 0xc421325e, mmCP_DFY_DATA_0 }, - { 0x04280020, mmCP_DFY_DATA_0 }, - { 0xcec1326c, mmCP_DFY_DATA_0 }, - { 0x26200010, mmCP_DFY_DATA_0 }, - { 0x3e640010, mmCP_DFY_DATA_0 }, - { 0x96000003, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xce81325e, mmCP_DFY_DATA_0 }, - { 0xc4300028, mmCP_DFY_DATA_0 }, - { 0xc434002e, mmCP_DFY_DATA_0 }, - { 0x17780001, mmCP_DFY_DATA_0 }, - { 0x27740001, mmCP_DFY_DATA_0 }, - { 0x07a811cf, mmCP_DFY_DATA_0 }, - { 0x9b00feb8, mmCP_DFY_DATA_0 }, - { 0xcf400010, mmCP_DFY_DATA_0 }, - { 0xc414005e, mmCP_DFY_DATA_0 }, - { 0x954009a7, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0x80000bfc, mmCP_DFY_DATA_0 }, - { 0x800012e9, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0xccc1c07c, mmCP_DFY_DATA_0 }, - { 0xcc41c07d, mmCP_DFY_DATA_0 }, - { 0xcc41c08c, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xcc41c079, mmCP_DFY_DATA_0 }, - { 0xcd01c07e, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x18f0012f, mmCP_DFY_DATA_0 }, - { 0x18f40612, mmCP_DFY_DATA_0 }, - { 0x18cc00c1, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x7cf7400a, mmCP_DFY_DATA_0 }, - { 0x39600004, mmCP_DFY_DATA_0 }, - { 0x9a000002, mmCP_DFY_DATA_0 }, - { 0xc0140004, mmCP_DFY_DATA_0 }, - { 0x11600001, mmCP_DFY_DATA_0 }, - { 0x18fc003e, mmCP_DFY_DATA_0 }, - { 0x9740001c, mmCP_DFY_DATA_0 }, - { 0xcf400041, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0x97c00003, mmCP_DFY_DATA_0 }, - { 0x166c001f, mmCP_DFY_DATA_0 }, - { 0x800011ee, mmCP_DFY_DATA_0 }, - { 0x1a6c003e, mmCP_DFY_DATA_0 }, - { 0x96c00006, mmCP_DFY_DATA_0 }, - { 0x04200002, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x800011e8, mmCP_DFY_DATA_0 }, - { 0xc428002c, mmCP_DFY_DATA_0 }, - { 0x96800010, mmCP_DFY_DATA_0 }, - { 0x26ac007f, mmCP_DFY_DATA_0 }, - { 0xcec0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x1ab00030, mmCP_DFY_DATA_0 }, - { 0x1aac0fe8, mmCP_DFY_DATA_0 }, - { 0xc434000f, mmCP_DFY_DATA_0 }, - { 0x9b40ffff, mmCP_DFY_DATA_0 }, - { 0x97000008, mmCP_DFY_DATA_0 }, - { 0xcec0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc434000f, mmCP_DFY_DATA_0 }, - { 0x9b40ffff, mmCP_DFY_DATA_0 }, - { 0x80001205, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0x166c001f, mmCP_DFY_DATA_0 }, - { 0x11600001, mmCP_DFY_DATA_0 }, - { 0x9ac0fffa, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8000033, mmCP_DFY_DATA_0 }, - { 0xc438000b, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0001, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd841c07f, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x1bfc0078, mmCP_DFY_DATA_0 }, - { 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { 0x97c0fffd, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc03a2800, mmCP_DFY_DATA_0 }, - { 0xcf81c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04380040, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380060, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x17fc001f, mmCP_DFY_DATA_0 }, - { 0x04380010, mmCP_DFY_DATA_0 }, - { 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd801c07f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0xcfc00078, mmCP_DFY_DATA_0 }, - { 0xd8000034, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc03ae000, mmCP_DFY_DATA_0 }, - { 0xcf81c200, mmCP_DFY_DATA_0 }, - { 0xc03a0800, mmCP_DFY_DATA_0 }, - { 0xcf81c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04380040, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x17fc001f, mmCP_DFY_DATA_0 }, - { 0x04380010, mmCP_DFY_DATA_0 }, - { 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc03ae000, mmCP_DFY_DATA_0 }, - { 0xcf81c200, mmCP_DFY_DATA_0 }, - { 0xc03a4000, mmCP_DFY_DATA_0 }, - { 0xcf81c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x17fc001f, mmCP_DFY_DATA_0 }, - { 0x04380010, mmCP_DFY_DATA_0 }, - { 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x30d00002, mmCP_DFY_DATA_0 }, - { 0x99000052, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x9640090f, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x1514001f, mmCP_DFY_DATA_0 }, - { 0x19180038, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0x99400030, mmCP_DFY_DATA_0 }, - { 0x30dc0001, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x99c0000a, mmCP_DFY_DATA_0 }, - { 0xc42d324e, mmCP_DFY_DATA_0 }, - { 0xc431324d, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc435324f, mmCP_DFY_DATA_0 }, - { 0xc4293256, mmCP_DFY_DATA_0 }, - { 0x1ab0c006, mmCP_DFY_DATA_0 }, - { 0x52ec0008, mmCP_DFY_DATA_0 }, - { 0x8000127f, mmCP_DFY_DATA_0 }, - { 0xc42d3258, mmCP_DFY_DATA_0 }, - { 0xc4313257, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc4353259, mmCP_DFY_DATA_0 }, - { 0xc429325a, mmCP_DFY_DATA_0 }, - { 0x1ab0c012, mmCP_DFY_DATA_0 }, - { 0x07740001, mmCP_DFY_DATA_0 }, - { 0x04240002, mmCP_DFY_DATA_0 }, - { 0x26a0003f, mmCP_DFY_DATA_0 }, - { 0x7e624004, mmCP_DFY_DATA_0 }, - { 0x7f67800f, mmCP_DFY_DATA_0 }, - { 0x97800002, mmCP_DFY_DATA_0 }, - { 0x04340000, mmCP_DFY_DATA_0 }, - { 0x53740002, mmCP_DFY_DATA_0 }, - { 0x7ef6c011, mmCP_DFY_DATA_0 }, - { 0x1ab42010, mmCP_DFY_DATA_0 }, - { 0x16a8000c, mmCP_DFY_DATA_0 }, - { 0x26a80800, mmCP_DFY_DATA_0 }, - { 0x2b740000, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0xcf40001c, mmCP_DFY_DATA_0 }, - { 0xd2c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4100011, mmCP_DFY_DATA_0 }, - { 0x1514001f, mmCP_DFY_DATA_0 }, - { 0x99400006, mmCP_DFY_DATA_0 }, - { 0x9980000a, mmCP_DFY_DATA_0 }, - { 0x8c0012e1, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0x80001267, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x964008d7, mmCP_DFY_DATA_0 }, - { 0xd9800036, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc42c001d, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x1b300677, mmCP_DFY_DATA_0 }, - { 0x11dc000c, mmCP_DFY_DATA_0 }, - { 0x800012aa, mmCP_DFY_DATA_0 }, - { 0xc4313256, mmCP_DFY_DATA_0 }, - { 0x1b34060b, mmCP_DFY_DATA_0 }, - { 0x1b300077, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x13300017, mmCP_DFY_DATA_0 }, - { 0x04340100, mmCP_DFY_DATA_0 }, - { 0x26ec00ff, mmCP_DFY_DATA_0 }, - { 0xc03a8002, mmCP_DFY_DATA_0 }, - { 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { 0x7edec00a, mmCP_DFY_DATA_0 }, - { 0x7f3b000a, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc4140032, mmCP_DFY_DATA_0 }, - { 0xc410001d, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x1858003f, mmCP_DFY_DATA_0 }, - { 0x251000ff, mmCP_DFY_DATA_0 }, - { 0x99800007, mmCP_DFY_DATA_0 }, - { 0x7d0cc00a, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x18d0006c, mmCP_DFY_DATA_0 }, - { 0x18d407f0, mmCP_DFY_DATA_0 }, - { 0x9900000e, mmCP_DFY_DATA_0 }, - { 0x04100002, mmCP_DFY_DATA_0 }, - { 0xc4193256, mmCP_DFY_DATA_0 }, - { 0xc41d324f, mmCP_DFY_DATA_0 }, - { 0x2598003f, mmCP_DFY_DATA_0 }, - { 0x7d190004, mmCP_DFY_DATA_0 }, - { 0x7d5d4001, mmCP_DFY_DATA_0 }, - { 0x7d52000f, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0xcd41324f, mmCP_DFY_DATA_0 }, - { 0x800012d8, mmCP_DFY_DATA_0 }, - { 0x7d514002, mmCP_DFY_DATA_0 }, - { 0xcd41324f, mmCP_DFY_DATA_0 }, - { 0x800012d8, mmCP_DFY_DATA_0 }, - { 0xc4193259, mmCP_DFY_DATA_0 }, - { 0xc41d325a, mmCP_DFY_DATA_0 }, - { 0x7d958001, mmCP_DFY_DATA_0 }, - { 0x7dd5c002, mmCP_DFY_DATA_0 }, - { 0xcd813259, mmCP_DFY_DATA_0 }, - { 0xcdc1325a, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x1ccc001e, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0xc4340028, mmCP_DFY_DATA_0 }, - { 0x14f00010, mmCP_DFY_DATA_0 }, - { 0xc4380030, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x9b000004, mmCP_DFY_DATA_0 }, - { 0x9b40000c, mmCP_DFY_DATA_0 }, - { 0x9b80000f, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b000005, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd980003f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd9c0003f, mmCP_DFY_DATA_0 }, - { 0x80001082, mmCP_DFY_DATA_0 }, - { 0xd9800040, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd9c00040, mmCP_DFY_DATA_0 }, - { 0x800010de, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x33f80003, mmCP_DFY_DATA_0 }, - { 0x97800051, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0x24b00008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4353249, mmCP_DFY_DATA_0 }, - { 0x1b74003e, mmCP_DFY_DATA_0 }, - { 0x9b400002, mmCP_DFY_DATA_0 }, - { 0xd840003d, mmCP_DFY_DATA_0 }, - { 0x2b304000, mmCP_DFY_DATA_0 }, - { 0xcf01326c, mmCP_DFY_DATA_0 }, - { 0xc431326c, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x50700020, mmCP_DFY_DATA_0 }, - { 0x04e81324, mmCP_DFY_DATA_0 }, - { 0x18ac0024, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x50600020, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0x30e40004, mmCP_DFY_DATA_0 }, - { 0x9a400007, mmCP_DFY_DATA_0 }, - { 0x7d71401a, mmCP_DFY_DATA_0 }, - { 0x596401fc, mmCP_DFY_DATA_0 }, - { 0x12640009, mmCP_DFY_DATA_0 }, - { 0x1b74008d, mmCP_DFY_DATA_0 }, - { 0x7e76400a, mmCP_DFY_DATA_0 }, - { 0x2a640000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000132c, mmCP_DFY_DATA_0 }, - { 0x8000133b, mmCP_DFY_DATA_0 }, - { 0x80001344, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc42530b5, mmCP_DFY_DATA_0 }, - { 0x1a68003a, mmCP_DFY_DATA_0 }, - { 0x9a80fffe, mmCP_DFY_DATA_0 }, - { 0x2024003a, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x25980700, mmCP_DFY_DATA_0 }, - { 0x11980014, mmCP_DFY_DATA_0 }, - { 0x7d19000a, mmCP_DFY_DATA_0 }, - { 0xcd0130b7, mmCP_DFY_DATA_0 }, - { 0xce4130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xce40001c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc4240011, mmCP_DFY_DATA_0 }, - { 0x7de6800f, mmCP_DFY_DATA_0 }, - { 0x9a80ffea, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xce40001c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8240011, mmCP_DFY_DATA_0 }, - { 0x7de1c01a, mmCP_DFY_DATA_0 }, - { 0x7de6800f, mmCP_DFY_DATA_0 }, - { 0x9a80ffe0, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x8c00104f, mmCP_DFY_DATA_0 }, - { 0x28182002, mmCP_DFY_DATA_0 }, - { 0xc430000d, mmCP_DFY_DATA_0 }, - { 0xc4340035, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc8140023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0xc4240004, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x7d614011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7ca4800a, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x7cb0800a, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0x7cb4800a, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x042c0008, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x20240030, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0xcc400026, mmCP_DFY_DATA_0 }, - { 0x28340000, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x507c0020, mmCP_DFY_DATA_0 }, - { 0x30e40004, mmCP_DFY_DATA_0 }, - { 0x9a400005, mmCP_DFY_DATA_0 }, - { 0x7d7d401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x557c0020, mmCP_DFY_DATA_0 }, - { 0x28342002, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcd400026, mmCP_DFY_DATA_0 }, - { 0xcfc00026, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x9a800005, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0x04380028, mmCP_DFY_DATA_0 }, - { 0xcec0003a, mmCP_DFY_DATA_0 }, - { 0xcf81a2a4, mmCP_DFY_DATA_0 }, - { 0x80001037, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c007eb, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50500020, mmCP_DFY_DATA_0 }, - { 0x7d0d001a, mmCP_DFY_DATA_0 }, - { 0xd1000072, mmCP_DFY_DATA_0 }, - { 0xc8100072, mmCP_DFY_DATA_0 }, - { 0x591c01fc, mmCP_DFY_DATA_0 }, - { 0x11dc0009, mmCP_DFY_DATA_0 }, - { 0x45140210, mmCP_DFY_DATA_0 }, - { 0x595801fc, mmCP_DFY_DATA_0 }, - { 0x11980009, mmCP_DFY_DATA_0 }, - { 0x29dc0000, mmCP_DFY_DATA_0 }, - { 0xcdc0001c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4200011, mmCP_DFY_DATA_0 }, - { 0x1624001f, mmCP_DFY_DATA_0 }, - { 0x96400069, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xce013249, mmCP_DFY_DATA_0 }, - { 0x1a307fe8, mmCP_DFY_DATA_0 }, - { 0xcf00000a, mmCP_DFY_DATA_0 }, - { 0x23304076, mmCP_DFY_DATA_0 }, - { 0xd1000001, mmCP_DFY_DATA_0 }, - { 0xcf000001, mmCP_DFY_DATA_0 }, - { 0xc41d3254, mmCP_DFY_DATA_0 }, - { 0xc4253256, mmCP_DFY_DATA_0 }, - { 0x18cc00e8, mmCP_DFY_DATA_0 }, - { 0x10cc0015, mmCP_DFY_DATA_0 }, - { 0x4514020c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4200011, mmCP_DFY_DATA_0 }, - { 0xce013248, mmCP_DFY_DATA_0 }, - { 0x1a2001e8, mmCP_DFY_DATA_0 }, - { 0x12200014, mmCP_DFY_DATA_0 }, - { 0x2a204001, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0x1a64003c, mmCP_DFY_DATA_0 }, - { 0x1264001f, mmCP_DFY_DATA_0 }, - { 0x11dc0009, mmCP_DFY_DATA_0 }, - { 0x15dc000b, mmCP_DFY_DATA_0 }, - { 0x7dcdc00a, mmCP_DFY_DATA_0 }, - { 0x7e5dc00a, mmCP_DFY_DATA_0 }, - { 0xcdc00100, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcf00000d, mmCP_DFY_DATA_0 }, - { 0xcf00000a, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x04340022, mmCP_DFY_DATA_0 }, - { 0x07740001, mmCP_DFY_DATA_0 }, - { 0x04300010, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0xd4412e01, mmCP_DFY_DATA_0 }, - { 0x0434001e, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xdf030000, mmCP_DFY_DATA_0 }, - { 0xd4412e40, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc41c030, mmCP_DFY_DATA_0 }, - { 0xcc41c031, mmCP_DFY_DATA_0 }, - { 0x248dfffe, mmCP_DFY_DATA_0 }, - { 0xccc12e00, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcc812e00, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x45140248, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc8200011, mmCP_DFY_DATA_0 }, - { 0xce013257, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce013258, mmCP_DFY_DATA_0 }, - { 0x0434000c, mmCP_DFY_DATA_0 }, - { 0xdb000024, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x45540008, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc8200011, mmCP_DFY_DATA_0 }, - { 0xce013259, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xc0337fff, mmCP_DFY_DATA_0 }, - { 0x7f220009, mmCP_DFY_DATA_0 }, - { 0xce01325a, mmCP_DFY_DATA_0 }, - { 0x55300020, mmCP_DFY_DATA_0 }, - { 0x7d01c001, mmCP_DFY_DATA_0 }, - { 0x042c01d0, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x06ec0004, mmCP_DFY_DATA_0 }, - { 0x7f01c001, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x041c0002, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0xc4380012, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50500020, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xd0c00072, mmCP_DFY_DATA_0 }, - { 0xc8240072, mmCP_DFY_DATA_0 }, - { 0xd240001e, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x19682011, mmCP_DFY_DATA_0 }, - { 0x5a6c01fc, mmCP_DFY_DATA_0 }, - { 0x12ec0009, mmCP_DFY_DATA_0 }, - { 0x7eeac00a, mmCP_DFY_DATA_0 }, - { 0x2aec0000, mmCP_DFY_DATA_0 }, - { 0xcec0001c, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc430000f, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0xc4180011, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x99800007, mmCP_DFY_DATA_0 }, - { 0xdf830000, mmCP_DFY_DATA_0 }, - { 0xcfa0000c, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xd8000012, mmCP_DFY_DATA_0 }, - { 0xc43c0008, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400012, mmCP_DFY_DATA_0 }, - { 0xc43c0008, mmCP_DFY_DATA_0 }, - { 0x97c0ffff, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380007, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x17b80001, mmCP_DFY_DATA_0 }, - { 0x18d40038, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x9b800004, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc414005e, mmCP_DFY_DATA_0 }, - { 0x9540073d, mmCP_DFY_DATA_0 }, - { 0x18c80066, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x30880001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x94800008, mmCP_DFY_DATA_0 }, - { 0x8c00187c, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc42c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd910000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x7d410001, mmCP_DFY_DATA_0 }, - { 0x043c0000, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0x04240001, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x4220000c, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0xcc000078, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x24e80007, mmCP_DFY_DATA_0 }, - { 0x24ec0010, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x9ac00006, mmCP_DFY_DATA_0 }, - { 0xc42c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc5310000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x80001465, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xd1000072, mmCP_DFY_DATA_0 }, - { 0xc82c0072, mmCP_DFY_DATA_0 }, - { 0xd2c0001e, mmCP_DFY_DATA_0 }, - { 0x18f02011, mmCP_DFY_DATA_0 }, - { 0x5aec01fc, mmCP_DFY_DATA_0 }, - { 0x12ec0009, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0x2aec0000, mmCP_DFY_DATA_0 }, - { 0xcec0001c, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x96800012, mmCP_DFY_DATA_0 }, - { 0x12a80001, mmCP_DFY_DATA_0 }, - { 0x0aa80001, mmCP_DFY_DATA_0 }, - { 0x06a8146a, mmCP_DFY_DATA_0 }, - { 0x7f1f0009, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x7f1b400f, mmCP_DFY_DATA_0 }, - { 0x80001478, mmCP_DFY_DATA_0 }, - { 0x7f1b400e, mmCP_DFY_DATA_0 }, - { 0x80001478, mmCP_DFY_DATA_0 }, - { 0x7f1b400c, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f1b400d, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f1b400f, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f1b400e, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f334002, mmCP_DFY_DATA_0 }, - { 0x97400014, mmCP_DFY_DATA_0 }, - { 0x8000147b, mmCP_DFY_DATA_0 }, - { 0x9b400012, mmCP_DFY_DATA_0 }, - { 0x9b800005, mmCP_DFY_DATA_0 }, - { 0x9bc0001f, mmCP_DFY_DATA_0 }, - { 0x7e024001, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x8000144a, mmCP_DFY_DATA_0 }, - { 0xc40c0032, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d325b, mmCP_DFY_DATA_0 }, - { 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { 0x7fbfc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x94800007, mmCP_DFY_DATA_0 }, - { 0x8c00187c, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc42c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd910000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x9b800003, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc40c0032, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x800012c2, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0xc43d3256, mmCP_DFY_DATA_0 }, - { 0x1bf0060b, mmCP_DFY_DATA_0 }, - { 0x1bfc0077, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x800014a9, mmCP_DFY_DATA_0 }, - { 0xc43d325a, mmCP_DFY_DATA_0 }, - { 0x1bfc0677, mmCP_DFY_DATA_0 }, - { 0x04300100, mmCP_DFY_DATA_0 }, - { 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xc0328007, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x13fc0017, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0xc03a0002, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcf8130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x043c0000, mmCP_DFY_DATA_0 }, - { 0xc414000e, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7dd9c01a, mmCP_DFY_DATA_0 }, - { 0x45dc0390, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0x1b380057, mmCP_DFY_DATA_0 }, - { 0x1b340213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd1c00025, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0x7c424001, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x7c428001, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0x7c42c001, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0x7c430001, mmCP_DFY_DATA_0 }, - { 0xcf000026, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0xcf800026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xd840004f, mmCP_DFY_DATA_0 }, - { 0x1a0800fd, mmCP_DFY_DATA_0 }, - { 0x109c000a, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { 0xcdc13265, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0xce080228, mmCP_DFY_DATA_0 }, - { 0x9880000e, mmCP_DFY_DATA_0 }, - { 0xce480250, mmCP_DFY_DATA_0 }, - { 0xce880258, mmCP_DFY_DATA_0 }, - { 0xd8080230, mmCP_DFY_DATA_0 }, - { 0xd8080238, mmCP_DFY_DATA_0 }, - { 0xd8080240, mmCP_DFY_DATA_0 }, - { 0xd8080248, mmCP_DFY_DATA_0 }, - { 0xd8080268, mmCP_DFY_DATA_0 }, - { 0xd8080270, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x97c0ec75, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x041c0010, mmCP_DFY_DATA_0 }, - { 0x26180001, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x16200001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x99c0fffb, mmCP_DFY_DATA_0 }, - { 0xccc80230, mmCP_DFY_DATA_0 }, - { 0xd8080238, mmCP_DFY_DATA_0 }, - { 0xd8080240, mmCP_DFY_DATA_0 }, - { 0xd8080248, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0xce480250, mmCP_DFY_DATA_0 }, - { 0xce880258, mmCP_DFY_DATA_0 }, - { 0x52a80020, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x041c0020, mmCP_DFY_DATA_0 }, - { 0x66580001, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x56640001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x99c0fffb, mmCP_DFY_DATA_0 }, - { 0xccc80260, mmCP_DFY_DATA_0 }, - { 0xd8080268, mmCP_DFY_DATA_0 }, - { 0xd8080270, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0xcec80288, mmCP_DFY_DATA_0 }, - { 0xcf080290, mmCP_DFY_DATA_0 }, - { 0xcec80298, mmCP_DFY_DATA_0 }, - { 0xcf0802a0, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x041c0010, mmCP_DFY_DATA_0 }, - { 0xcf4802a8, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x17740001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x99c0fffb, mmCP_DFY_DATA_0 }, - { 0xccc802b0, mmCP_DFY_DATA_0 }, - { 0xd80802b8, mmCP_DFY_DATA_0 }, - { 0x178c000b, mmCP_DFY_DATA_0 }, - { 0x27b8003f, mmCP_DFY_DATA_0 }, - { 0x7cf8c001, mmCP_DFY_DATA_0 }, - { 0xcf8802c0, mmCP_DFY_DATA_0 }, - { 0xccc802c8, mmCP_DFY_DATA_0 }, - { 0xcf8802d0, mmCP_DFY_DATA_0 }, - { 0xcf8802d8, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x25b8ffff, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0xc48f0238, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x24cc000f, mmCP_DFY_DATA_0 }, - { 0x7cd2800c, mmCP_DFY_DATA_0 }, - { 0x9a80000b, mmCP_DFY_DATA_0 }, - { 0xc5230309, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0x7e3a400c, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x80001539, mmCP_DFY_DATA_0 }, - { 0xcd08034b, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x98c00004, mmCP_DFY_DATA_0 }, - { 0xcd880353, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0xc49b0353, mmCP_DFY_DATA_0 }, - { 0xc4930238, mmCP_DFY_DATA_0 }, - { 0xc48f0228, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x7cd14005, mmCP_DFY_DATA_0 }, - { 0x25540001, mmCP_DFY_DATA_0 }, - { 0x99400004, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x8000154f, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0xcd080238, mmCP_DFY_DATA_0 }, - { 0xcd08034b, mmCP_DFY_DATA_0 }, - { 0x08cc0001, mmCP_DFY_DATA_0 }, - { 0x2598ffff, mmCP_DFY_DATA_0 }, - { 0x3d200008, mmCP_DFY_DATA_0 }, - { 0xccc80230, mmCP_DFY_DATA_0 }, - { 0xcd900309, mmCP_DFY_DATA_0 }, - { 0xd8100319, mmCP_DFY_DATA_0 }, - { 0x04340801, mmCP_DFY_DATA_0 }, - { 0x2198003f, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcd910ce7, mmCP_DFY_DATA_0 }, - { 0xc4190ce6, mmCP_DFY_DATA_0 }, - { 0x7d918005, mmCP_DFY_DATA_0 }, - { 0x25980001, mmCP_DFY_DATA_0 }, - { 0x9580fffd, mmCP_DFY_DATA_0 }, - { 0x7d918004, mmCP_DFY_DATA_0 }, - { 0xcd810ce6, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0xcdd1054f, mmCP_DFY_DATA_0 }, - { 0x8000156e, mmCP_DFY_DATA_0 }, - { 0x090c0008, mmCP_DFY_DATA_0 }, - { 0xcdcd050e, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x110c0014, mmCP_DFY_DATA_0 }, - { 0x28cc4001, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xcc41230a, mmCP_DFY_DATA_0 }, - { 0xcc41230b, mmCP_DFY_DATA_0 }, - { 0xcc41230c, mmCP_DFY_DATA_0 }, - { 0xcc41230d, mmCP_DFY_DATA_0 }, - { 0xcc480329, mmCP_DFY_DATA_0 }, - { 0xcc48032a, mmCP_DFY_DATA_0 }, - { 0xcc4802e0, mmCP_DFY_DATA_0 }, - { 0xd8000055, mmCP_DFY_DATA_0 }, - { 0xc48f02e0, mmCP_DFY_DATA_0 }, - { 0x24d8003f, mmCP_DFY_DATA_0 }, - { 0x09940001, mmCP_DFY_DATA_0 }, - { 0x44100001, mmCP_DFY_DATA_0 }, - { 0x9580002c, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x51100001, mmCP_DFY_DATA_0 }, - { 0x69100001, mmCP_DFY_DATA_0 }, - { 0x8000157f, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0xc4970290, mmCP_DFY_DATA_0 }, - { 0xc49b0288, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xc49b02a0, mmCP_DFY_DATA_0 }, - { 0xc49f0298, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x041c0040, mmCP_DFY_DATA_0 }, - { 0x04200000, mmCP_DFY_DATA_0 }, - { 0x7dcdc002, mmCP_DFY_DATA_0 }, - { 0x7d924019, mmCP_DFY_DATA_0 }, - { 0x7d26400c, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x9a400008, mmCP_DFY_DATA_0 }, - { 0x51100001, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x99c0fffa, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0x80001579, mmCP_DFY_DATA_0 }, - { 0x7d010021, mmCP_DFY_DATA_0 }, - { 0x7d914019, mmCP_DFY_DATA_0 }, - { 0xc4930238, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0xcd480298, mmCP_DFY_DATA_0 }, - { 0xcd8802a0, mmCP_DFY_DATA_0 }, - { 0x10d40010, mmCP_DFY_DATA_0 }, - { 0x12180016, mmCP_DFY_DATA_0 }, - { 0xc51f0309, mmCP_DFY_DATA_0 }, - { 0x7d95800a, mmCP_DFY_DATA_0 }, - { 0x7d62000a, mmCP_DFY_DATA_0 }, - { 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdd00309, mmCP_DFY_DATA_0 }, - { 0xce113320, mmCP_DFY_DATA_0 }, - { 0xc48f02e0, mmCP_DFY_DATA_0 }, - { 0xc49b02b0, mmCP_DFY_DATA_0 }, - { 0x18dc01e8, mmCP_DFY_DATA_0 }, - { 0x7dd9400e, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x95c0001d, mmCP_DFY_DATA_0 }, - { 0x95400003, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0x800015aa, mmCP_DFY_DATA_0 }, - { 0xc48f0238, mmCP_DFY_DATA_0 }, - { 0xc4a302b8, mmCP_DFY_DATA_0 }, - { 0x12240004, mmCP_DFY_DATA_0 }, - { 0x7e5e400a, mmCP_DFY_DATA_0 }, - { 0xc4ab02a8, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0xce4c0319, mmCP_DFY_DATA_0 }, - { 0x7d9d8002, mmCP_DFY_DATA_0 }, - { 0x7ea14005, mmCP_DFY_DATA_0 }, - { 0x25540001, mmCP_DFY_DATA_0 }, - { 0x99400004, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x2620000f, mmCP_DFY_DATA_0 }, - { 0x800015bc, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x04240001, mmCP_DFY_DATA_0 }, - { 0x7e624004, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x7d25000a, mmCP_DFY_DATA_0 }, - { 0x2620000f, mmCP_DFY_DATA_0 }, - { 0x99c0fff4, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd0d3330, mmCP_DFY_DATA_0 }, - { 0xce0802b8, mmCP_DFY_DATA_0 }, - { 0xcd8802b0, mmCP_DFY_DATA_0 }, - { 0xc4ab02e0, mmCP_DFY_DATA_0 }, - { 0x1aa807f0, mmCP_DFY_DATA_0 }, - { 0xc48f02d0, mmCP_DFY_DATA_0 }, - { 0xc49702d8, mmCP_DFY_DATA_0 }, - { 0xc49b02c8, mmCP_DFY_DATA_0 }, - { 0xc49f02c0, mmCP_DFY_DATA_0 }, - { 0x96800028, mmCP_DFY_DATA_0 }, - { 0x7d4e000f, mmCP_DFY_DATA_0 }, - { 0x9600000b, mmCP_DFY_DATA_0 }, - { 0x7d964002, mmCP_DFY_DATA_0 }, - { 0x7e6a000f, mmCP_DFY_DATA_0 }, - { 0x96000003, mmCP_DFY_DATA_0 }, - { 0x7d694001, mmCP_DFY_DATA_0 }, - { 0x800015e9, mmCP_DFY_DATA_0 }, - { 0x7cde4002, mmCP_DFY_DATA_0 }, - { 0x7e6a000f, mmCP_DFY_DATA_0 }, - { 0x96000008, mmCP_DFY_DATA_0 }, - { 0x7de94001, mmCP_DFY_DATA_0 }, - { 0x800015e9, mmCP_DFY_DATA_0 }, - { 0x7cd64002, mmCP_DFY_DATA_0 }, - { 0x7e6a000e, mmCP_DFY_DATA_0 }, - { 0x96000003, mmCP_DFY_DATA_0 }, - { 0x7d694001, mmCP_DFY_DATA_0 }, - { 0x800015e9, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0x800015cd, mmCP_DFY_DATA_0 }, - { 0xc4930238, mmCP_DFY_DATA_0 }, - { 0x7d698002, mmCP_DFY_DATA_0 }, - { 0xcd4802d8, mmCP_DFY_DATA_0 }, - { 0x129c0008, mmCP_DFY_DATA_0 }, - { 0xc50f0319, mmCP_DFY_DATA_0 }, - { 0x11a0000e, mmCP_DFY_DATA_0 }, - { 0x11140001, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x7e1e000a, mmCP_DFY_DATA_0 }, - { 0x1198000a, mmCP_DFY_DATA_0 }, - { 0xcd953300, mmCP_DFY_DATA_0 }, - { 0x7e0e000a, mmCP_DFY_DATA_0 }, - { 0x12a8000a, mmCP_DFY_DATA_0 }, - { 0xce953301, mmCP_DFY_DATA_0 }, - { 0xce100319, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0xc4b70280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x7f73800a, mmCP_DFY_DATA_0 }, - { 0x536c0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x9780eb68, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x043c0003, mmCP_DFY_DATA_0 }, - { 0x80001609, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x30b40000, mmCP_DFY_DATA_0 }, - { 0x9b400011, mmCP_DFY_DATA_0 }, - { 0xc4b70258, mmCP_DFY_DATA_0 }, - { 0xc4b30250, mmCP_DFY_DATA_0 }, - { 0x53780020, mmCP_DFY_DATA_0 }, - { 0x7fb3801a, mmCP_DFY_DATA_0 }, - { 0x7faf8019, mmCP_DFY_DATA_0 }, - { 0x04300020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x67b40001, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x57b80001, mmCP_DFY_DATA_0 }, - { 0x97400002, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9b00fffb, mmCP_DFY_DATA_0 }, - { 0xc4bb0260, mmCP_DFY_DATA_0 }, - { 0x7fab8001, mmCP_DFY_DATA_0 }, - { 0xcf880260, mmCP_DFY_DATA_0 }, - { 0x04300020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x66f40001, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x56ec0001, mmCP_DFY_DATA_0 }, - { 0x97400005, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4353247, mmCP_DFY_DATA_0 }, - { 0x7f7f4009, mmCP_DFY_DATA_0 }, - { 0x9b40fffe, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9b00fff7, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x269c0007, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0x29dc0008, mmCP_DFY_DATA_0 }, - { 0x26a00018, mmCP_DFY_DATA_0 }, - { 0x12200003, mmCP_DFY_DATA_0 }, - { 0x7de1c00a, mmCP_DFY_DATA_0 }, - { 0x26a00060, mmCP_DFY_DATA_0 }, - { 0x06200020, mmCP_DFY_DATA_0 }, - { 0x16200001, mmCP_DFY_DATA_0 }, - { 0x7de1c00a, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x269c0018, mmCP_DFY_DATA_0 }, - { 0x26a00007, mmCP_DFY_DATA_0 }, - { 0x26a40060, mmCP_DFY_DATA_0 }, - { 0x11dc0006, mmCP_DFY_DATA_0 }, - { 0x12200006, mmCP_DFY_DATA_0 }, - { 0x16640001, mmCP_DFY_DATA_0 }, - { 0x29dc0008, mmCP_DFY_DATA_0 }, - { 0x7de1c00a, mmCP_DFY_DATA_0 }, - { 0x7de5c00a, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4b70228, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0xccc80230, mmCP_DFY_DATA_0 }, - { 0x7f514005, mmCP_DFY_DATA_0 }, - { 0x25540001, mmCP_DFY_DATA_0 }, - { 0x99400004, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x80001644, mmCP_DFY_DATA_0 }, - { 0xc4b30248, mmCP_DFY_DATA_0 }, - { 0xcd080240, mmCP_DFY_DATA_0 }, - { 0x7f130005, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0x9b000002, mmCP_DFY_DATA_0 }, - { 0x8c001688, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001219, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x04340801, mmCP_DFY_DATA_0 }, - { 0x7f130004, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcf01051e, mmCP_DFY_DATA_0 }, - { 0xc42d051f, mmCP_DFY_DATA_0 }, - { 0x7ed2c005, mmCP_DFY_DATA_0 }, - { 0x26ec0001, mmCP_DFY_DATA_0 }, - { 0x96c0fffd, mmCP_DFY_DATA_0 }, - { 0xcf01051f, mmCP_DFY_DATA_0 }, - { 0xd8000055, mmCP_DFY_DATA_0 }, - { 0xc5170309, mmCP_DFY_DATA_0 }, - { 0x195c07f0, mmCP_DFY_DATA_0 }, - { 0x196007f6, mmCP_DFY_DATA_0 }, - { 0x04340000, mmCP_DFY_DATA_0 }, - { 0x95c00008, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x04340001, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x53740001, mmCP_DFY_DATA_0 }, - { 0x6b740001, mmCP_DFY_DATA_0 }, - { 0x80001665, mmCP_DFY_DATA_0 }, - { 0xc4a702a0, mmCP_DFY_DATA_0 }, - { 0xc4ab0298, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x7f634014, mmCP_DFY_DATA_0 }, - { 0x7e76401a, mmCP_DFY_DATA_0 }, - { 0xc4300004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x56680020, mmCP_DFY_DATA_0 }, - { 0xd8113320, mmCP_DFY_DATA_0 }, - { 0xce480298, mmCP_DFY_DATA_0 }, - { 0xce8802a0, mmCP_DFY_DATA_0 }, - { 0xc5170319, mmCP_DFY_DATA_0 }, - { 0xc4b702b0, mmCP_DFY_DATA_0 }, - { 0x255c000f, mmCP_DFY_DATA_0 }, - { 0x7f5f4001, mmCP_DFY_DATA_0 }, - { 0xd8113330, mmCP_DFY_DATA_0 }, - { 0xcf4802b0, mmCP_DFY_DATA_0 }, - { 0x11340001, mmCP_DFY_DATA_0 }, - { 0x195c07e8, mmCP_DFY_DATA_0 }, - { 0x196007ee, mmCP_DFY_DATA_0 }, - { 0xd8353300, mmCP_DFY_DATA_0 }, - { 0x7e1e4001, mmCP_DFY_DATA_0 }, - { 0xd8353301, mmCP_DFY_DATA_0 }, - { 0xce4802d0, mmCP_DFY_DATA_0 }, - { 0xd8100309, mmCP_DFY_DATA_0 }, - { 0xd8100319, mmCP_DFY_DATA_0 }, - { 0xcf000008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc48f0250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7cd4c01a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x64d80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x54cc0001, mmCP_DFY_DATA_0 }, - { 0x95800060, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4193247, mmCP_DFY_DATA_0 }, - { 0x25980001, mmCP_DFY_DATA_0 }, - { 0x9580005c, mmCP_DFY_DATA_0 }, - { 0x7dc24001, mmCP_DFY_DATA_0 }, - { 0xc41d3248, mmCP_DFY_DATA_0 }, - { 0x25dc000f, mmCP_DFY_DATA_0 }, - { 0x7dd2000c, mmCP_DFY_DATA_0 }, - { 0x96000057, mmCP_DFY_DATA_0 }, - { 0xc41d3255, mmCP_DFY_DATA_0 }, - { 0xc435324f, mmCP_DFY_DATA_0 }, - { 0x7df5c00c, mmCP_DFY_DATA_0 }, - { 0x99c00004, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x25980040, mmCP_DFY_DATA_0 }, - { 0x9580fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x1bb0003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1bb000e8, mmCP_DFY_DATA_0 }, - { 0x33380003, mmCP_DFY_DATA_0 }, - { 0x9b800046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xc4393260, mmCP_DFY_DATA_0 }, - { 0x1bb000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x800016f1, mmCP_DFY_DATA_0 }, - { 0xce400013, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x7f3b0009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b800ff, mmCP_DFY_DATA_0 }, - { 0x9b80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x1a7003e6, mmCP_DFY_DATA_0 }, - { 0x27380003, mmCP_DFY_DATA_0 }, - { 0x13b80004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x1a7000e8, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x07b80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x1a700064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x800016df, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7fb30002, mmCP_DFY_DATA_0 }, - { 0xc4392083, mmCP_DFY_DATA_0 }, - { 0x7fb38005, mmCP_DFY_DATA_0 }, - { 0x27b80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xce400013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffca, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x800016f2, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940ff9c, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd840004f, mmCP_DFY_DATA_0 }, - { 0xc414000e, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0xd80802e9, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18fc0064, mmCP_DFY_DATA_0 }, - { 0x9bc00042, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7dd9801a, mmCP_DFY_DATA_0 }, - { 0x45980400, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x043c3000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0x9bc00001, mmCP_DFY_DATA_0 }, - { 0x1b380057, mmCP_DFY_DATA_0 }, - { 0x1b340213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0x14f4001d, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x9bc0001c, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x192807fa, mmCP_DFY_DATA_0 }, - { 0xc4bf0258, mmCP_DFY_DATA_0 }, - { 0xc4a70250, mmCP_DFY_DATA_0 }, - { 0x53fc0020, mmCP_DFY_DATA_0 }, - { 0x7e7e401a, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0x04300000, mmCP_DFY_DATA_0 }, - { 0x667c0001, mmCP_DFY_DATA_0 }, - { 0x56640001, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x97c0fffd, mmCP_DFY_DATA_0 }, - { 0x07300001, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x7eebc00c, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x97c0fff8, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x43300007, mmCP_DFY_DATA_0 }, - { 0x53300002, mmCP_DFY_DATA_0 }, - { 0x7db30011, mmCP_DFY_DATA_0 }, - { 0xd3000025, mmCP_DFY_DATA_0 }, - { 0xc03ec005, mmCP_DFY_DATA_0 }, - { 0x2bfca200, mmCP_DFY_DATA_0 }, - { 0xcfc00026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0xcd000026, mmCP_DFY_DATA_0 }, - { 0x192807fa, mmCP_DFY_DATA_0 }, - { 0xc01f007f, mmCP_DFY_DATA_0 }, - { 0x7d1d0009, mmCP_DFY_DATA_0 }, - { 0x2110007d, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x203c003f, mmCP_DFY_DATA_0 }, - { 0xcfc13256, mmCP_DFY_DATA_0 }, - { 0x8c0017f5, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0x18fc01e8, mmCP_DFY_DATA_0 }, - { 0xcfc13248, mmCP_DFY_DATA_0 }, - { 0x8c00185b, mmCP_DFY_DATA_0 }, - { 0xd8413247, mmCP_DFY_DATA_0 }, - { 0x0b740001, mmCP_DFY_DATA_0 }, - { 0x9b40ffd5, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x97c0ea24, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x14d4001d, mmCP_DFY_DATA_0 }, - { 0xc4930260, mmCP_DFY_DATA_0 }, - { 0x7d52400e, mmCP_DFY_DATA_0 }, - { 0xc49f0258, mmCP_DFY_DATA_0 }, - { 0xc4a30250, mmCP_DFY_DATA_0 }, - { 0x51dc0020, mmCP_DFY_DATA_0 }, - { 0x7de1801a, mmCP_DFY_DATA_0 }, - { 0x96400017, mmCP_DFY_DATA_0 }, - { 0x7d534002, mmCP_DFY_DATA_0 }, - { 0xc4af0270, mmCP_DFY_DATA_0 }, - { 0x7dae4005, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x32e0001f, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0xcec80270, mmCP_DFY_DATA_0 }, - { 0x8000174f, mmCP_DFY_DATA_0 }, - { 0x0b740001, mmCP_DFY_DATA_0 }, - { 0x8c00178a, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x9b40fff3, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0xc4ab0268, mmCP_DFY_DATA_0 }, - { 0x7daa4005, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x32a0001f, mmCP_DFY_DATA_0 }, - { 0x9a400005, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0x24280000, mmCP_DFY_DATA_0 }, - { 0x80001765, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xc01f007f, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x7d1d0009, mmCP_DFY_DATA_0 }, - { 0x2110007d, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xd8013256, mmCP_DFY_DATA_0 }, - { 0x8c0017f2, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0xc4113248, mmCP_DFY_DATA_0 }, - { 0x15100004, mmCP_DFY_DATA_0 }, - { 0x11100004, mmCP_DFY_DATA_0 }, - { 0xc4b3034b, mmCP_DFY_DATA_0 }, - { 0x7f13000a, mmCP_DFY_DATA_0 }, - { 0xcf013248, mmCP_DFY_DATA_0 }, - { 0xc4930260, mmCP_DFY_DATA_0 }, - { 0x8c001855, mmCP_DFY_DATA_0 }, - { 0x32a4001f, mmCP_DFY_DATA_0 }, - { 0xd8413247, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x09100001, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0x24280000, mmCP_DFY_DATA_0 }, - { 0xcd080260, mmCP_DFY_DATA_0 }, - { 0xce880268, mmCP_DFY_DATA_0 }, - { 0x9940ffc0, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7ec28001, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x32e0001f, mmCP_DFY_DATA_0 }, - { 0xc4253247, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9640005e, mmCP_DFY_DATA_0 }, - { 0xc4293265, mmCP_DFY_DATA_0 }, - { 0xc4253255, mmCP_DFY_DATA_0 }, - { 0xc431324f, mmCP_DFY_DATA_0 }, - { 0x7e72400c, mmCP_DFY_DATA_0 }, - { 0x26a80040, mmCP_DFY_DATA_0 }, - { 0x9a400002, mmCP_DFY_DATA_0 }, - { 0x9680fff7, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x1aa4003f, mmCP_DFY_DATA_0 }, - { 0x96400049, mmCP_DFY_DATA_0 }, - { 0x1aa400e8, mmCP_DFY_DATA_0 }, - { 0x32680003, mmCP_DFY_DATA_0 }, - { 0x9a800046, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9640000a, mmCP_DFY_DATA_0 }, - { 0xc4293260, mmCP_DFY_DATA_0 }, - { 0x1aa400e4, mmCP_DFY_DATA_0 }, - { 0x32640004, mmCP_DFY_DATA_0 }, - { 0x96400040, mmCP_DFY_DATA_0 }, - { 0xc425325d, mmCP_DFY_DATA_0 }, - { 0x26640010, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x800017e2, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc027ffff, mmCP_DFY_DATA_0 }, - { 0x2e6400ff, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x7e6a4009, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x26a800ff, mmCP_DFY_DATA_0 }, - { 0x9a80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4240009, mmCP_DFY_DATA_0 }, - { 0x26640008, mmCP_DFY_DATA_0 }, - { 0x9640fffe, mmCP_DFY_DATA_0 }, - { 0x19e403e6, mmCP_DFY_DATA_0 }, - { 0x26680003, mmCP_DFY_DATA_0 }, - { 0x12a80004, mmCP_DFY_DATA_0 }, - { 0x26640003, mmCP_DFY_DATA_0 }, - { 0x12640003, mmCP_DFY_DATA_0 }, - { 0x7ea68001, mmCP_DFY_DATA_0 }, - { 0x19e400e8, mmCP_DFY_DATA_0 }, - { 0x7ea68001, mmCP_DFY_DATA_0 }, - { 0x12640001, mmCP_DFY_DATA_0 }, - { 0x7ea68001, mmCP_DFY_DATA_0 }, - { 0x06a80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19e40064, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x96400009, mmCP_DFY_DATA_0 }, - { 0x16a40005, mmCP_DFY_DATA_0 }, - { 0x06640003, mmCP_DFY_DATA_0 }, - { 0xce412082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0a640003, mmCP_DFY_DATA_0 }, - { 0x800017d0, mmCP_DFY_DATA_0 }, - { 0x16a40005, mmCP_DFY_DATA_0 }, - { 0xce412082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x12640005, mmCP_DFY_DATA_0 }, - { 0x7ea64002, mmCP_DFY_DATA_0 }, - { 0xc4292083, mmCP_DFY_DATA_0 }, - { 0x7ea68005, mmCP_DFY_DATA_0 }, - { 0x26a80001, mmCP_DFY_DATA_0 }, - { 0x9a80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc425325d, mmCP_DFY_DATA_0 }, - { 0x26640010, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x26a400ff, mmCP_DFY_DATA_0 }, - { 0x9a40ffca, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0x2024007b, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0x800017e3, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0xc4a70280, mmCP_DFY_DATA_0 }, - { 0xc4ab0278, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x04280001, mmCP_DFY_DATA_0 }, - { 0x7eae8014, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x56680020, mmCP_DFY_DATA_0 }, - { 0xce480278, mmCP_DFY_DATA_0 }, - { 0xce880280, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0xcec80270, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0x800017fe, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcf800026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0x800017fe, mmCP_DFY_DATA_0 }, - { 0xc43b02eb, mmCP_DFY_DATA_0 }, - { 0xc42302ec, mmCP_DFY_DATA_0 }, - { 0xcf813245, mmCP_DFY_DATA_0 }, - { 0xce013246, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7fa3801a, mmCP_DFY_DATA_0 }, - { 0x47b8020c, mmCP_DFY_DATA_0 }, - { 0x15e00008, mmCP_DFY_DATA_0 }, - { 0x1220000a, mmCP_DFY_DATA_0 }, - { 0x2a206032, mmCP_DFY_DATA_0 }, - { 0x513c001e, mmCP_DFY_DATA_0 }, - { 0x7e3e001a, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x9bc00005, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x8000180f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x1b3c0077, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7ff3000a, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x2b300032, mmCP_DFY_DATA_0 }, - { 0x043c3000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0xd200000b, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xd3800002, mmCP_DFY_DATA_0 }, - { 0xcf000002, mmCP_DFY_DATA_0 }, - { 0xd8000040, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0xd8400040, mmCP_DFY_DATA_0 }, - { 0xd8400018, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xd8000018, mmCP_DFY_DATA_0 }, - { 0xd8800010, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0x7dc30001, mmCP_DFY_DATA_0 }, - { 0xdc1e0000, mmCP_DFY_DATA_0 }, - { 0x04380032, mmCP_DFY_DATA_0 }, - { 0xcf80000e, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0xcc413248, mmCP_DFY_DATA_0 }, - { 0xc43d3269, mmCP_DFY_DATA_0 }, - { 0x27fc000f, mmCP_DFY_DATA_0 }, - { 0x33fc0003, mmCP_DFY_DATA_0 }, - { 0x97c00011, mmCP_DFY_DATA_0 }, - { 0x043c001f, mmCP_DFY_DATA_0 }, - { 0xdfc30000, mmCP_DFY_DATA_0 }, - { 0xd4413249, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x043c0024, mmCP_DFY_DATA_0 }, - { 0x0bfc0021, mmCP_DFY_DATA_0 }, - { 0xdfc30000, mmCP_DFY_DATA_0 }, - { 0xd441326a, mmCP_DFY_DATA_0 }, - { 0x173c0008, mmCP_DFY_DATA_0 }, - { 0x1b300303, mmCP_DFY_DATA_0 }, - { 0x7f3f0001, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x7ff3c004, mmCP_DFY_DATA_0 }, - { 0xcfc13084, mmCP_DFY_DATA_0 }, - { 0x80001842, mmCP_DFY_DATA_0 }, - { 0x043c0024, mmCP_DFY_DATA_0 }, - { 0xdfc30000, mmCP_DFY_DATA_0 }, - { 0xd4413249, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x23fc003f, mmCP_DFY_DATA_0 }, - { 0xcfc1326d, mmCP_DFY_DATA_0 }, - { 0x0bb80026, mmCP_DFY_DATA_0 }, - { 0xdf830000, mmCP_DFY_DATA_0 }, - { 0xd441326e, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0xc4393265, mmCP_DFY_DATA_0 }, - { 0x1fb8ffc6, mmCP_DFY_DATA_0 }, - { 0xddc30000, mmCP_DFY_DATA_0 }, - { 0xcf813265, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0xcdc0000c, mmCP_DFY_DATA_0 }, - { 0x80001852, mmCP_DFY_DATA_0 }, - { 0xcdc0000d, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcdc13252, mmCP_DFY_DATA_0 }, - { 0xce013253, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x80001878, mmCP_DFY_DATA_0 }, - { 0xc49f02e9, mmCP_DFY_DATA_0 }, - { 0x99c00018, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcdc13252, mmCP_DFY_DATA_0 }, - { 0xce013253, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x043c3000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0x97c0ffff, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc41c0012, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x80001878, mmCP_DFY_DATA_0 }, - { 0xc41f02ed, mmCP_DFY_DATA_0 }, - { 0xc42302ee, mmCP_DFY_DATA_0 }, - { 0xcdc13252, mmCP_DFY_DATA_0 }, - { 0xce013253, mmCP_DFY_DATA_0 }, - { 0x04200001, mmCP_DFY_DATA_0 }, - { 0x7e2a0004, mmCP_DFY_DATA_0 }, - { 0xce013084, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x28340001, mmCP_DFY_DATA_0 }, - { 0x313c0bcc, mmCP_DFY_DATA_0 }, - { 0x9bc00010, mmCP_DFY_DATA_0 }, - { 0x393c051f, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0x3d3c050e, mmCP_DFY_DATA_0 }, - { 0x9bc0000c, mmCP_DFY_DATA_0 }, - { 0x97c0000c, mmCP_DFY_DATA_0 }, - { 0x393c0560, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0x3d3c054f, mmCP_DFY_DATA_0 }, - { 0x9bc00007, mmCP_DFY_DATA_0 }, - { 0x97c00007, mmCP_DFY_DATA_0 }, - { 0x393c1538, mmCP_DFY_DATA_0 }, - { 0x9bc00005, mmCP_DFY_DATA_0 }, - { 0x3d3c1537, mmCP_DFY_DATA_0 }, - { 0x9bc00002, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0x2b740800, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18e8007c, mmCP_DFY_DATA_0 }, - { 0x7c42c001, mmCP_DFY_DATA_0 }, - { 0x06a8189a, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0x800018c5, mmCP_DFY_DATA_0 }, - { 0x800018f2, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x18d0007e, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x09200001, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x09240002, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x99000011, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc42130b5, mmCP_DFY_DATA_0 }, - { 0x1a24002c, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x2020002c, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0x1198001c, mmCP_DFY_DATA_0 }, - { 0x10cc0004, mmCP_DFY_DATA_0 }, - { 0x14cc0004, mmCP_DFY_DATA_0 }, - { 0x7cd8c00a, mmCP_DFY_DATA_0 }, - { 0xccc130b7, mmCP_DFY_DATA_0 }, - { 0xce0130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0x5978073a, mmCP_DFY_DATA_0 }, - { 0x2bb80002, mmCP_DFY_DATA_0 }, - { 0xcf800024, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9600e8a8, mmCP_DFY_DATA_0 }, - { 0xc4300012, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0x9640e8a5, mmCP_DFY_DATA_0 }, - { 0x800018a9, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0xc55b0309, mmCP_DFY_DATA_0 }, - { 0x3d5c0010, mmCP_DFY_DATA_0 }, - { 0x05540001, mmCP_DFY_DATA_0 }, - { 0x2598ffff, mmCP_DFY_DATA_0 }, - { 0x09780001, mmCP_DFY_DATA_0 }, - { 0x7dad800c, mmCP_DFY_DATA_0 }, - { 0x99c0ffd2, mmCP_DFY_DATA_0 }, - { 0x9580fff9, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x442c0000, mmCP_DFY_DATA_0 }, - { 0x65180001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9580000b, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc41d3248, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x25dc000f, mmCP_DFY_DATA_0 }, - { 0x7df9c00c, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xd8c13260, mmCP_DFY_DATA_0 }, - { 0xd901325d, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940fff1, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x66d80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x56ec0001, mmCP_DFY_DATA_0 }, - { 0x95800005, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc421325d, mmCP_DFY_DATA_0 }, - { 0x26240007, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940fff7, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc41d3254, mmCP_DFY_DATA_0 }, - { 0xc023007f, mmCP_DFY_DATA_0 }, - { 0x19e4003e, mmCP_DFY_DATA_0 }, - { 0x7de1c009, mmCP_DFY_DATA_0 }, - { 0x7dee000c, mmCP_DFY_DATA_0 }, - { 0x96400008, mmCP_DFY_DATA_0 }, - { 0x96000007, mmCP_DFY_DATA_0 }, - { 0xd8c13260, mmCP_DFY_DATA_0 }, - { 0xd901325d, mmCP_DFY_DATA_0 }, - { 0xc421325d, mmCP_DFY_DATA_0 }, - { 0x261c0007, mmCP_DFY_DATA_0 }, - { 0x99c0fffe, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940fff0, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18e00064, mmCP_DFY_DATA_0 }, - { 0x06281911, mmCP_DFY_DATA_0 }, - { 0x14f4001d, mmCP_DFY_DATA_0 }, - { 0x24cc0003, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80001915, mmCP_DFY_DATA_0 }, - { 0x800019af, mmCP_DFY_DATA_0 }, - { 0x80001a2b, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xcc48032b, mmCP_DFY_DATA_0 }, - { 0xcc480333, mmCP_DFY_DATA_0 }, - { 0xcc48033b, mmCP_DFY_DATA_0 }, - { 0xcc480343, mmCP_DFY_DATA_0 }, - { 0x98800011, mmCP_DFY_DATA_0 }, - { 0xc4213246, mmCP_DFY_DATA_0 }, - { 0xc4253245, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26401a, mmCP_DFY_DATA_0 }, - { 0x46640400, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04203000, mmCP_DFY_DATA_0 }, - { 0xce013267, mmCP_DFY_DATA_0 }, - { 0xc4213267, mmCP_DFY_DATA_0 }, - { 0x9a000001, mmCP_DFY_DATA_0 }, - { 0x1b3c0057, mmCP_DFY_DATA_0 }, - { 0x1b200213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7e3e000a, mmCP_DFY_DATA_0 }, - { 0x7e32000a, mmCP_DFY_DATA_0 }, - { 0xce000024, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04180000, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x7f438001, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc41d3247, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0x95c00068, mmCP_DFY_DATA_0 }, - { 0xc4213254, mmCP_DFY_DATA_0 }, - { 0x1a1c003e, mmCP_DFY_DATA_0 }, - { 0x95c00065, mmCP_DFY_DATA_0 }, - { 0xc01f007f, mmCP_DFY_DATA_0 }, - { 0x7e1e0009, mmCP_DFY_DATA_0 }, - { 0x97800062, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x43bc0008, mmCP_DFY_DATA_0 }, - { 0x7fcbc001, mmCP_DFY_DATA_0 }, - { 0xc7df032b, mmCP_DFY_DATA_0 }, - { 0x7e1fc00c, mmCP_DFY_DATA_0 }, - { 0x97c0fffa, mmCP_DFY_DATA_0 }, - { 0x043c0101, mmCP_DFY_DATA_0 }, - { 0x94c00002, mmCP_DFY_DATA_0 }, - { 0x043c0102, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x1bb0003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1bb000e8, mmCP_DFY_DATA_0 }, - { 0x33380003, mmCP_DFY_DATA_0 }, - { 0x9b800046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0xc4393260, mmCP_DFY_DATA_0 }, - { 0x1bb000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x80001994, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x7f3b0009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b800ff, mmCP_DFY_DATA_0 }, - { 0x9b80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x19f003e6, mmCP_DFY_DATA_0 }, - { 0x27380003, mmCP_DFY_DATA_0 }, - { 0x13b80004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x19f000e8, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x07b80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19f00064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x80001982, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7fb30002, mmCP_DFY_DATA_0 }, - { 0xc4392083, mmCP_DFY_DATA_0 }, - { 0x7fb38005, mmCP_DFY_DATA_0 }, - { 0x27b80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffcb, mmCP_DFY_DATA_0 }, - { 0xcfc1325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x80001995, mmCP_DFY_DATA_0 }, - { 0xcfc1325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x98800009, mmCP_DFY_DATA_0 }, - { 0x41bc0007, mmCP_DFY_DATA_0 }, - { 0x53fc0002, mmCP_DFY_DATA_0 }, - { 0x7e7fc011, mmCP_DFY_DATA_0 }, - { 0xd3c00025, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc43c0012, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0x653c0001, mmCP_DFY_DATA_0 }, - { 0x7dbd8001, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9940ff8f, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0xc55b0309, mmCP_DFY_DATA_0 }, - { 0x3d5c0010, mmCP_DFY_DATA_0 }, - { 0x2598ffff, mmCP_DFY_DATA_0 }, - { 0x05540001, mmCP_DFY_DATA_0 }, - { 0x7d91800c, mmCP_DFY_DATA_0 }, - { 0x95c00003, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x9580fff8, mmCP_DFY_DATA_0 }, - { 0x09780001, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x65180001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9580005d, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4253247, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x04200101, mmCP_DFY_DATA_0 }, - { 0x96400058, mmCP_DFY_DATA_0 }, - { 0x7dc24001, mmCP_DFY_DATA_0 }, - { 0xc41d3248, mmCP_DFY_DATA_0 }, - { 0x25dc000f, mmCP_DFY_DATA_0 }, - { 0x7df9c00c, mmCP_DFY_DATA_0 }, - { 0x95c00053, mmCP_DFY_DATA_0 }, - { 0x94c00002, mmCP_DFY_DATA_0 }, - { 0x04200102, mmCP_DFY_DATA_0 }, - { 0x7e41c001, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x1a70003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1a7000e8, mmCP_DFY_DATA_0 }, - { 0x33240003, mmCP_DFY_DATA_0 }, - { 0x9a400046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xc4253260, mmCP_DFY_DATA_0 }, - { 0x1a7000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x80001a21, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x7f270009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x266400ff, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x19f003e6, mmCP_DFY_DATA_0 }, - { 0x27240003, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x19f000e8, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x06640002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19f00064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x16700005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x80001a0f, mmCP_DFY_DATA_0 }, - { 0x16700005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7e730002, mmCP_DFY_DATA_0 }, - { 0xc4252083, mmCP_DFY_DATA_0 }, - { 0x7e724005, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9a40ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x267000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffca, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x80001a22, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940ff9f, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x8c001a31, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc4213246, mmCP_DFY_DATA_0 }, - { 0xc4253245, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26401a, mmCP_DFY_DATA_0 }, - { 0x46640400, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04203000, mmCP_DFY_DATA_0 }, - { 0xce013267, mmCP_DFY_DATA_0 }, - { 0xc4213267, mmCP_DFY_DATA_0 }, - { 0x9a000001, mmCP_DFY_DATA_0 }, - { 0x1b180057, mmCP_DFY_DATA_0 }, - { 0x1b200213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7e1a000a, mmCP_DFY_DATA_0 }, - { 0x7e32000a, mmCP_DFY_DATA_0 }, - { 0xce000024, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x65180001, mmCP_DFY_DATA_0 }, - { 0x95800060, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4193247, mmCP_DFY_DATA_0 }, - { 0x25980001, mmCP_DFY_DATA_0 }, - { 0x04200101, mmCP_DFY_DATA_0 }, - { 0x94c00005, mmCP_DFY_DATA_0 }, - { 0x30f00005, mmCP_DFY_DATA_0 }, - { 0x04200005, mmCP_DFY_DATA_0 }, - { 0x9b000002, mmCP_DFY_DATA_0 }, - { 0x04200102, mmCP_DFY_DATA_0 }, - { 0x95800056, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x1bb0003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1bb000e8, mmCP_DFY_DATA_0 }, - { 0x33380003, mmCP_DFY_DATA_0 }, - { 0x9b800046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xc4393260, mmCP_DFY_DATA_0 }, - { 0x1bb000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x80001aa2, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x7f3b0009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b800ff, mmCP_DFY_DATA_0 }, - { 0x9b80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x19f003e6, mmCP_DFY_DATA_0 }, - { 0x27380003, mmCP_DFY_DATA_0 }, - { 0x13b80004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x19f000e8, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x07b80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19f00064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x80001a90, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7fb30002, mmCP_DFY_DATA_0 }, - { 0xc4392083, mmCP_DFY_DATA_0 }, - { 0x7fb38005, mmCP_DFY_DATA_0 }, - { 0x27b80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffca, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf00325b, mmCP_DFY_DATA_0 }, - { 0x80001aa3, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc49b02e9, mmCP_DFY_DATA_0 }, - { 0x99800005, mmCP_DFY_DATA_0 }, - { 0xd2400025, mmCP_DFY_DATA_0 }, - { 0x4664001c, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9940ff9c, mmCP_DFY_DATA_0 }, - { 0xc49b02e9, mmCP_DFY_DATA_0 }, - { 0x99800008, mmCP_DFY_DATA_0 }, - { 0xc430000e, mmCP_DFY_DATA_0 }, - { 0x2b300008, mmCP_DFY_DATA_0 }, - { 0xcf000013, mmCP_DFY_DATA_0 }, - { 0x04302000, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x244c00ff, mmCP_DFY_DATA_0 }, - { 0xcc4c0200, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc44f0200, mmCP_DFY_DATA_0 }, - { 0xc410000b, mmCP_DFY_DATA_0 }, - { 0xc414000c, mmCP_DFY_DATA_0 }, - { 0x7d158010, mmCP_DFY_DATA_0 }, - { 0x059cc000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccdd0000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c0037, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0xcc000049, mmCP_DFY_DATA_0 }, - { 0xc40c003a, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x24d00001, mmCP_DFY_DATA_0 }, - { 0x9500e69a, mmCP_DFY_DATA_0 }, - { 0x18d0003b, mmCP_DFY_DATA_0 }, - { 0x18d40021, mmCP_DFY_DATA_0 }, - { 0x99400006, mmCP_DFY_DATA_0 }, - { 0xd840004a, mmCP_DFY_DATA_0 }, - { 0xc40c003c, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0x14cc0001, mmCP_DFY_DATA_0 }, - { 0x94c00028, mmCP_DFY_DATA_0 }, - { 0xd8000033, mmCP_DFY_DATA_0 }, - { 0xc438000b, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0001, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd841c07f, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x1bfc0078, mmCP_DFY_DATA_0 }, - { 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { 0x97c0fffd, mmCP_DFY_DATA_0 }, - { 0x99000004, mmCP_DFY_DATA_0 }, - { 0xc0120840, mmCP_DFY_DATA_0 }, - { 0x282c0040, mmCP_DFY_DATA_0 }, - { 0x80001ae8, mmCP_DFY_DATA_0 }, - { 0xc0121841, mmCP_DFY_DATA_0 }, - { 0x282c001a, mmCP_DFY_DATA_0 }, - { 0xcd01c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04200004, mmCP_DFY_DATA_0 }, - { 0xcec0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0x166c001f, mmCP_DFY_DATA_0 }, - { 0x04200004, mmCP_DFY_DATA_0 }, - { 0x9ac0fffb, mmCP_DFY_DATA_0 }, - { 0xc434000f, mmCP_DFY_DATA_0 }, - { 0x9b40ffff, mmCP_DFY_DATA_0 }, - { 0xd801c07f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0xce400078, mmCP_DFY_DATA_0 }, - { 0xd8000034, mmCP_DFY_DATA_0 }, - { 0x9940e66b, mmCP_DFY_DATA_0 }, - { 0xd800004a, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c0036, mmCP_DFY_DATA_0 }, - { 0x24d00001, mmCP_DFY_DATA_0 }, - { 0x9900fffe, mmCP_DFY_DATA_0 }, - { 0x18cc0021, mmCP_DFY_DATA_0 }, - { 0xccc00047, mmCP_DFY_DATA_0 }, - { 0xcc000046, mmCP_DFY_DATA_0 }, - { 0xc40c0039, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0xc40c003d, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x24d003ff, mmCP_DFY_DATA_0 }, - { 0x18d47fea, mmCP_DFY_DATA_0 }, - { 0x18d87ff4, mmCP_DFY_DATA_0 }, - { 0xcd00004c, mmCP_DFY_DATA_0 }, - { 0xcd40004e, mmCP_DFY_DATA_0 }, - { 0xcd80004d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd41c405, mmCP_DFY_DATA_0 }, - { 0xc02a0001, mmCP_DFY_DATA_0 }, - { 0x2aa80001, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xcd01c406, mmCP_DFY_DATA_0 }, - { 0xcc01c406, mmCP_DFY_DATA_0 }, - { 0xcc01c406, mmCP_DFY_DATA_0 }, - { 0xc40c0006, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0xc414000e, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0x295c0001, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8c1325e, mmCP_DFY_DATA_0 }, - { 0xcdc0001a, mmCP_DFY_DATA_0 }, - { 0x11980002, mmCP_DFY_DATA_0 }, - { 0x4110000c, mmCP_DFY_DATA_0 }, - { 0xc0160800, mmCP_DFY_DATA_0 }, - { 0x7d15000a, mmCP_DFY_DATA_0 }, - { 0xc0164010, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd41c078, mmCP_DFY_DATA_0 }, - { 0xcc01c080, mmCP_DFY_DATA_0 }, - { 0xcc01c081, mmCP_DFY_DATA_0 }, - { 0xcd81c082, mmCP_DFY_DATA_0 }, - { 0xcc01c083, mmCP_DFY_DATA_0 }, - { 0xcd01c084, mmCP_DFY_DATA_0 }, - { 0xc40c0006, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400048, mmCP_DFY_DATA_0 }, - { 0xc40c003b, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd801c40a, mmCP_DFY_DATA_0 }, - { 0xd901c40d, mmCP_DFY_DATA_0 }, - { 0xd801c410, mmCP_DFY_DATA_0 }, - { 0xd801c40e, mmCP_DFY_DATA_0 }, - { 0xd801c40f, mmCP_DFY_DATA_0 }, - { 0xc40c0040, mmCP_DFY_DATA_0 }, - { 0x04140001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x9940ffff, mmCP_DFY_DATA_0 }, - { 0x04140096, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1c400, mmCP_DFY_DATA_0 }, - { 0xc411c401, mmCP_DFY_DATA_0 }, - { 0x9500fffa, mmCP_DFY_DATA_0 }, - { 0xc424003e, mmCP_DFY_DATA_0 }, - { 0x04d00001, mmCP_DFY_DATA_0 }, - { 0x11100002, mmCP_DFY_DATA_0 }, - { 0xcd01c40c, mmCP_DFY_DATA_0 }, - { 0xc0180034, mmCP_DFY_DATA_0 }, - { 0xcd81c411, mmCP_DFY_DATA_0 }, - { 0xd841c414, mmCP_DFY_DATA_0 }, - { 0x0a540001, mmCP_DFY_DATA_0 }, - { 0xcd41c412, mmCP_DFY_DATA_0 }, - { 0x2468000f, mmCP_DFY_DATA_0 }, - { 0xc419c416, mmCP_DFY_DATA_0 }, - { 0x41980003, mmCP_DFY_DATA_0 }, - { 0xc41c003f, mmCP_DFY_DATA_0 }, - { 0x7dda0001, mmCP_DFY_DATA_0 }, - { 0x12200002, mmCP_DFY_DATA_0 }, - { 0x10cc0002, mmCP_DFY_DATA_0 }, - { 0xccc1c40c, mmCP_DFY_DATA_0 }, - { 0xd901c411, mmCP_DFY_DATA_0 }, - { 0xce41c412, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xce292e40, mmCP_DFY_DATA_0 }, - { 0xcc412e01, mmCP_DFY_DATA_0 }, - { 0xcc412e02, mmCP_DFY_DATA_0 }, - { 0xcc412e03, mmCP_DFY_DATA_0 }, - { 0xcc412e00, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xdc120000, mmCP_DFY_DATA_0 }, - { 0x31144000, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0xdc030000, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xcc3c000c, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x33f80003, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x9780e601, mmCP_DFY_DATA_0 }, - { 0x188cfff0, mmCP_DFY_DATA_0 }, - { 0x04e40002, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x96400006, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x96400003, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x80001b74, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x54106500, mmCP_DFY_ADDR_LO }, - { 0x7e000200, mmCP_DFY_DATA_0 }, - { 0x7e020204, mmCP_DFY_DATA_0 }, - { 0xc00a0505, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xbf8c007f, mmCP_DFY_DATA_0 }, - { 0xb8900904, mmCP_DFY_DATA_0 }, - { 0xb8911a04, mmCP_DFY_DATA_0 }, - { 0xb8920304, mmCP_DFY_DATA_0 }, - { 0xb8930b44, mmCP_DFY_DATA_0 }, - { 0x921c0d0c, mmCP_DFY_DATA_0 }, - { 0x921c1c13, mmCP_DFY_DATA_0 }, - { 0x921d0c12, mmCP_DFY_DATA_0 }, - { 0x811c1d1c, mmCP_DFY_DATA_0 }, - { 0x811c111c, mmCP_DFY_DATA_0 }, - { 0x921cff1c, mmCP_DFY_DATA_0 }, - { 0x00000400, mmCP_DFY_DATA_0 }, - { 0x921dff10, mmCP_DFY_DATA_0 }, - { 0x00000100, mmCP_DFY_DATA_0 }, - { 0x81181d1c, mmCP_DFY_DATA_0 }, - { 0x7e040218, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050002, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050102, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050002, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050102, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050002, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050102, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x54106900, mmCP_DFY_ADDR_LO }, - { 0x7e080200, mmCP_DFY_DATA_0 }, - { 0x7e100204, mmCP_DFY_DATA_0 }, - { 0xbefc00ff, mmCP_DFY_DATA_0 }, - { 0x00010000, mmCP_DFY_DATA_0 }, - { 0x24200087, mmCP_DFY_DATA_0 }, - { 0x262200ff, mmCP_DFY_DATA_0 }, - { 0x000001f0, mmCP_DFY_DATA_0 }, - { 0x20222282, mmCP_DFY_DATA_0 }, - { 0x28182111, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x54116f00, mmCP_DFY_ADDR_LO }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fe8, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000041, mmCP_DFY_DATA_0 }, - { 0x0000000c, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54116f00, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb454105e, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x000000c0, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54117300, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4541065, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000500, mmCP_DFY_DATA_0 }, - { 0x0000001c, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54117700, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4541069, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000444, mmCP_DFY_DATA_0 }, - { 0x0000008a, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54117b00, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, 0xFFFFFFFF }, +}; + +static const PWR_DFY_Section pwr_virus_section1 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x540fe800, + .dfy_data = { + 0x7e000200, 0x7e020201, 0x7e040204, 0x7e060205, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0xbf810000, 0x00000000, 0x00000000, 0x00000000, + 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54106f00, 0x000400b4, 0x00004000, 0x00804fac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 416 +}; + +static const PWR_DFY_Section pwr_virus_section2 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x540fef00, + .dfy_data = { + 0xc0031502, 0x00001e00, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 16 +}; + +static const PWR_DFY_Section pwr_virus_section3 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x540ff000, + .dfy_data = { + 0xc424000b, 0x80000145, 0x94800001, 0x94c00001, 0x95000001, 0x95400001, 0x95800001, 0xdc810000, + 0xdcc10000, 0xdd010000, 0xdd410000, 0xdd810000, 0xc4080061, 0xd8400013, 0xd8000003, 0xc40c0001, + 0x24ccffff, 0x3cd08000, 0x9500fffd, 0x1cd0ffcf, 0x7d018001, 0xc4140004, 0x050c0019, 0xd8400008, + 0x84c00000, 0x80000023, 0x80000067, 0x8000006a, 0x8000006d, 0x80000079, 0x80000084, 0x8000008f, + 0x80000099, 0x800000a0, 0x800000af, 0xd8400053, 0xc4080007, 0x388c0001, 0x08880002, 0x04100003, + 0x94c00005, 0x98800003, 0x04100004, 0x8000002d, 0x04100005, 0x8c00003f, 0x8c000043, 0x28cc0000, + 0xccc00050, 0x8c000055, 0x28080001, 0xcc000004, 0x7d808001, 0xd8400013, 0xd88130b8, 0xcd400008, + 0xdc180000, 0xdc140000, 0xdc100000, 0xdc0c0000, 0xcc800005, 0xdc080000, 0x80000168, 0xc40c000e, + 0x28cc0008, 0xccc00013, 0x90000000, 0xcd013278, 0xc4113278, 0x95000001, 0x24cc0700, 0xd8400029, + 0xc4113255, 0xcd01324f, 0xc4113254, 0x1d10ffdf, 0xcd013254, 0x10cc0014, 0x1d10c017, 0x7d0d000a, + 0xd8400013, 0xd8400008, 0xcd0130b7, 0x14cc0010, 0x90000000, 0xd9c00036, 0x8000005d, 0xd8400013, + 0xc00c4000, 0xccc130b5, 0xc40c000e, 0x28cc0008, 0xccc00013, 0xc40c0021, 0x14d00011, 0x9500fffe, + 0xdc030000, 0xd800000c, 0xd800000d, 0xc40c005e, 0x94c01b10, 0xd8400013, 0x90000000, 0xc00e0080, + 0xccc130b5, 0x8000013b, 0xc00e0800, 0xccc130b5, 0x8000013b, 0xd8400053, 0x04100006, 0x8c00003f, + 0x8c000043, 0x28cc0000, 0xccc00050, 0x8c000055, 0x280c0008, 0xccc00052, 0xd8000021, 0x28180039, + 0x80000034, 0xd8400053, 0x04100007, 0x8c00003f, 0x8c000043, 0x28cc0001, 0xccc00050, 0x8c000055, + 0x280c0010, 0xccc00052, 0x28180039, 0x80000034, 0xd8400053, 0x04100008, 0x8c00003f, 0x8c000043, + 0x28cc0003, 0xccc00050, 0x8c000055, 0x280c0020, 0xccc00052, 0x28180039, 0x80000034, 0xdc030000, + 0xd8000069, 0x28080001, 0xc428000d, 0x7ca88004, 0xcc800079, 0x04280001, 0xcc00006f, 0x8000013b, + 0x80000034, 0x04100010, 0x8c00003f, 0x8c000043, 0xccc00078, 0x8c000055, 0x28180080, 0x80000034, + 0x04100001, 0xc40c000e, 0x28cc0008, 0xccc00013, 0xcd013278, 0xc4113278, 0x95000001, 0xc00c4000, + 0xc4113254, 0x1d10c017, 0xd8400013, 0xd8400008, 0xccc130b5, 0xcd0130b7, 0x8000013b, 0x95c00001, + 0x96000001, 0x96400001, 0x96800001, 0x96c00001, 0x97000001, 0x97400001, 0x97800001, 0x97c00001, + 0xdc810000, 0xc40c000c, 0xcd4c0380, 0xcdcc0388, 0x55dc0020, 0xcdcc038c, 0xce0c0390, 0x56200020, + 0xce0c0394, 0xce4c0398, 0x56640020, 0xce4c039c, 0xce8c03a0, 0x56a80020, 0xce8c03a4, 0xcecc03a8, + 0x56ec0020, 0xcecc03ac, 0xcf0c03b0, 0x57300020, 0xcf0c03b4, 0xcf4c03b8, 0x57740020, 0xcf4c03bc, + 0xcf8c03c0, 0x57b80020, 0xcf8c03c4, 0xcfcc03c8, 0x57fc0020, 0xcfcc03cc, 0xd9000033, 0xc41c0009, + 0x25dc0010, 0x95c0fffe, 0xd8400013, 0xc41c000c, 0x05dc002f, 0xcdc12009, 0xc41d200a, 0xd8400013, + 0xcc012009, 0xd9000034, 0x25e01c00, 0x12200013, 0x25e40300, 0x12640008, 0x25e800c0, 0x12a80002, + 0x25ec003f, 0x7e25c00a, 0x7eae400a, 0x7de5c00a, 0xddc10000, 0xc02ee000, 0xcec1c200, 0xc40c005f, + 0xccc00037, 0x24d000ff, 0x31100006, 0x9500007b, 0x8c000190, 0xdc1c0000, 0xd8400013, 0xcdc1c200, + 0xc40c000c, 0xc4df0388, 0xc4d7038c, 0x51540020, 0x7d5dc01a, 0xc4e30390, 0xc4d70394, 0x51540020, + 0x7d62001a, 0xc4e70398, 0xc4d7039c, 0x51540020, 0x7d66401a, 0xc4eb03a0, 0xc4d703a4, 0x51540020, + 0x7d6a801a, 0xc4ef03a8, 0xc4d703ac, 0x51540020, 0x7d6ec01a, 0xc4f303b0, 0xc4d703b4, 0x51540020, + 0x7d73001a, 0xc4f703b8, 0xc4d703bc, 0x51540020, 0x7d77401a, 0xc4fb03c0, 0xc4d703c4, 0x51540020, + 0x7d7b801a, 0xc4ff03c8, 0xc4d703cc, 0x51540020, 0x7d7fc01a, 0xdc080000, 0xcc800013, 0xc4d70380, + 0xc4080001, 0x1c88001c, 0xcd400008, 0xc40c0083, 0x94c00010, 0xdc0e0000, 0x94c0000e, 0xc40c0082, + 0x24d00001, 0x9900000b, 0x18cc01e3, 0x3cd00004, 0x95000008, 0xc40c0085, 0x18cc006a, 0x98c00005, + 0xc40c0082, 0x18cc01e3, 0x3cd00004, 0x9900fffa, 0xdc180000, 0xdc140000, 0xdc100000, 0xdc0c0000, + 0xcc800004, 0xdc080000, 0x90000000, 0xc4080001, 0x1c88001c, 0xcd400008, 0xdc180000, 0xdc140000, + 0xdc100000, 0xdc0c0000, 0xcc800004, 0xdc080000, 0x90000000, 0xd8400051, 0xc428000c, 0x04180018, + 0x32640002, 0x9a80001f, 0x9a40001e, 0xcd800013, 0xc4293265, 0x040c0000, 0x1aac0027, 0x2aa80080, + 0xce813265, 0x9ac00017, 0xd80002f1, 0x04080002, 0x08880001, 0xd8080250, 0xd8080258, 0xd8080230, + 0xd8080238, 0xd8080240, 0xd8080248, 0xd8080268, 0xd8080270, 0xd8080278, 0xd8080280, 0xd8080228, + 0xd8000367, 0x9880fff3, 0x04080010, 0x08880001, 0xd80c0309, 0xd80c0319, 0x04cc0001, 0x9880fffc, + 0x7c408001, 0x88000000, 0xc00e0100, 0xd8400013, 0xd8400008, 0xccc130b5, 0x8000016e, 0xc4180032, + 0x29980008, 0xcd800013, 0x95800001, 0x7c40c001, 0x18d0003f, 0x24d4001f, 0x24d80001, 0x155c0001, + 0x05e80180, 0x9900000b, 0x202c003d, 0xcd800010, 0xcec1325b, 0xc42d325b, 0x96c00001, 0x86800000, + 0x80000168, 0x80000aa7, 0x80000bfc, 0x800012e9, 0xc4200007, 0x0a200001, 0xce000010, 0x80001b70, + 0x7c40c001, 0x8c000190, 0xc410001b, 0xd8000032, 0xd8000031, 0x9900091a, 0x7c408001, 0x88000000, + 0x24d000ff, 0x05280196, 0x18d4fe04, 0x29540008, 0xcd400013, 0x86800000, 0x800001b4, 0x8000032b, + 0x80000350, 0x80000352, 0x8000035f, 0x80000701, 0x8000047c, 0x8000019f, 0x80000800, 0xc419325b, + 0x1d98001f, 0xcd81325b, 0x8c00003f, 0xc4140004, 0xd8400008, 0x04100002, 0x8c000043, 0x28cc0002, + 0xccc00050, 0xc43c0044, 0x27fc0003, 0x9bc00002, 0x97c00006, 0xc00c4000, 0xccc130b5, 0x8c000055, + 0xd8400013, 0xd88130b8, 0xcd400008, 0x90000000, 0xd8400008, 0xcd400013, 0x7d40c001, 0xd8400028, + 0xd8400029, 0xd9400036, 0xc4193256, 0xc41d3254, 0x15540008, 0xcd400009, 0xcd40005b, 0xcd40005e, + 0xcd40005d, 0xd840006d, 0xc421325a, 0xc42d3249, 0x11540015, 0x19a4003c, 0x1998003f, 0x1af0007d, + 0x11dc000b, 0x1264001f, 0x15dc000d, 0x7d65400a, 0x13300018, 0x1a38003f, 0x7dd5c00a, 0x7df1c00a, + 0xcd800045, 0xcdc00100, 0xc411326a, 0xc415326b, 0xc419326c, 0xc41d326d, 0xc425326e, 0xc4293279, + 0xce800077, 0xcd000056, 0xcd400057, 0xcd800058, 0xcdc00059, 0xc4193265, 0x259c8000, 0x99c00004, + 0xce40005a, 0x29988000, 0xcd813265, 0xc4113248, 0x2510000f, 0xcd000073, 0xc418000d, 0xc411326f, + 0x17300019, 0x97000009, 0x25140fff, 0x95400007, 0xd800003a, 0x8c001b6d, 0xc4153279, 0xcd400077, + 0xcd00005f, 0xd8000075, 0x26f00001, 0x15100010, 0x7d190004, 0xcd000035, 0x97000035, 0x1af07fe8, + 0xd8800013, 0xd8400010, 0xd8400008, 0xcf00000d, 0xcf00000a, 0x8c001427, 0x04340022, 0x07740001, + 0x04300010, 0xdf430000, 0x7c434001, 0x7c408001, 0xd4412e01, 0x0434001e, 0xdf430000, 0xd4400078, + 0xdf030000, 0xd4412e40, 0xd8400013, 0xcc41c030, 0xcc41c031, 0xc43dc031, 0xccc00013, 0x04343000, + 0xc4113246, 0xc41d3245, 0xcf413267, 0x51100020, 0x7dd1c01a, 0xc4353267, 0x45dc0160, 0xc810001f, + 0x1b4c0057, 0x1b700213, 0x1b740199, 0x7f4f400a, 0x7f73400a, 0x55180020, 0x2198003f, 0xd1c00025, + 0xcf400024, 0xcd000026, 0xcd800026, 0xd8400027, 0x9bc00001, 0x248dfffe, 0xd8800013, 0xccc12e00, + 0x7c434001, 0x7c434001, 0x8c00142b, 0xc43c000e, 0x1af4007d, 0x2bfc0008, 0x33740003, 0x26d80001, + 0xcfc00013, 0x1ae8003e, 0x9680000c, 0xc4253277, 0x26680001, 0x96800009, 0x2a640002, 0xce413277, + 0xd8400013, 0xc4253348, 0xce413348, 0xc4253348, 0x96400001, 0xcfc00013, 0x9b400003, 0x958000d8, + 0x80000315, 0xc4253277, 0x04303000, 0x26680001, 0xcf013267, 0xc4193246, 0xc41d3245, 0xc4313267, + 0x96800041, 0x51980020, 0x1b342010, 0x7d9d801a, 0x1714000c, 0x25540800, 0x1b30c012, 0x459801b0, + 0x7d77400a, 0x7f37000a, 0x2b300000, 0xcf00001c, 0xd180001e, 0xd8400021, 0x04240010, 0x199c01e2, + 0x7e5e4002, 0x3e5c0004, 0x3e540002, 0xc428000f, 0x9a80ffff, 0x95c00006, 0xc80c0011, 0xc8140011, + 0x54d00020, 0x55580020, 0x80000282, 0x95400015, 0xc80c0011, 0x0a640002, 0x041c0001, 0x45980008, + 0x54d00020, 0x96400004, 0xc8140011, 0x45980004, 0x041c0000, 0xcf00001c, 0xd180001e, 0xd8400021, + 0xc428000f, 0x9a80ffff, 0x99c00003, 0xc8180011, 0x80000282, 0xc8140011, 0x55580020, 0x80000282, + 0x45980004, 0xc80c0011, 0xcf00001c, 0xd180001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc8100011, + 0xc8140011, 0x55580020, 0xd8400013, 0xccc1334e, 0xcd01334f, 0xcd413350, 0xcd813351, 0xd881334d, + 0xcfc00013, 0xc4193273, 0xc41d3275, 0xc40d3271, 0xc4113270, 0xc4153274, 0x50cc0020, 0x7cd0c01a, + 0x7cdcc011, 0x05900008, 0xcd00006a, 0xcdc0006b, 0xc41d3272, 0x7d594002, 0x54d00020, 0xd8800013, + 0xccc12e23, 0xcd012e24, 0xcdc12e25, 0xcfc00013, 0xc4193246, 0xc41d3245, 0xc4313267, 0x15540002, + 0x51980020, 0x7d9d801a, 0xc81c001f, 0x1b340057, 0x1b280213, 0x1b300199, 0x45980198, 0x7f37000a, + 0x7f2b000a, 0x55e40020, 0xcf000024, 0xd1800025, 0xcdc00026, 0xce400026, 0xd8400027, 0xcd40000d, + 0xcd40000a, 0xc40d3249, 0x20cc003c, 0xccc13249, 0xc4113274, 0xdd430000, 0xc01e0001, 0x29dc0002, + 0x04280000, 0xd8000036, 0xcc400078, 0xcc400078, 0x2d540002, 0x95400022, 0x078c0000, 0x07d40000, + 0x8c00120d, 0x8c001239, 0x8c001232, 0x04f80000, 0x057c0000, 0xcdc00013, 0xc414000d, 0xc41c0019, + 0x7dd5c005, 0x25dc0001, 0xd840007c, 0xd8400074, 0xd8400069, 0xc40c005e, 0x94c018a6, 0xd4412e22, + 0xd800007c, 0xc40c005e, 0x94c018a2, 0x95c00007, 0xc40c0019, 0x7cd4c005, 0x24cc0001, 0x94c00008, + 0x9680fffc, 0x800002e3, 0xc40c0057, 0x7cd0c002, 0x94c00003, 0x9680fffd, 0x800002e3, 0xd8000069, + 0xcfc00013, 0xcd013273, 0xcd013275, 0xd8000074, 0xc414005e, 0x9540188f, 0xcfc00013, 0xc40d3249, + 0xc013cfff, 0x7cd0c009, 0xccc13249, 0x9680000b, 0xc40c0077, 0x38d00001, 0x99000006, 0x04cc0002, + 0xdcc30000, 0xc40c005e, 0x94c01882, 0xd4400078, 0xd800000d, 0x80000304, 0x7c41c001, 0x7c41c001, + 0xd840002f, 0xc41c0015, 0x95c0ffff, 0xd8400030, 0xc41c0016, 0x95c0ffff, 0xd8000030, 0xc41c0016, + 0x99c0ffff, 0xd800002f, 0xc41c0015, 0x99c0ffff, 0xc81c001f, 0x49980198, 0x55e40020, 0x459801a0, + 0xcf000024, 0xd1800025, 0xcdc00026, 0xce400026, 0xd8400027, 0x04302000, 0xcfc00013, 0xcf013267, + 0xc4313267, 0x96800004, 0x97000001, 0xd8000036, 0x80000329, 0xd8800013, 0xcc812e00, 0x04302000, + 0xcfc00013, 0xcf013267, 0xc4313267, 0x97000001, 0xc4193256, 0xc42d3249, 0x16ec001f, 0xd8000028, + 0xd800002b, 0x1998003e, 0xcec00031, 0xd8000036, 0xd8000010, 0x97800004, 0xd8400010, 0xce00000a, + 0x1a18003e, 0xcd800008, 0x90000000, 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0x04100000, + 0x7d43c001, 0xcd400013, 0xc4093249, 0x1888003e, 0x94800015, 0xd8400074, 0x8c000671, 0xcd400013, + 0x9a400006, 0xc419324c, 0x259c0001, 0x1598001f, 0x95c0000d, 0x9580000c, 0x99000003, 0xd8400036, + 0x04100001, 0xc40c0021, 0x14d80011, 0x24dc00ff, 0x31e00002, 0x31dc0003, 0x9580fff0, 0x9a000003, + 0x99c00002, 0xd9c00036, 0x94800004, 0xd8000074, 0xc418005e, 0x95801827, 0xcf800008, 0x90000000, + 0xd8800036, 0x90000000, 0xd8c00036, 0xc424000b, 0x32640002, 0x9a400004, 0xc4180014, 0x9580ffff, + 0xd840002f, 0xc40c0021, 0x14dc0011, 0x95c0fffe, 0xccc00037, 0x8c000190, 0x90000000, 0xd8400008, + 0xd800006d, 0xc41d3246, 0xc4193245, 0x51dc0020, 0x7d9d801a, 0xd8400028, 0xd8400029, 0xc420000b, + 0x32200002, 0x9a0000ad, 0x04200032, 0xd9000010, 0xde030000, 0xd8400033, 0x04080000, 0xc43c0009, + 0x27fc0002, 0x97c0fffe, 0xc42c0015, 0x96c0ffff, 0xd800002e, 0xc42d3249, 0x1af4003e, 0x9740004d, + 0xc428000d, 0xc4080060, 0x7ca88005, 0x24880001, 0x7f4b4009, 0x97400046, 0xc4313274, 0xc4100057, + 0x7d33400c, 0x97400009, 0x28240100, 0x7e6a4004, 0xce400079, 0x1eecffdd, 0xcec13249, 0xcf013273, + 0xcf013275, 0x800003c3, 0xc429326f, 0x1aa80030, 0x96800006, 0x28240001, 0xc428000d, 0x06a80008, + 0x7e6a8004, 0xce800035, 0xc41d3272, 0x25cc0001, 0x10cc0004, 0x19e80042, 0x25dc0006, 0x11dc0001, + 0x7e8e800a, 0x7de9c00a, 0xc40d3271, 0xc4293270, 0x50cc0020, 0x7ce8c01a, 0x7cd30011, 0x11e80007, + 0x2aa80000, 0xce80001c, 0xd300001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc4300011, 0x1b30003f, + 0x33300000, 0xc4240059, 0x1660001f, 0x7e320009, 0xc0328000, 0x7e72400a, 0x0430000c, 0x9a000002, + 0x04300008, 0xc02ac000, 0x7d310002, 0x17300002, 0x2aa87600, 0x7cd0c011, 0xcdc00024, 0xd0c00025, + 0xce800026, 0x04280222, 0xce800026, 0x96000002, 0xce400026, 0xd8400027, 0xc4280058, 0x22ec003d, + 0xcec13249, 0xcd013273, 0xce813275, 0xd800007b, 0xc8380018, 0x57b00020, 0x04343108, 0xc429325d, + 0x040c3000, 0x13740008, 0x2374007e, 0x32a80003, 0xccc13267, 0xc40d3267, 0x18ec0057, 0x18e40213, + 0x18cc0199, 0x7cecc00a, 0x7ce4c00a, 0x94800003, 0xd4400078, 0x800003e7, 0x04200022, 0xde030000, + 0xccc00024, 0xd1800025, 0xcf400026, 0xd4400026, 0xd8400027, 0x04200010, 0xde030000, 0xccc00024, + 0x45980104, 0xd1800025, 0xd4400026, 0xcf800026, 0xcf000026, 0xd8400027, 0x49980104, 0x9a80000a, + 0xc81c001f, 0x45980168, 0x55e00020, 0xccc00024, 0xd1800025, 0xcdc00026, 0xce000026, 0xd8400027, + 0x800003f2, 0x8c000448, 0xcd400013, 0x040c2000, 0xccc13267, 0xc40d3267, 0x94c00001, 0xc40d3249, + 0x18cc003e, 0xd8400030, 0xc42c0016, 0x96c0ffff, 0xd8000030, 0xc42c0016, 0x9ac0ffff, 0xd800002f, + 0xc42c0015, 0x9ac0ffff, 0xd8400034, 0xc4300025, 0xc4340024, 0xc4380081, 0xcf813279, 0xcf41326e, + 0xcf01326d, 0x94c0000d, 0x254c0700, 0xc424001e, 0x10cc0010, 0x1a641fe8, 0x28cc0726, 0x2a640200, + 0xd8400013, 0xccc1237b, 0x2264003f, 0xcd400013, 0xd8813260, 0xce41325b, 0xc4240033, 0xc4280034, + 0xd9000036, 0xd8000010, 0x8c001427, 0x96400006, 0xde430000, 0xce40000c, 0xc40c005e, 0x94c01755, + 0xd4400078, 0x9680000a, 0xce80000a, 0x06a80002, 0xd8400010, 0xde830000, 0xce80000d, 0xc40c005e, + 0x94c0174c, 0xd4400078, 0xd8000010, 0x8c00142b, 0xc4393265, 0x2bb80040, 0xd8400032, 0xcf813265, + 0xc4200012, 0x9a00ffff, 0xc4100044, 0x19180024, 0xc8100072, 0x551c003f, 0x99c00003, 0x95800010, + 0x8000043d, 0xc00c8000, 0xd840006c, 0x28200000, 0x8000043f, 0xc00c4000, 0x282000f0, 0xcd400013, + 0xd8400008, 0xc4113255, 0xcd01324f, 0xd8400013, 0xd88130b8, 0xccc130b5, 0xce000053, 0x90000000, + 0x195c00e8, 0xc4100004, 0x2555fff0, 0xc0360001, 0x042c0000, 0x29540001, 0xd8400008, 0x04240000, + 0x04280004, 0xc420000b, 0x32200002, 0x9a000009, 0xcd400013, 0xcec1c200, 0xc5e124dc, 0x0aa80001, + 0x7ef6c001, 0x7e624001, 0x96000001, 0x9a80fff9, 0xc02ee000, 0xcd400013, 0x2555fff0, 0xcec1c200, + 0x29540008, 0xc81c001f, 0xcd400013, 0x55e00020, 0xc42d3255, 0xc4353259, 0xd8013260, 0x45980158, + 0xccc00024, 0xd1800025, 0xcdc00026, 0xce000026, 0xd8400027, 0x49980158, 0x45980170, 0xc4200012, + 0x16200010, 0x9a00fffe, 0xccc00024, 0xd1800025, 0xc429324f, 0xce400026, 0xce800026, 0xcec00026, + 0xcf400026, 0xd8400027, 0xcd000008, 0x90000000, 0xc40d325b, 0x7d43c001, 0x195400e8, 0x1154000a, + 0x18dc00e8, 0x05e80488, 0x18d0006c, 0x18f807f0, 0x18e40077, 0x18ec0199, 0x7e6e400a, 0x86800000, + 0x8000048e, 0x80000494, 0x800004de, 0x80000685, 0x80000686, 0x800006ac, 0x1ccc001f, 0xccc1325b, + 0xc411325d, 0x251001ef, 0xcd01325d, 0x90000000, 0xc4293254, 0x1264000a, 0xc4300004, 0x7d79400a, + 0x7e7a400a, 0x52a8001e, 0x15180001, 0x7d69401a, 0x202c007d, 0xcec1325b, 0x95000008, 0x95800028, + 0xc42d3267, 0xc4193246, 0xc41d3245, 0x1aec0028, 0xc40d325c, 0x800004cc, 0xc42d3256, 0xc419324e, + 0x26e8003f, 0x1aec003e, 0x12f4000e, 0xc41d324d, 0xc40d324f, 0x7d75401a, 0x04100002, 0x7d290004, + 0x7f8f4001, 0x7f52800f, 0x51980020, 0x7d9d801a, 0x50e00002, 0x51980008, 0x9a800002, 0x800004d1, + 0x7d0dc002, 0x6665fc00, 0x7e5e401a, 0xcec00008, 0x7da1c011, 0xd140000b, 0xd1c00002, 0x2a644000, + 0xce400002, 0x7f534002, 0x6665fc00, 0x7e76401a, 0xd1800002, 0xce400002, 0x800004d7, 0xc42d325a, + 0xc4193258, 0x1aec003e, 0xc41d3257, 0xc4213259, 0x12f4000e, 0x7d75401a, 0x51980020, 0x52200002, + 0x7d9d801a, 0xcec00008, 0x7da1c011, 0xd140000b, 0xd1c00002, 0x2a644000, 0xce400002, 0x202c003d, + 0xcf000008, 0xcfc00013, 0xcec1325b, 0xc42d325b, 0x96c00001, 0x90000000, 0xc4193260, 0x259c0007, + 0x15980004, 0x05e804e3, 0x86800000, 0x800004e7, 0x800004f0, 0x80000505, 0x8000016a, 0xc4380004, + 0xcfc00013, 0xd8400008, 0xc435325d, 0xd801325b, 0x277401ef, 0xcf41325d, 0xcf800008, 0x90000000, + 0xc4380004, 0xd8400008, 0x8c000671, 0x9640fff4, 0x17e00008, 0xc418000d, 0xce000009, 0xd84131db, + 0xcf800008, 0xcd800009, 0xc430001e, 0xcfc00013, 0xc42d325b, 0x1b301ff8, 0x2b300400, 0x2330003f, + 0x26edf000, 0x7ef2c00a, 0xd8413260, 0xcec1325b, 0x90000000, 0x05a80507, 0x86800000, 0x8000050c, + 0x80000528, 0x8000057d, 0x800005c2, 0x800005f3, 0xc4380004, 0xd8400008, 0x8c000671, 0xcfc00013, + 0x9a400012, 0x1bd400e8, 0xc42c004a, 0xcd40005e, 0xc41c004d, 0xcec0005e, 0x99c0000c, 0xc4100019, + 0x7d150005, 0x25100001, 0x99000008, 0x8c00063b, 0xcfc00013, 0xc4113277, 0x2511fffd, 0xcd013277, + 0xd801326f, 0x80000624, 0x04240012, 0x1be00fe4, 0xce413260, 0xce000066, 0xcf800008, 0x90000000, + 0xd8400068, 0xc4380004, 0xd8400008, 0x8c000671, 0xcfc00013, 0x9a400013, 0x1bd400e8, 0xc42c004a, + 0xcd40005e, 0xc41c004d, 0xcec0005e, 0x99c0000d, 0xc4100019, 0x7d150005, 0x25100001, 0x99000009, + 0xd8400067, 0x8c00063b, 0xcfc00013, 0xc4113277, 0x2511fffd, 0xcd013277, 0xd801326f, 0x80000624, + 0x1bd400e8, 0xc42c0060, 0x7ed6c005, 0x26ec0001, 0xc4113271, 0xc4153270, 0xc4193272, 0xc41d3273, + 0x04280022, 0x51100020, 0x7d51401a, 0xc4113274, 0xc4213275, 0xc4253276, 0xc4313248, 0xd1400061, + 0x2730000f, 0x13300010, 0x7db1800a, 0xcd800060, 0x96c00002, 0x05dc0008, 0xcdc00062, 0x042c3000, + 0xcd000063, 0xce000064, 0xce400065, 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, 0xce813260, + 0x52ec0020, 0x7ef2c01a, 0xc820001f, 0x1b700057, 0x1b680213, 0x1b740199, 0x46ec0188, 0x7f73400a, + 0x7f6b400a, 0x56240020, 0xcf400024, 0xd2c00025, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, + 0xc418000d, 0x17e00008, 0xce000009, 0xcec13267, 0xc42d3267, 0x26e01000, 0x9a00fffe, 0xd8400013, + 0xd9c131fc, 0xcd800009, 0xcf800008, 0x96c00001, 0x90000000, 0xc4380004, 0xd8400008, 0xc4113277, + 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, 0x11dc0008, 0x29dc0001, 0x25140001, 0x191807e4, + 0x192007ec, 0x95400004, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x9580000e, 0x09980001, 0x041c0001, + 0x95800005, 0x09980001, 0x51dc0001, 0x69dc0001, 0x9980fffd, 0x7de20014, 0x561c0020, 0xd8400013, + 0xce013344, 0xcdc13345, 0xcfc00013, 0x95400022, 0x042c3000, 0xcec13267, 0xc42d3246, 0xc4313245, + 0xc4353267, 0xd8400013, 0xc425334d, 0x26640001, 0x9640fffe, 0xc419334e, 0xc41d334f, 0xc4213350, + 0xc4253351, 0x52ec0020, 0x1b680057, 0x7ef2c01a, 0x1b700213, 0x1b740199, 0x46ec01b0, 0x7f6b400a, + 0x7f73400a, 0xcfc00013, 0xcf400024, 0xd2c00025, 0xcd800026, 0xcdc00026, 0xce000026, 0xce400026, + 0x042c2000, 0xd8400027, 0xcec13267, 0xc42d3267, 0x96c00001, 0x04280032, 0xce813260, 0xd8800068, + 0xcf800008, 0x90000000, 0xc4380004, 0xd8400008, 0x2010007d, 0xcd01325b, 0xc411325b, 0x1910003e, + 0x9500fffe, 0x04100040, 0xcd00001b, 0xd8400021, 0xc410000f, 0x9900ffff, 0x04100060, 0xcd00001b, + 0xd8400021, 0xc410000f, 0x9900ffff, 0xcfc00013, 0x2010003d, 0xcd01325b, 0xc4113277, 0x25140001, + 0x191807e4, 0x9540000b, 0x2511fffd, 0xcd013277, 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, + 0x11dc0008, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x95800005, 0xd8400013, 0xd8013344, 0xd8013345, + 0xcfc00013, 0xc4180050, 0xc41c0052, 0x04280042, 0xcd813273, 0xcdc13275, 0xce813260, 0xd9000068, + 0xd8400067, 0xcf800008, 0x90000000, 0x07d40000, 0x8c00120d, 0x8c00124f, 0x8c001232, 0x057c0000, + 0x042c3000, 0xc4380004, 0xcfc00013, 0xd8400008, 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, + 0x52ec0020, 0x7ef2c01a, 0x1b680057, 0x1b700213, 0x1b740199, 0xc820001f, 0x46ec0190, 0x7f6b400a, + 0x7f73400a, 0x56240020, 0xcf400024, 0xd2c00025, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, + 0xcfc00013, 0xcec13267, 0xc4153249, 0x2154003d, 0xc41c0019, 0x1bd800e8, 0x7dd9c005, 0x25dc0001, + 0xc42c004a, 0xcd80005e, 0xc420004d, 0xcec0005e, 0x11dc0010, 0x7e1e000a, 0xcd413249, 0xce01326f, + 0x28340001, 0x05980008, 0x7f598004, 0xcd800035, 0x1be800e8, 0xc42c004a, 0xce80005e, 0xd801327a, + 0xd800005f, 0xd8000075, 0xd800007f, 0xc424004c, 0xce41326e, 0xcec0005e, 0x28240100, 0x7e6a4004, + 0xce400079, 0xc435325d, 0x277401ef, 0x04240020, 0xce41325e, 0xd801325b, 0xd8013260, 0xcf41325d, + 0xda000068, 0xcf800008, 0x90000000, 0xc4113277, 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, + 0x11dc0008, 0x29dc0001, 0x25140001, 0x9540002d, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x042c3000, + 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, 0xd8400013, 0xc425334d, 0x26640001, 0x9640fffe, + 0xc419334e, 0xc41d334f, 0xc4213350, 0xc4253351, 0x52ec0020, 0x1b680057, 0x7ef2c01a, 0x1b700213, + 0x1b740199, 0x46ec01b0, 0x7f6b400a, 0x7f73400a, 0xcfc00013, 0xcf400024, 0xd2c00025, 0xcd800026, + 0xcdc00026, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, 0xcec13267, 0xc42d3267, 0x96c00001, + 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, 0x11dc0008, 0xd8400013, 0xcdc1334a, 0xcfc00013, + 0x90000000, 0xc430000b, 0x33300002, 0x04240000, 0x9b000010, 0x1be000e8, 0x042c0000, 0xc0360001, + 0x04280004, 0xd8400013, 0xcec1c200, 0xc63124dc, 0x0aa80001, 0x7ef6c001, 0x7e724001, 0x97000001, + 0x9a80fff9, 0xc02ee000, 0xd8400013, 0xcec1c200, 0x90000000, 0x90000000, 0xc4253260, 0x7fc14001, + 0xc40d3249, 0x18cc003e, 0x98c00005, 0x194c1c03, 0xccc0003b, 0xc40c002d, 0x80000697, 0xc420004a, + 0x194c00e8, 0xccc0005e, 0xc40c004c, 0xc431326d, 0x27301fff, 0xce00005e, 0x7cf0c00d, 0x98c00003, + 0x8c0007e0, 0x95c00008, 0xc430001e, 0x1b301ff8, 0x2b300400, 0x2330003f, 0xcd400013, 0xcf01325b, + 0x90000000, 0xcd400013, 0xd801325b, 0xc411325d, 0x251001ef, 0xcd01325d, 0x25100007, 0x31100005, + 0x9900008e, 0xc40c0007, 0xd9000010, 0x8000075e, 0x202c007d, 0xcec1325b, 0xc4293265, 0xc4353254, + 0x26a9feff, 0xc4380004, 0xd8400008, 0x1374000b, 0xc40c000d, 0xd8000009, 0x1774000d, 0xd8400013, + 0xc41d30b8, 0xcfc00013, 0x95c00008, 0xc411325d, 0xd801325b, 0xccc00009, 0xcf800008, 0x251001ef, + 0xcd01325d, 0x90000000, 0xce813265, 0xcf400100, 0xc00ac006, 0xc00e0000, 0x28880700, 0x28cc0014, + 0x8c0006de, 0x14cc0010, 0x30d4000f, 0x04cc0001, 0x10cc0010, 0x28cc0014, 0x99400009, 0xd8400013, + 0xc41530b8, 0xcfc00013, 0xc4193265, 0x19980028, 0x99400003, 0x99800002, 0x800006c8, 0xcfc00013, + 0xc411325d, 0xd801325b, 0xcf800008, 0x251001ef, 0xcd01325d, 0x90000000, 0x15600008, 0xce000009, + 0xc8380023, 0xc4180081, 0x11a00002, 0x7fa38011, 0xc4100026, 0x05980008, 0x7d1a0002, 0x282c2002, + 0x3e280008, 0xcec00013, 0xc4300027, 0x042c0008, 0xd3800025, 0xcf000024, 0x202400d0, 0x7ca48001, + 0xcc800026, 0xccc00026, 0x28240006, 0xcc000026, 0x0a640001, 0x9a40fffe, 0x9a800004, 0x32280000, + 0x9a800002, 0x9a000000, 0xd8400027, 0x24d8003f, 0xd840003c, 0xcec0003a, 0xd8800013, 0xcd81a2a4, + 0x90000000, 0xc41d325d, 0x25dc0007, 0xc40d3249, 0x18cc003e, 0x94c0000a, 0xc420004a, 0x194c00e8, + 0xccc0005e, 0xc40c004c, 0xc431326d, 0x27301fff, 0xce00005e, 0x7cf0c00d, 0x80000712, 0x194c1c03, + 0xccc0003b, 0xc40c002d, 0x05e80714, 0x86800000, 0x8000071c, 0x80000720, 0x80000747, 0x8000071d, + 0x800007c4, 0x80000732, 0x80000745, 0x80000744, 0x90000000, 0x98c00006, 0x8000072e, 0x90000000, + 0x98c00003, 0x8c0007e0, 0x95c0000c, 0xcd400013, 0xc4253265, 0x2a64008c, 0xce413265, 0xc430001e, + 0x1b301fe8, 0x2b300400, 0x2330003f, 0xd8013260, 0xcf01325b, 0x90000000, 0xc40c0007, 0xd9000010, + 0x04240000, 0x8000075e, 0x98c0fff1, 0x8c0007e0, 0x95c00002, 0x80000723, 0xcd400013, 0xc41f02f1, + 0x95c00004, 0xd8013247, 0xd801325d, 0x80000743, 0xd8813247, 0xd801325d, 0xc4100004, 0xd8400008, + 0xd8400013, 0xd88130b8, 0xcd000008, 0x90000000, 0x04100001, 0x98c0ffde, 0x8000072e, 0x98c00003, + 0x8c0007e0, 0x95c00012, 0xc4340004, 0xd8400008, 0x15600008, 0xc418000d, 0xce000009, 0xd8400013, + 0xd84131db, 0xcf400008, 0xcd800009, 0xc430001e, 0x1b301ff8, 0x2b300400, 0x2330003f, 0xcd400013, + 0xd8413260, 0xcf01325b, 0x90000000, 0xc40c0007, 0xd9000010, 0x04240000, 0xcd400013, 0x041c3000, + 0xcdc13267, 0xc41d3267, 0xc41d3265, 0x25dc8000, 0x95c00007, 0xc41c004a, 0x195800e8, 0xcd80005e, + 0xc418004c, 0xcd81326e, 0xcdc0005e, 0xc41d3265, 0x25dd7fff, 0xcdc13265, 0xc41d3246, 0xc4193245, + 0xc42d3267, 0x51e00020, 0x7e1a001a, 0x46200200, 0x04283247, 0x04300033, 0x1af80057, 0x1af40213, + 0x042c000c, 0x7f7b400a, 0x7f6f400a, 0xcf400024, 0xd2000025, 0xcd800026, 0xcdc00026, 0xc6990000, + 0x329c325d, 0x99c00008, 0x329c3269, 0x99c00006, 0x329c3267, 0x95c00005, 0xc01defff, 0x7d9d8009, + 0x8000078a, 0x25980000, 0x0b300001, 0x06a80001, 0xcd800026, 0x9b00fff2, 0xd8400027, 0xc43c0012, + 0x9bc0ffff, 0xcd400013, 0xd801325b, 0xc431325a, 0xc03e7ff0, 0x7f3f0009, 0xcf01325a, 0xc4313249, + 0x1f30001f, 0xcf013249, 0xc03e4000, 0xcfc13254, 0xcd400013, 0xd8013254, 0xc431325d, 0xd801324f, + 0xd8013255, 0xd8013247, 0xd801325d, 0x1b300028, 0x8c00120d, 0x8c001219, 0x8c001232, 0xc4380004, + 0xd8400008, 0xd8400013, 0x9900000d, 0xd88130b8, 0x9700000b, 0xc43d30b5, 0x1bf0003a, 0x9b000b80, + 0x203c003a, 0xc430000e, 0x27300700, 0x13300014, 0x2b300001, 0xcf0130b7, 0xcfc130b5, 0x46200008, + 0xcf400024, 0xd2000025, 0xd8000026, 0xd8400027, 0x043c2000, 0xcd400013, 0xcfc13267, 0xc43d3267, + 0x9bc00001, 0xccc00010, 0xcf800008, 0x90000000, 0xc4080007, 0xd9000010, 0xc4193260, 0x259c0003, + 0x31dc0003, 0x95c00014, 0x040c3000, 0xd8400008, 0xccc13267, 0xc40d3267, 0x18ec0057, 0x18e40213, + 0x18cc0199, 0x7cecc00a, 0x7ce4c00a, 0xc4193246, 0xc41d3245, 0x51980020, 0x7d9d801a, 0x8c000448, + 0xcd400013, 0x040c2000, 0xccc13267, 0xc40d3267, 0x94c00001, 0xcc800010, 0xd801325d, 0x90000000, + 0xc418000b, 0x31980002, 0x041c0000, 0x9980001c, 0x19580066, 0x15600008, 0x040c0000, 0xc0120001, + 0x11980003, 0x04240004, 0x7da18001, 0xc4200007, 0xc4340004, 0xd9000010, 0xd8400008, 0xd8400013, + 0xccc1c200, 0xc41d24db, 0x7cd0c001, 0x0a640001, 0x7dd9c005, 0x25dc0001, 0x99c00002, 0x9a40fff8, + 0xc418005e, 0x9580137b, 0xc00ee000, 0xd8400013, 0xccc1c200, 0xce000010, 0xcf400008, 0x90000000, + 0xd840004f, 0xc4113269, 0x19080070, 0x190c00e8, 0x2510003f, 0x2518000f, 0xcd813268, 0x05a80809, + 0x86800000, 0x8000080e, 0x8000080f, 0x80000898, 0x80000946, 0x800009e1, 0x80000a5a, 0x04a80811, + 0x86800000, 0x80000815, 0x80000834, 0x8000085e, 0x8000085e, 0x04341001, 0xcf400013, 0xc4380004, + 0xd8400008, 0xc42d3045, 0xcec1c091, 0x31300021, 0x9700000b, 0xd84002f1, 0xd8400013, 0xc43130b8, + 0x27300001, 0xc4293059, 0x56a8001f, 0x7f2b000a, 0xcf800008, 0x9b000241, 0x8000084a, 0xcf400013, + 0xd8400008, 0xc43130b6, 0x9b000003, 0xc02f0001, 0xcec130b6, 0xc4252087, 0x5668001a, 0x26a80005, + 0x9a80fffd, 0xcf400013, 0xd80130b6, 0x8000084a, 0xc4380004, 0xd8400008, 0x04341001, 0xcf400013, + 0xc431ecaa, 0x27300080, 0x9b000010, 0xc02e0001, 0xcec130b6, 0xcf400013, 0xd80130b6, 0x31300021, + 0x9700000a, 0xd84002f1, 0xd8400013, 0xc43130b8, 0x27300001, 0xc4293059, 0x56a8001f, 0x7f2b000a, + 0xcf800008, 0x9b00021d, 0xdd410000, 0x040c0005, 0xd84802e9, 0x8c001a41, 0xc43b02f1, 0x9b800006, + 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0xcf800008, 0xcec80278, 0x56f00020, 0xcf080280, + 0x8c001608, 0xdc140000, 0xcd400013, 0xd8813247, 0xd80802e9, 0x8000085e, 0xcd400013, 0x31100011, + 0x950001fa, 0xc02e0001, 0x2aec0008, 0xc01c0020, 0xc0180001, 0xc00c0007, 0x11a40006, 0x7de6000a, + 0x10e40008, 0x7e26000a, 0x7e2e000a, 0xce000013, 0xc4113254, 0x1d10ffdf, 0x2110003e, 0xcd013254, + 0xd801324f, 0xd8013255, 0x1d10ff9e, 0xcd013254, 0xd8013247, 0xd801325d, 0xd801325e, 0xc0245301, + 0xce413249, 0xd801325f, 0xc425326c, 0xc0121fff, 0x29108eff, 0x7e524009, 0xce41326c, 0xc425325a, + 0xc0127ff0, 0x7e524009, 0xce41325a, 0xc425325b, 0xc0131fff, 0x7e524009, 0xce41325b, 0xd801326d, + 0xd801326e, 0xd8013279, 0x94c00003, 0x08cc0001, 0x80000866, 0xc00c0007, 0x95800003, 0x09980001, + 0x80000866, 0xc0100010, 0x7dd2400c, 0x9a400004, 0xc0180003, 0x7dd1c002, 0x80000866, 0x80000a5a, + 0x04a8089a, 0x86800000, 0x8000089e, 0x800008fa, 0x80000945, 0x80000945, 0x31300022, 0x97000007, + 0xc4380004, 0xd8400008, 0xd8400013, 0xc43130b8, 0x27300001, 0xcf800008, 0xcd400013, 0x04183000, + 0xcd813267, 0xc4113246, 0xc4193245, 0x51100020, 0x7d91801a, 0x459801e0, 0xc4313267, 0x2738000f, + 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, + 0xd180001e, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8300011, 0x97000036, 0x45980008, 0xd180001e, + 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8340011, 0x9740002f, 0xc43c0004, 0xd8400008, 0xd8400013, + 0x13b80001, 0xc79d3300, 0xc7a13301, 0x96000001, 0xd8393300, 0xc0260001, 0xce793301, 0xc424005e, + 0x964012a4, 0x7c028009, 0x9740001c, 0x27580001, 0x99800004, 0x57740001, 0x06a80400, 0x800008d2, + 0xc4180006, 0x9980ffff, 0x29640001, 0xce40001a, 0x242c0000, 0x06ec0400, 0x57740001, 0x27580001, + 0x9980fffd, 0xc02620c0, 0xce41c078, 0xce81c080, 0xcc01c081, 0xcf01c082, 0x57240020, 0xce41c083, + 0xc0260400, 0x7e6e400a, 0xce41c084, 0x7eae8001, 0x7f2f0011, 0x800008d2, 0xc4180006, 0x9980ffff, + 0xcdf93300, 0xce393301, 0xcfc00008, 0xcd400013, 0xc43c0004, 0xd8400008, 0x04182000, 0xcd813267, + 0xcfc00008, 0x80000903, 0x31240022, 0x96400008, 0x04100001, 0xc4380004, 0xd8400008, 0xd8400013, + 0xc43130b8, 0x27300001, 0xcf800008, 0xc4af0280, 0xc4b30278, 0x52ec0020, 0x7ef2c01a, 0x7ec30011, + 0x32f80000, 0x9b800011, 0x043c0020, 0x04280000, 0x67180001, 0x0bfc0001, 0x57300001, 0x95800006, + 0x8c001628, 0x9a400003, 0xd981325d, 0x80000915, 0xd9c1325d, 0x06a80001, 0x9bc0fff6, 0x7f818001, + 0x8c001606, 0x7d838001, 0x94800010, 0xcd400013, 0xc41d3259, 0xc421325a, 0x16240014, 0x12640014, + 0x1a2801f0, 0x12a80010, 0x2620ffff, 0x7e2a000a, 0x7de1c001, 0x7e5e400a, 0x9b800002, 0x2264003f, + 0xce41325a, 0xd8013259, 0xc40c0007, 0xd9000010, 0x8c00075e, 0xc4af0228, 0x043c0000, 0x66d80001, + 0x95800010, 0x04300002, 0x1330000d, 0x13f40014, 0x7f73400a, 0xcf400013, 0x04380040, 0xcf80001b, + 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380060, 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, + 0x07fc0001, 0x56ec0001, 0x33e80010, 0x9680ffec, 0x80000a5a, 0x80000a5a, 0x04a80948, 0x86800000, + 0x8000094c, 0x8000099b, 0x800009e0, 0x800009e0, 0xc43c0004, 0xd8400008, 0xcd400013, 0x04183000, + 0xcd813267, 0xc4113246, 0xc4193245, 0x51100020, 0x7d91801a, 0x459801e0, 0xc4313267, 0x2738000f, + 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, + 0xd180001e, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8300011, 0x97000033, 0x45980008, 0xd180001e, + 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8340011, 0x9740002c, 0xd8400013, 0x13b80001, 0xc79d3300, + 0xc7a13301, 0x96000001, 0xd8393300, 0xc0260001, 0xce793301, 0xc424005e, 0x964011fe, 0x7c028009, + 0x9740001c, 0x27580001, 0x99800004, 0x57740001, 0x06a80400, 0x80000978, 0xc4180006, 0x9980ffff, + 0x29640001, 0xce40001a, 0x242c0000, 0x06ec0400, 0x57740001, 0x27580001, 0x9980fffd, 0xc0260010, + 0xce41c078, 0xcf01c080, 0x57240020, 0xce41c081, 0xce81c082, 0xcc01c083, 0xc0260800, 0x7e6e400a, + 0xce41c084, 0x7eae8001, 0x7f2f0011, 0x80000978, 0xc4180006, 0x9980ffff, 0xcdf93300, 0xce393301, + 0x04182000, 0xcd813267, 0xcfc00008, 0xcd400013, 0xc4193246, 0xc41d3245, 0x51980020, 0x7dda801a, + 0x7d41c001, 0x7e838011, 0xd84802e9, 0x8c001802, 0x469c0390, 0xc4313267, 0x04183000, 0xcd813267, + 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, + 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4200011, 0x45dc0004, 0xd1c0001e, + 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4240011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, + 0x9980ffff, 0xc4280011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc42c0011, + 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4300011, 0x45dc0004, 0xd1c0001e, + 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4340011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, + 0x9980ffff, 0xc4380011, 0xcd400013, 0x04182000, 0xcd813267, 0x043c0001, 0x8c0014df, 0x80000a5a, + 0x80000a5a, 0x31280014, 0xce8802ef, 0x9a800062, 0x31280034, 0x9a800060, 0x04a809e8, 0x86800000, + 0x800009ec, 0x80000a45, 0x80000a59, 0x80000a59, 0xcd400013, 0xc4113246, 0xc4193245, 0x51100020, + 0x7d91801a, 0x45980400, 0xc4b30258, 0xc4a70250, 0x53300020, 0x7e72401a, 0xc4313267, 0x1b342010, + 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, 0x042c0020, + 0x66740001, 0x97400041, 0xcd400013, 0x04383000, 0xcf813267, 0xc4393267, 0x9b800001, 0xd180001e, + 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4300011, 0x1b38007e, 0x33b40003, 0x9b400003, 0x4598001c, + 0x9740002f, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc40c0011, 0x45980004, + 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4100011, 0x45980004, 0xd180001e, 0xd8400021, + 0xc438000f, 0x9b80ffff, 0xc4340011, 0xcf4002eb, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, + 0x9b80ffff, 0xc4340011, 0xcf4002ec, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, + 0xc4340011, 0xcf4002ed, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4340011, + 0xcf4002ee, 0x45980004, 0xcd400013, 0x04382000, 0xcf813267, 0xd84802e9, 0x8c001715, 0xcd400013, + 0x04382000, 0xcf813267, 0x56640001, 0x0aec0001, 0x9ac0ffbc, 0xc4380004, 0xd8400008, 0x04341001, + 0xcf400013, 0x94800005, 0xc431ecaa, 0x27300080, 0x97000002, 0x80000a55, 0xc43130b6, 0x233c0032, + 0xcfc130b6, 0xcf400013, 0xcf0130b6, 0xc49302ef, 0x99000003, 0xcd400013, 0xd8413247, 0xcf800008, + 0x80000a5a, 0x80000a5a, 0xcd400013, 0x04180001, 0x5198001f, 0xcd813268, 0xc4193269, 0x2598000f, + 0x9980fffe, 0xd80002f1, 0xcd400013, 0xd8013268, 0xd800004f, 0x90000000, 0xcd400013, 0x04380001, + 0x53b8001f, 0x7db9801a, 0xcd813268, 0x80000a5e, 0xd8400029, 0xc40c005e, 0x94c01106, 0xd8800013, + 0xcc412e01, 0xcc412e02, 0xcc412e03, 0xcc412e00, 0x80000aa7, 0xd8400029, 0xc40c005e, 0x94c010fd, + 0x7c40c001, 0x50640020, 0x7ce4c01a, 0xd0c00072, 0xc80c0072, 0x58e801fc, 0x12a80009, 0x2aa80000, + 0xd0c0001e, 0xce80001c, 0xd8400021, 0xc424000f, 0x9a40ffff, 0x04240010, 0x18dc01e2, 0x7e5e4002, + 0x3e5c0003, 0x3e540002, 0x95c00006, 0xc8180011, 0xc8100011, 0xc8100011, 0x55140020, 0x80000aa2, + 0x9540000a, 0xc8180011, 0x44cc0008, 0x55900020, 0xd0c0001e, 0xd8400021, 0xc424000f, 0x9a40ffff, + 0xc4140011, 0x80000aa2, 0x44cc0004, 0xc4180011, 0xd0c0001e, 0xd8400021, 0xc424000f, 0x9a40ffff, + 0xc8100011, 0x55140020, 0xd8800013, 0xcd812e01, 0xcd012e02, 0xcd412e03, 0xcc412e00, 0xc428000e, + 0x2aa80008, 0xce800013, 0xc4253249, 0x2264003f, 0xce413249, 0xce800013, 0xc4253249, 0x96400001, + 0xd800002a, 0xc410001a, 0xc40c0021, 0xc4140028, 0x95000005, 0x1e64001f, 0xce800013, 0xce413249, + 0x80001b70, 0x14d00010, 0xc4180030, 0xc41c0007, 0x99000004, 0x99400009, 0x9980000c, 0x80000ab1, + 0xccc00037, 0x8c000190, 0xc420001c, 0xd8000032, 0x9a0010ac, 0x80000aa7, 0xd880003f, 0x95c00002, + 0xd8c0003f, 0x80001082, 0xd8800040, 0x95c00002, 0xd8c00040, 0x800010de, 0xc010ffff, 0x18d403f7, + 0x7d0cc009, 0xc41b0367, 0x7d958004, 0x7d85800a, 0xdc1e0000, 0x90000000, 0xc424000b, 0x32640002, + 0x7c40c001, 0x18d001fc, 0x05280adc, 0x86800000, 0x80000af1, 0x80000adf, 0x80000ae7, 0x8c000ace, + 0xd8c00013, 0x96400002, 0xd8400013, 0xcd8d2000, 0x99c00010, 0x7c408001, 0x88000000, 0x18d803f7, + 0xc010ffff, 0x7d0cc009, 0x04140000, 0x11940014, 0x29544001, 0x9a400002, 0x29544003, 0xcd400013, + 0x80000af4, 0xd8c00013, 0x96400002, 0xd8400013, 0xd44d2000, 0x7c408001, 0x88000000, 0xc424000b, + 0x32640002, 0x7c40c001, 0xd8c00013, 0x96400002, 0xd8400013, 0xd44dc000, 0x7c408001, 0x88000000, + 0x7c40c001, 0x18d0003c, 0x95000006, 0x8c000ace, 0xd8800013, 0xcd8d2c00, 0x99c00003, 0x80000b0a, + 0xd8800013, 0xd44d2c00, 0x7c408001, 0x88000000, 0x7c40c001, 0x28148004, 0x24d800ff, 0xccc00019, + 0xcd400013, 0xd4593240, 0x7c408001, 0x88000000, 0xd8400029, 0xc40c005e, 0x94c0105e, 0x7c410001, + 0x50540020, 0x7c418001, 0x2198003f, 0x199c0034, 0xc40c0007, 0x95c00028, 0xc428000e, 0x2aa80008, + 0xce800013, 0xc42d324f, 0xc4313255, 0x7ef3400c, 0x9b400021, 0xd800002a, 0x80001b70, 0xc40c0007, + 0x14e80001, 0x9a8000af, 0xd9000010, 0x041c0002, 0x042c01c8, 0x8c000d61, 0xccc00010, 0xd8400029, + 0xc40c005e, 0x94c01043, 0x7c410001, 0x50540020, 0x7c418001, 0x18a01fe8, 0x3620005c, 0x9a00000e, + 0x2464003f, 0xd8400013, 0xc6290ce7, 0x16ac001f, 0x96c00004, 0x26ac003f, 0x7ee6c00d, 0x96c00005, + 0x06200001, 0x2620000f, 0x9a00fff8, 0x8000016a, 0xce000367, 0xc424005e, 0x9640102e, 0xc428000e, + 0x199c0037, 0x19a00035, 0x2aa80008, 0xce800013, 0x95c0005d, 0xd800002a, 0xc42d3256, 0xc431325a, + 0x2330003f, 0x16f8001f, 0x9780000d, 0xc4253248, 0xc035f0ff, 0x7e764009, 0x19b401f8, 0x13740008, + 0x7e76400a, 0xce800013, 0xce413248, 0xcf01325a, 0xce800013, 0xc431325a, 0x97000001, 0x7d15001a, + 0xd1000072, 0xc8100072, 0x55140020, 0x199c0034, 0xd8400010, 0xd8400029, 0x9b800004, 0x1ae4003e, + 0xce400008, 0x80000b7c, 0xc4353254, 0x16a80008, 0x1aec003c, 0x19a4003f, 0x12a80015, 0x12ec001f, + 0x1374000b, 0x7eae800a, 0xc02e4000, 0x1774000d, 0x7eae800a, 0xce400008, 0x7f6b400a, 0x95c00005, + 0xc43d3248, 0x1bfc01e8, 0x13fc0018, 0x7dbd800a, 0x1d98ff15, 0x592c00fc, 0xcd80000a, 0x12e00016, + 0x7da1800a, 0x592c007e, 0x12e00015, 0x7da1800a, 0xd1000001, 0xcd800001, 0x11a0000c, 0x1264001e, + 0x1620000c, 0x7e26000a, 0x7e32000a, 0x12e4001b, 0x7e26000a, 0x5924007e, 0x12640017, 0x7e26000a, + 0x19a4003c, 0x12640018, 0x7e26000a, 0xd800002a, 0xce01325a, 0xcd013257, 0xcd413258, 0xc429325a, + 0xc40c005e, 0x94c00fdb, 0x96800001, 0x95c00003, 0x7c40c001, 0x7c410001, 0x9780f5ca, 0xcf400100, + 0xc40c0007, 0xd9000010, 0x8c00120d, 0x8c001219, 0x8c001232, 0xccc00010, 0x8c001b6d, 0x7c408001, + 0x88000000, 0xc42d324e, 0xc431324d, 0x52ec0020, 0x7ef2c01a, 0xc435324f, 0xc4293256, 0x52ec0008, + 0x07740003, 0x04240002, 0x269c003f, 0x7e5e4004, 0x7f67000f, 0x97000003, 0x7f674002, 0x0b740001, + 0x53740002, 0x7ef6c011, 0x1ab42010, 0x1ab8c006, 0x16a8000c, 0x26a80800, 0x2b740000, 0x7f7b400a, + 0x7f6b400a, 0xcf40001c, 0xd2c0001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4180011, 0x9a000003, + 0x8c000bec, 0x80000b47, 0xc42c001d, 0xc4313256, 0x1b34060b, 0x1b300077, 0x7f370009, 0x13300017, + 0x04340100, 0x26ec00ff, 0xc03a8004, 0x7ef6c00a, 0x7f3b000a, 0x7ef2c00a, 0xcec1325b, 0x80000c16, + 0xc40c0032, 0xc410001d, 0x28cc0008, 0xccc00013, 0xc415325b, 0x7c418001, 0x7c418001, 0x18580037, + 0x251000ff, 0xc421325d, 0x262001ef, 0xce01325d, 0x99800004, 0x7d15400a, 0xcd41325b, 0x80000168, + 0x1d54001f, 0xcd41325b, 0x7c408001, 0x88000000, 0xc428000b, 0xc42c000c, 0x12a80001, 0x26a80004, + 0x7eae800a, 0xc40c0021, 0xc4340028, 0x14f00010, 0xc4380030, 0xc43c0007, 0xcd280200, 0xcd680208, + 0xcda80210, 0x9b00000c, 0x9b400014, 0x9b800017, 0xc428000b, 0xc42c000c, 0x12a80001, 0x26a80004, + 0x7eae800a, 0xc6930200, 0xc6970208, 0xc69b0210, 0x90000000, 0x17300001, 0x9b000005, 0xccc00037, + 0x8c000190, 0xd8000032, 0x90000000, 0xd8000028, 0xd800002b, 0x80000168, 0xd900003f, 0x97c00002, + 0xd940003f, 0x80001082, 0xd9000040, 0x97c00002, 0xd9400040, 0x800010de, 0xc40c0021, 0x14fc0011, + 0x24f800ff, 0x33b80001, 0x97c0fffc, 0x9b800007, 0xccc00037, 0x8c000190, 0xd8000032, 0xd8000028, + 0xd800002b, 0x80001b70, 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0x04100000, 0x04140000, + 0xc418000e, 0x29980008, 0x7d83c001, 0xcd800013, 0xc4093249, 0x1888003e, 0x94800020, 0xd8400074, + 0x8c000671, 0x9a400009, 0xc418000e, 0x29980008, 0xcd800013, 0xc419324c, 0x259c0001, 0x1598001f, + 0x95c00016, 0x95800015, 0x99000003, 0xd8400036, 0x04100001, 0xc40c0021, 0x14d80011, 0x24e000ff, + 0x321c0002, 0x32200001, 0x9580ffee, 0x99c00014, 0x96000004, 0xccc00037, 0x04140001, 0x80000c30, + 0x9480000a, 0xd8000074, 0xc418005e, 0x95800f29, 0xcf800008, 0x80000c16, 0x94800004, 0xd8000074, + 0xc418005e, 0x95800f23, 0xd9c00036, 0x99400002, 0xccc00037, 0xcf800008, 0x80000c16, 0x94800004, + 0xd8000074, 0xc418005e, 0x95800f1a, 0xccc00037, 0xd8800036, 0x80001b70, 0x041c0003, 0x042c01c8, + 0x8c000d61, 0xc4200007, 0xc40c0077, 0x94c00001, 0x7c418001, 0xc428000e, 0x9600f502, 0x0a200001, + 0x98c0f500, 0x2aa80008, 0xce000010, 0x9a000f05, 0xce800013, 0xc431325a, 0xc42d3256, 0x1f30001f, + 0x16e4001f, 0xcf01325a, 0xc431325a, 0x97000001, 0x9640f4f4, 0xc434000b, 0x33740002, 0x9b40f4f1, + 0xc4353254, 0x16a80008, 0x1aec003c, 0x12a80015, 0x12ec001f, 0x1374000b, 0x7eae800a, 0xc02e4000, + 0x1774000d, 0x7eae800a, 0x7f6b400a, 0xcf400100, 0x12780001, 0x2bb80001, 0xc00ac005, 0xc00e0002, + 0x28cc8000, 0x28884900, 0x28cc0014, 0x80000ff3, 0xc43c0007, 0x7c40c001, 0x17fc0001, 0xd8400013, + 0x9bc00004, 0xd8400029, 0xc424005e, 0x96400ee1, 0xcc41c40a, 0xcc41c40c, 0xcc41c40d, 0x7c414001, + 0x24d0007f, 0x15580010, 0x255400ff, 0xcd01c411, 0xcd81c40f, 0xcd41c40e, 0xcc41c410, 0x7c414001, + 0x7c418001, 0x04200000, 0x18e80033, 0x18ec0034, 0xcc41c414, 0xcc41c415, 0xcd81c413, 0xcd41c412, + 0x18dc0032, 0x7c030011, 0x7c038011, 0x95c00027, 0x96c00002, 0xc431c417, 0xc435c416, 0x96800004, + 0x96c00002, 0xc439c419, 0xc43dc418, 0xc41c000e, 0x29dc0008, 0xcdc00013, 0xcf413261, 0x96c00002, + 0xcf013262, 0x96800004, 0xcfc13263, 0x96c00002, 0xcf813264, 0x18dc0030, 0xc43c0007, 0x95c00017, + 0x17fc0001, 0x9ac00005, 0x7d77000c, 0x9bc00015, 0x9700000a, 0x80000cd6, 0x51b80020, 0x53300020, + 0x7f97801a, 0x7f37001a, 0x7f3b000c, 0x9bc0000d, 0x97800002, 0x80000cd6, 0x9a000018, 0xd8400013, + 0x28200001, 0x80000ca7, 0x18dc0031, 0x95c00003, 0xc435c40b, 0x9740fffd, 0xd800002a, 0x80001b70, + 0xc4280032, 0x2aa80008, 0xce800013, 0xc40d325b, 0x97000002, 0x800012c2, 0xc438001d, 0x1bb81ff0, + 0x7f8cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, 0xcd01325d, 0x80001b70, 0xc428000e, 0xc43c0007, + 0x2aa80008, 0xc438001d, 0xce800013, 0x13f4000c, 0x9bc00006, 0xc43d3256, 0x1bf0060b, 0x1bfc0077, + 0x7ff3c00a, 0x80000cf4, 0xc43d325a, 0x1bfc0677, 0x13fc0017, 0x04300100, 0x1bb81fe8, 0x7f73400a, + 0xc032800b, 0x7fb7800a, 0x7ff3c00a, 0x7ffbc00a, 0xcfc1325b, 0x80000c16, 0xc43c0007, 0x7c40c001, + 0x18d42011, 0x17fc0001, 0x18d001e8, 0x24cc007f, 0x7cd4c00a, 0x9bc00004, 0xd8400029, 0xc428005e, + 0x96800e6c, 0x7c414001, 0x50580020, 0x7d59401a, 0xd1400072, 0xc8140072, 0x596001fc, 0x12200009, + 0x7ce0c00a, 0x7c418001, 0x505c0020, 0x7d9d801a, 0x7c41c001, 0x50600020, 0x7de1c01a, 0x7c420001, + 0xccc0001b, 0xd140001d, 0xd180001f, 0xd1c00020, 0xd8400021, 0x95000010, 0x04300000, 0xc428000f, + 0x9a80ffff, 0xc8240010, 0x7e5e800c, 0x9bc00015, 0x9a80000c, 0x9b000024, 0x28300001, 0x122c0004, + 0x06ec0001, 0x0aec0001, 0x9ac0ffff, 0xd8400021, 0x80000d1f, 0xc428000f, 0x9a80ffff, 0xc8240010, + 0x566c0020, 0xc428000e, 0x2aa80008, 0xce800013, 0xce413261, 0xcec13262, 0xd800002a, 0x80001b70, + 0xc4340032, 0x2b740008, 0xcf400013, 0xc40d325b, 0x96800005, 0x566c0020, 0xce413261, 0xcec13262, + 0x800012c2, 0xc438001d, 0x1bb81fe8, 0x7f8cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, 0xcd01325d, + 0x80001b70, 0xc43c0007, 0xc438001d, 0xc428000e, 0x2aa80008, 0xce800013, 0x13f4000c, 0x9bc00006, + 0xc43d3256, 0x1bf0060b, 0x1bfc0077, 0x7ff3c00a, 0x80000d57, 0xc43d325a, 0x1bfc0677, 0x13fc0017, + 0x04300100, 0x1bb81fe8, 0x7f73400a, 0xc0328009, 0x7fb7800a, 0x7ff3c00a, 0x7ffbc00a, 0xcfc1325b, + 0x80000c16, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0xc4253246, 0xc4113245, 0x04143000, 0xcd413267, + 0x52640020, 0x7e51001a, 0xc4153267, 0x7d2d0011, 0x19640057, 0x19580213, 0x19600199, 0x7da6400a, + 0x7e26400a, 0xd1000025, 0xce400024, 0xcdc00026, 0xd8400027, 0x04142000, 0xcfc00013, 0xcd413267, + 0xc4153267, 0x99400001, 0x90000000, 0x7c40c001, 0x18d001e8, 0x18d40030, 0x18d80034, 0x05280d83, + 0x7c420001, 0x7c424001, 0x86800000, 0x80000d8a, 0x8000016a, 0x80000d95, 0x80000db1, 0x8000016a, + 0x80000d95, 0x80000dbc, 0x11540010, 0x7e010001, 0x8c00187c, 0x7d75400a, 0xcd400013, 0xd4610000, + 0x9580f3d8, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0xd8000016, 0x526c0020, 0x18e80058, + 0x7e2ec01a, 0xd2c00072, 0xc82c0072, 0x5ae0073a, 0x7ea2800a, 0x9940000a, 0xce800024, 0xd2c00025, + 0xd4400026, 0xd8400027, 0x9580f3c6, 0xc4380012, 0x9b80ffff, 0x7c408001, 0x88000000, 0xdc3a0000, + 0x0bb80001, 0xce800024, 0xd2c00025, 0xcc400026, 0xd8400027, 0x9b80fffb, 0x9980fff5, 0x7c408001, + 0x88000000, 0xc02a0001, 0x2aa80001, 0x16200002, 0xce800013, 0xce01c405, 0xd441c406, 0x9580f3b1, + 0xc439c409, 0x97800001, 0x7c408001, 0x88000000, 0xc424000b, 0x32640002, 0x9a40000b, 0x11540010, + 0x29540002, 0xcd400013, 0xd4610000, 0x9580f3a5, 0xd8400013, 0xc439c040, 0x97800001, 0x7c408001, + 0x88000000, 0xd4400078, 0x80000168, 0xd8400029, 0xc40c005e, 0x94c00da7, 0x7c40c001, 0x50500020, + 0x7cd0c01a, 0xd0c00072, 0xc8280072, 0x5aac007e, 0x12d80017, 0x7c41c001, 0x7d9d800a, 0x56a00020, + 0x2620ffff, 0x7da1800a, 0x51980020, 0x7e82400a, 0x7e58c01a, 0x19d4003d, 0x28182002, 0x99400030, + 0x8c00104f, 0xc430000d, 0xc4340035, 0xd800002a, 0xcd800013, 0xc8140023, 0xc4180081, 0x13300005, + 0xc011000f, 0xc4240004, 0x11a00002, 0x7c908009, 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, + 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x3e280008, 0x20880188, 0x54ec0020, 0x7cb4800a, 0xc4300027, + 0x04380008, 0xd1400025, 0xcf000024, 0x20240090, 0x7ca48001, 0xcc800026, 0xccc00026, 0xcec00026, + 0xcec00026, 0x28240004, 0xcc000026, 0x0a640001, 0x9a40fffe, 0x9a800005, 0x32280000, 0x9a800002, + 0x9a000000, 0x7c018001, 0xd8400027, 0xd8000016, 0xcf80003a, 0xd901a2a4, 0x80001037, 0xc418000e, + 0x29980008, 0xcd800013, 0xc421326c, 0x1624001f, 0x9a40fffe, 0xd841325f, 0xd8800033, 0xc43c0009, + 0x27fc0004, 0x97c0fffe, 0xd8000039, 0xd0c00038, 0xc43c0022, 0x9bc0ffff, 0xd8800034, 0xc429325f, + 0x26ac0001, 0x9ac0fffe, 0x26ac0002, 0x96c00003, 0xd800002a, 0x80001b70, 0xc43c0007, 0xc430001e, + 0xd8800033, 0x13f4000c, 0x1b301ff0, 0x2b300300, 0x2330003f, 0x7f37000a, 0x9680000b, 0xc43c0009, + 0x27fc0004, 0x97c0fffe, 0xd8400039, 0xd0c00038, 0xc43c0022, 0x9bc0ffff, 0xcf01325b, 0xd8800034, + 0x80000c16, 0xd8800034, 0x8c0001a2, 0x80001b70, 0xcc80003b, 0x24b00008, 0xc418000e, 0x1330000a, + 0x18ac0024, 0x2b304000, 0x7c40c001, 0xcec00008, 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, + 0x29980008, 0xcd800013, 0xc4113249, 0x1910003e, 0x99000002, 0xd840003d, 0x7c410001, 0xd4400078, + 0x51100020, 0xcf01326c, 0x7cd0c01a, 0xc421326c, 0x12a80014, 0x2220003f, 0x7e2a000a, 0xcd800013, + 0xce01326c, 0xd8800033, 0xc43c0009, 0x27fc0004, 0x97c0fffe, 0xd8000039, 0xd0c00038, 0xc43c0022, + 0x9bc0ffff, 0xd8800034, 0x80001190, 0x7c40c001, 0x18dc003d, 0x95c00004, 0x041c0001, 0x042c01c8, + 0x8c000d61, 0x18d40030, 0x18d001e8, 0x18fc0034, 0x24e8000f, 0x06a80e71, 0x7c418001, 0x7c41c001, + 0x86800000, 0x80000edd, 0x80000e91, 0x80000e91, 0x80000ea1, 0x80000eaa, 0x80000e7c, 0x80000e7f, + 0x80000e7f, 0x80000e87, 0x80000e8f, 0x8000016a, 0x51dc0020, 0x7d9e001a, 0x80000ee6, 0xc420000e, + 0x2a200008, 0xce000013, 0xc4213262, 0xc4253261, 0x52200020, 0x7e26001a, 0x80000ee6, 0xc420000e, + 0x2a200008, 0xce000013, 0xc4213264, 0xc4253263, 0x52200020, 0x7e26001a, 0x80000ee6, 0xc820001f, + 0x80000ee6, 0x18e82005, 0x51e00020, 0x2aa80000, 0x7da1801a, 0xd1800072, 0xc8180072, 0x59a001fc, + 0x12200009, 0x7ea2800a, 0xce80001c, 0xd180001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc8200011, + 0x80000ee6, 0x15980002, 0xd8400013, 0xcd81c400, 0xc421c401, 0x95400041, 0xc425c401, 0x52640020, + 0x7e26001a, 0x80000ee6, 0x31ac2580, 0x9ac00011, 0x31ac260c, 0x9ac0000f, 0x31ac0800, 0x9ac0000d, + 0x31ac0828, 0x9ac0000b, 0x31ac2440, 0x9ac00009, 0x31ac2390, 0x9ac00007, 0x31ac0093, 0x9ac00005, + 0x31ac31dc, 0x9ac00003, 0x31ac31e6, 0x96c00004, 0xc4340004, 0xd8400008, 0x80000ede, 0x39ac7c06, + 0x3db07c00, 0x9ac00003, 0x97000002, 0x80000ebc, 0x39acc337, 0x3db0c330, 0x9ac00003, 0x97000002, + 0x80000ebc, 0x39acc335, 0x3db0c336, 0x9ac00003, 0x97000002, 0x80000ebc, 0x39ac9002, 0x3db09001, + 0x9ac00003, 0x97000002, 0x80000ebc, 0x39ac9012, 0x3db09011, 0x9ac00003, 0x97000002, 0x80000ebc, + 0x39acec70, 0x3db0ec6f, 0x9ac00003, 0x97000002, 0x80000ebc, 0xc4340004, 0xd8400013, 0xc5a10000, + 0x95400005, 0x05980001, 0xc5a50000, 0x52640020, 0x7e26001a, 0xcf400008, 0x05280eea, 0x7c418001, + 0x7c41c001, 0x86800000, 0x80000ef1, 0x8000016a, 0x80000efe, 0x80000f11, 0x80000f2e, 0x80000efe, + 0x80000f1f, 0xc4340004, 0xd8400013, 0xce190000, 0x95400005, 0x05980001, 0x56200020, 0xce190000, + 0xcf400008, 0x97c0f26f, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0x51ec0020, 0x18e80058, + 0x7daec01a, 0xd2c00072, 0xc82c0072, 0x5af8073a, 0x7eba800a, 0xd2c00025, 0xce800024, 0xce000026, + 0x95400003, 0x56240020, 0xce400026, 0xd8400027, 0x97c0f25c, 0xc4380012, 0x9b80ffff, 0x7c408001, + 0x88000000, 0xc02a0001, 0x2aa80001, 0x15980002, 0xce800013, 0xcd81c405, 0xce01c406, 0x95400003, + 0x56240020, 0xce41c406, 0x97c0f24e, 0xc439c409, 0x97800001, 0x7c408001, 0x88000000, 0xc424000b, + 0x32640002, 0x9a40f247, 0xd8800013, 0xce190000, 0x95400004, 0x05980001, 0x56200020, 0xce190000, + 0x97c0f240, 0xd8400013, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0x31ac2580, 0x9ac00011, + 0x31ac260c, 0x9ac0000f, 0x31ac0800, 0x9ac0000d, 0x31ac0828, 0x9ac0000b, 0x31ac2440, 0x9ac00009, + 0x31ac2390, 0x9ac00007, 0x31ac0093, 0x9ac00005, 0x31ac31dc, 0x9ac00003, 0x31ac31e6, 0x96c00004, + 0xc4340004, 0xd8400008, 0x80000ef2, 0x39ac7c06, 0x3db07c00, 0x9ac00003, 0x97000002, 0x80000f40, + 0x39acc337, 0x3db0c330, 0x9ac00003, 0x97000002, 0x80000f40, 0x39acc335, 0x3db0c336, 0x9ac00003, + 0x97000002, 0x80000f40, 0x39acec70, 0x3db0ec6f, 0x9ac00003, 0x97000002, 0x80000f40, 0x39ac9002, + 0x3db09002, 0x9ac00003, 0x97000002, 0x80000f40, 0x39ac9012, 0x3db09012, 0x9ac00003, 0x97000002, + 0x80000f40, 0x80000ef1, 0xc40c0006, 0x98c0ffff, 0x7c40c001, 0x7c410001, 0x7c414001, 0x7c418001, + 0x7c41c001, 0x7c43c001, 0x95c00001, 0xc434000e, 0x2b740008, 0x2b780001, 0xcf400013, 0xd8c1325e, + 0xcf80001a, 0xd8400013, 0x7c034001, 0x7c038001, 0x18e0007d, 0x32240003, 0x9a400006, 0x32240000, + 0x9a400004, 0xcd01c080, 0xcd41c081, 0x80000f88, 0x51640020, 0x7e52401a, 0xd2400072, 0xc8280072, + 0xce81c080, 0x56ac0020, 0x26f0ffff, 0xcf01c081, 0x1af000fc, 0x1334000a, 0x24e02000, 0x7f63400a, + 0x18e00074, 0x32240003, 0x9a400006, 0x32240000, 0x9a400004, 0xcd81c082, 0xcdc1c083, 0x80000f9d, + 0x51e40020, 0x7e5a401a, 0xd2400072, 0xc8280072, 0xce81c082, 0x56ac0020, 0x26f0ffff, 0xcf01c083, + 0x1af000fc, 0x13380016, 0x18e00039, 0x12200019, 0x7fa3800a, 0x7fb7800a, 0x18e0007d, 0x1220001d, + 0x7fa3800a, 0x18e00074, 0x12200014, 0x7fa3800a, 0xcf81c078, 0xcfc1c084, 0x80000c16, 0x7c40c001, + 0x18dc003d, 0x95c00004, 0x041c0000, 0x042c01c8, 0x8c000d61, 0x18d001e8, 0x31140005, 0x99400003, + 0x31140006, 0x95400002, 0x8c00104f, 0x05280fb7, 0x28140002, 0xcd400013, 0x86800000, 0x80000fbe, + 0x80000fbe, 0x80000fc2, 0x80000fbe, 0x80000fd1, 0x80000ff2, 0x80000ff2, 0x24cc003f, 0xccc1a2a4, + 0x7c408001, 0x88000000, 0x7c414001, 0x18e80039, 0x52a8003b, 0x50580020, 0x24cc003f, 0x7d59401a, + 0xd1400072, 0xc8140072, 0x7d69401a, 0xc41c0017, 0x99c0ffff, 0xd140004b, 0xccc1a2a4, 0x7c408001, + 0x88000000, 0xc414000d, 0x04180001, 0x24cc003f, 0x7d958004, 0xcd800035, 0xccc1a2a4, 0xc43c000e, + 0x2bfc0008, 0xcfc00013, 0xc43d3249, 0x1bfc003e, 0x97c00002, 0xd8400074, 0xc4100019, 0x7d150005, + 0x25100001, 0x9500000b, 0x97c0fffc, 0xc4180021, 0x159c0011, 0x259800ff, 0x31a00003, 0x31a40001, + 0x7e25800a, 0x95c0fff5, 0x9580fff4, 0x80000fef, 0xc411326f, 0x1d100010, 0xcd01326f, 0x97c00002, + 0xd8000074, 0x80001b70, 0x04380000, 0xc430000d, 0xc8140023, 0xc4180081, 0x13300005, 0xc011000f, + 0xc4240004, 0x33b40003, 0x97400003, 0xc0340008, 0x80000ffe, 0xc4340035, 0x11a00002, 0x7c908009, + 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x282c2002, + 0x208801a8, 0x3e280008, 0x7cb4800a, 0xcec00013, 0xc4300027, 0x042c0008, 0xd1400025, 0xcf000024, + 0x20240030, 0x7ca48001, 0xcc800026, 0xccc00026, 0x9b800013, 0xcc400026, 0x7c414001, 0x28340000, + 0xcf400013, 0x507c0020, 0x7d7d401a, 0xd1400072, 0xc8140072, 0x557c0020, 0x28342002, 0xcf400013, + 0xcd400026, 0xcfc00026, 0xd4400026, 0x9a80000e, 0x32280000, 0x9a80000b, 0x8000102f, 0xcc000026, + 0xcc000026, 0xcc000026, 0xcc000026, 0xcc000026, 0x9a800005, 0x32280000, 0x9a800002, 0x9a000000, + 0x7c018001, 0xcc000026, 0xd8400027, 0x1cccfe08, 0xd8800013, 0xcec0003a, 0xccc1a2a4, 0xc43c000e, + 0x2bfc0008, 0xcfc00013, 0xc43d3249, 0x1bfc003e, 0x9bc00007, 0xc428000e, 0x16a80008, 0xce800009, + 0xc42c005e, 0x96c00b33, 0xd840003c, 0xc4200025, 0x7da2400f, 0x7da28002, 0x7e1ac002, 0x0aec0001, + 0x96400002, 0x7d2ac002, 0x3ef40010, 0x9b40f11d, 0x04380030, 0xcf81325e, 0x80000c16, 0xde410000, + 0xdcc10000, 0xdd010000, 0xdd410000, 0xdd810000, 0xddc10000, 0xde010000, 0xc40c000e, 0x7c024001, + 0x28cc0008, 0xccc00013, 0xc8100086, 0x5510003f, 0xc40d3249, 0x18cc003e, 0x98c00003, 0x99000011, + 0x80001075, 0x9900000c, 0xc40c0026, 0xc4100081, 0xc4140025, 0x7d15800f, 0x7d15c002, 0x7d520002, + 0x0a200001, 0x95800002, 0x7cde0002, 0x3e20001a, 0x9a000009, 0x040c0030, 0xccc1325e, 0x80001071, + 0xd9c00036, 0xd8400029, 0xc40c005e, 0x94c00b01, 0x04240001, 0xdc200000, 0xdc1c0000, 0xdc180000, + 0xdc140000, 0xdc100000, 0xdc0c0000, 0x96400004, 0xdc240000, 0xdc0c0000, 0x80000c16, 0xdc240000, + 0x90000000, 0xcc40003f, 0xd8c00010, 0xc4080029, 0xcc80003b, 0xc418000e, 0x18a800e5, 0x1d980008, + 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, 0x18a400e5, 0x12500009, 0x248c0008, 0x94c00006, + 0x200c006d, 0x7cd0c00a, 0xccc1326c, 0xc421326c, 0x96000001, 0xcd800013, 0x200c0228, 0x7cd0c00a, + 0xccc1326c, 0xc421326c, 0x96000001, 0xc40c002a, 0xc410002b, 0x18881fe8, 0x18d4072c, 0x18cc00d1, + 0x7cd4c00a, 0x3094000d, 0x38d80000, 0x311c0003, 0x99400006, 0x30940007, 0x1620001f, 0x9940001d, + 0x9a000023, 0x800010c4, 0x9580001a, 0x99c00019, 0xccc00041, 0x25140001, 0xc418002c, 0x9940000d, + 0x259c007f, 0x95c00013, 0x19a00030, 0xcdc0001b, 0xd8400021, 0xd8400022, 0xc430000f, 0x17300001, + 0x9b00fffe, 0x9a000012, 0xd8400023, 0x800010cb, 0x199c0fe8, 0xcdc0001b, 0xd8400021, 0xd8400023, + 0xc430000f, 0x17300001, 0x9b00fffe, 0x800010cb, 0xd8c00010, 0xd8000022, 0xd8000023, 0xc430005e, + 0x97000aac, 0x7c408001, 0x88000000, 0xc43c000e, 0xc434002e, 0x2bfc0008, 0x2020002c, 0xcfc00013, + 0xce01326c, 0x17780001, 0x27740001, 0x07a810d8, 0xcf400010, 0xc421326c, 0x96000001, 0x86800000, + 0x80000168, 0x80000aa7, 0x80000bfc, 0x800012e9, 0x8000104c, 0xcc400040, 0xd8800010, 0xc4180032, + 0x29980008, 0xcd800013, 0x200c007d, 0xccc1325b, 0xc411325b, 0x95000001, 0x7c408001, 0x88000000, + 0x28240007, 0xde430000, 0xd4400078, 0x80001190, 0xcc80003b, 0x24b00008, 0xc418000e, 0x1330000a, + 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, 0xc40d3249, 0x18cc003e, + 0x98c00002, 0xd840003d, 0x2b304000, 0xcf01326c, 0xc431326c, 0x7c40c001, 0x7c410001, 0x7c414001, + 0x192400fd, 0x50580020, 0x7d59401a, 0x7c41c001, 0x06681110, 0x7c420001, 0xcc400078, 0x18ac0024, + 0x19180070, 0x19100078, 0xcec00008, 0x18f40058, 0x5978073a, 0x7f7b400a, 0x97000001, 0x86800000, + 0x80001117, 0x80001118, 0x80001122, 0x8000112d, 0x80001130, 0x80001133, 0x8000016a, 0x8000117b, + 0x24ec0f00, 0x32ec0600, 0x96c00003, 0xc4300006, 0x9b00ffff, 0xd1400025, 0xcf400024, 0xcdc00026, + 0xd8400027, 0x8000117b, 0x24ec0f00, 0x32ec0600, 0x96c00003, 0xc4300006, 0x9b00ffff, 0xd1400025, + 0xcf400024, 0xcdc00026, 0xce000026, 0xd8400027, 0x8000117b, 0xc81c001f, 0x55e00020, 0x80001122, + 0xc81c0020, 0x55e00020, 0x80001122, 0x8c00116b, 0xd8400013, 0xc02a0200, 0x7e8e8009, 0x22a8003d, + 0x22a80074, 0x2774001c, 0x13740014, 0x7eb6800a, 0x25ecffff, 0x55700020, 0x15f40010, 0x13740002, + 0x275c001f, 0x95c00027, 0x7c018001, 0x7f41c001, 0x15dc0002, 0x39e00008, 0x25dc0007, 0x7dc1c01e, + 0x05dc0001, 0x96000004, 0x05e40008, 0x8c00116e, 0x80001168, 0x7dc2001e, 0x06200001, 0x05e40008, + 0x7e62000e, 0x9a000004, 0x7da58001, 0x8c00116e, 0x80001165, 0x7dc2001e, 0x06200001, 0x7e1a0001, + 0x05cc0008, 0x7e0d000e, 0x95000007, 0x7e02401e, 0x06640001, 0x06640008, 0x05d80008, 0x8c00116e, + 0x80001168, 0x7dc2401e, 0x06640001, 0x7da58001, 0x8c00116e, 0x05e00008, 0x7da2000c, 0x9600ffe6, + 0x17640002, 0x8c00116e, 0x80001190, 0xc4200006, 0x9a00ffff, 0x90000000, 0x8c00116b, 0xc420000e, + 0x2a200001, 0xce00001a, 0xce81c078, 0xcec1c080, 0xcc01c081, 0xcd41c082, 0xcf01c083, 0x12640002, + 0x22640435, 0xce41c084, 0x90000000, 0x0528117e, 0x312c0003, 0x86800000, 0x80001190, 0x80001185, + 0x80001182, 0x80001182, 0xc4300012, 0x9b00ffff, 0x9ac0000c, 0xc03a0400, 0xc4340004, 0xd8400013, + 0xd8400008, 0xc418000e, 0x15980008, 0x1198001c, 0x7d81c00a, 0xcdc130b7, 0xcf8130b5, 0xcf400008, + 0x04240008, 0xc418000e, 0xc41c0049, 0x19a000e8, 0x29a80008, 0x7de2c00c, 0xce800013, 0xc421325e, + 0x26200010, 0xc415326d, 0x9a000006, 0xc420007d, 0x96000004, 0x96c00003, 0xce40003e, 0x800011a3, + 0x7d654001, 0xcd41326d, 0x7c020001, 0x96000005, 0xc4100026, 0xc4240081, 0xc4140025, 0x800011b6, + 0xc4253279, 0xc415326d, 0xc431326c, 0x2730003f, 0x3b380006, 0x97800004, 0x3f38000b, 0x9b800004, + 0x800011b4, 0x04300006, 0x800011b4, 0x0430000b, 0x04380002, 0x7fb10004, 0x7e57000f, 0x7e578002, + 0x7d67c002, 0x0be40001, 0x97000002, 0x7d3a4002, 0x202c002c, 0xc421325e, 0x04280020, 0xcec1326c, + 0x26200010, 0x3e640010, 0x96000003, 0x96400002, 0xce81325e, 0xc4300028, 0xc434002e, 0x17780001, + 0x27740001, 0x07a811cf, 0x9b00feb8, 0xcf400010, 0xc414005e, 0x954009a7, 0x86800000, 0x80000168, + 0x80000aa7, 0x80000bfc, 0x800012e9, 0x80000168, 0x8c00120d, 0x7c40c001, 0xccc1c07c, 0xcc41c07d, + 0xcc41c08c, 0x7c410001, 0xcc41c079, 0xcd01c07e, 0x7c414001, 0x18f0012f, 0x18f40612, 0x18cc00c1, + 0x7f73400a, 0x7cf7400a, 0x39600004, 0x9a000002, 0xc0140004, 0x11600001, 0x18fc003e, 0x9740001c, + 0xcf400041, 0xc425c07f, 0x97c00003, 0x166c001f, 0x800011ee, 0x1a6c003e, 0x96c00006, 0x04200002, + 0x0a200001, 0x9a00ffff, 0xd8400013, 0x800011e8, 0xc428002c, 0x96800010, 0x26ac007f, 0xcec0001b, + 0xd8400021, 0x1ab00030, 0x1aac0fe8, 0xc434000f, 0x9b40ffff, 0x97000008, 0xcec0001b, 0xd8400021, + 0xc434000f, 0x9b40ffff, 0x80001205, 0x0a200001, 0x9a00ffff, 0xd8400013, 0xc425c07f, 0x166c001f, + 0x11600001, 0x9ac0fffa, 0x8c001232, 0x7c408001, 0x88000000, 0xd8000033, 0xc438000b, 0xc43c0009, + 0x27fc0001, 0x97c0fffe, 0xd8400013, 0xd841c07f, 0xc43dc07f, 0x1bfc0078, 0x7ffbc00c, 0x97c0fffd, + 0x90000000, 0xc03a2800, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04380040, + 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380060, 0xcf80001b, 0xd8400021, 0xc438000f, + 0x9b80ffff, 0x04380002, 0x0bb80001, 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, + 0x9bc0fffa, 0x90000000, 0xd8400013, 0xd801c07f, 0xd8400013, 0xc43dc07f, 0xcfc00078, 0xd8000034, + 0x90000000, 0xc03ae000, 0xcf81c200, 0xc03a0800, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, + 0xcc01c07e, 0x04380040, 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380002, 0x0bb80001, + 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, 0x9bc0fffa, 0x90000000, 0xc03ae000, + 0xcf81c200, 0xc03a4000, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04380002, + 0x0bb80001, 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, 0x9bc0fffa, 0x90000000, + 0xc40c0007, 0x30d00002, 0x99000052, 0xd8400029, 0xc424005e, 0x9640090f, 0x7c410001, 0xc428000e, + 0x1514001f, 0x19180038, 0x2aa80008, 0x99400030, 0x30dc0001, 0xce800013, 0x99c0000a, 0xc42d324e, + 0xc431324d, 0x52ec0020, 0x7ef2c01a, 0xc435324f, 0xc4293256, 0x1ab0c006, 0x52ec0008, 0x8000127f, + 0xc42d3258, 0xc4313257, 0x52ec0020, 0x7ef2c01a, 0xc4353259, 0xc429325a, 0x1ab0c012, 0x07740001, + 0x04240002, 0x26a0003f, 0x7e624004, 0x7f67800f, 0x97800002, 0x04340000, 0x53740002, 0x7ef6c011, + 0x1ab42010, 0x16a8000c, 0x26a80800, 0x2b740000, 0x7f73400a, 0x7f6b400a, 0xcf40001c, 0xd2c0001e, + 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4100011, 0x1514001f, 0x99400006, 0x9980000a, 0x8c0012e1, + 0xc40c0007, 0x04100000, 0x80001267, 0xd800002a, 0xc424005e, 0x964008d7, 0xd9800036, 0x80000c16, + 0xc42c001d, 0x95c00005, 0xc431325a, 0x1b300677, 0x11dc000c, 0x800012aa, 0xc4313256, 0x1b34060b, + 0x1b300077, 0x7f37000a, 0x13300017, 0x04340100, 0x26ec00ff, 0xc03a8002, 0x7ef6c00a, 0x7edec00a, + 0x7f3b000a, 0x7ef2c00a, 0xcec1325b, 0x80000c16, 0xc4140032, 0xc410001d, 0x29540008, 0xcd400013, + 0xc40d325b, 0x1858003f, 0x251000ff, 0x99800007, 0x7d0cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, + 0xcd01325d, 0x80000168, 0x18d0006c, 0x18d407f0, 0x9900000e, 0x04100002, 0xc4193256, 0xc41d324f, + 0x2598003f, 0x7d190004, 0x7d5d4001, 0x7d52000f, 0x9a000003, 0xcd41324f, 0x800012d8, 0x7d514002, + 0xcd41324f, 0x800012d8, 0xc4193259, 0xc41d325a, 0x7d958001, 0x7dd5c002, 0xcd813259, 0xcdc1325a, + 0xc411325d, 0x251001ef, 0xcd01325d, 0x1ccc001e, 0xccc1325b, 0xc40d325b, 0x94c00001, 0x7c408001, + 0x88000000, 0xc40c0021, 0xc4340028, 0x14f00010, 0xc4380030, 0xc43c0007, 0x9b000004, 0x9b40000c, + 0x9b80000f, 0x90000000, 0x17300001, 0x9b000005, 0xccc00037, 0x8c000190, 0xd8000032, 0x90000000, + 0xd8000028, 0xd800002b, 0x80000168, 0xd980003f, 0x97c00002, 0xd9c0003f, 0x80001082, 0xd9800040, + 0x97c00002, 0xd9c00040, 0x800010de, 0xc43c0007, 0x33f80003, 0x97800051, 0xcc80003b, 0x24b00008, + 0xc418000e, 0x1330000a, 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, + 0xc4353249, 0x1b74003e, 0x9b400002, 0xd840003d, 0x2b304000, 0xcf01326c, 0xc431326c, 0x97000001, + 0x7c434001, 0x1b4c00f8, 0x7c410001, 0x7c414001, 0x50700020, 0x04e81324, 0x18ac0024, 0x7c41c001, + 0x50600020, 0xcc400078, 0x30e40004, 0x9a400007, 0x7d71401a, 0x596401fc, 0x12640009, 0x1b74008d, + 0x7e76400a, 0x2a640000, 0xcec00008, 0x86800000, 0x8000016a, 0x8000016a, 0x8000016a, 0x8000016a, + 0x8000132c, 0x8000133b, 0x80001344, 0x8000016a, 0xc4340004, 0xd8400013, 0xd8400008, 0xc42530b5, + 0x1a68003a, 0x9a80fffe, 0x2024003a, 0xc418000e, 0x25980700, 0x11980014, 0x7d19000a, 0xcd0130b7, + 0xce4130b5, 0xcf400008, 0x80001190, 0xce40001c, 0xd140001e, 0xd8400021, 0xc428000f, 0x9a80ffff, + 0xc4240011, 0x7de6800f, 0x9a80ffea, 0x80001190, 0xce40001c, 0xd140001e, 0xd8400021, 0xc428000f, + 0x9a80ffff, 0xc8240011, 0x7de1c01a, 0x7de6800f, 0x9a80ffe0, 0x80001190, 0x8c00104f, 0x28182002, + 0xc430000d, 0xc4340035, 0xcd800013, 0xc8140023, 0xc4180081, 0x13300005, 0xc4240004, 0x11a00002, + 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x3e280008, + 0x7cb4800a, 0xc4300027, 0x042c0008, 0xd1400025, 0xcf000024, 0x20240030, 0x7ca48001, 0xcc800026, + 0x7c434001, 0x1b4c00f8, 0xcf400026, 0xcc400026, 0x28340000, 0xcf400013, 0x7c414001, 0x507c0020, + 0x30e40004, 0x9a400005, 0x7d7d401a, 0xd1400072, 0xc8140072, 0x557c0020, 0x28342002, 0xcf400013, + 0xcd400026, 0xcfc00026, 0xd4400026, 0xcc000026, 0x9a800005, 0x32280000, 0x9a800002, 0x9a000000, + 0x7c018001, 0xd8400027, 0xd8800013, 0x04380028, 0xcec0003a, 0xcf81a2a4, 0x80001037, 0xd8400029, + 0xc40c005e, 0x94c007eb, 0x7c40c001, 0x50500020, 0x7d0d001a, 0xd1000072, 0xc8100072, 0x591c01fc, + 0x11dc0009, 0x45140210, 0x595801fc, 0x11980009, 0x29dc0000, 0xcdc0001c, 0xd140001e, 0xd8400021, + 0xc418000f, 0x9980ffff, 0xc4200011, 0x1624001f, 0x96400069, 0xc40c000e, 0x28cc0008, 0xccc00013, + 0xce013249, 0x1a307fe8, 0xcf00000a, 0x23304076, 0xd1000001, 0xcf000001, 0xc41d3254, 0xc4253256, + 0x18cc00e8, 0x10cc0015, 0x4514020c, 0xd140001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4200011, + 0xce013248, 0x1a2001e8, 0x12200014, 0x2a204001, 0xce000013, 0x1a64003c, 0x1264001f, 0x11dc0009, + 0x15dc000b, 0x7dcdc00a, 0x7e5dc00a, 0xcdc00100, 0xd8800013, 0xd8400010, 0xd800002a, 0xd8400008, + 0xcf00000d, 0xcf00000a, 0x8c001427, 0x04340022, 0x07740001, 0x04300010, 0xdf430000, 0x7c434001, + 0x7c408001, 0xd4412e01, 0x0434001e, 0xdf430000, 0xd4400078, 0xdf030000, 0xd4412e40, 0xd8400013, + 0xcc41c030, 0xcc41c031, 0x248dfffe, 0xccc12e00, 0xd8800013, 0xcc812e00, 0x7c434001, 0x7c434001, + 0x8c00142b, 0xd8000010, 0xc40c000e, 0x28cc0008, 0xccc00013, 0x45140248, 0xd140001e, 0xd8400021, + 0xc418000f, 0x9980ffff, 0xc8200011, 0xce013257, 0x56200020, 0xce013258, 0x0434000c, 0xdb000024, + 0xd1400025, 0xd8000026, 0xd8000026, 0xd8400027, 0x45540008, 0xd140001e, 0xd8400021, 0xc418000f, + 0x9980ffff, 0xc8200011, 0xce013259, 0x56200020, 0xc0337fff, 0x7f220009, 0xce01325a, 0x55300020, + 0x7d01c001, 0x042c01d0, 0x8c000d61, 0x06ec0004, 0x7f01c001, 0x8c000d61, 0x041c0002, 0x042c01c8, + 0x8c000d61, 0xc4380012, 0x9b80ffff, 0xd800002a, 0x80000aa7, 0xd800002a, 0x7c408001, 0x88000000, + 0xd8400029, 0x7c40c001, 0x50500020, 0x8c001427, 0x7cd0c01a, 0xc4200007, 0xd0c00072, 0xc8240072, + 0xd240001e, 0x7c414001, 0x19682011, 0x5a6c01fc, 0x12ec0009, 0x7eeac00a, 0x2aec0000, 0xcec0001c, + 0xd8400021, 0xc430000f, 0x9b00ffff, 0xc4180011, 0x7c438001, 0x99800007, 0xdf830000, 0xcfa0000c, + 0x8c00142b, 0xd4400078, 0xd800002a, 0x80001b70, 0x8c00142b, 0xd800002a, 0x80001b70, 0xd8000012, + 0xc43c0008, 0x9bc0ffff, 0x90000000, 0xd8400012, 0xc43c0008, 0x97c0ffff, 0x90000000, 0xc4380007, + 0x7c40c001, 0x17b80001, 0x18d40038, 0x7c410001, 0x9b800004, 0xd8400029, 0xc414005e, 0x9540073d, + 0x18c80066, 0x7c414001, 0x30880001, 0x7c418001, 0x94800008, 0x8c00187c, 0xcf400013, 0xc42c0004, + 0xd8400008, 0xcd910000, 0xcec00008, 0x7d410001, 0x043c0000, 0x7c41c001, 0x7c420001, 0x04240001, + 0x06200001, 0x4220000c, 0x0a640001, 0xcc000078, 0x9a40fffe, 0x24e80007, 0x24ec0010, 0xd8400013, + 0x9ac00006, 0xc42c0004, 0xd8400008, 0xc5310000, 0xcec00008, 0x80001465, 0x51540020, 0x7d15001a, + 0xd1000072, 0xc82c0072, 0xd2c0001e, 0x18f02011, 0x5aec01fc, 0x12ec0009, 0x7ef2c00a, 0x2aec0000, + 0xcec0001c, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc4300011, 0x96800012, 0x12a80001, 0x0aa80001, + 0x06a8146a, 0x7f1f0009, 0x86800000, 0x7f1b400f, 0x80001478, 0x7f1b400e, 0x80001478, 0x7f1b400c, + 0x8000147a, 0x7f1b400d, 0x8000147a, 0x7f1b400f, 0x8000147a, 0x7f1b400e, 0x8000147a, 0x7f334002, + 0x97400014, 0x8000147b, 0x9b400012, 0x9b800005, 0x9bc0001f, 0x7e024001, 0x043c0001, 0x8000144a, + 0xc40c0032, 0xc438001d, 0x28cc0008, 0xccc00013, 0xc43d325b, 0x1bb81ff0, 0x7fbfc00a, 0xcfc1325b, + 0xc411325d, 0x251001ef, 0xcd01325d, 0x80001b70, 0x94800007, 0x8c00187c, 0xcf400013, 0xc42c0004, + 0xd8400008, 0xcd910000, 0xcec00008, 0x9b800003, 0xd800002a, 0x80001b70, 0xc40c0032, 0x28cc0008, + 0xccc00013, 0xc40d325b, 0x800012c2, 0xc40c000e, 0xc43c0007, 0xc438001d, 0x28cc0008, 0xccc00013, + 0x13f4000c, 0x9bc00006, 0xc43d3256, 0x1bf0060b, 0x1bfc0077, 0x7ff3c00a, 0x800014a9, 0xc43d325a, + 0x1bfc0677, 0x04300100, 0x1bb81ff0, 0x7f73400a, 0xc0328007, 0x7fb7800a, 0x13fc0017, 0x7ff3c00a, + 0x7ffbc00a, 0xcfc1325b, 0xc03a0002, 0xc4340004, 0xd8400013, 0xd8400008, 0xcf8130b5, 0xcf400008, + 0x80000c16, 0x043c0000, 0xc414000e, 0x29540008, 0xcd400013, 0xc4193246, 0xc41d3245, 0x51980020, + 0x7dd9c01a, 0x45dc0390, 0xc4313267, 0x04183000, 0xcd813267, 0x1b380057, 0x1b340213, 0x1b300199, + 0x7f7b400a, 0x7f73400a, 0xcf400024, 0xd1c00025, 0xcc800026, 0x7c420001, 0xce000026, 0x7c424001, + 0xce400026, 0x7c428001, 0xce800026, 0x7c42c001, 0xcec00026, 0x7c430001, 0xcf000026, 0x7c434001, + 0xcf400026, 0x7c438001, 0xcf800026, 0xd8400027, 0xcd400013, 0x04182000, 0xcd813267, 0xd840004f, + 0x1a0800fd, 0x109c000a, 0xc4193265, 0x7dd9c00a, 0xcdc13265, 0x2620ffff, 0xce080228, 0x9880000e, + 0xce480250, 0xce880258, 0xd8080230, 0xd8080238, 0xd8080240, 0xd8080248, 0xd8080268, 0xd8080270, + 0xd8080278, 0xd8080280, 0xd800004f, 0x97c0ec75, 0x90000000, 0x040c0000, 0x041c0010, 0x26180001, + 0x09dc0001, 0x16200001, 0x95800002, 0x04cc0001, 0x99c0fffb, 0xccc80230, 0xd8080238, 0xd8080240, + 0xd8080248, 0x040c0000, 0xce480250, 0xce880258, 0x52a80020, 0x7e6a401a, 0x041c0020, 0x66580001, + 0x09dc0001, 0x56640001, 0x95800002, 0x04cc0001, 0x99c0fffb, 0xccc80260, 0xd8080268, 0xd8080270, + 0xd8080278, 0xd8080280, 0x040c0000, 0xcec80288, 0xcf080290, 0xcec80298, 0xcf0802a0, 0x040c0000, + 0x041c0010, 0xcf4802a8, 0x27580001, 0x09dc0001, 0x17740001, 0x95800002, 0x04cc0001, 0x99c0fffb, + 0xccc802b0, 0xd80802b8, 0x178c000b, 0x27b8003f, 0x7cf8c001, 0xcf8802c0, 0xccc802c8, 0xcf8802d0, + 0xcf8802d8, 0xd800004f, 0x97c00002, 0x90000000, 0x7c408001, 0x88000000, 0xc40c000e, 0x28cc0008, + 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c418001, 0x25b8ffff, 0xc4930240, 0xc48f0238, 0x04cc0001, + 0x24cc000f, 0x7cd2800c, 0x9a80000b, 0xc5230309, 0x2620ffff, 0x7e3a400c, 0x9a400004, 0x05100001, + 0x2510000f, 0x80001539, 0xcd08034b, 0xd4400078, 0x80000168, 0xc48f0230, 0xc4930240, 0x98c00004, + 0xcd880353, 0x8c00163f, 0xc49b0353, 0xc4930238, 0xc48f0228, 0x05100001, 0x2510000f, 0x7cd14005, + 0x25540001, 0x99400004, 0x05100001, 0x2510000f, 0x8000154f, 0xc48f0230, 0x7c41c001, 0xcd080238, + 0xcd08034b, 0x08cc0001, 0x2598ffff, 0x3d200008, 0xccc80230, 0xcd900309, 0xd8100319, 0x04340801, + 0x2198003f, 0xcf400013, 0xcd910ce7, 0xc4190ce6, 0x7d918005, 0x25980001, 0x9580fffd, 0x7d918004, + 0xcd810ce6, 0x9a000003, 0xcdd1054f, 0x8000156e, 0x090c0008, 0xcdcd050e, 0x040c0000, 0x110c0014, + 0x28cc4001, 0xccc00013, 0xcc41230a, 0xcc41230b, 0xcc41230c, 0xcc41230d, 0xcc480329, 0xcc48032a, + 0xcc4802e0, 0xd8000055, 0xc48f02e0, 0x24d8003f, 0x09940001, 0x44100001, 0x9580002c, 0x95400005, + 0x09540001, 0x51100001, 0x69100001, 0x8000157f, 0x24cc003f, 0xc4970290, 0xc49b0288, 0x51540020, + 0x7d59401a, 0xc49b02a0, 0xc49f0298, 0x51980020, 0x7d9d801a, 0x041c0040, 0x04200000, 0x7dcdc002, + 0x7d924019, 0x7d26400c, 0x09dc0001, 0x9a400008, 0x51100001, 0x06200001, 0x99c0fffa, 0xc48f0230, + 0xc4930240, 0x8c00163f, 0x80001579, 0x7d010021, 0x7d914019, 0xc4930238, 0x55580020, 0xcd480298, + 0xcd8802a0, 0x10d40010, 0x12180016, 0xc51f0309, 0x7d95800a, 0x7d62000a, 0x7dd9c00a, 0xd8400013, + 0xcdd00309, 0xce113320, 0xc48f02e0, 0xc49b02b0, 0x18dc01e8, 0x7dd9400e, 0xc48f0230, 0xc4930240, + 0x95c0001d, 0x95400003, 0x8c00163f, 0x800015aa, 0xc48f0238, 0xc4a302b8, 0x12240004, 0x7e5e400a, + 0xc4ab02a8, 0x04100000, 0xce4c0319, 0x7d9d8002, 0x7ea14005, 0x25540001, 0x99400004, 0x06200001, + 0x2620000f, 0x800015bc, 0x09dc0001, 0x04240001, 0x7e624004, 0x06200001, 0x7d25000a, 0x2620000f, + 0x99c0fff4, 0xd8400013, 0xcd0d3330, 0xce0802b8, 0xcd8802b0, 0xc4ab02e0, 0x1aa807f0, 0xc48f02d0, + 0xc49702d8, 0xc49b02c8, 0xc49f02c0, 0x96800028, 0x7d4e000f, 0x9600000b, 0x7d964002, 0x7e6a000f, + 0x96000003, 0x7d694001, 0x800015e9, 0x7cde4002, 0x7e6a000f, 0x96000008, 0x7de94001, 0x800015e9, + 0x7cd64002, 0x7e6a000e, 0x96000003, 0x7d694001, 0x800015e9, 0xc48f0230, 0xc4930240, 0x8c00163f, + 0x800015cd, 0xc4930238, 0x7d698002, 0xcd4802d8, 0x129c0008, 0xc50f0319, 0x11a0000e, 0x11140001, + 0xc4340004, 0xd8400008, 0xd8400013, 0x7e1e000a, 0x1198000a, 0xcd953300, 0x7e0e000a, 0x12a8000a, + 0xce953301, 0xce100319, 0xcf400008, 0xc4b70280, 0xc4b30278, 0x7f73800a, 0x536c0020, 0x7ef2c01a, + 0x9780eb68, 0x8c001608, 0xd8080278, 0xd8080280, 0x7c408001, 0x88000000, 0x043c0003, 0x80001609, + 0x043c0001, 0x30b40000, 0x9b400011, 0xc4b70258, 0xc4b30250, 0x53780020, 0x7fb3801a, 0x7faf8019, + 0x04300020, 0x04280000, 0x67b40001, 0x0b300001, 0x57b80001, 0x97400002, 0x06a80001, 0x9b00fffb, + 0xc4bb0260, 0x7fab8001, 0xcf880260, 0x04300020, 0x04280000, 0x66f40001, 0x0b300001, 0x56ec0001, + 0x97400005, 0x8c001628, 0xc4353247, 0x7f7f4009, 0x9b40fffe, 0x06a80001, 0x9b00fff7, 0x90000000, + 0x269c0007, 0x11dc0008, 0x29dc0008, 0x26a00018, 0x12200003, 0x7de1c00a, 0x26a00060, 0x06200020, + 0x16200001, 0x7de1c00a, 0xcdc00013, 0x90000000, 0x269c0018, 0x26a00007, 0x26a40060, 0x11dc0006, + 0x12200006, 0x16640001, 0x29dc0008, 0x7de1c00a, 0x7de5c00a, 0xcdc00013, 0x90000000, 0xc4b70228, + 0x05100001, 0x04cc0001, 0x2510000f, 0xccc80230, 0x7f514005, 0x25540001, 0x99400004, 0x05100001, + 0x2510000f, 0x80001644, 0xc4b30248, 0xcd080240, 0x7f130005, 0x27300001, 0x9b000002, 0x8c001688, + 0x8c00120d, 0x8c001219, 0x8c001232, 0x04300001, 0x04340801, 0x7f130004, 0xcf400013, 0xcf01051e, + 0xc42d051f, 0x7ed2c005, 0x26ec0001, 0x96c0fffd, 0xcf01051f, 0xd8000055, 0xc5170309, 0x195c07f0, + 0x196007f6, 0x04340000, 0x95c00008, 0x09dc0001, 0x04340001, 0x95c00005, 0x09dc0001, 0x53740001, + 0x6b740001, 0x80001665, 0xc4a702a0, 0xc4ab0298, 0x52640020, 0x7e6a401a, 0x7f634014, 0x7e76401a, + 0xc4300004, 0xd8400008, 0xd8400013, 0x56680020, 0xd8113320, 0xce480298, 0xce8802a0, 0xc5170319, + 0xc4b702b0, 0x255c000f, 0x7f5f4001, 0xd8113330, 0xcf4802b0, 0x11340001, 0x195c07e8, 0x196007ee, + 0xd8353300, 0x7e1e4001, 0xd8353301, 0xce4802d0, 0xd8100309, 0xd8100319, 0xcf000008, 0x90000000, + 0xc4970258, 0xc48f0250, 0x51540020, 0x7cd4c01a, 0xc4af0280, 0xc4b30278, 0x52ec0020, 0x7ef2c01a, + 0x04140020, 0x04280000, 0x64d80001, 0x09540001, 0x54cc0001, 0x95800060, 0x8c001628, 0xc4193247, + 0x25980001, 0x9580005c, 0x7dc24001, 0xc41d3248, 0x25dc000f, 0x7dd2000c, 0x96000057, 0xc41d3255, + 0xc435324f, 0x7df5c00c, 0x99c00004, 0xc4193265, 0x25980040, 0x9580fffe, 0xc439325b, 0x1bb0003f, + 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, 0x9700000a, 0xc4393260, 0x1bb000e4, + 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x800016f1, 0xce400013, 0xc033ffff, + 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, 0x27b800ff, 0x9b80fffe, 0xd8c00033, + 0xc4300009, 0x27300008, 0x9700fffe, 0x1a7003e6, 0x27380003, 0x13b80004, 0x27300003, 0x13300003, + 0x7fb38001, 0x1a7000e8, 0x7fb38001, 0x13300001, 0x7fb38001, 0x07b80002, 0xd8400013, 0x1a700064, + 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x0b300003, 0x800016df, 0x17b00005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, 0x13300005, + 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, 0xd8c00034, 0xce400013, 0xc431325d, + 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffca, 0xd841325d, 0x2030007b, 0xcf01325b, + 0x800016f2, 0xd841325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0x06a80001, 0x9940ff9c, 0x8c001608, + 0xd8080278, 0xd8080280, 0x90000000, 0xd840004f, 0xc414000e, 0x29540008, 0xcd400013, 0xc43d3265, + 0x1bc800ea, 0xd80802e9, 0x7c40c001, 0x18fc0064, 0x9bc00042, 0xc4193246, 0xc41d3245, 0x51980020, + 0x7dd9801a, 0x45980400, 0xc4313267, 0x043c3000, 0xcfc13267, 0xc43d3267, 0x9bc00001, 0x1b380057, + 0x1b340213, 0x1b300199, 0x7f7b400a, 0x7f73400a, 0xcf400024, 0x14f4001d, 0xc4bf02e9, 0x9bc0001c, + 0x7c410001, 0x192807fa, 0xc4bf0258, 0xc4a70250, 0x53fc0020, 0x7e7e401a, 0x042c0000, 0x04300000, + 0x667c0001, 0x56640001, 0x06ec0001, 0x97c0fffd, 0x07300001, 0x0aec0001, 0x7eebc00c, 0x06ec0001, + 0x97c0fff8, 0x0b300001, 0x43300007, 0x53300002, 0x7db30011, 0xd3000025, 0xc03ec005, 0x2bfca200, + 0xcfc00026, 0xccc00026, 0xcd000026, 0x192807fa, 0xc01f007f, 0x7d1d0009, 0x2110007d, 0x8c001628, + 0x203c003f, 0xcfc13256, 0x8c0017f5, 0xcd013254, 0x18fc01e8, 0xcfc13248, 0x8c00185b, 0xd8413247, + 0x0b740001, 0x9b40ffd5, 0xd800004f, 0xc4bf02e9, 0x97c0ea24, 0x90000000, 0x14d4001d, 0xc4930260, + 0x7d52400e, 0xc49f0258, 0xc4a30250, 0x51dc0020, 0x7de1801a, 0x96400017, 0x7d534002, 0xc4af0270, + 0x7dae4005, 0x26640001, 0x32e0001f, 0x9a400006, 0x06ec0001, 0x96000002, 0x042c0000, 0xcec80270, + 0x8000174f, 0x0b740001, 0x8c00178a, 0x05100001, 0x9b40fff3, 0xc4af0280, 0xc4b30278, 0x52ec0020, + 0x7ef2c01a, 0x8c001608, 0xd8080278, 0xd8080280, 0xc4ab0268, 0x7daa4005, 0x26640001, 0x32a0001f, + 0x9a400005, 0x06a80001, 0x96000002, 0x24280000, 0x80001765, 0x7c410001, 0xc01f007f, 0x09540001, + 0x7d1d0009, 0x2110007d, 0x8c001628, 0xd8013256, 0x8c0017f2, 0xcd013254, 0xc4113248, 0x15100004, + 0x11100004, 0xc4b3034b, 0x7f13000a, 0xcf013248, 0xc4930260, 0x8c001855, 0x32a4001f, 0xd8413247, + 0xd800004f, 0x09100001, 0x06a80001, 0x96400002, 0x24280000, 0xcd080260, 0xce880268, 0x9940ffc0, + 0x7c408001, 0x88000000, 0x7ec28001, 0x8c001628, 0x32e0001f, 0xc4253247, 0x26640001, 0x9640005e, + 0xc4293265, 0xc4253255, 0xc431324f, 0x7e72400c, 0x26a80040, 0x9a400002, 0x9680fff7, 0xc429325b, + 0x1aa4003f, 0x96400049, 0x1aa400e8, 0x32680003, 0x9a800046, 0x32640002, 0x9640000a, 0xc4293260, + 0x1aa400e4, 0x32640004, 0x96400040, 0xc425325d, 0x26640010, 0x9a40fffe, 0x800017e2, 0xcdc00013, + 0xc027ffff, 0x2e6400ff, 0xc429325b, 0x7e6a4009, 0xce41325b, 0xc429325b, 0x26a800ff, 0x9a80fffe, + 0xd8c00033, 0xc4240009, 0x26640008, 0x9640fffe, 0x19e403e6, 0x26680003, 0x12a80004, 0x26640003, + 0x12640003, 0x7ea68001, 0x19e400e8, 0x7ea68001, 0x12640001, 0x7ea68001, 0x06a80002, 0xd8400013, + 0x19e40064, 0x32640002, 0x96400009, 0x16a40005, 0x06640003, 0xce412082, 0xcc01203f, 0xd8400013, + 0xcc01203f, 0x0a640003, 0x800017d0, 0x16a40005, 0xce412082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x12640005, 0x7ea64002, 0xc4292083, 0x7ea68005, 0x26a80001, 0x9a80ffdf, 0xd8c00034, 0xcdc00013, + 0xc425325d, 0x26640010, 0x9a40fffe, 0xc429325b, 0x26a400ff, 0x9a40ffca, 0xd841325d, 0x2024007b, + 0xce41325b, 0x800017e3, 0xd841325d, 0xc4a70280, 0xc4ab0278, 0x52640020, 0x7e6a401a, 0x04280001, + 0x7eae8014, 0x7e6a401a, 0x56680020, 0xce480278, 0xce880280, 0x06ec0001, 0x96000002, 0x042c0000, + 0xcec80270, 0x90000000, 0x7c438001, 0x7c420001, 0x800017fe, 0xc4bf02e9, 0x9bc00006, 0x7c438001, + 0x7c420001, 0xcf800026, 0xce000026, 0x800017fe, 0xc43b02eb, 0xc42302ec, 0xcf813245, 0xce013246, + 0x52200020, 0x7fa3801a, 0x47b8020c, 0x15e00008, 0x1220000a, 0x2a206032, 0x513c001e, 0x7e3e001a, + 0xc4bf02e9, 0x9bc00005, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0x8000180f, 0xcd400013, 0xc4313267, + 0x1b3c0077, 0x1b300199, 0x7ff3000a, 0x1330000a, 0x2b300032, 0x043c3000, 0xcfc13267, 0xc43d3267, + 0xd200000b, 0xc4200007, 0xd3800002, 0xcf000002, 0xd8000040, 0x96000002, 0xd8400040, 0xd8400018, + 0x043c2000, 0xcfc13267, 0xd8000018, 0xd8800010, 0xcdc00013, 0x7dc30001, 0xdc1e0000, 0x04380032, + 0xcf80000e, 0x8c001427, 0xcc413248, 0xc43d3269, 0x27fc000f, 0x33fc0003, 0x97c00011, 0x043c001f, + 0xdfc30000, 0xd4413249, 0x7c43c001, 0x7c43c001, 0x043c0024, 0x0bfc0021, 0xdfc30000, 0xd441326a, + 0x173c0008, 0x1b300303, 0x7f3f0001, 0x043c0001, 0x7ff3c004, 0xcfc13084, 0x80001842, 0x043c0024, + 0xdfc30000, 0xd4413249, 0x7c43c001, 0x23fc003f, 0xcfc1326d, 0x0bb80026, 0xdf830000, 0xd441326e, + 0x7c438001, 0x7c438001, 0xc4393265, 0x1fb8ffc6, 0xddc30000, 0xcf813265, 0x9a000003, 0xcdc0000c, + 0x80001852, 0xcdc0000d, 0xce000010, 0x8c00142b, 0x90000000, 0x7c41c001, 0x7c420001, 0xcdc13252, + 0xce013253, 0x8c001628, 0x80001878, 0xc49f02e9, 0x99c00018, 0x7c41c001, 0x7c420001, 0xcdc13252, + 0xce013253, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0x043c3000, 0xcfc13267, 0xc43d3267, 0x97c0ffff, + 0xcdc00026, 0xce000026, 0xd8400027, 0xc41c0012, 0x99c0ffff, 0xc43c000e, 0x2bfc0008, 0xcfc00013, + 0x043c2000, 0xcfc13267, 0x8c001628, 0x80001878, 0xc41f02ed, 0xc42302ee, 0xcdc13252, 0xce013253, + 0x04200001, 0x7e2a0004, 0xce013084, 0x90000000, 0x28340001, 0x313c0bcc, 0x9bc00010, 0x393c051f, + 0x9bc00004, 0x3d3c050e, 0x9bc0000c, 0x97c0000c, 0x393c0560, 0x9bc00004, 0x3d3c054f, 0x9bc00007, + 0x97c00007, 0x393c1538, 0x9bc00005, 0x3d3c1537, 0x9bc00002, 0x97c00002, 0x2b740800, 0x90000000, + 0xc40c000e, 0x28cc0008, 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c40c001, 0x18e8007c, 0x7c42c001, + 0x06a8189a, 0x86800000, 0x8000189e, 0x800018c5, 0x800018f2, 0x8000016a, 0x7c414001, 0x18d0007e, + 0x50580020, 0x09200001, 0x7d59401a, 0xd1400072, 0xc8140072, 0x09240002, 0x7c418001, 0x7c41c001, + 0x99000011, 0xc4340004, 0xd8400013, 0xd8400008, 0xc42130b5, 0x1a24002c, 0x9a40fffe, 0x2020002c, + 0xc418000d, 0x1198001c, 0x10cc0004, 0x14cc0004, 0x7cd8c00a, 0xccc130b7, 0xce0130b5, 0xcf400008, + 0x80000168, 0xd1400025, 0x5978073a, 0x2bb80002, 0xcf800024, 0xcd800026, 0xcdc00026, 0xd8400027, + 0x9600e8a8, 0xc4300012, 0x9b00ffff, 0x9640e8a5, 0x800018a9, 0x04140000, 0xc55b0309, 0x3d5c0010, + 0x05540001, 0x2598ffff, 0x09780001, 0x7dad800c, 0x99c0ffd2, 0x9580fff9, 0xc4970258, 0xc4930250, + 0x51540020, 0x7d15001a, 0x04140020, 0x04280000, 0x442c0000, 0x65180001, 0x09540001, 0x55100001, + 0x9580000b, 0x8c001628, 0xc41d3248, 0x04300001, 0x7f2b0014, 0x25dc000f, 0x7df9c00c, 0x95c00004, + 0x7ef2c01a, 0xd8c13260, 0xd901325d, 0x06a80001, 0x9940fff1, 0x04140020, 0x04280000, 0x66d80001, + 0x09540001, 0x56ec0001, 0x95800005, 0x8c001628, 0xc421325d, 0x26240007, 0x9a40fffe, 0x06a80001, + 0x9940fff7, 0x8000189e, 0x04140020, 0x04280000, 0x09540001, 0x8c001628, 0xc41d3254, 0xc023007f, + 0x19e4003e, 0x7de1c009, 0x7dee000c, 0x96400008, 0x96000007, 0xd8c13260, 0xd901325d, 0xc421325d, + 0x261c0007, 0x99c0fffe, 0x8000189e, 0x06a80001, 0x9940fff0, 0x8000189e, 0xc40c000e, 0x28cc0008, + 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c40c001, 0x18e00064, 0x06281911, 0x14f4001d, 0x24cc0003, + 0x86800000, 0x80001915, 0x800019af, 0x80001a2b, 0x8000016a, 0xcc48032b, 0xcc480333, 0xcc48033b, + 0xcc480343, 0x98800011, 0xc4213246, 0xc4253245, 0x52200020, 0x7e26401a, 0x46640400, 0xc4313267, + 0x04203000, 0xce013267, 0xc4213267, 0x9a000001, 0x1b3c0057, 0x1b200213, 0x1b300199, 0x7e3e000a, + 0x7e32000a, 0xce000024, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, 0xc4b30278, + 0x52ec0020, 0x7ef2c01a, 0x04180000, 0x04140020, 0x04280000, 0x7f438001, 0x8c001628, 0xc41d3247, + 0x25dc0001, 0x95c00068, 0xc4213254, 0x1a1c003e, 0x95c00065, 0xc01f007f, 0x7e1e0009, 0x97800062, + 0x0bb80001, 0x43bc0008, 0x7fcbc001, 0xc7df032b, 0x7e1fc00c, 0x97c0fffa, 0x043c0101, 0x94c00002, + 0x043c0102, 0xc439325b, 0x1bb0003f, 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, + 0x97000009, 0xc4393260, 0x1bb000e4, 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, + 0x80001994, 0x8c001628, 0xc033ffff, 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, + 0x27b800ff, 0x9b80fffe, 0xd8c00033, 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27380003, + 0x13b80004, 0x27300003, 0x13300003, 0x7fb38001, 0x19f000e8, 0x7fb38001, 0x13300001, 0x7fb38001, + 0x07b80002, 0xd8400013, 0x19f00064, 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, + 0xcc01203f, 0xd8400013, 0xcc01203f, 0x0b300003, 0x80001982, 0x17b00005, 0xcf012082, 0xcc01203f, + 0xd8400013, 0xcc01203f, 0x13300005, 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, + 0xd8c00034, 0xcdc00013, 0xc431325d, 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffcb, + 0xcfc1325d, 0x2030007b, 0xcf01325b, 0x80001995, 0xcfc1325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, + 0x98800009, 0x41bc0007, 0x53fc0002, 0x7e7fc011, 0xd3c00025, 0xd8000026, 0xd8400027, 0xc43c0012, + 0x9bc0ffff, 0x653c0001, 0x7dbd8001, 0x06a80001, 0x09540001, 0x55100001, 0x9940ff8f, 0xc43c000e, + 0x2bfc0008, 0xcfc00013, 0x043c2000, 0xcfc13267, 0xd8080278, 0xd8080280, 0x80000168, 0x7c410001, + 0x04140000, 0xc55b0309, 0x3d5c0010, 0x2598ffff, 0x05540001, 0x7d91800c, 0x95c00003, 0xd4400078, + 0x80000168, 0x9580fff8, 0x09780001, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, + 0xc4b30278, 0x52ec0020, 0x7ef2c01a, 0x04140020, 0x04280000, 0x65180001, 0x09540001, 0x55100001, + 0x9580005d, 0x8c001628, 0xc4253247, 0x26640001, 0x04200101, 0x96400058, 0x7dc24001, 0xc41d3248, + 0x25dc000f, 0x7df9c00c, 0x95c00053, 0x94c00002, 0x04200102, 0x7e41c001, 0xc425325b, 0x1a70003f, + 0x97000049, 0x1a7000e8, 0x33240003, 0x9a400046, 0x33300002, 0x9700000a, 0xc4253260, 0x1a7000e4, + 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x80001a21, 0xcdc00013, 0xc033ffff, + 0x2f3000ff, 0xc425325b, 0x7f270009, 0xcf01325b, 0xc425325b, 0x266400ff, 0x9a40fffe, 0xd8c00033, + 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27240003, 0x12640004, 0x27300003, 0x13300003, + 0x7e724001, 0x19f000e8, 0x7e724001, 0x13300001, 0x7e724001, 0x06640002, 0xd8400013, 0x19f00064, + 0x33300002, 0x97000009, 0x16700005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x0b300003, 0x80001a0f, 0x16700005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, 0x13300005, + 0x7e730002, 0xc4252083, 0x7e724005, 0x26640001, 0x9a40ffdf, 0xd8c00034, 0xcdc00013, 0xc431325d, + 0x27300010, 0x9b00fffe, 0xc425325b, 0x267000ff, 0x9b00ffca, 0xce01325d, 0x2030007b, 0xcf01325b, + 0x80001a22, 0xce01325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0x06a80001, 0x9940ff9f, 0xd4400078, + 0xd8080278, 0xd8080280, 0x80000168, 0x8c001a31, 0xd4400078, 0xd8080278, 0xd8080280, 0x7c408001, + 0x88000000, 0xc4213246, 0xc4253245, 0x52200020, 0x7e26401a, 0x46640400, 0xc4313267, 0x04203000, + 0xce013267, 0xc4213267, 0x9a000001, 0x1b180057, 0x1b200213, 0x1b300199, 0x7e1a000a, 0x7e32000a, + 0xce000024, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, 0xc4b30278, 0x52ec0020, + 0x7ef2c01a, 0x04140020, 0x04280000, 0x65180001, 0x95800060, 0x8c001628, 0xc4193247, 0x25980001, + 0x04200101, 0x94c00005, 0x30f00005, 0x04200005, 0x9b000002, 0x04200102, 0x95800056, 0xc439325b, + 0x1bb0003f, 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, 0x9700000a, 0xc4393260, + 0x1bb000e4, 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x80001aa2, 0xcdc00013, + 0xc033ffff, 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, 0x27b800ff, 0x9b80fffe, + 0xd8c00033, 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27380003, 0x13b80004, 0x27300003, + 0x13300003, 0x7fb38001, 0x19f000e8, 0x7fb38001, 0x13300001, 0x7fb38001, 0x07b80002, 0xd8400013, + 0x19f00064, 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, + 0xcc01203f, 0x0b300003, 0x80001a90, 0x17b00005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x13300005, 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, 0xd8c00034, 0xcdc00013, + 0xc431325d, 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffca, 0xce01325d, 0x2030007b, + 0xcf00325b, 0x80001aa3, 0xce01325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0xc49b02e9, 0x99800005, + 0xd2400025, 0x4664001c, 0xd8000026, 0xd8400027, 0x06a80001, 0x09540001, 0x55100001, 0x9940ff9c, + 0xc49b02e9, 0x99800008, 0xc430000e, 0x2b300008, 0xcf000013, 0x04302000, 0xcf013267, 0xc4313267, + 0x97000001, 0x90000000, 0x244c00ff, 0xcc4c0200, 0x7c408001, 0x88000000, 0xc44f0200, 0xc410000b, + 0xc414000c, 0x7d158010, 0x059cc000, 0xd8400013, 0xccdd0000, 0x7c408001, 0x88000000, 0xc40c0037, + 0x94c0ffff, 0xcc000049, 0xc40c003a, 0x94c0ffff, 0x7c40c001, 0x24d00001, 0x9500e69a, 0x18d0003b, + 0x18d40021, 0x99400006, 0xd840004a, 0xc40c003c, 0x94c0ffff, 0x14cc0001, 0x94c00028, 0xd8000033, + 0xc438000b, 0xc43c0009, 0x27fc0001, 0x97c0fffe, 0xd8400013, 0xd841c07f, 0xc43dc07f, 0x1bfc0078, + 0x7ffbc00c, 0x97c0fffd, 0x99000004, 0xc0120840, 0x282c0040, 0x80001ae8, 0xc0121841, 0x282c001a, + 0xcd01c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04200004, 0xcec0001b, 0xd8400021, + 0x0a200001, 0x9a00ffff, 0xc425c07f, 0x166c001f, 0x04200004, 0x9ac0fffb, 0xc434000f, 0x9b40ffff, + 0xd801c07f, 0xd8400013, 0xc425c07f, 0xce400078, 0xd8000034, 0x9940e66b, 0xd800004a, 0x7c408001, + 0x88000000, 0xc40c0036, 0x24d00001, 0x9900fffe, 0x18cc0021, 0xccc00047, 0xcc000046, 0xc40c0039, + 0x94c0ffff, 0xc40c003d, 0x98c0ffff, 0x7c40c001, 0x24d003ff, 0x18d47fea, 0x18d87ff4, 0xcd00004c, + 0xcd40004e, 0xcd80004d, 0xd8400013, 0xcd41c405, 0xc02a0001, 0x2aa80001, 0xce800013, 0xcd01c406, + 0xcc01c406, 0xcc01c406, 0xc40c0006, 0x98c0ffff, 0xc414000e, 0x29540008, 0x295c0001, 0xcd400013, + 0xd8c1325e, 0xcdc0001a, 0x11980002, 0x4110000c, 0xc0160800, 0x7d15000a, 0xc0164010, 0xd8400013, + 0xcd41c078, 0xcc01c080, 0xcc01c081, 0xcd81c082, 0xcc01c083, 0xcd01c084, 0xc40c0006, 0x98c0ffff, + 0xd8400048, 0xc40c003b, 0x94c0ffff, 0x80000c16, 0xd8400013, 0xd801c40a, 0xd901c40d, 0xd801c410, + 0xd801c40e, 0xd801c40f, 0xc40c0040, 0x04140001, 0x09540001, 0x9940ffff, 0x04140096, 0xd8400013, + 0xccc1c400, 0xc411c401, 0x9500fffa, 0xc424003e, 0x04d00001, 0x11100002, 0xcd01c40c, 0xc0180034, + 0xcd81c411, 0xd841c414, 0x0a540001, 0xcd41c412, 0x2468000f, 0xc419c416, 0x41980003, 0xc41c003f, + 0x7dda0001, 0x12200002, 0x10cc0002, 0xccc1c40c, 0xd901c411, 0xce41c412, 0xd8800013, 0xce292e40, + 0xcc412e01, 0xcc412e02, 0xcc412e03, 0xcc412e00, 0x80000aa7, 0xc43c0007, 0xdc120000, 0x31144000, + 0x95400005, 0xdc030000, 0xd800002a, 0xcc3c000c, 0x80001b70, 0x33f80003, 0xd4400078, 0x9780e601, + 0x188cfff0, 0x04e40002, 0x80001190, 0x7c408001, 0x88000000, 0xc424005e, 0x96400006, 0x90000000, + 0xc424005e, 0x96400003, 0x7c408001, 0x88000000, 0x80001b74, 0x80000168, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 7440 +}; + +static const PWR_DFY_Section pwr_virus_section4 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x54106500, + .dfy_data = { + 0x7e000200, 0x7e020204, 0xc00a0505, 0x00000000, 0xbf8c007f, 0xb8900904, 0xb8911a04, 0xb8920304, + 0xb8930b44, 0x921c0d0c, 0x921c1c13, 0x921d0c12, 0x811c1d1c, 0x811c111c, 0x921cff1c, 0x00000400, + 0x921dff10, 0x00000100, 0x81181d1c, 0x7e040218, 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 240 +}; + +static const PWR_DFY_Section pwr_virus_section5 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x54106900, + .dfy_data = { + 0x7e080200, 0x7e100204, 0xbefc00ff, 0x00010000, 0x24200087, 0x262200ff, 0x000001f0, 0x20222282, + 0x28182111, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 384 +}; + +static const PWR_DFY_Section pwr_virus_section6 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x54116f00, + .dfy_data = { + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4540fe8, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000041, 0x0000000c, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54116f00, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb454105e, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000000c0, 0x00000010, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54117300, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4541065, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000500, 0x0000001c, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54117700, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4541069, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000444, 0x0000008a, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54117b00, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 1024 +}; + +static const PWR_Command_Table pwr_virus_table_post[] = { { 0x00000000, mmCP_MEC_CNTL }, { 0x00000000, mmCP_MEC_CNTL }, { 0x00000004, mmSRBM_GFX_CNTL }, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index f039320fa794..61ee6281fbda 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -60,27 +60,44 @@ static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = { static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 = { 0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00}; -static int polaris10_setup_pwr_virus(struct pp_hwmgr *hwmgr) +static void execute_pwr_table(struct pp_hwmgr *hwmgr, const PWR_Command_Table *pvirus, int size) { int i; - int result = -EINVAL; uint32_t reg, data; - const PWR_Command_Table *pvirus = pwr_virus_table; - - for (i = 0; i < ARRAY_SIZE(pwr_virus_table); i++) { + for (i = 0; i < size; i++) { reg = pvirus->reg; data = pvirus->data; - if (reg != 0xffffffff) { + if (reg != 0xffffffff) cgs_write_register(hwmgr->device, reg, data); - } else { - result = 0; + else break; - } pvirus++; } +} - return result; +static void execute_pwr_dfy_table(struct pp_hwmgr *hwmgr, const PWR_DFY_Section *section) +{ + int i; + cgs_write_register(hwmgr->device, mmCP_DFY_CNTL, section->dfy_cntl); + cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_HI, section->dfy_addr_hi); + cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_LO, section->dfy_addr_lo); + for (i = 0; i < section->dfy_size; i++) + cgs_write_register(hwmgr->device, mmCP_DFY_DATA_0, section->dfy_data[i]); +} + +static int polaris10_setup_pwr_virus(struct pp_hwmgr *hwmgr) +{ + execute_pwr_table(hwmgr, pwr_virus_table_pre, ARRAY_SIZE(pwr_virus_table_pre)); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section1); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section2); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section3); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section4); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section5); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section6); + execute_pwr_table(hwmgr, pwr_virus_table_post, ARRAY_SIZE(pwr_virus_table_post)); + + return 0; } static int polaris10_perform_btc(struct pp_hwmgr *hwmgr) -- cgit v1.2.3 From 63cdc76e29a60d810263474ab072a587009d18b8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 12:30:23 +1000 Subject: amdgpu/pp: rewrite fiji pwr virus upload code. Along the same lines as rewriting the polaris code, this rewrites the fiji code, and reduces the driver size by ~40k. Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h | 10797 +++---------------- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 35 +- 2 files changed, 1284 insertions(+), 9548 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h b/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h index e202e567faf4..9d391f0eca94 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h +++ b/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h @@ -35,7 +35,16 @@ struct PWR_Command_Table }; typedef struct PWR_Command_Table PWR_Command_Table; -static const PWR_Command_Table PwrVirusTable[] = +struct PWR_DFY_Section { + uint32_t dfy_cntl; + uint32_t dfy_addr_hi, dfy_addr_lo; + uint32_t dfy_size; + uint32_t dfy_data[]; +}; + +typedef struct PWR_DFY_Section PWR_DFY_Section; + +static const PWR_Command_Table PwrVirusTable_pre[] = { { 0x100100b6, mmPCIE_INDEX }, { 0x00000000, mmPCIE_DATA }, @@ -457,9544 +466,1254 @@ static const PWR_Command_Table PwrVirusTable[] = { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x540fe800, mmCP_DFY_ADDR_LO }, - { 0x7e000200, mmCP_DFY_DATA_0 }, - { 0x7e020201, mmCP_DFY_DATA_0 }, - { 0x7e040204, mmCP_DFY_DATA_0 }, - { 0x7e060205, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080102, mmCP_DFY_DATA_0 }, - { 0x0a0a0701, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0x0a080500, mmCP_DFY_DATA_0 }, - { 0x0a0a0303, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000005, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54106f00, mmCP_DFY_DATA_0 }, - { 0x000400b4, mmCP_DFY_DATA_0 }, - { 0x00004000, mmCP_DFY_DATA_0 }, - { 0x00804fac, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x540fef00, mmCP_DFY_ADDR_LO }, - { 0xc0031502, mmCP_DFY_DATA_0 }, - { 0x00001e00, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x540ff000, mmCP_DFY_ADDR_LO }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x80000145, mmCP_DFY_DATA_0 }, - { 0x94800001, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0x95400001, mmCP_DFY_DATA_0 }, - { 0x95800001, mmCP_DFY_DATA_0 }, - { 0xdc810000, mmCP_DFY_DATA_0 }, - { 0xdcc10000, mmCP_DFY_DATA_0 }, - { 0xdd010000, mmCP_DFY_DATA_0 }, - { 0xdd410000, mmCP_DFY_DATA_0 }, - { 0xdd810000, mmCP_DFY_DATA_0 }, - { 0xc4080061, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8000003, mmCP_DFY_DATA_0 }, - { 0xc40c0001, mmCP_DFY_DATA_0 }, - { 0x24ccffff, mmCP_DFY_DATA_0 }, - { 0x3cd08000, mmCP_DFY_DATA_0 }, - { 0x9500fffd, mmCP_DFY_DATA_0 }, - { 0x1cd0ffcf, mmCP_DFY_DATA_0 }, - { 0x7d018001, mmCP_DFY_DATA_0 }, - { 0xc4140004, mmCP_DFY_DATA_0 }, - { 0x050c0019, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x84c00000, mmCP_DFY_DATA_0 }, - { 0x80000023, mmCP_DFY_DATA_0 }, - { 0x80000067, mmCP_DFY_DATA_0 }, - { 0x8000006a, mmCP_DFY_DATA_0 }, - { 0x8000006d, mmCP_DFY_DATA_0 }, - { 0x80000079, mmCP_DFY_DATA_0 }, - { 0x80000084, mmCP_DFY_DATA_0 }, - { 0x8000008f, mmCP_DFY_DATA_0 }, - { 0x80000099, mmCP_DFY_DATA_0 }, - { 0x800000a0, mmCP_DFY_DATA_0 }, - { 0x800000af, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0xc4080007, mmCP_DFY_DATA_0 }, - { 0x388c0001, mmCP_DFY_DATA_0 }, - { 0x08880002, mmCP_DFY_DATA_0 }, - { 0x04100003, mmCP_DFY_DATA_0 }, - { 0x94c00005, mmCP_DFY_DATA_0 }, - { 0x98800003, mmCP_DFY_DATA_0 }, - { 0x04100004, mmCP_DFY_DATA_0 }, - { 0x8000002d, mmCP_DFY_DATA_0 }, - { 0x04100005, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0000, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x28080001, mmCP_DFY_DATA_0 }, - { 0xcc000004, mmCP_DFY_DATA_0 }, - { 0x7d808001, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0xcc800005, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcd013278, mmCP_DFY_DATA_0 }, - { 0xc4113278, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0x24cc0700, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc4113255, mmCP_DFY_DATA_0 }, - { 0xcd01324f, mmCP_DFY_DATA_0 }, - { 0xc4113254, mmCP_DFY_DATA_0 }, - { 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0x10cc0014, mmCP_DFY_DATA_0 }, - { 0x1d10c017, mmCP_DFY_DATA_0 }, - { 0x7d0d000a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd0130b7, mmCP_DFY_DATA_0 }, - { 0x14cc0010, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0x8000005d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14d00011, mmCP_DFY_DATA_0 }, - { 0x9500fffe, mmCP_DFY_DATA_0 }, - { 0xdc030000, mmCP_DFY_DATA_0 }, - { 0xd800000c, mmCP_DFY_DATA_0 }, - { 0xd800000d, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01b10, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc00e0080, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0xc00e0800, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0x04100006, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0000, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x280c0008, mmCP_DFY_DATA_0 }, - { 0xccc00052, mmCP_DFY_DATA_0 }, - { 0xd8000021, mmCP_DFY_DATA_0 }, - { 0x28180039, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0x04100007, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0001, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x280c0010, mmCP_DFY_DATA_0 }, - { 0xccc00052, mmCP_DFY_DATA_0 }, - { 0x28180039, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0xd8400053, mmCP_DFY_DATA_0 }, - { 0x04100008, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0003, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x280c0020, mmCP_DFY_DATA_0 }, - { 0xccc00052, mmCP_DFY_DATA_0 }, - { 0x28180039, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0xdc030000, mmCP_DFY_DATA_0 }, - { 0xd8000069, mmCP_DFY_DATA_0 }, - { 0x28080001, mmCP_DFY_DATA_0 }, - { 0xc428000d, mmCP_DFY_DATA_0 }, - { 0x7ca88004, mmCP_DFY_DATA_0 }, - { 0xcc800079, mmCP_DFY_DATA_0 }, - { 0x04280001, mmCP_DFY_DATA_0 }, - { 0xcc00006f, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0x04100010, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0xccc00078, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0x28180080, mmCP_DFY_DATA_0 }, - { 0x80000034, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xcd013278, mmCP_DFY_DATA_0 }, - { 0xc4113278, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0xc4113254, mmCP_DFY_DATA_0 }, - { 0x1d10c017, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0xcd0130b7, mmCP_DFY_DATA_0 }, - { 0x8000013b, mmCP_DFY_DATA_0 }, - { 0x95c00001, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0x96400001, mmCP_DFY_DATA_0 }, - { 0x96800001, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x97400001, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x97c00001, mmCP_DFY_DATA_0 }, - { 0xdc810000, mmCP_DFY_DATA_0 }, - { 0xc40c000c, mmCP_DFY_DATA_0 }, - { 0xcd4c0380, mmCP_DFY_DATA_0 }, - { 0xcdcc0388, mmCP_DFY_DATA_0 }, - { 0x55dc0020, mmCP_DFY_DATA_0 }, - { 0xcdcc038c, mmCP_DFY_DATA_0 }, - { 0xce0c0390, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce0c0394, mmCP_DFY_DATA_0 }, - { 0xce4c0398, mmCP_DFY_DATA_0 }, - { 0x56640020, mmCP_DFY_DATA_0 }, - { 0xce4c039c, mmCP_DFY_DATA_0 }, - { 0xce8c03a0, mmCP_DFY_DATA_0 }, - { 0x56a80020, mmCP_DFY_DATA_0 }, - { 0xce8c03a4, mmCP_DFY_DATA_0 }, - { 0xcecc03a8, mmCP_DFY_DATA_0 }, - { 0x56ec0020, mmCP_DFY_DATA_0 }, - { 0xcecc03ac, mmCP_DFY_DATA_0 }, - { 0xcf0c03b0, mmCP_DFY_DATA_0 }, - { 0x57300020, mmCP_DFY_DATA_0 }, - { 0xcf0c03b4, mmCP_DFY_DATA_0 }, - { 0xcf4c03b8, mmCP_DFY_DATA_0 }, - { 0x57740020, mmCP_DFY_DATA_0 }, - { 0xcf4c03bc, mmCP_DFY_DATA_0 }, - { 0xcf8c03c0, mmCP_DFY_DATA_0 }, - { 0x57b80020, mmCP_DFY_DATA_0 }, - { 0xcf8c03c4, mmCP_DFY_DATA_0 }, - { 0xcfcc03c8, mmCP_DFY_DATA_0 }, - { 0x57fc0020, mmCP_DFY_DATA_0 }, - { 0xcfcc03cc, mmCP_DFY_DATA_0 }, - { 0xd9000033, mmCP_DFY_DATA_0 }, - { 0xc41c0009, mmCP_DFY_DATA_0 }, - { 0x25dc0010, mmCP_DFY_DATA_0 }, - { 0x95c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc41c000c, mmCP_DFY_DATA_0 }, - { 0x05dc002f, mmCP_DFY_DATA_0 }, - { 0xcdc12009, mmCP_DFY_DATA_0 }, - { 0xc41d200a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc012009, mmCP_DFY_DATA_0 }, - { 0xd9000034, mmCP_DFY_DATA_0 }, - { 0x25e01c00, mmCP_DFY_DATA_0 }, - { 0x12200013, mmCP_DFY_DATA_0 }, - { 0x25e40300, mmCP_DFY_DATA_0 }, - { 0x12640008, mmCP_DFY_DATA_0 }, - { 0x25e800c0, mmCP_DFY_DATA_0 }, - { 0x12a80002, mmCP_DFY_DATA_0 }, - { 0x25ec003f, mmCP_DFY_DATA_0 }, - { 0x7e25c00a, mmCP_DFY_DATA_0 }, - { 0x7eae400a, mmCP_DFY_DATA_0 }, - { 0x7de5c00a, mmCP_DFY_DATA_0 }, - { 0xddc10000, mmCP_DFY_DATA_0 }, - { 0xc02ee000, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0xc40c005f, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x24d000ff, mmCP_DFY_DATA_0 }, - { 0x31100006, mmCP_DFY_DATA_0 }, - { 0x9500007b, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xdc1c0000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1c200, mmCP_DFY_DATA_0 }, - { 0xc40c000c, mmCP_DFY_DATA_0 }, - { 0xc4df0388, mmCP_DFY_DATA_0 }, - { 0xc4d7038c, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d5dc01a, mmCP_DFY_DATA_0 }, - { 0xc4e30390, mmCP_DFY_DATA_0 }, - { 0xc4d70394, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d62001a, mmCP_DFY_DATA_0 }, - { 0xc4e70398, mmCP_DFY_DATA_0 }, - { 0xc4d7039c, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d66401a, mmCP_DFY_DATA_0 }, - { 0xc4eb03a0, mmCP_DFY_DATA_0 }, - { 0xc4d703a4, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d6a801a, mmCP_DFY_DATA_0 }, - { 0xc4ef03a8, mmCP_DFY_DATA_0 }, - { 0xc4d703ac, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d6ec01a, mmCP_DFY_DATA_0 }, - { 0xc4f303b0, mmCP_DFY_DATA_0 }, - { 0xc4d703b4, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d73001a, mmCP_DFY_DATA_0 }, - { 0xc4f703b8, mmCP_DFY_DATA_0 }, - { 0xc4d703bc, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d77401a, mmCP_DFY_DATA_0 }, - { 0xc4fb03c0, mmCP_DFY_DATA_0 }, - { 0xc4d703c4, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d7b801a, mmCP_DFY_DATA_0 }, - { 0xc4ff03c8, mmCP_DFY_DATA_0 }, - { 0xc4d703cc, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d7fc01a, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0xcc800013, mmCP_DFY_DATA_0 }, - { 0xc4d70380, mmCP_DFY_DATA_0 }, - { 0xc4080001, mmCP_DFY_DATA_0 }, - { 0x1c88001c, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0xc40c0083, mmCP_DFY_DATA_0 }, - { 0x94c00010, mmCP_DFY_DATA_0 }, - { 0xdc0e0000, mmCP_DFY_DATA_0 }, - { 0x94c0000e, mmCP_DFY_DATA_0 }, - { 0xc40c0082, mmCP_DFY_DATA_0 }, - { 0x24d00001, mmCP_DFY_DATA_0 }, - { 0x9900000b, mmCP_DFY_DATA_0 }, - { 0x18cc01e3, mmCP_DFY_DATA_0 }, - { 0x3cd00004, mmCP_DFY_DATA_0 }, - { 0x95000008, mmCP_DFY_DATA_0 }, - { 0xc40c0085, mmCP_DFY_DATA_0 }, - { 0x18cc006a, mmCP_DFY_DATA_0 }, - { 0x98c00005, mmCP_DFY_DATA_0 }, - { 0xc40c0082, mmCP_DFY_DATA_0 }, - { 0x18cc01e3, mmCP_DFY_DATA_0 }, - { 0x3cd00004, mmCP_DFY_DATA_0 }, - { 0x9900fffa, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0xcc800004, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4080001, mmCP_DFY_DATA_0 }, - { 0x1c88001c, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0xcc800004, mmCP_DFY_DATA_0 }, - { 0xdc080000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400051, mmCP_DFY_DATA_0 }, - { 0xc428000c, mmCP_DFY_DATA_0 }, - { 0x04180018, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a80001f, mmCP_DFY_DATA_0 }, - { 0x9a40001e, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4293265, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x1aac0027, mmCP_DFY_DATA_0 }, - { 0x2aa80080, mmCP_DFY_DATA_0 }, - { 0xce813265, mmCP_DFY_DATA_0 }, - { 0x9ac00017, mmCP_DFY_DATA_0 }, - { 0xd80002f1, mmCP_DFY_DATA_0 }, - { 0x04080002, mmCP_DFY_DATA_0 }, - { 0x08880001, mmCP_DFY_DATA_0 }, - { 0xd8080250, mmCP_DFY_DATA_0 }, - { 0xd8080258, mmCP_DFY_DATA_0 }, - { 0xd8080230, mmCP_DFY_DATA_0 }, - { 0xd8080238, mmCP_DFY_DATA_0 }, - { 0xd8080240, mmCP_DFY_DATA_0 }, - { 0xd8080248, mmCP_DFY_DATA_0 }, - { 0xd8080268, mmCP_DFY_DATA_0 }, - { 0xd8080270, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0xd8080228, mmCP_DFY_DATA_0 }, - { 0xd8000367, mmCP_DFY_DATA_0 }, - { 0x9880fff3, mmCP_DFY_DATA_0 }, - { 0x04080010, mmCP_DFY_DATA_0 }, - { 0x08880001, mmCP_DFY_DATA_0 }, - { 0xd80c0309, mmCP_DFY_DATA_0 }, - { 0xd80c0319, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x9880fffc, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc00e0100, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8000016e, mmCP_DFY_DATA_0 }, - { 0xc4180032, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x95800001, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d0003f, mmCP_DFY_DATA_0 }, - { 0x24d4001f, mmCP_DFY_DATA_0 }, - { 0x24d80001, mmCP_DFY_DATA_0 }, - { 0x155c0001, mmCP_DFY_DATA_0 }, - { 0x05e80180, mmCP_DFY_DATA_0 }, - { 0x9900000b, mmCP_DFY_DATA_0 }, - { 0x202c003d, mmCP_DFY_DATA_0 }, - { 0xcd800010, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0xc42d325b, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0x80000bfc, mmCP_DFY_DATA_0 }, - { 0x800012e9, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xc410001b, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0xd8000031, mmCP_DFY_DATA_0 }, - { 0x9900091a, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x24d000ff, mmCP_DFY_DATA_0 }, - { 0x05280196, mmCP_DFY_DATA_0 }, - { 0x18d4fe04, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x800001b4, mmCP_DFY_DATA_0 }, - { 0x8000032b, mmCP_DFY_DATA_0 }, - { 0x80000350, mmCP_DFY_DATA_0 }, - { 0x80000352, mmCP_DFY_DATA_0 }, - { 0x8000035f, mmCP_DFY_DATA_0 }, - { 0x80000701, mmCP_DFY_DATA_0 }, - { 0x8000047c, mmCP_DFY_DATA_0 }, - { 0x8000019f, mmCP_DFY_DATA_0 }, - { 0x80000800, mmCP_DFY_DATA_0 }, - { 0xc419325b, mmCP_DFY_DATA_0 }, - { 0x1d98001f, mmCP_DFY_DATA_0 }, - { 0xcd81325b, mmCP_DFY_DATA_0 }, - { 0x8c00003f, mmCP_DFY_DATA_0 }, - { 0xc4140004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04100002, mmCP_DFY_DATA_0 }, - { 0x8c000043, mmCP_DFY_DATA_0 }, - { 0x28cc0002, mmCP_DFY_DATA_0 }, - { 0xccc00050, mmCP_DFY_DATA_0 }, - { 0xc43c0044, mmCP_DFY_DATA_0 }, - { 0x27fc0003, mmCP_DFY_DATA_0 }, - { 0x9bc00002, mmCP_DFY_DATA_0 }, - { 0x97c00006, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0x8c000055, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcd400008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x7d40c001, mmCP_DFY_DATA_0 }, - { 0xd8400028, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xd9400036, mmCP_DFY_DATA_0 }, - { 0xc4193256, mmCP_DFY_DATA_0 }, - { 0xc41d3254, mmCP_DFY_DATA_0 }, - { 0x15540008, mmCP_DFY_DATA_0 }, - { 0xcd400009, mmCP_DFY_DATA_0 }, - { 0xcd40005b, mmCP_DFY_DATA_0 }, - { 0xcd40005e, mmCP_DFY_DATA_0 }, - { 0xcd40005d, mmCP_DFY_DATA_0 }, - { 0xd840006d, mmCP_DFY_DATA_0 }, - { 0xc421325a, mmCP_DFY_DATA_0 }, - { 0xc42d3249, mmCP_DFY_DATA_0 }, - { 0x11540015, mmCP_DFY_DATA_0 }, - { 0x19a4003c, mmCP_DFY_DATA_0 }, - { 0x1998003f, mmCP_DFY_DATA_0 }, - { 0x1af0007d, mmCP_DFY_DATA_0 }, - { 0x11dc000b, mmCP_DFY_DATA_0 }, - { 0x1264001f, mmCP_DFY_DATA_0 }, - { 0x15dc000d, mmCP_DFY_DATA_0 }, - { 0x7d65400a, mmCP_DFY_DATA_0 }, - { 0x13300018, mmCP_DFY_DATA_0 }, - { 0x1a38003f, mmCP_DFY_DATA_0 }, - { 0x7dd5c00a, mmCP_DFY_DATA_0 }, - { 0x7df1c00a, mmCP_DFY_DATA_0 }, - { 0xcd800045, mmCP_DFY_DATA_0 }, - { 0xcdc00100, mmCP_DFY_DATA_0 }, - { 0xc411326a, mmCP_DFY_DATA_0 }, - { 0xc415326b, mmCP_DFY_DATA_0 }, - { 0xc419326c, mmCP_DFY_DATA_0 }, - { 0xc41d326d, mmCP_DFY_DATA_0 }, - { 0xc425326e, mmCP_DFY_DATA_0 }, - { 0xc4293279, mmCP_DFY_DATA_0 }, - { 0xce800077, mmCP_DFY_DATA_0 }, - { 0xcd000056, mmCP_DFY_DATA_0 }, - { 0xcd400057, mmCP_DFY_DATA_0 }, - { 0xcd800058, mmCP_DFY_DATA_0 }, - { 0xcdc00059, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x259c8000, mmCP_DFY_DATA_0 }, - { 0x99c00004, mmCP_DFY_DATA_0 }, - { 0xce40005a, mmCP_DFY_DATA_0 }, - { 0x29988000, mmCP_DFY_DATA_0 }, - { 0xcd813265, mmCP_DFY_DATA_0 }, - { 0xc4113248, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0xcd000073, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0xc411326f, mmCP_DFY_DATA_0 }, - { 0x17300019, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x25140fff, mmCP_DFY_DATA_0 }, - { 0x95400007, mmCP_DFY_DATA_0 }, - { 0xd800003a, mmCP_DFY_DATA_0 }, - { 0x8c001b6d, mmCP_DFY_DATA_0 }, - { 0xc4153279, mmCP_DFY_DATA_0 }, - { 0xcd400077, mmCP_DFY_DATA_0 }, - { 0xcd00005f, mmCP_DFY_DATA_0 }, - { 0xd8000075, mmCP_DFY_DATA_0 }, - { 0x26f00001, mmCP_DFY_DATA_0 }, - { 0x15100010, mmCP_DFY_DATA_0 }, - { 0x7d190004, mmCP_DFY_DATA_0 }, - { 0xcd000035, mmCP_DFY_DATA_0 }, - { 0x97000035, mmCP_DFY_DATA_0 }, - { 0x1af07fe8, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcf00000d, mmCP_DFY_DATA_0 }, - { 0xcf00000a, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x04340022, mmCP_DFY_DATA_0 }, - { 0x07740001, mmCP_DFY_DATA_0 }, - { 0x04300010, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0xd4412e01, mmCP_DFY_DATA_0 }, - { 0x0434001e, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xdf030000, mmCP_DFY_DATA_0 }, - { 0xd4412e40, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc41c030, mmCP_DFY_DATA_0 }, - { 0xcc41c031, mmCP_DFY_DATA_0 }, - { 0xc43dc031, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x04343000, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0xcf413267, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7dd1c01a, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0x45dc0160, mmCP_DFY_DATA_0 }, - { 0xc810001f, mmCP_DFY_DATA_0 }, - { 0x1b4c0057, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x7f4f400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x55180020, mmCP_DFY_DATA_0 }, - { 0x2198003f, mmCP_DFY_DATA_0 }, - { 0xd1c00025, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xcd000026, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9bc00001, mmCP_DFY_DATA_0 }, - { 0x248dfffe, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xccc12e00, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x1af4007d, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0x33740003, mmCP_DFY_DATA_0 }, - { 0x26d80001, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x1ae8003e, mmCP_DFY_DATA_0 }, - { 0x9680000c, mmCP_DFY_DATA_0 }, - { 0xc4253277, mmCP_DFY_DATA_0 }, - { 0x26680001, mmCP_DFY_DATA_0 }, - { 0x96800009, mmCP_DFY_DATA_0 }, - { 0x2a640002, mmCP_DFY_DATA_0 }, - { 0xce413277, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc4253348, mmCP_DFY_DATA_0 }, - { 0xce413348, mmCP_DFY_DATA_0 }, - { 0xc4253348, mmCP_DFY_DATA_0 }, - { 0x96400001, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9b400003, mmCP_DFY_DATA_0 }, - { 0x958000d8, mmCP_DFY_DATA_0 }, - { 0x80000315, mmCP_DFY_DATA_0 }, - { 0xc4253277, mmCP_DFY_DATA_0 }, - { 0x04303000, mmCP_DFY_DATA_0 }, - { 0x26680001, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x96800041, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x1714000c, mmCP_DFY_DATA_0 }, - { 0x25540800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x459801b0, mmCP_DFY_DATA_0 }, - { 0x7d77400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x04240010, mmCP_DFY_DATA_0 }, - { 0x199c01e2, mmCP_DFY_DATA_0 }, - { 0x7e5e4002, mmCP_DFY_DATA_0 }, - { 0x3e5c0004, mmCP_DFY_DATA_0 }, - { 0x3e540002, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0x95c00006, mmCP_DFY_DATA_0 }, - { 0xc80c0011, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x54d00020, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0x80000282, mmCP_DFY_DATA_0 }, - { 0x95400015, mmCP_DFY_DATA_0 }, - { 0xc80c0011, mmCP_DFY_DATA_0 }, - { 0x0a640002, mmCP_DFY_DATA_0 }, - { 0x041c0001, mmCP_DFY_DATA_0 }, - { 0x45980008, mmCP_DFY_DATA_0 }, - { 0x54d00020, mmCP_DFY_DATA_0 }, - { 0x96400004, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0x041c0000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0x99c00003, mmCP_DFY_DATA_0 }, - { 0xc8180011, mmCP_DFY_DATA_0 }, - { 0x80000282, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0x80000282, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xc80c0011, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0xc8140011, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1334e, mmCP_DFY_DATA_0 }, - { 0xcd01334f, mmCP_DFY_DATA_0 }, - { 0xcd413350, mmCP_DFY_DATA_0 }, - { 0xcd813351, mmCP_DFY_DATA_0 }, - { 0xd881334d, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4193273, mmCP_DFY_DATA_0 }, - { 0xc41d3275, mmCP_DFY_DATA_0 }, - { 0xc40d3271, mmCP_DFY_DATA_0 }, - { 0xc4113270, mmCP_DFY_DATA_0 }, - { 0xc4153274, mmCP_DFY_DATA_0 }, - { 0x50cc0020, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0x7cdcc011, mmCP_DFY_DATA_0 }, - { 0x05900008, mmCP_DFY_DATA_0 }, - { 0xcd00006a, mmCP_DFY_DATA_0 }, - { 0xcdc0006b, mmCP_DFY_DATA_0 }, - { 0xc41d3272, mmCP_DFY_DATA_0 }, - { 0x7d594002, mmCP_DFY_DATA_0 }, - { 0x54d00020, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xccc12e23, mmCP_DFY_DATA_0 }, - { 0xcd012e24, mmCP_DFY_DATA_0 }, - { 0xcdc12e25, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x15540002, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x1b340057, mmCP_DFY_DATA_0 }, - { 0x1b280213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x45980198, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x7f2b000a, mmCP_DFY_DATA_0 }, - { 0x55e40020, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcd40000d, mmCP_DFY_DATA_0 }, - { 0xcd40000a, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x20cc003c, mmCP_DFY_DATA_0 }, - { 0xccc13249, mmCP_DFY_DATA_0 }, - { 0xc4113274, mmCP_DFY_DATA_0 }, - { 0xdd430000, mmCP_DFY_DATA_0 }, - { 0xc01e0001, mmCP_DFY_DATA_0 }, - { 0x29dc0002, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0xd8000036, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0x2d540002, mmCP_DFY_DATA_0 }, - { 0x95400022, mmCP_DFY_DATA_0 }, - { 0x078c0000, mmCP_DFY_DATA_0 }, - { 0x07d40000, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001239, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x04f80000, mmCP_DFY_DATA_0 }, - { 0x057c0000, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc414000d, mmCP_DFY_DATA_0 }, - { 0xc41c0019, mmCP_DFY_DATA_0 }, - { 0x7dd5c005, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0xd840007c, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0xd8400069, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c018a6, mmCP_DFY_DATA_0 }, - { 0xd4412e22, mmCP_DFY_DATA_0 }, - { 0xd800007c, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c018a2, mmCP_DFY_DATA_0 }, - { 0x95c00007, mmCP_DFY_DATA_0 }, - { 0xc40c0019, mmCP_DFY_DATA_0 }, - { 0x7cd4c005, mmCP_DFY_DATA_0 }, - { 0x24cc0001, mmCP_DFY_DATA_0 }, - { 0x94c00008, mmCP_DFY_DATA_0 }, - { 0x9680fffc, mmCP_DFY_DATA_0 }, - { 0x800002e3, mmCP_DFY_DATA_0 }, - { 0xc40c0057, mmCP_DFY_DATA_0 }, - { 0x7cd0c002, mmCP_DFY_DATA_0 }, - { 0x94c00003, mmCP_DFY_DATA_0 }, - { 0x9680fffd, mmCP_DFY_DATA_0 }, - { 0x800002e3, mmCP_DFY_DATA_0 }, - { 0xd8000069, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcd013273, mmCP_DFY_DATA_0 }, - { 0xcd013275, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc414005e, mmCP_DFY_DATA_0 }, - { 0x9540188f, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0xc013cfff, mmCP_DFY_DATA_0 }, - { 0x7cd0c009, mmCP_DFY_DATA_0 }, - { 0xccc13249, mmCP_DFY_DATA_0 }, - { 0x9680000b, mmCP_DFY_DATA_0 }, - { 0xc40c0077, mmCP_DFY_DATA_0 }, - { 0x38d00001, mmCP_DFY_DATA_0 }, - { 0x99000006, mmCP_DFY_DATA_0 }, - { 0x04cc0002, mmCP_DFY_DATA_0 }, - { 0xdcc30000, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01882, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd800000d, mmCP_DFY_DATA_0 }, - { 0x80000304, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0xd840002f, mmCP_DFY_DATA_0 }, - { 0xc41c0015, mmCP_DFY_DATA_0 }, - { 0x95c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400030, mmCP_DFY_DATA_0 }, - { 0xc41c0016, mmCP_DFY_DATA_0 }, - { 0x95c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8000030, mmCP_DFY_DATA_0 }, - { 0xc41c0016, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xd800002f, mmCP_DFY_DATA_0 }, - { 0xc41c0015, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x49980198, mmCP_DFY_DATA_0 }, - { 0x55e40020, mmCP_DFY_DATA_0 }, - { 0x459801a0, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x04302000, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x96800004, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0xd8000036, mmCP_DFY_DATA_0 }, - { 0x80000329, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcc812e00, mmCP_DFY_DATA_0 }, - { 0x04302000, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0xc4193256, mmCP_DFY_DATA_0 }, - { 0xc42d3249, mmCP_DFY_DATA_0 }, - { 0x16ec001f, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x1998003e, mmCP_DFY_DATA_0 }, - { 0xcec00031, mmCP_DFY_DATA_0 }, - { 0xd8000036, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0x97800004, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xce00000a, mmCP_DFY_DATA_0 }, - { 0x1a18003e, mmCP_DFY_DATA_0 }, - { 0xcd800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0x7d43c001, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4093249, mmCP_DFY_DATA_0 }, - { 0x1888003e, mmCP_DFY_DATA_0 }, - { 0x94800015, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0xc419324c, mmCP_DFY_DATA_0 }, - { 0x259c0001, mmCP_DFY_DATA_0 }, - { 0x1598001f, mmCP_DFY_DATA_0 }, - { 0x95c0000d, mmCP_DFY_DATA_0 }, - { 0x9580000c, mmCP_DFY_DATA_0 }, - { 0x99000003, mmCP_DFY_DATA_0 }, - { 0xd8400036, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14d80011, mmCP_DFY_DATA_0 }, - { 0x24dc00ff, mmCP_DFY_DATA_0 }, - { 0x31e00002, mmCP_DFY_DATA_0 }, - { 0x31dc0003, mmCP_DFY_DATA_0 }, - { 0x9580fff0, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0x99c00002, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0x94800004, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95801827, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8800036, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8c00036, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xc4180014, mmCP_DFY_DATA_0 }, - { 0x9580ffff, mmCP_DFY_DATA_0 }, - { 0xd840002f, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14dc0011, mmCP_DFY_DATA_0 }, - { 0x95c0fffe, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd800006d, mmCP_DFY_DATA_0 }, - { 0xc41d3246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51dc0020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0xd8400028, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc420000b, mmCP_DFY_DATA_0 }, - { 0x32200002, mmCP_DFY_DATA_0 }, - { 0x9a0000ad, mmCP_DFY_DATA_0 }, - { 0x04200032, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0xde030000, mmCP_DFY_DATA_0 }, - { 0xd8400033, mmCP_DFY_DATA_0 }, - { 0x04080000, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0002, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xc42c0015, mmCP_DFY_DATA_0 }, - { 0x96c0ffff, mmCP_DFY_DATA_0 }, - { 0xd800002e, mmCP_DFY_DATA_0 }, - { 0xc42d3249, mmCP_DFY_DATA_0 }, - { 0x1af4003e, mmCP_DFY_DATA_0 }, - { 0x9740004d, mmCP_DFY_DATA_0 }, - { 0xc428000d, mmCP_DFY_DATA_0 }, - { 0xc4080060, mmCP_DFY_DATA_0 }, - { 0x7ca88005, mmCP_DFY_DATA_0 }, - { 0x24880001, mmCP_DFY_DATA_0 }, - { 0x7f4b4009, mmCP_DFY_DATA_0 }, - { 0x97400046, mmCP_DFY_DATA_0 }, - { 0xc4313274, mmCP_DFY_DATA_0 }, - { 0xc4100057, mmCP_DFY_DATA_0 }, - { 0x7d33400c, mmCP_DFY_DATA_0 }, - { 0x97400009, mmCP_DFY_DATA_0 }, - { 0x28240100, mmCP_DFY_DATA_0 }, - { 0x7e6a4004, mmCP_DFY_DATA_0 }, - { 0xce400079, mmCP_DFY_DATA_0 }, - { 0x1eecffdd, mmCP_DFY_DATA_0 }, - { 0xcec13249, mmCP_DFY_DATA_0 }, - { 0xcf013273, mmCP_DFY_DATA_0 }, - { 0xcf013275, mmCP_DFY_DATA_0 }, - { 0x800003c3, mmCP_DFY_DATA_0 }, - { 0xc429326f, mmCP_DFY_DATA_0 }, - { 0x1aa80030, mmCP_DFY_DATA_0 }, - { 0x96800006, mmCP_DFY_DATA_0 }, - { 0x28240001, mmCP_DFY_DATA_0 }, - { 0xc428000d, mmCP_DFY_DATA_0 }, - { 0x06a80008, mmCP_DFY_DATA_0 }, - { 0x7e6a8004, mmCP_DFY_DATA_0 }, - { 0xce800035, mmCP_DFY_DATA_0 }, - { 0xc41d3272, mmCP_DFY_DATA_0 }, - { 0x25cc0001, mmCP_DFY_DATA_0 }, - { 0x10cc0004, mmCP_DFY_DATA_0 }, - { 0x19e80042, mmCP_DFY_DATA_0 }, - { 0x25dc0006, mmCP_DFY_DATA_0 }, - { 0x11dc0001, mmCP_DFY_DATA_0 }, - { 0x7e8e800a, mmCP_DFY_DATA_0 }, - { 0x7de9c00a, mmCP_DFY_DATA_0 }, - { 0xc40d3271, mmCP_DFY_DATA_0 }, - { 0xc4293270, mmCP_DFY_DATA_0 }, - { 0x50cc0020, mmCP_DFY_DATA_0 }, - { 0x7ce8c01a, mmCP_DFY_DATA_0 }, - { 0x7cd30011, mmCP_DFY_DATA_0 }, - { 0x11e80007, mmCP_DFY_DATA_0 }, - { 0x2aa80000, mmCP_DFY_DATA_0 }, - { 0xce80001c, mmCP_DFY_DATA_0 }, - { 0xd300001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x1b30003f, mmCP_DFY_DATA_0 }, - { 0x33300000, mmCP_DFY_DATA_0 }, - { 0xc4240059, mmCP_DFY_DATA_0 }, - { 0x1660001f, mmCP_DFY_DATA_0 }, - { 0x7e320009, mmCP_DFY_DATA_0 }, - { 0xc0328000, mmCP_DFY_DATA_0 }, - { 0x7e72400a, mmCP_DFY_DATA_0 }, - { 0x0430000c, mmCP_DFY_DATA_0 }, - { 0x9a000002, mmCP_DFY_DATA_0 }, - { 0x04300008, mmCP_DFY_DATA_0 }, - { 0xc02ac000, mmCP_DFY_DATA_0 }, - { 0x7d310002, mmCP_DFY_DATA_0 }, - { 0x17300002, mmCP_DFY_DATA_0 }, - { 0x2aa87600, mmCP_DFY_DATA_0 }, - { 0x7cd0c011, mmCP_DFY_DATA_0 }, - { 0xcdc00024, mmCP_DFY_DATA_0 }, - { 0xd0c00025, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0x04280222, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc4280058, mmCP_DFY_DATA_0 }, - { 0x22ec003d, mmCP_DFY_DATA_0 }, - { 0xcec13249, mmCP_DFY_DATA_0 }, - { 0xcd013273, mmCP_DFY_DATA_0 }, - { 0xce813275, mmCP_DFY_DATA_0 }, - { 0xd800007b, mmCP_DFY_DATA_0 }, - { 0xc8380018, mmCP_DFY_DATA_0 }, - { 0x57b00020, mmCP_DFY_DATA_0 }, - { 0x04343108, mmCP_DFY_DATA_0 }, - { 0xc429325d, mmCP_DFY_DATA_0 }, - { 0x040c3000, mmCP_DFY_DATA_0 }, - { 0x13740008, mmCP_DFY_DATA_0 }, - { 0x2374007e, mmCP_DFY_DATA_0 }, - { 0x32a80003, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x18ec0057, mmCP_DFY_DATA_0 }, - { 0x18e40213, mmCP_DFY_DATA_0 }, - { 0x18cc0199, mmCP_DFY_DATA_0 }, - { 0x7cecc00a, mmCP_DFY_DATA_0 }, - { 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { 0x94800003, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x800003e7, mmCP_DFY_DATA_0 }, - { 0x04200022, mmCP_DFY_DATA_0 }, - { 0xde030000, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x04200010, mmCP_DFY_DATA_0 }, - { 0xde030000, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0x45980104, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xcf800026, mmCP_DFY_DATA_0 }, - { 0xcf000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x49980104, mmCP_DFY_DATA_0 }, - { 0x9a80000a, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x45980168, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x800003f2, mmCP_DFY_DATA_0 }, - { 0x8c000448, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x040c2000, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0xd8400030, mmCP_DFY_DATA_0 }, - { 0xc42c0016, mmCP_DFY_DATA_0 }, - { 0x96c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8000030, mmCP_DFY_DATA_0 }, - { 0xc42c0016, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xd800002f, mmCP_DFY_DATA_0 }, - { 0xc42c0015, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400034, mmCP_DFY_DATA_0 }, - { 0xc4300025, mmCP_DFY_DATA_0 }, - { 0xc4340024, mmCP_DFY_DATA_0 }, - { 0xc4380081, mmCP_DFY_DATA_0 }, - { 0xcf813279, mmCP_DFY_DATA_0 }, - { 0xcf41326e, mmCP_DFY_DATA_0 }, - { 0xcf01326d, mmCP_DFY_DATA_0 }, - { 0x94c0000d, mmCP_DFY_DATA_0 }, - { 0x254c0700, mmCP_DFY_DATA_0 }, - { 0xc424001e, mmCP_DFY_DATA_0 }, - { 0x10cc0010, mmCP_DFY_DATA_0 }, - { 0x1a641fe8, mmCP_DFY_DATA_0 }, - { 0x28cc0726, mmCP_DFY_DATA_0 }, - { 0x2a640200, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1237b, mmCP_DFY_DATA_0 }, - { 0x2264003f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8813260, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0xc4240033, mmCP_DFY_DATA_0 }, - { 0xc4280034, mmCP_DFY_DATA_0 }, - { 0xd9000036, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x96400006, mmCP_DFY_DATA_0 }, - { 0xde430000, mmCP_DFY_DATA_0 }, - { 0xce40000c, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01755, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x9680000a, mmCP_DFY_DATA_0 }, - { 0xce80000a, mmCP_DFY_DATA_0 }, - { 0x06a80002, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xde830000, mmCP_DFY_DATA_0 }, - { 0xce80000d, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c0174c, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xc4393265, mmCP_DFY_DATA_0 }, - { 0x2bb80040, mmCP_DFY_DATA_0 }, - { 0xd8400032, mmCP_DFY_DATA_0 }, - { 0xcf813265, mmCP_DFY_DATA_0 }, - { 0xc4200012, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xc4100044, mmCP_DFY_DATA_0 }, - { 0x19180024, mmCP_DFY_DATA_0 }, - { 0xc8100072, mmCP_DFY_DATA_0 }, - { 0x551c003f, mmCP_DFY_DATA_0 }, - { 0x99c00003, mmCP_DFY_DATA_0 }, - { 0x95800010, mmCP_DFY_DATA_0 }, - { 0x8000043d, mmCP_DFY_DATA_0 }, - { 0xc00c8000, mmCP_DFY_DATA_0 }, - { 0xd840006c, mmCP_DFY_DATA_0 }, - { 0x28200000, mmCP_DFY_DATA_0 }, - { 0x8000043f, mmCP_DFY_DATA_0 }, - { 0xc00c4000, mmCP_DFY_DATA_0 }, - { 0x282000f0, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc4113255, mmCP_DFY_DATA_0 }, - { 0xcd01324f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xccc130b5, mmCP_DFY_DATA_0 }, - { 0xce000053, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x195c00e8, mmCP_DFY_DATA_0 }, - { 0xc4100004, mmCP_DFY_DATA_0 }, - { 0x2555fff0, mmCP_DFY_DATA_0 }, - { 0xc0360001, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0x29540001, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0x04280004, mmCP_DFY_DATA_0 }, - { 0xc420000b, mmCP_DFY_DATA_0 }, - { 0x32200002, mmCP_DFY_DATA_0 }, - { 0x9a000009, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0xc5e124dc, mmCP_DFY_DATA_0 }, - { 0x0aa80001, mmCP_DFY_DATA_0 }, - { 0x7ef6c001, mmCP_DFY_DATA_0 }, - { 0x7e624001, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0x9a80fff9, mmCP_DFY_DATA_0 }, - { 0xc02ee000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x2555fff0, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0xc42d3255, mmCP_DFY_DATA_0 }, - { 0xc4353259, mmCP_DFY_DATA_0 }, - { 0xd8013260, mmCP_DFY_DATA_0 }, - { 0x45980158, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x49980158, mmCP_DFY_DATA_0 }, - { 0x45980170, mmCP_DFY_DATA_0 }, - { 0xc4200012, mmCP_DFY_DATA_0 }, - { 0x16200010, mmCP_DFY_DATA_0 }, - { 0x9a00fffe, mmCP_DFY_DATA_0 }, - { 0xccc00024, mmCP_DFY_DATA_0 }, - { 0xd1800025, mmCP_DFY_DATA_0 }, - { 0xc429324f, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcd000008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x7d43c001, mmCP_DFY_DATA_0 }, - { 0x195400e8, mmCP_DFY_DATA_0 }, - { 0x1154000a, mmCP_DFY_DATA_0 }, - { 0x18dc00e8, mmCP_DFY_DATA_0 }, - { 0x05e80488, mmCP_DFY_DATA_0 }, - { 0x18d0006c, mmCP_DFY_DATA_0 }, - { 0x18f807f0, mmCP_DFY_DATA_0 }, - { 0x18e40077, mmCP_DFY_DATA_0 }, - { 0x18ec0199, mmCP_DFY_DATA_0 }, - { 0x7e6e400a, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000048e, mmCP_DFY_DATA_0 }, - { 0x80000494, mmCP_DFY_DATA_0 }, - { 0x800004de, mmCP_DFY_DATA_0 }, - { 0x80000685, mmCP_DFY_DATA_0 }, - { 0x80000686, mmCP_DFY_DATA_0 }, - { 0x800006ac, mmCP_DFY_DATA_0 }, - { 0x1ccc001f, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4293254, mmCP_DFY_DATA_0 }, - { 0x1264000a, mmCP_DFY_DATA_0 }, - { 0xc4300004, mmCP_DFY_DATA_0 }, - { 0x7d79400a, mmCP_DFY_DATA_0 }, - { 0x7e7a400a, mmCP_DFY_DATA_0 }, - { 0x52a8001e, mmCP_DFY_DATA_0 }, - { 0x15180001, mmCP_DFY_DATA_0 }, - { 0x7d69401a, mmCP_DFY_DATA_0 }, - { 0x202c007d, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x95000008, mmCP_DFY_DATA_0 }, - { 0x95800028, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x1aec0028, mmCP_DFY_DATA_0 }, - { 0xc40d325c, mmCP_DFY_DATA_0 }, - { 0x800004cc, mmCP_DFY_DATA_0 }, - { 0xc42d3256, mmCP_DFY_DATA_0 }, - { 0xc419324e, mmCP_DFY_DATA_0 }, - { 0x26e8003f, mmCP_DFY_DATA_0 }, - { 0x1aec003e, mmCP_DFY_DATA_0 }, - { 0x12f4000e, mmCP_DFY_DATA_0 }, - { 0xc41d324d, mmCP_DFY_DATA_0 }, - { 0xc40d324f, mmCP_DFY_DATA_0 }, - { 0x7d75401a, mmCP_DFY_DATA_0 }, - { 0x04100002, mmCP_DFY_DATA_0 }, - { 0x7d290004, mmCP_DFY_DATA_0 }, - { 0x7f8f4001, mmCP_DFY_DATA_0 }, - { 0x7f52800f, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x50e00002, mmCP_DFY_DATA_0 }, - { 0x51980008, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x800004d1, mmCP_DFY_DATA_0 }, - { 0x7d0dc002, mmCP_DFY_DATA_0 }, - { 0x6665fc00, mmCP_DFY_DATA_0 }, - { 0x7e5e401a, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x7da1c011, mmCP_DFY_DATA_0 }, - { 0xd140000b, mmCP_DFY_DATA_0 }, - { 0xd1c00002, mmCP_DFY_DATA_0 }, - { 0x2a644000, mmCP_DFY_DATA_0 }, - { 0xce400002, mmCP_DFY_DATA_0 }, - { 0x7f534002, mmCP_DFY_DATA_0 }, - { 0x6665fc00, mmCP_DFY_DATA_0 }, - { 0x7e76401a, mmCP_DFY_DATA_0 }, - { 0xd1800002, mmCP_DFY_DATA_0 }, - { 0xce400002, mmCP_DFY_DATA_0 }, - { 0x800004d7, mmCP_DFY_DATA_0 }, - { 0xc42d325a, mmCP_DFY_DATA_0 }, - { 0xc4193258, mmCP_DFY_DATA_0 }, - { 0x1aec003e, mmCP_DFY_DATA_0 }, - { 0xc41d3257, mmCP_DFY_DATA_0 }, - { 0xc4213259, mmCP_DFY_DATA_0 }, - { 0x12f4000e, mmCP_DFY_DATA_0 }, - { 0x7d75401a, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x52200002, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x7da1c011, mmCP_DFY_DATA_0 }, - { 0xd140000b, mmCP_DFY_DATA_0 }, - { 0xd1c00002, mmCP_DFY_DATA_0 }, - { 0x2a644000, mmCP_DFY_DATA_0 }, - { 0xce400002, mmCP_DFY_DATA_0 }, - { 0x202c003d, mmCP_DFY_DATA_0 }, - { 0xcf000008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0xc42d325b, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4193260, mmCP_DFY_DATA_0 }, - { 0x259c0007, mmCP_DFY_DATA_0 }, - { 0x15980004, mmCP_DFY_DATA_0 }, - { 0x05e804e3, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x800004e7, mmCP_DFY_DATA_0 }, - { 0x800004f0, mmCP_DFY_DATA_0 }, - { 0x80000505, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc435325d, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0x277401ef, mmCP_DFY_DATA_0 }, - { 0xcf41325d, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0x9640fff4, mmCP_DFY_DATA_0 }, - { 0x17e00008, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xd84131db, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xcd800009, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc42d325b, mmCP_DFY_DATA_0 }, - { 0x1b301ff8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0x26edf000, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0xd8413260, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x05a80507, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000050c, mmCP_DFY_DATA_0 }, - { 0x80000528, mmCP_DFY_DATA_0 }, - { 0x8000057d, mmCP_DFY_DATA_0 }, - { 0x800005c2, mmCP_DFY_DATA_0 }, - { 0x800005f3, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9a400012, mmCP_DFY_DATA_0 }, - { 0x1bd400e8, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xcd40005e, mmCP_DFY_DATA_0 }, - { 0xc41c004d, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x99c0000c, mmCP_DFY_DATA_0 }, - { 0xc4100019, mmCP_DFY_DATA_0 }, - { 0x7d150005, mmCP_DFY_DATA_0 }, - { 0x25100001, mmCP_DFY_DATA_0 }, - { 0x99000008, mmCP_DFY_DATA_0 }, - { 0x8c00063b, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0x2511fffd, mmCP_DFY_DATA_0 }, - { 0xcd013277, mmCP_DFY_DATA_0 }, - { 0xd801326f, mmCP_DFY_DATA_0 }, - { 0x80000624, mmCP_DFY_DATA_0 }, - { 0x04240012, mmCP_DFY_DATA_0 }, - { 0x1be00fe4, mmCP_DFY_DATA_0 }, - { 0xce413260, mmCP_DFY_DATA_0 }, - { 0xce000066, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400068, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9a400013, mmCP_DFY_DATA_0 }, - { 0x1bd400e8, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xcd40005e, mmCP_DFY_DATA_0 }, - { 0xc41c004d, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x99c0000d, mmCP_DFY_DATA_0 }, - { 0xc4100019, mmCP_DFY_DATA_0 }, - { 0x7d150005, mmCP_DFY_DATA_0 }, - { 0x25100001, mmCP_DFY_DATA_0 }, - { 0x99000009, mmCP_DFY_DATA_0 }, - { 0xd8400067, mmCP_DFY_DATA_0 }, - { 0x8c00063b, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0x2511fffd, mmCP_DFY_DATA_0 }, - { 0xcd013277, mmCP_DFY_DATA_0 }, - { 0xd801326f, mmCP_DFY_DATA_0 }, - { 0x80000624, mmCP_DFY_DATA_0 }, - { 0x1bd400e8, mmCP_DFY_DATA_0 }, - { 0xc42c0060, mmCP_DFY_DATA_0 }, - { 0x7ed6c005, mmCP_DFY_DATA_0 }, - { 0x26ec0001, mmCP_DFY_DATA_0 }, - { 0xc4113271, mmCP_DFY_DATA_0 }, - { 0xc4153270, mmCP_DFY_DATA_0 }, - { 0xc4193272, mmCP_DFY_DATA_0 }, - { 0xc41d3273, mmCP_DFY_DATA_0 }, - { 0x04280022, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d51401a, mmCP_DFY_DATA_0 }, - { 0xc4113274, mmCP_DFY_DATA_0 }, - { 0xc4213275, mmCP_DFY_DATA_0 }, - { 0xc4253276, mmCP_DFY_DATA_0 }, - { 0xc4313248, mmCP_DFY_DATA_0 }, - { 0xd1400061, mmCP_DFY_DATA_0 }, - { 0x2730000f, mmCP_DFY_DATA_0 }, - { 0x13300010, mmCP_DFY_DATA_0 }, - { 0x7db1800a, mmCP_DFY_DATA_0 }, - { 0xcd800060, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0x05dc0008, mmCP_DFY_DATA_0 }, - { 0xcdc00062, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xcd000063, mmCP_DFY_DATA_0 }, - { 0xce000064, mmCP_DFY_DATA_0 }, - { 0xce400065, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0xce813260, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc820001f, mmCP_DFY_DATA_0 }, - { 0x1b700057, mmCP_DFY_DATA_0 }, - { 0x1b680213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x46ec0188, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0x17e00008, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x26e01000, mmCP_DFY_DATA_0 }, - { 0x9a00fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd9c131fc, mmCP_DFY_DATA_0 }, - { 0xcd800009, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0x29dc0001, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0x191807e4, mmCP_DFY_DATA_0 }, - { 0x192007ec, mmCP_DFY_DATA_0 }, - { 0x95400004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x9580000e, mmCP_DFY_DATA_0 }, - { 0x09980001, mmCP_DFY_DATA_0 }, - { 0x041c0001, mmCP_DFY_DATA_0 }, - { 0x95800005, mmCP_DFY_DATA_0 }, - { 0x09980001, mmCP_DFY_DATA_0 }, - { 0x51dc0001, mmCP_DFY_DATA_0 }, - { 0x69dc0001, mmCP_DFY_DATA_0 }, - { 0x9980fffd, mmCP_DFY_DATA_0 }, - { 0x7de20014, mmCP_DFY_DATA_0 }, - { 0x561c0020, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xce013344, mmCP_DFY_DATA_0 }, - { 0xcdc13345, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x95400022, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425334d, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9640fffe, mmCP_DFY_DATA_0 }, - { 0xc419334e, mmCP_DFY_DATA_0 }, - { 0xc41d334f, mmCP_DFY_DATA_0 }, - { 0xc4213350, mmCP_DFY_DATA_0 }, - { 0xc4253351, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x1b680057, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x46ec01b0, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0x04280032, mmCP_DFY_DATA_0 }, - { 0xce813260, mmCP_DFY_DATA_0 }, - { 0xd8800068, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x2010007d, mmCP_DFY_DATA_0 }, - { 0xcd01325b, mmCP_DFY_DATA_0 }, - { 0xc411325b, mmCP_DFY_DATA_0 }, - { 0x1910003e, mmCP_DFY_DATA_0 }, - { 0x9500fffe, mmCP_DFY_DATA_0 }, - { 0x04100040, mmCP_DFY_DATA_0 }, - { 0xcd00001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc410000f, mmCP_DFY_DATA_0 }, - { 0x9900ffff, mmCP_DFY_DATA_0 }, - { 0x04100060, mmCP_DFY_DATA_0 }, - { 0xcd00001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc410000f, mmCP_DFY_DATA_0 }, - { 0x9900ffff, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x2010003d, mmCP_DFY_DATA_0 }, - { 0xcd01325b, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0x191807e4, mmCP_DFY_DATA_0 }, - { 0x9540000b, mmCP_DFY_DATA_0 }, - { 0x2511fffd, mmCP_DFY_DATA_0 }, - { 0xcd013277, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x95800005, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8013344, mmCP_DFY_DATA_0 }, - { 0xd8013345, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4180050, mmCP_DFY_DATA_0 }, - { 0xc41c0052, mmCP_DFY_DATA_0 }, - { 0x04280042, mmCP_DFY_DATA_0 }, - { 0xcd813273, mmCP_DFY_DATA_0 }, - { 0xcdc13275, mmCP_DFY_DATA_0 }, - { 0xce813260, mmCP_DFY_DATA_0 }, - { 0xd9000068, mmCP_DFY_DATA_0 }, - { 0xd8400067, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x07d40000, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c00124f, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x057c0000, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x1b680057, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0xc820001f, mmCP_DFY_DATA_0 }, - { 0x46ec0190, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc4153249, mmCP_DFY_DATA_0 }, - { 0x2154003d, mmCP_DFY_DATA_0 }, - { 0xc41c0019, mmCP_DFY_DATA_0 }, - { 0x1bd800e8, mmCP_DFY_DATA_0 }, - { 0x7dd9c005, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xcd80005e, mmCP_DFY_DATA_0 }, - { 0xc420004d, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x11dc0010, mmCP_DFY_DATA_0 }, - { 0x7e1e000a, mmCP_DFY_DATA_0 }, - { 0xcd413249, mmCP_DFY_DATA_0 }, - { 0xce01326f, mmCP_DFY_DATA_0 }, - { 0x28340001, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7f598004, mmCP_DFY_DATA_0 }, - { 0xcd800035, mmCP_DFY_DATA_0 }, - { 0x1be800e8, mmCP_DFY_DATA_0 }, - { 0xc42c004a, mmCP_DFY_DATA_0 }, - { 0xce80005e, mmCP_DFY_DATA_0 }, - { 0xd801327a, mmCP_DFY_DATA_0 }, - { 0xd800005f, mmCP_DFY_DATA_0 }, - { 0xd8000075, mmCP_DFY_DATA_0 }, - { 0xd800007f, mmCP_DFY_DATA_0 }, - { 0xc424004c, mmCP_DFY_DATA_0 }, - { 0xce41326e, mmCP_DFY_DATA_0 }, - { 0xcec0005e, mmCP_DFY_DATA_0 }, - { 0x28240100, mmCP_DFY_DATA_0 }, - { 0x7e6a4004, mmCP_DFY_DATA_0 }, - { 0xce400079, mmCP_DFY_DATA_0 }, - { 0xc435325d, mmCP_DFY_DATA_0 }, - { 0x277401ef, mmCP_DFY_DATA_0 }, - { 0x04240020, mmCP_DFY_DATA_0 }, - { 0xce41325e, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xd8013260, mmCP_DFY_DATA_0 }, - { 0xcf41325d, mmCP_DFY_DATA_0 }, - { 0xda000068, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4113277, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0x29dc0001, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0x9540002d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x042c3000, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3246, mmCP_DFY_DATA_0 }, - { 0xc4313245, mmCP_DFY_DATA_0 }, - { 0xc4353267, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425334d, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9640fffe, mmCP_DFY_DATA_0 }, - { 0xc419334e, mmCP_DFY_DATA_0 }, - { 0xc41d334f, mmCP_DFY_DATA_0 }, - { 0xc4213350, mmCP_DFY_DATA_0 }, - { 0xc4253351, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x1b680057, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x1b700213, mmCP_DFY_DATA_0 }, - { 0x1b740199, mmCP_DFY_DATA_0 }, - { 0x46ec01b0, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x042c2000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcec13267, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x96c00001, mmCP_DFY_DATA_0 }, - { 0xc41c000b, mmCP_DFY_DATA_0 }, - { 0xc420000c, mmCP_DFY_DATA_0 }, - { 0x11dc0002, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdc1334a, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc430000b, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0x9b000010, mmCP_DFY_DATA_0 }, - { 0x1be000e8, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0xc0360001, mmCP_DFY_DATA_0 }, - { 0x04280004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0xc63124dc, mmCP_DFY_DATA_0 }, - { 0x0aa80001, mmCP_DFY_DATA_0 }, - { 0x7ef6c001, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x9a80fff9, mmCP_DFY_DATA_0 }, - { 0xc02ee000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcec1c200, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4253260, mmCP_DFY_DATA_0 }, - { 0x7fc14001, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x98c00005, mmCP_DFY_DATA_0 }, - { 0x194c1c03, mmCP_DFY_DATA_0 }, - { 0xccc0003b, mmCP_DFY_DATA_0 }, - { 0xc40c002d, mmCP_DFY_DATA_0 }, - { 0x80000697, mmCP_DFY_DATA_0 }, - { 0xc420004a, mmCP_DFY_DATA_0 }, - { 0x194c00e8, mmCP_DFY_DATA_0 }, - { 0xccc0005e, mmCP_DFY_DATA_0 }, - { 0xc40c004c, mmCP_DFY_DATA_0 }, - { 0xc431326d, mmCP_DFY_DATA_0 }, - { 0x27301fff, mmCP_DFY_DATA_0 }, - { 0xce00005e, mmCP_DFY_DATA_0 }, - { 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c00008, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0x1b301ff8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x25100007, mmCP_DFY_DATA_0 }, - { 0x31100005, mmCP_DFY_DATA_0 }, - { 0x9900008e, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x8000075e, mmCP_DFY_DATA_0 }, - { 0x202c007d, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0xc4293265, mmCP_DFY_DATA_0 }, - { 0xc4353254, mmCP_DFY_DATA_0 }, - { 0x26a9feff, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x1374000b, mmCP_DFY_DATA_0 }, - { 0xc40c000d, mmCP_DFY_DATA_0 }, - { 0xd8000009, mmCP_DFY_DATA_0 }, - { 0x1774000d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc41d30b8, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x95c00008, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xccc00009, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xce813265, mmCP_DFY_DATA_0 }, - { 0xcf400100, mmCP_DFY_DATA_0 }, - { 0xc00ac006, mmCP_DFY_DATA_0 }, - { 0xc00e0000, mmCP_DFY_DATA_0 }, - { 0x28880700, mmCP_DFY_DATA_0 }, - { 0x28cc0014, mmCP_DFY_DATA_0 }, - { 0x8c0006de, mmCP_DFY_DATA_0 }, - { 0x14cc0010, mmCP_DFY_DATA_0 }, - { 0x30d4000f, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x10cc0010, mmCP_DFY_DATA_0 }, - { 0x28cc0014, mmCP_DFY_DATA_0 }, - { 0x99400009, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc41530b8, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x19980028, mmCP_DFY_DATA_0 }, - { 0x99400003, mmCP_DFY_DATA_0 }, - { 0x99800002, mmCP_DFY_DATA_0 }, - { 0x800006c8, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x15600008, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xc8380023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x7fa38011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x282c2002, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0xcec00013, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x042c0008, mmCP_DFY_DATA_0 }, - { 0xd3800025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x202400d0, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0x28240006, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x9a800004, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x24d8003f, mmCP_DFY_DATA_0 }, - { 0xd840003c, mmCP_DFY_DATA_0 }, - { 0xcec0003a, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcd81a2a4, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc41d325d, mmCP_DFY_DATA_0 }, - { 0x25dc0007, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x94c0000a, mmCP_DFY_DATA_0 }, - { 0xc420004a, mmCP_DFY_DATA_0 }, - { 0x194c00e8, mmCP_DFY_DATA_0 }, - { 0xccc0005e, mmCP_DFY_DATA_0 }, - { 0xc40c004c, mmCP_DFY_DATA_0 }, - { 0xc431326d, mmCP_DFY_DATA_0 }, - { 0x27301fff, mmCP_DFY_DATA_0 }, - { 0xce00005e, mmCP_DFY_DATA_0 }, - { 0x7cf0c00d, mmCP_DFY_DATA_0 }, - { 0x80000712, mmCP_DFY_DATA_0 }, - { 0x194c1c03, mmCP_DFY_DATA_0 }, - { 0xccc0003b, mmCP_DFY_DATA_0 }, - { 0xc40c002d, mmCP_DFY_DATA_0 }, - { 0x05e80714, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000071c, mmCP_DFY_DATA_0 }, - { 0x80000720, mmCP_DFY_DATA_0 }, - { 0x80000747, mmCP_DFY_DATA_0 }, - { 0x8000071d, mmCP_DFY_DATA_0 }, - { 0x800007c4, mmCP_DFY_DATA_0 }, - { 0x80000732, mmCP_DFY_DATA_0 }, - { 0x80000745, mmCP_DFY_DATA_0 }, - { 0x80000744, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x98c00006, mmCP_DFY_DATA_0 }, - { 0x8000072e, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c0000c, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4253265, mmCP_DFY_DATA_0 }, - { 0x2a64008c, mmCP_DFY_DATA_0 }, - { 0xce413265, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0x1b301fe8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0xd8013260, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0x8000075e, mmCP_DFY_DATA_0 }, - { 0x98c0fff1, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c00002, mmCP_DFY_DATA_0 }, - { 0x80000723, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc41f02f1, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0xd8013247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0x80000743, mmCP_DFY_DATA_0 }, - { 0xd8813247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0xc4100004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcd000008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0x98c0ffde, mmCP_DFY_DATA_0 }, - { 0x8000072e, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x8c0007e0, mmCP_DFY_DATA_0 }, - { 0x95c00012, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x15600008, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0xce000009, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd84131db, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0xcd800009, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0x1b301ff8, mmCP_DFY_DATA_0 }, - { 0x2b300400, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8413260, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x04240000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x041c3000, mmCP_DFY_DATA_0 }, - { 0xcdc13267, mmCP_DFY_DATA_0 }, - { 0xc41d3267, mmCP_DFY_DATA_0 }, - { 0xc41d3265, mmCP_DFY_DATA_0 }, - { 0x25dc8000, mmCP_DFY_DATA_0 }, - { 0x95c00007, mmCP_DFY_DATA_0 }, - { 0xc41c004a, mmCP_DFY_DATA_0 }, - { 0x195800e8, mmCP_DFY_DATA_0 }, - { 0xcd80005e, mmCP_DFY_DATA_0 }, - { 0xc418004c, mmCP_DFY_DATA_0 }, - { 0xcd81326e, mmCP_DFY_DATA_0 }, - { 0xcdc0005e, mmCP_DFY_DATA_0 }, - { 0xc41d3265, mmCP_DFY_DATA_0 }, - { 0x25dd7fff, mmCP_DFY_DATA_0 }, - { 0xcdc13265, mmCP_DFY_DATA_0 }, - { 0xc41d3246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0xc42d3267, mmCP_DFY_DATA_0 }, - { 0x51e00020, mmCP_DFY_DATA_0 }, - { 0x7e1a001a, mmCP_DFY_DATA_0 }, - { 0x46200200, mmCP_DFY_DATA_0 }, - { 0x04283247, mmCP_DFY_DATA_0 }, - { 0x04300033, mmCP_DFY_DATA_0 }, - { 0x1af80057, mmCP_DFY_DATA_0 }, - { 0x1af40213, mmCP_DFY_DATA_0 }, - { 0x042c000c, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f6f400a, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2000025, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xc6990000, mmCP_DFY_DATA_0 }, - { 0x329c325d, mmCP_DFY_DATA_0 }, - { 0x99c00008, mmCP_DFY_DATA_0 }, - { 0x329c3269, mmCP_DFY_DATA_0 }, - { 0x99c00006, mmCP_DFY_DATA_0 }, - { 0x329c3267, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0xc01defff, mmCP_DFY_DATA_0 }, - { 0x7d9d8009, mmCP_DFY_DATA_0 }, - { 0x8000078a, mmCP_DFY_DATA_0 }, - { 0x25980000, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0x9b00fff2, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc43c0012, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd801325b, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0xc03e7ff0, mmCP_DFY_DATA_0 }, - { 0x7f3f0009, mmCP_DFY_DATA_0 }, - { 0xcf01325a, mmCP_DFY_DATA_0 }, - { 0xc4313249, mmCP_DFY_DATA_0 }, - { 0x1f30001f, mmCP_DFY_DATA_0 }, - { 0xcf013249, mmCP_DFY_DATA_0 }, - { 0xc03e4000, mmCP_DFY_DATA_0 }, - { 0xcfc13254, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8013254, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0xd801324f, mmCP_DFY_DATA_0 }, - { 0xd8013255, mmCP_DFY_DATA_0 }, - { 0xd8013247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0x1b300028, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001219, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x9900000d, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0x9700000b, mmCP_DFY_DATA_0 }, - { 0xc43d30b5, mmCP_DFY_DATA_0 }, - { 0x1bf0003a, mmCP_DFY_DATA_0 }, - { 0x9b000b80, mmCP_DFY_DATA_0 }, - { 0x203c003a, mmCP_DFY_DATA_0 }, - { 0xc430000e, mmCP_DFY_DATA_0 }, - { 0x27300700, mmCP_DFY_DATA_0 }, - { 0x13300014, mmCP_DFY_DATA_0 }, - { 0x2b300001, mmCP_DFY_DATA_0 }, - { 0xcf0130b7, mmCP_DFY_DATA_0 }, - { 0xcfc130b5, mmCP_DFY_DATA_0 }, - { 0x46200008, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd2000025, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0x9bc00001, mmCP_DFY_DATA_0 }, - { 0xccc00010, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4080007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0xc4193260, mmCP_DFY_DATA_0 }, - { 0x259c0003, mmCP_DFY_DATA_0 }, - { 0x31dc0003, mmCP_DFY_DATA_0 }, - { 0x95c00014, mmCP_DFY_DATA_0 }, - { 0x040c3000, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x18ec0057, mmCP_DFY_DATA_0 }, - { 0x18e40213, mmCP_DFY_DATA_0 }, - { 0x18cc0199, mmCP_DFY_DATA_0 }, - { 0x7cecc00a, mmCP_DFY_DATA_0 }, - { 0x7ce4c00a, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x8c000448, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x040c2000, mmCP_DFY_DATA_0 }, - { 0xccc13267, mmCP_DFY_DATA_0 }, - { 0xc40d3267, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0xcc800010, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc418000b, mmCP_DFY_DATA_0 }, - { 0x31980002, mmCP_DFY_DATA_0 }, - { 0x041c0000, mmCP_DFY_DATA_0 }, - { 0x9980001c, mmCP_DFY_DATA_0 }, - { 0x19580066, mmCP_DFY_DATA_0 }, - { 0x15600008, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0xc0120001, mmCP_DFY_DATA_0 }, - { 0x11980003, mmCP_DFY_DATA_0 }, - { 0x04240004, mmCP_DFY_DATA_0 }, - { 0x7da18001, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1c200, mmCP_DFY_DATA_0 }, - { 0xc41d24db, mmCP_DFY_DATA_0 }, - { 0x7cd0c001, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0x7dd9c005, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0x99c00002, mmCP_DFY_DATA_0 }, - { 0x9a40fff8, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x9580137b, mmCP_DFY_DATA_0 }, - { 0xc00ee000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1c200, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd840004f, mmCP_DFY_DATA_0 }, - { 0xc4113269, mmCP_DFY_DATA_0 }, - { 0x19080070, mmCP_DFY_DATA_0 }, - { 0x190c00e8, mmCP_DFY_DATA_0 }, - { 0x2510003f, mmCP_DFY_DATA_0 }, - { 0x2518000f, mmCP_DFY_DATA_0 }, - { 0xcd813268, mmCP_DFY_DATA_0 }, - { 0x05a80809, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000080e, mmCP_DFY_DATA_0 }, - { 0x8000080f, mmCP_DFY_DATA_0 }, - { 0x80000898, mmCP_DFY_DATA_0 }, - { 0x80000946, mmCP_DFY_DATA_0 }, - { 0x800009e1, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x04a80811, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000815, mmCP_DFY_DATA_0 }, - { 0x80000834, mmCP_DFY_DATA_0 }, - { 0x8000085e, mmCP_DFY_DATA_0 }, - { 0x8000085e, mmCP_DFY_DATA_0 }, - { 0x04341001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc42d3045, mmCP_DFY_DATA_0 }, - { 0xcec1c091, mmCP_DFY_DATA_0 }, - { 0x31300021, mmCP_DFY_DATA_0 }, - { 0x9700000b, mmCP_DFY_DATA_0 }, - { 0xd84002f1, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xc4293059, mmCP_DFY_DATA_0 }, - { 0x56a8001f, mmCP_DFY_DATA_0 }, - { 0x7f2b000a, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x9b000241, mmCP_DFY_DATA_0 }, - { 0x8000084a, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc43130b6, mmCP_DFY_DATA_0 }, - { 0x9b000003, mmCP_DFY_DATA_0 }, - { 0xc02f0001, mmCP_DFY_DATA_0 }, - { 0xcec130b6, mmCP_DFY_DATA_0 }, - { 0xc4252087, mmCP_DFY_DATA_0 }, - { 0x5668001a, mmCP_DFY_DATA_0 }, - { 0x26a80005, mmCP_DFY_DATA_0 }, - { 0x9a80fffd, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd80130b6, mmCP_DFY_DATA_0 }, - { 0x8000084a, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04341001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc431ecaa, mmCP_DFY_DATA_0 }, - { 0x27300080, mmCP_DFY_DATA_0 }, - { 0x9b000010, mmCP_DFY_DATA_0 }, - { 0xc02e0001, mmCP_DFY_DATA_0 }, - { 0xcec130b6, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd80130b6, mmCP_DFY_DATA_0 }, - { 0x31300021, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xd84002f1, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xc4293059, mmCP_DFY_DATA_0 }, - { 0x56a8001f, mmCP_DFY_DATA_0 }, - { 0x7f2b000a, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x9b00021d, mmCP_DFY_DATA_0 }, - { 0xdd410000, mmCP_DFY_DATA_0 }, - { 0x040c0005, mmCP_DFY_DATA_0 }, - { 0xd84802e9, mmCP_DFY_DATA_0 }, - { 0x8c001a41, mmCP_DFY_DATA_0 }, - { 0xc43b02f1, mmCP_DFY_DATA_0 }, - { 0x9b800006, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xcec80278, mmCP_DFY_DATA_0 }, - { 0x56f00020, mmCP_DFY_DATA_0 }, - { 0xcf080280, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8813247, mmCP_DFY_DATA_0 }, - { 0xd80802e9, mmCP_DFY_DATA_0 }, - { 0x8000085e, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x31100011, mmCP_DFY_DATA_0 }, - { 0x950001fa, mmCP_DFY_DATA_0 }, - { 0xc02e0001, mmCP_DFY_DATA_0 }, - { 0x2aec0008, mmCP_DFY_DATA_0 }, - { 0xc01c0020, mmCP_DFY_DATA_0 }, - { 0xc0180001, mmCP_DFY_DATA_0 }, - { 0xc00c0007, mmCP_DFY_DATA_0 }, - { 0x11a40006, mmCP_DFY_DATA_0 }, - { 0x7de6000a, mmCP_DFY_DATA_0 }, - { 0x10e40008, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x7e2e000a, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0xc4113254, mmCP_DFY_DATA_0 }, - { 0x1d10ffdf, mmCP_DFY_DATA_0 }, - { 0x2110003e, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0xd801324f, mmCP_DFY_DATA_0 }, - { 0xd8013255, mmCP_DFY_DATA_0 }, - { 0x1d10ff9e, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0xd8013247, mmCP_DFY_DATA_0 }, - { 0xd801325d, mmCP_DFY_DATA_0 }, - { 0xd801325e, mmCP_DFY_DATA_0 }, - { 0xc0245301, mmCP_DFY_DATA_0 }, - { 0xce413249, mmCP_DFY_DATA_0 }, - { 0xd801325f, mmCP_DFY_DATA_0 }, - { 0xc425326c, mmCP_DFY_DATA_0 }, - { 0xc0121fff, mmCP_DFY_DATA_0 }, - { 0x29108eff, mmCP_DFY_DATA_0 }, - { 0x7e524009, mmCP_DFY_DATA_0 }, - { 0xce41326c, mmCP_DFY_DATA_0 }, - { 0xc425325a, mmCP_DFY_DATA_0 }, - { 0xc0127ff0, mmCP_DFY_DATA_0 }, - { 0x7e524009, mmCP_DFY_DATA_0 }, - { 0xce41325a, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0xc0131fff, mmCP_DFY_DATA_0 }, - { 0x7e524009, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0xd801326d, mmCP_DFY_DATA_0 }, - { 0xd801326e, mmCP_DFY_DATA_0 }, - { 0xd8013279, mmCP_DFY_DATA_0 }, - { 0x94c00003, mmCP_DFY_DATA_0 }, - { 0x08cc0001, mmCP_DFY_DATA_0 }, - { 0x80000866, mmCP_DFY_DATA_0 }, - { 0xc00c0007, mmCP_DFY_DATA_0 }, - { 0x95800003, mmCP_DFY_DATA_0 }, - { 0x09980001, mmCP_DFY_DATA_0 }, - { 0x80000866, mmCP_DFY_DATA_0 }, - { 0xc0100010, mmCP_DFY_DATA_0 }, - { 0x7dd2400c, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xc0180003, mmCP_DFY_DATA_0 }, - { 0x7dd1c002, mmCP_DFY_DATA_0 }, - { 0x80000866, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x04a8089a, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000089e, mmCP_DFY_DATA_0 }, - { 0x800008fa, mmCP_DFY_DATA_0 }, - { 0x80000945, mmCP_DFY_DATA_0 }, - { 0x80000945, mmCP_DFY_DATA_0 }, - { 0x31300022, mmCP_DFY_DATA_0 }, - { 0x97000007, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d91801a, mmCP_DFY_DATA_0 }, - { 0x459801e0, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x2738000f, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8300011, mmCP_DFY_DATA_0 }, - { 0x97000036, mmCP_DFY_DATA_0 }, - { 0x45980008, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8340011, mmCP_DFY_DATA_0 }, - { 0x9740002f, mmCP_DFY_DATA_0 }, - { 0xc43c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x13b80001, mmCP_DFY_DATA_0 }, - { 0xc79d3300, mmCP_DFY_DATA_0 }, - { 0xc7a13301, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xd8393300, mmCP_DFY_DATA_0 }, - { 0xc0260001, mmCP_DFY_DATA_0 }, - { 0xce793301, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x964012a4, mmCP_DFY_DATA_0 }, - { 0x7c028009, mmCP_DFY_DATA_0 }, - { 0x9740001c, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x99800004, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x06a80400, mmCP_DFY_DATA_0 }, - { 0x800008d2, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0x29640001, mmCP_DFY_DATA_0 }, - { 0xce40001a, mmCP_DFY_DATA_0 }, - { 0x242c0000, mmCP_DFY_DATA_0 }, - { 0x06ec0400, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x9980fffd, mmCP_DFY_DATA_0 }, - { 0xc02620c0, mmCP_DFY_DATA_0 }, - { 0xce41c078, mmCP_DFY_DATA_0 }, - { 0xce81c080, mmCP_DFY_DATA_0 }, - { 0xcc01c081, mmCP_DFY_DATA_0 }, - { 0xcf01c082, mmCP_DFY_DATA_0 }, - { 0x57240020, mmCP_DFY_DATA_0 }, - { 0xce41c083, mmCP_DFY_DATA_0 }, - { 0xc0260400, mmCP_DFY_DATA_0 }, - { 0x7e6e400a, mmCP_DFY_DATA_0 }, - { 0xce41c084, mmCP_DFY_DATA_0 }, - { 0x7eae8001, mmCP_DFY_DATA_0 }, - { 0x7f2f0011, mmCP_DFY_DATA_0 }, - { 0x800008d2, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xcdf93300, mmCP_DFY_DATA_0 }, - { 0xce393301, mmCP_DFY_DATA_0 }, - { 0xcfc00008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc43c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xcfc00008, mmCP_DFY_DATA_0 }, - { 0x80000903, mmCP_DFY_DATA_0 }, - { 0x31240022, mmCP_DFY_DATA_0 }, - { 0x96400008, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43130b8, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x7ec30011, mmCP_DFY_DATA_0 }, - { 0x32f80000, mmCP_DFY_DATA_0 }, - { 0x9b800011, mmCP_DFY_DATA_0 }, - { 0x043c0020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x67180001, mmCP_DFY_DATA_0 }, - { 0x0bfc0001, mmCP_DFY_DATA_0 }, - { 0x57300001, mmCP_DFY_DATA_0 }, - { 0x95800006, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x9a400003, mmCP_DFY_DATA_0 }, - { 0xd981325d, mmCP_DFY_DATA_0 }, - { 0x80000915, mmCP_DFY_DATA_0 }, - { 0xd9c1325d, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9bc0fff6, mmCP_DFY_DATA_0 }, - { 0x7f818001, mmCP_DFY_DATA_0 }, - { 0x8c001606, mmCP_DFY_DATA_0 }, - { 0x7d838001, mmCP_DFY_DATA_0 }, - { 0x94800010, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc41d3259, mmCP_DFY_DATA_0 }, - { 0xc421325a, mmCP_DFY_DATA_0 }, - { 0x16240014, mmCP_DFY_DATA_0 }, - { 0x12640014, mmCP_DFY_DATA_0 }, - { 0x1a2801f0, mmCP_DFY_DATA_0 }, - { 0x12a80010, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0x7e2a000a, mmCP_DFY_DATA_0 }, - { 0x7de1c001, mmCP_DFY_DATA_0 }, - { 0x7e5e400a, mmCP_DFY_DATA_0 }, - { 0x9b800002, mmCP_DFY_DATA_0 }, - { 0x2264003f, mmCP_DFY_DATA_0 }, - { 0xce41325a, mmCP_DFY_DATA_0 }, - { 0xd8013259, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x8c00075e, mmCP_DFY_DATA_0 }, - { 0xc4af0228, mmCP_DFY_DATA_0 }, - { 0x043c0000, mmCP_DFY_DATA_0 }, - { 0x66d80001, mmCP_DFY_DATA_0 }, - { 0x95800010, mmCP_DFY_DATA_0 }, - { 0x04300002, mmCP_DFY_DATA_0 }, - { 0x1330000d, mmCP_DFY_DATA_0 }, - { 0x13f40014, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x04380040, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380060, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x07fc0001, mmCP_DFY_DATA_0 }, - { 0x56ec0001, mmCP_DFY_DATA_0 }, - { 0x33e80010, mmCP_DFY_DATA_0 }, - { 0x9680ffec, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x04a80948, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000094c, mmCP_DFY_DATA_0 }, - { 0x8000099b, mmCP_DFY_DATA_0 }, - { 0x800009e0, mmCP_DFY_DATA_0 }, - { 0x800009e0, mmCP_DFY_DATA_0 }, - { 0xc43c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d91801a, mmCP_DFY_DATA_0 }, - { 0x459801e0, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x2738000f, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8300011, mmCP_DFY_DATA_0 }, - { 0x97000033, mmCP_DFY_DATA_0 }, - { 0x45980008, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc8340011, mmCP_DFY_DATA_0 }, - { 0x9740002c, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x13b80001, mmCP_DFY_DATA_0 }, - { 0xc79d3300, mmCP_DFY_DATA_0 }, - { 0xc7a13301, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xd8393300, mmCP_DFY_DATA_0 }, - { 0xc0260001, mmCP_DFY_DATA_0 }, - { 0xce793301, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x964011fe, mmCP_DFY_DATA_0 }, - { 0x7c028009, mmCP_DFY_DATA_0 }, - { 0x9740001c, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x99800004, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x06a80400, mmCP_DFY_DATA_0 }, - { 0x80000978, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0x29640001, mmCP_DFY_DATA_0 }, - { 0xce40001a, mmCP_DFY_DATA_0 }, - { 0x242c0000, mmCP_DFY_DATA_0 }, - { 0x06ec0400, mmCP_DFY_DATA_0 }, - { 0x57740001, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x9980fffd, mmCP_DFY_DATA_0 }, - { 0xc0260010, mmCP_DFY_DATA_0 }, - { 0xce41c078, mmCP_DFY_DATA_0 }, - { 0xcf01c080, mmCP_DFY_DATA_0 }, - { 0x57240020, mmCP_DFY_DATA_0 }, - { 0xce41c081, mmCP_DFY_DATA_0 }, - { 0xce81c082, mmCP_DFY_DATA_0 }, - { 0xcc01c083, mmCP_DFY_DATA_0 }, - { 0xc0260800, mmCP_DFY_DATA_0 }, - { 0x7e6e400a, mmCP_DFY_DATA_0 }, - { 0xce41c084, mmCP_DFY_DATA_0 }, - { 0x7eae8001, mmCP_DFY_DATA_0 }, - { 0x7f2f0011, mmCP_DFY_DATA_0 }, - { 0x80000978, mmCP_DFY_DATA_0 }, - { 0xc4180006, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xcdf93300, mmCP_DFY_DATA_0 }, - { 0xce393301, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xcfc00008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7dda801a, mmCP_DFY_DATA_0 }, - { 0x7d41c001, mmCP_DFY_DATA_0 }, - { 0x7e838011, mmCP_DFY_DATA_0 }, - { 0xd84802e9, mmCP_DFY_DATA_0 }, - { 0x8c001802, mmCP_DFY_DATA_0 }, - { 0x469c0390, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4200011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4240011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4280011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc42c0011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0x45dc0004, mmCP_DFY_DATA_0 }, - { 0xd1c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4380011, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x8c0014df, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x31280014, mmCP_DFY_DATA_0 }, - { 0xce8802ef, mmCP_DFY_DATA_0 }, - { 0x9a800062, mmCP_DFY_DATA_0 }, - { 0x31280034, mmCP_DFY_DATA_0 }, - { 0x9a800060, mmCP_DFY_DATA_0 }, - { 0x04a809e8, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x800009ec, mmCP_DFY_DATA_0 }, - { 0x80000a45, mmCP_DFY_DATA_0 }, - { 0x80000a59, mmCP_DFY_DATA_0 }, - { 0x80000a59, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4113246, mmCP_DFY_DATA_0 }, - { 0xc4193245, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0x7d91801a, mmCP_DFY_DATA_0 }, - { 0x45980400, mmCP_DFY_DATA_0 }, - { 0xc4b30258, mmCP_DFY_DATA_0 }, - { 0xc4a70250, mmCP_DFY_DATA_0 }, - { 0x53300020, mmCP_DFY_DATA_0 }, - { 0x7e72401a, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x1b342010, mmCP_DFY_DATA_0 }, - { 0x172c000c, mmCP_DFY_DATA_0 }, - { 0x26ec0800, mmCP_DFY_DATA_0 }, - { 0x1b30c012, mmCP_DFY_DATA_0 }, - { 0x7ef7400a, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x2b300000, mmCP_DFY_DATA_0 }, - { 0xcf00001c, mmCP_DFY_DATA_0 }, - { 0x042c0020, mmCP_DFY_DATA_0 }, - { 0x66740001, mmCP_DFY_DATA_0 }, - { 0x97400041, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04383000, mmCP_DFY_DATA_0 }, - { 0xcf813267, mmCP_DFY_DATA_0 }, - { 0xc4393267, mmCP_DFY_DATA_0 }, - { 0x9b800001, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x1b38007e, mmCP_DFY_DATA_0 }, - { 0x33b40003, mmCP_DFY_DATA_0 }, - { 0x9b400003, mmCP_DFY_DATA_0 }, - { 0x4598001c, mmCP_DFY_DATA_0 }, - { 0x9740002f, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc40c0011, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4100011, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002eb, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002ec, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002ed, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4340011, mmCP_DFY_DATA_0 }, - { 0xcf4002ee, mmCP_DFY_DATA_0 }, - { 0x45980004, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04382000, mmCP_DFY_DATA_0 }, - { 0xcf813267, mmCP_DFY_DATA_0 }, - { 0xd84802e9, mmCP_DFY_DATA_0 }, - { 0x8c001715, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04382000, mmCP_DFY_DATA_0 }, - { 0xcf813267, mmCP_DFY_DATA_0 }, - { 0x56640001, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x9ac0ffbc, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x04341001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x94800005, mmCP_DFY_DATA_0 }, - { 0xc431ecaa, mmCP_DFY_DATA_0 }, - { 0x27300080, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000a55, mmCP_DFY_DATA_0 }, - { 0xc43130b6, mmCP_DFY_DATA_0 }, - { 0x233c0032, mmCP_DFY_DATA_0 }, - { 0xcfc130b6, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcf0130b6, mmCP_DFY_DATA_0 }, - { 0xc49302ef, mmCP_DFY_DATA_0 }, - { 0x99000003, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8413247, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0x80000a5a, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04180001, mmCP_DFY_DATA_0 }, - { 0x5198001f, mmCP_DFY_DATA_0 }, - { 0xcd813268, mmCP_DFY_DATA_0 }, - { 0xc4193269, mmCP_DFY_DATA_0 }, - { 0x2598000f, mmCP_DFY_DATA_0 }, - { 0x9980fffe, mmCP_DFY_DATA_0 }, - { 0xd80002f1, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8013268, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04380001, mmCP_DFY_DATA_0 }, - { 0x53b8001f, mmCP_DFY_DATA_0 }, - { 0x7db9801a, mmCP_DFY_DATA_0 }, - { 0xcd813268, mmCP_DFY_DATA_0 }, - { 0x80000a5e, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01106, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcc412e01, mmCP_DFY_DATA_0 }, - { 0xcc412e02, mmCP_DFY_DATA_0 }, - { 0xcc412e03, mmCP_DFY_DATA_0 }, - { 0xcc412e00, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c010fd, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50640020, mmCP_DFY_DATA_0 }, - { 0x7ce4c01a, mmCP_DFY_DATA_0 }, - { 0xd0c00072, mmCP_DFY_DATA_0 }, - { 0xc80c0072, mmCP_DFY_DATA_0 }, - { 0x58e801fc, mmCP_DFY_DATA_0 }, - { 0x12a80009, mmCP_DFY_DATA_0 }, - { 0x2aa80000, mmCP_DFY_DATA_0 }, - { 0xd0c0001e, mmCP_DFY_DATA_0 }, - { 0xce80001c, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc424000f, mmCP_DFY_DATA_0 }, - { 0x9a40ffff, mmCP_DFY_DATA_0 }, - { 0x04240010, mmCP_DFY_DATA_0 }, - { 0x18dc01e2, mmCP_DFY_DATA_0 }, - { 0x7e5e4002, mmCP_DFY_DATA_0 }, - { 0x3e5c0003, mmCP_DFY_DATA_0 }, - { 0x3e540002, mmCP_DFY_DATA_0 }, - { 0x95c00006, mmCP_DFY_DATA_0 }, - { 0xc8180011, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0x55140020, mmCP_DFY_DATA_0 }, - { 0x80000aa2, mmCP_DFY_DATA_0 }, - { 0x9540000a, mmCP_DFY_DATA_0 }, - { 0xc8180011, mmCP_DFY_DATA_0 }, - { 0x44cc0008, mmCP_DFY_DATA_0 }, - { 0x55900020, mmCP_DFY_DATA_0 }, - { 0xd0c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc424000f, mmCP_DFY_DATA_0 }, - { 0x9a40ffff, mmCP_DFY_DATA_0 }, - { 0xc4140011, mmCP_DFY_DATA_0 }, - { 0x80000aa2, mmCP_DFY_DATA_0 }, - { 0x44cc0004, mmCP_DFY_DATA_0 }, - { 0xc4180011, mmCP_DFY_DATA_0 }, - { 0xd0c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc424000f, mmCP_DFY_DATA_0 }, - { 0x9a40ffff, mmCP_DFY_DATA_0 }, - { 0xc8100011, mmCP_DFY_DATA_0 }, - { 0x55140020, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcd812e01, mmCP_DFY_DATA_0 }, - { 0xcd012e02, mmCP_DFY_DATA_0 }, - { 0xcd412e03, mmCP_DFY_DATA_0 }, - { 0xcc412e00, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc4253249, mmCP_DFY_DATA_0 }, - { 0x2264003f, mmCP_DFY_DATA_0 }, - { 0xce413249, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc4253249, mmCP_DFY_DATA_0 }, - { 0x96400001, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xc410001a, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0xc4140028, mmCP_DFY_DATA_0 }, - { 0x95000005, mmCP_DFY_DATA_0 }, - { 0x1e64001f, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce413249, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x14d00010, mmCP_DFY_DATA_0 }, - { 0xc4180030, mmCP_DFY_DATA_0 }, - { 0xc41c0007, mmCP_DFY_DATA_0 }, - { 0x99000004, mmCP_DFY_DATA_0 }, - { 0x99400009, mmCP_DFY_DATA_0 }, - { 0x9980000c, mmCP_DFY_DATA_0 }, - { 0x80000ab1, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xc420001c, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0x9a0010ac, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xd880003f, mmCP_DFY_DATA_0 }, - { 0x95c00002, mmCP_DFY_DATA_0 }, - { 0xd8c0003f, mmCP_DFY_DATA_0 }, - { 0x80001082, mmCP_DFY_DATA_0 }, - { 0xd8800040, mmCP_DFY_DATA_0 }, - { 0x95c00002, mmCP_DFY_DATA_0 }, - { 0xd8c00040, mmCP_DFY_DATA_0 }, - { 0x800010de, mmCP_DFY_DATA_0 }, - { 0xc010ffff, mmCP_DFY_DATA_0 }, - { 0x18d403f7, mmCP_DFY_DATA_0 }, - { 0x7d0cc009, mmCP_DFY_DATA_0 }, - { 0xc41b0367, mmCP_DFY_DATA_0 }, - { 0x7d958004, mmCP_DFY_DATA_0 }, - { 0x7d85800a, mmCP_DFY_DATA_0 }, - { 0xdc1e0000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d001fc, mmCP_DFY_DATA_0 }, - { 0x05280adc, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000af1, mmCP_DFY_DATA_0 }, - { 0x80000adf, mmCP_DFY_DATA_0 }, - { 0x80000ae7, mmCP_DFY_DATA_0 }, - { 0x8c000ace, mmCP_DFY_DATA_0 }, - { 0xd8c00013, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd8d2000, mmCP_DFY_DATA_0 }, - { 0x99c00010, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x18d803f7, mmCP_DFY_DATA_0 }, - { 0xc010ffff, mmCP_DFY_DATA_0 }, - { 0x7d0cc009, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0x11940014, mmCP_DFY_DATA_0 }, - { 0x29544001, mmCP_DFY_DATA_0 }, - { 0x9a400002, mmCP_DFY_DATA_0 }, - { 0x29544003, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x80000af4, mmCP_DFY_DATA_0 }, - { 0xd8c00013, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd44d2000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0xd8c00013, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd44dc000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d0003c, mmCP_DFY_DATA_0 }, - { 0x95000006, mmCP_DFY_DATA_0 }, - { 0x8c000ace, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcd8d2c00, mmCP_DFY_DATA_0 }, - { 0x99c00003, mmCP_DFY_DATA_0 }, - { 0x80000b0a, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xd44d2c00, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x28148004, mmCP_DFY_DATA_0 }, - { 0x24d800ff, mmCP_DFY_DATA_0 }, - { 0xccc00019, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd4593240, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c0105e, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x50540020, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x2198003f, mmCP_DFY_DATA_0 }, - { 0x199c0034, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x95c00028, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc42d324f, mmCP_DFY_DATA_0 }, - { 0xc4313255, mmCP_DFY_DATA_0 }, - { 0x7ef3400c, mmCP_DFY_DATA_0 }, - { 0x9b400021, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x14e80001, mmCP_DFY_DATA_0 }, - { 0x9a8000af, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x041c0002, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0xccc00010, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c01043, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x50540020, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x18a01fe8, mmCP_DFY_DATA_0 }, - { 0x3620005c, mmCP_DFY_DATA_0 }, - { 0x9a00000e, mmCP_DFY_DATA_0 }, - { 0x2464003f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc6290ce7, mmCP_DFY_DATA_0 }, - { 0x16ac001f, mmCP_DFY_DATA_0 }, - { 0x96c00004, mmCP_DFY_DATA_0 }, - { 0x26ac003f, mmCP_DFY_DATA_0 }, - { 0x7ee6c00d, mmCP_DFY_DATA_0 }, - { 0x96c00005, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x2620000f, mmCP_DFY_DATA_0 }, - { 0x9a00fff8, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xce000367, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x9640102e, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x199c0037, mmCP_DFY_DATA_0 }, - { 0x19a00035, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x95c0005d, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xc42d3256, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0x16f8001f, mmCP_DFY_DATA_0 }, - { 0x9780000d, mmCP_DFY_DATA_0 }, - { 0xc4253248, mmCP_DFY_DATA_0 }, - { 0xc035f0ff, mmCP_DFY_DATA_0 }, - { 0x7e764009, mmCP_DFY_DATA_0 }, - { 0x19b401f8, mmCP_DFY_DATA_0 }, - { 0x13740008, mmCP_DFY_DATA_0 }, - { 0x7e76400a, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce413248, mmCP_DFY_DATA_0 }, - { 0xcf01325a, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xd1000072, mmCP_DFY_DATA_0 }, - { 0xc8100072, mmCP_DFY_DATA_0 }, - { 0x55140020, mmCP_DFY_DATA_0 }, - { 0x199c0034, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0x9b800004, mmCP_DFY_DATA_0 }, - { 0x1ae4003e, mmCP_DFY_DATA_0 }, - { 0xce400008, mmCP_DFY_DATA_0 }, - { 0x80000b7c, mmCP_DFY_DATA_0 }, - { 0xc4353254, mmCP_DFY_DATA_0 }, - { 0x16a80008, mmCP_DFY_DATA_0 }, - { 0x1aec003c, mmCP_DFY_DATA_0 }, - { 0x19a4003f, mmCP_DFY_DATA_0 }, - { 0x12a80015, mmCP_DFY_DATA_0 }, - { 0x12ec001f, mmCP_DFY_DATA_0 }, - { 0x1374000b, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc02e4000, mmCP_DFY_DATA_0 }, - { 0x1774000d, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xce400008, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0xc43d3248, mmCP_DFY_DATA_0 }, - { 0x1bfc01e8, mmCP_DFY_DATA_0 }, - { 0x13fc0018, mmCP_DFY_DATA_0 }, - { 0x7dbd800a, mmCP_DFY_DATA_0 }, - { 0x1d98ff15, mmCP_DFY_DATA_0 }, - { 0x592c00fc, mmCP_DFY_DATA_0 }, - { 0xcd80000a, mmCP_DFY_DATA_0 }, - { 0x12e00016, mmCP_DFY_DATA_0 }, - { 0x7da1800a, mmCP_DFY_DATA_0 }, - { 0x592c007e, mmCP_DFY_DATA_0 }, - { 0x12e00015, mmCP_DFY_DATA_0 }, - { 0x7da1800a, mmCP_DFY_DATA_0 }, - { 0xd1000001, mmCP_DFY_DATA_0 }, - { 0xcd800001, mmCP_DFY_DATA_0 }, - { 0x11a0000c, mmCP_DFY_DATA_0 }, - { 0x1264001e, mmCP_DFY_DATA_0 }, - { 0x1620000c, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x7e32000a, mmCP_DFY_DATA_0 }, - { 0x12e4001b, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x5924007e, mmCP_DFY_DATA_0 }, - { 0x12640017, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0x19a4003c, mmCP_DFY_DATA_0 }, - { 0x12640018, mmCP_DFY_DATA_0 }, - { 0x7e26000a, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xce01325a, mmCP_DFY_DATA_0 }, - { 0xcd013257, mmCP_DFY_DATA_0 }, - { 0xcd413258, mmCP_DFY_DATA_0 }, - { 0xc429325a, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c00fdb, mmCP_DFY_DATA_0 }, - { 0x96800001, mmCP_DFY_DATA_0 }, - { 0x95c00003, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x9780f5ca, mmCP_DFY_DATA_0 }, - { 0xcf400100, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0xd9000010, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001219, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0xccc00010, mmCP_DFY_DATA_0 }, - { 0x8c001b6d, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc42d324e, mmCP_DFY_DATA_0 }, - { 0xc431324d, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc435324f, mmCP_DFY_DATA_0 }, - { 0xc4293256, mmCP_DFY_DATA_0 }, - { 0x52ec0008, mmCP_DFY_DATA_0 }, - { 0x07740003, mmCP_DFY_DATA_0 }, - { 0x04240002, mmCP_DFY_DATA_0 }, - { 0x269c003f, mmCP_DFY_DATA_0 }, - { 0x7e5e4004, mmCP_DFY_DATA_0 }, - { 0x7f67000f, mmCP_DFY_DATA_0 }, - { 0x97000003, mmCP_DFY_DATA_0 }, - { 0x7f674002, mmCP_DFY_DATA_0 }, - { 0x0b740001, mmCP_DFY_DATA_0 }, - { 0x53740002, mmCP_DFY_DATA_0 }, - { 0x7ef6c011, mmCP_DFY_DATA_0 }, - { 0x1ab42010, mmCP_DFY_DATA_0 }, - { 0x1ab8c006, mmCP_DFY_DATA_0 }, - { 0x16a8000c, mmCP_DFY_DATA_0 }, - { 0x26a80800, mmCP_DFY_DATA_0 }, - { 0x2b740000, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0xcf40001c, mmCP_DFY_DATA_0 }, - { 0xd2c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4180011, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0x8c000bec, mmCP_DFY_DATA_0 }, - { 0x80000b47, mmCP_DFY_DATA_0 }, - { 0xc42c001d, mmCP_DFY_DATA_0 }, - { 0xc4313256, mmCP_DFY_DATA_0 }, - { 0x1b34060b, mmCP_DFY_DATA_0 }, - { 0x1b300077, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x13300017, mmCP_DFY_DATA_0 }, - { 0x04340100, mmCP_DFY_DATA_0 }, - { 0x26ec00ff, mmCP_DFY_DATA_0 }, - { 0xc03a8004, mmCP_DFY_DATA_0 }, - { 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { 0x7f3b000a, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc40c0032, mmCP_DFY_DATA_0 }, - { 0xc410001d, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc415325b, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x18580037, mmCP_DFY_DATA_0 }, - { 0x251000ff, mmCP_DFY_DATA_0 }, - { 0xc421325d, mmCP_DFY_DATA_0 }, - { 0x262001ef, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x99800004, mmCP_DFY_DATA_0 }, - { 0x7d15400a, mmCP_DFY_DATA_0 }, - { 0xcd41325b, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x1d54001f, mmCP_DFY_DATA_0 }, - { 0xcd41325b, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc428000b, mmCP_DFY_DATA_0 }, - { 0xc42c000c, mmCP_DFY_DATA_0 }, - { 0x12a80001, mmCP_DFY_DATA_0 }, - { 0x26a80004, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0xc4340028, mmCP_DFY_DATA_0 }, - { 0x14f00010, mmCP_DFY_DATA_0 }, - { 0xc4380030, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xcd280200, mmCP_DFY_DATA_0 }, - { 0xcd680208, mmCP_DFY_DATA_0 }, - { 0xcda80210, mmCP_DFY_DATA_0 }, - { 0x9b00000c, mmCP_DFY_DATA_0 }, - { 0x9b400014, mmCP_DFY_DATA_0 }, - { 0x9b800017, mmCP_DFY_DATA_0 }, - { 0xc428000b, mmCP_DFY_DATA_0 }, - { 0xc42c000c, mmCP_DFY_DATA_0 }, - { 0x12a80001, mmCP_DFY_DATA_0 }, - { 0x26a80004, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc6930200, mmCP_DFY_DATA_0 }, - { 0xc6970208, mmCP_DFY_DATA_0 }, - { 0xc69b0210, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b000005, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd900003f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd940003f, mmCP_DFY_DATA_0 }, - { 0x80001082, mmCP_DFY_DATA_0 }, - { 0xd9000040, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd9400040, mmCP_DFY_DATA_0 }, - { 0x800010de, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14fc0011, mmCP_DFY_DATA_0 }, - { 0x24f800ff, mmCP_DFY_DATA_0 }, - { 0x33b80001, mmCP_DFY_DATA_0 }, - { 0x97c0fffc, mmCP_DFY_DATA_0 }, - { 0x9b800007, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc4380004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd88130b8, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0x7d83c001, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4093249, mmCP_DFY_DATA_0 }, - { 0x1888003e, mmCP_DFY_DATA_0 }, - { 0x94800020, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0x8c000671, mmCP_DFY_DATA_0 }, - { 0x9a400009, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc419324c, mmCP_DFY_DATA_0 }, - { 0x259c0001, mmCP_DFY_DATA_0 }, - { 0x1598001f, mmCP_DFY_DATA_0 }, - { 0x95c00016, mmCP_DFY_DATA_0 }, - { 0x95800015, mmCP_DFY_DATA_0 }, - { 0x99000003, mmCP_DFY_DATA_0 }, - { 0xd8400036, mmCP_DFY_DATA_0 }, - { 0x04100001, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0x14d80011, mmCP_DFY_DATA_0 }, - { 0x24e000ff, mmCP_DFY_DATA_0 }, - { 0x321c0002, mmCP_DFY_DATA_0 }, - { 0x32200001, mmCP_DFY_DATA_0 }, - { 0x9580ffee, mmCP_DFY_DATA_0 }, - { 0x99c00014, mmCP_DFY_DATA_0 }, - { 0x96000004, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x04140001, mmCP_DFY_DATA_0 }, - { 0x80000c30, mmCP_DFY_DATA_0 }, - { 0x9480000a, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95800f29, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x94800004, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95800f23, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0x99400002, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0xcf800008, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x94800004, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0xc418005e, mmCP_DFY_DATA_0 }, - { 0x95800f1a, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0xd8800036, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x041c0003, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xc40c0077, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x9600f502, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x98c0f500, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0x9a000f05, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0xc42d3256, mmCP_DFY_DATA_0 }, - { 0x1f30001f, mmCP_DFY_DATA_0 }, - { 0x16e4001f, mmCP_DFY_DATA_0 }, - { 0xcf01325a, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x9640f4f4, mmCP_DFY_DATA_0 }, - { 0xc434000b, mmCP_DFY_DATA_0 }, - { 0x33740002, mmCP_DFY_DATA_0 }, - { 0x9b40f4f1, mmCP_DFY_DATA_0 }, - { 0xc4353254, mmCP_DFY_DATA_0 }, - { 0x16a80008, mmCP_DFY_DATA_0 }, - { 0x1aec003c, mmCP_DFY_DATA_0 }, - { 0x12a80015, mmCP_DFY_DATA_0 }, - { 0x12ec001f, mmCP_DFY_DATA_0 }, - { 0x1374000b, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0xc02e4000, mmCP_DFY_DATA_0 }, - { 0x1774000d, mmCP_DFY_DATA_0 }, - { 0x7eae800a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0xcf400100, mmCP_DFY_DATA_0 }, - { 0x12780001, mmCP_DFY_DATA_0 }, - { 0x2bb80001, mmCP_DFY_DATA_0 }, - { 0xc00ac005, mmCP_DFY_DATA_0 }, - { 0xc00e0002, mmCP_DFY_DATA_0 }, - { 0x28cc8000, mmCP_DFY_DATA_0 }, - { 0x28884900, mmCP_DFY_DATA_0 }, - { 0x28cc0014, mmCP_DFY_DATA_0 }, - { 0x80000ff3, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x17fc0001, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x96400ee1, mmCP_DFY_DATA_0 }, - { 0xcc41c40a, mmCP_DFY_DATA_0 }, - { 0xcc41c40c, mmCP_DFY_DATA_0 }, - { 0xcc41c40d, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x24d0007f, mmCP_DFY_DATA_0 }, - { 0x15580010, mmCP_DFY_DATA_0 }, - { 0x255400ff, mmCP_DFY_DATA_0 }, - { 0xcd01c411, mmCP_DFY_DATA_0 }, - { 0xcd81c40f, mmCP_DFY_DATA_0 }, - { 0xcd41c40e, mmCP_DFY_DATA_0 }, - { 0xcc41c410, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x04200000, mmCP_DFY_DATA_0 }, - { 0x18e80033, mmCP_DFY_DATA_0 }, - { 0x18ec0034, mmCP_DFY_DATA_0 }, - { 0xcc41c414, mmCP_DFY_DATA_0 }, - { 0xcc41c415, mmCP_DFY_DATA_0 }, - { 0xcd81c413, mmCP_DFY_DATA_0 }, - { 0xcd41c412, mmCP_DFY_DATA_0 }, - { 0x18dc0032, mmCP_DFY_DATA_0 }, - { 0x7c030011, mmCP_DFY_DATA_0 }, - { 0x7c038011, mmCP_DFY_DATA_0 }, - { 0x95c00027, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xc431c417, mmCP_DFY_DATA_0 }, - { 0xc435c416, mmCP_DFY_DATA_0 }, - { 0x96800004, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xc439c419, mmCP_DFY_DATA_0 }, - { 0xc43dc418, mmCP_DFY_DATA_0 }, - { 0xc41c000e, mmCP_DFY_DATA_0 }, - { 0x29dc0008, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xcf413261, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xcf013262, mmCP_DFY_DATA_0 }, - { 0x96800004, mmCP_DFY_DATA_0 }, - { 0xcfc13263, mmCP_DFY_DATA_0 }, - { 0x96c00002, mmCP_DFY_DATA_0 }, - { 0xcf813264, mmCP_DFY_DATA_0 }, - { 0x18dc0030, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x95c00017, mmCP_DFY_DATA_0 }, - { 0x17fc0001, mmCP_DFY_DATA_0 }, - { 0x9ac00005, mmCP_DFY_DATA_0 }, - { 0x7d77000c, mmCP_DFY_DATA_0 }, - { 0x9bc00015, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0x80000cd6, mmCP_DFY_DATA_0 }, - { 0x51b80020, mmCP_DFY_DATA_0 }, - { 0x53300020, mmCP_DFY_DATA_0 }, - { 0x7f97801a, mmCP_DFY_DATA_0 }, - { 0x7f37001a, mmCP_DFY_DATA_0 }, - { 0x7f3b000c, mmCP_DFY_DATA_0 }, - { 0x9bc0000d, mmCP_DFY_DATA_0 }, - { 0x97800002, mmCP_DFY_DATA_0 }, - { 0x80000cd6, mmCP_DFY_DATA_0 }, - { 0x9a000018, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x28200001, mmCP_DFY_DATA_0 }, - { 0x80000ca7, mmCP_DFY_DATA_0 }, - { 0x18dc0031, mmCP_DFY_DATA_0 }, - { 0x95c00003, mmCP_DFY_DATA_0 }, - { 0xc435c40b, mmCP_DFY_DATA_0 }, - { 0x9740fffd, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc4280032, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x800012c2, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0xc43d3256, mmCP_DFY_DATA_0 }, - { 0x1bf0060b, mmCP_DFY_DATA_0 }, - { 0x1bfc0077, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x80000cf4, mmCP_DFY_DATA_0 }, - { 0xc43d325a, mmCP_DFY_DATA_0 }, - { 0x1bfc0677, mmCP_DFY_DATA_0 }, - { 0x13fc0017, mmCP_DFY_DATA_0 }, - { 0x04300100, mmCP_DFY_DATA_0 }, - { 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xc032800b, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d42011, mmCP_DFY_DATA_0 }, - { 0x17fc0001, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x24cc007f, mmCP_DFY_DATA_0 }, - { 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc428005e, mmCP_DFY_DATA_0 }, - { 0x96800e6c, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x596001fc, mmCP_DFY_DATA_0 }, - { 0x12200009, mmCP_DFY_DATA_0 }, - { 0x7ce0c00a, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x505c0020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x50600020, mmCP_DFY_DATA_0 }, - { 0x7de1c01a, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xccc0001b, mmCP_DFY_DATA_0 }, - { 0xd140001d, mmCP_DFY_DATA_0 }, - { 0xd180001f, mmCP_DFY_DATA_0 }, - { 0xd1c00020, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x95000010, mmCP_DFY_DATA_0 }, - { 0x04300000, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8240010, mmCP_DFY_DATA_0 }, - { 0x7e5e800c, mmCP_DFY_DATA_0 }, - { 0x9bc00015, mmCP_DFY_DATA_0 }, - { 0x9a80000c, mmCP_DFY_DATA_0 }, - { 0x9b000024, mmCP_DFY_DATA_0 }, - { 0x28300001, mmCP_DFY_DATA_0 }, - { 0x122c0004, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x80000d1f, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8240010, mmCP_DFY_DATA_0 }, - { 0x566c0020, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce413261, mmCP_DFY_DATA_0 }, - { 0xcec13262, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc4340032, mmCP_DFY_DATA_0 }, - { 0x2b740008, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x96800005, mmCP_DFY_DATA_0 }, - { 0x566c0020, mmCP_DFY_DATA_0 }, - { 0xce413261, mmCP_DFY_DATA_0 }, - { 0xcec13262, mmCP_DFY_DATA_0 }, - { 0x800012c2, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { 0x7f8cc00a, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0xc43d3256, mmCP_DFY_DATA_0 }, - { 0x1bf0060b, mmCP_DFY_DATA_0 }, - { 0x1bfc0077, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x80000d57, mmCP_DFY_DATA_0 }, - { 0xc43d325a, mmCP_DFY_DATA_0 }, - { 0x1bfc0677, mmCP_DFY_DATA_0 }, - { 0x13fc0017, mmCP_DFY_DATA_0 }, - { 0x04300100, mmCP_DFY_DATA_0 }, - { 0x1bb81fe8, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xc0328009, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc4253246, mmCP_DFY_DATA_0 }, - { 0xc4113245, mmCP_DFY_DATA_0 }, - { 0x04143000, mmCP_DFY_DATA_0 }, - { 0xcd413267, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e51001a, mmCP_DFY_DATA_0 }, - { 0xc4153267, mmCP_DFY_DATA_0 }, - { 0x7d2d0011, mmCP_DFY_DATA_0 }, - { 0x19640057, mmCP_DFY_DATA_0 }, - { 0x19580213, mmCP_DFY_DATA_0 }, - { 0x19600199, mmCP_DFY_DATA_0 }, - { 0x7da6400a, mmCP_DFY_DATA_0 }, - { 0x7e26400a, mmCP_DFY_DATA_0 }, - { 0xd1000025, mmCP_DFY_DATA_0 }, - { 0xce400024, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x04142000, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xcd413267, mmCP_DFY_DATA_0 }, - { 0xc4153267, mmCP_DFY_DATA_0 }, - { 0x99400001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x18d40030, mmCP_DFY_DATA_0 }, - { 0x18d80034, mmCP_DFY_DATA_0 }, - { 0x05280d83, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0x7c424001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000d8a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x80000d95, mmCP_DFY_DATA_0 }, - { 0x80000db1, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x80000d95, mmCP_DFY_DATA_0 }, - { 0x80000dbc, mmCP_DFY_DATA_0 }, - { 0x11540010, mmCP_DFY_DATA_0 }, - { 0x7e010001, mmCP_DFY_DATA_0 }, - { 0x8c00187c, mmCP_DFY_DATA_0 }, - { 0x7d75400a, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd4610000, mmCP_DFY_DATA_0 }, - { 0x9580f3d8, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8000016, mmCP_DFY_DATA_0 }, - { 0x526c0020, mmCP_DFY_DATA_0 }, - { 0x18e80058, mmCP_DFY_DATA_0 }, - { 0x7e2ec01a, mmCP_DFY_DATA_0 }, - { 0xd2c00072, mmCP_DFY_DATA_0 }, - { 0xc82c0072, mmCP_DFY_DATA_0 }, - { 0x5ae0073a, mmCP_DFY_DATA_0 }, - { 0x7ea2800a, mmCP_DFY_DATA_0 }, - { 0x9940000a, mmCP_DFY_DATA_0 }, - { 0xce800024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9580f3c6, mmCP_DFY_DATA_0 }, - { 0xc4380012, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xdc3a0000, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0xce800024, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xcc400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9b80fffb, mmCP_DFY_DATA_0 }, - { 0x9980fff5, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc02a0001, mmCP_DFY_DATA_0 }, - { 0x2aa80001, mmCP_DFY_DATA_0 }, - { 0x16200002, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xce01c405, mmCP_DFY_DATA_0 }, - { 0xd441c406, mmCP_DFY_DATA_0 }, - { 0x9580f3b1, mmCP_DFY_DATA_0 }, - { 0xc439c409, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a40000b, mmCP_DFY_DATA_0 }, - { 0x11540010, mmCP_DFY_DATA_0 }, - { 0x29540002, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd4610000, mmCP_DFY_DATA_0 }, - { 0x9580f3a5, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c00da7, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50500020, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0xd0c00072, mmCP_DFY_DATA_0 }, - { 0xc8280072, mmCP_DFY_DATA_0 }, - { 0x5aac007e, mmCP_DFY_DATA_0 }, - { 0x12d80017, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7d9d800a, mmCP_DFY_DATA_0 }, - { 0x56a00020, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0x7da1800a, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7e82400a, mmCP_DFY_DATA_0 }, - { 0x7e58c01a, mmCP_DFY_DATA_0 }, - { 0x19d4003d, mmCP_DFY_DATA_0 }, - { 0x28182002, mmCP_DFY_DATA_0 }, - { 0x99400030, mmCP_DFY_DATA_0 }, - { 0x8c00104f, mmCP_DFY_DATA_0 }, - { 0xc430000d, mmCP_DFY_DATA_0 }, - { 0xc4340035, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc8140023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0xc011000f, mmCP_DFY_DATA_0 }, - { 0xc4240004, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x7c908009, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x7d614011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7ca4800a, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x7cb0800a, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0x20880188, mmCP_DFY_DATA_0 }, - { 0x54ec0020, mmCP_DFY_DATA_0 }, - { 0x7cb4800a, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x04380008, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x20240090, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0x28240004, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x9a800005, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xd8000016, mmCP_DFY_DATA_0 }, - { 0xcf80003a, mmCP_DFY_DATA_0 }, - { 0xd901a2a4, mmCP_DFY_DATA_0 }, - { 0x80001037, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x1624001f, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0xd841325f, mmCP_DFY_DATA_0 }, - { 0xd8800033, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0004, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8000039, mmCP_DFY_DATA_0 }, - { 0xd0c00038, mmCP_DFY_DATA_0 }, - { 0xc43c0022, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0xc429325f, mmCP_DFY_DATA_0 }, - { 0x26ac0001, mmCP_DFY_DATA_0 }, - { 0x9ac0fffe, mmCP_DFY_DATA_0 }, - { 0x26ac0002, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xc430001e, mmCP_DFY_DATA_0 }, - { 0xd8800033, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x1b301ff0, mmCP_DFY_DATA_0 }, - { 0x2b300300, mmCP_DFY_DATA_0 }, - { 0x2330003f, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x9680000b, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0004, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400039, mmCP_DFY_DATA_0 }, - { 0xd0c00038, mmCP_DFY_DATA_0 }, - { 0xc43c0022, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0x8c0001a2, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0x24b00008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x18ac0024, mmCP_DFY_DATA_0 }, - { 0x2b304000, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4113249, mmCP_DFY_DATA_0 }, - { 0x1910003e, mmCP_DFY_DATA_0 }, - { 0x99000002, mmCP_DFY_DATA_0 }, - { 0xd840003d, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x51100020, mmCP_DFY_DATA_0 }, - { 0xcf01326c, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x12a80014, mmCP_DFY_DATA_0 }, - { 0x2220003f, mmCP_DFY_DATA_0 }, - { 0x7e2a000a, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xce01326c, mmCP_DFY_DATA_0 }, - { 0xd8800033, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0004, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8000039, mmCP_DFY_DATA_0 }, - { 0xd0c00038, mmCP_DFY_DATA_0 }, - { 0xc43c0022, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0xd8800034, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18dc003d, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0x041c0001, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x18d40030, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x18fc0034, mmCP_DFY_DATA_0 }, - { 0x24e8000f, mmCP_DFY_DATA_0 }, - { 0x06a80e71, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000edd, mmCP_DFY_DATA_0 }, - { 0x80000e91, mmCP_DFY_DATA_0 }, - { 0x80000e91, mmCP_DFY_DATA_0 }, - { 0x80000ea1, mmCP_DFY_DATA_0 }, - { 0x80000eaa, mmCP_DFY_DATA_0 }, - { 0x80000e7c, mmCP_DFY_DATA_0 }, - { 0x80000e7f, mmCP_DFY_DATA_0 }, - { 0x80000e7f, mmCP_DFY_DATA_0 }, - { 0x80000e87, mmCP_DFY_DATA_0 }, - { 0x80000e8f, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x51dc0020, mmCP_DFY_DATA_0 }, - { 0x7d9e001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0xc420000e, mmCP_DFY_DATA_0 }, - { 0x2a200008, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0xc4213262, mmCP_DFY_DATA_0 }, - { 0xc4253261, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0xc420000e, mmCP_DFY_DATA_0 }, - { 0x2a200008, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0xc4213264, mmCP_DFY_DATA_0 }, - { 0xc4253263, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0xc820001f, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0x18e82005, mmCP_DFY_DATA_0 }, - { 0x51e00020, mmCP_DFY_DATA_0 }, - { 0x2aa80000, mmCP_DFY_DATA_0 }, - { 0x7da1801a, mmCP_DFY_DATA_0 }, - { 0xd1800072, mmCP_DFY_DATA_0 }, - { 0xc8180072, mmCP_DFY_DATA_0 }, - { 0x59a001fc, mmCP_DFY_DATA_0 }, - { 0x12200009, mmCP_DFY_DATA_0 }, - { 0x7ea2800a, mmCP_DFY_DATA_0 }, - { 0xce80001c, mmCP_DFY_DATA_0 }, - { 0xd180001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8200011, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0x15980002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd81c400, mmCP_DFY_DATA_0 }, - { 0xc421c401, mmCP_DFY_DATA_0 }, - { 0x95400041, mmCP_DFY_DATA_0 }, - { 0xc425c401, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0x80000ee6, mmCP_DFY_DATA_0 }, - { 0x31ac2580, mmCP_DFY_DATA_0 }, - { 0x9ac00011, mmCP_DFY_DATA_0 }, - { 0x31ac260c, mmCP_DFY_DATA_0 }, - { 0x9ac0000f, mmCP_DFY_DATA_0 }, - { 0x31ac0800, mmCP_DFY_DATA_0 }, - { 0x9ac0000d, mmCP_DFY_DATA_0 }, - { 0x31ac0828, mmCP_DFY_DATA_0 }, - { 0x9ac0000b, mmCP_DFY_DATA_0 }, - { 0x31ac2440, mmCP_DFY_DATA_0 }, - { 0x9ac00009, mmCP_DFY_DATA_0 }, - { 0x31ac2390, mmCP_DFY_DATA_0 }, - { 0x9ac00007, mmCP_DFY_DATA_0 }, - { 0x31ac0093, mmCP_DFY_DATA_0 }, - { 0x9ac00005, mmCP_DFY_DATA_0 }, - { 0x31ac31dc, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x31ac31e6, mmCP_DFY_DATA_0 }, - { 0x96c00004, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x80000ede, mmCP_DFY_DATA_0 }, - { 0x39ac7c06, mmCP_DFY_DATA_0 }, - { 0x3db07c00, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39acc337, mmCP_DFY_DATA_0 }, - { 0x3db0c330, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39acc335, mmCP_DFY_DATA_0 }, - { 0x3db0c336, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39ac9002, mmCP_DFY_DATA_0 }, - { 0x3db09001, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39ac9012, mmCP_DFY_DATA_0 }, - { 0x3db09011, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0x39acec70, mmCP_DFY_DATA_0 }, - { 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000ebc, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc5a10000, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0x05980001, mmCP_DFY_DATA_0 }, - { 0xc5a50000, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e26001a, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x05280eea, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000ef1, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x80000efe, mmCP_DFY_DATA_0 }, - { 0x80000f11, mmCP_DFY_DATA_0 }, - { 0x80000f2e, mmCP_DFY_DATA_0 }, - { 0x80000efe, mmCP_DFY_DATA_0 }, - { 0x80000f1f, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0x05980001, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x97c0f26f, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x51ec0020, mmCP_DFY_DATA_0 }, - { 0x18e80058, mmCP_DFY_DATA_0 }, - { 0x7daec01a, mmCP_DFY_DATA_0 }, - { 0xd2c00072, mmCP_DFY_DATA_0 }, - { 0xc82c0072, mmCP_DFY_DATA_0 }, - { 0x5af8073a, mmCP_DFY_DATA_0 }, - { 0x7eba800a, mmCP_DFY_DATA_0 }, - { 0xd2c00025, mmCP_DFY_DATA_0 }, - { 0xce800024, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0x95400003, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x97c0f25c, mmCP_DFY_DATA_0 }, - { 0xc4380012, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc02a0001, mmCP_DFY_DATA_0 }, - { 0x2aa80001, mmCP_DFY_DATA_0 }, - { 0x15980002, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xcd81c405, mmCP_DFY_DATA_0 }, - { 0xce01c406, mmCP_DFY_DATA_0 }, - { 0x95400003, mmCP_DFY_DATA_0 }, - { 0x56240020, mmCP_DFY_DATA_0 }, - { 0xce41c406, mmCP_DFY_DATA_0 }, - { 0x97c0f24e, mmCP_DFY_DATA_0 }, - { 0xc439c409, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424000b, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9a40f247, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0x95400004, mmCP_DFY_DATA_0 }, - { 0x05980001, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce190000, mmCP_DFY_DATA_0 }, - { 0x97c0f240, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc439c040, mmCP_DFY_DATA_0 }, - { 0x97800001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x31ac2580, mmCP_DFY_DATA_0 }, - { 0x9ac00011, mmCP_DFY_DATA_0 }, - { 0x31ac260c, mmCP_DFY_DATA_0 }, - { 0x9ac0000f, mmCP_DFY_DATA_0 }, - { 0x31ac0800, mmCP_DFY_DATA_0 }, - { 0x9ac0000d, mmCP_DFY_DATA_0 }, - { 0x31ac0828, mmCP_DFY_DATA_0 }, - { 0x9ac0000b, mmCP_DFY_DATA_0 }, - { 0x31ac2440, mmCP_DFY_DATA_0 }, - { 0x9ac00009, mmCP_DFY_DATA_0 }, - { 0x31ac2390, mmCP_DFY_DATA_0 }, - { 0x9ac00007, mmCP_DFY_DATA_0 }, - { 0x31ac0093, mmCP_DFY_DATA_0 }, - { 0x9ac00005, mmCP_DFY_DATA_0 }, - { 0x31ac31dc, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x31ac31e6, mmCP_DFY_DATA_0 }, - { 0x96c00004, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0x80000ef2, mmCP_DFY_DATA_0 }, - { 0x39ac7c06, mmCP_DFY_DATA_0 }, - { 0x3db07c00, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39acc337, mmCP_DFY_DATA_0 }, - { 0x3db0c330, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39acc335, mmCP_DFY_DATA_0 }, - { 0x3db0c336, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39acec70, mmCP_DFY_DATA_0 }, - { 0x3db0ec6f, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39ac9002, mmCP_DFY_DATA_0 }, - { 0x3db09002, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x39ac9012, mmCP_DFY_DATA_0 }, - { 0x3db09012, mmCP_DFY_DATA_0 }, - { 0x9ac00003, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x80000f40, mmCP_DFY_DATA_0 }, - { 0x80000ef1, mmCP_DFY_DATA_0 }, - { 0xc40c0006, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x95c00001, mmCP_DFY_DATA_0 }, - { 0xc434000e, mmCP_DFY_DATA_0 }, - { 0x2b740008, mmCP_DFY_DATA_0 }, - { 0x2b780001, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xd8c1325e, mmCP_DFY_DATA_0 }, - { 0xcf80001a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x7c034001, mmCP_DFY_DATA_0 }, - { 0x7c038001, mmCP_DFY_DATA_0 }, - { 0x18e0007d, mmCP_DFY_DATA_0 }, - { 0x32240003, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0x32240000, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xcd01c080, mmCP_DFY_DATA_0 }, - { 0xcd41c081, mmCP_DFY_DATA_0 }, - { 0x80000f88, mmCP_DFY_DATA_0 }, - { 0x51640020, mmCP_DFY_DATA_0 }, - { 0x7e52401a, mmCP_DFY_DATA_0 }, - { 0xd2400072, mmCP_DFY_DATA_0 }, - { 0xc8280072, mmCP_DFY_DATA_0 }, - { 0xce81c080, mmCP_DFY_DATA_0 }, - { 0x56ac0020, mmCP_DFY_DATA_0 }, - { 0x26f0ffff, mmCP_DFY_DATA_0 }, - { 0xcf01c081, mmCP_DFY_DATA_0 }, - { 0x1af000fc, mmCP_DFY_DATA_0 }, - { 0x1334000a, mmCP_DFY_DATA_0 }, - { 0x24e02000, mmCP_DFY_DATA_0 }, - { 0x7f63400a, mmCP_DFY_DATA_0 }, - { 0x18e00074, mmCP_DFY_DATA_0 }, - { 0x32240003, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0x32240000, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0xcd81c082, mmCP_DFY_DATA_0 }, - { 0xcdc1c083, mmCP_DFY_DATA_0 }, - { 0x80000f9d, mmCP_DFY_DATA_0 }, - { 0x51e40020, mmCP_DFY_DATA_0 }, - { 0x7e5a401a, mmCP_DFY_DATA_0 }, - { 0xd2400072, mmCP_DFY_DATA_0 }, - { 0xc8280072, mmCP_DFY_DATA_0 }, - { 0xce81c082, mmCP_DFY_DATA_0 }, - { 0x56ac0020, mmCP_DFY_DATA_0 }, - { 0x26f0ffff, mmCP_DFY_DATA_0 }, - { 0xcf01c083, mmCP_DFY_DATA_0 }, - { 0x1af000fc, mmCP_DFY_DATA_0 }, - { 0x13380016, mmCP_DFY_DATA_0 }, - { 0x18e00039, mmCP_DFY_DATA_0 }, - { 0x12200019, mmCP_DFY_DATA_0 }, - { 0x7fa3800a, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x18e0007d, mmCP_DFY_DATA_0 }, - { 0x1220001d, mmCP_DFY_DATA_0 }, - { 0x7fa3800a, mmCP_DFY_DATA_0 }, - { 0x18e00074, mmCP_DFY_DATA_0 }, - { 0x12200014, mmCP_DFY_DATA_0 }, - { 0x7fa3800a, mmCP_DFY_DATA_0 }, - { 0xcf81c078, mmCP_DFY_DATA_0 }, - { 0xcfc1c084, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18dc003d, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0x041c0000, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x18d001e8, mmCP_DFY_DATA_0 }, - { 0x31140005, mmCP_DFY_DATA_0 }, - { 0x99400003, mmCP_DFY_DATA_0 }, - { 0x31140006, mmCP_DFY_DATA_0 }, - { 0x95400002, mmCP_DFY_DATA_0 }, - { 0x8c00104f, mmCP_DFY_DATA_0 }, - { 0x05280fb7, mmCP_DFY_DATA_0 }, - { 0x28140002, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000fbe, mmCP_DFY_DATA_0 }, - { 0x80000fbe, mmCP_DFY_DATA_0 }, - { 0x80000fc2, mmCP_DFY_DATA_0 }, - { 0x80000fbe, mmCP_DFY_DATA_0 }, - { 0x80000fd1, mmCP_DFY_DATA_0 }, - { 0x80000ff2, mmCP_DFY_DATA_0 }, - { 0x80000ff2, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x18e80039, mmCP_DFY_DATA_0 }, - { 0x52a8003b, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x7d69401a, mmCP_DFY_DATA_0 }, - { 0xc41c0017, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xd140004b, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc414000d, mmCP_DFY_DATA_0 }, - { 0x04180001, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0x7d958004, mmCP_DFY_DATA_0 }, - { 0xcd800035, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3249, mmCP_DFY_DATA_0 }, - { 0x1bfc003e, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd8400074, mmCP_DFY_DATA_0 }, - { 0xc4100019, mmCP_DFY_DATA_0 }, - { 0x7d150005, mmCP_DFY_DATA_0 }, - { 0x25100001, mmCP_DFY_DATA_0 }, - { 0x9500000b, mmCP_DFY_DATA_0 }, - { 0x97c0fffc, mmCP_DFY_DATA_0 }, - { 0xc4180021, mmCP_DFY_DATA_0 }, - { 0x159c0011, mmCP_DFY_DATA_0 }, - { 0x259800ff, mmCP_DFY_DATA_0 }, - { 0x31a00003, mmCP_DFY_DATA_0 }, - { 0x31a40001, mmCP_DFY_DATA_0 }, - { 0x7e25800a, mmCP_DFY_DATA_0 }, - { 0x95c0fff5, mmCP_DFY_DATA_0 }, - { 0x9580fff4, mmCP_DFY_DATA_0 }, - { 0x80000fef, mmCP_DFY_DATA_0 }, - { 0xc411326f, mmCP_DFY_DATA_0 }, - { 0x1d100010, mmCP_DFY_DATA_0 }, - { 0xcd01326f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd8000074, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x04380000, mmCP_DFY_DATA_0 }, - { 0xc430000d, mmCP_DFY_DATA_0 }, - { 0xc8140023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0xc011000f, mmCP_DFY_DATA_0 }, - { 0xc4240004, mmCP_DFY_DATA_0 }, - { 0x33b40003, mmCP_DFY_DATA_0 }, - { 0x97400003, mmCP_DFY_DATA_0 }, - { 0xc0340008, mmCP_DFY_DATA_0 }, - { 0x80000ffe, mmCP_DFY_DATA_0 }, - { 0xc4340035, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x7c908009, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x7d614011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7ca4800a, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x7cb0800a, mmCP_DFY_DATA_0 }, - { 0x282c2002, mmCP_DFY_DATA_0 }, - { 0x208801a8, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0x7cb4800a, mmCP_DFY_DATA_0 }, - { 0xcec00013, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x042c0008, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x20240030, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0x9b800013, mmCP_DFY_DATA_0 }, - { 0xcc400026, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x28340000, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x507c0020, mmCP_DFY_DATA_0 }, - { 0x7d7d401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x557c0020, mmCP_DFY_DATA_0 }, - { 0x28342002, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcd400026, mmCP_DFY_DATA_0 }, - { 0xcfc00026, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0x9a80000e, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a80000b, mmCP_DFY_DATA_0 }, - { 0x8000102f, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x9a800005, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x1cccfe08, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcec0003a, mmCP_DFY_DATA_0 }, - { 0xccc1a2a4, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3249, mmCP_DFY_DATA_0 }, - { 0x1bfc003e, mmCP_DFY_DATA_0 }, - { 0x9bc00007, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x16a80008, mmCP_DFY_DATA_0 }, - { 0xce800009, mmCP_DFY_DATA_0 }, - { 0xc42c005e, mmCP_DFY_DATA_0 }, - { 0x96c00b33, mmCP_DFY_DATA_0 }, - { 0xd840003c, mmCP_DFY_DATA_0 }, - { 0xc4200025, mmCP_DFY_DATA_0 }, - { 0x7da2400f, mmCP_DFY_DATA_0 }, - { 0x7da28002, mmCP_DFY_DATA_0 }, - { 0x7e1ac002, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0x7d2ac002, mmCP_DFY_DATA_0 }, - { 0x3ef40010, mmCP_DFY_DATA_0 }, - { 0x9b40f11d, mmCP_DFY_DATA_0 }, - { 0x04380030, mmCP_DFY_DATA_0 }, - { 0xcf81325e, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xde410000, mmCP_DFY_DATA_0 }, - { 0xdcc10000, mmCP_DFY_DATA_0 }, - { 0xdd010000, mmCP_DFY_DATA_0 }, - { 0xdd410000, mmCP_DFY_DATA_0 }, - { 0xdd810000, mmCP_DFY_DATA_0 }, - { 0xddc10000, mmCP_DFY_DATA_0 }, - { 0xde010000, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x7c024001, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc8100086, mmCP_DFY_DATA_0 }, - { 0x5510003f, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x98c00003, mmCP_DFY_DATA_0 }, - { 0x99000011, mmCP_DFY_DATA_0 }, - { 0x80001075, mmCP_DFY_DATA_0 }, - { 0x9900000c, mmCP_DFY_DATA_0 }, - { 0xc40c0026, mmCP_DFY_DATA_0 }, - { 0xc4100081, mmCP_DFY_DATA_0 }, - { 0xc4140025, mmCP_DFY_DATA_0 }, - { 0x7d15800f, mmCP_DFY_DATA_0 }, - { 0x7d15c002, mmCP_DFY_DATA_0 }, - { 0x7d520002, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x7cde0002, mmCP_DFY_DATA_0 }, - { 0x3e20001a, mmCP_DFY_DATA_0 }, - { 0x9a000009, mmCP_DFY_DATA_0 }, - { 0x040c0030, mmCP_DFY_DATA_0 }, - { 0xccc1325e, mmCP_DFY_DATA_0 }, - { 0x80001071, mmCP_DFY_DATA_0 }, - { 0xd9c00036, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c00b01, mmCP_DFY_DATA_0 }, - { 0x04240001, mmCP_DFY_DATA_0 }, - { 0xdc200000, mmCP_DFY_DATA_0 }, - { 0xdc1c0000, mmCP_DFY_DATA_0 }, - { 0xdc180000, mmCP_DFY_DATA_0 }, - { 0xdc140000, mmCP_DFY_DATA_0 }, - { 0xdc100000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0x96400004, mmCP_DFY_DATA_0 }, - { 0xdc240000, mmCP_DFY_DATA_0 }, - { 0xdc0c0000, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xdc240000, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xcc40003f, mmCP_DFY_DATA_0 }, - { 0xd8c00010, mmCP_DFY_DATA_0 }, - { 0xc4080029, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x18a400e5, mmCP_DFY_DATA_0 }, - { 0x12500009, mmCP_DFY_DATA_0 }, - { 0x248c0008, mmCP_DFY_DATA_0 }, - { 0x94c00006, mmCP_DFY_DATA_0 }, - { 0x200c006d, mmCP_DFY_DATA_0 }, - { 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { 0xccc1326c, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x200c0228, mmCP_DFY_DATA_0 }, - { 0x7cd0c00a, mmCP_DFY_DATA_0 }, - { 0xccc1326c, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0xc40c002a, mmCP_DFY_DATA_0 }, - { 0xc410002b, mmCP_DFY_DATA_0 }, - { 0x18881fe8, mmCP_DFY_DATA_0 }, - { 0x18d4072c, mmCP_DFY_DATA_0 }, - { 0x18cc00d1, mmCP_DFY_DATA_0 }, - { 0x7cd4c00a, mmCP_DFY_DATA_0 }, - { 0x3094000d, mmCP_DFY_DATA_0 }, - { 0x38d80000, mmCP_DFY_DATA_0 }, - { 0x311c0003, mmCP_DFY_DATA_0 }, - { 0x99400006, mmCP_DFY_DATA_0 }, - { 0x30940007, mmCP_DFY_DATA_0 }, - { 0x1620001f, mmCP_DFY_DATA_0 }, - { 0x9940001d, mmCP_DFY_DATA_0 }, - { 0x9a000023, mmCP_DFY_DATA_0 }, - { 0x800010c4, mmCP_DFY_DATA_0 }, - { 0x9580001a, mmCP_DFY_DATA_0 }, - { 0x99c00019, mmCP_DFY_DATA_0 }, - { 0xccc00041, mmCP_DFY_DATA_0 }, - { 0x25140001, mmCP_DFY_DATA_0 }, - { 0xc418002c, mmCP_DFY_DATA_0 }, - { 0x9940000d, mmCP_DFY_DATA_0 }, - { 0x259c007f, mmCP_DFY_DATA_0 }, - { 0x95c00013, mmCP_DFY_DATA_0 }, - { 0x19a00030, mmCP_DFY_DATA_0 }, - { 0xcdc0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xd8400022, mmCP_DFY_DATA_0 }, - { 0xc430000f, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x9a000012, mmCP_DFY_DATA_0 }, - { 0xd8400023, mmCP_DFY_DATA_0 }, - { 0x800010cb, mmCP_DFY_DATA_0 }, - { 0x199c0fe8, mmCP_DFY_DATA_0 }, - { 0xcdc0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xd8400023, mmCP_DFY_DATA_0 }, - { 0xc430000f, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x800010cb, mmCP_DFY_DATA_0 }, - { 0xd8c00010, mmCP_DFY_DATA_0 }, - { 0xd8000022, mmCP_DFY_DATA_0 }, - { 0xd8000023, mmCP_DFY_DATA_0 }, - { 0xc430005e, mmCP_DFY_DATA_0 }, - { 0x97000aac, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0xc434002e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0x2020002c, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0xce01326c, mmCP_DFY_DATA_0 }, - { 0x17780001, mmCP_DFY_DATA_0 }, - { 0x27740001, mmCP_DFY_DATA_0 }, - { 0x07a810d8, mmCP_DFY_DATA_0 }, - { 0xcf400010, mmCP_DFY_DATA_0 }, - { 0xc421326c, mmCP_DFY_DATA_0 }, - { 0x96000001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0x80000bfc, mmCP_DFY_DATA_0 }, - { 0x800012e9, mmCP_DFY_DATA_0 }, - { 0x8000104c, mmCP_DFY_DATA_0 }, - { 0xcc400040, mmCP_DFY_DATA_0 }, - { 0xd8800010, mmCP_DFY_DATA_0 }, - { 0xc4180032, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0x200c007d, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325b, mmCP_DFY_DATA_0 }, - { 0x95000001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x28240007, mmCP_DFY_DATA_0 }, - { 0xde430000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0x24b00008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc40d3249, mmCP_DFY_DATA_0 }, - { 0x18cc003e, mmCP_DFY_DATA_0 }, - { 0x98c00002, mmCP_DFY_DATA_0 }, - { 0xd840003d, mmCP_DFY_DATA_0 }, - { 0x2b304000, mmCP_DFY_DATA_0 }, - { 0xcf01326c, mmCP_DFY_DATA_0 }, - { 0xc431326c, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x192400fd, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x06681110, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0x18ac0024, mmCP_DFY_DATA_0 }, - { 0x19180070, mmCP_DFY_DATA_0 }, - { 0x19100078, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x18f40058, mmCP_DFY_DATA_0 }, - { 0x5978073a, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80001117, mmCP_DFY_DATA_0 }, - { 0x80001118, mmCP_DFY_DATA_0 }, - { 0x80001122, mmCP_DFY_DATA_0 }, - { 0x8000112d, mmCP_DFY_DATA_0 }, - { 0x80001130, mmCP_DFY_DATA_0 }, - { 0x80001133, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000117b, mmCP_DFY_DATA_0 }, - { 0x24ec0f00, mmCP_DFY_DATA_0 }, - { 0x32ec0600, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xc4300006, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x8000117b, mmCP_DFY_DATA_0 }, - { 0x24ec0f00, mmCP_DFY_DATA_0 }, - { 0x32ec0600, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xc4300006, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x8000117b, mmCP_DFY_DATA_0 }, - { 0xc81c001f, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0x80001122, mmCP_DFY_DATA_0 }, - { 0xc81c0020, mmCP_DFY_DATA_0 }, - { 0x55e00020, mmCP_DFY_DATA_0 }, - { 0x80001122, mmCP_DFY_DATA_0 }, - { 0x8c00116b, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc02a0200, mmCP_DFY_DATA_0 }, - { 0x7e8e8009, mmCP_DFY_DATA_0 }, - { 0x22a8003d, mmCP_DFY_DATA_0 }, - { 0x22a80074, mmCP_DFY_DATA_0 }, - { 0x2774001c, mmCP_DFY_DATA_0 }, - { 0x13740014, mmCP_DFY_DATA_0 }, - { 0x7eb6800a, mmCP_DFY_DATA_0 }, - { 0x25ecffff, mmCP_DFY_DATA_0 }, - { 0x55700020, mmCP_DFY_DATA_0 }, - { 0x15f40010, mmCP_DFY_DATA_0 }, - { 0x13740002, mmCP_DFY_DATA_0 }, - { 0x275c001f, mmCP_DFY_DATA_0 }, - { 0x95c00027, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0x7f41c001, mmCP_DFY_DATA_0 }, - { 0x15dc0002, mmCP_DFY_DATA_0 }, - { 0x39e00008, mmCP_DFY_DATA_0 }, - { 0x25dc0007, mmCP_DFY_DATA_0 }, - { 0x7dc1c01e, mmCP_DFY_DATA_0 }, - { 0x05dc0001, mmCP_DFY_DATA_0 }, - { 0x96000004, mmCP_DFY_DATA_0 }, - { 0x05e40008, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001168, mmCP_DFY_DATA_0 }, - { 0x7dc2001e, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x05e40008, mmCP_DFY_DATA_0 }, - { 0x7e62000e, mmCP_DFY_DATA_0 }, - { 0x9a000004, mmCP_DFY_DATA_0 }, - { 0x7da58001, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001165, mmCP_DFY_DATA_0 }, - { 0x7dc2001e, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x7e1a0001, mmCP_DFY_DATA_0 }, - { 0x05cc0008, mmCP_DFY_DATA_0 }, - { 0x7e0d000e, mmCP_DFY_DATA_0 }, - { 0x95000007, mmCP_DFY_DATA_0 }, - { 0x7e02401e, mmCP_DFY_DATA_0 }, - { 0x06640001, mmCP_DFY_DATA_0 }, - { 0x06640008, mmCP_DFY_DATA_0 }, - { 0x05d80008, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001168, mmCP_DFY_DATA_0 }, - { 0x7dc2401e, mmCP_DFY_DATA_0 }, - { 0x06640001, mmCP_DFY_DATA_0 }, - { 0x7da58001, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x05e00008, mmCP_DFY_DATA_0 }, - { 0x7da2000c, mmCP_DFY_DATA_0 }, - { 0x9600ffe6, mmCP_DFY_DATA_0 }, - { 0x17640002, mmCP_DFY_DATA_0 }, - { 0x8c00116e, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xc4200006, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x8c00116b, mmCP_DFY_DATA_0 }, - { 0xc420000e, mmCP_DFY_DATA_0 }, - { 0x2a200001, mmCP_DFY_DATA_0 }, - { 0xce00001a, mmCP_DFY_DATA_0 }, - { 0xce81c078, mmCP_DFY_DATA_0 }, - { 0xcec1c080, mmCP_DFY_DATA_0 }, - { 0xcc01c081, mmCP_DFY_DATA_0 }, - { 0xcd41c082, mmCP_DFY_DATA_0 }, - { 0xcf01c083, mmCP_DFY_DATA_0 }, - { 0x12640002, mmCP_DFY_DATA_0 }, - { 0x22640435, mmCP_DFY_DATA_0 }, - { 0xce41c084, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x0528117e, mmCP_DFY_DATA_0 }, - { 0x312c0003, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x80001185, mmCP_DFY_DATA_0 }, - { 0x80001182, mmCP_DFY_DATA_0 }, - { 0x80001182, mmCP_DFY_DATA_0 }, - { 0xc4300012, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0x9ac0000c, mmCP_DFY_DATA_0 }, - { 0xc03a0400, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x15980008, mmCP_DFY_DATA_0 }, - { 0x1198001c, mmCP_DFY_DATA_0 }, - { 0x7d81c00a, mmCP_DFY_DATA_0 }, - { 0xcdc130b7, mmCP_DFY_DATA_0 }, - { 0xcf8130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x04240008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0xc41c0049, mmCP_DFY_DATA_0 }, - { 0x19a000e8, mmCP_DFY_DATA_0 }, - { 0x29a80008, mmCP_DFY_DATA_0 }, - { 0x7de2c00c, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xc421325e, mmCP_DFY_DATA_0 }, - { 0x26200010, mmCP_DFY_DATA_0 }, - { 0xc415326d, mmCP_DFY_DATA_0 }, - { 0x9a000006, mmCP_DFY_DATA_0 }, - { 0xc420007d, mmCP_DFY_DATA_0 }, - { 0x96000004, mmCP_DFY_DATA_0 }, - { 0x96c00003, mmCP_DFY_DATA_0 }, - { 0xce40003e, mmCP_DFY_DATA_0 }, - { 0x800011a3, mmCP_DFY_DATA_0 }, - { 0x7d654001, mmCP_DFY_DATA_0 }, - { 0xcd41326d, mmCP_DFY_DATA_0 }, - { 0x7c020001, mmCP_DFY_DATA_0 }, - { 0x96000005, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0xc4240081, mmCP_DFY_DATA_0 }, - { 0xc4140025, mmCP_DFY_DATA_0 }, - { 0x800011b6, mmCP_DFY_DATA_0 }, - { 0xc4253279, mmCP_DFY_DATA_0 }, - { 0xc415326d, mmCP_DFY_DATA_0 }, - { 0xc431326c, mmCP_DFY_DATA_0 }, - { 0x2730003f, mmCP_DFY_DATA_0 }, - { 0x3b380006, mmCP_DFY_DATA_0 }, - { 0x97800004, mmCP_DFY_DATA_0 }, - { 0x3f38000b, mmCP_DFY_DATA_0 }, - { 0x9b800004, mmCP_DFY_DATA_0 }, - { 0x800011b4, mmCP_DFY_DATA_0 }, - { 0x04300006, mmCP_DFY_DATA_0 }, - { 0x800011b4, mmCP_DFY_DATA_0 }, - { 0x0430000b, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x7fb10004, mmCP_DFY_DATA_0 }, - { 0x7e57000f, mmCP_DFY_DATA_0 }, - { 0x7e578002, mmCP_DFY_DATA_0 }, - { 0x7d67c002, mmCP_DFY_DATA_0 }, - { 0x0be40001, mmCP_DFY_DATA_0 }, - { 0x97000002, mmCP_DFY_DATA_0 }, - { 0x7d3a4002, mmCP_DFY_DATA_0 }, - { 0x202c002c, mmCP_DFY_DATA_0 }, - { 0xc421325e, mmCP_DFY_DATA_0 }, - { 0x04280020, mmCP_DFY_DATA_0 }, - { 0xcec1326c, mmCP_DFY_DATA_0 }, - { 0x26200010, mmCP_DFY_DATA_0 }, - { 0x3e640010, mmCP_DFY_DATA_0 }, - { 0x96000003, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0xce81325e, mmCP_DFY_DATA_0 }, - { 0xc4300028, mmCP_DFY_DATA_0 }, - { 0xc434002e, mmCP_DFY_DATA_0 }, - { 0x17780001, mmCP_DFY_DATA_0 }, - { 0x27740001, mmCP_DFY_DATA_0 }, - { 0x07a811cf, mmCP_DFY_DATA_0 }, - { 0x9b00feb8, mmCP_DFY_DATA_0 }, - { 0xcf400010, mmCP_DFY_DATA_0 }, - { 0xc414005e, mmCP_DFY_DATA_0 }, - { 0x954009a7, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0x80000bfc, mmCP_DFY_DATA_0 }, - { 0x800012e9, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0xccc1c07c, mmCP_DFY_DATA_0 }, - { 0xcc41c07d, mmCP_DFY_DATA_0 }, - { 0xcc41c08c, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xcc41c079, mmCP_DFY_DATA_0 }, - { 0xcd01c07e, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x18f0012f, mmCP_DFY_DATA_0 }, - { 0x18f40612, mmCP_DFY_DATA_0 }, - { 0x18cc00c1, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x7cf7400a, mmCP_DFY_DATA_0 }, - { 0x39600004, mmCP_DFY_DATA_0 }, - { 0x9a000002, mmCP_DFY_DATA_0 }, - { 0xc0140004, mmCP_DFY_DATA_0 }, - { 0x11600001, mmCP_DFY_DATA_0 }, - { 0x18fc003e, mmCP_DFY_DATA_0 }, - { 0x9740001c, mmCP_DFY_DATA_0 }, - { 0xcf400041, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0x97c00003, mmCP_DFY_DATA_0 }, - { 0x166c001f, mmCP_DFY_DATA_0 }, - { 0x800011ee, mmCP_DFY_DATA_0 }, - { 0x1a6c003e, mmCP_DFY_DATA_0 }, - { 0x96c00006, mmCP_DFY_DATA_0 }, - { 0x04200002, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x800011e8, mmCP_DFY_DATA_0 }, - { 0xc428002c, mmCP_DFY_DATA_0 }, - { 0x96800010, mmCP_DFY_DATA_0 }, - { 0x26ac007f, mmCP_DFY_DATA_0 }, - { 0xcec0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x1ab00030, mmCP_DFY_DATA_0 }, - { 0x1aac0fe8, mmCP_DFY_DATA_0 }, - { 0xc434000f, mmCP_DFY_DATA_0 }, - { 0x9b40ffff, mmCP_DFY_DATA_0 }, - { 0x97000008, mmCP_DFY_DATA_0 }, - { 0xcec0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc434000f, mmCP_DFY_DATA_0 }, - { 0x9b40ffff, mmCP_DFY_DATA_0 }, - { 0x80001205, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0x166c001f, mmCP_DFY_DATA_0 }, - { 0x11600001, mmCP_DFY_DATA_0 }, - { 0x9ac0fffa, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8000033, mmCP_DFY_DATA_0 }, - { 0xc438000b, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0001, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd841c07f, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x1bfc0078, mmCP_DFY_DATA_0 }, - { 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { 0x97c0fffd, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc03a2800, mmCP_DFY_DATA_0 }, - { 0xcf81c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04380040, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380060, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x17fc001f, mmCP_DFY_DATA_0 }, - { 0x04380010, mmCP_DFY_DATA_0 }, - { 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd801c07f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0xcfc00078, mmCP_DFY_DATA_0 }, - { 0xd8000034, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc03ae000, mmCP_DFY_DATA_0 }, - { 0xcf81c200, mmCP_DFY_DATA_0 }, - { 0xc03a0800, mmCP_DFY_DATA_0 }, - { 0xcf81c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04380040, mmCP_DFY_DATA_0 }, - { 0xcf80001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x17fc001f, mmCP_DFY_DATA_0 }, - { 0x04380010, mmCP_DFY_DATA_0 }, - { 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc03ae000, mmCP_DFY_DATA_0 }, - { 0xcf81c200, mmCP_DFY_DATA_0 }, - { 0xc03a4000, mmCP_DFY_DATA_0 }, - { 0xcf81c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04380002, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x17fc001f, mmCP_DFY_DATA_0 }, - { 0x04380010, mmCP_DFY_DATA_0 }, - { 0x9bc0fffa, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x30d00002, mmCP_DFY_DATA_0 }, - { 0x99000052, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x9640090f, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xc428000e, mmCP_DFY_DATA_0 }, - { 0x1514001f, mmCP_DFY_DATA_0 }, - { 0x19180038, mmCP_DFY_DATA_0 }, - { 0x2aa80008, mmCP_DFY_DATA_0 }, - { 0x99400030, mmCP_DFY_DATA_0 }, - { 0x30dc0001, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0x99c0000a, mmCP_DFY_DATA_0 }, - { 0xc42d324e, mmCP_DFY_DATA_0 }, - { 0xc431324d, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc435324f, mmCP_DFY_DATA_0 }, - { 0xc4293256, mmCP_DFY_DATA_0 }, - { 0x1ab0c006, mmCP_DFY_DATA_0 }, - { 0x52ec0008, mmCP_DFY_DATA_0 }, - { 0x8000127f, mmCP_DFY_DATA_0 }, - { 0xc42d3258, mmCP_DFY_DATA_0 }, - { 0xc4313257, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc4353259, mmCP_DFY_DATA_0 }, - { 0xc429325a, mmCP_DFY_DATA_0 }, - { 0x1ab0c012, mmCP_DFY_DATA_0 }, - { 0x07740001, mmCP_DFY_DATA_0 }, - { 0x04240002, mmCP_DFY_DATA_0 }, - { 0x26a0003f, mmCP_DFY_DATA_0 }, - { 0x7e624004, mmCP_DFY_DATA_0 }, - { 0x7f67800f, mmCP_DFY_DATA_0 }, - { 0x97800002, mmCP_DFY_DATA_0 }, - { 0x04340000, mmCP_DFY_DATA_0 }, - { 0x53740002, mmCP_DFY_DATA_0 }, - { 0x7ef6c011, mmCP_DFY_DATA_0 }, - { 0x1ab42010, mmCP_DFY_DATA_0 }, - { 0x16a8000c, mmCP_DFY_DATA_0 }, - { 0x26a80800, mmCP_DFY_DATA_0 }, - { 0x2b740000, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0x7f6b400a, mmCP_DFY_DATA_0 }, - { 0xcf40001c, mmCP_DFY_DATA_0 }, - { 0xd2c0001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc438000f, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xc4100011, mmCP_DFY_DATA_0 }, - { 0x1514001f, mmCP_DFY_DATA_0 }, - { 0x99400006, mmCP_DFY_DATA_0 }, - { 0x9980000a, mmCP_DFY_DATA_0 }, - { 0x8c0012e1, mmCP_DFY_DATA_0 }, - { 0xc40c0007, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0x80001267, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x964008d7, mmCP_DFY_DATA_0 }, - { 0xd9800036, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc42c001d, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0xc431325a, mmCP_DFY_DATA_0 }, - { 0x1b300677, mmCP_DFY_DATA_0 }, - { 0x11dc000c, mmCP_DFY_DATA_0 }, - { 0x800012aa, mmCP_DFY_DATA_0 }, - { 0xc4313256, mmCP_DFY_DATA_0 }, - { 0x1b34060b, mmCP_DFY_DATA_0 }, - { 0x1b300077, mmCP_DFY_DATA_0 }, - { 0x7f37000a, mmCP_DFY_DATA_0 }, - { 0x13300017, mmCP_DFY_DATA_0 }, - { 0x04340100, mmCP_DFY_DATA_0 }, - { 0x26ec00ff, mmCP_DFY_DATA_0 }, - { 0xc03a8002, mmCP_DFY_DATA_0 }, - { 0x7ef6c00a, mmCP_DFY_DATA_0 }, - { 0x7edec00a, mmCP_DFY_DATA_0 }, - { 0x7f3b000a, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0xcec1325b, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xc4140032, mmCP_DFY_DATA_0 }, - { 0xc410001d, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x1858003f, mmCP_DFY_DATA_0 }, - { 0x251000ff, mmCP_DFY_DATA_0 }, - { 0x99800007, mmCP_DFY_DATA_0 }, - { 0x7d0cc00a, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x18d0006c, mmCP_DFY_DATA_0 }, - { 0x18d407f0, mmCP_DFY_DATA_0 }, - { 0x9900000e, mmCP_DFY_DATA_0 }, - { 0x04100002, mmCP_DFY_DATA_0 }, - { 0xc4193256, mmCP_DFY_DATA_0 }, - { 0xc41d324f, mmCP_DFY_DATA_0 }, - { 0x2598003f, mmCP_DFY_DATA_0 }, - { 0x7d190004, mmCP_DFY_DATA_0 }, - { 0x7d5d4001, mmCP_DFY_DATA_0 }, - { 0x7d52000f, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0xcd41324f, mmCP_DFY_DATA_0 }, - { 0x800012d8, mmCP_DFY_DATA_0 }, - { 0x7d514002, mmCP_DFY_DATA_0 }, - { 0xcd41324f, mmCP_DFY_DATA_0 }, - { 0x800012d8, mmCP_DFY_DATA_0 }, - { 0xc4193259, mmCP_DFY_DATA_0 }, - { 0xc41d325a, mmCP_DFY_DATA_0 }, - { 0x7d958001, mmCP_DFY_DATA_0 }, - { 0x7dd5c002, mmCP_DFY_DATA_0 }, - { 0xcd813259, mmCP_DFY_DATA_0 }, - { 0xcdc1325a, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x1ccc001e, mmCP_DFY_DATA_0 }, - { 0xccc1325b, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x94c00001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c0021, mmCP_DFY_DATA_0 }, - { 0xc4340028, mmCP_DFY_DATA_0 }, - { 0x14f00010, mmCP_DFY_DATA_0 }, - { 0xc4380030, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x9b000004, mmCP_DFY_DATA_0 }, - { 0x9b40000c, mmCP_DFY_DATA_0 }, - { 0x9b80000f, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x17300001, mmCP_DFY_DATA_0 }, - { 0x9b000005, mmCP_DFY_DATA_0 }, - { 0xccc00037, mmCP_DFY_DATA_0 }, - { 0x8c000190, mmCP_DFY_DATA_0 }, - { 0xd8000032, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8000028, mmCP_DFY_DATA_0 }, - { 0xd800002b, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd980003f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd9c0003f, mmCP_DFY_DATA_0 }, - { 0x80001082, mmCP_DFY_DATA_0 }, - { 0xd9800040, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0xd9c00040, mmCP_DFY_DATA_0 }, - { 0x800010de, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0x33f80003, mmCP_DFY_DATA_0 }, - { 0x97800051, mmCP_DFY_DATA_0 }, - { 0xcc80003b, mmCP_DFY_DATA_0 }, - { 0x24b00008, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x18a800e5, mmCP_DFY_DATA_0 }, - { 0x1d980008, mmCP_DFY_DATA_0 }, - { 0x12a80008, mmCP_DFY_DATA_0 }, - { 0x7da9800a, mmCP_DFY_DATA_0 }, - { 0x29980008, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc4353249, mmCP_DFY_DATA_0 }, - { 0x1b74003e, mmCP_DFY_DATA_0 }, - { 0x9b400002, mmCP_DFY_DATA_0 }, - { 0xd840003d, mmCP_DFY_DATA_0 }, - { 0x2b304000, mmCP_DFY_DATA_0 }, - { 0xcf01326c, mmCP_DFY_DATA_0 }, - { 0xc431326c, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x50700020, mmCP_DFY_DATA_0 }, - { 0x04e81324, mmCP_DFY_DATA_0 }, - { 0x18ac0024, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x50600020, mmCP_DFY_DATA_0 }, - { 0xcc400078, mmCP_DFY_DATA_0 }, - { 0x30e40004, mmCP_DFY_DATA_0 }, - { 0x9a400007, mmCP_DFY_DATA_0 }, - { 0x7d71401a, mmCP_DFY_DATA_0 }, - { 0x596401fc, mmCP_DFY_DATA_0 }, - { 0x12640009, mmCP_DFY_DATA_0 }, - { 0x1b74008d, mmCP_DFY_DATA_0 }, - { 0x7e76400a, mmCP_DFY_DATA_0 }, - { 0x2a640000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x8000132c, mmCP_DFY_DATA_0 }, - { 0x8000133b, mmCP_DFY_DATA_0 }, - { 0x80001344, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc42530b5, mmCP_DFY_DATA_0 }, - { 0x1a68003a, mmCP_DFY_DATA_0 }, - { 0x9a80fffe, mmCP_DFY_DATA_0 }, - { 0x2024003a, mmCP_DFY_DATA_0 }, - { 0xc418000e, mmCP_DFY_DATA_0 }, - { 0x25980700, mmCP_DFY_DATA_0 }, - { 0x11980014, mmCP_DFY_DATA_0 }, - { 0x7d19000a, mmCP_DFY_DATA_0 }, - { 0xcd0130b7, mmCP_DFY_DATA_0 }, - { 0xce4130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xce40001c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc4240011, mmCP_DFY_DATA_0 }, - { 0x7de6800f, mmCP_DFY_DATA_0 }, - { 0x9a80ffea, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0xce40001c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc428000f, mmCP_DFY_DATA_0 }, - { 0x9a80ffff, mmCP_DFY_DATA_0 }, - { 0xc8240011, mmCP_DFY_DATA_0 }, - { 0x7de1c01a, mmCP_DFY_DATA_0 }, - { 0x7de6800f, mmCP_DFY_DATA_0 }, - { 0x9a80ffe0, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x8c00104f, mmCP_DFY_DATA_0 }, - { 0x28182002, mmCP_DFY_DATA_0 }, - { 0xc430000d, mmCP_DFY_DATA_0 }, - { 0xc4340035, mmCP_DFY_DATA_0 }, - { 0xcd800013, mmCP_DFY_DATA_0 }, - { 0xc8140023, mmCP_DFY_DATA_0 }, - { 0xc4180081, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0xc4240004, mmCP_DFY_DATA_0 }, - { 0x11a00002, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x7d614011, mmCP_DFY_DATA_0 }, - { 0xc4100026, mmCP_DFY_DATA_0 }, - { 0x05980008, mmCP_DFY_DATA_0 }, - { 0x7ca4800a, mmCP_DFY_DATA_0 }, - { 0x7d1a0002, mmCP_DFY_DATA_0 }, - { 0x7cb0800a, mmCP_DFY_DATA_0 }, - { 0x3e280008, mmCP_DFY_DATA_0 }, - { 0x7cb4800a, mmCP_DFY_DATA_0 }, - { 0xc4300027, mmCP_DFY_DATA_0 }, - { 0x042c0008, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xcf000024, mmCP_DFY_DATA_0 }, - { 0x20240030, mmCP_DFY_DATA_0 }, - { 0x7ca48001, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x1b4c00f8, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0xcc400026, mmCP_DFY_DATA_0 }, - { 0x28340000, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x507c0020, mmCP_DFY_DATA_0 }, - { 0x30e40004, mmCP_DFY_DATA_0 }, - { 0x9a400005, mmCP_DFY_DATA_0 }, - { 0x7d7d401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x557c0020, mmCP_DFY_DATA_0 }, - { 0x28342002, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcd400026, mmCP_DFY_DATA_0 }, - { 0xcfc00026, mmCP_DFY_DATA_0 }, - { 0xd4400026, mmCP_DFY_DATA_0 }, - { 0xcc000026, mmCP_DFY_DATA_0 }, - { 0x9a800005, mmCP_DFY_DATA_0 }, - { 0x32280000, mmCP_DFY_DATA_0 }, - { 0x9a800002, mmCP_DFY_DATA_0 }, - { 0x9a000000, mmCP_DFY_DATA_0 }, - { 0x7c018001, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0x04380028, mmCP_DFY_DATA_0 }, - { 0xcec0003a, mmCP_DFY_DATA_0 }, - { 0xcf81a2a4, mmCP_DFY_DATA_0 }, - { 0x80001037, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc40c005e, mmCP_DFY_DATA_0 }, - { 0x94c007eb, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50500020, mmCP_DFY_DATA_0 }, - { 0x7d0d001a, mmCP_DFY_DATA_0 }, - { 0xd1000072, mmCP_DFY_DATA_0 }, - { 0xc8100072, mmCP_DFY_DATA_0 }, - { 0x591c01fc, mmCP_DFY_DATA_0 }, - { 0x11dc0009, mmCP_DFY_DATA_0 }, - { 0x45140210, mmCP_DFY_DATA_0 }, - { 0x595801fc, mmCP_DFY_DATA_0 }, - { 0x11980009, mmCP_DFY_DATA_0 }, - { 0x29dc0000, mmCP_DFY_DATA_0 }, - { 0xcdc0001c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4200011, mmCP_DFY_DATA_0 }, - { 0x1624001f, mmCP_DFY_DATA_0 }, - { 0x96400069, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xce013249, mmCP_DFY_DATA_0 }, - { 0x1a307fe8, mmCP_DFY_DATA_0 }, - { 0xcf00000a, mmCP_DFY_DATA_0 }, - { 0x23304076, mmCP_DFY_DATA_0 }, - { 0xd1000001, mmCP_DFY_DATA_0 }, - { 0xcf000001, mmCP_DFY_DATA_0 }, - { 0xc41d3254, mmCP_DFY_DATA_0 }, - { 0xc4253256, mmCP_DFY_DATA_0 }, - { 0x18cc00e8, mmCP_DFY_DATA_0 }, - { 0x10cc0015, mmCP_DFY_DATA_0 }, - { 0x4514020c, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc4200011, mmCP_DFY_DATA_0 }, - { 0xce013248, mmCP_DFY_DATA_0 }, - { 0x1a2001e8, mmCP_DFY_DATA_0 }, - { 0x12200014, mmCP_DFY_DATA_0 }, - { 0x2a204001, mmCP_DFY_DATA_0 }, - { 0xce000013, mmCP_DFY_DATA_0 }, - { 0x1a64003c, mmCP_DFY_DATA_0 }, - { 0x1264001f, mmCP_DFY_DATA_0 }, - { 0x11dc0009, mmCP_DFY_DATA_0 }, - { 0x15dc000b, mmCP_DFY_DATA_0 }, - { 0x7dcdc00a, mmCP_DFY_DATA_0 }, - { 0x7e5dc00a, mmCP_DFY_DATA_0 }, - { 0xcdc00100, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xd8400010, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcf00000d, mmCP_DFY_DATA_0 }, - { 0xcf00000a, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x04340022, mmCP_DFY_DATA_0 }, - { 0x07740001, mmCP_DFY_DATA_0 }, - { 0x04300010, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0xd4412e01, mmCP_DFY_DATA_0 }, - { 0x0434001e, mmCP_DFY_DATA_0 }, - { 0xdf430000, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xdf030000, mmCP_DFY_DATA_0 }, - { 0xd4412e40, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc41c030, mmCP_DFY_DATA_0 }, - { 0xcc41c031, mmCP_DFY_DATA_0 }, - { 0x248dfffe, mmCP_DFY_DATA_0 }, - { 0xccc12e00, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xcc812e00, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xd8000010, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x45140248, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc8200011, mmCP_DFY_DATA_0 }, - { 0xce013257, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xce013258, mmCP_DFY_DATA_0 }, - { 0x0434000c, mmCP_DFY_DATA_0 }, - { 0xdb000024, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x45540008, mmCP_DFY_DATA_0 }, - { 0xd140001e, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc418000f, mmCP_DFY_DATA_0 }, - { 0x9980ffff, mmCP_DFY_DATA_0 }, - { 0xc8200011, mmCP_DFY_DATA_0 }, - { 0xce013259, mmCP_DFY_DATA_0 }, - { 0x56200020, mmCP_DFY_DATA_0 }, - { 0xc0337fff, mmCP_DFY_DATA_0 }, - { 0x7f220009, mmCP_DFY_DATA_0 }, - { 0xce01325a, mmCP_DFY_DATA_0 }, - { 0x55300020, mmCP_DFY_DATA_0 }, - { 0x7d01c001, mmCP_DFY_DATA_0 }, - { 0x042c01d0, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x06ec0004, mmCP_DFY_DATA_0 }, - { 0x7f01c001, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0x041c0002, mmCP_DFY_DATA_0 }, - { 0x042c01c8, mmCP_DFY_DATA_0 }, - { 0x8c000d61, mmCP_DFY_DATA_0 }, - { 0xc4380012, mmCP_DFY_DATA_0 }, - { 0x9b80ffff, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x50500020, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0x7cd0c01a, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xd0c00072, mmCP_DFY_DATA_0 }, - { 0xc8240072, mmCP_DFY_DATA_0 }, - { 0xd240001e, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x19682011, mmCP_DFY_DATA_0 }, - { 0x5a6c01fc, mmCP_DFY_DATA_0 }, - { 0x12ec0009, mmCP_DFY_DATA_0 }, - { 0x7eeac00a, mmCP_DFY_DATA_0 }, - { 0x2aec0000, mmCP_DFY_DATA_0 }, - { 0xcec0001c, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc430000f, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0xc4180011, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x99800007, mmCP_DFY_DATA_0 }, - { 0xdf830000, mmCP_DFY_DATA_0 }, - { 0xcfa0000c, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xd8000012, mmCP_DFY_DATA_0 }, - { 0xc43c0008, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd8400012, mmCP_DFY_DATA_0 }, - { 0xc43c0008, mmCP_DFY_DATA_0 }, - { 0x97c0ffff, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4380007, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x17b80001, mmCP_DFY_DATA_0 }, - { 0x18d40038, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x9b800004, mmCP_DFY_DATA_0 }, - { 0xd8400029, mmCP_DFY_DATA_0 }, - { 0xc414005e, mmCP_DFY_DATA_0 }, - { 0x9540073d, mmCP_DFY_DATA_0 }, - { 0x18c80066, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x30880001, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x94800008, mmCP_DFY_DATA_0 }, - { 0x8c00187c, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc42c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd910000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x7d410001, mmCP_DFY_DATA_0 }, - { 0x043c0000, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0x04240001, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x4220000c, mmCP_DFY_DATA_0 }, - { 0x0a640001, mmCP_DFY_DATA_0 }, - { 0xcc000078, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x24e80007, mmCP_DFY_DATA_0 }, - { 0x24ec0010, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x9ac00006, mmCP_DFY_DATA_0 }, - { 0xc42c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc5310000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x80001465, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xd1000072, mmCP_DFY_DATA_0 }, - { 0xc82c0072, mmCP_DFY_DATA_0 }, - { 0xd2c0001e, mmCP_DFY_DATA_0 }, - { 0x18f02011, mmCP_DFY_DATA_0 }, - { 0x5aec01fc, mmCP_DFY_DATA_0 }, - { 0x12ec0009, mmCP_DFY_DATA_0 }, - { 0x7ef2c00a, mmCP_DFY_DATA_0 }, - { 0x2aec0000, mmCP_DFY_DATA_0 }, - { 0xcec0001c, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0xc42c000f, mmCP_DFY_DATA_0 }, - { 0x9ac0ffff, mmCP_DFY_DATA_0 }, - { 0xc4300011, mmCP_DFY_DATA_0 }, - { 0x96800012, mmCP_DFY_DATA_0 }, - { 0x12a80001, mmCP_DFY_DATA_0 }, - { 0x0aa80001, mmCP_DFY_DATA_0 }, - { 0x06a8146a, mmCP_DFY_DATA_0 }, - { 0x7f1f0009, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x7f1b400f, mmCP_DFY_DATA_0 }, - { 0x80001478, mmCP_DFY_DATA_0 }, - { 0x7f1b400e, mmCP_DFY_DATA_0 }, - { 0x80001478, mmCP_DFY_DATA_0 }, - { 0x7f1b400c, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f1b400d, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f1b400f, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f1b400e, mmCP_DFY_DATA_0 }, - { 0x8000147a, mmCP_DFY_DATA_0 }, - { 0x7f334002, mmCP_DFY_DATA_0 }, - { 0x97400014, mmCP_DFY_DATA_0 }, - { 0x8000147b, mmCP_DFY_DATA_0 }, - { 0x9b400012, mmCP_DFY_DATA_0 }, - { 0x9b800005, mmCP_DFY_DATA_0 }, - { 0x9bc0001f, mmCP_DFY_DATA_0 }, - { 0x7e024001, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x8000144a, mmCP_DFY_DATA_0 }, - { 0xc40c0032, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d325b, mmCP_DFY_DATA_0 }, - { 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { 0x7fbfc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0xc411325d, mmCP_DFY_DATA_0 }, - { 0x251001ef, mmCP_DFY_DATA_0 }, - { 0xcd01325d, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x94800007, mmCP_DFY_DATA_0 }, - { 0x8c00187c, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xc42c0004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcd910000, mmCP_DFY_DATA_0 }, - { 0xcec00008, mmCP_DFY_DATA_0 }, - { 0x9b800003, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0xc40c0032, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc40d325b, mmCP_DFY_DATA_0 }, - { 0x800012c2, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xc438001d, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0x13f4000c, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0xc43d3256, mmCP_DFY_DATA_0 }, - { 0x1bf0060b, mmCP_DFY_DATA_0 }, - { 0x1bfc0077, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x800014a9, mmCP_DFY_DATA_0 }, - { 0xc43d325a, mmCP_DFY_DATA_0 }, - { 0x1bfc0677, mmCP_DFY_DATA_0 }, - { 0x04300100, mmCP_DFY_DATA_0 }, - { 0x1bb81ff0, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xc0328007, mmCP_DFY_DATA_0 }, - { 0x7fb7800a, mmCP_DFY_DATA_0 }, - { 0x13fc0017, mmCP_DFY_DATA_0 }, - { 0x7ff3c00a, mmCP_DFY_DATA_0 }, - { 0x7ffbc00a, mmCP_DFY_DATA_0 }, - { 0xcfc1325b, mmCP_DFY_DATA_0 }, - { 0xc03a0002, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xcf8130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0x043c0000, mmCP_DFY_DATA_0 }, - { 0xc414000e, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7dd9c01a, mmCP_DFY_DATA_0 }, - { 0x45dc0390, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04183000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0x1b380057, mmCP_DFY_DATA_0 }, - { 0x1b340213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0xd1c00025, mmCP_DFY_DATA_0 }, - { 0xcc800026, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0x7c424001, mmCP_DFY_DATA_0 }, - { 0xce400026, mmCP_DFY_DATA_0 }, - { 0x7c428001, mmCP_DFY_DATA_0 }, - { 0xce800026, mmCP_DFY_DATA_0 }, - { 0x7c42c001, mmCP_DFY_DATA_0 }, - { 0xcec00026, mmCP_DFY_DATA_0 }, - { 0x7c430001, mmCP_DFY_DATA_0 }, - { 0xcf000026, mmCP_DFY_DATA_0 }, - { 0x7c434001, mmCP_DFY_DATA_0 }, - { 0xcf400026, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0xcf800026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0x04182000, mmCP_DFY_DATA_0 }, - { 0xcd813267, mmCP_DFY_DATA_0 }, - { 0xd840004f, mmCP_DFY_DATA_0 }, - { 0x1a0800fd, mmCP_DFY_DATA_0 }, - { 0x109c000a, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { 0xcdc13265, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0xce080228, mmCP_DFY_DATA_0 }, - { 0x9880000e, mmCP_DFY_DATA_0 }, - { 0xce480250, mmCP_DFY_DATA_0 }, - { 0xce880258, mmCP_DFY_DATA_0 }, - { 0xd8080230, mmCP_DFY_DATA_0 }, - { 0xd8080238, mmCP_DFY_DATA_0 }, - { 0xd8080240, mmCP_DFY_DATA_0 }, - { 0xd8080248, mmCP_DFY_DATA_0 }, - { 0xd8080268, mmCP_DFY_DATA_0 }, - { 0xd8080270, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x97c0ec75, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x041c0010, mmCP_DFY_DATA_0 }, - { 0x26180001, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x16200001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x99c0fffb, mmCP_DFY_DATA_0 }, - { 0xccc80230, mmCP_DFY_DATA_0 }, - { 0xd8080238, mmCP_DFY_DATA_0 }, - { 0xd8080240, mmCP_DFY_DATA_0 }, - { 0xd8080248, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0xce480250, mmCP_DFY_DATA_0 }, - { 0xce880258, mmCP_DFY_DATA_0 }, - { 0x52a80020, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x041c0020, mmCP_DFY_DATA_0 }, - { 0x66580001, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x56640001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x99c0fffb, mmCP_DFY_DATA_0 }, - { 0xccc80260, mmCP_DFY_DATA_0 }, - { 0xd8080268, mmCP_DFY_DATA_0 }, - { 0xd8080270, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0xcec80288, mmCP_DFY_DATA_0 }, - { 0xcf080290, mmCP_DFY_DATA_0 }, - { 0xcec80298, mmCP_DFY_DATA_0 }, - { 0xcf0802a0, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x041c0010, mmCP_DFY_DATA_0 }, - { 0xcf4802a8, mmCP_DFY_DATA_0 }, - { 0x27580001, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x17740001, mmCP_DFY_DATA_0 }, - { 0x95800002, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x99c0fffb, mmCP_DFY_DATA_0 }, - { 0xccc802b0, mmCP_DFY_DATA_0 }, - { 0xd80802b8, mmCP_DFY_DATA_0 }, - { 0x178c000b, mmCP_DFY_DATA_0 }, - { 0x27b8003f, mmCP_DFY_DATA_0 }, - { 0x7cf8c001, mmCP_DFY_DATA_0 }, - { 0xcf8802c0, mmCP_DFY_DATA_0 }, - { 0xccc802c8, mmCP_DFY_DATA_0 }, - { 0xcf8802d0, mmCP_DFY_DATA_0 }, - { 0xcf8802d8, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x25b8ffff, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0xc48f0238, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x24cc000f, mmCP_DFY_DATA_0 }, - { 0x7cd2800c, mmCP_DFY_DATA_0 }, - { 0x9a80000b, mmCP_DFY_DATA_0 }, - { 0xc5230309, mmCP_DFY_DATA_0 }, - { 0x2620ffff, mmCP_DFY_DATA_0 }, - { 0x7e3a400c, mmCP_DFY_DATA_0 }, - { 0x9a400004, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x80001539, mmCP_DFY_DATA_0 }, - { 0xcd08034b, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x98c00004, mmCP_DFY_DATA_0 }, - { 0xcd880353, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0xc49b0353, mmCP_DFY_DATA_0 }, - { 0xc4930238, mmCP_DFY_DATA_0 }, - { 0xc48f0228, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x7cd14005, mmCP_DFY_DATA_0 }, - { 0x25540001, mmCP_DFY_DATA_0 }, - { 0x99400004, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x8000154f, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0xcd080238, mmCP_DFY_DATA_0 }, - { 0xcd08034b, mmCP_DFY_DATA_0 }, - { 0x08cc0001, mmCP_DFY_DATA_0 }, - { 0x2598ffff, mmCP_DFY_DATA_0 }, - { 0x3d200008, mmCP_DFY_DATA_0 }, - { 0xccc80230, mmCP_DFY_DATA_0 }, - { 0xcd900309, mmCP_DFY_DATA_0 }, - { 0xd8100319, mmCP_DFY_DATA_0 }, - { 0x04340801, mmCP_DFY_DATA_0 }, - { 0x2198003f, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcd910ce7, mmCP_DFY_DATA_0 }, - { 0xc4190ce6, mmCP_DFY_DATA_0 }, - { 0x7d918005, mmCP_DFY_DATA_0 }, - { 0x25980001, mmCP_DFY_DATA_0 }, - { 0x9580fffd, mmCP_DFY_DATA_0 }, - { 0x7d918004, mmCP_DFY_DATA_0 }, - { 0xcd810ce6, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0xcdd1054f, mmCP_DFY_DATA_0 }, - { 0x8000156e, mmCP_DFY_DATA_0 }, - { 0x090c0008, mmCP_DFY_DATA_0 }, - { 0xcdcd050e, mmCP_DFY_DATA_0 }, - { 0x040c0000, mmCP_DFY_DATA_0 }, - { 0x110c0014, mmCP_DFY_DATA_0 }, - { 0x28cc4001, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xcc41230a, mmCP_DFY_DATA_0 }, - { 0xcc41230b, mmCP_DFY_DATA_0 }, - { 0xcc41230c, mmCP_DFY_DATA_0 }, - { 0xcc41230d, mmCP_DFY_DATA_0 }, - { 0xcc480329, mmCP_DFY_DATA_0 }, - { 0xcc48032a, mmCP_DFY_DATA_0 }, - { 0xcc4802e0, mmCP_DFY_DATA_0 }, - { 0xd8000055, mmCP_DFY_DATA_0 }, - { 0xc48f02e0, mmCP_DFY_DATA_0 }, - { 0x24d8003f, mmCP_DFY_DATA_0 }, - { 0x09940001, mmCP_DFY_DATA_0 }, - { 0x44100001, mmCP_DFY_DATA_0 }, - { 0x9580002c, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x51100001, mmCP_DFY_DATA_0 }, - { 0x69100001, mmCP_DFY_DATA_0 }, - { 0x8000157f, mmCP_DFY_DATA_0 }, - { 0x24cc003f, mmCP_DFY_DATA_0 }, - { 0xc4970290, mmCP_DFY_DATA_0 }, - { 0xc49b0288, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xc49b02a0, mmCP_DFY_DATA_0 }, - { 0xc49f0298, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7d9d801a, mmCP_DFY_DATA_0 }, - { 0x041c0040, mmCP_DFY_DATA_0 }, - { 0x04200000, mmCP_DFY_DATA_0 }, - { 0x7dcdc002, mmCP_DFY_DATA_0 }, - { 0x7d924019, mmCP_DFY_DATA_0 }, - { 0x7d26400c, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x9a400008, mmCP_DFY_DATA_0 }, - { 0x51100001, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x99c0fffa, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0x80001579, mmCP_DFY_DATA_0 }, - { 0x7d010021, mmCP_DFY_DATA_0 }, - { 0x7d914019, mmCP_DFY_DATA_0 }, - { 0xc4930238, mmCP_DFY_DATA_0 }, - { 0x55580020, mmCP_DFY_DATA_0 }, - { 0xcd480298, mmCP_DFY_DATA_0 }, - { 0xcd8802a0, mmCP_DFY_DATA_0 }, - { 0x10d40010, mmCP_DFY_DATA_0 }, - { 0x12180016, mmCP_DFY_DATA_0 }, - { 0xc51f0309, mmCP_DFY_DATA_0 }, - { 0x7d95800a, mmCP_DFY_DATA_0 }, - { 0x7d62000a, mmCP_DFY_DATA_0 }, - { 0x7dd9c00a, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcdd00309, mmCP_DFY_DATA_0 }, - { 0xce113320, mmCP_DFY_DATA_0 }, - { 0xc48f02e0, mmCP_DFY_DATA_0 }, - { 0xc49b02b0, mmCP_DFY_DATA_0 }, - { 0x18dc01e8, mmCP_DFY_DATA_0 }, - { 0x7dd9400e, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x95c0001d, mmCP_DFY_DATA_0 }, - { 0x95400003, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0x800015aa, mmCP_DFY_DATA_0 }, - { 0xc48f0238, mmCP_DFY_DATA_0 }, - { 0xc4a302b8, mmCP_DFY_DATA_0 }, - { 0x12240004, mmCP_DFY_DATA_0 }, - { 0x7e5e400a, mmCP_DFY_DATA_0 }, - { 0xc4ab02a8, mmCP_DFY_DATA_0 }, - { 0x04100000, mmCP_DFY_DATA_0 }, - { 0xce4c0319, mmCP_DFY_DATA_0 }, - { 0x7d9d8002, mmCP_DFY_DATA_0 }, - { 0x7ea14005, mmCP_DFY_DATA_0 }, - { 0x25540001, mmCP_DFY_DATA_0 }, - { 0x99400004, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x2620000f, mmCP_DFY_DATA_0 }, - { 0x800015bc, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x04240001, mmCP_DFY_DATA_0 }, - { 0x7e624004, mmCP_DFY_DATA_0 }, - { 0x06200001, mmCP_DFY_DATA_0 }, - { 0x7d25000a, mmCP_DFY_DATA_0 }, - { 0x2620000f, mmCP_DFY_DATA_0 }, - { 0x99c0fff4, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd0d3330, mmCP_DFY_DATA_0 }, - { 0xce0802b8, mmCP_DFY_DATA_0 }, - { 0xcd8802b0, mmCP_DFY_DATA_0 }, - { 0xc4ab02e0, mmCP_DFY_DATA_0 }, - { 0x1aa807f0, mmCP_DFY_DATA_0 }, - { 0xc48f02d0, mmCP_DFY_DATA_0 }, - { 0xc49702d8, mmCP_DFY_DATA_0 }, - { 0xc49b02c8, mmCP_DFY_DATA_0 }, - { 0xc49f02c0, mmCP_DFY_DATA_0 }, - { 0x96800028, mmCP_DFY_DATA_0 }, - { 0x7d4e000f, mmCP_DFY_DATA_0 }, - { 0x9600000b, mmCP_DFY_DATA_0 }, - { 0x7d964002, mmCP_DFY_DATA_0 }, - { 0x7e6a000f, mmCP_DFY_DATA_0 }, - { 0x96000003, mmCP_DFY_DATA_0 }, - { 0x7d694001, mmCP_DFY_DATA_0 }, - { 0x800015e9, mmCP_DFY_DATA_0 }, - { 0x7cde4002, mmCP_DFY_DATA_0 }, - { 0x7e6a000f, mmCP_DFY_DATA_0 }, - { 0x96000008, mmCP_DFY_DATA_0 }, - { 0x7de94001, mmCP_DFY_DATA_0 }, - { 0x800015e9, mmCP_DFY_DATA_0 }, - { 0x7cd64002, mmCP_DFY_DATA_0 }, - { 0x7e6a000e, mmCP_DFY_DATA_0 }, - { 0x96000003, mmCP_DFY_DATA_0 }, - { 0x7d694001, mmCP_DFY_DATA_0 }, - { 0x800015e9, mmCP_DFY_DATA_0 }, - { 0xc48f0230, mmCP_DFY_DATA_0 }, - { 0xc4930240, mmCP_DFY_DATA_0 }, - { 0x8c00163f, mmCP_DFY_DATA_0 }, - { 0x800015cd, mmCP_DFY_DATA_0 }, - { 0xc4930238, mmCP_DFY_DATA_0 }, - { 0x7d698002, mmCP_DFY_DATA_0 }, - { 0xcd4802d8, mmCP_DFY_DATA_0 }, - { 0x129c0008, mmCP_DFY_DATA_0 }, - { 0xc50f0319, mmCP_DFY_DATA_0 }, - { 0x11a0000e, mmCP_DFY_DATA_0 }, - { 0x11140001, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x7e1e000a, mmCP_DFY_DATA_0 }, - { 0x1198000a, mmCP_DFY_DATA_0 }, - { 0xcd953300, mmCP_DFY_DATA_0 }, - { 0x7e0e000a, mmCP_DFY_DATA_0 }, - { 0x12a8000a, mmCP_DFY_DATA_0 }, - { 0xce953301, mmCP_DFY_DATA_0 }, - { 0xce100319, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0xc4b70280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x7f73800a, mmCP_DFY_DATA_0 }, - { 0x536c0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x9780eb68, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x043c0003, mmCP_DFY_DATA_0 }, - { 0x80001609, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x30b40000, mmCP_DFY_DATA_0 }, - { 0x9b400011, mmCP_DFY_DATA_0 }, - { 0xc4b70258, mmCP_DFY_DATA_0 }, - { 0xc4b30250, mmCP_DFY_DATA_0 }, - { 0x53780020, mmCP_DFY_DATA_0 }, - { 0x7fb3801a, mmCP_DFY_DATA_0 }, - { 0x7faf8019, mmCP_DFY_DATA_0 }, - { 0x04300020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x67b40001, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x57b80001, mmCP_DFY_DATA_0 }, - { 0x97400002, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9b00fffb, mmCP_DFY_DATA_0 }, - { 0xc4bb0260, mmCP_DFY_DATA_0 }, - { 0x7fab8001, mmCP_DFY_DATA_0 }, - { 0xcf880260, mmCP_DFY_DATA_0 }, - { 0x04300020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x66f40001, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x56ec0001, mmCP_DFY_DATA_0 }, - { 0x97400005, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4353247, mmCP_DFY_DATA_0 }, - { 0x7f7f4009, mmCP_DFY_DATA_0 }, - { 0x9b40fffe, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9b00fff7, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x269c0007, mmCP_DFY_DATA_0 }, - { 0x11dc0008, mmCP_DFY_DATA_0 }, - { 0x29dc0008, mmCP_DFY_DATA_0 }, - { 0x26a00018, mmCP_DFY_DATA_0 }, - { 0x12200003, mmCP_DFY_DATA_0 }, - { 0x7de1c00a, mmCP_DFY_DATA_0 }, - { 0x26a00060, mmCP_DFY_DATA_0 }, - { 0x06200020, mmCP_DFY_DATA_0 }, - { 0x16200001, mmCP_DFY_DATA_0 }, - { 0x7de1c00a, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x269c0018, mmCP_DFY_DATA_0 }, - { 0x26a00007, mmCP_DFY_DATA_0 }, - { 0x26a40060, mmCP_DFY_DATA_0 }, - { 0x11dc0006, mmCP_DFY_DATA_0 }, - { 0x12200006, mmCP_DFY_DATA_0 }, - { 0x16640001, mmCP_DFY_DATA_0 }, - { 0x29dc0008, mmCP_DFY_DATA_0 }, - { 0x7de1c00a, mmCP_DFY_DATA_0 }, - { 0x7de5c00a, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4b70228, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x04cc0001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0xccc80230, mmCP_DFY_DATA_0 }, - { 0x7f514005, mmCP_DFY_DATA_0 }, - { 0x25540001, mmCP_DFY_DATA_0 }, - { 0x99400004, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x2510000f, mmCP_DFY_DATA_0 }, - { 0x80001644, mmCP_DFY_DATA_0 }, - { 0xc4b30248, mmCP_DFY_DATA_0 }, - { 0xcd080240, mmCP_DFY_DATA_0 }, - { 0x7f130005, mmCP_DFY_DATA_0 }, - { 0x27300001, mmCP_DFY_DATA_0 }, - { 0x9b000002, mmCP_DFY_DATA_0 }, - { 0x8c001688, mmCP_DFY_DATA_0 }, - { 0x8c00120d, mmCP_DFY_DATA_0 }, - { 0x8c001219, mmCP_DFY_DATA_0 }, - { 0x8c001232, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x04340801, mmCP_DFY_DATA_0 }, - { 0x7f130004, mmCP_DFY_DATA_0 }, - { 0xcf400013, mmCP_DFY_DATA_0 }, - { 0xcf01051e, mmCP_DFY_DATA_0 }, - { 0xc42d051f, mmCP_DFY_DATA_0 }, - { 0x7ed2c005, mmCP_DFY_DATA_0 }, - { 0x26ec0001, mmCP_DFY_DATA_0 }, - { 0x96c0fffd, mmCP_DFY_DATA_0 }, - { 0xcf01051f, mmCP_DFY_DATA_0 }, - { 0xd8000055, mmCP_DFY_DATA_0 }, - { 0xc5170309, mmCP_DFY_DATA_0 }, - { 0x195c07f0, mmCP_DFY_DATA_0 }, - { 0x196007f6, mmCP_DFY_DATA_0 }, - { 0x04340000, mmCP_DFY_DATA_0 }, - { 0x95c00008, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x04340001, mmCP_DFY_DATA_0 }, - { 0x95c00005, mmCP_DFY_DATA_0 }, - { 0x09dc0001, mmCP_DFY_DATA_0 }, - { 0x53740001, mmCP_DFY_DATA_0 }, - { 0x6b740001, mmCP_DFY_DATA_0 }, - { 0x80001665, mmCP_DFY_DATA_0 }, - { 0xc4a702a0, mmCP_DFY_DATA_0 }, - { 0xc4ab0298, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x7f634014, mmCP_DFY_DATA_0 }, - { 0x7e76401a, mmCP_DFY_DATA_0 }, - { 0xc4300004, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x56680020, mmCP_DFY_DATA_0 }, - { 0xd8113320, mmCP_DFY_DATA_0 }, - { 0xce480298, mmCP_DFY_DATA_0 }, - { 0xce8802a0, mmCP_DFY_DATA_0 }, - { 0xc5170319, mmCP_DFY_DATA_0 }, - { 0xc4b702b0, mmCP_DFY_DATA_0 }, - { 0x255c000f, mmCP_DFY_DATA_0 }, - { 0x7f5f4001, mmCP_DFY_DATA_0 }, - { 0xd8113330, mmCP_DFY_DATA_0 }, - { 0xcf4802b0, mmCP_DFY_DATA_0 }, - { 0x11340001, mmCP_DFY_DATA_0 }, - { 0x195c07e8, mmCP_DFY_DATA_0 }, - { 0x196007ee, mmCP_DFY_DATA_0 }, - { 0xd8353300, mmCP_DFY_DATA_0 }, - { 0x7e1e4001, mmCP_DFY_DATA_0 }, - { 0xd8353301, mmCP_DFY_DATA_0 }, - { 0xce4802d0, mmCP_DFY_DATA_0 }, - { 0xd8100309, mmCP_DFY_DATA_0 }, - { 0xd8100319, mmCP_DFY_DATA_0 }, - { 0xcf000008, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc48f0250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7cd4c01a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x64d80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x54cc0001, mmCP_DFY_DATA_0 }, - { 0x95800060, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4193247, mmCP_DFY_DATA_0 }, - { 0x25980001, mmCP_DFY_DATA_0 }, - { 0x9580005c, mmCP_DFY_DATA_0 }, - { 0x7dc24001, mmCP_DFY_DATA_0 }, - { 0xc41d3248, mmCP_DFY_DATA_0 }, - { 0x25dc000f, mmCP_DFY_DATA_0 }, - { 0x7dd2000c, mmCP_DFY_DATA_0 }, - { 0x96000057, mmCP_DFY_DATA_0 }, - { 0xc41d3255, mmCP_DFY_DATA_0 }, - { 0xc435324f, mmCP_DFY_DATA_0 }, - { 0x7df5c00c, mmCP_DFY_DATA_0 }, - { 0x99c00004, mmCP_DFY_DATA_0 }, - { 0xc4193265, mmCP_DFY_DATA_0 }, - { 0x25980040, mmCP_DFY_DATA_0 }, - { 0x9580fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x1bb0003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1bb000e8, mmCP_DFY_DATA_0 }, - { 0x33380003, mmCP_DFY_DATA_0 }, - { 0x9b800046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xc4393260, mmCP_DFY_DATA_0 }, - { 0x1bb000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x800016f1, mmCP_DFY_DATA_0 }, - { 0xce400013, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x7f3b0009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b800ff, mmCP_DFY_DATA_0 }, - { 0x9b80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x1a7003e6, mmCP_DFY_DATA_0 }, - { 0x27380003, mmCP_DFY_DATA_0 }, - { 0x13b80004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x1a7000e8, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x07b80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x1a700064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x800016df, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7fb30002, mmCP_DFY_DATA_0 }, - { 0xc4392083, mmCP_DFY_DATA_0 }, - { 0x7fb38005, mmCP_DFY_DATA_0 }, - { 0x27b80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xce400013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffca, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x800016f2, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940ff9c, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xd840004f, mmCP_DFY_DATA_0 }, - { 0xc414000e, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0xd80802e9, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18fc0064, mmCP_DFY_DATA_0 }, - { 0x9bc00042, mmCP_DFY_DATA_0 }, - { 0xc4193246, mmCP_DFY_DATA_0 }, - { 0xc41d3245, mmCP_DFY_DATA_0 }, - { 0x51980020, mmCP_DFY_DATA_0 }, - { 0x7dd9801a, mmCP_DFY_DATA_0 }, - { 0x45980400, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x043c3000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0x9bc00001, mmCP_DFY_DATA_0 }, - { 0x1b380057, mmCP_DFY_DATA_0 }, - { 0x1b340213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7f7b400a, mmCP_DFY_DATA_0 }, - { 0x7f73400a, mmCP_DFY_DATA_0 }, - { 0xcf400024, mmCP_DFY_DATA_0 }, - { 0x14f4001d, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x9bc0001c, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x192807fa, mmCP_DFY_DATA_0 }, - { 0xc4bf0258, mmCP_DFY_DATA_0 }, - { 0xc4a70250, mmCP_DFY_DATA_0 }, - { 0x53fc0020, mmCP_DFY_DATA_0 }, - { 0x7e7e401a, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0x04300000, mmCP_DFY_DATA_0 }, - { 0x667c0001, mmCP_DFY_DATA_0 }, - { 0x56640001, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x97c0fffd, mmCP_DFY_DATA_0 }, - { 0x07300001, mmCP_DFY_DATA_0 }, - { 0x0aec0001, mmCP_DFY_DATA_0 }, - { 0x7eebc00c, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x97c0fff8, mmCP_DFY_DATA_0 }, - { 0x0b300001, mmCP_DFY_DATA_0 }, - { 0x43300007, mmCP_DFY_DATA_0 }, - { 0x53300002, mmCP_DFY_DATA_0 }, - { 0x7db30011, mmCP_DFY_DATA_0 }, - { 0xd3000025, mmCP_DFY_DATA_0 }, - { 0xc03ec005, mmCP_DFY_DATA_0 }, - { 0x2bfca200, mmCP_DFY_DATA_0 }, - { 0xcfc00026, mmCP_DFY_DATA_0 }, - { 0xccc00026, mmCP_DFY_DATA_0 }, - { 0xcd000026, mmCP_DFY_DATA_0 }, - { 0x192807fa, mmCP_DFY_DATA_0 }, - { 0xc01f007f, mmCP_DFY_DATA_0 }, - { 0x7d1d0009, mmCP_DFY_DATA_0 }, - { 0x2110007d, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x203c003f, mmCP_DFY_DATA_0 }, - { 0xcfc13256, mmCP_DFY_DATA_0 }, - { 0x8c0017f5, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0x18fc01e8, mmCP_DFY_DATA_0 }, - { 0xcfc13248, mmCP_DFY_DATA_0 }, - { 0x8c00185b, mmCP_DFY_DATA_0 }, - { 0xd8413247, mmCP_DFY_DATA_0 }, - { 0x0b740001, mmCP_DFY_DATA_0 }, - { 0x9b40ffd5, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x97c0ea24, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x14d4001d, mmCP_DFY_DATA_0 }, - { 0xc4930260, mmCP_DFY_DATA_0 }, - { 0x7d52400e, mmCP_DFY_DATA_0 }, - { 0xc49f0258, mmCP_DFY_DATA_0 }, - { 0xc4a30250, mmCP_DFY_DATA_0 }, - { 0x51dc0020, mmCP_DFY_DATA_0 }, - { 0x7de1801a, mmCP_DFY_DATA_0 }, - { 0x96400017, mmCP_DFY_DATA_0 }, - { 0x7d534002, mmCP_DFY_DATA_0 }, - { 0xc4af0270, mmCP_DFY_DATA_0 }, - { 0x7dae4005, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x32e0001f, mmCP_DFY_DATA_0 }, - { 0x9a400006, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0xcec80270, mmCP_DFY_DATA_0 }, - { 0x8000174f, mmCP_DFY_DATA_0 }, - { 0x0b740001, mmCP_DFY_DATA_0 }, - { 0x8c00178a, mmCP_DFY_DATA_0 }, - { 0x05100001, mmCP_DFY_DATA_0 }, - { 0x9b40fff3, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x8c001608, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0xc4ab0268, mmCP_DFY_DATA_0 }, - { 0x7daa4005, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x32a0001f, mmCP_DFY_DATA_0 }, - { 0x9a400005, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0x24280000, mmCP_DFY_DATA_0 }, - { 0x80001765, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0xc01f007f, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x7d1d0009, mmCP_DFY_DATA_0 }, - { 0x2110007d, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xd8013256, mmCP_DFY_DATA_0 }, - { 0x8c0017f2, mmCP_DFY_DATA_0 }, - { 0xcd013254, mmCP_DFY_DATA_0 }, - { 0xc4113248, mmCP_DFY_DATA_0 }, - { 0x15100004, mmCP_DFY_DATA_0 }, - { 0x11100004, mmCP_DFY_DATA_0 }, - { 0xc4b3034b, mmCP_DFY_DATA_0 }, - { 0x7f13000a, mmCP_DFY_DATA_0 }, - { 0xcf013248, mmCP_DFY_DATA_0 }, - { 0xc4930260, mmCP_DFY_DATA_0 }, - { 0x8c001855, mmCP_DFY_DATA_0 }, - { 0x32a4001f, mmCP_DFY_DATA_0 }, - { 0xd8413247, mmCP_DFY_DATA_0 }, - { 0xd800004f, mmCP_DFY_DATA_0 }, - { 0x09100001, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x96400002, mmCP_DFY_DATA_0 }, - { 0x24280000, mmCP_DFY_DATA_0 }, - { 0xcd080260, mmCP_DFY_DATA_0 }, - { 0xce880268, mmCP_DFY_DATA_0 }, - { 0x9940ffc0, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x7ec28001, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x32e0001f, mmCP_DFY_DATA_0 }, - { 0xc4253247, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9640005e, mmCP_DFY_DATA_0 }, - { 0xc4293265, mmCP_DFY_DATA_0 }, - { 0xc4253255, mmCP_DFY_DATA_0 }, - { 0xc431324f, mmCP_DFY_DATA_0 }, - { 0x7e72400c, mmCP_DFY_DATA_0 }, - { 0x26a80040, mmCP_DFY_DATA_0 }, - { 0x9a400002, mmCP_DFY_DATA_0 }, - { 0x9680fff7, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x1aa4003f, mmCP_DFY_DATA_0 }, - { 0x96400049, mmCP_DFY_DATA_0 }, - { 0x1aa400e8, mmCP_DFY_DATA_0 }, - { 0x32680003, mmCP_DFY_DATA_0 }, - { 0x9a800046, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x9640000a, mmCP_DFY_DATA_0 }, - { 0xc4293260, mmCP_DFY_DATA_0 }, - { 0x1aa400e4, mmCP_DFY_DATA_0 }, - { 0x32640004, mmCP_DFY_DATA_0 }, - { 0x96400040, mmCP_DFY_DATA_0 }, - { 0xc425325d, mmCP_DFY_DATA_0 }, - { 0x26640010, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x800017e2, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc027ffff, mmCP_DFY_DATA_0 }, - { 0x2e6400ff, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x7e6a4009, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x26a800ff, mmCP_DFY_DATA_0 }, - { 0x9a80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4240009, mmCP_DFY_DATA_0 }, - { 0x26640008, mmCP_DFY_DATA_0 }, - { 0x9640fffe, mmCP_DFY_DATA_0 }, - { 0x19e403e6, mmCP_DFY_DATA_0 }, - { 0x26680003, mmCP_DFY_DATA_0 }, - { 0x12a80004, mmCP_DFY_DATA_0 }, - { 0x26640003, mmCP_DFY_DATA_0 }, - { 0x12640003, mmCP_DFY_DATA_0 }, - { 0x7ea68001, mmCP_DFY_DATA_0 }, - { 0x19e400e8, mmCP_DFY_DATA_0 }, - { 0x7ea68001, mmCP_DFY_DATA_0 }, - { 0x12640001, mmCP_DFY_DATA_0 }, - { 0x7ea68001, mmCP_DFY_DATA_0 }, - { 0x06a80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19e40064, mmCP_DFY_DATA_0 }, - { 0x32640002, mmCP_DFY_DATA_0 }, - { 0x96400009, mmCP_DFY_DATA_0 }, - { 0x16a40005, mmCP_DFY_DATA_0 }, - { 0x06640003, mmCP_DFY_DATA_0 }, - { 0xce412082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0a640003, mmCP_DFY_DATA_0 }, - { 0x800017d0, mmCP_DFY_DATA_0 }, - { 0x16a40005, mmCP_DFY_DATA_0 }, - { 0xce412082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x12640005, mmCP_DFY_DATA_0 }, - { 0x7ea64002, mmCP_DFY_DATA_0 }, - { 0xc4292083, mmCP_DFY_DATA_0 }, - { 0x7ea68005, mmCP_DFY_DATA_0 }, - { 0x26a80001, mmCP_DFY_DATA_0 }, - { 0x9a80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc425325d, mmCP_DFY_DATA_0 }, - { 0x26640010, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0xc429325b, mmCP_DFY_DATA_0 }, - { 0x26a400ff, mmCP_DFY_DATA_0 }, - { 0x9a40ffca, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0x2024007b, mmCP_DFY_DATA_0 }, - { 0xce41325b, mmCP_DFY_DATA_0 }, - { 0x800017e3, mmCP_DFY_DATA_0 }, - { 0xd841325d, mmCP_DFY_DATA_0 }, - { 0xc4a70280, mmCP_DFY_DATA_0 }, - { 0xc4ab0278, mmCP_DFY_DATA_0 }, - { 0x52640020, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x04280001, mmCP_DFY_DATA_0 }, - { 0x7eae8014, mmCP_DFY_DATA_0 }, - { 0x7e6a401a, mmCP_DFY_DATA_0 }, - { 0x56680020, mmCP_DFY_DATA_0 }, - { 0xce480278, mmCP_DFY_DATA_0 }, - { 0xce880280, mmCP_DFY_DATA_0 }, - { 0x06ec0001, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0x042c0000, mmCP_DFY_DATA_0 }, - { 0xcec80270, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0x800017fe, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x9bc00006, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcf800026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0x800017fe, mmCP_DFY_DATA_0 }, - { 0xc43b02eb, mmCP_DFY_DATA_0 }, - { 0xc42302ec, mmCP_DFY_DATA_0 }, - { 0xcf813245, mmCP_DFY_DATA_0 }, - { 0xce013246, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7fa3801a, mmCP_DFY_DATA_0 }, - { 0x47b8020c, mmCP_DFY_DATA_0 }, - { 0x15e00008, mmCP_DFY_DATA_0 }, - { 0x1220000a, mmCP_DFY_DATA_0 }, - { 0x2a206032, mmCP_DFY_DATA_0 }, - { 0x513c001e, mmCP_DFY_DATA_0 }, - { 0x7e3e001a, mmCP_DFY_DATA_0 }, - { 0xc4bf02e9, mmCP_DFY_DATA_0 }, - { 0x9bc00005, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x8000180f, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x1b3c0077, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7ff3000a, mmCP_DFY_DATA_0 }, - { 0x1330000a, mmCP_DFY_DATA_0 }, - { 0x2b300032, mmCP_DFY_DATA_0 }, - { 0x043c3000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0xd200000b, mmCP_DFY_DATA_0 }, - { 0xc4200007, mmCP_DFY_DATA_0 }, - { 0xd3800002, mmCP_DFY_DATA_0 }, - { 0xcf000002, mmCP_DFY_DATA_0 }, - { 0xd8000040, mmCP_DFY_DATA_0 }, - { 0x96000002, mmCP_DFY_DATA_0 }, - { 0xd8400040, mmCP_DFY_DATA_0 }, - { 0xd8400018, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xd8000018, mmCP_DFY_DATA_0 }, - { 0xd8800010, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0x7dc30001, mmCP_DFY_DATA_0 }, - { 0xdc1e0000, mmCP_DFY_DATA_0 }, - { 0x04380032, mmCP_DFY_DATA_0 }, - { 0xcf80000e, mmCP_DFY_DATA_0 }, - { 0x8c001427, mmCP_DFY_DATA_0 }, - { 0xcc413248, mmCP_DFY_DATA_0 }, - { 0xc43d3269, mmCP_DFY_DATA_0 }, - { 0x27fc000f, mmCP_DFY_DATA_0 }, - { 0x33fc0003, mmCP_DFY_DATA_0 }, - { 0x97c00011, mmCP_DFY_DATA_0 }, - { 0x043c001f, mmCP_DFY_DATA_0 }, - { 0xdfc30000, mmCP_DFY_DATA_0 }, - { 0xd4413249, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x043c0024, mmCP_DFY_DATA_0 }, - { 0x0bfc0021, mmCP_DFY_DATA_0 }, - { 0xdfc30000, mmCP_DFY_DATA_0 }, - { 0xd441326a, mmCP_DFY_DATA_0 }, - { 0x173c0008, mmCP_DFY_DATA_0 }, - { 0x1b300303, mmCP_DFY_DATA_0 }, - { 0x7f3f0001, mmCP_DFY_DATA_0 }, - { 0x043c0001, mmCP_DFY_DATA_0 }, - { 0x7ff3c004, mmCP_DFY_DATA_0 }, - { 0xcfc13084, mmCP_DFY_DATA_0 }, - { 0x80001842, mmCP_DFY_DATA_0 }, - { 0x043c0024, mmCP_DFY_DATA_0 }, - { 0xdfc30000, mmCP_DFY_DATA_0 }, - { 0xd4413249, mmCP_DFY_DATA_0 }, - { 0x7c43c001, mmCP_DFY_DATA_0 }, - { 0x23fc003f, mmCP_DFY_DATA_0 }, - { 0xcfc1326d, mmCP_DFY_DATA_0 }, - { 0x0bb80026, mmCP_DFY_DATA_0 }, - { 0xdf830000, mmCP_DFY_DATA_0 }, - { 0xd441326e, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0x7c438001, mmCP_DFY_DATA_0 }, - { 0xc4393265, mmCP_DFY_DATA_0 }, - { 0x1fb8ffc6, mmCP_DFY_DATA_0 }, - { 0xddc30000, mmCP_DFY_DATA_0 }, - { 0xcf813265, mmCP_DFY_DATA_0 }, - { 0x9a000003, mmCP_DFY_DATA_0 }, - { 0xcdc0000c, mmCP_DFY_DATA_0 }, - { 0x80001852, mmCP_DFY_DATA_0 }, - { 0xcdc0000d, mmCP_DFY_DATA_0 }, - { 0xce000010, mmCP_DFY_DATA_0 }, - { 0x8c00142b, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcdc13252, mmCP_DFY_DATA_0 }, - { 0xce013253, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x80001878, mmCP_DFY_DATA_0 }, - { 0xc49f02e9, mmCP_DFY_DATA_0 }, - { 0x99c00018, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x7c420001, mmCP_DFY_DATA_0 }, - { 0xcdc13252, mmCP_DFY_DATA_0 }, - { 0xce013253, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x043c3000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xc43d3267, mmCP_DFY_DATA_0 }, - { 0x97c0ffff, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xce000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc41c0012, mmCP_DFY_DATA_0 }, - { 0x99c0ffff, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0x80001878, mmCP_DFY_DATA_0 }, - { 0xc41f02ed, mmCP_DFY_DATA_0 }, - { 0xc42302ee, mmCP_DFY_DATA_0 }, - { 0xcdc13252, mmCP_DFY_DATA_0 }, - { 0xce013253, mmCP_DFY_DATA_0 }, - { 0x04200001, mmCP_DFY_DATA_0 }, - { 0x7e2a0004, mmCP_DFY_DATA_0 }, - { 0xce013084, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x28340001, mmCP_DFY_DATA_0 }, - { 0x313c0bcc, mmCP_DFY_DATA_0 }, - { 0x9bc00010, mmCP_DFY_DATA_0 }, - { 0x393c051f, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0x3d3c050e, mmCP_DFY_DATA_0 }, - { 0x9bc0000c, mmCP_DFY_DATA_0 }, - { 0x97c0000c, mmCP_DFY_DATA_0 }, - { 0x393c0560, mmCP_DFY_DATA_0 }, - { 0x9bc00004, mmCP_DFY_DATA_0 }, - { 0x3d3c054f, mmCP_DFY_DATA_0 }, - { 0x9bc00007, mmCP_DFY_DATA_0 }, - { 0x97c00007, mmCP_DFY_DATA_0 }, - { 0x393c1538, mmCP_DFY_DATA_0 }, - { 0x9bc00005, mmCP_DFY_DATA_0 }, - { 0x3d3c1537, mmCP_DFY_DATA_0 }, - { 0x9bc00002, mmCP_DFY_DATA_0 }, - { 0x97c00002, mmCP_DFY_DATA_0 }, - { 0x2b740800, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18e8007c, mmCP_DFY_DATA_0 }, - { 0x7c42c001, mmCP_DFY_DATA_0 }, - { 0x06a8189a, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0x800018c5, mmCP_DFY_DATA_0 }, - { 0x800018f2, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0x7c414001, mmCP_DFY_DATA_0 }, - { 0x18d0007e, mmCP_DFY_DATA_0 }, - { 0x50580020, mmCP_DFY_DATA_0 }, - { 0x09200001, mmCP_DFY_DATA_0 }, - { 0x7d59401a, mmCP_DFY_DATA_0 }, - { 0xd1400072, mmCP_DFY_DATA_0 }, - { 0xc8140072, mmCP_DFY_DATA_0 }, - { 0x09240002, mmCP_DFY_DATA_0 }, - { 0x7c418001, mmCP_DFY_DATA_0 }, - { 0x7c41c001, mmCP_DFY_DATA_0 }, - { 0x99000011, mmCP_DFY_DATA_0 }, - { 0xc4340004, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd8400008, mmCP_DFY_DATA_0 }, - { 0xc42130b5, mmCP_DFY_DATA_0 }, - { 0x1a24002c, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x2020002c, mmCP_DFY_DATA_0 }, - { 0xc418000d, mmCP_DFY_DATA_0 }, - { 0x1198001c, mmCP_DFY_DATA_0 }, - { 0x10cc0004, mmCP_DFY_DATA_0 }, - { 0x14cc0004, mmCP_DFY_DATA_0 }, - { 0x7cd8c00a, mmCP_DFY_DATA_0 }, - { 0xccc130b7, mmCP_DFY_DATA_0 }, - { 0xce0130b5, mmCP_DFY_DATA_0 }, - { 0xcf400008, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0xd1400025, mmCP_DFY_DATA_0 }, - { 0x5978073a, mmCP_DFY_DATA_0 }, - { 0x2bb80002, mmCP_DFY_DATA_0 }, - { 0xcf800024, mmCP_DFY_DATA_0 }, - { 0xcd800026, mmCP_DFY_DATA_0 }, - { 0xcdc00026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x9600e8a8, mmCP_DFY_DATA_0 }, - { 0xc4300012, mmCP_DFY_DATA_0 }, - { 0x9b00ffff, mmCP_DFY_DATA_0 }, - { 0x9640e8a5, mmCP_DFY_DATA_0 }, - { 0x800018a9, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0xc55b0309, mmCP_DFY_DATA_0 }, - { 0x3d5c0010, mmCP_DFY_DATA_0 }, - { 0x05540001, mmCP_DFY_DATA_0 }, - { 0x2598ffff, mmCP_DFY_DATA_0 }, - { 0x09780001, mmCP_DFY_DATA_0 }, - { 0x7dad800c, mmCP_DFY_DATA_0 }, - { 0x99c0ffd2, mmCP_DFY_DATA_0 }, - { 0x9580fff9, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x442c0000, mmCP_DFY_DATA_0 }, - { 0x65180001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9580000b, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc41d3248, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x25dc000f, mmCP_DFY_DATA_0 }, - { 0x7df9c00c, mmCP_DFY_DATA_0 }, - { 0x95c00004, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xd8c13260, mmCP_DFY_DATA_0 }, - { 0xd901325d, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940fff1, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x66d80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x56ec0001, mmCP_DFY_DATA_0 }, - { 0x95800005, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc421325d, mmCP_DFY_DATA_0 }, - { 0x26240007, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940fff7, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc41d3254, mmCP_DFY_DATA_0 }, - { 0xc023007f, mmCP_DFY_DATA_0 }, - { 0x19e4003e, mmCP_DFY_DATA_0 }, - { 0x7de1c009, mmCP_DFY_DATA_0 }, - { 0x7dee000c, mmCP_DFY_DATA_0 }, - { 0x96400008, mmCP_DFY_DATA_0 }, - { 0x96000007, mmCP_DFY_DATA_0 }, - { 0xd8c13260, mmCP_DFY_DATA_0 }, - { 0xd901325d, mmCP_DFY_DATA_0 }, - { 0xc421325d, mmCP_DFY_DATA_0 }, - { 0x261c0007, mmCP_DFY_DATA_0 }, - { 0x99c0fffe, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940fff0, mmCP_DFY_DATA_0 }, - { 0x8000189e, mmCP_DFY_DATA_0 }, - { 0xc40c000e, mmCP_DFY_DATA_0 }, - { 0x28cc0008, mmCP_DFY_DATA_0 }, - { 0xccc00013, mmCP_DFY_DATA_0 }, - { 0xc43d3265, mmCP_DFY_DATA_0 }, - { 0x1bc800ea, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x18e00064, mmCP_DFY_DATA_0 }, - { 0x06281911, mmCP_DFY_DATA_0 }, - { 0x14f4001d, mmCP_DFY_DATA_0 }, - { 0x24cc0003, mmCP_DFY_DATA_0 }, - { 0x86800000, mmCP_DFY_DATA_0 }, - { 0x80001915, mmCP_DFY_DATA_0 }, - { 0x800019af, mmCP_DFY_DATA_0 }, - { 0x80001a2b, mmCP_DFY_DATA_0 }, - { 0x8000016a, mmCP_DFY_DATA_0 }, - { 0xcc48032b, mmCP_DFY_DATA_0 }, - { 0xcc480333, mmCP_DFY_DATA_0 }, - { 0xcc48033b, mmCP_DFY_DATA_0 }, - { 0xcc480343, mmCP_DFY_DATA_0 }, - { 0x98800011, mmCP_DFY_DATA_0 }, - { 0xc4213246, mmCP_DFY_DATA_0 }, - { 0xc4253245, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26401a, mmCP_DFY_DATA_0 }, - { 0x46640400, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04203000, mmCP_DFY_DATA_0 }, - { 0xce013267, mmCP_DFY_DATA_0 }, - { 0xc4213267, mmCP_DFY_DATA_0 }, - { 0x9a000001, mmCP_DFY_DATA_0 }, - { 0x1b3c0057, mmCP_DFY_DATA_0 }, - { 0x1b200213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7e3e000a, mmCP_DFY_DATA_0 }, - { 0x7e32000a, mmCP_DFY_DATA_0 }, - { 0xce000024, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04180000, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x7f438001, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc41d3247, mmCP_DFY_DATA_0 }, - { 0x25dc0001, mmCP_DFY_DATA_0 }, - { 0x95c00068, mmCP_DFY_DATA_0 }, - { 0xc4213254, mmCP_DFY_DATA_0 }, - { 0x1a1c003e, mmCP_DFY_DATA_0 }, - { 0x95c00065, mmCP_DFY_DATA_0 }, - { 0xc01f007f, mmCP_DFY_DATA_0 }, - { 0x7e1e0009, mmCP_DFY_DATA_0 }, - { 0x97800062, mmCP_DFY_DATA_0 }, - { 0x0bb80001, mmCP_DFY_DATA_0 }, - { 0x43bc0008, mmCP_DFY_DATA_0 }, - { 0x7fcbc001, mmCP_DFY_DATA_0 }, - { 0xc7df032b, mmCP_DFY_DATA_0 }, - { 0x7e1fc00c, mmCP_DFY_DATA_0 }, - { 0x97c0fffa, mmCP_DFY_DATA_0 }, - { 0x043c0101, mmCP_DFY_DATA_0 }, - { 0x94c00002, mmCP_DFY_DATA_0 }, - { 0x043c0102, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x1bb0003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1bb000e8, mmCP_DFY_DATA_0 }, - { 0x33380003, mmCP_DFY_DATA_0 }, - { 0x9b800046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0xc4393260, mmCP_DFY_DATA_0 }, - { 0x1bb000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x80001994, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x7f3b0009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b800ff, mmCP_DFY_DATA_0 }, - { 0x9b80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x19f003e6, mmCP_DFY_DATA_0 }, - { 0x27380003, mmCP_DFY_DATA_0 }, - { 0x13b80004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x19f000e8, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x07b80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19f00064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x80001982, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7fb30002, mmCP_DFY_DATA_0 }, - { 0xc4392083, mmCP_DFY_DATA_0 }, - { 0x7fb38005, mmCP_DFY_DATA_0 }, - { 0x27b80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffcb, mmCP_DFY_DATA_0 }, - { 0xcfc1325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x80001995, mmCP_DFY_DATA_0 }, - { 0xcfc1325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x98800009, mmCP_DFY_DATA_0 }, - { 0x41bc0007, mmCP_DFY_DATA_0 }, - { 0x53fc0002, mmCP_DFY_DATA_0 }, - { 0x7e7fc011, mmCP_DFY_DATA_0 }, - { 0xd3c00025, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0xc43c0012, mmCP_DFY_DATA_0 }, - { 0x9bc0ffff, mmCP_DFY_DATA_0 }, - { 0x653c0001, mmCP_DFY_DATA_0 }, - { 0x7dbd8001, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9940ff8f, mmCP_DFY_DATA_0 }, - { 0xc43c000e, mmCP_DFY_DATA_0 }, - { 0x2bfc0008, mmCP_DFY_DATA_0 }, - { 0xcfc00013, mmCP_DFY_DATA_0 }, - { 0x043c2000, mmCP_DFY_DATA_0 }, - { 0xcfc13267, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x7c410001, mmCP_DFY_DATA_0 }, - { 0x04140000, mmCP_DFY_DATA_0 }, - { 0xc55b0309, mmCP_DFY_DATA_0 }, - { 0x3d5c0010, mmCP_DFY_DATA_0 }, - { 0x2598ffff, mmCP_DFY_DATA_0 }, - { 0x05540001, mmCP_DFY_DATA_0 }, - { 0x7d91800c, mmCP_DFY_DATA_0 }, - { 0x95c00003, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x9580fff8, mmCP_DFY_DATA_0 }, - { 0x09780001, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x65180001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9580005d, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4253247, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x04200101, mmCP_DFY_DATA_0 }, - { 0x96400058, mmCP_DFY_DATA_0 }, - { 0x7dc24001, mmCP_DFY_DATA_0 }, - { 0xc41d3248, mmCP_DFY_DATA_0 }, - { 0x25dc000f, mmCP_DFY_DATA_0 }, - { 0x7df9c00c, mmCP_DFY_DATA_0 }, - { 0x95c00053, mmCP_DFY_DATA_0 }, - { 0x94c00002, mmCP_DFY_DATA_0 }, - { 0x04200102, mmCP_DFY_DATA_0 }, - { 0x7e41c001, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x1a70003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1a7000e8, mmCP_DFY_DATA_0 }, - { 0x33240003, mmCP_DFY_DATA_0 }, - { 0x9a400046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xc4253260, mmCP_DFY_DATA_0 }, - { 0x1a7000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x80001a21, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x7f270009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x266400ff, mmCP_DFY_DATA_0 }, - { 0x9a40fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x19f003e6, mmCP_DFY_DATA_0 }, - { 0x27240003, mmCP_DFY_DATA_0 }, - { 0x12640004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x19f000e8, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7e724001, mmCP_DFY_DATA_0 }, - { 0x06640002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19f00064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x16700005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x80001a0f, mmCP_DFY_DATA_0 }, - { 0x16700005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7e730002, mmCP_DFY_DATA_0 }, - { 0xc4252083, mmCP_DFY_DATA_0 }, - { 0x7e724005, mmCP_DFY_DATA_0 }, - { 0x26640001, mmCP_DFY_DATA_0 }, - { 0x9a40ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc425325b, mmCP_DFY_DATA_0 }, - { 0x267000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffca, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0x80001a22, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x9940ff9f, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x8c001a31, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0xd8080278, mmCP_DFY_DATA_0 }, - { 0xd8080280, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc4213246, mmCP_DFY_DATA_0 }, - { 0xc4253245, mmCP_DFY_DATA_0 }, - { 0x52200020, mmCP_DFY_DATA_0 }, - { 0x7e26401a, mmCP_DFY_DATA_0 }, - { 0x46640400, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x04203000, mmCP_DFY_DATA_0 }, - { 0xce013267, mmCP_DFY_DATA_0 }, - { 0xc4213267, mmCP_DFY_DATA_0 }, - { 0x9a000001, mmCP_DFY_DATA_0 }, - { 0x1b180057, mmCP_DFY_DATA_0 }, - { 0x1b200213, mmCP_DFY_DATA_0 }, - { 0x1b300199, mmCP_DFY_DATA_0 }, - { 0x7e1a000a, mmCP_DFY_DATA_0 }, - { 0x7e32000a, mmCP_DFY_DATA_0 }, - { 0xce000024, mmCP_DFY_DATA_0 }, - { 0xc4970258, mmCP_DFY_DATA_0 }, - { 0xc4930250, mmCP_DFY_DATA_0 }, - { 0x51540020, mmCP_DFY_DATA_0 }, - { 0x7d15001a, mmCP_DFY_DATA_0 }, - { 0xc4af0280, mmCP_DFY_DATA_0 }, - { 0xc4b30278, mmCP_DFY_DATA_0 }, - { 0x52ec0020, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0x04140020, mmCP_DFY_DATA_0 }, - { 0x04280000, mmCP_DFY_DATA_0 }, - { 0x65180001, mmCP_DFY_DATA_0 }, - { 0x95800060, mmCP_DFY_DATA_0 }, - { 0x8c001628, mmCP_DFY_DATA_0 }, - { 0xc4193247, mmCP_DFY_DATA_0 }, - { 0x25980001, mmCP_DFY_DATA_0 }, - { 0x04200101, mmCP_DFY_DATA_0 }, - { 0x94c00005, mmCP_DFY_DATA_0 }, - { 0x30f00005, mmCP_DFY_DATA_0 }, - { 0x04200005, mmCP_DFY_DATA_0 }, - { 0x9b000002, mmCP_DFY_DATA_0 }, - { 0x04200102, mmCP_DFY_DATA_0 }, - { 0x95800056, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x1bb0003f, mmCP_DFY_DATA_0 }, - { 0x97000049, mmCP_DFY_DATA_0 }, - { 0x1bb000e8, mmCP_DFY_DATA_0 }, - { 0x33380003, mmCP_DFY_DATA_0 }, - { 0x9b800046, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x9700000a, mmCP_DFY_DATA_0 }, - { 0xc4393260, mmCP_DFY_DATA_0 }, - { 0x1bb000e4, mmCP_DFY_DATA_0 }, - { 0x33300004, mmCP_DFY_DATA_0 }, - { 0x97000040, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0x80001aa2, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc033ffff, mmCP_DFY_DATA_0 }, - { 0x2f3000ff, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x7f3b0009, mmCP_DFY_DATA_0 }, - { 0xcf01325b, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b800ff, mmCP_DFY_DATA_0 }, - { 0x9b80fffe, mmCP_DFY_DATA_0 }, - { 0xd8c00033, mmCP_DFY_DATA_0 }, - { 0xc4300009, mmCP_DFY_DATA_0 }, - { 0x27300008, mmCP_DFY_DATA_0 }, - { 0x9700fffe, mmCP_DFY_DATA_0 }, - { 0x19f003e6, mmCP_DFY_DATA_0 }, - { 0x27380003, mmCP_DFY_DATA_0 }, - { 0x13b80004, mmCP_DFY_DATA_0 }, - { 0x27300003, mmCP_DFY_DATA_0 }, - { 0x13300003, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x19f000e8, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x13300001, mmCP_DFY_DATA_0 }, - { 0x7fb38001, mmCP_DFY_DATA_0 }, - { 0x07b80002, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0x19f00064, mmCP_DFY_DATA_0 }, - { 0x33300002, mmCP_DFY_DATA_0 }, - { 0x97000009, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0x07300003, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x0b300003, mmCP_DFY_DATA_0 }, - { 0x80001a90, mmCP_DFY_DATA_0 }, - { 0x17b00005, mmCP_DFY_DATA_0 }, - { 0xcf012082, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcc01203f, mmCP_DFY_DATA_0 }, - { 0x13300005, mmCP_DFY_DATA_0 }, - { 0x7fb30002, mmCP_DFY_DATA_0 }, - { 0xc4392083, mmCP_DFY_DATA_0 }, - { 0x7fb38005, mmCP_DFY_DATA_0 }, - { 0x27b80001, mmCP_DFY_DATA_0 }, - { 0x9b80ffdf, mmCP_DFY_DATA_0 }, - { 0xd8c00034, mmCP_DFY_DATA_0 }, - { 0xcdc00013, mmCP_DFY_DATA_0 }, - { 0xc431325d, mmCP_DFY_DATA_0 }, - { 0x27300010, mmCP_DFY_DATA_0 }, - { 0x9b00fffe, mmCP_DFY_DATA_0 }, - { 0xc439325b, mmCP_DFY_DATA_0 }, - { 0x27b000ff, mmCP_DFY_DATA_0 }, - { 0x9b00ffca, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x2030007b, mmCP_DFY_DATA_0 }, - { 0xcf00325b, mmCP_DFY_DATA_0 }, - { 0x80001aa3, mmCP_DFY_DATA_0 }, - { 0xce01325d, mmCP_DFY_DATA_0 }, - { 0x04300001, mmCP_DFY_DATA_0 }, - { 0x7f2b0014, mmCP_DFY_DATA_0 }, - { 0x7ef2c01a, mmCP_DFY_DATA_0 }, - { 0xc49b02e9, mmCP_DFY_DATA_0 }, - { 0x99800005, mmCP_DFY_DATA_0 }, - { 0xd2400025, mmCP_DFY_DATA_0 }, - { 0x4664001c, mmCP_DFY_DATA_0 }, - { 0xd8000026, mmCP_DFY_DATA_0 }, - { 0xd8400027, mmCP_DFY_DATA_0 }, - { 0x06a80001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x55100001, mmCP_DFY_DATA_0 }, - { 0x9940ff9c, mmCP_DFY_DATA_0 }, - { 0xc49b02e9, mmCP_DFY_DATA_0 }, - { 0x99800008, mmCP_DFY_DATA_0 }, - { 0xc430000e, mmCP_DFY_DATA_0 }, - { 0x2b300008, mmCP_DFY_DATA_0 }, - { 0xcf000013, mmCP_DFY_DATA_0 }, - { 0x04302000, mmCP_DFY_DATA_0 }, - { 0xcf013267, mmCP_DFY_DATA_0 }, - { 0xc4313267, mmCP_DFY_DATA_0 }, - { 0x97000001, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0x244c00ff, mmCP_DFY_DATA_0 }, - { 0xcc4c0200, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc44f0200, mmCP_DFY_DATA_0 }, - { 0xc410000b, mmCP_DFY_DATA_0 }, - { 0xc414000c, mmCP_DFY_DATA_0 }, - { 0x7d158010, mmCP_DFY_DATA_0 }, - { 0x059cc000, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccdd0000, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c0037, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0xcc000049, mmCP_DFY_DATA_0 }, - { 0xc40c003a, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x24d00001, mmCP_DFY_DATA_0 }, - { 0x9500e69a, mmCP_DFY_DATA_0 }, - { 0x18d0003b, mmCP_DFY_DATA_0 }, - { 0x18d40021, mmCP_DFY_DATA_0 }, - { 0x99400006, mmCP_DFY_DATA_0 }, - { 0xd840004a, mmCP_DFY_DATA_0 }, - { 0xc40c003c, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0x14cc0001, mmCP_DFY_DATA_0 }, - { 0x94c00028, mmCP_DFY_DATA_0 }, - { 0xd8000033, mmCP_DFY_DATA_0 }, - { 0xc438000b, mmCP_DFY_DATA_0 }, - { 0xc43c0009, mmCP_DFY_DATA_0 }, - { 0x27fc0001, mmCP_DFY_DATA_0 }, - { 0x97c0fffe, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd841c07f, mmCP_DFY_DATA_0 }, - { 0xc43dc07f, mmCP_DFY_DATA_0 }, - { 0x1bfc0078, mmCP_DFY_DATA_0 }, - { 0x7ffbc00c, mmCP_DFY_DATA_0 }, - { 0x97c0fffd, mmCP_DFY_DATA_0 }, - { 0x99000004, mmCP_DFY_DATA_0 }, - { 0xc0120840, mmCP_DFY_DATA_0 }, - { 0x282c0040, mmCP_DFY_DATA_0 }, - { 0x80001ae8, mmCP_DFY_DATA_0 }, - { 0xc0121841, mmCP_DFY_DATA_0 }, - { 0x282c001a, mmCP_DFY_DATA_0 }, - { 0xcd01c07c, mmCP_DFY_DATA_0 }, - { 0xcc01c07d, mmCP_DFY_DATA_0 }, - { 0xcc01c08c, mmCP_DFY_DATA_0 }, - { 0xcc01c079, mmCP_DFY_DATA_0 }, - { 0xcc01c07e, mmCP_DFY_DATA_0 }, - { 0x04200004, mmCP_DFY_DATA_0 }, - { 0xcec0001b, mmCP_DFY_DATA_0 }, - { 0xd8400021, mmCP_DFY_DATA_0 }, - { 0x0a200001, mmCP_DFY_DATA_0 }, - { 0x9a00ffff, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0x166c001f, mmCP_DFY_DATA_0 }, - { 0x04200004, mmCP_DFY_DATA_0 }, - { 0x9ac0fffb, mmCP_DFY_DATA_0 }, - { 0xc434000f, mmCP_DFY_DATA_0 }, - { 0x9b40ffff, mmCP_DFY_DATA_0 }, - { 0xd801c07f, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xc425c07f, mmCP_DFY_DATA_0 }, - { 0xce400078, mmCP_DFY_DATA_0 }, - { 0xd8000034, mmCP_DFY_DATA_0 }, - { 0x9940e66b, mmCP_DFY_DATA_0 }, - { 0xd800004a, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc40c0036, mmCP_DFY_DATA_0 }, - { 0x24d00001, mmCP_DFY_DATA_0 }, - { 0x9900fffe, mmCP_DFY_DATA_0 }, - { 0x18cc0021, mmCP_DFY_DATA_0 }, - { 0xccc00047, mmCP_DFY_DATA_0 }, - { 0xcc000046, mmCP_DFY_DATA_0 }, - { 0xc40c0039, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0xc40c003d, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0x7c40c001, mmCP_DFY_DATA_0 }, - { 0x24d003ff, mmCP_DFY_DATA_0 }, - { 0x18d47fea, mmCP_DFY_DATA_0 }, - { 0x18d87ff4, mmCP_DFY_DATA_0 }, - { 0xcd00004c, mmCP_DFY_DATA_0 }, - { 0xcd40004e, mmCP_DFY_DATA_0 }, - { 0xcd80004d, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd41c405, mmCP_DFY_DATA_0 }, - { 0xc02a0001, mmCP_DFY_DATA_0 }, - { 0x2aa80001, mmCP_DFY_DATA_0 }, - { 0xce800013, mmCP_DFY_DATA_0 }, - { 0xcd01c406, mmCP_DFY_DATA_0 }, - { 0xcc01c406, mmCP_DFY_DATA_0 }, - { 0xcc01c406, mmCP_DFY_DATA_0 }, - { 0xc40c0006, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0xc414000e, mmCP_DFY_DATA_0 }, - { 0x29540008, mmCP_DFY_DATA_0 }, - { 0x295c0001, mmCP_DFY_DATA_0 }, - { 0xcd400013, mmCP_DFY_DATA_0 }, - { 0xd8c1325e, mmCP_DFY_DATA_0 }, - { 0xcdc0001a, mmCP_DFY_DATA_0 }, - { 0x11980002, mmCP_DFY_DATA_0 }, - { 0x4110000c, mmCP_DFY_DATA_0 }, - { 0xc0160800, mmCP_DFY_DATA_0 }, - { 0x7d15000a, mmCP_DFY_DATA_0 }, - { 0xc0164010, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xcd41c078, mmCP_DFY_DATA_0 }, - { 0xcc01c080, mmCP_DFY_DATA_0 }, - { 0xcc01c081, mmCP_DFY_DATA_0 }, - { 0xcd81c082, mmCP_DFY_DATA_0 }, - { 0xcc01c083, mmCP_DFY_DATA_0 }, - { 0xcd01c084, mmCP_DFY_DATA_0 }, - { 0xc40c0006, mmCP_DFY_DATA_0 }, - { 0x98c0ffff, mmCP_DFY_DATA_0 }, - { 0xd8400048, mmCP_DFY_DATA_0 }, - { 0xc40c003b, mmCP_DFY_DATA_0 }, - { 0x94c0ffff, mmCP_DFY_DATA_0 }, - { 0x80000c16, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xd801c40a, mmCP_DFY_DATA_0 }, - { 0xd901c40d, mmCP_DFY_DATA_0 }, - { 0xd801c410, mmCP_DFY_DATA_0 }, - { 0xd801c40e, mmCP_DFY_DATA_0 }, - { 0xd801c40f, mmCP_DFY_DATA_0 }, - { 0xc40c0040, mmCP_DFY_DATA_0 }, - { 0x04140001, mmCP_DFY_DATA_0 }, - { 0x09540001, mmCP_DFY_DATA_0 }, - { 0x9940ffff, mmCP_DFY_DATA_0 }, - { 0x04140096, mmCP_DFY_DATA_0 }, - { 0xd8400013, mmCP_DFY_DATA_0 }, - { 0xccc1c400, mmCP_DFY_DATA_0 }, - { 0xc411c401, mmCP_DFY_DATA_0 }, - { 0x9500fffa, mmCP_DFY_DATA_0 }, - { 0xc424003e, mmCP_DFY_DATA_0 }, - { 0x04d00001, mmCP_DFY_DATA_0 }, - { 0x11100002, mmCP_DFY_DATA_0 }, - { 0xcd01c40c, mmCP_DFY_DATA_0 }, - { 0xc0180034, mmCP_DFY_DATA_0 }, - { 0xcd81c411, mmCP_DFY_DATA_0 }, - { 0xd841c414, mmCP_DFY_DATA_0 }, - { 0x0a540001, mmCP_DFY_DATA_0 }, - { 0xcd41c412, mmCP_DFY_DATA_0 }, - { 0x2468000f, mmCP_DFY_DATA_0 }, - { 0xc419c416, mmCP_DFY_DATA_0 }, - { 0x41980003, mmCP_DFY_DATA_0 }, - { 0xc41c003f, mmCP_DFY_DATA_0 }, - { 0x7dda0001, mmCP_DFY_DATA_0 }, - { 0x12200002, mmCP_DFY_DATA_0 }, - { 0x10cc0002, mmCP_DFY_DATA_0 }, - { 0xccc1c40c, mmCP_DFY_DATA_0 }, - { 0xd901c411, mmCP_DFY_DATA_0 }, - { 0xce41c412, mmCP_DFY_DATA_0 }, - { 0xd8800013, mmCP_DFY_DATA_0 }, - { 0xce292e40, mmCP_DFY_DATA_0 }, - { 0xcc412e01, mmCP_DFY_DATA_0 }, - { 0xcc412e02, mmCP_DFY_DATA_0 }, - { 0xcc412e03, mmCP_DFY_DATA_0 }, - { 0xcc412e00, mmCP_DFY_DATA_0 }, - { 0x80000aa7, mmCP_DFY_DATA_0 }, - { 0xc43c0007, mmCP_DFY_DATA_0 }, - { 0xdc120000, mmCP_DFY_DATA_0 }, - { 0x31144000, mmCP_DFY_DATA_0 }, - { 0x95400005, mmCP_DFY_DATA_0 }, - { 0xdc030000, mmCP_DFY_DATA_0 }, - { 0xd800002a, mmCP_DFY_DATA_0 }, - { 0xcc3c000c, mmCP_DFY_DATA_0 }, - { 0x80001b70, mmCP_DFY_DATA_0 }, - { 0x33f80003, mmCP_DFY_DATA_0 }, - { 0xd4400078, mmCP_DFY_DATA_0 }, - { 0x9780e601, mmCP_DFY_DATA_0 }, - { 0x188cfff0, mmCP_DFY_DATA_0 }, - { 0x04e40002, mmCP_DFY_DATA_0 }, - { 0x80001190, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x96400006, mmCP_DFY_DATA_0 }, - { 0x90000000, mmCP_DFY_DATA_0 }, - { 0xc424005e, mmCP_DFY_DATA_0 }, - { 0x96400003, mmCP_DFY_DATA_0 }, - { 0x7c408001, mmCP_DFY_DATA_0 }, - { 0x88000000, mmCP_DFY_DATA_0 }, - { 0x80001b74, mmCP_DFY_DATA_0 }, - { 0x80000168, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0x92100004, mmCP_DFY_DATA_0 }, - { 0x92110501, mmCP_DFY_DATA_0 }, - { 0x92120206, mmCP_DFY_DATA_0 }, - { 0x92130703, mmCP_DFY_DATA_0 }, - { 0x92100400, mmCP_DFY_DATA_0 }, - { 0x92110105, mmCP_DFY_DATA_0 }, - { 0x92120602, mmCP_DFY_DATA_0 }, - { 0x92130307, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x54106500, mmCP_DFY_ADDR_LO }, - { 0x7e000200, mmCP_DFY_DATA_0 }, - { 0x7e020204, mmCP_DFY_DATA_0 }, - { 0xc00a0505, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xbf8c007f, mmCP_DFY_DATA_0 }, - { 0xb8900904, mmCP_DFY_DATA_0 }, - { 0xb8911a04, mmCP_DFY_DATA_0 }, - { 0xb8920304, mmCP_DFY_DATA_0 }, - { 0xb8930b44, mmCP_DFY_DATA_0 }, - { 0x921c0d0c, mmCP_DFY_DATA_0 }, - { 0x921c1c13, mmCP_DFY_DATA_0 }, - { 0x921d0c12, mmCP_DFY_DATA_0 }, - { 0x811c1d1c, mmCP_DFY_DATA_0 }, - { 0x811c111c, mmCP_DFY_DATA_0 }, - { 0x921cff1c, mmCP_DFY_DATA_0 }, - { 0x00000400, mmCP_DFY_DATA_0 }, - { 0x921dff10, mmCP_DFY_DATA_0 }, - { 0x00000100, mmCP_DFY_DATA_0 }, - { 0x81181d1c, mmCP_DFY_DATA_0 }, - { 0x7e040218, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050002, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050102, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050002, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050102, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050002, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0701000, mmCP_DFY_DATA_0 }, - { 0x80050102, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xe0501000, mmCP_DFY_DATA_0 }, - { 0x80050302, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x54106900, mmCP_DFY_ADDR_LO }, - { 0x7e080200, mmCP_DFY_DATA_0 }, - { 0x7e100204, mmCP_DFY_DATA_0 }, - { 0xbefc00ff, mmCP_DFY_DATA_0 }, - { 0x00010000, mmCP_DFY_DATA_0 }, - { 0x24200087, mmCP_DFY_DATA_0 }, - { 0x262200ff, mmCP_DFY_DATA_0 }, - { 0x000001f0, mmCP_DFY_DATA_0 }, - { 0x20222282, mmCP_DFY_DATA_0 }, - { 0x28182111, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000040c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd81a0000, mmCP_DFY_DATA_0 }, - { 0x0000080c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xd86c0000, mmCP_DFY_DATA_0 }, - { 0x1100000c, mmCP_DFY_DATA_0 }, - { 0xbf810000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x000000b4, mmCP_DFY_ADDR_HI }, - { 0x54116f00, mmCP_DFY_ADDR_LO }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fe8, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000041, mmCP_DFY_DATA_0 }, - { 0x0000000c, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54116f00, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb454105e, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x000000c0, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54117300, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4541065, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000500, mmCP_DFY_DATA_0 }, - { 0x0000001c, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54117700, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xc0310800, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000040, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4541069, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000444, mmCP_DFY_DATA_0 }, - { 0x0000008a, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x07808000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0xffffffff, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000002, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0xaaaaaaaa, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x55555555, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee40, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000010, mmCP_DFY_DATA_0 }, - { 0x00000001, mmCP_DFY_DATA_0 }, - { 0x00000004, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x54117b00, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00005301, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0xb4540fef, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x540fee20, mmCP_DFY_DATA_0 }, - { 0x000000b4, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x08000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, - { 0x00000000, mmCP_DFY_DATA_0 }, + { 0x00000000, 0xFFFFFFFF }, +}; + +static const PWR_DFY_Section pwr_virus_section1 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x540fe800, + .dfy_data = { + 0x7e000200, 0x7e020201, 0x7e040204, 0x7e060205, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, + 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0xbf810000, 0x00000000, 0x00000000, 0x00000000, + 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54106f00, 0x000400b4, 0x00004000, 0x00804fac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 416 +}; + +static const PWR_DFY_Section pwr_virus_section2 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x540fef00, + .dfy_data = { + 0xc0031502, 0x00001e00, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 16 +}; + +static const PWR_DFY_Section pwr_virus_section3 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x540ff000, + .dfy_data = { + 0xc424000b, 0x80000145, 0x94800001, 0x94c00001, 0x95000001, 0x95400001, 0x95800001, 0xdc810000, + 0xdcc10000, 0xdd010000, 0xdd410000, 0xdd810000, 0xc4080061, 0xd8400013, 0xd8000003, 0xc40c0001, + 0x24ccffff, 0x3cd08000, 0x9500fffd, 0x1cd0ffcf, 0x7d018001, 0xc4140004, 0x050c0019, 0xd8400008, + 0x84c00000, 0x80000023, 0x80000067, 0x8000006a, 0x8000006d, 0x80000079, 0x80000084, 0x8000008f, + 0x80000099, 0x800000a0, 0x800000af, 0xd8400053, 0xc4080007, 0x388c0001, 0x08880002, 0x04100003, + 0x94c00005, 0x98800003, 0x04100004, 0x8000002d, 0x04100005, 0x8c00003f, 0x8c000043, 0x28cc0000, + 0xccc00050, 0x8c000055, 0x28080001, 0xcc000004, 0x7d808001, 0xd8400013, 0xd88130b8, 0xcd400008, + 0xdc180000, 0xdc140000, 0xdc100000, 0xdc0c0000, 0xcc800005, 0xdc080000, 0x80000168, 0xc40c000e, + 0x28cc0008, 0xccc00013, 0x90000000, 0xcd013278, 0xc4113278, 0x95000001, 0x24cc0700, 0xd8400029, + 0xc4113255, 0xcd01324f, 0xc4113254, 0x1d10ffdf, 0xcd013254, 0x10cc0014, 0x1d10c017, 0x7d0d000a, + 0xd8400013, 0xd8400008, 0xcd0130b7, 0x14cc0010, 0x90000000, 0xd9c00036, 0x8000005d, 0xd8400013, + 0xc00c4000, 0xccc130b5, 0xc40c000e, 0x28cc0008, 0xccc00013, 0xc40c0021, 0x14d00011, 0x9500fffe, + 0xdc030000, 0xd800000c, 0xd800000d, 0xc40c005e, 0x94c01b10, 0xd8400013, 0x90000000, 0xc00e0080, + 0xccc130b5, 0x8000013b, 0xc00e0800, 0xccc130b5, 0x8000013b, 0xd8400053, 0x04100006, 0x8c00003f, + 0x8c000043, 0x28cc0000, 0xccc00050, 0x8c000055, 0x280c0008, 0xccc00052, 0xd8000021, 0x28180039, + 0x80000034, 0xd8400053, 0x04100007, 0x8c00003f, 0x8c000043, 0x28cc0001, 0xccc00050, 0x8c000055, + 0x280c0010, 0xccc00052, 0x28180039, 0x80000034, 0xd8400053, 0x04100008, 0x8c00003f, 0x8c000043, + 0x28cc0003, 0xccc00050, 0x8c000055, 0x280c0020, 0xccc00052, 0x28180039, 0x80000034, 0xdc030000, + 0xd8000069, 0x28080001, 0xc428000d, 0x7ca88004, 0xcc800079, 0x04280001, 0xcc00006f, 0x8000013b, + 0x80000034, 0x04100010, 0x8c00003f, 0x8c000043, 0xccc00078, 0x8c000055, 0x28180080, 0x80000034, + 0x04100001, 0xc40c000e, 0x28cc0008, 0xccc00013, 0xcd013278, 0xc4113278, 0x95000001, 0xc00c4000, + 0xc4113254, 0x1d10c017, 0xd8400013, 0xd8400008, 0xccc130b5, 0xcd0130b7, 0x8000013b, 0x95c00001, + 0x96000001, 0x96400001, 0x96800001, 0x96c00001, 0x97000001, 0x97400001, 0x97800001, 0x97c00001, + 0xdc810000, 0xc40c000c, 0xcd4c0380, 0xcdcc0388, 0x55dc0020, 0xcdcc038c, 0xce0c0390, 0x56200020, + 0xce0c0394, 0xce4c0398, 0x56640020, 0xce4c039c, 0xce8c03a0, 0x56a80020, 0xce8c03a4, 0xcecc03a8, + 0x56ec0020, 0xcecc03ac, 0xcf0c03b0, 0x57300020, 0xcf0c03b4, 0xcf4c03b8, 0x57740020, 0xcf4c03bc, + 0xcf8c03c0, 0x57b80020, 0xcf8c03c4, 0xcfcc03c8, 0x57fc0020, 0xcfcc03cc, 0xd9000033, 0xc41c0009, + 0x25dc0010, 0x95c0fffe, 0xd8400013, 0xc41c000c, 0x05dc002f, 0xcdc12009, 0xc41d200a, 0xd8400013, + 0xcc012009, 0xd9000034, 0x25e01c00, 0x12200013, 0x25e40300, 0x12640008, 0x25e800c0, 0x12a80002, + 0x25ec003f, 0x7e25c00a, 0x7eae400a, 0x7de5c00a, 0xddc10000, 0xc02ee000, 0xcec1c200, 0xc40c005f, + 0xccc00037, 0x24d000ff, 0x31100006, 0x9500007b, 0x8c000190, 0xdc1c0000, 0xd8400013, 0xcdc1c200, + 0xc40c000c, 0xc4df0388, 0xc4d7038c, 0x51540020, 0x7d5dc01a, 0xc4e30390, 0xc4d70394, 0x51540020, + 0x7d62001a, 0xc4e70398, 0xc4d7039c, 0x51540020, 0x7d66401a, 0xc4eb03a0, 0xc4d703a4, 0x51540020, + 0x7d6a801a, 0xc4ef03a8, 0xc4d703ac, 0x51540020, 0x7d6ec01a, 0xc4f303b0, 0xc4d703b4, 0x51540020, + 0x7d73001a, 0xc4f703b8, 0xc4d703bc, 0x51540020, 0x7d77401a, 0xc4fb03c0, 0xc4d703c4, 0x51540020, + 0x7d7b801a, 0xc4ff03c8, 0xc4d703cc, 0x51540020, 0x7d7fc01a, 0xdc080000, 0xcc800013, 0xc4d70380, + 0xc4080001, 0x1c88001c, 0xcd400008, 0xc40c0083, 0x94c00010, 0xdc0e0000, 0x94c0000e, 0xc40c0082, + 0x24d00001, 0x9900000b, 0x18cc01e3, 0x3cd00004, 0x95000008, 0xc40c0085, 0x18cc006a, 0x98c00005, + 0xc40c0082, 0x18cc01e3, 0x3cd00004, 0x9900fffa, 0xdc180000, 0xdc140000, 0xdc100000, 0xdc0c0000, + 0xcc800004, 0xdc080000, 0x90000000, 0xc4080001, 0x1c88001c, 0xcd400008, 0xdc180000, 0xdc140000, + 0xdc100000, 0xdc0c0000, 0xcc800004, 0xdc080000, 0x90000000, 0xd8400051, 0xc428000c, 0x04180018, + 0x32640002, 0x9a80001f, 0x9a40001e, 0xcd800013, 0xc4293265, 0x040c0000, 0x1aac0027, 0x2aa80080, + 0xce813265, 0x9ac00017, 0xd80002f1, 0x04080002, 0x08880001, 0xd8080250, 0xd8080258, 0xd8080230, + 0xd8080238, 0xd8080240, 0xd8080248, 0xd8080268, 0xd8080270, 0xd8080278, 0xd8080280, 0xd8080228, + 0xd8000367, 0x9880fff3, 0x04080010, 0x08880001, 0xd80c0309, 0xd80c0319, 0x04cc0001, 0x9880fffc, + 0x7c408001, 0x88000000, 0xc00e0100, 0xd8400013, 0xd8400008, 0xccc130b5, 0x8000016e, 0xc4180032, + 0x29980008, 0xcd800013, 0x95800001, 0x7c40c001, 0x18d0003f, 0x24d4001f, 0x24d80001, 0x155c0001, + 0x05e80180, 0x9900000b, 0x202c003d, 0xcd800010, 0xcec1325b, 0xc42d325b, 0x96c00001, 0x86800000, + 0x80000168, 0x80000aa7, 0x80000bfc, 0x800012e9, 0xc4200007, 0x0a200001, 0xce000010, 0x80001b70, + 0x7c40c001, 0x8c000190, 0xc410001b, 0xd8000032, 0xd8000031, 0x9900091a, 0x7c408001, 0x88000000, + 0x24d000ff, 0x05280196, 0x18d4fe04, 0x29540008, 0xcd400013, 0x86800000, 0x800001b4, 0x8000032b, + 0x80000350, 0x80000352, 0x8000035f, 0x80000701, 0x8000047c, 0x8000019f, 0x80000800, 0xc419325b, + 0x1d98001f, 0xcd81325b, 0x8c00003f, 0xc4140004, 0xd8400008, 0x04100002, 0x8c000043, 0x28cc0002, + 0xccc00050, 0xc43c0044, 0x27fc0003, 0x9bc00002, 0x97c00006, 0xc00c4000, 0xccc130b5, 0x8c000055, + 0xd8400013, 0xd88130b8, 0xcd400008, 0x90000000, 0xd8400008, 0xcd400013, 0x7d40c001, 0xd8400028, + 0xd8400029, 0xd9400036, 0xc4193256, 0xc41d3254, 0x15540008, 0xcd400009, 0xcd40005b, 0xcd40005e, + 0xcd40005d, 0xd840006d, 0xc421325a, 0xc42d3249, 0x11540015, 0x19a4003c, 0x1998003f, 0x1af0007d, + 0x11dc000b, 0x1264001f, 0x15dc000d, 0x7d65400a, 0x13300018, 0x1a38003f, 0x7dd5c00a, 0x7df1c00a, + 0xcd800045, 0xcdc00100, 0xc411326a, 0xc415326b, 0xc419326c, 0xc41d326d, 0xc425326e, 0xc4293279, + 0xce800077, 0xcd000056, 0xcd400057, 0xcd800058, 0xcdc00059, 0xc4193265, 0x259c8000, 0x99c00004, + 0xce40005a, 0x29988000, 0xcd813265, 0xc4113248, 0x2510000f, 0xcd000073, 0xc418000d, 0xc411326f, + 0x17300019, 0x97000009, 0x25140fff, 0x95400007, 0xd800003a, 0x8c001b6d, 0xc4153279, 0xcd400077, + 0xcd00005f, 0xd8000075, 0x26f00001, 0x15100010, 0x7d190004, 0xcd000035, 0x97000035, 0x1af07fe8, + 0xd8800013, 0xd8400010, 0xd8400008, 0xcf00000d, 0xcf00000a, 0x8c001427, 0x04340022, 0x07740001, + 0x04300010, 0xdf430000, 0x7c434001, 0x7c408001, 0xd4412e01, 0x0434001e, 0xdf430000, 0xd4400078, + 0xdf030000, 0xd4412e40, 0xd8400013, 0xcc41c030, 0xcc41c031, 0xc43dc031, 0xccc00013, 0x04343000, + 0xc4113246, 0xc41d3245, 0xcf413267, 0x51100020, 0x7dd1c01a, 0xc4353267, 0x45dc0160, 0xc810001f, + 0x1b4c0057, 0x1b700213, 0x1b740199, 0x7f4f400a, 0x7f73400a, 0x55180020, 0x2198003f, 0xd1c00025, + 0xcf400024, 0xcd000026, 0xcd800026, 0xd8400027, 0x9bc00001, 0x248dfffe, 0xd8800013, 0xccc12e00, + 0x7c434001, 0x7c434001, 0x8c00142b, 0xc43c000e, 0x1af4007d, 0x2bfc0008, 0x33740003, 0x26d80001, + 0xcfc00013, 0x1ae8003e, 0x9680000c, 0xc4253277, 0x26680001, 0x96800009, 0x2a640002, 0xce413277, + 0xd8400013, 0xc4253348, 0xce413348, 0xc4253348, 0x96400001, 0xcfc00013, 0x9b400003, 0x958000d8, + 0x80000315, 0xc4253277, 0x04303000, 0x26680001, 0xcf013267, 0xc4193246, 0xc41d3245, 0xc4313267, + 0x96800041, 0x51980020, 0x1b342010, 0x7d9d801a, 0x1714000c, 0x25540800, 0x1b30c012, 0x459801b0, + 0x7d77400a, 0x7f37000a, 0x2b300000, 0xcf00001c, 0xd180001e, 0xd8400021, 0x04240010, 0x199c01e2, + 0x7e5e4002, 0x3e5c0004, 0x3e540002, 0xc428000f, 0x9a80ffff, 0x95c00006, 0xc80c0011, 0xc8140011, + 0x54d00020, 0x55580020, 0x80000282, 0x95400015, 0xc80c0011, 0x0a640002, 0x041c0001, 0x45980008, + 0x54d00020, 0x96400004, 0xc8140011, 0x45980004, 0x041c0000, 0xcf00001c, 0xd180001e, 0xd8400021, + 0xc428000f, 0x9a80ffff, 0x99c00003, 0xc8180011, 0x80000282, 0xc8140011, 0x55580020, 0x80000282, + 0x45980004, 0xc80c0011, 0xcf00001c, 0xd180001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc8100011, + 0xc8140011, 0x55580020, 0xd8400013, 0xccc1334e, 0xcd01334f, 0xcd413350, 0xcd813351, 0xd881334d, + 0xcfc00013, 0xc4193273, 0xc41d3275, 0xc40d3271, 0xc4113270, 0xc4153274, 0x50cc0020, 0x7cd0c01a, + 0x7cdcc011, 0x05900008, 0xcd00006a, 0xcdc0006b, 0xc41d3272, 0x7d594002, 0x54d00020, 0xd8800013, + 0xccc12e23, 0xcd012e24, 0xcdc12e25, 0xcfc00013, 0xc4193246, 0xc41d3245, 0xc4313267, 0x15540002, + 0x51980020, 0x7d9d801a, 0xc81c001f, 0x1b340057, 0x1b280213, 0x1b300199, 0x45980198, 0x7f37000a, + 0x7f2b000a, 0x55e40020, 0xcf000024, 0xd1800025, 0xcdc00026, 0xce400026, 0xd8400027, 0xcd40000d, + 0xcd40000a, 0xc40d3249, 0x20cc003c, 0xccc13249, 0xc4113274, 0xdd430000, 0xc01e0001, 0x29dc0002, + 0x04280000, 0xd8000036, 0xcc400078, 0xcc400078, 0x2d540002, 0x95400022, 0x078c0000, 0x07d40000, + 0x8c00120d, 0x8c001239, 0x8c001232, 0x04f80000, 0x057c0000, 0xcdc00013, 0xc414000d, 0xc41c0019, + 0x7dd5c005, 0x25dc0001, 0xd840007c, 0xd8400074, 0xd8400069, 0xc40c005e, 0x94c018a6, 0xd4412e22, + 0xd800007c, 0xc40c005e, 0x94c018a2, 0x95c00007, 0xc40c0019, 0x7cd4c005, 0x24cc0001, 0x94c00008, + 0x9680fffc, 0x800002e3, 0xc40c0057, 0x7cd0c002, 0x94c00003, 0x9680fffd, 0x800002e3, 0xd8000069, + 0xcfc00013, 0xcd013273, 0xcd013275, 0xd8000074, 0xc414005e, 0x9540188f, 0xcfc00013, 0xc40d3249, + 0xc013cfff, 0x7cd0c009, 0xccc13249, 0x9680000b, 0xc40c0077, 0x38d00001, 0x99000006, 0x04cc0002, + 0xdcc30000, 0xc40c005e, 0x94c01882, 0xd4400078, 0xd800000d, 0x80000304, 0x7c41c001, 0x7c41c001, + 0xd840002f, 0xc41c0015, 0x95c0ffff, 0xd8400030, 0xc41c0016, 0x95c0ffff, 0xd8000030, 0xc41c0016, + 0x99c0ffff, 0xd800002f, 0xc41c0015, 0x99c0ffff, 0xc81c001f, 0x49980198, 0x55e40020, 0x459801a0, + 0xcf000024, 0xd1800025, 0xcdc00026, 0xce400026, 0xd8400027, 0x04302000, 0xcfc00013, 0xcf013267, + 0xc4313267, 0x96800004, 0x97000001, 0xd8000036, 0x80000329, 0xd8800013, 0xcc812e00, 0x04302000, + 0xcfc00013, 0xcf013267, 0xc4313267, 0x97000001, 0xc4193256, 0xc42d3249, 0x16ec001f, 0xd8000028, + 0xd800002b, 0x1998003e, 0xcec00031, 0xd8000036, 0xd8000010, 0x97800004, 0xd8400010, 0xce00000a, + 0x1a18003e, 0xcd800008, 0x90000000, 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0x04100000, + 0x7d43c001, 0xcd400013, 0xc4093249, 0x1888003e, 0x94800015, 0xd8400074, 0x8c000671, 0xcd400013, + 0x9a400006, 0xc419324c, 0x259c0001, 0x1598001f, 0x95c0000d, 0x9580000c, 0x99000003, 0xd8400036, + 0x04100001, 0xc40c0021, 0x14d80011, 0x24dc00ff, 0x31e00002, 0x31dc0003, 0x9580fff0, 0x9a000003, + 0x99c00002, 0xd9c00036, 0x94800004, 0xd8000074, 0xc418005e, 0x95801827, 0xcf800008, 0x90000000, + 0xd8800036, 0x90000000, 0xd8c00036, 0xc424000b, 0x32640002, 0x9a400004, 0xc4180014, 0x9580ffff, + 0xd840002f, 0xc40c0021, 0x14dc0011, 0x95c0fffe, 0xccc00037, 0x8c000190, 0x90000000, 0xd8400008, + 0xd800006d, 0xc41d3246, 0xc4193245, 0x51dc0020, 0x7d9d801a, 0xd8400028, 0xd8400029, 0xc420000b, + 0x32200002, 0x9a0000ad, 0x04200032, 0xd9000010, 0xde030000, 0xd8400033, 0x04080000, 0xc43c0009, + 0x27fc0002, 0x97c0fffe, 0xc42c0015, 0x96c0ffff, 0xd800002e, 0xc42d3249, 0x1af4003e, 0x9740004d, + 0xc428000d, 0xc4080060, 0x7ca88005, 0x24880001, 0x7f4b4009, 0x97400046, 0xc4313274, 0xc4100057, + 0x7d33400c, 0x97400009, 0x28240100, 0x7e6a4004, 0xce400079, 0x1eecffdd, 0xcec13249, 0xcf013273, + 0xcf013275, 0x800003c3, 0xc429326f, 0x1aa80030, 0x96800006, 0x28240001, 0xc428000d, 0x06a80008, + 0x7e6a8004, 0xce800035, 0xc41d3272, 0x25cc0001, 0x10cc0004, 0x19e80042, 0x25dc0006, 0x11dc0001, + 0x7e8e800a, 0x7de9c00a, 0xc40d3271, 0xc4293270, 0x50cc0020, 0x7ce8c01a, 0x7cd30011, 0x11e80007, + 0x2aa80000, 0xce80001c, 0xd300001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc4300011, 0x1b30003f, + 0x33300000, 0xc4240059, 0x1660001f, 0x7e320009, 0xc0328000, 0x7e72400a, 0x0430000c, 0x9a000002, + 0x04300008, 0xc02ac000, 0x7d310002, 0x17300002, 0x2aa87600, 0x7cd0c011, 0xcdc00024, 0xd0c00025, + 0xce800026, 0x04280222, 0xce800026, 0x96000002, 0xce400026, 0xd8400027, 0xc4280058, 0x22ec003d, + 0xcec13249, 0xcd013273, 0xce813275, 0xd800007b, 0xc8380018, 0x57b00020, 0x04343108, 0xc429325d, + 0x040c3000, 0x13740008, 0x2374007e, 0x32a80003, 0xccc13267, 0xc40d3267, 0x18ec0057, 0x18e40213, + 0x18cc0199, 0x7cecc00a, 0x7ce4c00a, 0x94800003, 0xd4400078, 0x800003e7, 0x04200022, 0xde030000, + 0xccc00024, 0xd1800025, 0xcf400026, 0xd4400026, 0xd8400027, 0x04200010, 0xde030000, 0xccc00024, + 0x45980104, 0xd1800025, 0xd4400026, 0xcf800026, 0xcf000026, 0xd8400027, 0x49980104, 0x9a80000a, + 0xc81c001f, 0x45980168, 0x55e00020, 0xccc00024, 0xd1800025, 0xcdc00026, 0xce000026, 0xd8400027, + 0x800003f2, 0x8c000448, 0xcd400013, 0x040c2000, 0xccc13267, 0xc40d3267, 0x94c00001, 0xc40d3249, + 0x18cc003e, 0xd8400030, 0xc42c0016, 0x96c0ffff, 0xd8000030, 0xc42c0016, 0x9ac0ffff, 0xd800002f, + 0xc42c0015, 0x9ac0ffff, 0xd8400034, 0xc4300025, 0xc4340024, 0xc4380081, 0xcf813279, 0xcf41326e, + 0xcf01326d, 0x94c0000d, 0x254c0700, 0xc424001e, 0x10cc0010, 0x1a641fe8, 0x28cc0726, 0x2a640200, + 0xd8400013, 0xccc1237b, 0x2264003f, 0xcd400013, 0xd8813260, 0xce41325b, 0xc4240033, 0xc4280034, + 0xd9000036, 0xd8000010, 0x8c001427, 0x96400006, 0xde430000, 0xce40000c, 0xc40c005e, 0x94c01755, + 0xd4400078, 0x9680000a, 0xce80000a, 0x06a80002, 0xd8400010, 0xde830000, 0xce80000d, 0xc40c005e, + 0x94c0174c, 0xd4400078, 0xd8000010, 0x8c00142b, 0xc4393265, 0x2bb80040, 0xd8400032, 0xcf813265, + 0xc4200012, 0x9a00ffff, 0xc4100044, 0x19180024, 0xc8100072, 0x551c003f, 0x99c00003, 0x95800010, + 0x8000043d, 0xc00c8000, 0xd840006c, 0x28200000, 0x8000043f, 0xc00c4000, 0x282000f0, 0xcd400013, + 0xd8400008, 0xc4113255, 0xcd01324f, 0xd8400013, 0xd88130b8, 0xccc130b5, 0xce000053, 0x90000000, + 0x195c00e8, 0xc4100004, 0x2555fff0, 0xc0360001, 0x042c0000, 0x29540001, 0xd8400008, 0x04240000, + 0x04280004, 0xc420000b, 0x32200002, 0x9a000009, 0xcd400013, 0xcec1c200, 0xc5e124dc, 0x0aa80001, + 0x7ef6c001, 0x7e624001, 0x96000001, 0x9a80fff9, 0xc02ee000, 0xcd400013, 0x2555fff0, 0xcec1c200, + 0x29540008, 0xc81c001f, 0xcd400013, 0x55e00020, 0xc42d3255, 0xc4353259, 0xd8013260, 0x45980158, + 0xccc00024, 0xd1800025, 0xcdc00026, 0xce000026, 0xd8400027, 0x49980158, 0x45980170, 0xc4200012, + 0x16200010, 0x9a00fffe, 0xccc00024, 0xd1800025, 0xc429324f, 0xce400026, 0xce800026, 0xcec00026, + 0xcf400026, 0xd8400027, 0xcd000008, 0x90000000, 0xc40d325b, 0x7d43c001, 0x195400e8, 0x1154000a, + 0x18dc00e8, 0x05e80488, 0x18d0006c, 0x18f807f0, 0x18e40077, 0x18ec0199, 0x7e6e400a, 0x86800000, + 0x8000048e, 0x80000494, 0x800004de, 0x80000685, 0x80000686, 0x800006ac, 0x1ccc001f, 0xccc1325b, + 0xc411325d, 0x251001ef, 0xcd01325d, 0x90000000, 0xc4293254, 0x1264000a, 0xc4300004, 0x7d79400a, + 0x7e7a400a, 0x52a8001e, 0x15180001, 0x7d69401a, 0x202c007d, 0xcec1325b, 0x95000008, 0x95800028, + 0xc42d3267, 0xc4193246, 0xc41d3245, 0x1aec0028, 0xc40d325c, 0x800004cc, 0xc42d3256, 0xc419324e, + 0x26e8003f, 0x1aec003e, 0x12f4000e, 0xc41d324d, 0xc40d324f, 0x7d75401a, 0x04100002, 0x7d290004, + 0x7f8f4001, 0x7f52800f, 0x51980020, 0x7d9d801a, 0x50e00002, 0x51980008, 0x9a800002, 0x800004d1, + 0x7d0dc002, 0x6665fc00, 0x7e5e401a, 0xcec00008, 0x7da1c011, 0xd140000b, 0xd1c00002, 0x2a644000, + 0xce400002, 0x7f534002, 0x6665fc00, 0x7e76401a, 0xd1800002, 0xce400002, 0x800004d7, 0xc42d325a, + 0xc4193258, 0x1aec003e, 0xc41d3257, 0xc4213259, 0x12f4000e, 0x7d75401a, 0x51980020, 0x52200002, + 0x7d9d801a, 0xcec00008, 0x7da1c011, 0xd140000b, 0xd1c00002, 0x2a644000, 0xce400002, 0x202c003d, + 0xcf000008, 0xcfc00013, 0xcec1325b, 0xc42d325b, 0x96c00001, 0x90000000, 0xc4193260, 0x259c0007, + 0x15980004, 0x05e804e3, 0x86800000, 0x800004e7, 0x800004f0, 0x80000505, 0x8000016a, 0xc4380004, + 0xcfc00013, 0xd8400008, 0xc435325d, 0xd801325b, 0x277401ef, 0xcf41325d, 0xcf800008, 0x90000000, + 0xc4380004, 0xd8400008, 0x8c000671, 0x9640fff4, 0x17e00008, 0xc418000d, 0xce000009, 0xd84131db, + 0xcf800008, 0xcd800009, 0xc430001e, 0xcfc00013, 0xc42d325b, 0x1b301ff8, 0x2b300400, 0x2330003f, + 0x26edf000, 0x7ef2c00a, 0xd8413260, 0xcec1325b, 0x90000000, 0x05a80507, 0x86800000, 0x8000050c, + 0x80000528, 0x8000057d, 0x800005c2, 0x800005f3, 0xc4380004, 0xd8400008, 0x8c000671, 0xcfc00013, + 0x9a400012, 0x1bd400e8, 0xc42c004a, 0xcd40005e, 0xc41c004d, 0xcec0005e, 0x99c0000c, 0xc4100019, + 0x7d150005, 0x25100001, 0x99000008, 0x8c00063b, 0xcfc00013, 0xc4113277, 0x2511fffd, 0xcd013277, + 0xd801326f, 0x80000624, 0x04240012, 0x1be00fe4, 0xce413260, 0xce000066, 0xcf800008, 0x90000000, + 0xd8400068, 0xc4380004, 0xd8400008, 0x8c000671, 0xcfc00013, 0x9a400013, 0x1bd400e8, 0xc42c004a, + 0xcd40005e, 0xc41c004d, 0xcec0005e, 0x99c0000d, 0xc4100019, 0x7d150005, 0x25100001, 0x99000009, + 0xd8400067, 0x8c00063b, 0xcfc00013, 0xc4113277, 0x2511fffd, 0xcd013277, 0xd801326f, 0x80000624, + 0x1bd400e8, 0xc42c0060, 0x7ed6c005, 0x26ec0001, 0xc4113271, 0xc4153270, 0xc4193272, 0xc41d3273, + 0x04280022, 0x51100020, 0x7d51401a, 0xc4113274, 0xc4213275, 0xc4253276, 0xc4313248, 0xd1400061, + 0x2730000f, 0x13300010, 0x7db1800a, 0xcd800060, 0x96c00002, 0x05dc0008, 0xcdc00062, 0x042c3000, + 0xcd000063, 0xce000064, 0xce400065, 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, 0xce813260, + 0x52ec0020, 0x7ef2c01a, 0xc820001f, 0x1b700057, 0x1b680213, 0x1b740199, 0x46ec0188, 0x7f73400a, + 0x7f6b400a, 0x56240020, 0xcf400024, 0xd2c00025, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, + 0xc418000d, 0x17e00008, 0xce000009, 0xcec13267, 0xc42d3267, 0x26e01000, 0x9a00fffe, 0xd8400013, + 0xd9c131fc, 0xcd800009, 0xcf800008, 0x96c00001, 0x90000000, 0xc4380004, 0xd8400008, 0xc4113277, + 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, 0x11dc0008, 0x29dc0001, 0x25140001, 0x191807e4, + 0x192007ec, 0x95400004, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x9580000e, 0x09980001, 0x041c0001, + 0x95800005, 0x09980001, 0x51dc0001, 0x69dc0001, 0x9980fffd, 0x7de20014, 0x561c0020, 0xd8400013, + 0xce013344, 0xcdc13345, 0xcfc00013, 0x95400022, 0x042c3000, 0xcec13267, 0xc42d3246, 0xc4313245, + 0xc4353267, 0xd8400013, 0xc425334d, 0x26640001, 0x9640fffe, 0xc419334e, 0xc41d334f, 0xc4213350, + 0xc4253351, 0x52ec0020, 0x1b680057, 0x7ef2c01a, 0x1b700213, 0x1b740199, 0x46ec01b0, 0x7f6b400a, + 0x7f73400a, 0xcfc00013, 0xcf400024, 0xd2c00025, 0xcd800026, 0xcdc00026, 0xce000026, 0xce400026, + 0x042c2000, 0xd8400027, 0xcec13267, 0xc42d3267, 0x96c00001, 0x04280032, 0xce813260, 0xd8800068, + 0xcf800008, 0x90000000, 0xc4380004, 0xd8400008, 0x2010007d, 0xcd01325b, 0xc411325b, 0x1910003e, + 0x9500fffe, 0x04100040, 0xcd00001b, 0xd8400021, 0xc410000f, 0x9900ffff, 0x04100060, 0xcd00001b, + 0xd8400021, 0xc410000f, 0x9900ffff, 0xcfc00013, 0x2010003d, 0xcd01325b, 0xc4113277, 0x25140001, + 0x191807e4, 0x9540000b, 0x2511fffd, 0xcd013277, 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, + 0x11dc0008, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x95800005, 0xd8400013, 0xd8013344, 0xd8013345, + 0xcfc00013, 0xc4180050, 0xc41c0052, 0x04280042, 0xcd813273, 0xcdc13275, 0xce813260, 0xd9000068, + 0xd8400067, 0xcf800008, 0x90000000, 0x07d40000, 0x8c00120d, 0x8c00124f, 0x8c001232, 0x057c0000, + 0x042c3000, 0xc4380004, 0xcfc00013, 0xd8400008, 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, + 0x52ec0020, 0x7ef2c01a, 0x1b680057, 0x1b700213, 0x1b740199, 0xc820001f, 0x46ec0190, 0x7f6b400a, + 0x7f73400a, 0x56240020, 0xcf400024, 0xd2c00025, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, + 0xcfc00013, 0xcec13267, 0xc4153249, 0x2154003d, 0xc41c0019, 0x1bd800e8, 0x7dd9c005, 0x25dc0001, + 0xc42c004a, 0xcd80005e, 0xc420004d, 0xcec0005e, 0x11dc0010, 0x7e1e000a, 0xcd413249, 0xce01326f, + 0x28340001, 0x05980008, 0x7f598004, 0xcd800035, 0x1be800e8, 0xc42c004a, 0xce80005e, 0xd801327a, + 0xd800005f, 0xd8000075, 0xd800007f, 0xc424004c, 0xce41326e, 0xcec0005e, 0x28240100, 0x7e6a4004, + 0xce400079, 0xc435325d, 0x277401ef, 0x04240020, 0xce41325e, 0xd801325b, 0xd8013260, 0xcf41325d, + 0xda000068, 0xcf800008, 0x90000000, 0xc4113277, 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, + 0x11dc0008, 0x29dc0001, 0x25140001, 0x9540002d, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x042c3000, + 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, 0xd8400013, 0xc425334d, 0x26640001, 0x9640fffe, + 0xc419334e, 0xc41d334f, 0xc4213350, 0xc4253351, 0x52ec0020, 0x1b680057, 0x7ef2c01a, 0x1b700213, + 0x1b740199, 0x46ec01b0, 0x7f6b400a, 0x7f73400a, 0xcfc00013, 0xcf400024, 0xd2c00025, 0xcd800026, + 0xcdc00026, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, 0xcec13267, 0xc42d3267, 0x96c00001, + 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, 0x11dc0008, 0xd8400013, 0xcdc1334a, 0xcfc00013, + 0x90000000, 0xc430000b, 0x33300002, 0x04240000, 0x9b000010, 0x1be000e8, 0x042c0000, 0xc0360001, + 0x04280004, 0xd8400013, 0xcec1c200, 0xc63124dc, 0x0aa80001, 0x7ef6c001, 0x7e724001, 0x97000001, + 0x9a80fff9, 0xc02ee000, 0xd8400013, 0xcec1c200, 0x90000000, 0x90000000, 0xc4253260, 0x7fc14001, + 0xc40d3249, 0x18cc003e, 0x98c00005, 0x194c1c03, 0xccc0003b, 0xc40c002d, 0x80000697, 0xc420004a, + 0x194c00e8, 0xccc0005e, 0xc40c004c, 0xc431326d, 0x27301fff, 0xce00005e, 0x7cf0c00d, 0x98c00003, + 0x8c0007e0, 0x95c00008, 0xc430001e, 0x1b301ff8, 0x2b300400, 0x2330003f, 0xcd400013, 0xcf01325b, + 0x90000000, 0xcd400013, 0xd801325b, 0xc411325d, 0x251001ef, 0xcd01325d, 0x25100007, 0x31100005, + 0x9900008e, 0xc40c0007, 0xd9000010, 0x8000075e, 0x202c007d, 0xcec1325b, 0xc4293265, 0xc4353254, + 0x26a9feff, 0xc4380004, 0xd8400008, 0x1374000b, 0xc40c000d, 0xd8000009, 0x1774000d, 0xd8400013, + 0xc41d30b8, 0xcfc00013, 0x95c00008, 0xc411325d, 0xd801325b, 0xccc00009, 0xcf800008, 0x251001ef, + 0xcd01325d, 0x90000000, 0xce813265, 0xcf400100, 0xc00ac006, 0xc00e0000, 0x28880700, 0x28cc0014, + 0x8c0006de, 0x14cc0010, 0x30d4000f, 0x04cc0001, 0x10cc0010, 0x28cc0014, 0x99400009, 0xd8400013, + 0xc41530b8, 0xcfc00013, 0xc4193265, 0x19980028, 0x99400003, 0x99800002, 0x800006c8, 0xcfc00013, + 0xc411325d, 0xd801325b, 0xcf800008, 0x251001ef, 0xcd01325d, 0x90000000, 0x15600008, 0xce000009, + 0xc8380023, 0xc4180081, 0x11a00002, 0x7fa38011, 0xc4100026, 0x05980008, 0x7d1a0002, 0x282c2002, + 0x3e280008, 0xcec00013, 0xc4300027, 0x042c0008, 0xd3800025, 0xcf000024, 0x202400d0, 0x7ca48001, + 0xcc800026, 0xccc00026, 0x28240006, 0xcc000026, 0x0a640001, 0x9a40fffe, 0x9a800004, 0x32280000, + 0x9a800002, 0x9a000000, 0xd8400027, 0x24d8003f, 0xd840003c, 0xcec0003a, 0xd8800013, 0xcd81a2a4, + 0x90000000, 0xc41d325d, 0x25dc0007, 0xc40d3249, 0x18cc003e, 0x94c0000a, 0xc420004a, 0x194c00e8, + 0xccc0005e, 0xc40c004c, 0xc431326d, 0x27301fff, 0xce00005e, 0x7cf0c00d, 0x80000712, 0x194c1c03, + 0xccc0003b, 0xc40c002d, 0x05e80714, 0x86800000, 0x8000071c, 0x80000720, 0x80000747, 0x8000071d, + 0x800007c4, 0x80000732, 0x80000745, 0x80000744, 0x90000000, 0x98c00006, 0x8000072e, 0x90000000, + 0x98c00003, 0x8c0007e0, 0x95c0000c, 0xcd400013, 0xc4253265, 0x2a64008c, 0xce413265, 0xc430001e, + 0x1b301fe8, 0x2b300400, 0x2330003f, 0xd8013260, 0xcf01325b, 0x90000000, 0xc40c0007, 0xd9000010, + 0x04240000, 0x8000075e, 0x98c0fff1, 0x8c0007e0, 0x95c00002, 0x80000723, 0xcd400013, 0xc41f02f1, + 0x95c00004, 0xd8013247, 0xd801325d, 0x80000743, 0xd8813247, 0xd801325d, 0xc4100004, 0xd8400008, + 0xd8400013, 0xd88130b8, 0xcd000008, 0x90000000, 0x04100001, 0x98c0ffde, 0x8000072e, 0x98c00003, + 0x8c0007e0, 0x95c00012, 0xc4340004, 0xd8400008, 0x15600008, 0xc418000d, 0xce000009, 0xd8400013, + 0xd84131db, 0xcf400008, 0xcd800009, 0xc430001e, 0x1b301ff8, 0x2b300400, 0x2330003f, 0xcd400013, + 0xd8413260, 0xcf01325b, 0x90000000, 0xc40c0007, 0xd9000010, 0x04240000, 0xcd400013, 0x041c3000, + 0xcdc13267, 0xc41d3267, 0xc41d3265, 0x25dc8000, 0x95c00007, 0xc41c004a, 0x195800e8, 0xcd80005e, + 0xc418004c, 0xcd81326e, 0xcdc0005e, 0xc41d3265, 0x25dd7fff, 0xcdc13265, 0xc41d3246, 0xc4193245, + 0xc42d3267, 0x51e00020, 0x7e1a001a, 0x46200200, 0x04283247, 0x04300033, 0x1af80057, 0x1af40213, + 0x042c000c, 0x7f7b400a, 0x7f6f400a, 0xcf400024, 0xd2000025, 0xcd800026, 0xcdc00026, 0xc6990000, + 0x329c325d, 0x99c00008, 0x329c3269, 0x99c00006, 0x329c3267, 0x95c00005, 0xc01defff, 0x7d9d8009, + 0x8000078a, 0x25980000, 0x0b300001, 0x06a80001, 0xcd800026, 0x9b00fff2, 0xd8400027, 0xc43c0012, + 0x9bc0ffff, 0xcd400013, 0xd801325b, 0xc431325a, 0xc03e7ff0, 0x7f3f0009, 0xcf01325a, 0xc4313249, + 0x1f30001f, 0xcf013249, 0xc03e4000, 0xcfc13254, 0xcd400013, 0xd8013254, 0xc431325d, 0xd801324f, + 0xd8013255, 0xd8013247, 0xd801325d, 0x1b300028, 0x8c00120d, 0x8c001219, 0x8c001232, 0xc4380004, + 0xd8400008, 0xd8400013, 0x9900000d, 0xd88130b8, 0x9700000b, 0xc43d30b5, 0x1bf0003a, 0x9b000b80, + 0x203c003a, 0xc430000e, 0x27300700, 0x13300014, 0x2b300001, 0xcf0130b7, 0xcfc130b5, 0x46200008, + 0xcf400024, 0xd2000025, 0xd8000026, 0xd8400027, 0x043c2000, 0xcd400013, 0xcfc13267, 0xc43d3267, + 0x9bc00001, 0xccc00010, 0xcf800008, 0x90000000, 0xc4080007, 0xd9000010, 0xc4193260, 0x259c0003, + 0x31dc0003, 0x95c00014, 0x040c3000, 0xd8400008, 0xccc13267, 0xc40d3267, 0x18ec0057, 0x18e40213, + 0x18cc0199, 0x7cecc00a, 0x7ce4c00a, 0xc4193246, 0xc41d3245, 0x51980020, 0x7d9d801a, 0x8c000448, + 0xcd400013, 0x040c2000, 0xccc13267, 0xc40d3267, 0x94c00001, 0xcc800010, 0xd801325d, 0x90000000, + 0xc418000b, 0x31980002, 0x041c0000, 0x9980001c, 0x19580066, 0x15600008, 0x040c0000, 0xc0120001, + 0x11980003, 0x04240004, 0x7da18001, 0xc4200007, 0xc4340004, 0xd9000010, 0xd8400008, 0xd8400013, + 0xccc1c200, 0xc41d24db, 0x7cd0c001, 0x0a640001, 0x7dd9c005, 0x25dc0001, 0x99c00002, 0x9a40fff8, + 0xc418005e, 0x9580137b, 0xc00ee000, 0xd8400013, 0xccc1c200, 0xce000010, 0xcf400008, 0x90000000, + 0xd840004f, 0xc4113269, 0x19080070, 0x190c00e8, 0x2510003f, 0x2518000f, 0xcd813268, 0x05a80809, + 0x86800000, 0x8000080e, 0x8000080f, 0x80000898, 0x80000946, 0x800009e1, 0x80000a5a, 0x04a80811, + 0x86800000, 0x80000815, 0x80000834, 0x8000085e, 0x8000085e, 0x04341001, 0xcf400013, 0xc4380004, + 0xd8400008, 0xc42d3045, 0xcec1c091, 0x31300021, 0x9700000b, 0xd84002f1, 0xd8400013, 0xc43130b8, + 0x27300001, 0xc4293059, 0x56a8001f, 0x7f2b000a, 0xcf800008, 0x9b000241, 0x8000084a, 0xcf400013, + 0xd8400008, 0xc43130b6, 0x9b000003, 0xc02f0001, 0xcec130b6, 0xc4252087, 0x5668001a, 0x26a80005, + 0x9a80fffd, 0xcf400013, 0xd80130b6, 0x8000084a, 0xc4380004, 0xd8400008, 0x04341001, 0xcf400013, + 0xc431ecaa, 0x27300080, 0x9b000010, 0xc02e0001, 0xcec130b6, 0xcf400013, 0xd80130b6, 0x31300021, + 0x9700000a, 0xd84002f1, 0xd8400013, 0xc43130b8, 0x27300001, 0xc4293059, 0x56a8001f, 0x7f2b000a, + 0xcf800008, 0x9b00021d, 0xdd410000, 0x040c0005, 0xd84802e9, 0x8c001a41, 0xc43b02f1, 0x9b800006, + 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0xcf800008, 0xcec80278, 0x56f00020, 0xcf080280, + 0x8c001608, 0xdc140000, 0xcd400013, 0xd8813247, 0xd80802e9, 0x8000085e, 0xcd400013, 0x31100011, + 0x950001fa, 0xc02e0001, 0x2aec0008, 0xc01c0020, 0xc0180001, 0xc00c0007, 0x11a40006, 0x7de6000a, + 0x10e40008, 0x7e26000a, 0x7e2e000a, 0xce000013, 0xc4113254, 0x1d10ffdf, 0x2110003e, 0xcd013254, + 0xd801324f, 0xd8013255, 0x1d10ff9e, 0xcd013254, 0xd8013247, 0xd801325d, 0xd801325e, 0xc0245301, + 0xce413249, 0xd801325f, 0xc425326c, 0xc0121fff, 0x29108eff, 0x7e524009, 0xce41326c, 0xc425325a, + 0xc0127ff0, 0x7e524009, 0xce41325a, 0xc425325b, 0xc0131fff, 0x7e524009, 0xce41325b, 0xd801326d, + 0xd801326e, 0xd8013279, 0x94c00003, 0x08cc0001, 0x80000866, 0xc00c0007, 0x95800003, 0x09980001, + 0x80000866, 0xc0100010, 0x7dd2400c, 0x9a400004, 0xc0180003, 0x7dd1c002, 0x80000866, 0x80000a5a, + 0x04a8089a, 0x86800000, 0x8000089e, 0x800008fa, 0x80000945, 0x80000945, 0x31300022, 0x97000007, + 0xc4380004, 0xd8400008, 0xd8400013, 0xc43130b8, 0x27300001, 0xcf800008, 0xcd400013, 0x04183000, + 0xcd813267, 0xc4113246, 0xc4193245, 0x51100020, 0x7d91801a, 0x459801e0, 0xc4313267, 0x2738000f, + 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, + 0xd180001e, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8300011, 0x97000036, 0x45980008, 0xd180001e, + 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8340011, 0x9740002f, 0xc43c0004, 0xd8400008, 0xd8400013, + 0x13b80001, 0xc79d3300, 0xc7a13301, 0x96000001, 0xd8393300, 0xc0260001, 0xce793301, 0xc424005e, + 0x964012a4, 0x7c028009, 0x9740001c, 0x27580001, 0x99800004, 0x57740001, 0x06a80400, 0x800008d2, + 0xc4180006, 0x9980ffff, 0x29640001, 0xce40001a, 0x242c0000, 0x06ec0400, 0x57740001, 0x27580001, + 0x9980fffd, 0xc02620c0, 0xce41c078, 0xce81c080, 0xcc01c081, 0xcf01c082, 0x57240020, 0xce41c083, + 0xc0260400, 0x7e6e400a, 0xce41c084, 0x7eae8001, 0x7f2f0011, 0x800008d2, 0xc4180006, 0x9980ffff, + 0xcdf93300, 0xce393301, 0xcfc00008, 0xcd400013, 0xc43c0004, 0xd8400008, 0x04182000, 0xcd813267, + 0xcfc00008, 0x80000903, 0x31240022, 0x96400008, 0x04100001, 0xc4380004, 0xd8400008, 0xd8400013, + 0xc43130b8, 0x27300001, 0xcf800008, 0xc4af0280, 0xc4b30278, 0x52ec0020, 0x7ef2c01a, 0x7ec30011, + 0x32f80000, 0x9b800011, 0x043c0020, 0x04280000, 0x67180001, 0x0bfc0001, 0x57300001, 0x95800006, + 0x8c001628, 0x9a400003, 0xd981325d, 0x80000915, 0xd9c1325d, 0x06a80001, 0x9bc0fff6, 0x7f818001, + 0x8c001606, 0x7d838001, 0x94800010, 0xcd400013, 0xc41d3259, 0xc421325a, 0x16240014, 0x12640014, + 0x1a2801f0, 0x12a80010, 0x2620ffff, 0x7e2a000a, 0x7de1c001, 0x7e5e400a, 0x9b800002, 0x2264003f, + 0xce41325a, 0xd8013259, 0xc40c0007, 0xd9000010, 0x8c00075e, 0xc4af0228, 0x043c0000, 0x66d80001, + 0x95800010, 0x04300002, 0x1330000d, 0x13f40014, 0x7f73400a, 0xcf400013, 0x04380040, 0xcf80001b, + 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380060, 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, + 0x07fc0001, 0x56ec0001, 0x33e80010, 0x9680ffec, 0x80000a5a, 0x80000a5a, 0x04a80948, 0x86800000, + 0x8000094c, 0x8000099b, 0x800009e0, 0x800009e0, 0xc43c0004, 0xd8400008, 0xcd400013, 0x04183000, + 0xcd813267, 0xc4113246, 0xc4193245, 0x51100020, 0x7d91801a, 0x459801e0, 0xc4313267, 0x2738000f, + 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, + 0xd180001e, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8300011, 0x97000033, 0x45980008, 0xd180001e, + 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8340011, 0x9740002c, 0xd8400013, 0x13b80001, 0xc79d3300, + 0xc7a13301, 0x96000001, 0xd8393300, 0xc0260001, 0xce793301, 0xc424005e, 0x964011fe, 0x7c028009, + 0x9740001c, 0x27580001, 0x99800004, 0x57740001, 0x06a80400, 0x80000978, 0xc4180006, 0x9980ffff, + 0x29640001, 0xce40001a, 0x242c0000, 0x06ec0400, 0x57740001, 0x27580001, 0x9980fffd, 0xc0260010, + 0xce41c078, 0xcf01c080, 0x57240020, 0xce41c081, 0xce81c082, 0xcc01c083, 0xc0260800, 0x7e6e400a, + 0xce41c084, 0x7eae8001, 0x7f2f0011, 0x80000978, 0xc4180006, 0x9980ffff, 0xcdf93300, 0xce393301, + 0x04182000, 0xcd813267, 0xcfc00008, 0xcd400013, 0xc4193246, 0xc41d3245, 0x51980020, 0x7dda801a, + 0x7d41c001, 0x7e838011, 0xd84802e9, 0x8c001802, 0x469c0390, 0xc4313267, 0x04183000, 0xcd813267, + 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, + 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4200011, 0x45dc0004, 0xd1c0001e, + 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4240011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, + 0x9980ffff, 0xc4280011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc42c0011, + 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4300011, 0x45dc0004, 0xd1c0001e, + 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4340011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, + 0x9980ffff, 0xc4380011, 0xcd400013, 0x04182000, 0xcd813267, 0x043c0001, 0x8c0014df, 0x80000a5a, + 0x80000a5a, 0x31280014, 0xce8802ef, 0x9a800062, 0x31280034, 0x9a800060, 0x04a809e8, 0x86800000, + 0x800009ec, 0x80000a45, 0x80000a59, 0x80000a59, 0xcd400013, 0xc4113246, 0xc4193245, 0x51100020, + 0x7d91801a, 0x45980400, 0xc4b30258, 0xc4a70250, 0x53300020, 0x7e72401a, 0xc4313267, 0x1b342010, + 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, 0x042c0020, + 0x66740001, 0x97400041, 0xcd400013, 0x04383000, 0xcf813267, 0xc4393267, 0x9b800001, 0xd180001e, + 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4300011, 0x1b38007e, 0x33b40003, 0x9b400003, 0x4598001c, + 0x9740002f, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc40c0011, 0x45980004, + 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4100011, 0x45980004, 0xd180001e, 0xd8400021, + 0xc438000f, 0x9b80ffff, 0xc4340011, 0xcf4002eb, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, + 0x9b80ffff, 0xc4340011, 0xcf4002ec, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, + 0xc4340011, 0xcf4002ed, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4340011, + 0xcf4002ee, 0x45980004, 0xcd400013, 0x04382000, 0xcf813267, 0xd84802e9, 0x8c001715, 0xcd400013, + 0x04382000, 0xcf813267, 0x56640001, 0x0aec0001, 0x9ac0ffbc, 0xc4380004, 0xd8400008, 0x04341001, + 0xcf400013, 0x94800005, 0xc431ecaa, 0x27300080, 0x97000002, 0x80000a55, 0xc43130b6, 0x233c0032, + 0xcfc130b6, 0xcf400013, 0xcf0130b6, 0xc49302ef, 0x99000003, 0xcd400013, 0xd8413247, 0xcf800008, + 0x80000a5a, 0x80000a5a, 0xcd400013, 0x04180001, 0x5198001f, 0xcd813268, 0xc4193269, 0x2598000f, + 0x9980fffe, 0xd80002f1, 0xcd400013, 0xd8013268, 0xd800004f, 0x90000000, 0xcd400013, 0x04380001, + 0x53b8001f, 0x7db9801a, 0xcd813268, 0x80000a5e, 0xd8400029, 0xc40c005e, 0x94c01106, 0xd8800013, + 0xcc412e01, 0xcc412e02, 0xcc412e03, 0xcc412e00, 0x80000aa7, 0xd8400029, 0xc40c005e, 0x94c010fd, + 0x7c40c001, 0x50640020, 0x7ce4c01a, 0xd0c00072, 0xc80c0072, 0x58e801fc, 0x12a80009, 0x2aa80000, + 0xd0c0001e, 0xce80001c, 0xd8400021, 0xc424000f, 0x9a40ffff, 0x04240010, 0x18dc01e2, 0x7e5e4002, + 0x3e5c0003, 0x3e540002, 0x95c00006, 0xc8180011, 0xc8100011, 0xc8100011, 0x55140020, 0x80000aa2, + 0x9540000a, 0xc8180011, 0x44cc0008, 0x55900020, 0xd0c0001e, 0xd8400021, 0xc424000f, 0x9a40ffff, + 0xc4140011, 0x80000aa2, 0x44cc0004, 0xc4180011, 0xd0c0001e, 0xd8400021, 0xc424000f, 0x9a40ffff, + 0xc8100011, 0x55140020, 0xd8800013, 0xcd812e01, 0xcd012e02, 0xcd412e03, 0xcc412e00, 0xc428000e, + 0x2aa80008, 0xce800013, 0xc4253249, 0x2264003f, 0xce413249, 0xce800013, 0xc4253249, 0x96400001, + 0xd800002a, 0xc410001a, 0xc40c0021, 0xc4140028, 0x95000005, 0x1e64001f, 0xce800013, 0xce413249, + 0x80001b70, 0x14d00010, 0xc4180030, 0xc41c0007, 0x99000004, 0x99400009, 0x9980000c, 0x80000ab1, + 0xccc00037, 0x8c000190, 0xc420001c, 0xd8000032, 0x9a0010ac, 0x80000aa7, 0xd880003f, 0x95c00002, + 0xd8c0003f, 0x80001082, 0xd8800040, 0x95c00002, 0xd8c00040, 0x800010de, 0xc010ffff, 0x18d403f7, + 0x7d0cc009, 0xc41b0367, 0x7d958004, 0x7d85800a, 0xdc1e0000, 0x90000000, 0xc424000b, 0x32640002, + 0x7c40c001, 0x18d001fc, 0x05280adc, 0x86800000, 0x80000af1, 0x80000adf, 0x80000ae7, 0x8c000ace, + 0xd8c00013, 0x96400002, 0xd8400013, 0xcd8d2000, 0x99c00010, 0x7c408001, 0x88000000, 0x18d803f7, + 0xc010ffff, 0x7d0cc009, 0x04140000, 0x11940014, 0x29544001, 0x9a400002, 0x29544003, 0xcd400013, + 0x80000af4, 0xd8c00013, 0x96400002, 0xd8400013, 0xd44d2000, 0x7c408001, 0x88000000, 0xc424000b, + 0x32640002, 0x7c40c001, 0xd8c00013, 0x96400002, 0xd8400013, 0xd44dc000, 0x7c408001, 0x88000000, + 0x7c40c001, 0x18d0003c, 0x95000006, 0x8c000ace, 0xd8800013, 0xcd8d2c00, 0x99c00003, 0x80000b0a, + 0xd8800013, 0xd44d2c00, 0x7c408001, 0x88000000, 0x7c40c001, 0x28148004, 0x24d800ff, 0xccc00019, + 0xcd400013, 0xd4593240, 0x7c408001, 0x88000000, 0xd8400029, 0xc40c005e, 0x94c0105e, 0x7c410001, + 0x50540020, 0x7c418001, 0x2198003f, 0x199c0034, 0xc40c0007, 0x95c00028, 0xc428000e, 0x2aa80008, + 0xce800013, 0xc42d324f, 0xc4313255, 0x7ef3400c, 0x9b400021, 0xd800002a, 0x80001b70, 0xc40c0007, + 0x14e80001, 0x9a8000af, 0xd9000010, 0x041c0002, 0x042c01c8, 0x8c000d61, 0xccc00010, 0xd8400029, + 0xc40c005e, 0x94c01043, 0x7c410001, 0x50540020, 0x7c418001, 0x18a01fe8, 0x3620005c, 0x9a00000e, + 0x2464003f, 0xd8400013, 0xc6290ce7, 0x16ac001f, 0x96c00004, 0x26ac003f, 0x7ee6c00d, 0x96c00005, + 0x06200001, 0x2620000f, 0x9a00fff8, 0x8000016a, 0xce000367, 0xc424005e, 0x9640102e, 0xc428000e, + 0x199c0037, 0x19a00035, 0x2aa80008, 0xce800013, 0x95c0005d, 0xd800002a, 0xc42d3256, 0xc431325a, + 0x2330003f, 0x16f8001f, 0x9780000d, 0xc4253248, 0xc035f0ff, 0x7e764009, 0x19b401f8, 0x13740008, + 0x7e76400a, 0xce800013, 0xce413248, 0xcf01325a, 0xce800013, 0xc431325a, 0x97000001, 0x7d15001a, + 0xd1000072, 0xc8100072, 0x55140020, 0x199c0034, 0xd8400010, 0xd8400029, 0x9b800004, 0x1ae4003e, + 0xce400008, 0x80000b7c, 0xc4353254, 0x16a80008, 0x1aec003c, 0x19a4003f, 0x12a80015, 0x12ec001f, + 0x1374000b, 0x7eae800a, 0xc02e4000, 0x1774000d, 0x7eae800a, 0xce400008, 0x7f6b400a, 0x95c00005, + 0xc43d3248, 0x1bfc01e8, 0x13fc0018, 0x7dbd800a, 0x1d98ff15, 0x592c00fc, 0xcd80000a, 0x12e00016, + 0x7da1800a, 0x592c007e, 0x12e00015, 0x7da1800a, 0xd1000001, 0xcd800001, 0x11a0000c, 0x1264001e, + 0x1620000c, 0x7e26000a, 0x7e32000a, 0x12e4001b, 0x7e26000a, 0x5924007e, 0x12640017, 0x7e26000a, + 0x19a4003c, 0x12640018, 0x7e26000a, 0xd800002a, 0xce01325a, 0xcd013257, 0xcd413258, 0xc429325a, + 0xc40c005e, 0x94c00fdb, 0x96800001, 0x95c00003, 0x7c40c001, 0x7c410001, 0x9780f5ca, 0xcf400100, + 0xc40c0007, 0xd9000010, 0x8c00120d, 0x8c001219, 0x8c001232, 0xccc00010, 0x8c001b6d, 0x7c408001, + 0x88000000, 0xc42d324e, 0xc431324d, 0x52ec0020, 0x7ef2c01a, 0xc435324f, 0xc4293256, 0x52ec0008, + 0x07740003, 0x04240002, 0x269c003f, 0x7e5e4004, 0x7f67000f, 0x97000003, 0x7f674002, 0x0b740001, + 0x53740002, 0x7ef6c011, 0x1ab42010, 0x1ab8c006, 0x16a8000c, 0x26a80800, 0x2b740000, 0x7f7b400a, + 0x7f6b400a, 0xcf40001c, 0xd2c0001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4180011, 0x9a000003, + 0x8c000bec, 0x80000b47, 0xc42c001d, 0xc4313256, 0x1b34060b, 0x1b300077, 0x7f37000a, 0x13300017, + 0x04340100, 0x26ec00ff, 0xc03a8004, 0x7ef6c00a, 0x7f3b000a, 0x7ef2c00a, 0xcec1325b, 0x80000c16, + 0xc40c0032, 0xc410001d, 0x28cc0008, 0xccc00013, 0xc415325b, 0x7c418001, 0x7c418001, 0x18580037, + 0x251000ff, 0xc421325d, 0x262001ef, 0xce01325d, 0x99800004, 0x7d15400a, 0xcd41325b, 0x80000168, + 0x1d54001f, 0xcd41325b, 0x7c408001, 0x88000000, 0xc428000b, 0xc42c000c, 0x12a80001, 0x26a80004, + 0x7eae800a, 0xc40c0021, 0xc4340028, 0x14f00010, 0xc4380030, 0xc43c0007, 0xcd280200, 0xcd680208, + 0xcda80210, 0x9b00000c, 0x9b400014, 0x9b800017, 0xc428000b, 0xc42c000c, 0x12a80001, 0x26a80004, + 0x7eae800a, 0xc6930200, 0xc6970208, 0xc69b0210, 0x90000000, 0x17300001, 0x9b000005, 0xccc00037, + 0x8c000190, 0xd8000032, 0x90000000, 0xd8000028, 0xd800002b, 0x80000168, 0xd900003f, 0x97c00002, + 0xd940003f, 0x80001082, 0xd9000040, 0x97c00002, 0xd9400040, 0x800010de, 0xc40c0021, 0x14fc0011, + 0x24f800ff, 0x33b80001, 0x97c0fffc, 0x9b800007, 0xccc00037, 0x8c000190, 0xd8000032, 0xd8000028, + 0xd800002b, 0x80001b70, 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0x04100000, 0x04140000, + 0xc418000e, 0x29980008, 0x7d83c001, 0xcd800013, 0xc4093249, 0x1888003e, 0x94800020, 0xd8400074, + 0x8c000671, 0x9a400009, 0xc418000e, 0x29980008, 0xcd800013, 0xc419324c, 0x259c0001, 0x1598001f, + 0x95c00016, 0x95800015, 0x99000003, 0xd8400036, 0x04100001, 0xc40c0021, 0x14d80011, 0x24e000ff, + 0x321c0002, 0x32200001, 0x9580ffee, 0x99c00014, 0x96000004, 0xccc00037, 0x04140001, 0x80000c30, + 0x9480000a, 0xd8000074, 0xc418005e, 0x95800f29, 0xcf800008, 0x80000c16, 0x94800004, 0xd8000074, + 0xc418005e, 0x95800f23, 0xd9c00036, 0x99400002, 0xccc00037, 0xcf800008, 0x80000c16, 0x94800004, + 0xd8000074, 0xc418005e, 0x95800f1a, 0xccc00037, 0xd8800036, 0x80001b70, 0x041c0003, 0x042c01c8, + 0x8c000d61, 0xc4200007, 0xc40c0077, 0x94c00001, 0x7c418001, 0xc428000e, 0x9600f502, 0x0a200001, + 0x98c0f500, 0x2aa80008, 0xce000010, 0x9a000f05, 0xce800013, 0xc431325a, 0xc42d3256, 0x1f30001f, + 0x16e4001f, 0xcf01325a, 0xc431325a, 0x97000001, 0x9640f4f4, 0xc434000b, 0x33740002, 0x9b40f4f1, + 0xc4353254, 0x16a80008, 0x1aec003c, 0x12a80015, 0x12ec001f, 0x1374000b, 0x7eae800a, 0xc02e4000, + 0x1774000d, 0x7eae800a, 0x7f6b400a, 0xcf400100, 0x12780001, 0x2bb80001, 0xc00ac005, 0xc00e0002, + 0x28cc8000, 0x28884900, 0x28cc0014, 0x80000ff3, 0xc43c0007, 0x7c40c001, 0x17fc0001, 0xd8400013, + 0x9bc00004, 0xd8400029, 0xc424005e, 0x96400ee1, 0xcc41c40a, 0xcc41c40c, 0xcc41c40d, 0x7c414001, + 0x24d0007f, 0x15580010, 0x255400ff, 0xcd01c411, 0xcd81c40f, 0xcd41c40e, 0xcc41c410, 0x7c414001, + 0x7c418001, 0x04200000, 0x18e80033, 0x18ec0034, 0xcc41c414, 0xcc41c415, 0xcd81c413, 0xcd41c412, + 0x18dc0032, 0x7c030011, 0x7c038011, 0x95c00027, 0x96c00002, 0xc431c417, 0xc435c416, 0x96800004, + 0x96c00002, 0xc439c419, 0xc43dc418, 0xc41c000e, 0x29dc0008, 0xcdc00013, 0xcf413261, 0x96c00002, + 0xcf013262, 0x96800004, 0xcfc13263, 0x96c00002, 0xcf813264, 0x18dc0030, 0xc43c0007, 0x95c00017, + 0x17fc0001, 0x9ac00005, 0x7d77000c, 0x9bc00015, 0x9700000a, 0x80000cd6, 0x51b80020, 0x53300020, + 0x7f97801a, 0x7f37001a, 0x7f3b000c, 0x9bc0000d, 0x97800002, 0x80000cd6, 0x9a000018, 0xd8400013, + 0x28200001, 0x80000ca7, 0x18dc0031, 0x95c00003, 0xc435c40b, 0x9740fffd, 0xd800002a, 0x80001b70, + 0xc4280032, 0x2aa80008, 0xce800013, 0xc40d325b, 0x97000002, 0x800012c2, 0xc438001d, 0x1bb81ff0, + 0x7f8cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, 0xcd01325d, 0x80001b70, 0xc428000e, 0xc43c0007, + 0x2aa80008, 0xc438001d, 0xce800013, 0x13f4000c, 0x9bc00006, 0xc43d3256, 0x1bf0060b, 0x1bfc0077, + 0x7ff3c00a, 0x80000cf4, 0xc43d325a, 0x1bfc0677, 0x13fc0017, 0x04300100, 0x1bb81fe8, 0x7f73400a, + 0xc032800b, 0x7fb7800a, 0x7ff3c00a, 0x7ffbc00a, 0xcfc1325b, 0x80000c16, 0xc43c0007, 0x7c40c001, + 0x18d42011, 0x17fc0001, 0x18d001e8, 0x24cc007f, 0x7cd4c00a, 0x9bc00004, 0xd8400029, 0xc428005e, + 0x96800e6c, 0x7c414001, 0x50580020, 0x7d59401a, 0xd1400072, 0xc8140072, 0x596001fc, 0x12200009, + 0x7ce0c00a, 0x7c418001, 0x505c0020, 0x7d9d801a, 0x7c41c001, 0x50600020, 0x7de1c01a, 0x7c420001, + 0xccc0001b, 0xd140001d, 0xd180001f, 0xd1c00020, 0xd8400021, 0x95000010, 0x04300000, 0xc428000f, + 0x9a80ffff, 0xc8240010, 0x7e5e800c, 0x9bc00015, 0x9a80000c, 0x9b000024, 0x28300001, 0x122c0004, + 0x06ec0001, 0x0aec0001, 0x9ac0ffff, 0xd8400021, 0x80000d1f, 0xc428000f, 0x9a80ffff, 0xc8240010, + 0x566c0020, 0xc428000e, 0x2aa80008, 0xce800013, 0xce413261, 0xcec13262, 0xd800002a, 0x80001b70, + 0xc4340032, 0x2b740008, 0xcf400013, 0xc40d325b, 0x96800005, 0x566c0020, 0xce413261, 0xcec13262, + 0x800012c2, 0xc438001d, 0x1bb81fe8, 0x7f8cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, 0xcd01325d, + 0x80001b70, 0xc43c0007, 0xc438001d, 0xc428000e, 0x2aa80008, 0xce800013, 0x13f4000c, 0x9bc00006, + 0xc43d3256, 0x1bf0060b, 0x1bfc0077, 0x7ff3c00a, 0x80000d57, 0xc43d325a, 0x1bfc0677, 0x13fc0017, + 0x04300100, 0x1bb81fe8, 0x7f73400a, 0xc0328009, 0x7fb7800a, 0x7ff3c00a, 0x7ffbc00a, 0xcfc1325b, + 0x80000c16, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0xc4253246, 0xc4113245, 0x04143000, 0xcd413267, + 0x52640020, 0x7e51001a, 0xc4153267, 0x7d2d0011, 0x19640057, 0x19580213, 0x19600199, 0x7da6400a, + 0x7e26400a, 0xd1000025, 0xce400024, 0xcdc00026, 0xd8400027, 0x04142000, 0xcfc00013, 0xcd413267, + 0xc4153267, 0x99400001, 0x90000000, 0x7c40c001, 0x18d001e8, 0x18d40030, 0x18d80034, 0x05280d83, + 0x7c420001, 0x7c424001, 0x86800000, 0x80000d8a, 0x8000016a, 0x80000d95, 0x80000db1, 0x8000016a, + 0x80000d95, 0x80000dbc, 0x11540010, 0x7e010001, 0x8c00187c, 0x7d75400a, 0xcd400013, 0xd4610000, + 0x9580f3d8, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0xd8000016, 0x526c0020, 0x18e80058, + 0x7e2ec01a, 0xd2c00072, 0xc82c0072, 0x5ae0073a, 0x7ea2800a, 0x9940000a, 0xce800024, 0xd2c00025, + 0xd4400026, 0xd8400027, 0x9580f3c6, 0xc4380012, 0x9b80ffff, 0x7c408001, 0x88000000, 0xdc3a0000, + 0x0bb80001, 0xce800024, 0xd2c00025, 0xcc400026, 0xd8400027, 0x9b80fffb, 0x9980fff5, 0x7c408001, + 0x88000000, 0xc02a0001, 0x2aa80001, 0x16200002, 0xce800013, 0xce01c405, 0xd441c406, 0x9580f3b1, + 0xc439c409, 0x97800001, 0x7c408001, 0x88000000, 0xc424000b, 0x32640002, 0x9a40000b, 0x11540010, + 0x29540002, 0xcd400013, 0xd4610000, 0x9580f3a5, 0xd8400013, 0xc439c040, 0x97800001, 0x7c408001, + 0x88000000, 0xd4400078, 0x80000168, 0xd8400029, 0xc40c005e, 0x94c00da7, 0x7c40c001, 0x50500020, + 0x7cd0c01a, 0xd0c00072, 0xc8280072, 0x5aac007e, 0x12d80017, 0x7c41c001, 0x7d9d800a, 0x56a00020, + 0x2620ffff, 0x7da1800a, 0x51980020, 0x7e82400a, 0x7e58c01a, 0x19d4003d, 0x28182002, 0x99400030, + 0x8c00104f, 0xc430000d, 0xc4340035, 0xd800002a, 0xcd800013, 0xc8140023, 0xc4180081, 0x13300005, + 0xc011000f, 0xc4240004, 0x11a00002, 0x7c908009, 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, + 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x3e280008, 0x20880188, 0x54ec0020, 0x7cb4800a, 0xc4300027, + 0x04380008, 0xd1400025, 0xcf000024, 0x20240090, 0x7ca48001, 0xcc800026, 0xccc00026, 0xcec00026, + 0xcec00026, 0x28240004, 0xcc000026, 0x0a640001, 0x9a40fffe, 0x9a800005, 0x32280000, 0x9a800002, + 0x9a000000, 0x7c018001, 0xd8400027, 0xd8000016, 0xcf80003a, 0xd901a2a4, 0x80001037, 0xc418000e, + 0x29980008, 0xcd800013, 0xc421326c, 0x1624001f, 0x9a40fffe, 0xd841325f, 0xd8800033, 0xc43c0009, + 0x27fc0004, 0x97c0fffe, 0xd8000039, 0xd0c00038, 0xc43c0022, 0x9bc0ffff, 0xd8800034, 0xc429325f, + 0x26ac0001, 0x9ac0fffe, 0x26ac0002, 0x96c00003, 0xd800002a, 0x80001b70, 0xc43c0007, 0xc430001e, + 0xd8800033, 0x13f4000c, 0x1b301ff0, 0x2b300300, 0x2330003f, 0x7f37000a, 0x9680000b, 0xc43c0009, + 0x27fc0004, 0x97c0fffe, 0xd8400039, 0xd0c00038, 0xc43c0022, 0x9bc0ffff, 0xcf01325b, 0xd8800034, + 0x80000c16, 0xd8800034, 0x8c0001a2, 0x80001b70, 0xcc80003b, 0x24b00008, 0xc418000e, 0x1330000a, + 0x18ac0024, 0x2b304000, 0x7c40c001, 0xcec00008, 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, + 0x29980008, 0xcd800013, 0xc4113249, 0x1910003e, 0x99000002, 0xd840003d, 0x7c410001, 0xd4400078, + 0x51100020, 0xcf01326c, 0x7cd0c01a, 0xc421326c, 0x12a80014, 0x2220003f, 0x7e2a000a, 0xcd800013, + 0xce01326c, 0xd8800033, 0xc43c0009, 0x27fc0004, 0x97c0fffe, 0xd8000039, 0xd0c00038, 0xc43c0022, + 0x9bc0ffff, 0xd8800034, 0x80001190, 0x7c40c001, 0x18dc003d, 0x95c00004, 0x041c0001, 0x042c01c8, + 0x8c000d61, 0x18d40030, 0x18d001e8, 0x18fc0034, 0x24e8000f, 0x06a80e71, 0x7c418001, 0x7c41c001, + 0x86800000, 0x80000edd, 0x80000e91, 0x80000e91, 0x80000ea1, 0x80000eaa, 0x80000e7c, 0x80000e7f, + 0x80000e7f, 0x80000e87, 0x80000e8f, 0x8000016a, 0x51dc0020, 0x7d9e001a, 0x80000ee6, 0xc420000e, + 0x2a200008, 0xce000013, 0xc4213262, 0xc4253261, 0x52200020, 0x7e26001a, 0x80000ee6, 0xc420000e, + 0x2a200008, 0xce000013, 0xc4213264, 0xc4253263, 0x52200020, 0x7e26001a, 0x80000ee6, 0xc820001f, + 0x80000ee6, 0x18e82005, 0x51e00020, 0x2aa80000, 0x7da1801a, 0xd1800072, 0xc8180072, 0x59a001fc, + 0x12200009, 0x7ea2800a, 0xce80001c, 0xd180001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc8200011, + 0x80000ee6, 0x15980002, 0xd8400013, 0xcd81c400, 0xc421c401, 0x95400041, 0xc425c401, 0x52640020, + 0x7e26001a, 0x80000ee6, 0x31ac2580, 0x9ac00011, 0x31ac260c, 0x9ac0000f, 0x31ac0800, 0x9ac0000d, + 0x31ac0828, 0x9ac0000b, 0x31ac2440, 0x9ac00009, 0x31ac2390, 0x9ac00007, 0x31ac0093, 0x9ac00005, + 0x31ac31dc, 0x9ac00003, 0x31ac31e6, 0x96c00004, 0xc4340004, 0xd8400008, 0x80000ede, 0x39ac7c06, + 0x3db07c00, 0x9ac00003, 0x97000002, 0x80000ebc, 0x39acc337, 0x3db0c330, 0x9ac00003, 0x97000002, + 0x80000ebc, 0x39acc335, 0x3db0c336, 0x9ac00003, 0x97000002, 0x80000ebc, 0x39ac9002, 0x3db09001, + 0x9ac00003, 0x97000002, 0x80000ebc, 0x39ac9012, 0x3db09011, 0x9ac00003, 0x97000002, 0x80000ebc, + 0x39acec70, 0x3db0ec6f, 0x9ac00003, 0x97000002, 0x80000ebc, 0xc4340004, 0xd8400013, 0xc5a10000, + 0x95400005, 0x05980001, 0xc5a50000, 0x52640020, 0x7e26001a, 0xcf400008, 0x05280eea, 0x7c418001, + 0x7c41c001, 0x86800000, 0x80000ef1, 0x8000016a, 0x80000efe, 0x80000f11, 0x80000f2e, 0x80000efe, + 0x80000f1f, 0xc4340004, 0xd8400013, 0xce190000, 0x95400005, 0x05980001, 0x56200020, 0xce190000, + 0xcf400008, 0x97c0f26f, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0x51ec0020, 0x18e80058, + 0x7daec01a, 0xd2c00072, 0xc82c0072, 0x5af8073a, 0x7eba800a, 0xd2c00025, 0xce800024, 0xce000026, + 0x95400003, 0x56240020, 0xce400026, 0xd8400027, 0x97c0f25c, 0xc4380012, 0x9b80ffff, 0x7c408001, + 0x88000000, 0xc02a0001, 0x2aa80001, 0x15980002, 0xce800013, 0xcd81c405, 0xce01c406, 0x95400003, + 0x56240020, 0xce41c406, 0x97c0f24e, 0xc439c409, 0x97800001, 0x7c408001, 0x88000000, 0xc424000b, + 0x32640002, 0x9a40f247, 0xd8800013, 0xce190000, 0x95400004, 0x05980001, 0x56200020, 0xce190000, + 0x97c0f240, 0xd8400013, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0x31ac2580, 0x9ac00011, + 0x31ac260c, 0x9ac0000f, 0x31ac0800, 0x9ac0000d, 0x31ac0828, 0x9ac0000b, 0x31ac2440, 0x9ac00009, + 0x31ac2390, 0x9ac00007, 0x31ac0093, 0x9ac00005, 0x31ac31dc, 0x9ac00003, 0x31ac31e6, 0x96c00004, + 0xc4340004, 0xd8400008, 0x80000ef2, 0x39ac7c06, 0x3db07c00, 0x9ac00003, 0x97000002, 0x80000f40, + 0x39acc337, 0x3db0c330, 0x9ac00003, 0x97000002, 0x80000f40, 0x39acc335, 0x3db0c336, 0x9ac00003, + 0x97000002, 0x80000f40, 0x39acec70, 0x3db0ec6f, 0x9ac00003, 0x97000002, 0x80000f40, 0x39ac9002, + 0x3db09002, 0x9ac00003, 0x97000002, 0x80000f40, 0x39ac9012, 0x3db09012, 0x9ac00003, 0x97000002, + 0x80000f40, 0x80000ef1, 0xc40c0006, 0x98c0ffff, 0x7c40c001, 0x7c410001, 0x7c414001, 0x7c418001, + 0x7c41c001, 0x7c43c001, 0x95c00001, 0xc434000e, 0x2b740008, 0x2b780001, 0xcf400013, 0xd8c1325e, + 0xcf80001a, 0xd8400013, 0x7c034001, 0x7c038001, 0x18e0007d, 0x32240003, 0x9a400006, 0x32240000, + 0x9a400004, 0xcd01c080, 0xcd41c081, 0x80000f88, 0x51640020, 0x7e52401a, 0xd2400072, 0xc8280072, + 0xce81c080, 0x56ac0020, 0x26f0ffff, 0xcf01c081, 0x1af000fc, 0x1334000a, 0x24e02000, 0x7f63400a, + 0x18e00074, 0x32240003, 0x9a400006, 0x32240000, 0x9a400004, 0xcd81c082, 0xcdc1c083, 0x80000f9d, + 0x51e40020, 0x7e5a401a, 0xd2400072, 0xc8280072, 0xce81c082, 0x56ac0020, 0x26f0ffff, 0xcf01c083, + 0x1af000fc, 0x13380016, 0x18e00039, 0x12200019, 0x7fa3800a, 0x7fb7800a, 0x18e0007d, 0x1220001d, + 0x7fa3800a, 0x18e00074, 0x12200014, 0x7fa3800a, 0xcf81c078, 0xcfc1c084, 0x80000c16, 0x7c40c001, + 0x18dc003d, 0x95c00004, 0x041c0000, 0x042c01c8, 0x8c000d61, 0x18d001e8, 0x31140005, 0x99400003, + 0x31140006, 0x95400002, 0x8c00104f, 0x05280fb7, 0x28140002, 0xcd400013, 0x86800000, 0x80000fbe, + 0x80000fbe, 0x80000fc2, 0x80000fbe, 0x80000fd1, 0x80000ff2, 0x80000ff2, 0x24cc003f, 0xccc1a2a4, + 0x7c408001, 0x88000000, 0x7c414001, 0x18e80039, 0x52a8003b, 0x50580020, 0x24cc003f, 0x7d59401a, + 0xd1400072, 0xc8140072, 0x7d69401a, 0xc41c0017, 0x99c0ffff, 0xd140004b, 0xccc1a2a4, 0x7c408001, + 0x88000000, 0xc414000d, 0x04180001, 0x24cc003f, 0x7d958004, 0xcd800035, 0xccc1a2a4, 0xc43c000e, + 0x2bfc0008, 0xcfc00013, 0xc43d3249, 0x1bfc003e, 0x97c00002, 0xd8400074, 0xc4100019, 0x7d150005, + 0x25100001, 0x9500000b, 0x97c0fffc, 0xc4180021, 0x159c0011, 0x259800ff, 0x31a00003, 0x31a40001, + 0x7e25800a, 0x95c0fff5, 0x9580fff4, 0x80000fef, 0xc411326f, 0x1d100010, 0xcd01326f, 0x97c00002, + 0xd8000074, 0x80001b70, 0x04380000, 0xc430000d, 0xc8140023, 0xc4180081, 0x13300005, 0xc011000f, + 0xc4240004, 0x33b40003, 0x97400003, 0xc0340008, 0x80000ffe, 0xc4340035, 0x11a00002, 0x7c908009, + 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x282c2002, + 0x208801a8, 0x3e280008, 0x7cb4800a, 0xcec00013, 0xc4300027, 0x042c0008, 0xd1400025, 0xcf000024, + 0x20240030, 0x7ca48001, 0xcc800026, 0xccc00026, 0x9b800013, 0xcc400026, 0x7c414001, 0x28340000, + 0xcf400013, 0x507c0020, 0x7d7d401a, 0xd1400072, 0xc8140072, 0x557c0020, 0x28342002, 0xcf400013, + 0xcd400026, 0xcfc00026, 0xd4400026, 0x9a80000e, 0x32280000, 0x9a80000b, 0x8000102f, 0xcc000026, + 0xcc000026, 0xcc000026, 0xcc000026, 0xcc000026, 0x9a800005, 0x32280000, 0x9a800002, 0x9a000000, + 0x7c018001, 0xcc000026, 0xd8400027, 0x1cccfe08, 0xd8800013, 0xcec0003a, 0xccc1a2a4, 0xc43c000e, + 0x2bfc0008, 0xcfc00013, 0xc43d3249, 0x1bfc003e, 0x9bc00007, 0xc428000e, 0x16a80008, 0xce800009, + 0xc42c005e, 0x96c00b33, 0xd840003c, 0xc4200025, 0x7da2400f, 0x7da28002, 0x7e1ac002, 0x0aec0001, + 0x96400002, 0x7d2ac002, 0x3ef40010, 0x9b40f11d, 0x04380030, 0xcf81325e, 0x80000c16, 0xde410000, + 0xdcc10000, 0xdd010000, 0xdd410000, 0xdd810000, 0xddc10000, 0xde010000, 0xc40c000e, 0x7c024001, + 0x28cc0008, 0xccc00013, 0xc8100086, 0x5510003f, 0xc40d3249, 0x18cc003e, 0x98c00003, 0x99000011, + 0x80001075, 0x9900000c, 0xc40c0026, 0xc4100081, 0xc4140025, 0x7d15800f, 0x7d15c002, 0x7d520002, + 0x0a200001, 0x95800002, 0x7cde0002, 0x3e20001a, 0x9a000009, 0x040c0030, 0xccc1325e, 0x80001071, + 0xd9c00036, 0xd8400029, 0xc40c005e, 0x94c00b01, 0x04240001, 0xdc200000, 0xdc1c0000, 0xdc180000, + 0xdc140000, 0xdc100000, 0xdc0c0000, 0x96400004, 0xdc240000, 0xdc0c0000, 0x80000c16, 0xdc240000, + 0x90000000, 0xcc40003f, 0xd8c00010, 0xc4080029, 0xcc80003b, 0xc418000e, 0x18a800e5, 0x1d980008, + 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, 0x18a400e5, 0x12500009, 0x248c0008, 0x94c00006, + 0x200c006d, 0x7cd0c00a, 0xccc1326c, 0xc421326c, 0x96000001, 0xcd800013, 0x200c0228, 0x7cd0c00a, + 0xccc1326c, 0xc421326c, 0x96000001, 0xc40c002a, 0xc410002b, 0x18881fe8, 0x18d4072c, 0x18cc00d1, + 0x7cd4c00a, 0x3094000d, 0x38d80000, 0x311c0003, 0x99400006, 0x30940007, 0x1620001f, 0x9940001d, + 0x9a000023, 0x800010c4, 0x9580001a, 0x99c00019, 0xccc00041, 0x25140001, 0xc418002c, 0x9940000d, + 0x259c007f, 0x95c00013, 0x19a00030, 0xcdc0001b, 0xd8400021, 0xd8400022, 0xc430000f, 0x17300001, + 0x9b00fffe, 0x9a000012, 0xd8400023, 0x800010cb, 0x199c0fe8, 0xcdc0001b, 0xd8400021, 0xd8400023, + 0xc430000f, 0x17300001, 0x9b00fffe, 0x800010cb, 0xd8c00010, 0xd8000022, 0xd8000023, 0xc430005e, + 0x97000aac, 0x7c408001, 0x88000000, 0xc43c000e, 0xc434002e, 0x2bfc0008, 0x2020002c, 0xcfc00013, + 0xce01326c, 0x17780001, 0x27740001, 0x07a810d8, 0xcf400010, 0xc421326c, 0x96000001, 0x86800000, + 0x80000168, 0x80000aa7, 0x80000bfc, 0x800012e9, 0x8000104c, 0xcc400040, 0xd8800010, 0xc4180032, + 0x29980008, 0xcd800013, 0x200c007d, 0xccc1325b, 0xc411325b, 0x95000001, 0x7c408001, 0x88000000, + 0x28240007, 0xde430000, 0xd4400078, 0x80001190, 0xcc80003b, 0x24b00008, 0xc418000e, 0x1330000a, + 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, 0xc40d3249, 0x18cc003e, + 0x98c00002, 0xd840003d, 0x2b304000, 0xcf01326c, 0xc431326c, 0x7c40c001, 0x7c410001, 0x7c414001, + 0x192400fd, 0x50580020, 0x7d59401a, 0x7c41c001, 0x06681110, 0x7c420001, 0xcc400078, 0x18ac0024, + 0x19180070, 0x19100078, 0xcec00008, 0x18f40058, 0x5978073a, 0x7f7b400a, 0x97000001, 0x86800000, + 0x80001117, 0x80001118, 0x80001122, 0x8000112d, 0x80001130, 0x80001133, 0x8000016a, 0x8000117b, + 0x24ec0f00, 0x32ec0600, 0x96c00003, 0xc4300006, 0x9b00ffff, 0xd1400025, 0xcf400024, 0xcdc00026, + 0xd8400027, 0x8000117b, 0x24ec0f00, 0x32ec0600, 0x96c00003, 0xc4300006, 0x9b00ffff, 0xd1400025, + 0xcf400024, 0xcdc00026, 0xce000026, 0xd8400027, 0x8000117b, 0xc81c001f, 0x55e00020, 0x80001122, + 0xc81c0020, 0x55e00020, 0x80001122, 0x8c00116b, 0xd8400013, 0xc02a0200, 0x7e8e8009, 0x22a8003d, + 0x22a80074, 0x2774001c, 0x13740014, 0x7eb6800a, 0x25ecffff, 0x55700020, 0x15f40010, 0x13740002, + 0x275c001f, 0x95c00027, 0x7c018001, 0x7f41c001, 0x15dc0002, 0x39e00008, 0x25dc0007, 0x7dc1c01e, + 0x05dc0001, 0x96000004, 0x05e40008, 0x8c00116e, 0x80001168, 0x7dc2001e, 0x06200001, 0x05e40008, + 0x7e62000e, 0x9a000004, 0x7da58001, 0x8c00116e, 0x80001165, 0x7dc2001e, 0x06200001, 0x7e1a0001, + 0x05cc0008, 0x7e0d000e, 0x95000007, 0x7e02401e, 0x06640001, 0x06640008, 0x05d80008, 0x8c00116e, + 0x80001168, 0x7dc2401e, 0x06640001, 0x7da58001, 0x8c00116e, 0x05e00008, 0x7da2000c, 0x9600ffe6, + 0x17640002, 0x8c00116e, 0x80001190, 0xc4200006, 0x9a00ffff, 0x90000000, 0x8c00116b, 0xc420000e, + 0x2a200001, 0xce00001a, 0xce81c078, 0xcec1c080, 0xcc01c081, 0xcd41c082, 0xcf01c083, 0x12640002, + 0x22640435, 0xce41c084, 0x90000000, 0x0528117e, 0x312c0003, 0x86800000, 0x80001190, 0x80001185, + 0x80001182, 0x80001182, 0xc4300012, 0x9b00ffff, 0x9ac0000c, 0xc03a0400, 0xc4340004, 0xd8400013, + 0xd8400008, 0xc418000e, 0x15980008, 0x1198001c, 0x7d81c00a, 0xcdc130b7, 0xcf8130b5, 0xcf400008, + 0x04240008, 0xc418000e, 0xc41c0049, 0x19a000e8, 0x29a80008, 0x7de2c00c, 0xce800013, 0xc421325e, + 0x26200010, 0xc415326d, 0x9a000006, 0xc420007d, 0x96000004, 0x96c00003, 0xce40003e, 0x800011a3, + 0x7d654001, 0xcd41326d, 0x7c020001, 0x96000005, 0xc4100026, 0xc4240081, 0xc4140025, 0x800011b6, + 0xc4253279, 0xc415326d, 0xc431326c, 0x2730003f, 0x3b380006, 0x97800004, 0x3f38000b, 0x9b800004, + 0x800011b4, 0x04300006, 0x800011b4, 0x0430000b, 0x04380002, 0x7fb10004, 0x7e57000f, 0x7e578002, + 0x7d67c002, 0x0be40001, 0x97000002, 0x7d3a4002, 0x202c002c, 0xc421325e, 0x04280020, 0xcec1326c, + 0x26200010, 0x3e640010, 0x96000003, 0x96400002, 0xce81325e, 0xc4300028, 0xc434002e, 0x17780001, + 0x27740001, 0x07a811cf, 0x9b00feb8, 0xcf400010, 0xc414005e, 0x954009a7, 0x86800000, 0x80000168, + 0x80000aa7, 0x80000bfc, 0x800012e9, 0x80000168, 0x8c00120d, 0x7c40c001, 0xccc1c07c, 0xcc41c07d, + 0xcc41c08c, 0x7c410001, 0xcc41c079, 0xcd01c07e, 0x7c414001, 0x18f0012f, 0x18f40612, 0x18cc00c1, + 0x7f73400a, 0x7cf7400a, 0x39600004, 0x9a000002, 0xc0140004, 0x11600001, 0x18fc003e, 0x9740001c, + 0xcf400041, 0xc425c07f, 0x97c00003, 0x166c001f, 0x800011ee, 0x1a6c003e, 0x96c00006, 0x04200002, + 0x0a200001, 0x9a00ffff, 0xd8400013, 0x800011e8, 0xc428002c, 0x96800010, 0x26ac007f, 0xcec0001b, + 0xd8400021, 0x1ab00030, 0x1aac0fe8, 0xc434000f, 0x9b40ffff, 0x97000008, 0xcec0001b, 0xd8400021, + 0xc434000f, 0x9b40ffff, 0x80001205, 0x0a200001, 0x9a00ffff, 0xd8400013, 0xc425c07f, 0x166c001f, + 0x11600001, 0x9ac0fffa, 0x8c001232, 0x7c408001, 0x88000000, 0xd8000033, 0xc438000b, 0xc43c0009, + 0x27fc0001, 0x97c0fffe, 0xd8400013, 0xd841c07f, 0xc43dc07f, 0x1bfc0078, 0x7ffbc00c, 0x97c0fffd, + 0x90000000, 0xc03a2800, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04380040, + 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380060, 0xcf80001b, 0xd8400021, 0xc438000f, + 0x9b80ffff, 0x04380002, 0x0bb80001, 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, + 0x9bc0fffa, 0x90000000, 0xd8400013, 0xd801c07f, 0xd8400013, 0xc43dc07f, 0xcfc00078, 0xd8000034, + 0x90000000, 0xc03ae000, 0xcf81c200, 0xc03a0800, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, + 0xcc01c07e, 0x04380040, 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380002, 0x0bb80001, + 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, 0x9bc0fffa, 0x90000000, 0xc03ae000, + 0xcf81c200, 0xc03a4000, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04380002, + 0x0bb80001, 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, 0x9bc0fffa, 0x90000000, + 0xc40c0007, 0x30d00002, 0x99000052, 0xd8400029, 0xc424005e, 0x9640090f, 0x7c410001, 0xc428000e, + 0x1514001f, 0x19180038, 0x2aa80008, 0x99400030, 0x30dc0001, 0xce800013, 0x99c0000a, 0xc42d324e, + 0xc431324d, 0x52ec0020, 0x7ef2c01a, 0xc435324f, 0xc4293256, 0x1ab0c006, 0x52ec0008, 0x8000127f, + 0xc42d3258, 0xc4313257, 0x52ec0020, 0x7ef2c01a, 0xc4353259, 0xc429325a, 0x1ab0c012, 0x07740001, + 0x04240002, 0x26a0003f, 0x7e624004, 0x7f67800f, 0x97800002, 0x04340000, 0x53740002, 0x7ef6c011, + 0x1ab42010, 0x16a8000c, 0x26a80800, 0x2b740000, 0x7f73400a, 0x7f6b400a, 0xcf40001c, 0xd2c0001e, + 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4100011, 0x1514001f, 0x99400006, 0x9980000a, 0x8c0012e1, + 0xc40c0007, 0x04100000, 0x80001267, 0xd800002a, 0xc424005e, 0x964008d7, 0xd9800036, 0x80000c16, + 0xc42c001d, 0x95c00005, 0xc431325a, 0x1b300677, 0x11dc000c, 0x800012aa, 0xc4313256, 0x1b34060b, + 0x1b300077, 0x7f37000a, 0x13300017, 0x04340100, 0x26ec00ff, 0xc03a8002, 0x7ef6c00a, 0x7edec00a, + 0x7f3b000a, 0x7ef2c00a, 0xcec1325b, 0x80000c16, 0xc4140032, 0xc410001d, 0x29540008, 0xcd400013, + 0xc40d325b, 0x1858003f, 0x251000ff, 0x99800007, 0x7d0cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, + 0xcd01325d, 0x80000168, 0x18d0006c, 0x18d407f0, 0x9900000e, 0x04100002, 0xc4193256, 0xc41d324f, + 0x2598003f, 0x7d190004, 0x7d5d4001, 0x7d52000f, 0x9a000003, 0xcd41324f, 0x800012d8, 0x7d514002, + 0xcd41324f, 0x800012d8, 0xc4193259, 0xc41d325a, 0x7d958001, 0x7dd5c002, 0xcd813259, 0xcdc1325a, + 0xc411325d, 0x251001ef, 0xcd01325d, 0x1ccc001e, 0xccc1325b, 0xc40d325b, 0x94c00001, 0x7c408001, + 0x88000000, 0xc40c0021, 0xc4340028, 0x14f00010, 0xc4380030, 0xc43c0007, 0x9b000004, 0x9b40000c, + 0x9b80000f, 0x90000000, 0x17300001, 0x9b000005, 0xccc00037, 0x8c000190, 0xd8000032, 0x90000000, + 0xd8000028, 0xd800002b, 0x80000168, 0xd980003f, 0x97c00002, 0xd9c0003f, 0x80001082, 0xd9800040, + 0x97c00002, 0xd9c00040, 0x800010de, 0xc43c0007, 0x33f80003, 0x97800051, 0xcc80003b, 0x24b00008, + 0xc418000e, 0x1330000a, 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, + 0xc4353249, 0x1b74003e, 0x9b400002, 0xd840003d, 0x2b304000, 0xcf01326c, 0xc431326c, 0x97000001, + 0x7c434001, 0x1b4c00f8, 0x7c410001, 0x7c414001, 0x50700020, 0x04e81324, 0x18ac0024, 0x7c41c001, + 0x50600020, 0xcc400078, 0x30e40004, 0x9a400007, 0x7d71401a, 0x596401fc, 0x12640009, 0x1b74008d, + 0x7e76400a, 0x2a640000, 0xcec00008, 0x86800000, 0x8000016a, 0x8000016a, 0x8000016a, 0x8000016a, + 0x8000132c, 0x8000133b, 0x80001344, 0x8000016a, 0xc4340004, 0xd8400013, 0xd8400008, 0xc42530b5, + 0x1a68003a, 0x9a80fffe, 0x2024003a, 0xc418000e, 0x25980700, 0x11980014, 0x7d19000a, 0xcd0130b7, + 0xce4130b5, 0xcf400008, 0x80001190, 0xce40001c, 0xd140001e, 0xd8400021, 0xc428000f, 0x9a80ffff, + 0xc4240011, 0x7de6800f, 0x9a80ffea, 0x80001190, 0xce40001c, 0xd140001e, 0xd8400021, 0xc428000f, + 0x9a80ffff, 0xc8240011, 0x7de1c01a, 0x7de6800f, 0x9a80ffe0, 0x80001190, 0x8c00104f, 0x28182002, + 0xc430000d, 0xc4340035, 0xcd800013, 0xc8140023, 0xc4180081, 0x13300005, 0xc4240004, 0x11a00002, + 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x3e280008, + 0x7cb4800a, 0xc4300027, 0x042c0008, 0xd1400025, 0xcf000024, 0x20240030, 0x7ca48001, 0xcc800026, + 0x7c434001, 0x1b4c00f8, 0xcf400026, 0xcc400026, 0x28340000, 0xcf400013, 0x7c414001, 0x507c0020, + 0x30e40004, 0x9a400005, 0x7d7d401a, 0xd1400072, 0xc8140072, 0x557c0020, 0x28342002, 0xcf400013, + 0xcd400026, 0xcfc00026, 0xd4400026, 0xcc000026, 0x9a800005, 0x32280000, 0x9a800002, 0x9a000000, + 0x7c018001, 0xd8400027, 0xd8800013, 0x04380028, 0xcec0003a, 0xcf81a2a4, 0x80001037, 0xd8400029, + 0xc40c005e, 0x94c007eb, 0x7c40c001, 0x50500020, 0x7d0d001a, 0xd1000072, 0xc8100072, 0x591c01fc, + 0x11dc0009, 0x45140210, 0x595801fc, 0x11980009, 0x29dc0000, 0xcdc0001c, 0xd140001e, 0xd8400021, + 0xc418000f, 0x9980ffff, 0xc4200011, 0x1624001f, 0x96400069, 0xc40c000e, 0x28cc0008, 0xccc00013, + 0xce013249, 0x1a307fe8, 0xcf00000a, 0x23304076, 0xd1000001, 0xcf000001, 0xc41d3254, 0xc4253256, + 0x18cc00e8, 0x10cc0015, 0x4514020c, 0xd140001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4200011, + 0xce013248, 0x1a2001e8, 0x12200014, 0x2a204001, 0xce000013, 0x1a64003c, 0x1264001f, 0x11dc0009, + 0x15dc000b, 0x7dcdc00a, 0x7e5dc00a, 0xcdc00100, 0xd8800013, 0xd8400010, 0xd800002a, 0xd8400008, + 0xcf00000d, 0xcf00000a, 0x8c001427, 0x04340022, 0x07740001, 0x04300010, 0xdf430000, 0x7c434001, + 0x7c408001, 0xd4412e01, 0x0434001e, 0xdf430000, 0xd4400078, 0xdf030000, 0xd4412e40, 0xd8400013, + 0xcc41c030, 0xcc41c031, 0x248dfffe, 0xccc12e00, 0xd8800013, 0xcc812e00, 0x7c434001, 0x7c434001, + 0x8c00142b, 0xd8000010, 0xc40c000e, 0x28cc0008, 0xccc00013, 0x45140248, 0xd140001e, 0xd8400021, + 0xc418000f, 0x9980ffff, 0xc8200011, 0xce013257, 0x56200020, 0xce013258, 0x0434000c, 0xdb000024, + 0xd1400025, 0xd8000026, 0xd8000026, 0xd8400027, 0x45540008, 0xd140001e, 0xd8400021, 0xc418000f, + 0x9980ffff, 0xc8200011, 0xce013259, 0x56200020, 0xc0337fff, 0x7f220009, 0xce01325a, 0x55300020, + 0x7d01c001, 0x042c01d0, 0x8c000d61, 0x06ec0004, 0x7f01c001, 0x8c000d61, 0x041c0002, 0x042c01c8, + 0x8c000d61, 0xc4380012, 0x9b80ffff, 0xd800002a, 0x80000aa7, 0xd800002a, 0x7c408001, 0x88000000, + 0xd8400029, 0x7c40c001, 0x50500020, 0x8c001427, 0x7cd0c01a, 0xc4200007, 0xd0c00072, 0xc8240072, + 0xd240001e, 0x7c414001, 0x19682011, 0x5a6c01fc, 0x12ec0009, 0x7eeac00a, 0x2aec0000, 0xcec0001c, + 0xd8400021, 0xc430000f, 0x9b00ffff, 0xc4180011, 0x7c438001, 0x99800007, 0xdf830000, 0xcfa0000c, + 0x8c00142b, 0xd4400078, 0xd800002a, 0x80001b70, 0x8c00142b, 0xd800002a, 0x80001b70, 0xd8000012, + 0xc43c0008, 0x9bc0ffff, 0x90000000, 0xd8400012, 0xc43c0008, 0x97c0ffff, 0x90000000, 0xc4380007, + 0x7c40c001, 0x17b80001, 0x18d40038, 0x7c410001, 0x9b800004, 0xd8400029, 0xc414005e, 0x9540073d, + 0x18c80066, 0x7c414001, 0x30880001, 0x7c418001, 0x94800008, 0x8c00187c, 0xcf400013, 0xc42c0004, + 0xd8400008, 0xcd910000, 0xcec00008, 0x7d410001, 0x043c0000, 0x7c41c001, 0x7c420001, 0x04240001, + 0x06200001, 0x4220000c, 0x0a640001, 0xcc000078, 0x9a40fffe, 0x24e80007, 0x24ec0010, 0xd8400013, + 0x9ac00006, 0xc42c0004, 0xd8400008, 0xc5310000, 0xcec00008, 0x80001465, 0x51540020, 0x7d15001a, + 0xd1000072, 0xc82c0072, 0xd2c0001e, 0x18f02011, 0x5aec01fc, 0x12ec0009, 0x7ef2c00a, 0x2aec0000, + 0xcec0001c, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc4300011, 0x96800012, 0x12a80001, 0x0aa80001, + 0x06a8146a, 0x7f1f0009, 0x86800000, 0x7f1b400f, 0x80001478, 0x7f1b400e, 0x80001478, 0x7f1b400c, + 0x8000147a, 0x7f1b400d, 0x8000147a, 0x7f1b400f, 0x8000147a, 0x7f1b400e, 0x8000147a, 0x7f334002, + 0x97400014, 0x8000147b, 0x9b400012, 0x9b800005, 0x9bc0001f, 0x7e024001, 0x043c0001, 0x8000144a, + 0xc40c0032, 0xc438001d, 0x28cc0008, 0xccc00013, 0xc43d325b, 0x1bb81ff0, 0x7fbfc00a, 0xcfc1325b, + 0xc411325d, 0x251001ef, 0xcd01325d, 0x80001b70, 0x94800007, 0x8c00187c, 0xcf400013, 0xc42c0004, + 0xd8400008, 0xcd910000, 0xcec00008, 0x9b800003, 0xd800002a, 0x80001b70, 0xc40c0032, 0x28cc0008, + 0xccc00013, 0xc40d325b, 0x800012c2, 0xc40c000e, 0xc43c0007, 0xc438001d, 0x28cc0008, 0xccc00013, + 0x13f4000c, 0x9bc00006, 0xc43d3256, 0x1bf0060b, 0x1bfc0077, 0x7ff3c00a, 0x800014a9, 0xc43d325a, + 0x1bfc0677, 0x04300100, 0x1bb81ff0, 0x7f73400a, 0xc0328007, 0x7fb7800a, 0x13fc0017, 0x7ff3c00a, + 0x7ffbc00a, 0xcfc1325b, 0xc03a0002, 0xc4340004, 0xd8400013, 0xd8400008, 0xcf8130b5, 0xcf400008, + 0x80000c16, 0x043c0000, 0xc414000e, 0x29540008, 0xcd400013, 0xc4193246, 0xc41d3245, 0x51980020, + 0x7dd9c01a, 0x45dc0390, 0xc4313267, 0x04183000, 0xcd813267, 0x1b380057, 0x1b340213, 0x1b300199, + 0x7f7b400a, 0x7f73400a, 0xcf400024, 0xd1c00025, 0xcc800026, 0x7c420001, 0xce000026, 0x7c424001, + 0xce400026, 0x7c428001, 0xce800026, 0x7c42c001, 0xcec00026, 0x7c430001, 0xcf000026, 0x7c434001, + 0xcf400026, 0x7c438001, 0xcf800026, 0xd8400027, 0xcd400013, 0x04182000, 0xcd813267, 0xd840004f, + 0x1a0800fd, 0x109c000a, 0xc4193265, 0x7dd9c00a, 0xcdc13265, 0x2620ffff, 0xce080228, 0x9880000e, + 0xce480250, 0xce880258, 0xd8080230, 0xd8080238, 0xd8080240, 0xd8080248, 0xd8080268, 0xd8080270, + 0xd8080278, 0xd8080280, 0xd800004f, 0x97c0ec75, 0x90000000, 0x040c0000, 0x041c0010, 0x26180001, + 0x09dc0001, 0x16200001, 0x95800002, 0x04cc0001, 0x99c0fffb, 0xccc80230, 0xd8080238, 0xd8080240, + 0xd8080248, 0x040c0000, 0xce480250, 0xce880258, 0x52a80020, 0x7e6a401a, 0x041c0020, 0x66580001, + 0x09dc0001, 0x56640001, 0x95800002, 0x04cc0001, 0x99c0fffb, 0xccc80260, 0xd8080268, 0xd8080270, + 0xd8080278, 0xd8080280, 0x040c0000, 0xcec80288, 0xcf080290, 0xcec80298, 0xcf0802a0, 0x040c0000, + 0x041c0010, 0xcf4802a8, 0x27580001, 0x09dc0001, 0x17740001, 0x95800002, 0x04cc0001, 0x99c0fffb, + 0xccc802b0, 0xd80802b8, 0x178c000b, 0x27b8003f, 0x7cf8c001, 0xcf8802c0, 0xccc802c8, 0xcf8802d0, + 0xcf8802d8, 0xd800004f, 0x97c00002, 0x90000000, 0x7c408001, 0x88000000, 0xc40c000e, 0x28cc0008, + 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c418001, 0x25b8ffff, 0xc4930240, 0xc48f0238, 0x04cc0001, + 0x24cc000f, 0x7cd2800c, 0x9a80000b, 0xc5230309, 0x2620ffff, 0x7e3a400c, 0x9a400004, 0x05100001, + 0x2510000f, 0x80001539, 0xcd08034b, 0xd4400078, 0x80000168, 0xc48f0230, 0xc4930240, 0x98c00004, + 0xcd880353, 0x8c00163f, 0xc49b0353, 0xc4930238, 0xc48f0228, 0x05100001, 0x2510000f, 0x7cd14005, + 0x25540001, 0x99400004, 0x05100001, 0x2510000f, 0x8000154f, 0xc48f0230, 0x7c41c001, 0xcd080238, + 0xcd08034b, 0x08cc0001, 0x2598ffff, 0x3d200008, 0xccc80230, 0xcd900309, 0xd8100319, 0x04340801, + 0x2198003f, 0xcf400013, 0xcd910ce7, 0xc4190ce6, 0x7d918005, 0x25980001, 0x9580fffd, 0x7d918004, + 0xcd810ce6, 0x9a000003, 0xcdd1054f, 0x8000156e, 0x090c0008, 0xcdcd050e, 0x040c0000, 0x110c0014, + 0x28cc4001, 0xccc00013, 0xcc41230a, 0xcc41230b, 0xcc41230c, 0xcc41230d, 0xcc480329, 0xcc48032a, + 0xcc4802e0, 0xd8000055, 0xc48f02e0, 0x24d8003f, 0x09940001, 0x44100001, 0x9580002c, 0x95400005, + 0x09540001, 0x51100001, 0x69100001, 0x8000157f, 0x24cc003f, 0xc4970290, 0xc49b0288, 0x51540020, + 0x7d59401a, 0xc49b02a0, 0xc49f0298, 0x51980020, 0x7d9d801a, 0x041c0040, 0x04200000, 0x7dcdc002, + 0x7d924019, 0x7d26400c, 0x09dc0001, 0x9a400008, 0x51100001, 0x06200001, 0x99c0fffa, 0xc48f0230, + 0xc4930240, 0x8c00163f, 0x80001579, 0x7d010021, 0x7d914019, 0xc4930238, 0x55580020, 0xcd480298, + 0xcd8802a0, 0x10d40010, 0x12180016, 0xc51f0309, 0x7d95800a, 0x7d62000a, 0x7dd9c00a, 0xd8400013, + 0xcdd00309, 0xce113320, 0xc48f02e0, 0xc49b02b0, 0x18dc01e8, 0x7dd9400e, 0xc48f0230, 0xc4930240, + 0x95c0001d, 0x95400003, 0x8c00163f, 0x800015aa, 0xc48f0238, 0xc4a302b8, 0x12240004, 0x7e5e400a, + 0xc4ab02a8, 0x04100000, 0xce4c0319, 0x7d9d8002, 0x7ea14005, 0x25540001, 0x99400004, 0x06200001, + 0x2620000f, 0x800015bc, 0x09dc0001, 0x04240001, 0x7e624004, 0x06200001, 0x7d25000a, 0x2620000f, + 0x99c0fff4, 0xd8400013, 0xcd0d3330, 0xce0802b8, 0xcd8802b0, 0xc4ab02e0, 0x1aa807f0, 0xc48f02d0, + 0xc49702d8, 0xc49b02c8, 0xc49f02c0, 0x96800028, 0x7d4e000f, 0x9600000b, 0x7d964002, 0x7e6a000f, + 0x96000003, 0x7d694001, 0x800015e9, 0x7cde4002, 0x7e6a000f, 0x96000008, 0x7de94001, 0x800015e9, + 0x7cd64002, 0x7e6a000e, 0x96000003, 0x7d694001, 0x800015e9, 0xc48f0230, 0xc4930240, 0x8c00163f, + 0x800015cd, 0xc4930238, 0x7d698002, 0xcd4802d8, 0x129c0008, 0xc50f0319, 0x11a0000e, 0x11140001, + 0xc4340004, 0xd8400008, 0xd8400013, 0x7e1e000a, 0x1198000a, 0xcd953300, 0x7e0e000a, 0x12a8000a, + 0xce953301, 0xce100319, 0xcf400008, 0xc4b70280, 0xc4b30278, 0x7f73800a, 0x536c0020, 0x7ef2c01a, + 0x9780eb68, 0x8c001608, 0xd8080278, 0xd8080280, 0x7c408001, 0x88000000, 0x043c0003, 0x80001609, + 0x043c0001, 0x30b40000, 0x9b400011, 0xc4b70258, 0xc4b30250, 0x53780020, 0x7fb3801a, 0x7faf8019, + 0x04300020, 0x04280000, 0x67b40001, 0x0b300001, 0x57b80001, 0x97400002, 0x06a80001, 0x9b00fffb, + 0xc4bb0260, 0x7fab8001, 0xcf880260, 0x04300020, 0x04280000, 0x66f40001, 0x0b300001, 0x56ec0001, + 0x97400005, 0x8c001628, 0xc4353247, 0x7f7f4009, 0x9b40fffe, 0x06a80001, 0x9b00fff7, 0x90000000, + 0x269c0007, 0x11dc0008, 0x29dc0008, 0x26a00018, 0x12200003, 0x7de1c00a, 0x26a00060, 0x06200020, + 0x16200001, 0x7de1c00a, 0xcdc00013, 0x90000000, 0x269c0018, 0x26a00007, 0x26a40060, 0x11dc0006, + 0x12200006, 0x16640001, 0x29dc0008, 0x7de1c00a, 0x7de5c00a, 0xcdc00013, 0x90000000, 0xc4b70228, + 0x05100001, 0x04cc0001, 0x2510000f, 0xccc80230, 0x7f514005, 0x25540001, 0x99400004, 0x05100001, + 0x2510000f, 0x80001644, 0xc4b30248, 0xcd080240, 0x7f130005, 0x27300001, 0x9b000002, 0x8c001688, + 0x8c00120d, 0x8c001219, 0x8c001232, 0x04300001, 0x04340801, 0x7f130004, 0xcf400013, 0xcf01051e, + 0xc42d051f, 0x7ed2c005, 0x26ec0001, 0x96c0fffd, 0xcf01051f, 0xd8000055, 0xc5170309, 0x195c07f0, + 0x196007f6, 0x04340000, 0x95c00008, 0x09dc0001, 0x04340001, 0x95c00005, 0x09dc0001, 0x53740001, + 0x6b740001, 0x80001665, 0xc4a702a0, 0xc4ab0298, 0x52640020, 0x7e6a401a, 0x7f634014, 0x7e76401a, + 0xc4300004, 0xd8400008, 0xd8400013, 0x56680020, 0xd8113320, 0xce480298, 0xce8802a0, 0xc5170319, + 0xc4b702b0, 0x255c000f, 0x7f5f4001, 0xd8113330, 0xcf4802b0, 0x11340001, 0x195c07e8, 0x196007ee, + 0xd8353300, 0x7e1e4001, 0xd8353301, 0xce4802d0, 0xd8100309, 0xd8100319, 0xcf000008, 0x90000000, + 0xc4970258, 0xc48f0250, 0x51540020, 0x7cd4c01a, 0xc4af0280, 0xc4b30278, 0x52ec0020, 0x7ef2c01a, + 0x04140020, 0x04280000, 0x64d80001, 0x09540001, 0x54cc0001, 0x95800060, 0x8c001628, 0xc4193247, + 0x25980001, 0x9580005c, 0x7dc24001, 0xc41d3248, 0x25dc000f, 0x7dd2000c, 0x96000057, 0xc41d3255, + 0xc435324f, 0x7df5c00c, 0x99c00004, 0xc4193265, 0x25980040, 0x9580fffe, 0xc439325b, 0x1bb0003f, + 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, 0x9700000a, 0xc4393260, 0x1bb000e4, + 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x800016f1, 0xce400013, 0xc033ffff, + 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, 0x27b800ff, 0x9b80fffe, 0xd8c00033, + 0xc4300009, 0x27300008, 0x9700fffe, 0x1a7003e6, 0x27380003, 0x13b80004, 0x27300003, 0x13300003, + 0x7fb38001, 0x1a7000e8, 0x7fb38001, 0x13300001, 0x7fb38001, 0x07b80002, 0xd8400013, 0x1a700064, + 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x0b300003, 0x800016df, 0x17b00005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, 0x13300005, + 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, 0xd8c00034, 0xce400013, 0xc431325d, + 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffca, 0xd841325d, 0x2030007b, 0xcf01325b, + 0x800016f2, 0xd841325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0x06a80001, 0x9940ff9c, 0x8c001608, + 0xd8080278, 0xd8080280, 0x90000000, 0xd840004f, 0xc414000e, 0x29540008, 0xcd400013, 0xc43d3265, + 0x1bc800ea, 0xd80802e9, 0x7c40c001, 0x18fc0064, 0x9bc00042, 0xc4193246, 0xc41d3245, 0x51980020, + 0x7dd9801a, 0x45980400, 0xc4313267, 0x043c3000, 0xcfc13267, 0xc43d3267, 0x9bc00001, 0x1b380057, + 0x1b340213, 0x1b300199, 0x7f7b400a, 0x7f73400a, 0xcf400024, 0x14f4001d, 0xc4bf02e9, 0x9bc0001c, + 0x7c410001, 0x192807fa, 0xc4bf0258, 0xc4a70250, 0x53fc0020, 0x7e7e401a, 0x042c0000, 0x04300000, + 0x667c0001, 0x56640001, 0x06ec0001, 0x97c0fffd, 0x07300001, 0x0aec0001, 0x7eebc00c, 0x06ec0001, + 0x97c0fff8, 0x0b300001, 0x43300007, 0x53300002, 0x7db30011, 0xd3000025, 0xc03ec005, 0x2bfca200, + 0xcfc00026, 0xccc00026, 0xcd000026, 0x192807fa, 0xc01f007f, 0x7d1d0009, 0x2110007d, 0x8c001628, + 0x203c003f, 0xcfc13256, 0x8c0017f5, 0xcd013254, 0x18fc01e8, 0xcfc13248, 0x8c00185b, 0xd8413247, + 0x0b740001, 0x9b40ffd5, 0xd800004f, 0xc4bf02e9, 0x97c0ea24, 0x90000000, 0x14d4001d, 0xc4930260, + 0x7d52400e, 0xc49f0258, 0xc4a30250, 0x51dc0020, 0x7de1801a, 0x96400017, 0x7d534002, 0xc4af0270, + 0x7dae4005, 0x26640001, 0x32e0001f, 0x9a400006, 0x06ec0001, 0x96000002, 0x042c0000, 0xcec80270, + 0x8000174f, 0x0b740001, 0x8c00178a, 0x05100001, 0x9b40fff3, 0xc4af0280, 0xc4b30278, 0x52ec0020, + 0x7ef2c01a, 0x8c001608, 0xd8080278, 0xd8080280, 0xc4ab0268, 0x7daa4005, 0x26640001, 0x32a0001f, + 0x9a400005, 0x06a80001, 0x96000002, 0x24280000, 0x80001765, 0x7c410001, 0xc01f007f, 0x09540001, + 0x7d1d0009, 0x2110007d, 0x8c001628, 0xd8013256, 0x8c0017f2, 0xcd013254, 0xc4113248, 0x15100004, + 0x11100004, 0xc4b3034b, 0x7f13000a, 0xcf013248, 0xc4930260, 0x8c001855, 0x32a4001f, 0xd8413247, + 0xd800004f, 0x09100001, 0x06a80001, 0x96400002, 0x24280000, 0xcd080260, 0xce880268, 0x9940ffc0, + 0x7c408001, 0x88000000, 0x7ec28001, 0x8c001628, 0x32e0001f, 0xc4253247, 0x26640001, 0x9640005e, + 0xc4293265, 0xc4253255, 0xc431324f, 0x7e72400c, 0x26a80040, 0x9a400002, 0x9680fff7, 0xc429325b, + 0x1aa4003f, 0x96400049, 0x1aa400e8, 0x32680003, 0x9a800046, 0x32640002, 0x9640000a, 0xc4293260, + 0x1aa400e4, 0x32640004, 0x96400040, 0xc425325d, 0x26640010, 0x9a40fffe, 0x800017e2, 0xcdc00013, + 0xc027ffff, 0x2e6400ff, 0xc429325b, 0x7e6a4009, 0xce41325b, 0xc429325b, 0x26a800ff, 0x9a80fffe, + 0xd8c00033, 0xc4240009, 0x26640008, 0x9640fffe, 0x19e403e6, 0x26680003, 0x12a80004, 0x26640003, + 0x12640003, 0x7ea68001, 0x19e400e8, 0x7ea68001, 0x12640001, 0x7ea68001, 0x06a80002, 0xd8400013, + 0x19e40064, 0x32640002, 0x96400009, 0x16a40005, 0x06640003, 0xce412082, 0xcc01203f, 0xd8400013, + 0xcc01203f, 0x0a640003, 0x800017d0, 0x16a40005, 0xce412082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x12640005, 0x7ea64002, 0xc4292083, 0x7ea68005, 0x26a80001, 0x9a80ffdf, 0xd8c00034, 0xcdc00013, + 0xc425325d, 0x26640010, 0x9a40fffe, 0xc429325b, 0x26a400ff, 0x9a40ffca, 0xd841325d, 0x2024007b, + 0xce41325b, 0x800017e3, 0xd841325d, 0xc4a70280, 0xc4ab0278, 0x52640020, 0x7e6a401a, 0x04280001, + 0x7eae8014, 0x7e6a401a, 0x56680020, 0xce480278, 0xce880280, 0x06ec0001, 0x96000002, 0x042c0000, + 0xcec80270, 0x90000000, 0x7c438001, 0x7c420001, 0x800017fe, 0xc4bf02e9, 0x9bc00006, 0x7c438001, + 0x7c420001, 0xcf800026, 0xce000026, 0x800017fe, 0xc43b02eb, 0xc42302ec, 0xcf813245, 0xce013246, + 0x52200020, 0x7fa3801a, 0x47b8020c, 0x15e00008, 0x1220000a, 0x2a206032, 0x513c001e, 0x7e3e001a, + 0xc4bf02e9, 0x9bc00005, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0x8000180f, 0xcd400013, 0xc4313267, + 0x1b3c0077, 0x1b300199, 0x7ff3000a, 0x1330000a, 0x2b300032, 0x043c3000, 0xcfc13267, 0xc43d3267, + 0xd200000b, 0xc4200007, 0xd3800002, 0xcf000002, 0xd8000040, 0x96000002, 0xd8400040, 0xd8400018, + 0x043c2000, 0xcfc13267, 0xd8000018, 0xd8800010, 0xcdc00013, 0x7dc30001, 0xdc1e0000, 0x04380032, + 0xcf80000e, 0x8c001427, 0xcc413248, 0xc43d3269, 0x27fc000f, 0x33fc0003, 0x97c00011, 0x043c001f, + 0xdfc30000, 0xd4413249, 0x7c43c001, 0x7c43c001, 0x043c0024, 0x0bfc0021, 0xdfc30000, 0xd441326a, + 0x173c0008, 0x1b300303, 0x7f3f0001, 0x043c0001, 0x7ff3c004, 0xcfc13084, 0x80001842, 0x043c0024, + 0xdfc30000, 0xd4413249, 0x7c43c001, 0x23fc003f, 0xcfc1326d, 0x0bb80026, 0xdf830000, 0xd441326e, + 0x7c438001, 0x7c438001, 0xc4393265, 0x1fb8ffc6, 0xddc30000, 0xcf813265, 0x9a000003, 0xcdc0000c, + 0x80001852, 0xcdc0000d, 0xce000010, 0x8c00142b, 0x90000000, 0x7c41c001, 0x7c420001, 0xcdc13252, + 0xce013253, 0x8c001628, 0x80001878, 0xc49f02e9, 0x99c00018, 0x7c41c001, 0x7c420001, 0xcdc13252, + 0xce013253, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0x043c3000, 0xcfc13267, 0xc43d3267, 0x97c0ffff, + 0xcdc00026, 0xce000026, 0xd8400027, 0xc41c0012, 0x99c0ffff, 0xc43c000e, 0x2bfc0008, 0xcfc00013, + 0x043c2000, 0xcfc13267, 0x8c001628, 0x80001878, 0xc41f02ed, 0xc42302ee, 0xcdc13252, 0xce013253, + 0x04200001, 0x7e2a0004, 0xce013084, 0x90000000, 0x28340001, 0x313c0bcc, 0x9bc00010, 0x393c051f, + 0x9bc00004, 0x3d3c050e, 0x9bc0000c, 0x97c0000c, 0x393c0560, 0x9bc00004, 0x3d3c054f, 0x9bc00007, + 0x97c00007, 0x393c1538, 0x9bc00005, 0x3d3c1537, 0x9bc00002, 0x97c00002, 0x2b740800, 0x90000000, + 0xc40c000e, 0x28cc0008, 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c40c001, 0x18e8007c, 0x7c42c001, + 0x06a8189a, 0x86800000, 0x8000189e, 0x800018c5, 0x800018f2, 0x8000016a, 0x7c414001, 0x18d0007e, + 0x50580020, 0x09200001, 0x7d59401a, 0xd1400072, 0xc8140072, 0x09240002, 0x7c418001, 0x7c41c001, + 0x99000011, 0xc4340004, 0xd8400013, 0xd8400008, 0xc42130b5, 0x1a24002c, 0x9a40fffe, 0x2020002c, + 0xc418000d, 0x1198001c, 0x10cc0004, 0x14cc0004, 0x7cd8c00a, 0xccc130b7, 0xce0130b5, 0xcf400008, + 0x80000168, 0xd1400025, 0x5978073a, 0x2bb80002, 0xcf800024, 0xcd800026, 0xcdc00026, 0xd8400027, + 0x9600e8a8, 0xc4300012, 0x9b00ffff, 0x9640e8a5, 0x800018a9, 0x04140000, 0xc55b0309, 0x3d5c0010, + 0x05540001, 0x2598ffff, 0x09780001, 0x7dad800c, 0x99c0ffd2, 0x9580fff9, 0xc4970258, 0xc4930250, + 0x51540020, 0x7d15001a, 0x04140020, 0x04280000, 0x442c0000, 0x65180001, 0x09540001, 0x55100001, + 0x9580000b, 0x8c001628, 0xc41d3248, 0x04300001, 0x7f2b0014, 0x25dc000f, 0x7df9c00c, 0x95c00004, + 0x7ef2c01a, 0xd8c13260, 0xd901325d, 0x06a80001, 0x9940fff1, 0x04140020, 0x04280000, 0x66d80001, + 0x09540001, 0x56ec0001, 0x95800005, 0x8c001628, 0xc421325d, 0x26240007, 0x9a40fffe, 0x06a80001, + 0x9940fff7, 0x8000189e, 0x04140020, 0x04280000, 0x09540001, 0x8c001628, 0xc41d3254, 0xc023007f, + 0x19e4003e, 0x7de1c009, 0x7dee000c, 0x96400008, 0x96000007, 0xd8c13260, 0xd901325d, 0xc421325d, + 0x261c0007, 0x99c0fffe, 0x8000189e, 0x06a80001, 0x9940fff0, 0x8000189e, 0xc40c000e, 0x28cc0008, + 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c40c001, 0x18e00064, 0x06281911, 0x14f4001d, 0x24cc0003, + 0x86800000, 0x80001915, 0x800019af, 0x80001a2b, 0x8000016a, 0xcc48032b, 0xcc480333, 0xcc48033b, + 0xcc480343, 0x98800011, 0xc4213246, 0xc4253245, 0x52200020, 0x7e26401a, 0x46640400, 0xc4313267, + 0x04203000, 0xce013267, 0xc4213267, 0x9a000001, 0x1b3c0057, 0x1b200213, 0x1b300199, 0x7e3e000a, + 0x7e32000a, 0xce000024, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, 0xc4b30278, + 0x52ec0020, 0x7ef2c01a, 0x04180000, 0x04140020, 0x04280000, 0x7f438001, 0x8c001628, 0xc41d3247, + 0x25dc0001, 0x95c00068, 0xc4213254, 0x1a1c003e, 0x95c00065, 0xc01f007f, 0x7e1e0009, 0x97800062, + 0x0bb80001, 0x43bc0008, 0x7fcbc001, 0xc7df032b, 0x7e1fc00c, 0x97c0fffa, 0x043c0101, 0x94c00002, + 0x043c0102, 0xc439325b, 0x1bb0003f, 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, + 0x97000009, 0xc4393260, 0x1bb000e4, 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, + 0x80001994, 0x8c001628, 0xc033ffff, 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, + 0x27b800ff, 0x9b80fffe, 0xd8c00033, 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27380003, + 0x13b80004, 0x27300003, 0x13300003, 0x7fb38001, 0x19f000e8, 0x7fb38001, 0x13300001, 0x7fb38001, + 0x07b80002, 0xd8400013, 0x19f00064, 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, + 0xcc01203f, 0xd8400013, 0xcc01203f, 0x0b300003, 0x80001982, 0x17b00005, 0xcf012082, 0xcc01203f, + 0xd8400013, 0xcc01203f, 0x13300005, 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, + 0xd8c00034, 0xcdc00013, 0xc431325d, 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffcb, + 0xcfc1325d, 0x2030007b, 0xcf01325b, 0x80001995, 0xcfc1325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, + 0x98800009, 0x41bc0007, 0x53fc0002, 0x7e7fc011, 0xd3c00025, 0xd8000026, 0xd8400027, 0xc43c0012, + 0x9bc0ffff, 0x653c0001, 0x7dbd8001, 0x06a80001, 0x09540001, 0x55100001, 0x9940ff8f, 0xc43c000e, + 0x2bfc0008, 0xcfc00013, 0x043c2000, 0xcfc13267, 0xd8080278, 0xd8080280, 0x80000168, 0x7c410001, + 0x04140000, 0xc55b0309, 0x3d5c0010, 0x2598ffff, 0x05540001, 0x7d91800c, 0x95c00003, 0xd4400078, + 0x80000168, 0x9580fff8, 0x09780001, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, + 0xc4b30278, 0x52ec0020, 0x7ef2c01a, 0x04140020, 0x04280000, 0x65180001, 0x09540001, 0x55100001, + 0x9580005d, 0x8c001628, 0xc4253247, 0x26640001, 0x04200101, 0x96400058, 0x7dc24001, 0xc41d3248, + 0x25dc000f, 0x7df9c00c, 0x95c00053, 0x94c00002, 0x04200102, 0x7e41c001, 0xc425325b, 0x1a70003f, + 0x97000049, 0x1a7000e8, 0x33240003, 0x9a400046, 0x33300002, 0x9700000a, 0xc4253260, 0x1a7000e4, + 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x80001a21, 0xcdc00013, 0xc033ffff, + 0x2f3000ff, 0xc425325b, 0x7f270009, 0xcf01325b, 0xc425325b, 0x266400ff, 0x9a40fffe, 0xd8c00033, + 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27240003, 0x12640004, 0x27300003, 0x13300003, + 0x7e724001, 0x19f000e8, 0x7e724001, 0x13300001, 0x7e724001, 0x06640002, 0xd8400013, 0x19f00064, + 0x33300002, 0x97000009, 0x16700005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x0b300003, 0x80001a0f, 0x16700005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, 0x13300005, + 0x7e730002, 0xc4252083, 0x7e724005, 0x26640001, 0x9a40ffdf, 0xd8c00034, 0xcdc00013, 0xc431325d, + 0x27300010, 0x9b00fffe, 0xc425325b, 0x267000ff, 0x9b00ffca, 0xce01325d, 0x2030007b, 0xcf01325b, + 0x80001a22, 0xce01325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0x06a80001, 0x9940ff9f, 0xd4400078, + 0xd8080278, 0xd8080280, 0x80000168, 0x8c001a31, 0xd4400078, 0xd8080278, 0xd8080280, 0x7c408001, + 0x88000000, 0xc4213246, 0xc4253245, 0x52200020, 0x7e26401a, 0x46640400, 0xc4313267, 0x04203000, + 0xce013267, 0xc4213267, 0x9a000001, 0x1b180057, 0x1b200213, 0x1b300199, 0x7e1a000a, 0x7e32000a, + 0xce000024, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, 0xc4b30278, 0x52ec0020, + 0x7ef2c01a, 0x04140020, 0x04280000, 0x65180001, 0x95800060, 0x8c001628, 0xc4193247, 0x25980001, + 0x04200101, 0x94c00005, 0x30f00005, 0x04200005, 0x9b000002, 0x04200102, 0x95800056, 0xc439325b, + 0x1bb0003f, 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, 0x9700000a, 0xc4393260, + 0x1bb000e4, 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x80001aa2, 0xcdc00013, + 0xc033ffff, 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, 0x27b800ff, 0x9b80fffe, + 0xd8c00033, 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27380003, 0x13b80004, 0x27300003, + 0x13300003, 0x7fb38001, 0x19f000e8, 0x7fb38001, 0x13300001, 0x7fb38001, 0x07b80002, 0xd8400013, + 0x19f00064, 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, + 0xcc01203f, 0x0b300003, 0x80001a90, 0x17b00005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, + 0x13300005, 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, 0xd8c00034, 0xcdc00013, + 0xc431325d, 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffca, 0xce01325d, 0x2030007b, + 0xcf00325b, 0x80001aa3, 0xce01325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0xc49b02e9, 0x99800005, + 0xd2400025, 0x4664001c, 0xd8000026, 0xd8400027, 0x06a80001, 0x09540001, 0x55100001, 0x9940ff9c, + 0xc49b02e9, 0x99800008, 0xc430000e, 0x2b300008, 0xcf000013, 0x04302000, 0xcf013267, 0xc4313267, + 0x97000001, 0x90000000, 0x244c00ff, 0xcc4c0200, 0x7c408001, 0x88000000, 0xc44f0200, 0xc410000b, + 0xc414000c, 0x7d158010, 0x059cc000, 0xd8400013, 0xccdd0000, 0x7c408001, 0x88000000, 0xc40c0037, + 0x94c0ffff, 0xcc000049, 0xc40c003a, 0x94c0ffff, 0x7c40c001, 0x24d00001, 0x9500e69a, 0x18d0003b, + 0x18d40021, 0x99400006, 0xd840004a, 0xc40c003c, 0x94c0ffff, 0x14cc0001, 0x94c00028, 0xd8000033, + 0xc438000b, 0xc43c0009, 0x27fc0001, 0x97c0fffe, 0xd8400013, 0xd841c07f, 0xc43dc07f, 0x1bfc0078, + 0x7ffbc00c, 0x97c0fffd, 0x99000004, 0xc0120840, 0x282c0040, 0x80001ae8, 0xc0121841, 0x282c001a, + 0xcd01c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04200004, 0xcec0001b, 0xd8400021, + 0x0a200001, 0x9a00ffff, 0xc425c07f, 0x166c001f, 0x04200004, 0x9ac0fffb, 0xc434000f, 0x9b40ffff, + 0xd801c07f, 0xd8400013, 0xc425c07f, 0xce400078, 0xd8000034, 0x9940e66b, 0xd800004a, 0x7c408001, + 0x88000000, 0xc40c0036, 0x24d00001, 0x9900fffe, 0x18cc0021, 0xccc00047, 0xcc000046, 0xc40c0039, + 0x94c0ffff, 0xc40c003d, 0x98c0ffff, 0x7c40c001, 0x24d003ff, 0x18d47fea, 0x18d87ff4, 0xcd00004c, + 0xcd40004e, 0xcd80004d, 0xd8400013, 0xcd41c405, 0xc02a0001, 0x2aa80001, 0xce800013, 0xcd01c406, + 0xcc01c406, 0xcc01c406, 0xc40c0006, 0x98c0ffff, 0xc414000e, 0x29540008, 0x295c0001, 0xcd400013, + 0xd8c1325e, 0xcdc0001a, 0x11980002, 0x4110000c, 0xc0160800, 0x7d15000a, 0xc0164010, 0xd8400013, + 0xcd41c078, 0xcc01c080, 0xcc01c081, 0xcd81c082, 0xcc01c083, 0xcd01c084, 0xc40c0006, 0x98c0ffff, + 0xd8400048, 0xc40c003b, 0x94c0ffff, 0x80000c16, 0xd8400013, 0xd801c40a, 0xd901c40d, 0xd801c410, + 0xd801c40e, 0xd801c40f, 0xc40c0040, 0x04140001, 0x09540001, 0x9940ffff, 0x04140096, 0xd8400013, + 0xccc1c400, 0xc411c401, 0x9500fffa, 0xc424003e, 0x04d00001, 0x11100002, 0xcd01c40c, 0xc0180034, + 0xcd81c411, 0xd841c414, 0x0a540001, 0xcd41c412, 0x2468000f, 0xc419c416, 0x41980003, 0xc41c003f, + 0x7dda0001, 0x12200002, 0x10cc0002, 0xccc1c40c, 0xd901c411, 0xce41c412, 0xd8800013, 0xce292e40, + 0xcc412e01, 0xcc412e02, 0xcc412e03, 0xcc412e00, 0x80000aa7, 0xc43c0007, 0xdc120000, 0x31144000, + 0x95400005, 0xdc030000, 0xd800002a, 0xcc3c000c, 0x80001b70, 0x33f80003, 0xd4400078, 0x9780e601, + 0x188cfff0, 0x04e40002, 0x80001190, 0x7c408001, 0x88000000, 0xc424005e, 0x96400006, 0x90000000, + 0xc424005e, 0x96400003, 0x7c408001, 0x88000000, 0x80001b74, 0x80000168, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, + 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 7440 +}; + +static const PWR_DFY_Section pwr_virus_section4 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x54106500, + .dfy_data = { + 0x7e000200, 0x7e020204, 0xc00a0505, 0x00000000, 0xbf8c007f, 0xb8900904, 0xb8911a04, 0xb8920304, + 0xb8930b44, 0x921c0d0c, 0x921c1c13, 0x921d0c12, 0x811c1d1c, 0x811c111c, 0x921cff1c, 0x00000400, + 0x921dff10, 0x00000100, 0x81181d1c, 0x7e040218, 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, + 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 240 +}; + +static const PWR_DFY_Section pwr_virus_section5 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x54106900, + .dfy_data = { + 0x7e080200, 0x7e100204, 0xbefc00ff, 0x00010000, 0x24200087, 0x262200ff, 0x000001f0, 0x20222282, + 0x28182111, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, + 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, + 0x1100000c, 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 384 +}; + +static const PWR_DFY_Section pwr_virus_section6 = { + .dfy_cntl = 0x80000004, + .dfy_addr_hi = 0x000000b4, + .dfy_addr_lo = 0x54116f00, + .dfy_data = { + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4540fe8, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000041, 0x0000000c, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54116f00, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb454105e, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x000000c0, 0x00000010, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54117300, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4541065, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000500, 0x0000001c, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54117700, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4541069, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000444, 0x0000008a, 0x00000000, 0x07808000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x54117b00, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, + 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, + 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + .dfy_size = 1024 +}; + +static const PWR_Command_Table PwrVirusTable_post[] = { { 0x00000000, mmCP_MEC_CNTL }, { 0x00000000, mmCP_MEC_CNTL }, { 0x00000004, mmSRBM_GFX_CNTL }, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 289006b8d421..592a89aff12b 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -159,27 +159,44 @@ static int fiji_start_smu_in_non_protection_mode(struct pp_hwmgr *hwmgr) return result; } -static int fiji_setup_pwr_virus(struct pp_hwmgr *hwmgr) +static void execute_pwr_table(struct pp_hwmgr *hwmgr, const PWR_Command_Table *pvirus, int size) { int i; - int result = -EINVAL; uint32_t reg, data; - const PWR_Command_Table *pvirus = PwrVirusTable; - - for (i = 0; i < ARRAY_SIZE(PwrVirusTable); i++) { + for (i = 0; i < size; i++) { reg = pvirus->reg; data = pvirus->data; if (reg != 0xffffffff) cgs_write_register(hwmgr->device, reg, data); - else { - result = 0; + else break; - } pvirus++; } +} - return result; +static void execute_pwr_dfy_table(struct pp_hwmgr *hwmgr, const PWR_DFY_Section *section) +{ + int i; + cgs_write_register(hwmgr->device, mmCP_DFY_CNTL, section->dfy_cntl); + cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_HI, section->dfy_addr_hi); + cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_LO, section->dfy_addr_lo); + for (i = 0; i < section->dfy_size; i++) + cgs_write_register(hwmgr->device, mmCP_DFY_DATA_0, section->dfy_data[i]); +} + +static int fiji_setup_pwr_virus(struct pp_hwmgr *hwmgr) +{ + execute_pwr_table(hwmgr, PwrVirusTable_pre, ARRAY_SIZE(PwrVirusTable_pre)); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section1); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section2); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section3); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section4); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section5); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section6); + execute_pwr_table(hwmgr, PwrVirusTable_post, ARRAY_SIZE(PwrVirusTable_post)); + + return 0; } static int fiji_start_avfs_btc(struct pp_hwmgr *hwmgr) -- cgit v1.2.3 From 9792bf5ad5e30b207274ccbb459a89eab6033b46 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Fri, 22 Sep 2017 22:00:29 -0700 Subject: clk: Export clk_bulk_prepare() Allow clk_bulk_prepare() to be referenced by kernel modules by adding the missing EXPORT_SYMBOL_GPL(). Fixes: 266e4e9d9150 ("clk: add clk_bulk_get accessories") Reported-by: Ulf Hansson Signed-off-by: Bjorn Andersson Reviewed-by: Ulf Hansson Signed-off-by: Stephen Boyd --- drivers/clk/clk-bulk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c index c834f5abfc49..4c10456f8a32 100644 --- a/drivers/clk/clk-bulk.c +++ b/drivers/clk/clk-bulk.c @@ -105,6 +105,7 @@ err: return ret; } +EXPORT_SYMBOL_GPL(clk_bulk_prepare); #endif /* CONFIG_HAVE_CLK_PREPARE */ -- cgit v1.2.3 From 13ffe9a26df4e156363579b25c904dd0b1e31bfb Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 13 Sep 2017 18:02:02 +0100 Subject: staging: iio: ade7759: fix signed extension bug on shift of a u8 The current shift of st->rx[2] left shifts a u8 24 bits left, promotes the integer to a an int and then to a unsigned u64. If the top bit of st->rx[2] is set then we end up with all the upper bits being set to 1. Fix this by casting st->rx[2] to a u64 before the 24 bit left shift. Detected by CoverityScan CID#144940 ("Unintended sign extension") Fixes: 2919fa54ef64 ("staging: iio: meter: new driver for ADE7759 devices") Signed-off-by: Colin Ian King Signed-off-by: Jonathan Cameron --- drivers/staging/iio/meter/ade7759.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 1691760339da..02573c517d9d 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -172,7 +172,7 @@ static int ade7759_spi_read_reg_40(struct device *dev, reg_address); goto error_ret; } - *val = ((u64)st->rx[1] << 32) | (st->rx[2] << 24) | + *val = ((u64)st->rx[1] << 32) | ((u64)st->rx[2] << 24) | (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5]; error_ret: -- cgit v1.2.3 From 5a59a3a0ef0e546626a762d49dc06feaa204bab3 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Thu, 28 Sep 2017 17:57:58 +0200 Subject: ppp: fix __percpu annotation Move sparse annotation right after pointer type. Fixes sparse warning: drivers/net/ppp/ppp_generic.c:1422:13: warning: incorrect type in initializer (different address spaces) drivers/net/ppp/ppp_generic.c:1422:13: expected void const [noderef] *__vpp_verify drivers/net/ppp/ppp_generic.c:1422:13: got int * ... Fixes: e5dadc65f9e0 ("ppp: Fix false xmit recursion detect with two ppp devices") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller --- drivers/net/ppp/ppp_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index a404552555d4..c3f77e3b7819 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -120,7 +120,7 @@ struct ppp { int n_channels; /* how many channels are attached 54 */ spinlock_t rlock; /* lock for receive side 58 */ spinlock_t wlock; /* lock for transmit side 5c */ - int *xmit_recursion __percpu; /* xmit recursion detect */ + int __percpu *xmit_recursion; /* xmit recursion detect */ int mru; /* max receive unit 60 */ unsigned int flags; /* control bits 64 */ unsigned int xstate; /* transmit state bits 68 */ -- cgit v1.2.3 From 007a61ae2f35c7fcf767313285c4924e81f11983 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Thu, 28 Sep 2017 21:33:23 +0200 Subject: nvme: fix visibility of "uuid" ns attribute "uuid" must be invisible if both ns->uuid and ns->nguid are unset, not if either one is. Fixes: d934f9848a77 "nvme: provide UUID value to userspace" Signed-off-by: Martin Wilck Signed-off-by: Christoph Hellwig --- drivers/nvme/host/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index bb2aad078637..5a14cc7f28ee 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2136,7 +2136,7 @@ static umode_t nvme_ns_attrs_are_visible(struct kobject *kobj, struct nvme_ns *ns = nvme_get_ns_from_dev(dev); if (a == &dev_attr_uuid.attr) { - if (uuid_is_null(&ns->uuid) || + if (uuid_is_null(&ns->uuid) && !memchr_inv(ns->nguid, 0, sizeof(ns->nguid))) return 0; } -- cgit v1.2.3 From be94a6f6d488b4767662e8949dc62361bd1d6311 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 29 Sep 2017 15:24:05 +0200 Subject: iio: dummy: events: Add missing break Add missing break in iio_simple_dummy_write_event_config() for the voltage threshold event enable attribute. Without this writing to the in_voltage0_thresh_rising_en always returns -EINVAL even though the change was correctly applied. Fixes: 3e34e650db197 ("iio: dummy: Demonstrate the usage of new channel types") Signed-off-by: Lars-Peter Clausen Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dummy/iio_simple_dummy_events.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iio/dummy/iio_simple_dummy_events.c b/drivers/iio/dummy/iio_simple_dummy_events.c index ed63ffd849f8..7ec2a0bb0807 100644 --- a/drivers/iio/dummy/iio_simple_dummy_events.c +++ b/drivers/iio/dummy/iio_simple_dummy_events.c @@ -72,6 +72,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev, st->event_en = state; else return -EINVAL; + break; default: return -EINVAL; } -- cgit v1.2.3 From 74007ae6316ebe40260e44f8ab558f9b1ccc04e5 Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Sat, 23 Sep 2017 08:44:15 +0200 Subject: hwmon: (xgene) Fix up error handling path mixup in 'xgene_hwmon_probe()' Commit 2ca492e22cb7 has moved the call to 'kfifo_alloc()' from after the main 'if' statement to before it. But it has not updated the error handling paths accordingly. Fix all that: - if 'kfifo_alloc()' fails we can return directly - direct returns after 'kfifo_alloc()' must now go to 'out_mbox_free' - 'goto out_mbox_free' must be replaced by 'goto out', otherwise the '[pcc_]mbox_free_channel()' call will be missed. Fixes: 2ca492e22cb7 ("hwmon: (xgene) Fix crash when alarm occurs before driver probe") Signed-off-by: Christophe JAILLET Signed-off-by: Guenter Roeck --- drivers/hwmon/xgene-hwmon.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/xgene-hwmon.c b/drivers/hwmon/xgene-hwmon.c index 9c0dbb8191ad..e1be61095532 100644 --- a/drivers/hwmon/xgene-hwmon.c +++ b/drivers/hwmon/xgene-hwmon.c @@ -630,7 +630,7 @@ static int xgene_hwmon_probe(struct platform_device *pdev) sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE, GFP_KERNEL); if (rc) - goto out_mbox_free; + return -ENOMEM; INIT_WORK(&ctx->workq, xgene_hwmon_evt_work); @@ -646,7 +646,8 @@ static int xgene_hwmon_probe(struct platform_device *pdev) if (IS_ERR(ctx->mbox_chan)) { dev_err(&pdev->dev, "SLIMpro mailbox channel request failed\n"); - return -ENODEV; + rc = -ENODEV; + goto out_mbox_free; } } else { struct acpi_pcct_hw_reduced *cppc_ss; @@ -654,7 +655,8 @@ static int xgene_hwmon_probe(struct platform_device *pdev) if (device_property_read_u32(&pdev->dev, "pcc-channel", &ctx->mbox_idx)) { dev_err(&pdev->dev, "no pcc-channel property\n"); - return -ENODEV; + rc = -ENODEV; + goto out_mbox_free; } cl->rx_callback = xgene_hwmon_pcc_rx_cb; @@ -662,7 +664,8 @@ static int xgene_hwmon_probe(struct platform_device *pdev) if (IS_ERR(ctx->mbox_chan)) { dev_err(&pdev->dev, "PPC channel request failed\n"); - return -ENODEV; + rc = -ENODEV; + goto out_mbox_free; } /* @@ -675,13 +678,13 @@ static int xgene_hwmon_probe(struct platform_device *pdev) if (!cppc_ss) { dev_err(&pdev->dev, "PPC subspace not found\n"); rc = -ENODEV; - goto out_mbox_free; + goto out; } if (!ctx->mbox_chan->mbox->txdone_irq) { dev_err(&pdev->dev, "PCC IRQ not supported\n"); rc = -ENODEV; - goto out_mbox_free; + goto out; } /* @@ -696,14 +699,14 @@ static int xgene_hwmon_probe(struct platform_device *pdev) } else { dev_err(&pdev->dev, "Failed to get PCC comm region\n"); rc = -ENODEV; - goto out_mbox_free; + goto out; } if (!ctx->pcc_comm_addr) { dev_err(&pdev->dev, "Failed to ioremap PCC comm region\n"); rc = -ENOMEM; - goto out_mbox_free; + goto out; } /* -- cgit v1.2.3 From e5f23736a88c1d8d727ac655fef5e752507eea8e Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 29 Sep 2017 13:57:54 +0800 Subject: drm/amd/powerplay: refine code in amd_powerplay.c (v2) 1. use flag PP_DPM_DISABLED within powerplay notify amdgpu dpm state by cgs interface. 2. delete redundant virtualization check in powerplay v2: squash in fix for hwmgr_init (Rex) Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 12 ----- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 59 ++++++++++------------- drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 2 - 3 files changed, 25 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 1649b1e3f23d..3b42f407971d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -98,10 +98,6 @@ static int amdgpu_pp_early_init(void *handle) amd_pp->cgs_device ? amd_pp->cgs_device : amd_pp->pp_handle); - if (ret == PP_DPM_DISABLED) { - adev->pm.dpm_enabled = false; - return 0; - } return ret; } @@ -154,14 +150,6 @@ static int amdgpu_pp_hw_init(void *handle) ret = adev->powerplay.ip_funcs->hw_init( adev->powerplay.pp_handle); - if (ret == PP_DPM_DISABLED) { - adev->pm.dpm_enabled = false; - return 0; - } - - if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev)) - adev->pm.dpm_enabled = true; - return ret; } diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 488347a11f01..38ae400c3a35 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -30,6 +30,8 @@ #include "pp_instance.h" #include "power_state.h" +#define PP_DPM_DISABLED 0xCCCC + static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, void *input, void *output); @@ -99,10 +101,6 @@ static int pp_early_init(void *handle) if (ret) return -EINVAL; - if ((pp_handle->pm_en == 0) - || cgs_is_virtualization_enabled(pp_handle->device)) - return PP_DPM_DISABLED; - return 0; } @@ -114,7 +112,7 @@ static int pp_sw_init(void *handle) ret = pp_check(pp_handle); - if (ret == 0 || ret == PP_DPM_DISABLED) { + if (ret >= 0) { hwmgr = pp_handle->hwmgr; if (hwmgr->smumgr_funcs->smu_init == NULL) @@ -134,7 +132,7 @@ static int pp_sw_fini(void *handle) struct pp_instance *pp_handle = (struct pp_instance *)handle; ret = pp_check(pp_handle); - if (ret == 0 || ret == PP_DPM_DISABLED) { + if (ret >= 0) { hwmgr = pp_handle->hwmgr; if (hwmgr->smumgr_funcs->smu_fini == NULL) @@ -153,7 +151,7 @@ static int pp_hw_init(void *handle) ret = pp_check(pp_handle); - if (ret == 0 || ret == PP_DPM_DISABLED) { + if (ret >= 0) { hwmgr = pp_handle->hwmgr; if (hwmgr->smumgr_funcs->start_smu == NULL) @@ -165,16 +163,17 @@ static int pp_hw_init(void *handle) return -EINVAL;; } if (ret == PP_DPM_DISABLED) - return PP_DPM_DISABLED; + goto exit; + ret = hwmgr_hw_init(pp_handle); + if (ret) + goto exit; } - - ret = hwmgr_hw_init(pp_handle); - if (ret) - goto err; - return 0; -err: + return ret; +exit: pp_handle->pm_en = 0; - return PP_DPM_DISABLED; + cgs_notify_dpm_enabled(hwmgr->device, false); + return 0; + } static int pp_hw_fini(void *handle) @@ -275,39 +274,34 @@ static int pp_suspend(void *handle) int ret = 0; ret = pp_check(pp_handle); - - if (ret == PP_DPM_DISABLED) - return 0; - else if (ret != 0) - return ret; - - return hwmgr_hw_suspend(pp_handle); + if (ret == 0) + hwmgr_hw_suspend(pp_handle); + return 0; } static int pp_resume(void *handle) { struct pp_hwmgr *hwmgr; - int ret, ret1; + int ret; struct pp_instance *pp_handle = (struct pp_instance *)handle; - ret1 = pp_check(pp_handle); + ret = pp_check(pp_handle); - if (ret1 != 0 && ret1 != PP_DPM_DISABLED) - return ret1; + if (ret < 0) + return ret; hwmgr = pp_handle->hwmgr; if (hwmgr->smumgr_funcs->start_smu == NULL) return -EINVAL; - ret = hwmgr->smumgr_funcs->start_smu(pp_handle->hwmgr); - if (ret) { + if (hwmgr->smumgr_funcs->start_smu(pp_handle->hwmgr)) { pr_err("smc start failed\n"); hwmgr->smumgr_funcs->smu_fini(pp_handle->hwmgr); - return ret; + return -EINVAL; } - if (ret1 == PP_DPM_DISABLED) + if (ret == PP_DPM_DISABLED) return 0; return hwmgr_hw_resume(pp_handle); @@ -1190,9 +1184,6 @@ int amd_powerplay_reset(void *handle) struct pp_instance *instance = (struct pp_instance *)handle; int ret; - if (cgs_is_virtualization_enabled(instance->hwmgr->device)) - return PP_DPM_DISABLED; - ret = pp_check(instance); if (ret != 0) return ret; @@ -1203,7 +1194,7 @@ int amd_powerplay_reset(void *handle) ret = hwmgr_hw_init(instance); if (ret) - return PP_DPM_DISABLED; + return ret; return hwmgr_handle_task(instance, AMD_PP_TASK_COMPLETE_INIT, NULL, NULL); } diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 916b6c420ea4..e52adc873413 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -33,8 +33,6 @@ extern const struct amd_ip_funcs pp_ip_funcs; extern const struct amd_pm_funcs pp_dpm_funcs; -#define PP_DPM_DISABLED 0xCCCC - enum amd_pp_sensors { AMDGPU_PP_SENSOR_GFX_SCLK = 0, AMDGPU_PP_SENSOR_VDDNB, -- cgit v1.2.3 From 90841047a01b452cc8c3f9b990698b264143334a Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Thu, 28 Sep 2017 11:35:00 -0700 Subject: r8152: add Linksys USB3GIGV1 id This linksys dongle by default comes up in cdc_ether mode. This patch allows r8152 to claim the device: Bus 002 Device 002: ID 13b1:0041 Linksys Signed-off-by: Grant Grundler Reviewed-by: Douglas Anderson Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 10 ++++++++++ drivers/net/usb/r8152.c | 2 ++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 8ab281b478f2..677a85360db1 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -547,6 +547,7 @@ static const struct driver_info wwan_info = { #define REALTEK_VENDOR_ID 0x0bda #define SAMSUNG_VENDOR_ID 0x04e8 #define LENOVO_VENDOR_ID 0x17ef +#define LINKSYS_VENDOR_ID 0x13b1 #define NVIDIA_VENDOR_ID 0x0955 #define HP_VENDOR_ID 0x03f0 #define MICROSOFT_VENDOR_ID 0x045e @@ -737,6 +738,15 @@ static const struct usb_device_id products[] = { .driver_info = 0, }, +#if IS_ENABLED(CONFIG_USB_RTL8152) +/* Linksys USB3GIGV1 Ethernet Adapter */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, +#endif + /* ThinkPad USB-C Dock (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM, diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ceb78e2ea4f0..941ece08ba78 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -613,6 +613,7 @@ enum rtl8152_flags { #define VENDOR_ID_MICROSOFT 0x045e #define VENDOR_ID_SAMSUNG 0x04e8 #define VENDOR_ID_LENOVO 0x17ef +#define VENDOR_ID_LINKSYS 0x13b1 #define VENDOR_ID_NVIDIA 0x0955 #define MCU_TYPE_PLA 0x0100 @@ -5316,6 +5317,7 @@ static const struct usb_device_id rtl8152_table[] = { {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, {} }; -- cgit v1.2.3 From 4792ea04bcd03b8ccfd1ae336c5deba52dd9edc9 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 29 Sep 2017 14:27:39 +0200 Subject: net: mvpp2: Fix clock resource by adding an optional bus clock On Armada 7K/8K we need to explicitly enable the bus clock. The bus clock is optional because not all the SoCs need them but at least for Armada 7K/8K it is actually mandatory. The binding documentation is updating accordingly. Signed-off-by: Gregory CLEMENT Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/marvell-pp2.txt | 10 ++++++---- drivers/net/ethernet/marvell/mvpp2.c | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/net/marvell-pp2.txt b/Documentation/devicetree/bindings/net/marvell-pp2.txt index 7e2dad08a12e..1814fa13f6ab 100644 --- a/Documentation/devicetree/bindings/net/marvell-pp2.txt +++ b/Documentation/devicetree/bindings/net/marvell-pp2.txt @@ -21,8 +21,9 @@ Required properties: - main controller clock (for both armada-375-pp2 and armada-7k-pp2) - GOP clock (for both armada-375-pp2 and armada-7k-pp2) - MG clock (only for armada-7k-pp2) -- clock-names: names of used clocks, must be "pp_clk", "gop_clk" and - "mg_clk" (the latter only for armada-7k-pp2). + - AXI clock (only for armada-7k-pp2) +- clock-names: names of used clocks, must be "pp_clk", "gop_clk", "mg_clk" + and "axi_clk" (the 2 latter only for armada-7k-pp2). The ethernet ports are represented by subnodes. At least one port is required. @@ -78,8 +79,9 @@ Example for marvell,armada-7k-pp2: cpm_ethernet: ethernet@0 { compatible = "marvell,armada-7k-pp22"; reg = <0x0 0x100000>, <0x129000 0xb000>; - clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, <&cpm_syscon0 1 5>; - clock-names = "pp_clk", "gop_clk", "gp_clk"; + clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, + <&cpm_syscon0 1 5>, <&cpm_syscon0 1 18>; + clock-names = "pp_clk", "gop_clk", "gp_clk", "axi_clk"; eth0: eth0 { interrupts = , diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 161055564720..9c86cb7cb988 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -793,6 +793,7 @@ struct mvpp2 { struct clk *pp_clk; struct clk *gop_clk; struct clk *mg_clk; + struct clk *axi_clk; /* List of pointers to port structures */ struct mvpp2_port **port_list; @@ -7970,6 +7971,18 @@ static int mvpp2_probe(struct platform_device *pdev) err = clk_prepare_enable(priv->mg_clk); if (err < 0) goto err_gop_clk; + + priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk"); + if (IS_ERR(priv->axi_clk)) { + err = PTR_ERR(priv->axi_clk); + if (err == -EPROBE_DEFER) + goto err_gop_clk; + priv->axi_clk = NULL; + } else { + err = clk_prepare_enable(priv->axi_clk); + if (err < 0) + goto err_gop_clk; + } } /* Get system's tclk rate */ @@ -8024,6 +8037,7 @@ static int mvpp2_probe(struct platform_device *pdev) return 0; err_mg_clk: + clk_disable_unprepare(priv->axi_clk); if (priv->hw_version == MVPP22) clk_disable_unprepare(priv->mg_clk); err_gop_clk: @@ -8061,6 +8075,7 @@ static int mvpp2_remove(struct platform_device *pdev) aggr_txq->descs_dma); } + clk_disable_unprepare(priv->axi_clk); clk_disable_unprepare(priv->mg_clk); clk_disable_unprepare(priv->pp_clk); clk_disable_unprepare(priv->gop_clk); -- cgit v1.2.3 From 81359617f1b783a01e6e22b46cbb046e9513b9c6 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 30 Sep 2017 07:34:34 +0200 Subject: net: hns3: Fix an error handling path in 'hclge_rss_init_hw()' If this sanity check fails, we must free 'rss_indir'. Otherwise there is a memory leak. 'goto err' as done in the other error handling paths to fix it. Fixes: 46a3df9f9718 ("net: hns3: Fix for setting rss_size incorrectly") Signed-off-by: Christophe JAILLET Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index e0685e630afe..c1cdbfd83bdb 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -2652,7 +2652,8 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev) dev_err(&hdev->pdev->dev, "Configure rss tc size failed, invalid TC_SIZE = %d\n", rss_size); - return -EINVAL; + ret = -EINVAL; + goto err; } roundup_size = roundup_pow_of_two(rss_size); -- cgit v1.2.3 From fb458864d9a78cc433fec7979acbe4078c82d7a8 Mon Sep 17 00:00:00 2001 From: Chanho Min Date: Tue, 26 Sep 2017 09:03:40 +0900 Subject: mmc: core: add driver strength selection when selecting hs400es The driver strength selection is missed and required when selecting hs400es. So, It is added here. Fixes: 81ac2af65793ecf ("mmc: core: implement enhanced strobe support") Cc: stable@vger.kernel.org Signed-off-by: Hankyung Yu Signed-off-by: Chanho Min Reviewed-by: Adrian Hunter Reviewed-by: Shawn Lin Signed-off-by: Ulf Hansson --- drivers/mmc/core/mmc.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a7eb623f8daa..36217ad5e9b1 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1286,6 +1286,23 @@ out_err: return err; } +static void mmc_select_driver_type(struct mmc_card *card) +{ + int card_drv_type, drive_strength, drv_type; + + card_drv_type = card->ext_csd.raw_driver_strength | + mmc_driver_type_mask(0); + + drive_strength = mmc_select_drive_strength(card, + card->ext_csd.hs200_max_dtr, + card_drv_type, &drv_type); + + card->drive_strength = drive_strength; + + if (drv_type) + mmc_set_driver_type(card->host, drv_type); +} + static int mmc_select_hs400es(struct mmc_card *card) { struct mmc_host *host = card->host; @@ -1341,6 +1358,8 @@ static int mmc_select_hs400es(struct mmc_card *card) goto out_err; } + mmc_select_driver_type(card); + /* Switch card to HS400 */ val = EXT_CSD_TIMING_HS400 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; @@ -1374,23 +1393,6 @@ out_err: return err; } -static void mmc_select_driver_type(struct mmc_card *card) -{ - int card_drv_type, drive_strength, drv_type; - - card_drv_type = card->ext_csd.raw_driver_strength | - mmc_driver_type_mask(0); - - drive_strength = mmc_select_drive_strength(card, - card->ext_csd.hs200_max_dtr, - card_drv_type, &drv_type); - - card->drive_strength = drive_strength; - - if (drv_type) - mmc_set_driver_type(card->host, drv_type); -} - /* * For device supporting HS200 mode, the following sequence * should be done before executing the tuning process. -- cgit v1.2.3 From dd9f31c7a3887950cbd0d49eb9d43f7a1518a356 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 16 Aug 2017 17:46:07 +0300 Subject: drm/i915/gen9+: Set same power state before hibernation image save/restore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atm, on GEN9 big core platforms before saving the hibernation image we uninitialize the display, disabling power wells manually, while before restoring the image we keep things powered (letting HW/DMC power down things as needed). The state mismatch will trigger the following error: DC state mismatch (0x0 -> 0x2) While the restore handler knows how to initialize the display from an unknown state (due to a different loader kernel or not having i915 loaded in the loader kernel) we should still use the same state for consistency before image saving and restoring. Do this by uniniting the display before restoring the image too. Bugzilla: https://bugs.freedesktop.org/attachment.cgi?id=133376 Reported-and-tested-by: Wang Wendy Reported-and-tested-by: Joonas Lahtinen Cc: Wang Wendy Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Ville Syrjala Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170816144607.9935-1-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 59ac9199b35d..5cc24344c266 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1580,7 +1580,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) intel_display_set_init_power(dev_priv, false); - fw_csr = !IS_GEN9_LP(dev_priv) && + fw_csr = !IS_GEN9_LP(dev_priv) && !hibernation && suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload; /* * In case of firmware assisted context save/restore don't manually @@ -2070,11 +2070,14 @@ static int i915_pm_resume(struct device *kdev) /* freeze: before creating the hibernation_image */ static int i915_pm_freeze(struct device *kdev) { + struct drm_device *dev = &kdev_to_i915(kdev)->drm; int ret; - ret = i915_pm_suspend(kdev); - if (ret) - return ret; + if (dev->switch_power_state != DRM_SWITCH_POWER_OFF) { + ret = i915_drm_suspend(dev); + if (ret) + return ret; + } ret = i915_gem_freeze(kdev_to_i915(kdev)); if (ret) @@ -2085,11 +2088,14 @@ static int i915_pm_freeze(struct device *kdev) static int i915_pm_freeze_late(struct device *kdev) { + struct drm_device *dev = &kdev_to_i915(kdev)->drm; int ret; - ret = i915_pm_suspend_late(kdev); - if (ret) - return ret; + if (dev->switch_power_state != DRM_SWITCH_POWER_OFF) { + ret = i915_drm_suspend_late(dev, true); + if (ret) + return ret; + } ret = i915_gem_freeze_late(kdev_to_i915(kdev)); if (ret) -- cgit v1.2.3 From 9dfe2e3ad375a9ba32a13888873ec4586be01ff7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 28 Sep 2017 13:06:24 +0300 Subject: drm/i915/gen8+: Init/reset display interrupts only if i915 IRQs are enabled Only init / reset the display interrupts during power well enabling / disabling if the i915 interrupts are enabled. So far we did the init / reset during driver loading / resuming too, where initialization / enabling of the i915 interrupts happens only at a later point. This didn't cause a problem due to GEN8_MASTER_IRQ_CONTROL being cleared, but triggered gen3_assert_iir_is_zero() in GEN8_IRQ_INIT_NDX(). References: https://bugs.freedesktop.org/show_bug.cgi?id=102988 Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20170928100624.15533-1-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index efd7827ff181..e5997e818673 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3163,10 +3163,17 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); + + if (!intel_irqs_enabled(dev_priv)) { + spin_unlock_irq(&dev_priv->irq_lock); + return; + } + for_each_pipe_masked(dev_priv, pipe, pipe_mask) GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, dev_priv->de_irq_mask[pipe], ~dev_priv->de_irq_mask[pipe] | extra_ier); + spin_unlock_irq(&dev_priv->irq_lock); } @@ -3176,8 +3183,15 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); + + if (!intel_irqs_enabled(dev_priv)) { + spin_unlock_irq(&dev_priv->irq_lock); + return; + } + for_each_pipe_masked(dev_priv, pipe, pipe_mask) GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); + spin_unlock_irq(&dev_priv->irq_lock); /* make sure we're done processing display irqs */ -- cgit v1.2.3 From 2a5e597c6bb1b873e473e5f57147e9e5d2755430 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 18 Sep 2017 09:27:42 -0700 Subject: HID: wacom: Always increment hdev refcount within wacom_get_hdev_data The wacom_get_hdev_data function is used to find and return a reference to the "other half" of a Wacom device (i.e., the touch device associated with a pen, or vice-versa). To ensure these references are properly accounted for, the function is supposed to automatically increment the refcount before returning. This was not done, however, for devices which have pen & touch on different interfaces of the same USB device. This can lead to a WARNING ("refcount_t: underflow; use-after-free") when removing the module or device as we call kref_put() more times than kref_get(). Triggering an "actual" use- after-free would be difficult since both devices will disappear nearly- simultaneously. To silence this warning and prevent the potential error, we need to increment the refcount for all cases within wacom_get_hdev_data. Fixes: 41372d5d40 ("HID: wacom: Augment 'oVid' and 'oPid' with heuristics for HID_GENERIC") Cc: # v4.9+ Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 735bfbbcaa82..906e654fb0ba 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -668,8 +668,10 @@ static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev) /* Try to find an already-probed interface from the same device */ list_for_each_entry(data, &wacom_udev_list, list) { - if (compare_device_paths(hdev, data->dev, '/')) + if (compare_device_paths(hdev, data->dev, '/')) { + kref_get(&data->kref); return data; + } } /* Fallback to finding devices that appear to be "siblings" */ -- cgit v1.2.3 From 814b6d17487fd970f293ee674c90ba267f82415d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 19 Sep 2017 18:37:46 -0700 Subject: HID: hidraw: fix power sequence when closing device We should not try to bring HID device out of full power state before calling hid_hw_close(), so that transport driver operates on powered up device (making this inverse of the opening sequence). Signed-off-by: Dmitry Torokhov Reviewed-by: Guenter Roeck Reviewed-by: Benson Leung Signed-off-by: Jiri Kosina --- drivers/hid/hidraw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index ec530454e6f6..5fbe0f81ab2e 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -337,8 +337,8 @@ static void drop_ref(struct hidraw *hidraw, int exists_bit) kfree(hidraw); } else { /* close device for last reader */ - hid_hw_power(hidraw->hid, PM_HINT_NORMAL); hid_hw_close(hidraw->hid); + hid_hw_power(hidraw->hid, PM_HINT_NORMAL); } } } -- cgit v1.2.3 From 66dcdafe8e251a3edc5d84cf725835567bd3dd35 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Mon, 2 Oct 2017 15:50:34 +0800 Subject: Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A" This reverts commit fcaa4a07d2a4b541e91da7a55d8b3331f96d1865. As noted by Masaki [1], 0x120A + trackpoint will not be used in mass production machines, so remove the ID accordingly. [1] http://www.spinics.net/lists/linux-input/msg53222.html Signed-off-by: Kai-Heng Feng Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 - drivers/hid/hid-multitouch.c | 4 ---- 2 files changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 832897d4a849..a98919199858 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -75,7 +75,6 @@ #define USB_VENDOR_ID_ALPS_JP 0x044E #define HID_DEVICE_ID_ALPS_U1_DUAL 0x120B -#define HID_DEVICE_ID_ALPS_U1_PTP_2 0x120A #define HID_DEVICE_ID_ALPS_U1_DUAL_PTP 0x121F #define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP 0x1220 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index c78625dceced..9e8c4d2ba11d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1419,10 +1419,6 @@ static const struct hid_device_id mt_devices[] = { HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, - { .driver_data = MT_CLS_WIN_8_DUAL, - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_ALPS_JP, - HID_DEVICE_ID_ALPS_U1_PTP_2) }, /* Lenovo X1 TAB Gen 2 */ { .driver_data = MT_CLS_WIN_8_DUAL, -- cgit v1.2.3 From b8b8b16352cd90c6083033fd4487f04fae935c18 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 20 Sep 2017 16:15:05 -0500 Subject: rtlwifi: rtl8821ae: Fix connection lost problem In commit 40b368af4b75 ("rtlwifi: Fix alignment issues"), the read of REG_DBI_READ was changed from 16 to 8 bits. For unknown reasonsi this change results in reduced stability for the wireless connection. This regression was located using bisection. Fixes: 40b368af4b75 ("rtlwifi: Fix alignment issues") Reported-and-tested-by: James Cameron Signed-off-by: Larry Finger Cc: Stable # 4.11+ Cc: Ping-Ke Shih Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 4f73012978e9..1d431d4bf6d2 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -1122,7 +1122,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr) } if (0 == tmp) { read_addr = REG_DBI_RDATA + addr % 4; - ret = rtl_read_byte(rtlpriv, read_addr); + ret = rtl_read_word(rtlpriv, read_addr); } return ret; } -- cgit v1.2.3 From dd2349121bb1b8ff688c3ca6a2a0bea9d8c142ca Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 16 Sep 2017 21:08:24 -0700 Subject: brcmfmac: Add check for short event packets The length of the data in the received skb is currently passed into brcmf_fweh_process_event() as packet_len, but this value is not checked. event_packet should be followed by DATALEN bytes of additional event data. Ensure that the received packet actually contains at least DATALEN bytes of additional data, to avoid copying uninitialized memory into event->data. Cc: # v3.8 Suggested-by: Mattias Nissler Signed-off-by: Kevin Cernekee Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c index 4eb1e1ce9ace..ef72baf6dd96 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c @@ -429,7 +429,8 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, if (code != BRCMF_E_IF && !fweh->evt_handler[code]) return; - if (datalen > BRCMF_DCMD_MAXLEN) + if (datalen > BRCMF_DCMD_MAXLEN || + datalen + sizeof(*event_packet) > packet_len) return; if (in_interrupt()) -- cgit v1.2.3 From c503dd38f850be28867ef7a42d9abe5ade81a9bd Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 22 Sep 2017 23:29:12 +0200 Subject: brcmsmac: make some local variables 'static const' to reduce stack size With KASAN and a couple of other patches applied, this driver is one of the few remaining ones that actually use more than 2048 bytes of kernel stack: broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy_gainctrl': broadcom/brcm80211/brcmsmac/phy/phy_n.c:16065:1: warning: the frame size of 3264 bytes is larger than 2048 bytes [-Wframe-larger-than=] broadcom/brcm80211/brcmsmac/phy/phy_n.c: In function 'wlc_phy_workarounds_nphy': broadcom/brcm80211/brcmsmac/phy/phy_n.c:17138:1: warning: the frame size of 2864 bytes is larger than 2048 bytes [-Wframe-larger-than=] Here, I'm reducing the stack size by marking as many local variables as 'static const' as I can without changing the actual code. This is the first of three patches to improve the stack usage in this driver. It would be good to have this backported to stabl kernels to get all drivers in 'allmodconfig' below the 2048 byte limit so we can turn on the frame warning again globally, but I realize that the patch is larger than the normal limit for stable backports. The other two patches do not need to be backported. Cc: Acked-by: Arend van Spriel Signed-off-by: Arnd Bergmann Signed-off-by: Kalle Valo --- .../broadcom/brcm80211/brcmsmac/phy/phy_n.c | 197 ++++++++++----------- 1 file changed, 97 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c index b3aab2fe96eb..ef685465f80a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -14764,8 +14764,8 @@ static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi) } static void -wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys, - u8 len) +wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events, + const u8 *dlys, u8 len) { u32 t1_offset, t2_offset; u8 ctr; @@ -15240,16 +15240,16 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi) static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) { u16 currband; - s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; - s8 *lna1_gain_db = NULL; - s8 *lna1_gain_db_2 = NULL; - s8 *lna2_gain_db = NULL; - s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; - s8 *tia_gain_db; - s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; - s8 *tia_gainbits; - u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; - u16 *rfseq_init_gain; + static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; + const s8 *lna1_gain_db = NULL; + const s8 *lna1_gain_db_2 = NULL; + const s8 *lna2_gain_db = NULL; + static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; + const s8 *tia_gain_db; + static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; + const s8 *tia_gainbits; + static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; + const u16 *rfseq_init_gain; u16 init_gaincode; u16 clip1hi_gaincode; u16 clip1md_gaincode = 0; @@ -15310,10 +15310,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) if ((freq <= 5080) || (freq == 5825)) { - s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; - s8 lna1A_gain_db_2_rev7[] = { - 11, 17, 22, 25}; - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; + static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25}; + static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; crsminu_th = 0x3e; lna1_gain_db = lna1A_gain_db_rev7; @@ -15321,10 +15320,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) lna2_gain_db = lna2A_gain_db_rev7; } else if ((freq >= 5500) && (freq <= 5700)) { - s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; - s8 lna1A_gain_db_2_rev7[] = { - 12, 18, 22, 26}; - s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; + static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; + static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; + static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; crsminu_th = 0x45; clip1md_gaincode_B = 0x14; @@ -15335,10 +15333,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) lna2_gain_db = lna2A_gain_db_rev7; } else { - s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; - s8 lna1A_gain_db_2_rev7[] = { - 12, 18, 22, 26}; - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; + static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; + static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; crsminu_th = 0x41; lna1_gain_db = lna1A_gain_db_rev7; @@ -15450,65 +15447,65 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) NPHY_RFSEQ_CMD_CLR_HIQ_DIS, NPHY_RFSEQ_CMD_SET_HPF_BW }; - u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; - s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; - s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; - s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; - s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; - s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; - s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; - s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; - s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; - s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; - s8 *lna1_gain_db = NULL; - s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; - s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; - s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; - s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; - s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; - s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; - s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; - s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; - s8 *lna2_gain_db = NULL; - s8 tiaG_gain_db[] = { + static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; + static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; + static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; + static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; + static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; + static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; + static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; + static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; + static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; + static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; + const s8 *lna1_gain_db = NULL; + static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; + static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; + static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; + static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; + static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; + static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; + static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; + static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; + const s8 *lna2_gain_db = NULL; + static const s8 tiaG_gain_db[] = { 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; - s8 tiaA_gain_db[] = { + static const s8 tiaA_gain_db[] = { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; - s8 tiaA_gain_db_rev4[] = { + static const s8 tiaA_gain_db_rev4[] = { 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 tiaA_gain_db_rev5[] = { + static const s8 tiaA_gain_db_rev5[] = { 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 tiaA_gain_db_rev6[] = { + static const s8 tiaA_gain_db_rev6[] = { 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 *tia_gain_db; - s8 tiaG_gainbits[] = { + const s8 *tia_gain_db; + static const s8 tiaG_gainbits[] = { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; - s8 tiaA_gainbits[] = { + static const s8 tiaA_gainbits[] = { 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; - s8 tiaA_gainbits_rev4[] = { + static const s8 tiaA_gainbits_rev4[] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 tiaA_gainbits_rev5[] = { + static const s8 tiaA_gainbits_rev5[] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 tiaA_gainbits_rev6[] = { + static const s8 tiaA_gainbits_rev6[] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 *tia_gainbits; - s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; - s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; - u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; - u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; - u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; - u16 rfseqG_init_gain_rev5_elna[] = { + const s8 *tia_gainbits; + static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; + static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; + static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; + static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; + static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; + static const u16 rfseqG_init_gain_rev5_elna[] = { 0x013f, 0x013f, 0x013f, 0x013f }; - u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; - u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; - u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; - u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; - u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; - u16 rfseqA_init_gain_rev4_elna[] = { + static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; + static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; + static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; + static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; + static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; + static const u16 rfseqA_init_gain_rev4_elna[] = { 0x314f, 0x314f, 0x314f, 0x314f }; - u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; - u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; - u16 *rfseq_init_gain; + static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; + static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; + const u16 *rfseq_init_gain; u16 initG_gaincode = 0x627e; u16 initG_gaincode_rev4 = 0x527e; u16 initG_gaincode_rev5 = 0x427e; @@ -15538,10 +15535,10 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) u16 clip1mdA_gaincode_rev6 = 0x2084; u16 clip1md_gaincode = 0; u16 clip1loG_gaincode = 0x0074; - u16 clip1loG_gaincode_rev5[] = { + static const u16 clip1loG_gaincode_rev5[] = { 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c }; - u16 clip1loG_gaincode_rev6[] = { + static const u16 clip1loG_gaincode_rev6[] = { 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e }; u16 clip1loG_gaincode_rev6_224B0 = 0x1074; @@ -16066,7 +16063,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) { - u8 rfseq_rx2tx_events[] = { + static const u8 rfseq_rx2tx_events[] = { NPHY_RFSEQ_CMD_NOP, NPHY_RFSEQ_CMD_RXG_FBW, NPHY_RFSEQ_CMD_TR_SWITCH, @@ -16076,7 +16073,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) NPHY_RFSEQ_CMD_EXT_PA }; u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 }; - u8 rfseq_tx2rx_events[] = { + static const u8 rfseq_tx2rx_events[] = { NPHY_RFSEQ_CMD_NOP, NPHY_RFSEQ_CMD_EXT_PA, NPHY_RFSEQ_CMD_TX_GAIN, @@ -16085,8 +16082,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) NPHY_RFSEQ_CMD_RXG_FBW, NPHY_RFSEQ_CMD_CLR_HIQ_DIS }; - u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; - u8 rfseq_tx2rx_events_rev3[] = { + static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; + static const u8 rfseq_tx2rx_events_rev3[] = { NPHY_REV3_RFSEQ_CMD_EXT_PA, NPHY_REV3_RFSEQ_CMD_INT_PA_PU, NPHY_REV3_RFSEQ_CMD_TX_GAIN, @@ -16096,7 +16093,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, NPHY_REV3_RFSEQ_CMD_END }; - u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; + static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; u8 rfseq_rx2tx_events_rev3[] = { NPHY_REV3_RFSEQ_CMD_NOP, NPHY_REV3_RFSEQ_CMD_RXG_FBW, @@ -16110,7 +16107,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) }; u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; - u8 rfseq_rx2tx_events_rev3_ipa[] = { + static const u8 rfseq_rx2tx_events_rev3_ipa[] = { NPHY_REV3_RFSEQ_CMD_NOP, NPHY_REV3_RFSEQ_CMD_RXG_FBW, NPHY_REV3_RFSEQ_CMD_TR_SWITCH, @@ -16121,15 +16118,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) NPHY_REV3_RFSEQ_CMD_INT_PA_PU, NPHY_REV3_RFSEQ_CMD_END }; - u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; - u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; + static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; + static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; s16 alpha0, alpha1, alpha2; s16 beta0, beta1, beta2; u32 leg_data_weights, ht_data_weights, nss1_data_weights, stbc_data_weights; u8 chan_freq_range = 0; - u16 dac_control = 0x0002; + static const u16 dac_control = 0x0002; u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 }; u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 }; u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 }; @@ -16139,8 +16136,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 }; u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 }; u16 *aux_adc_gain; - u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; - u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; + static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; + static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; s32 min_nvar_val = 0x18d; s32 min_nvar_offset_6mbps = 20; u8 pdetrange; @@ -16151,9 +16148,9 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77; u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77; u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77; - u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; - u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; - u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; + static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; + static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; + static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; u16 ipalvlshift_3p3_war_en = 0; u16 rccal_bcap_val, rccal_scap_val; u16 rccal_tx20_11b_bcap = 0; @@ -24291,13 +24288,13 @@ static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core) u16 bbmult; u16 tblentry; - struct nphy_txiqcal_ladder ladder_lo[] = { + static const struct nphy_txiqcal_ladder ladder_lo[] = { {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} }; - struct nphy_txiqcal_ladder ladder_iq[] = { + static const struct nphy_txiqcal_ladder ladder_iq[] = { {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} @@ -25773,67 +25770,67 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, u16 cal_gain[2]; struct nphy_iqcal_params cal_params[2]; u32 tbl_len; - void *tbl_ptr; + const void *tbl_ptr; bool ladder_updated[2]; u8 mphase_cal_lastphase = 0; int bcmerror = 0; bool phyhang_avoid_state = false; - u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { + static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901, 0x1902, 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607, 0x6407 }; - u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { + static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400, 0x3200, 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, 0x6407 }; - u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { + static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201, 0x1202, 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207, 0x4707 }; - u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { + static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900, 0x2300, 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, 0x4707 }; - u16 tbl_tx_iqlo_cal_startcoefs[] = { + static const u16 tbl_tx_iqlo_cal_startcoefs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; - u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { + static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { 0x8123, 0x8264, 0x8086, 0x8245, 0x8056, 0x9123, 0x9264, 0x9086, 0x9245, 0x9056 }; - u16 tbl_tx_iqlo_cal_cmds_recal[] = { + static const u16 tbl_tx_iqlo_cal_cmds_recal[] = { 0x8101, 0x8253, 0x8053, 0x8234, 0x8034, 0x9101, 0x9253, 0x9053, 0x9234, 0x9034 }; - u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { + static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; - u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { + static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234, 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234 }; - u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { + static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223, 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223 }; -- cgit v1.2.3 From 28a04c7b7bbecaab642fcb6a2d7354eb70ea7fbe Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 2 Oct 2017 12:14:56 +0200 Subject: mlxsw: spectrum_router: Move VRF refcounting When creating a new RIF, bumping RIF count of the containing VR is the last thing to be done. Symmetrically, when destroying a RIF, RIF count is first dropped and only then the rest of the cleanup proceeds. That's a problem for loopback RIFs. Those hold two VR references: one for overlay and one for underlay. mlxsw_sp_rif_destroy() releases the overlay one, and the deconfigure() callback the underlay one. But if both overlay and underlay are the same, and if there are no other artifacts holding the VR alive, this put actually destroys the VR. Later on, when mlxsw_sp_rif_destroy() calls mlxsw_sp_vr_put() for the same VR, the VR will already have been released and the kernel crashes with NULL pointer dereference. The underlying problem is that the RIF under destruction ends up referencing the overlay VR much longer than it claims: all the way until the call to mlxsw_sp_vr_put(). So line up the reference counting properly to reflect this. Make corresponding changes in mlxsw_sp_rif_create() as well for symmetry. Fixes: 6ddb7426a7d4 ("mlxsw: spectrum_router: Introduce loopback RIFs") Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 2cfb3f5d092d..3917b4dd4202 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -5068,6 +5068,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN); if (IS_ERR(vr)) return ERR_CAST(vr); + vr->rif_count++; err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index); if (err) @@ -5099,7 +5100,6 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_rif_counters_alloc(rif); mlxsw_sp->router->rifs[rif_index] = rif; - vr->rif_count++; return rif; @@ -5110,6 +5110,7 @@ err_fid_get: kfree(rif); err_rif_alloc: err_rif_index_alloc: + vr->rif_count--; mlxsw_sp_vr_put(vr); return ERR_PTR(err); } @@ -5124,7 +5125,6 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif); vr = &mlxsw_sp->router->vrs[rif->vr_id]; - vr->rif_count--; mlxsw_sp->router->rifs[rif->rif_index] = NULL; mlxsw_sp_rif_counters_free(rif); ops->deconfigure(rif); @@ -5132,6 +5132,7 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) /* Loopback RIFs are not associated with a FID. */ mlxsw_sp_fid_put(fid); kfree(rif); + vr->rif_count--; mlxsw_sp_vr_put(vr); } -- cgit v1.2.3 From de0f43c01a4b5d408a5c087c8a92ac1739938f8b Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 2 Oct 2017 12:14:57 +0200 Subject: mlxsw: spectrum_router: Track RIF of IPIP next hops When considering whether to set RTNH_F_OFFLOAD flag on an IPv6 route, mlxsw_sp_fib6_entry_offload_set() looks up the mlxsw_sp_nexthop corresponding to a given route, and decides based on whether the next hop's offloaded flag was set. When looking for the matching next hop, it also takes into account the device of the route, which must match next hop's RIF. IPIP next hops however hitherto didn't set the RIF. As a result, IPv6 routes forwarding traffic to IP-in-IP netdevices are never marked as offloaded, even when they actually are. Thus track RIF of IPIP next hops the same way as that of ETHERNET next hops. Fixes: 8f28a3097645 ("mlxsw: spectrum_router: Support IPv6 overlay encap") Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 3917b4dd4202..032089efc1a0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -2723,6 +2723,7 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_nexthop_rif_fini(nh); break; case MLXSW_SP_NEXTHOP_TYPE_IPIP: + mlxsw_sp_nexthop_rif_fini(nh); mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh); break; } @@ -2742,7 +2743,11 @@ static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp, router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, MLXSW_SP_L3_PROTO_IPV4)) { nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; - return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); + err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); + if (err) + return err; + mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); + return 0; } nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; @@ -4009,7 +4014,11 @@ static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp, router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, MLXSW_SP_L3_PROTO_IPV6)) { nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; - return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); + err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); + if (err) + return err; + mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); + return 0; } nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; -- cgit v1.2.3 From d312fefea8387503375f728855c9a62de20c9665 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 2 Oct 2017 19:31:24 +0100 Subject: ahci: don't ignore result code of ahci_reset_controller() ahci_pci_reset_controller() calls ahci_reset_controller(), which may fail, but ignores the result code and always returns success. This may result in failures like below ahci 0000:02:00.0: version 3.0 ahci 0000:02:00.0: enabling device (0000 -> 0003) ahci 0000:02:00.0: SSS flag set, parallel bus scan disabled ahci 0000:02:00.0: controller reset failed (0xffffffff) ahci 0000:02:00.0: failed to stop engine (-5) ... repeated many times ... ahci 0000:02:00.0: failed to stop engine (-5) Unable to handle kernel paging request at virtual address ffff0000093f9018 ... PC is at ahci_stop_engine+0x5c/0xd8 [libahci] LR is at ahci_deinit_port.constprop.12+0x1c/0xc0 [libahci] ... [] ahci_stop_engine+0x5c/0xd8 [libahci] [] ahci_deinit_port.constprop.12+0x1c/0xc0 [libahci] [] ahci_init_controller+0x80/0x168 [libahci] [] ahci_pci_init_controller+0x60/0x68 [ahci] [] ahci_init_one+0x75c/0xd88 [ahci] [] local_pci_probe+0x3c/0xb8 [] pci_device_probe+0x138/0x170 [] driver_probe_device+0x2dc/0x458 [] __driver_attach+0x114/0x118 [] bus_for_each_dev+0x60/0xa0 [] driver_attach+0x20/0x28 [] bus_add_driver+0x1f0/0x2a8 [] driver_register+0x60/0xf8 [] __pci_register_driver+0x3c/0x48 [] ahci_pci_driver_init+0x1c/0x1000 [ahci] [] do_one_initcall+0x38/0x120 where an obvious hardware level failure results in an unnecessary 15 second delay and a subsequent crash. So record the result code of ahci_reset_controller() and relay it, rather than ignoring it. Signed-off-by: Ard Biesheuvel Signed-off-by: Tejun Heo --- drivers/ata/ahci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index cb9b0e9090e3..9f78bb03bb76 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -621,8 +621,11 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev, static int ahci_pci_reset_controller(struct ata_host *host) { struct pci_dev *pdev = to_pci_dev(host->dev); + int rc; - ahci_reset_controller(host); + rc = ahci_reset_controller(host); + if (rc) + return rc; if (pdev->vendor == PCI_VENDOR_ID_INTEL) { struct ahci_host_priv *hpriv = host->private_data; -- cgit v1.2.3 From cb1dab0e01969d63717c7464cb5d75c77a39bf02 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 29 Sep 2017 16:22:57 +0800 Subject: drm/sun4i: hdmi: Disable clks in bind function error path and unbind function The HDMI driver enables the bus and mod clocks in the bind function, but does not disable them if it then bails our due to any errors. Neither does it disable the clocks in the unbind function. Fix this by adding a proper error path to the bind function, and clk_disable_unprepare calls to the unbind function. Also rename the err_cleanup_connector label to err_cleanup_encoder, since it is the encoder that gets cleaned up. Fixes: 9c5681011a0c ("drm/sun4i: Add HDMI support") Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20170929082306.16193-6-wens@csie.org --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 9ea6cd5a1370..3cf1a6932fac 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -302,26 +302,29 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, hdmi->mod_clk = devm_clk_get(dev, "mod"); if (IS_ERR(hdmi->mod_clk)) { dev_err(dev, "Couldn't get the HDMI mod clock\n"); - return PTR_ERR(hdmi->mod_clk); + ret = PTR_ERR(hdmi->mod_clk); + goto err_disable_bus_clk; } clk_prepare_enable(hdmi->mod_clk); hdmi->pll0_clk = devm_clk_get(dev, "pll-0"); if (IS_ERR(hdmi->pll0_clk)) { dev_err(dev, "Couldn't get the HDMI PLL 0 clock\n"); - return PTR_ERR(hdmi->pll0_clk); + ret = PTR_ERR(hdmi->pll0_clk); + goto err_disable_mod_clk; } hdmi->pll1_clk = devm_clk_get(dev, "pll-1"); if (IS_ERR(hdmi->pll1_clk)) { dev_err(dev, "Couldn't get the HDMI PLL 1 clock\n"); - return PTR_ERR(hdmi->pll1_clk); + ret = PTR_ERR(hdmi->pll1_clk); + goto err_disable_mod_clk; } ret = sun4i_tmds_create(hdmi); if (ret) { dev_err(dev, "Couldn't create the TMDS clock\n"); - return ret; + goto err_disable_mod_clk; } writel(SUN4I_HDMI_CTRL_ENABLE, hdmi->base + SUN4I_HDMI_CTRL_REG); @@ -362,7 +365,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, ret = sun4i_hdmi_i2c_create(dev, hdmi); if (ret) { dev_err(dev, "Couldn't create the HDMI I2C adapter\n"); - return ret; + goto err_disable_mod_clk; } drm_encoder_helper_add(&hdmi->encoder, @@ -422,6 +425,10 @@ err_cleanup_connector: drm_encoder_cleanup(&hdmi->encoder); err_del_i2c_adapter: i2c_del_adapter(hdmi->i2c); +err_disable_mod_clk: + clk_disable_unprepare(hdmi->mod_clk); +err_disable_bus_clk: + clk_disable_unprepare(hdmi->bus_clk); return ret; } @@ -434,6 +441,8 @@ static void sun4i_hdmi_unbind(struct device *dev, struct device *master, drm_connector_cleanup(&hdmi->connector); drm_encoder_cleanup(&hdmi->encoder); i2c_del_adapter(hdmi->i2c); + clk_disable_unprepare(hdmi->mod_clk); + clk_disable_unprepare(hdmi->bus_clk); } static const struct component_ops sun4i_hdmi_ops = { -- cgit v1.2.3 From 495001c6457124e553ebeec30a42e75367724e4b Mon Sep 17 00:00:00 2001 From: David Weinehall Date: Tue, 8 Aug 2017 13:09:52 +0300 Subject: drm/i915: Add has_psr-flag to gen9lp While testing Jim Bride's latest batch of PSR patches I noticed that gen9lp doesn't include the has_psr flag, and that our GLK system thus reported PSR as unsupported. This patch simply adds has_psr. Signed-off-by: David Weinehall Acked-by: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20170808100952.26448-1-david.weinehall@linux.intel.com --- drivers/gpu/drm/i915/i915_pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index da60866b6628..17823980b40d 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -463,6 +463,7 @@ static const struct intel_device_info intel_skylake_gt4_info __initconst = { .has_ddi = 1, \ .has_fpga_dbg = 1, \ .has_fbc = 1, \ + .has_psr = 1, \ .has_runtime_pm = 1, \ .has_pooled_eu = 0, \ .has_csr = 1, \ -- cgit v1.2.3 From 6e60a3bbb45bd8b307269d6a821ee2c72d815846 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 2 Oct 2017 16:22:08 -0400 Subject: nbd: fix -ERESTARTSYS handling Christoph made it so that if we return'ed BLK_STS_RESOURCE whenever we got ERESTARTSYS from sending our packets we'd return BLK_STS_OK, which means we'd never requeue and just hang. We really need to return the right value from the upper layer. Fixes: fc17b6534eb8 ("blk-mq: switch ->queue_rq return value to blk_status_t") Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 3684e21d543f..883dfebd3014 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -820,9 +820,13 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, * appropriate. */ ret = nbd_handle_cmd(cmd, hctx->queue_num); + if (ret < 0) + ret = BLK_STS_IOERR; + else if (!ret) + ret = BLK_STS_OK; complete(&cmd->send_complete); - return ret < 0 ? BLK_STS_IOERR : BLK_STS_OK; + return ret; } static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, -- cgit v1.2.3 From 28a0bc4120d38a394499382ba21d6965a67a3703 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 27 Sep 2017 21:35:12 -0400 Subject: scsi: sd: Implement blacklist option for WRITE SAME w/ UNMAP SBC-4 states: "A MAXIMUM UNMAP LBA COUNT field set to a non-zero value indicates the maximum number of LBAs that may be unmapped by an UNMAP command" "A MAXIMUM WRITE SAME LENGTH field set to a non-zero value indicates the maximum number of contiguous logical blocks that the device server allows to be unmapped or written in a single WRITE SAME command." Despite the spec being clear on the topic, some devices incorrectly expect WRITE SAME commands with the UNMAP bit set to be limited to the value reported in MAXIMUM UNMAP LBA COUNT in the Block Limits VPD. Implement a blacklist option that can be used to accommodate devices with this behavior. Cc: Reported-by: Bill Kuzeja Reported-by: Ewan D. Milne Reviewed-by: Ewan D. Milne Tested-by: Laurence Oberman Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_scan.c | 3 +++ drivers/scsi/sd.c | 16 ++++++++++++---- include/scsi/scsi_device.h | 1 + include/scsi/scsi_devinfo.h | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index e7818afeda2b..15590a063ad9 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -956,6 +956,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, if (*bflags & BLIST_NO_DIF) sdev->no_dif = 1; + if (*bflags & BLIST_UNMAP_LIMIT_WS) + sdev->unmap_limit_for_ws = 1; + sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT; if (*bflags & BLIST_TRY_VPD_PAGES) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fb9f8b5f4673..3d26a729825c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -715,13 +715,21 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) break; case SD_LBP_WS16: - max_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS16_BLOCKS); + if (sdkp->device->unmap_limit_for_ws) + max_blocks = sdkp->max_unmap_blocks; + else + max_blocks = sdkp->max_ws_blocks; + + max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS); break; case SD_LBP_WS10: - max_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS10_BLOCKS); + if (sdkp->device->unmap_limit_for_ws) + max_blocks = sdkp->max_unmap_blocks; + else + max_blocks = sdkp->max_ws_blocks; + + max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS); break; case SD_LBP_ZERO: diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 82e93ee94708..67c5a9f223f7 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -192,6 +192,7 @@ struct scsi_device { unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ unsigned broken_fua:1; /* Don't set FUA bit */ unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */ + unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */ atomic_t disk_events_disable_depth; /* disable depth for disk events */ diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h index 9592570e092a..36b03013d629 100644 --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -29,5 +29,6 @@ #define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */ #define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */ #define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */ +#define BLIST_UNMAP_LIMIT_WS 0x80000000 /* Use UNMAP limit for WRITE SAME */ #endif -- cgit v1.2.3 From 77082ca503bed061f7fbda7cfd7c93beda967a41 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 27 Sep 2017 21:38:59 -0400 Subject: scsi: sd: Do not override max_sectors_kb sysfs setting A user may lower the max_sectors_kb setting in sysfs to accommodate certain workloads. Previously we would always set the max I/O size to either the block layer default or the optional preferred I/O size reported by the device. Keep the current heuristics for the initial setting of max_sectors_kb. For subsequent invocations, only update the current queue limit if it exceeds the capabilities of the hardware. Cc: Reported-by: Don Brace Reviewed-by: Martin Wilck Tested-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3d26a729825c..d175c5c5ccf8 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3107,8 +3107,6 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_security(sdkp, buffer); } - sdkp->first_scan = 0; - /* * We now have all cache related info, determine how we deal * with flush requests. @@ -3123,7 +3121,7 @@ static int sd_revalidate_disk(struct gendisk *disk) q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max); /* - * Use the device's preferred I/O size for reads and writes + * Determine the device's preferred I/O size for reads and writes * unless the reported value is unreasonably small, large, or * garbage. */ @@ -3137,8 +3135,19 @@ static int sd_revalidate_disk(struct gendisk *disk) rw_max = min_not_zero(logical_to_sectors(sdp, dev_max), (sector_t)BLK_DEF_MAX_SECTORS); - /* Combine with controller limits */ - q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); + /* Do not exceed controller limit */ + rw_max = min(rw_max, queue_max_hw_sectors(q)); + + /* + * Only update max_sectors if previously unset or if the current value + * exceeds the capabilities of the hardware. + */ + if (sdkp->first_scan || + q->limits.max_sectors > q->limits.max_dev_sectors || + q->limits.max_sectors > q->limits.max_hw_sectors) + q->limits.max_sectors = rw_max; + + sdkp->first_scan = 0; set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity)); sd_config_write_same(sdkp); -- cgit v1.2.3 From 9e10b5121ad991ea6e84ca40b15a04cdc551bfe9 Mon Sep 17 00:00:00 2001 From: Khazhismel Kumykov Date: Thu, 13 Jul 2017 09:11:21 -0700 Subject: scsi: libiscsi: Fix use-after-free race during iscsi_session_teardown Session attributes exposed through sysfs were freed before the device was destroyed, resulting in a potential use-after-free. Free these attributes after removing the device. Signed-off-by: Khazhismel Kumykov Acked-by: Chris Leech Signed-off-by: Martin K. Petersen --- drivers/scsi/libiscsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index bd4605a34f54..c62e8d111fd9 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2851,9 +2851,6 @@ EXPORT_SYMBOL_GPL(iscsi_session_setup); /** * iscsi_session_teardown - destroy session, host, and cls_session * @cls_session: iscsi session - * - * The driver must have called iscsi_remove_session before - * calling this. */ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) { @@ -2863,6 +2860,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) iscsi_pool_free(&session->cmdpool); + iscsi_remove_session(cls_session); + kfree(session->password); kfree(session->password_in); kfree(session->username); @@ -2877,7 +2876,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) kfree(session->portal_type); kfree(session->discovery_parent_type); - iscsi_destroy_session(cls_session); + iscsi_free_session(cls_session); + iscsi_host_dec_session_cnt(shost); module_put(owner); } -- cgit v1.2.3 From 1c048a250aae1aaab0ba9dbec908f0c6cdb8614f Mon Sep 17 00:00:00 2001 From: Khazhismel Kumykov Date: Thu, 13 Jul 2017 09:11:22 -0700 Subject: scsi: libiscsi: Remove iscsi_destroy_session iscsi_session_teardown was the only user of this function. Function currently is just short for iscsi_remove_session + iscsi_free_session. Signed-off-by: Khazhismel Kumykov Acked-by: Chris Leech Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_iscsi.c | 16 ---------------- include/scsi/scsi_transport_iscsi.h | 1 - 2 files changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 0190aeff5f7f..7404d26895f5 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -2210,22 +2210,6 @@ void iscsi_free_session(struct iscsi_cls_session *session) } EXPORT_SYMBOL_GPL(iscsi_free_session); -/** - * iscsi_destroy_session - destroy iscsi session - * @session: iscsi_session - * - * Can be called by a LLD or iscsi_transport. There must not be - * any running connections. - */ -int iscsi_destroy_session(struct iscsi_cls_session *session) -{ - iscsi_remove_session(session); - ISCSI_DBG_TRANS_SESSION(session, "Completing session destruction\n"); - iscsi_free_session(session); - return 0; -} -EXPORT_SYMBOL_GPL(iscsi_destroy_session); - /** * iscsi_create_conn - create iscsi class connection * @session: iscsi cls session diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 6183d20a01fb..b266d2a3bcb1 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -434,7 +434,6 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, unsigned int target_id); extern void iscsi_remove_session(struct iscsi_cls_session *session); extern void iscsi_free_session(struct iscsi_cls_session *session); -extern int iscsi_destroy_session(struct iscsi_cls_session *session); extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, int dd_size, uint32_t cid); extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); -- cgit v1.2.3 From 88e65389fce1f68ba6d13ae2fc0f8d7e5c338c52 Mon Sep 17 00:00:00 2001 From: "Bryant G. Ly" Date: Mon, 2 Oct 2017 12:59:38 -0500 Subject: scsi: ibmvscsis: Fix write_pending failure path For write_pending if the queue is down or client failed then return -EIO so that LIO can properly process the completed command. Prior we returned 0 since LIO could not handle it properly. Now with commit fa7e25cf13a6 ("target: Fix unknown fabric callback queue-full errors") that patch addresses LIO's ability to handle things right. Signed-off-by: Bryant G. Ly Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index 785fb42f6650..2799a6b08f73 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -3767,7 +3767,7 @@ static int ibmvscsis_write_pending(struct se_cmd *se_cmd) */ if ((vscsi->flags & (CLIENT_FAILED | RESPONSE_Q_DOWN))) { pr_err("write_pending failed since: %d\n", vscsi->flags); - return 0; + return -EIO; } rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma, -- cgit v1.2.3 From 77913bbcb43ac9a07a6fe849c2fd3bf85fc8bdd8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Sep 2017 15:05:38 +1000 Subject: drm/nouveau/mmu: flush tlbs before deleting page tables Even though we've zeroed the PDE, the GPU may have cached the PD, so we need to flush when deleting them. Noticed while working on replacement MMU code, but a backport might be a good idea, so let's fix it in the current code too. Signed-off-by: Ben Skeggs Cc: stable@vger.kernel.org --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index d06ad2c372bf..455da298227f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -241,6 +241,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde) mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem); } + mmu->func->flush(vm); + nvkm_memory_del(&pgt); } } -- cgit v1.2.3 From 194d68dd051c2dd5ac2b522ae16100e774e8d869 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 1 Oct 2017 13:52:43 -0400 Subject: drm/nouveau/bsp/g92: disable by default G92's seem to require some additional bit of initialization before the BSP engine can work. It feels like clocks are not set up for the underlying VLD engine, which means that all commands submitted to the xtensa chip end up hanging. VP seems to work fine though. This still allows people to force-enable the bsp engine if they want to play around with it, but makes it harder for the card to hang by default. Signed-off-by: Ilia Mirkin Signed-off-by: Ben Skeggs Cc: stable@vger.kernel.org --- drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c index 8e2e24a74774..44e116f7880d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c @@ -39,5 +39,5 @@ int g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine) { return nvkm_xtensa_new_(&g84_bsp, device, index, - true, 0x103000, pengine); + device->chipset != 0x92, 0x103000, pengine); } -- cgit v1.2.3 From 227f66d2f9954f68375736af62ebcd73c6754d69 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 3 Oct 2017 16:24:28 +1000 Subject: drm/nouveau/kms/nv50: fix oops during DP IRQ handling on non-MST boards Reported-by: Woody Suwalski Signed-off-by: Ben Skeggs Cc: stable@vger.kernel.org --- drivers/gpu/drm/nouveau/nv50_display.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 2dbf62a2ac41..e4751f92b342 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -3265,11 +3265,14 @@ nv50_mstm = { void nv50_mstm_service(struct nv50_mstm *mstm) { - struct drm_dp_aux *aux = mstm->mgr.aux; + struct drm_dp_aux *aux = mstm ? mstm->mgr.aux : NULL; bool handled = true; int ret; u8 esi[8] = {}; + if (!aux) + return; + while (handled) { ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8); if (ret != 8) { -- cgit v1.2.3 From ed69cd40685c949ec9c65701758bbf9e6840240f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 2 Oct 2017 10:55:57 +0300 Subject: drm/i915/glk, cnl: Implement WaDisableScalarClockGating On GLK and CNL enabling a pipe with its pipe scaler enabled will result in a FIFO underrun. This happens only once after driver loading or system/runtime resume, more specifically after power well 1 gets enabled; subsequent modesets seem to be free of underruns. The BSpec workaround for this is to disable the pipe scaler clock gating for the duration of modeset. Based on my tests disabling clock gating must be done before enabling pipe scaling and we can re-enable it after the pipe is enabled and one vblank has passed. For consistency I also checked if plane scaling would cause the same problem, but that doesn't seem to trigger this problem. The patch is based on an earlier version from Ander. v2 (Rodrigo): - Set also CLKGATE_DIS_PSL bits 8 and 9. - Add also the BSpec workaround ID. Cc: Ander Conselvan de Oliveira Cc: Rodrigo Vivi Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100302 Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171002075557.32615-1-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 10 ++++++++++ drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ee0d4f14ac98..39ad9327e2a0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3819,6 +3819,16 @@ enum { #define PWM2_GATING_DIS (1 << 14) #define PWM1_GATING_DIS (1 << 13) +#define _CLKGATE_DIS_PSL_A 0x46520 +#define _CLKGATE_DIS_PSL_B 0x46524 +#define _CLKGATE_DIS_PSL_C 0x46528 +#define DPF_GATING_DIS (1 << 10) +#define DPF_RAM_GATING_DIS (1 << 9) +#define DPFR_GATING_DIS (1 << 8) + +#define CLKGATE_DIS_PSL(pipe) \ + _MMIO_PIPE(pipe, _CLKGATE_DIS_PSL_A, _CLKGATE_DIS_PSL_B) + /* * GEN10 clock gating regs */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c4b224a3a0ee..b7a6ddc6a66d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5459,6 +5459,20 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc) return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A; } +static void glk_pipe_scaler_clock_gating_wa(struct drm_i915_private *dev_priv, + enum pipe pipe, bool apply) +{ + u32 val = I915_READ(CLKGATE_DIS_PSL(pipe)); + u32 mask = DPF_GATING_DIS | DPF_RAM_GATING_DIS | DPFR_GATING_DIS; + + if (apply) + val |= mask; + else + val &= ~mask; + + I915_WRITE(CLKGATE_DIS_PSL(pipe), val); +} + static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, struct drm_atomic_state *old_state) { @@ -5469,6 +5483,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; struct intel_atomic_state *old_intel_state = to_intel_atomic_state(old_state); + bool psl_clkgate_wa; if (WARN_ON(intel_crtc->active)) return; @@ -5522,6 +5537,12 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, if (!transcoder_is_dsi(cpu_transcoder)) intel_ddi_enable_pipe_clock(pipe_config); + /* Display WA #1180: WaDisableScalarClockGating: glk, cnl */ + psl_clkgate_wa = (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) && + intel_crtc->config->pch_pfit.enabled; + if (psl_clkgate_wa) + glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, true); + if (INTEL_GEN(dev_priv) >= 9) skylake_pfit_enable(intel_crtc); else @@ -5555,6 +5576,11 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, intel_encoders_enable(crtc, pipe_config, old_state); + if (psl_clkgate_wa) { + intel_wait_for_vblank(dev_priv, pipe); + glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false); + } + if (intel_crtc->config->has_pch_encoder) { intel_wait_for_vblank(dev_priv, pipe); intel_wait_for_vblank(dev_priv, pipe); -- cgit v1.2.3 From e19c1eb885ac4186e64c7e484424124f3145318e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 2 Oct 2017 16:53:07 +0300 Subject: drm/i915: Fix DDI PHY init if it was already on The common lane power down flag of a DPIO PHY has a funky semantic: after the initial enabling of the PHY (so from a disabled state) this flag will be clear. It will be set only after the PHY will be used for the first time (for instance due to enabling the corresponding pipe) and then become unused (due to disabling the pipe). During the initial PHY enablement we don't know which of the above phases we are in, so move the check for the flag where this is known, the HW readout code. This is where the rest of lane power down status checks are done anyway. This fixes at least a problem on GLK where after module reloading, the common lane power down flag of PHY1 is set, but the PHY is actually powered-on and properly set up. The GRC readout code for other PHYs will hence think that PHY1 is not powered initially and disable it after the GRC readout. This will cause the AUX power well related to PHY1 to get disabled in a stuck state, timing out when we try to enable it later. Cc: Ville Syrjala Fixes: e93da0a0137b ("drm/i915/bxt: Sanitiy check the PHY lane power down status") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102777 Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171002135307.26117-1-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 3 ++- drivers/gpu/drm/i915/intel_dpio_phy.c | 20 -------------------- 2 files changed, 2 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 93cbbcbbc193..65f4b6786791 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1713,7 +1713,8 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, out: if (ret && IS_GEN9_LP(dev_priv)) { tmp = I915_READ(BXT_PHY_CTL(port)); - if ((tmp & (BXT_PHY_LANE_POWERDOWN_ACK | + if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | + BXT_PHY_LANE_POWERDOWN_ACK | BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) DRM_ERROR("Port %c enabled but PHY powered down? " "(PHY_CTL %08x)\n", port_name(port), tmp); diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c index 09b670929786..de38d014ed39 100644 --- a/drivers/gpu/drm/i915/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c @@ -208,12 +208,6 @@ static const struct bxt_ddi_phy_info glk_ddi_phy_info[] = { }, }; -static u32 bxt_phy_port_mask(const struct bxt_ddi_phy_info *phy_info) -{ - return (phy_info->dual_channel * BIT(phy_info->channel[DPIO_CH1].port)) | - BIT(phy_info->channel[DPIO_CH0].port); -} - static const struct bxt_ddi_phy_info * bxt_get_phy_list(struct drm_i915_private *dev_priv, int *count) { @@ -313,7 +307,6 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, enum dpio_phy phy) { const struct bxt_ddi_phy_info *phy_info; - enum port port; phy_info = bxt_get_phy_info(dev_priv, phy); @@ -335,19 +328,6 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, return false; } - for_each_port_masked(port, bxt_phy_port_mask(phy_info)) { - u32 tmp = I915_READ(BXT_PHY_CTL(port)); - - if (tmp & BXT_PHY_CMNLANE_POWERDOWN_ACK) { - DRM_DEBUG_DRIVER("DDI PHY %d powered, but common lane " - "for port %c powered down " - "(PHY_CTL %08x)\n", - phy, port_name(port), tmp); - - return false; - } - } - return true; } -- cgit v1.2.3 From 2fb850092fd95198a0a4746f07b80077d5a3aa37 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 29 Sep 2017 16:58:46 -0700 Subject: phy: rockchip-typec: Check for errors from tcphy_phy_init() The function tcphy_phy_init() could return an error but the callers weren't checking the return value. They should. In at least one case while testing I saw the message "wait pma ready timeout" which indicates that tcphy_phy_init() really could return an error and we should account for it. Signed-off-by: Douglas Anderson Reviewed-by: Guenter Roeck Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/rockchip/phy-rockchip-typec.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index b25c00432f9b..a958c9bced01 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -708,8 +708,11 @@ static int rockchip_usb3_phy_power_on(struct phy *phy) if (tcphy->mode == new_mode) goto unlock_ret; - if (tcphy->mode == MODE_DISCONNECT) - tcphy_phy_init(tcphy, new_mode); + if (tcphy->mode == MODE_DISCONNECT) { + ret = tcphy_phy_init(tcphy, new_mode); + if (ret) + goto unlock_ret; + } /* wait TCPHY for pipe ready */ for (timeout = 0; timeout < 100; timeout++) { @@ -783,10 +786,12 @@ static int rockchip_dp_phy_power_on(struct phy *phy) */ if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) { tcphy_phy_deinit(tcphy); - tcphy_phy_init(tcphy, new_mode); + ret = tcphy_phy_init(tcphy, new_mode); } else if (tcphy->mode == MODE_DISCONNECT) { - tcphy_phy_init(tcphy, new_mode); + ret = tcphy_phy_init(tcphy, new_mode); } + if (ret) + goto unlock_ret; ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, val, val & DP_MODE_A2, 1000, -- cgit v1.2.3 From f5d9644c5fca7d8e8972268598bb516a7eae17f9 Mon Sep 17 00:00:00 2001 From: Shrirang Bagul Date: Fri, 29 Sep 2017 12:39:51 +0800 Subject: USB: serial: qcserial: add Dell DW5818, DW5819 Dell Wireless 5819/5818 devices are re-branded Sierra Wireless MC74 series which will by default boot with vid 0x413c and pid's 0x81cf, 0x81d0, 0x81d1, 0x81d2. Signed-off-by: Shrirang Bagul Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/qcserial.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index ebc0beea69d6..eb9928963a53 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ + {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ + {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ + {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ + {DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */ /* Huawei devices */ {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ -- cgit v1.2.3 From 4d6ef0da415124ebce578b1326f4e511e35d95f2 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 2 Oct 2017 23:36:50 -0700 Subject: drm/i915/skl: Fix has_ipc on skl and document WaDisableIPC. According to Spec for SKL+: "Isochronous Priority Control. If enabled, Display sends demoted requests once the transition watermark is reached. If transition watermark is not enabled, Display sends demoted requests when the display buffer is full." The commit 'e57f1c02155f ("drm/i915/gen9+: Add has_ipc flag in device info structure")' introduced that as gen9+ but missing many SKL Skus. I believe the reason for that is Spec also mentions workarounds for SKL-ALL: "IPC (Isoch Priority Control) may cause underflows WA: Do not enable IPC in register ARB_CTL2" It seems lame to add the feature and forever disable it, but it will avoid a mistake of enabling it when we are reorganizing the feature definitions on i915_pci.c later. It will also allow us to probably extend that workaround for other platforms. Cc: Mahesh Kumar Cc: Maarten Lankhorst Cc: Chris Wilson Signed-off-by: Rodrigo Vivi Reviewed-by: Mahesh Kumar Link: https://patchwork.freedesktop.org/patch/msgid/20171003063652.17248-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_pci.c | 1 + drivers/gpu/drm/i915/intel_pm.c | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 17823980b40d..66f4ab0cb2e8 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -426,6 +426,7 @@ static const struct intel_device_info intel_cherryview_info __initconst = { .platform = INTEL_SKYLAKE, \ .has_csr = 1, \ .has_guc = 1, \ + .has_ipc = 1, \ .ddb_size = 896 static const struct intel_device_info intel_skylake_gt1_info __initconst = { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c66af09e27a7..171b21f6c4ad 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5827,6 +5827,12 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv) { u32 val; + /* Display WA #0477 WaDisableIPC: skl */ + if (IS_SKYLAKE(dev_priv)) { + dev_priv->ipc_enabled = false; + return; + } + val = I915_READ(DISP_ARB_CTL2); if (dev_priv->ipc_enabled) -- cgit v1.2.3 From 42a3ae88500e394a79b27f6ae9705580033f805d Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 2 Oct 2017 23:36:51 -0700 Subject: drm/i915: Organize GEN features inheritance. As Chris noticed the current organization is confusing and inheritance is not clear. So, let's split it in GEN_FEATURES _PLATFORM where new GEN inherit features from previous gens and Platforms only use gen features plus what ever is specific for that platform and shouldn't be passed on. Cc: Chris Wilson Signed-off-by: Rodrigo Vivi Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171003063652.17248-2-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_pci.c | 48 +++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 66f4ab0cb2e8..bfec3a7841d0 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -329,7 +329,7 @@ static const struct intel_device_info intel_valleyview_info __initconst = { CURSOR_OFFSETS }; -#define HSW_FEATURES \ +#define G75_FEATURES \ GEN7_FEATURES, \ .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \ .has_ddi = 1, \ @@ -341,7 +341,7 @@ static const struct intel_device_info intel_valleyview_info __initconst = { .has_runtime_pm = 1 #define HSW_PLATFORM \ - HSW_FEATURES, \ + G75_FEATURES, \ .platform = INTEL_HASWELL, \ .has_l3_dpf = 1 @@ -360,8 +360,8 @@ static const struct intel_device_info intel_haswell_gt3_info __initconst = { .gt = 3, }; -#define BDW_FEATURES \ - HSW_FEATURES, \ +#define GEN8_FEATURES \ + G75_FEATURES, \ BDW_COLORS, \ .has_logical_ring_contexts = 1, \ .has_full_48bit_ppgtt = 1, \ @@ -369,7 +369,7 @@ static const struct intel_device_info intel_haswell_gt3_info __initconst = { .has_reset_engine = 1 #define BDW_PLATFORM \ - BDW_FEATURES, \ + GEN8_FEATURES, \ .gen = 8, \ .platform = INTEL_BROADWELL @@ -420,15 +420,18 @@ static const struct intel_device_info intel_cherryview_info __initconst = { CHV_COLORS, }; -#define SKL_PLATFORM \ - BDW_FEATURES, \ - .gen = 9, \ - .platform = INTEL_SKYLAKE, \ +#define GEN9_FEATURES \ + GEN8_FEATURES, \ .has_csr = 1, \ .has_guc = 1, \ .has_ipc = 1, \ .ddb_size = 896 +#define SKL_PLATFORM \ + GEN9_FEATURES, \ + .gen = 9, \ + .platform = INTEL_SKYLAKE + static const struct intel_device_info intel_skylake_gt1_info __initconst = { SKL_PLATFORM, .gt = 1, @@ -497,13 +500,9 @@ static const struct intel_device_info intel_geminilake_info __initconst = { }; #define KBL_PLATFORM \ - BDW_FEATURES, \ + GEN9_FEATURES, \ .gen = 9, \ - .platform = INTEL_KABYLAKE, \ - .has_csr = 1, \ - .has_guc = 1, \ - .has_ipc = 1, \ - .ddb_size = 896 + .platform = INTEL_KABYLAKE static const struct intel_device_info intel_kabylake_gt1_info __initconst = { KBL_PLATFORM, @@ -522,13 +521,9 @@ static const struct intel_device_info intel_kabylake_gt3_info __initconst = { }; #define CFL_PLATFORM \ - BDW_FEATURES, \ + GEN9_FEATURES, \ .gen = 9, \ - .platform = INTEL_COFFEELAKE, \ - .has_csr = 1, \ - .has_guc = 1, \ - .has_ipc = 1, \ - .ddb_size = 896 + .platform = INTEL_COFFEELAKE static const struct intel_device_info intel_coffeelake_gt1_info __initconst = { CFL_PLATFORM, @@ -546,16 +541,17 @@ static const struct intel_device_info intel_coffeelake_gt3_info __initconst = { .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; +#define GEN10_FEATURES \ + GEN9_FEATURES, \ + .ddb_size = 1024, \ + .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } + static const struct intel_device_info intel_cannonlake_gt2_info __initconst = { - BDW_FEATURES, + GEN10_FEATURES, .is_alpha_support = 1, .platform = INTEL_CANNONLAKE, .gen = 10, .gt = 2, - .ddb_size = 1024, - .has_csr = 1, - .has_ipc = 1, - .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } }; /* -- cgit v1.2.3 From 4672770d247806551de4aee6619d4f097eed155a Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 2 Oct 2017 23:36:52 -0700 Subject: drm/i915: Organize GLK_COLORS. Let's organize this in a way that it gets more obvious when looking to the platform colors and in a easier way to get inherited. v2: Add comma at the end (Jani), when possible. Cc: Jani Nikula Signed-off-by: Rodrigo Vivi Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171003063652.17248-3-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index bfec3a7841d0..d3a6fe5e3c10 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -54,6 +54,8 @@ .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } #define CHV_COLORS \ .color = { .degamma_lut_size = 65, .gamma_lut_size = 257 } +#define GLK_COLORS \ + .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } /* Keep in gen based order, and chronological order within a gen */ #define GEN2_FEATURES \ @@ -496,7 +498,7 @@ static const struct intel_device_info intel_geminilake_info __initconst = { GEN9_LP_FEATURES, .platform = INTEL_GEMINILAKE, .ddb_size = 1024, - .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } + GLK_COLORS, }; #define KBL_PLATFORM \ @@ -544,7 +546,7 @@ static const struct intel_device_info intel_coffeelake_gt3_info __initconst = { #define GEN10_FEATURES \ GEN9_FEATURES, \ .ddb_size = 1024, \ - .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } + GLK_COLORS static const struct intel_device_info intel_cannonlake_gt2_info __initconst = { GEN10_FEATURES, -- cgit v1.2.3 From d410a6417e5e4deb4a9c34164addcebebc9099c9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 3 Oct 2017 13:18:47 +0200 Subject: ide: free hwif->portdev on hwif_init() failure Recent pci_assign_irq() changes uncovered a problem with missing freeing of ide_port class instance on hwif_init() failure in ide_host_register(): ide0: disabled, no IRQ ide0: failed to initialize IDE interface ide0: disabling port cmd64x 0000:00:02.0: IDE controller (0x1095:0x0646 rev 0x07) CMD64x_IDE 0000:00:02.0: BAR 0: can't reserve [io 0x8050-0x8057] cmd64x 0000:00:02.0: can't reserve resources CMD64x_IDE: probe of 0000:00:02.0 failed with error -16 ide_generic: please use "probe_mask=0x3f" module parameter for probing all legacy ISA IDE ports ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x94/0xd0 sysfs: cannot create duplicate filename '/class/ide_port/ide0' ... Trace: [] __warn+0x160/0x190 [] sysfs_warn_dup+0x94/0xd0 [] warn_slowpath_fmt+0x58/0x70 [] sysfs_warn_dup+0x94/0xd0 [] kernfs_path_from_node+0x30/0x60 [] kernfs_put+0x16c/0x2c0 [] kernfs_put+0x16c/0x2c0 [] sysfs_do_create_link_sd.isra.2+0x100/0x120 [] device_add+0x2a4/0x7c0 [] device_create_groups_vargs+0x14c/0x170 [] device_create_groups_vargs+0x98/0x170 [] device_create+0x50/0x70 [] ide_host_register+0x48c/0xa00 [] ide_host_register+0x450/0xa00 [] device_register+0x20/0x50 [] ide_host_register+0x450/0xa00 [] ide_host_add+0x64/0xe0 [] kobject_uevent_env+0x16c/0x710 [] do_one_initcall+0x68/0x260 [] kernel_init+0x1c/0x1a0 [] kernel_init+0x0/0x1a0 [] ret_from_kernel_thread+0x18/0x20 [] kernel_init+0x0/0x1a0 ---[ end trace 24a70433c3e4d374 ]--- ide0: disabling port Fix the problem by adding missing code to ide_host_register(). Fixes: 30fdfb929e82 ("PCI: Add a call to pci_assign_irq() in pci_device_probe()") Fixes: 0e4c2eeb758a ("alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks") Link: http://lkml.kernel.org/r/32ec730f-c1b0-5584-cd35-f8a809122b96@roeck-us.net Reported-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Bartlomiej Zolnierkiewicz [bhelgaas: add Fixes:] Signed-off-by: Bjorn Helgaas Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner --- drivers/ide/ide-probe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 01b2adfd8226..eaf39e5db08b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1451,6 +1451,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, if (hwif_init(hwif) == 0) { printk(KERN_INFO "%s: failed to initialize IDE " "interface\n", hwif->name); + device_unregister(hwif->portdev); device_unregister(&hwif->gendev); ide_disable_port(hwif); continue; -- cgit v1.2.3 From a06876a766c27dcedf17a0f60be89609ee23d861 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 3 Oct 2017 14:17:13 +0200 Subject: ide: pci: free PCI BARs on initialization failure Recent pci_assign_irq() changes uncovered a problem with missing freeing of PCI BARs on PCI IDE host initialization failure: ide0: disabled, no IRQ ide0: failed to initialize IDE interface ide0: disabling port cmd64x 0000:00:02.0: IDE controller (0x1095:0x0646 rev 0x07) CMD64x_IDE 0000:00:02.0: BAR 0: can't reserve [io 0x8050-0x8057] cmd64x 0000:00:02.0: can't reserve resources CMD64x_IDE: probe of 0000:00:02.0 failed with error -16 Fix the problem by adding missing freeing of PCI BARs to ide_setup_pci_controller() and ide_pci_init_two(). Fixes: 30fdfb929e82 ("PCI: Add a call to pci_assign_irq() in pci_device_probe()") Fixes: 0e4c2eeb758a ("alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks") Link: http://lkml.kernel.org/r/32ec730f-c1b0-5584-cd35-f8a809122b96@roeck-us.net Reported-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Bartlomiej Zolnierkiewicz [bhelgaas: add Fixes:] Signed-off-by: Bjorn Helgaas Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner --- drivers/ide/setup-pci.c | 63 +++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 112d2fe1bcdb..fdc8e813170c 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -179,6 +179,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); /** * ide_pci_enable - do PCI enables * @dev: PCI device + * @bars: PCI BARs mask * @d: IDE port info * * Enable the IDE PCI device. We attempt to enable the device in full @@ -189,9 +190,10 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); * Returns zero on success or an error code */ -static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d) +static int ide_pci_enable(struct pci_dev *dev, int bars, + const struct ide_port_info *d) { - int ret, bars; + int ret; if (pci_enable_device(dev)) { ret = pci_enable_device_io(dev); @@ -216,18 +218,6 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d) goto out; } - if (d->host_flags & IDE_HFLAG_SINGLE) - bars = (1 << 2) - 1; - else - bars = (1 << 4) - 1; - - if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { - if (d->host_flags & IDE_HFLAG_CS5520) - bars |= (1 << 2); - else - bars |= (1 << 4); - } - ret = pci_request_selected_regions(dev, bars, d->name); if (ret < 0) printk(KERN_ERR "%s %s: can't reserve resources\n", @@ -403,6 +393,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) /** * ide_setup_pci_controller - set up IDE PCI * @dev: PCI device + * @bars: PCI BARs mask * @d: IDE port info * @noisy: verbose flag * @@ -411,7 +402,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) * and enables it if need be */ -static int ide_setup_pci_controller(struct pci_dev *dev, +static int ide_setup_pci_controller(struct pci_dev *dev, int bars, const struct ide_port_info *d, int noisy) { int ret; @@ -420,7 +411,7 @@ static int ide_setup_pci_controller(struct pci_dev *dev, if (noisy) ide_setup_pci_noise(dev, d); - ret = ide_pci_enable(dev, d); + ret = ide_pci_enable(dev, bars, d); if (ret < 0) goto out; @@ -428,16 +419,20 @@ static int ide_setup_pci_controller(struct pci_dev *dev, if (ret < 0) { printk(KERN_ERR "%s %s: error accessing PCI regs\n", d->name, pci_name(dev)); - goto out; + goto out_free_bars; } if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */ ret = ide_pci_configure(dev, d); if (ret < 0) - goto out; + goto out_free_bars; printk(KERN_INFO "%s %s: device enabled (Linux)\n", d->name, pci_name(dev)); } + goto out; + +out_free_bars: + pci_release_selected_regions(dev, bars); out: return ret; } @@ -540,13 +535,28 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, { struct pci_dev *pdev[] = { dev1, dev2 }; struct ide_host *host; - int ret, i, n_ports = dev2 ? 4 : 2; + int ret, i, n_ports = dev2 ? 4 : 2, bars; struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL }; + if (d->host_flags & IDE_HFLAG_SINGLE) + bars = (1 << 2) - 1; + else + bars = (1 << 4) - 1; + + if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { + if (d->host_flags & IDE_HFLAG_CS5520) + bars |= (1 << 2); + else + bars |= (1 << 4); + } + for (i = 0; i < n_ports / 2; i++) { - ret = ide_setup_pci_controller(pdev[i], d, !i); - if (ret < 0) + ret = ide_setup_pci_controller(pdev[i], bars, d, !i); + if (ret < 0) { + if (i == 1) + pci_release_selected_regions(pdev[0], bars); goto out; + } ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); } @@ -554,7 +564,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, host = ide_host_alloc(d, hws, n_ports); if (host == NULL) { ret = -ENOMEM; - goto out; + goto out_free_bars; } host->dev[0] = &dev1->dev; @@ -576,7 +586,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, * do_ide_setup_pci_device() on the first device! */ if (ret < 0) - goto out; + goto out_free_bars; /* fixup IRQ */ if (ide_pci_is_in_compatibility_mode(pdev[i])) { @@ -589,6 +599,13 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, ret = ide_host_register(host, d, hws); if (ret) ide_host_free(host); + else + goto out; + +out_free_bars: + i = n_ports / 2; + while (i--) + pci_release_selected_regions(pdev[i], bars); out: return ret; } -- cgit v1.2.3 From b1f9e5e355e909000fcccfd2bc31f7c1ded358ab Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 2 Oct 2017 11:52:47 +0100 Subject: ide: fix IRQ assignment for PCI bus order probing We used to assign IRQs for all devices at boot-time, before any drivers claimed devices. The following commits: 30fdfb929e82 ("PCI: Add a call to pci_assign_irq() in pci_device_probe()") 0e4c2eeb758a ("alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks") changed this so we now call pci_assign_irq() from pci_device_probe() when we call a driver's probe method. The ide_scan_pcibus() path (enabled by CONFIG_IDEPCI_PCIBUS_ORDER) bypasses pci_device_probe() so it can guarantee devices are claimed in order of PCI bus address. It calls the driver's probe method directly, so it misses the pci_assign_irq() call (and other PCI initialization functions), which causes failures like this: ide0: disabled, no IRQ ide0: failed to initialize IDE interface ide0: disabling port cmd64x 0000:00:02.0: IDE controller (0x1095:0x0646 rev 0x07) CMD64x_IDE 0000:00:02.0: BAR 0: can't reserve [io 0x8050-0x8057] cmd64x 0000:00:02.0: can't reserve resources CMD64x_IDE: probe of 0000:00:02.0 failed with error -16 ide_generic: please use "probe_mask=0x3f" module parameter for probing all legacy ISA IDE ports ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x94/0xd0 sysfs: cannot create duplicate filename '/class/ide_port/ide0' ... Trace: [] sysfs_warn_dup+0x94/0xd0 [] warn_slowpath_fmt+0x58/0x70 [] sysfs_warn_dup+0x94/0xd0 [] kernfs_path_from_node+0x30/0x60 [] kernfs_put+0x16c/0x2c0 [] kernfs_put+0x16c/0x2c0 [] sysfs_do_create_link_sd.isra.2+0x100/0x120 [] device_add+0x2a4/0x7c0 [] device_create_groups_vargs+0x14c/0x170 [] device_create_groups_vargs+0x98/0x170 [] device_create+0x50/0x70 [] ide_host_register+0x48c/0xa00 [] ide_host_register+0x450/0xa00 [] device_register+0x20/0x50 [] ide_host_register+0x450/0xa00 [] ide_host_add+0x64/0xe0 [] kobject_uevent_env+0x16c/0x710 [] do_one_initcall+0x68/0x260 [] kernel_init+0x1c/0x1a0 ... ---[ end trace 24a70433c3e4d374 ]--- ide0: disabling port Fix the IRQ allocation issue by calling pci_assign_irq() from ide_scan_pcidev() before probing the IDE PCI drivers, so that IRQs for a given PCI device are allocated for the IDE PCI drivers to use them for device configuration. Fixes: 30fdfb929e82 ("PCI: Add a call to pci_assign_irq() in pci_device_probe()") Fixes: 0e4c2eeb758a ("alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks") Link: http://lkml.kernel.org/r/32ec730f-c1b0-5584-cd35-f8a809122b96@roeck-us.net Reported-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Lorenzo Pieralisi [bhelgaas: changelog] Signed-off-by: Bjorn Helgaas Reviewed-by: Bartlomiej Zolnierkiewicz Acked-by: David S. Miller Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner --- drivers/ide/ide-scan-pci.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c index 86aa88aeb3a6..acf874800ca4 100644 --- a/drivers/ide/ide-scan-pci.c +++ b/drivers/ide/ide-scan-pci.c @@ -56,6 +56,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev) { struct list_head *l; struct pci_driver *d; + int ret; list_for_each(l, &ide_pci_drivers) { d = list_entry(l, struct pci_driver, node); @@ -63,10 +64,14 @@ static int __init ide_scan_pcidev(struct pci_dev *dev) const struct pci_device_id *id = pci_match_id(d->id_table, dev); - if (id != NULL && d->probe(dev, id) >= 0) { - dev->driver = d; - pci_dev_get(dev); - return 1; + if (id != NULL) { + pci_assign_irq(dev); + ret = d->probe(dev, id); + if (ret >= 0) { + dev->driver = d; + pci_dev_get(dev); + return 1; + } } } } -- cgit v1.2.3 From 71300132975f364a0d3ebf68671a2ce4923191db Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 2 Oct 2017 16:53:07 +0300 Subject: drm/i915: Fix DDI PHY init if it was already on The common lane power down flag of a DPIO PHY has a funky semantic: after the initial enabling of the PHY (so from a disabled state) this flag will be clear. It will be set only after the PHY will be used for the first time (for instance due to enabling the corresponding pipe) and then become unused (due to disabling the pipe). During the initial PHY enablement we don't know which of the above phases we are in, so move the check for the flag where this is known, the HW readout code. This is where the rest of lane power down status checks are done anyway. This fixes at least a problem on GLK where after module reloading, the common lane power down flag of PHY1 is set, but the PHY is actually powered-on and properly set up. The GRC readout code for other PHYs will hence think that PHY1 is not powered initially and disable it after the GRC readout. This will cause the AUX power well related to PHY1 to get disabled in a stuck state, timing out when we try to enable it later. Cc: Ville Syrjala Fixes: e93da0a0137b ("drm/i915/bxt: Sanitiy check the PHY lane power down status") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102777 Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171002135307.26117-1-imre.deak@intel.com (cherry picked from commit e19c1eb885ac4186e64c7e484424124f3145318e) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_ddi.c | 3 ++- drivers/gpu/drm/i915/intel_dpio_phy.c | 20 -------------------- 2 files changed, 2 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 4b4fd1f8110b..476681d5940c 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1655,7 +1655,8 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, out: if (ret && IS_GEN9_LP(dev_priv)) { tmp = I915_READ(BXT_PHY_CTL(port)); - if ((tmp & (BXT_PHY_LANE_POWERDOWN_ACK | + if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | + BXT_PHY_LANE_POWERDOWN_ACK | BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) DRM_ERROR("Port %c enabled but PHY powered down? " "(PHY_CTL %08x)\n", port_name(port), tmp); diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c index 09b670929786..de38d014ed39 100644 --- a/drivers/gpu/drm/i915/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c @@ -208,12 +208,6 @@ static const struct bxt_ddi_phy_info glk_ddi_phy_info[] = { }, }; -static u32 bxt_phy_port_mask(const struct bxt_ddi_phy_info *phy_info) -{ - return (phy_info->dual_channel * BIT(phy_info->channel[DPIO_CH1].port)) | - BIT(phy_info->channel[DPIO_CH0].port); -} - static const struct bxt_ddi_phy_info * bxt_get_phy_list(struct drm_i915_private *dev_priv, int *count) { @@ -313,7 +307,6 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, enum dpio_phy phy) { const struct bxt_ddi_phy_info *phy_info; - enum port port; phy_info = bxt_get_phy_info(dev_priv, phy); @@ -335,19 +328,6 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, return false; } - for_each_port_masked(port, bxt_phy_port_mask(phy_info)) { - u32 tmp = I915_READ(BXT_PHY_CTL(port)); - - if (tmp & BXT_PHY_CMNLANE_POWERDOWN_ACK) { - DRM_DEBUG_DRIVER("DDI PHY %d powered, but common lane " - "for port %c powered down " - "(PHY_CTL %08x)\n", - phy, port_name(port), tmp); - - return false; - } - } - return true; } -- cgit v1.2.3 From 63ba395cd7a52431cbb61658dad3beb5b24e9300 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Wed, 27 Sep 2017 23:31:03 +0200 Subject: rndis_host: support Novatel Verizon USB730L MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Treat the ef/04/01 interface class/subclass/protocol combination used by the Novatel Verizon USB730L (1410:9030) as a possible RNDIS interface. T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 17 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 3 P: Vendor=1410 ProdID=9030 Rev=03.10 S: Manufacturer=Novatel Wireless S: Product=MiFi USB730L S: SerialNumber=0123456789ABCDEF C: #Ifs= 3 Cfg#= 1 Atr=80 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host I: If#= 2 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid Once the network interface is brought up, the user just needs to run a DHCP client to get IP address and routing setup. As a side note, other Novatel Verizon USB730L models with the same vid:pid end up exposing a standard ECM interface which doesn't require any other kernel update to make it work. Signed-off-by: Aleksander Morgado Reviewed-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 11 ++++++++++- drivers/net/usb/rndis_host.c | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 677a85360db1..29c7e2ec0dcb 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -54,11 +54,19 @@ static int is_wireless_rndis(struct usb_interface_descriptor *desc) desc->bInterfaceProtocol == 3); } +static int is_novatel_rndis(struct usb_interface_descriptor *desc) +{ + return (desc->bInterfaceClass == USB_CLASS_MISC && + desc->bInterfaceSubClass == 4 && + desc->bInterfaceProtocol == 1); +} + #else #define is_rndis(desc) 0 #define is_activesync(desc) 0 #define is_wireless_rndis(desc) 0 +#define is_novatel_rndis(desc) 0 #endif @@ -150,7 +158,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) */ rndis = (is_rndis(&intf->cur_altsetting->desc) || is_activesync(&intf->cur_altsetting->desc) || - is_wireless_rndis(&intf->cur_altsetting->desc)); + is_wireless_rndis(&intf->cur_altsetting->desc) || + is_novatel_rndis(&intf->cur_altsetting->desc)); memset(info, 0, sizeof(*info)); info->control = intf; diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index a151f267aebb..b807c91abe1d 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -632,6 +632,10 @@ static const struct usb_device_id products [] = { /* RNDIS for tethering */ USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), .driver_info = (unsigned long) &rndis_info, +}, { + /* Novatel Verizon USB730L */ + USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1), + .driver_info = (unsigned long) &rndis_info, }, { }, // END }; -- cgit v1.2.3 From 6cd1a6fef7058de15405b13d6587538853279c7b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 3 Oct 2017 15:58:15 -0600 Subject: null_blk: change configfs dependency to select A recent commit made null_blk depend on configfs, which is kind of annoying since you now have to find this dependency and enable that as well. Discovered this since I no longer had null_blk available on a box I needed to debug, since it got killed when the config updated after the configfs change was merged. Fixes: 3bf2bd20734e ("nullb: add configfs interface") Reviewed-by: Shaohua Li Signed-off-by: Jens Axboe --- drivers/block/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 4a438b8abe27..2dfe99b328f8 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -17,7 +17,7 @@ if BLK_DEV config BLK_DEV_NULL_BLK tristate "Null test block driver" - depends on CONFIGFS_FS + select CONFIGFS_FS config BLK_DEV_FD tristate "Normal floppy disk support" -- cgit v1.2.3 From 05946876f0c16f6fe1db692d575aba42b25f0811 Mon Sep 17 00:00:00 2001 From: David Wu Date: Sat, 30 Sep 2017 17:47:23 +0800 Subject: net: stmmac: dwmac-rk: Add RK3128 GMAC support Add constants and callback functions for the dwmac on rk3128 soc. As can be seen, the base structure is the same, only registers and the bits in them moved slightly. Signed-off-by: David Wu Signed-off-by: David S. Miller --- .../devicetree/bindings/net/rockchip-dwmac.txt | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 112 +++++++++++++++++++++ 2 files changed, 113 insertions(+) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt index 6af8eed1adeb..9c16ee2965a2 100644 --- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt +++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt @@ -4,6 +4,7 @@ The device node has following properties. Required properties: - compatible: should be "rockchip,-gamc" + "rockchip,rk3128-gmac": found on RK312x SoCs "rockchip,rk3228-gmac": found on RK322x SoCs "rockchip,rk3288-gmac": found on RK3288 SoCs "rockchip,rk3328-gmac": found on RK3328 SoCs diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 99823f54696a..13133b30b575 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -83,6 +83,117 @@ struct rk_priv_data { (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) +#define RK3128_GRF_MAC_CON0 0x0168 +#define RK3128_GRF_MAC_CON1 0x016c + +/* RK3128_GRF_MAC_CON0 */ +#define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) +#define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) +#define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) +#define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) +#define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) +#define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) + +/* RK3128_GRF_MAC_CON1 */ +#define RK3128_GMAC_PHY_INTF_SEL_RGMII \ + (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8)) +#define RK3128_GMAC_PHY_INTF_SEL_RMII \ + (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8)) +#define RK3128_GMAC_FLOW_CTRL GRF_BIT(9) +#define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) +#define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10) +#define RK3128_GMAC_SPEED_100M GRF_BIT(10) +#define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11) +#define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) +#define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) +#define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) +#define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) +#define RK3128_GMAC_RMII_MODE GRF_BIT(14) +#define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) + +static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, + RK3128_GMAC_PHY_INTF_SEL_RGMII | + RK3128_GMAC_RMII_MODE_CLR); + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, + DELAY_ENABLE(RK3128, tx_delay, rx_delay) | + RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | + RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); +} + +static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, + RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); +} + +static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + if (speed == 10) + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, + RK3128_GMAC_CLK_2_5M); + else if (speed == 100) + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, + RK3128_GMAC_CLK_25M); + else if (speed == 1000) + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, + RK3128_GMAC_CLK_125M); + else + dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); +} + +static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "Missing rockchip,grf property\n"); + return; + } + + if (speed == 10) { + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, + RK3128_GMAC_RMII_CLK_2_5M | + RK3128_GMAC_SPEED_10M); + } else if (speed == 100) { + regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, + RK3128_GMAC_RMII_CLK_25M | + RK3128_GMAC_SPEED_100M); + } else { + dev_err(dev, "unknown speed value for RMII! speed=%d", speed); + } +} + +static const struct rk_gmac_ops rk3128_ops = { + .set_to_rgmii = rk3128_set_to_rgmii, + .set_to_rmii = rk3128_set_to_rmii, + .set_rgmii_speed = rk3128_set_rgmii_speed, + .set_rmii_speed = rk3128_set_rmii_speed, +}; + #define RK3228_GRF_MAC_CON0 0x0900 #define RK3228_GRF_MAC_CON1 0x0904 @@ -1313,6 +1424,7 @@ static int rk_gmac_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); static const struct of_device_id rk_gmac_dwmac_match[] = { + { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, -- cgit v1.2.3 From a1b2289cef92ef0e9a92afcd2e1ea71d5bcaaf64 Mon Sep 17 00:00:00 2001 From: Sherry Yang Date: Tue, 3 Oct 2017 16:15:00 -0700 Subject: android: binder: drop lru lock in isolate callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the global lru lock in isolate callback before calling zap_page_range which calls cond_resched, and re-acquire the global lru lock before returning. Also change return code to LRU_REMOVED_RETRY. Use mmput_async when fail to acquire mmap sem in an atomic context. Fix "BUG: sleeping function called from invalid context" errors when CONFIG_DEBUG_ATOMIC_SLEEP is enabled. Also restore mmput_async, which was initially introduced in commit ec8d7c14ea14 ("mm, oom_reaper: do not mmput synchronously from the oom reaper context"), and was removed in commit 212925802454 ("mm: oom: let oom_reap_task and exit_mmap run concurrently"). Link: http://lkml.kernel.org/r/20170914182231.90908-1-sherryy@android.com Fixes: f2517eb76f1f2 ("android: binder: Add global lru shrinker to binder") Signed-off-by: Sherry Yang Signed-off-by: Greg Kroah-Hartman Reported-by: Kyle Yan Acked-by: Arve Hjønnevåg Acked-by: Michal Hocko Cc: Martijn Coenen Cc: Todd Kjos Cc: Riley Andrews Cc: Ingo Molnar Cc: Vlastimil Babka Cc: Hillf Danton Cc: Peter Zijlstra Cc: Andrea Arcangeli Cc: Thomas Gleixner Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: Hoeun Ryu Cc: Christopher Lameter Cc: Vegard Nossum Cc: Frederic Weisbecker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/android/binder_alloc.c | 18 ++++++++++++------ include/linux/sched/mm.h | 6 ++++++ kernel/fork.c | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 8fe165844e47..064f5e31ec55 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -913,6 +913,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, struct binder_alloc *alloc; uintptr_t page_addr; size_t index; + struct vm_area_struct *vma; alloc = page->alloc; if (!mutex_trylock(&alloc->mutex)) @@ -923,16 +924,22 @@ enum lru_status binder_alloc_free_page(struct list_head *item, index = page - alloc->pages; page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; - if (alloc->vma) { + vma = alloc->vma; + if (vma) { mm = get_task_mm(alloc->tsk); if (!mm) goto err_get_task_mm_failed; if (!down_write_trylock(&mm->mmap_sem)) goto err_down_write_mmap_sem_failed; + } + + list_lru_isolate(lru, item); + spin_unlock(lock); + if (vma) { trace_binder_unmap_user_start(alloc, index); - zap_page_range(alloc->vma, + zap_page_range(vma, page_addr + alloc->user_buffer_offset, PAGE_SIZE); @@ -950,13 +957,12 @@ enum lru_status binder_alloc_free_page(struct list_head *item, trace_binder_unmap_kernel_end(alloc, index); - list_lru_isolate(lru, item); - + spin_lock(lock); mutex_unlock(&alloc->mutex); - return LRU_REMOVED; + return LRU_REMOVED_RETRY; err_down_write_mmap_sem_failed: - mmput(mm); + mmput_async(mm); err_get_task_mm_failed: err_page_already_freed: mutex_unlock(&alloc->mutex); diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 3a19c253bdb1..ae53e413fb13 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -84,6 +84,12 @@ static inline bool mmget_not_zero(struct mm_struct *mm) /* mmput gets rid of the mappings and all user-space */ extern void mmput(struct mm_struct *); +#ifdef CONFIG_MMU +/* same as above but performs the slow path from the async context. Can + * be called from the atomic context as well + */ +void mmput_async(struct mm_struct *); +#endif /* Grab a reference to a task's mm, if it is not already going away */ extern struct mm_struct *get_task_mm(struct task_struct *task); diff --git a/kernel/fork.c b/kernel/fork.c index 10646182440f..e702cb9ffbd8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -946,6 +946,24 @@ void mmput(struct mm_struct *mm) } EXPORT_SYMBOL_GPL(mmput); +#ifdef CONFIG_MMU +static void mmput_async_fn(struct work_struct *work) +{ + struct mm_struct *mm = container_of(work, struct mm_struct, + async_put_work); + + __mmput(mm); +} + +void mmput_async(struct mm_struct *mm) +{ + if (atomic_dec_and_test(&mm->mm_users)) { + INIT_WORK(&mm->async_put_work, mmput_async_fn); + schedule_work(&mm->async_put_work); + } +} +#endif + /** * set_mm_exe_file - change a reference to the mm's executable file * -- cgit v1.2.3 From 31d1e130f4a0f8f629a460167569577cac9b17c1 Mon Sep 17 00:00:00 2001 From: Ioan Nicu Date: Tue, 3 Oct 2017 16:15:13 -0700 Subject: rapidio: remove global irq spinlocks from the subsystem Locking of config and doorbell operations should be done only if the underlying hardware requires it. This patch removes the global spinlocks from the rapidio subsystem and moves them to the mport drivers (fsl_rio and tsi721), only to the necessary places. For example, local config space read and write operations (lcread/lcwrite) are atomic in all existing drivers, so there should be no need for locking, while the cread/cwrite operations which generate maintenance transactions need to be synchronized with a lock. Later, each driver could chose to use a per-port lock instead of a global one, or even more granular locking. Link: http://lkml.kernel.org/r/20170824113023.GD50104@nokia.com Signed-off-by: Ioan Nicu Signed-off-by: Frank Kunz Acked-by: Alexandre Bounine Cc: Matt Porter Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/sysdev/fsl_rio.c | 17 +++++++++++++++-- arch/powerpc/sysdev/fsl_rmu.c | 8 ++++++++ drivers/rapidio/devices/tsi721.c | 7 +++++++ drivers/rapidio/rio-access.c | 40 +++++----------------------------------- 4 files changed, 35 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 9234be1e66f5..5011ffea4e4b 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -71,6 +71,8 @@ #define RIWAR_WRTYP_ALLOC 0x00006000 #define RIWAR_SIZE_MASK 0x0000003F +static DEFINE_SPINLOCK(fsl_rio_config_lock); + #define __fsl_read_rio_config(x, addr, err, op) \ __asm__ __volatile__( \ "1: "op" %1,0(%2)\n" \ @@ -184,6 +186,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, u8 hopcount, u32 offset, int len, u32 *val) { struct rio_priv *priv = mport->priv; + unsigned long flags; u8 *data; u32 rval, err = 0; @@ -197,6 +200,8 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) return -EINVAL; + spin_lock_irqsave(&fsl_rio_config_lock, flags); + out_be32(&priv->maint_atmu_regs->rowtar, (destid << 22) | (hopcount << 12) | (offset >> 12)); out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -213,6 +218,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, __fsl_read_rio_config(rval, data, err, "lwz"); break; default: + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); return -EINVAL; } @@ -221,6 +227,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, err, destid, hopcount, offset); } + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); *val = rval; return err; @@ -244,7 +251,10 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, u8 hopcount, u32 offset, int len, u32 val) { struct rio_priv *priv = mport->priv; + unsigned long flags; u8 *data; + int ret = 0; + pr_debug ("fsl_rio_config_write:" " index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", @@ -255,6 +265,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) return -EINVAL; + spin_lock_irqsave(&fsl_rio_config_lock, flags); + out_be32(&priv->maint_atmu_regs->rowtar, (destid << 22) | (hopcount << 12) | (offset >> 12)); out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -271,10 +283,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, out_be32((u32 *) data, val); break; default: - return -EINVAL; + ret = -EINVAL; } + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); - return 0; + return ret; } static void fsl_rio_inbound_mem_init(struct rio_priv *priv) diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index ab7a74c75be8..88b35a3dcdc5 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -104,6 +104,8 @@ #define DOORBELL_MESSAGE_SIZE 0x08 +static DEFINE_SPINLOCK(fsl_rio_doorbell_lock); + struct rio_msg_regs { u32 omr; u32 osr; @@ -626,9 +628,13 @@ err_out: int fsl_rio_doorbell_send(struct rio_mport *mport, int index, u16 destid, u16 data) { + unsigned long flags; + pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n", index, destid, data); + spin_lock_irqsave(&fsl_rio_doorbell_lock, flags); + /* In the serial version silicons, such as MPC8548, MPC8641, * below operations is must be. */ @@ -638,6 +644,8 @@ int fsl_rio_doorbell_send(struct rio_mport *mport, out_be32(&dbell->dbell_regs->oddatr, (index << 20) | data); out_be32(&dbell->dbell_regs->odmr, 0x00000001); + spin_unlock_irqrestore(&fsl_rio_doorbell_lock, flags); + return 0; } diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 315a4be8dc1e..9a68914100ad 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c @@ -51,6 +51,8 @@ module_param(mbox_sel, byte, S_IRUGO); MODULE_PARM_DESC(mbox_sel, "RIO Messaging MBOX Selection Mask (default: 0x0f = all)"); +static DEFINE_SPINLOCK(tsi721_maint_lock); + static void tsi721_omsg_handler(struct tsi721_device *priv, int ch); static void tsi721_imsg_handler(struct tsi721_device *priv, int ch); @@ -124,12 +126,15 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size, void __iomem *regs = priv->regs + TSI721_DMAC_BASE(priv->mdma.ch_id); struct tsi721_dma_desc *bd_ptr; u32 rd_count, swr_ptr, ch_stat; + unsigned long flags; int i, err = 0; u32 op = do_wr ? MAINT_WR : MAINT_RD; if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32))) return -EINVAL; + spin_lock_irqsave(&tsi721_maint_lock, flags); + bd_ptr = priv->mdma.bd_base; rd_count = ioread32(regs + TSI721_DMAC_DRDCNT); @@ -197,7 +202,9 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size, */ swr_ptr = ioread32(regs + TSI721_DMAC_DSWP); iowrite32(swr_ptr, regs + TSI721_DMAC_DSRP); + err_out: + spin_unlock_irqrestore(&tsi721_maint_lock, flags); return err; } diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c index a3824baca2e5..3ee9af83b638 100644 --- a/drivers/rapidio/rio-access.c +++ b/drivers/rapidio/rio-access.c @@ -13,17 +13,9 @@ #include #include -/* - * These interrupt-safe spinlocks protect all accesses to RIO - * configuration space and doorbell access. - */ -static DEFINE_SPINLOCK(rio_config_lock); -static DEFINE_SPINLOCK(rio_doorbell_lock); - /* * Wrappers for all RIO configuration access functions. They just check - * alignment, do locking and call the low-level functions pointed to - * by rio_mport->ops. + * alignment and call the low-level functions pointed to by rio_mport->ops. */ #define RIO_8_BAD 0 @@ -44,13 +36,10 @@ int __rio_local_read_config_##size \ (struct rio_mport *mport, u32 offset, type *value) \ { \ int res; \ - unsigned long flags; \ u32 data = 0; \ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ - spin_lock_irqsave(&rio_config_lock, flags); \ res = mport->ops->lcread(mport, mport->id, offset, len, &data); \ *value = (type)data; \ - spin_unlock_irqrestore(&rio_config_lock, flags); \ return res; \ } @@ -67,13 +56,8 @@ int __rio_local_read_config_##size \ int __rio_local_write_config_##size \ (struct rio_mport *mport, u32 offset, type value) \ { \ - int res; \ - unsigned long flags; \ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ - spin_lock_irqsave(&rio_config_lock, flags); \ - res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\ - spin_unlock_irqrestore(&rio_config_lock, flags); \ - return res; \ + return mport->ops->lcwrite(mport, mport->id, offset, len, value);\ } RIO_LOP_READ(8, u8, 1) @@ -104,13 +88,10 @@ int rio_mport_read_config_##size \ (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \ { \ int res; \ - unsigned long flags; \ u32 data = 0; \ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ - spin_lock_irqsave(&rio_config_lock, flags); \ res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \ *value = (type)data; \ - spin_unlock_irqrestore(&rio_config_lock, flags); \ return res; \ } @@ -127,13 +108,9 @@ int rio_mport_read_config_##size \ int rio_mport_write_config_##size \ (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \ { \ - int res; \ - unsigned long flags; \ if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ - spin_lock_irqsave(&rio_config_lock, flags); \ - res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \ - spin_unlock_irqrestore(&rio_config_lock, flags); \ - return res; \ + return mport->ops->cwrite(mport, mport->id, destid, hopcount, \ + offset, len, value); \ } RIO_OP_READ(8, u8, 1) @@ -162,14 +139,7 @@ EXPORT_SYMBOL_GPL(rio_mport_write_config_32); */ int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data) { - int res; - unsigned long flags; - - spin_lock_irqsave(&rio_doorbell_lock, flags); - res = mport->ops->dsend(mport, mport->id, destid, data); - spin_unlock_irqrestore(&rio_doorbell_lock, flags); - - return res; + return mport->ops->dsend(mport, mport->id, destid, data); } EXPORT_SYMBOL_GPL(rio_mport_send_doorbell); -- cgit v1.2.3 From ae94264ed4b0cf7cd887947650db4c69acb62072 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Tue, 3 Oct 2017 16:15:19 -0700 Subject: zram: fix null dereference of handle In testing I found handle passed to zs_map_object in __zram_bvec_read is NULL so eh kernel goes oops in pin_object(). The reason is there is no routine to check the slot's freeing after getting the slot's lock. This patch fixes it. [minchan@kernel.org: v2] Link: http://lkml.kernel.org/r/1505887347-10881-1-git-send-email-minchan@kernel.org Link: http://lkml.kernel.org/r/1505788488-26723-1-git-send-email-minchan@kernel.org Fixes: 1f7319c74275 ("zram: partial IO refactoring") Signed-off-by: Minchan Kim Reviewed-by: Sergey Senozhatsky Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/zram/zram_drv.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 2981c27d3aae..f149d3e61234 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -766,27 +766,6 @@ static void zram_slot_unlock(struct zram *zram, u32 index) bit_spin_unlock(ZRAM_ACCESS, &zram->table[index].value); } -static bool zram_same_page_read(struct zram *zram, u32 index, - struct page *page, - unsigned int offset, unsigned int len) -{ - zram_slot_lock(zram, index); - if (unlikely(!zram_get_handle(zram, index) || - zram_test_flag(zram, index, ZRAM_SAME))) { - void *mem; - - zram_slot_unlock(zram, index); - mem = kmap_atomic(page); - zram_fill_page(mem + offset, len, - zram_get_element(zram, index)); - kunmap_atomic(mem); - return true; - } - zram_slot_unlock(zram, index); - - return false; -} - static void zram_meta_free(struct zram *zram, u64 disksize) { size_t num_pages = disksize >> PAGE_SHIFT; @@ -884,11 +863,20 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, zram_slot_unlock(zram, index); } - if (zram_same_page_read(zram, index, page, 0, PAGE_SIZE)) - return 0; - zram_slot_lock(zram, index); handle = zram_get_handle(zram, index); + if (!handle || zram_test_flag(zram, index, ZRAM_SAME)) { + unsigned long value; + void *mem; + + value = handle ? zram_get_element(zram, index) : 0; + mem = kmap_atomic(page); + zram_fill_page(mem, PAGE_SIZE, value); + kunmap_atomic(mem); + zram_slot_unlock(zram, index); + return 0; + } + size = zram_get_obj_size(zram, index); src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); -- cgit v1.2.3 From 3cf50c63a76177e0bbe0e46e1abe4eb263128ba4 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 19 Sep 2017 14:14:18 +0200 Subject: drm/i915: Unset legacy_cursor_update early in intel_atomic_commit, v3. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit b44d5c0c105a ("drm/i915: Always wait for flip_done, v2.") removed the call to wait_for_vblanks and replaced it with flip_done. Unfortunately legacy_cursor_update was unset too late, and the replacement call drm_atomic_helper_wait_for_flip_done() was a noop. Make sure that its unset before setup_commit() is called to fix this issue. Changes since v1: - Force vblank wait for watermarks not yet converted to atomic too. (Ville) - Use for_each_new_intel_crtc_in_state. (Ville) Changes since v2: - Move the optimization to a separate commit. (Ville) Signed-off-by: Maarten Lankhorst Fixes: b44d5c0c105a ("drm/i915: Always wait for flip_done, v2.") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102675 Testcase: kms_cursor_crc Cc: Daniel Vetter Cc: Jani Nikula Reported-by: Marta Löfstedt Cc: Marta Löfstedt Tested-by: Marta Löfstedt Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170919121419.13708-1-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b7a6ddc6a66d..e55f68cda755 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12541,21 +12541,10 @@ static int intel_atomic_commit(struct drm_device *dev, struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; - ret = drm_atomic_helper_setup_commit(state, nonblock); - if (ret) - return ret; - drm_atomic_state_get(state); i915_sw_fence_init(&intel_state->commit_ready, intel_atomic_commit_ready); - ret = intel_atomic_prepare_commit(dev, state); - if (ret) { - DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret); - i915_sw_fence_commit(&intel_state->commit_ready); - return ret; - } - /* * The intel_legacy_cursor_update() fast path takes care * of avoiding the vblank waits for simple cursor @@ -12564,11 +12553,11 @@ static int intel_atomic_commit(struct drm_device *dev, * updates happen during the correct frames. Gen9+ have * double buffered watermarks and so shouldn't need this. * - * Do this after drm_atomic_helper_setup_commit() and - * intel_atomic_prepare_commit() because we still want - * to skip the flip and fb cleanup waits. Although that - * does risk yanking the mapping from under the display - * engine. + * Unset state->legacy_cursor_update before the call to + * drm_atomic_helper_setup_commit() because otherwise + * drm_atomic_helper_wait_for_flip_done() is a noop and + * we get FIFO underruns because we didn't wait + * for vblank. * * FIXME doing watermarks and fb cleanup from a vblank worker * (assuming we had any) would solve these problems. @@ -12576,7 +12565,17 @@ static int intel_atomic_commit(struct drm_device *dev, if (INTEL_GEN(dev_priv) < 9) state->legacy_cursor_update = false; - ret = drm_atomic_helper_swap_state(state, true); + ret = intel_atomic_prepare_commit(dev, state); + if (ret) { + DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret); + i915_sw_fence_commit(&intel_state->commit_ready); + return ret; + } + + ret = drm_atomic_helper_setup_commit(state, nonblock); + if (!ret) + ret = drm_atomic_helper_swap_state(state, true); + if (ret) { i915_sw_fence_commit(&intel_state->commit_ready); -- cgit v1.2.3 From 213f1bd035edc36f8d68c028d1b79675cd167d1d Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 19 Sep 2017 14:14:19 +0200 Subject: drm/i915: Skip vblank waits for cursor updates when watermarks dont need updating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In legacy cursor updates we need the extra vblank waits if we update watermarks, and then we cannot skip the vblank for cursors. This is why for < gen9 we disabled the cursor fastpath, but we can skip the wait when post vblank watermarks are untouched. Signed-off-by: Maarten Lankhorst Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170919121419.13708-2-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e55f68cda755..cdb2e25a577c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12562,8 +12562,16 @@ static int intel_atomic_commit(struct drm_device *dev, * FIXME doing watermarks and fb cleanup from a vblank worker * (assuming we had any) would solve these problems. */ - if (INTEL_GEN(dev_priv) < 9) - state->legacy_cursor_update = false; + if (INTEL_GEN(dev_priv) < 9 && state->legacy_cursor_update) { + struct intel_crtc_state *new_crtc_state; + struct intel_crtc *crtc; + int i; + + for_each_new_intel_crtc_in_state(intel_state, crtc, new_crtc_state, i) + if (new_crtc_state->wm.need_postvbl_update || + new_crtc_state->update_wm_post) + state->legacy_cursor_update = false; + } ret = intel_atomic_prepare_commit(dev, state); if (ret) { -- cgit v1.2.3 From de3ee99b097dd51938276e3af388cd4ad0f2750a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 20 Sep 2017 10:56:14 +0200 Subject: mmc: Delete bounce buffer handling In may, Steven sent a patch deleting the bounce buffer handling and the CONFIG_MMC_BLOCK_BOUNCE option. I chose the less invasive path of making it a runtime config option, and we merged that successfully for kernel v4.12. The code is however just standing in the way and taking up space for seemingly no gain on any systems in wide use today. Pierre says the code was there to improve speed on TI SDHCI controllers on certain HP laptops and possibly some Ricoh controllers as well. Early SDHCI controllers lacked the scatter-gather feature, which made software bounce buffers a significant speed boost. We are clearly talking about the list of SDHCI PCI-based MMC/SD card readers found in the pci_ids[] list in drivers/mmc/host/sdhci-pci-core.c. The TI SDHCI derivative is not supported by the upstream kernel. This leaves the Ricoh. What we can however notice is that the x86 defconfigs in the kernel did not enable CONFIG_MMC_BLOCK_BOUNCE option, which means that any such laptop would have to have a custom configured kernel to actually take advantage of this bounce buffer speed-up. It simply seems like there was a speed optimization for the Ricoh controllers that noone was using. (I have not checked the distro defconfigs but I am pretty sure the situation is the same there.) Bounce buffers increased performance on the OMAP HSMMC at one point, and was part of the original submission in commit a45c6cb81647 ("[ARM] 5369/1: omap mmc: Add new omap hsmmc controller for 2430 and 34xx, v3") This optimization was removed in commit 0ccd76d4c236 ("omap_hsmmc: Implement scatter-gather emulation") which found that scatter-gather emulation provided even better performance. The same was introduced for SDHCI in commit 2134a922c6e7 ("sdhci: scatter-gather (ADMA) support") I am pretty positively convinced that software scatter-gather emulation will do for any host controller what the bounce buffers were doing. Essentially, the bounce buffer was a reimplementation of software scatter-gather-emulation in the MMC subsystem, and it should be done away with. Cc: Pierre Ossman Cc: Juha Yrjola Cc: Steven J. Hill Cc: Shawn Lin Cc: Adrian Hunter Suggested-by: Steven J. Hill Suggested-by: Shawn Lin Signed-off-by: Linus Walleij Signed-off-by: Ulf Hansson --- drivers/mmc/core/block.c | 3 -- drivers/mmc/core/queue.c | 125 ++++------------------------------------------ drivers/mmc/core/queue.h | 6 --- drivers/mmc/host/cavium.c | 2 +- drivers/mmc/host/pxamci.c | 6 +-- include/linux/mmc/host.h | 2 +- 6 files changed, 12 insertions(+), 132 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 29fc1e662891..2ad7b5c69156 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1634,8 +1634,6 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, } mqrq->areq.mrq = &brq->mrq; - - mmc_queue_bounce_pre(mqrq); } static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, @@ -1829,7 +1827,6 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) brq = &mq_rq->brq; old_req = mmc_queue_req_to_req(mq_rq); type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; - mmc_queue_bounce_post(mq_rq); switch (status) { case MMC_BLK_SUCCESS: diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 74c663b1c0a7..0a4e77a5ba33 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -23,8 +23,6 @@ #include "core.h" #include "card.h" -#define MMC_QUEUE_BOUNCESZ 65536 - /* * Prepare a MMC request. This just filters out odd stuff. */ @@ -150,26 +148,6 @@ static void mmc_queue_setup_discard(struct request_queue *q, queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); } -static unsigned int mmc_queue_calc_bouncesz(struct mmc_host *host) -{ - unsigned int bouncesz = MMC_QUEUE_BOUNCESZ; - - if (host->max_segs != 1 || (host->caps & MMC_CAP_NO_BOUNCE_BUFF)) - return 0; - - if (bouncesz > host->max_req_size) - bouncesz = host->max_req_size; - if (bouncesz > host->max_seg_size) - bouncesz = host->max_seg_size; - if (bouncesz > host->max_blk_count * 512) - bouncesz = host->max_blk_count * 512; - - if (bouncesz <= 512) - return 0; - - return bouncesz; -} - /** * mmc_init_request() - initialize the MMC-specific per-request data * @q: the request queue @@ -184,26 +162,9 @@ static int mmc_init_request(struct request_queue *q, struct request *req, struct mmc_card *card = mq->card; struct mmc_host *host = card->host; - if (card->bouncesz) { - mq_rq->bounce_buf = kmalloc(card->bouncesz, gfp); - if (!mq_rq->bounce_buf) - return -ENOMEM; - if (card->bouncesz > 512) { - mq_rq->sg = mmc_alloc_sg(1, gfp); - if (!mq_rq->sg) - return -ENOMEM; - mq_rq->bounce_sg = mmc_alloc_sg(card->bouncesz / 512, - gfp); - if (!mq_rq->bounce_sg) - return -ENOMEM; - } - } else { - mq_rq->bounce_buf = NULL; - mq_rq->bounce_sg = NULL; - mq_rq->sg = mmc_alloc_sg(host->max_segs, gfp); - if (!mq_rq->sg) - return -ENOMEM; - } + mq_rq->sg = mmc_alloc_sg(host->max_segs, gfp); + if (!mq_rq->sg) + return -ENOMEM; return 0; } @@ -212,13 +173,6 @@ static void mmc_exit_request(struct request_queue *q, struct request *req) { struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req); - /* It is OK to kfree(NULL) so this will be smooth */ - kfree(mq_rq->bounce_sg); - mq_rq->bounce_sg = NULL; - - kfree(mq_rq->bounce_buf); - mq_rq->bounce_buf = NULL; - kfree(mq_rq->sg); mq_rq->sg = NULL; } @@ -242,12 +196,6 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; - /* - * mmc_init_request() depends on card->bouncesz so it must be calculated - * before blk_init_allocated_queue() starts allocating requests. - */ - card->bouncesz = mmc_queue_calc_bouncesz(host); - mq->card = card; mq->queue = blk_alloc_queue(GFP_KERNEL); if (!mq->queue) @@ -271,17 +219,11 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, if (mmc_can_erase(card)) mmc_queue_setup_discard(mq->queue, card); - if (card->bouncesz) { - blk_queue_max_hw_sectors(mq->queue, card->bouncesz / 512); - blk_queue_max_segments(mq->queue, card->bouncesz / 512); - blk_queue_max_segment_size(mq->queue, card->bouncesz); - } else { - blk_queue_bounce_limit(mq->queue, limit); - blk_queue_max_hw_sectors(mq->queue, - min(host->max_blk_count, host->max_req_size / 512)); - blk_queue_max_segments(mq->queue, host->max_segs); - blk_queue_max_segment_size(mq->queue, host->max_seg_size); - } + blk_queue_bounce_limit(mq->queue, limit); + blk_queue_max_hw_sectors(mq->queue, + min(host->max_blk_count, host->max_req_size / 512)); + blk_queue_max_segments(mq->queue, host->max_segs); + blk_queue_max_segment_size(mq->queue, host->max_seg_size); sema_init(&mq->thread_sem, 1); @@ -370,56 +312,7 @@ void mmc_queue_resume(struct mmc_queue *mq) */ unsigned int mmc_queue_map_sg(struct mmc_queue *mq, struct mmc_queue_req *mqrq) { - unsigned int sg_len; - size_t buflen; - struct scatterlist *sg; struct request *req = mmc_queue_req_to_req(mqrq); - int i; - - if (!mqrq->bounce_buf) - return blk_rq_map_sg(mq->queue, req, mqrq->sg); - - sg_len = blk_rq_map_sg(mq->queue, req, mqrq->bounce_sg); - - mqrq->bounce_sg_len = sg_len; - - buflen = 0; - for_each_sg(mqrq->bounce_sg, sg, sg_len, i) - buflen += sg->length; - - sg_init_one(mqrq->sg, mqrq->bounce_buf, buflen); - - return 1; -} - -/* - * If writing, bounce the data to the buffer before the request - * is sent to the host driver - */ -void mmc_queue_bounce_pre(struct mmc_queue_req *mqrq) -{ - if (!mqrq->bounce_buf) - return; - - if (rq_data_dir(mmc_queue_req_to_req(mqrq)) != WRITE) - return; - - sg_copy_to_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, - mqrq->bounce_buf, mqrq->sg[0].length); -} - -/* - * If reading, bounce the data from the buffer after the request - * has been handled by the host driver - */ -void mmc_queue_bounce_post(struct mmc_queue_req *mqrq) -{ - if (!mqrq->bounce_buf) - return; - - if (rq_data_dir(mmc_queue_req_to_req(mqrq)) != READ) - return; - sg_copy_from_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, - mqrq->bounce_buf, mqrq->sg[0].length); + return blk_rq_map_sg(mq->queue, req, mqrq->sg); } diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index 04fc89360a7a..f18d3f656baa 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h @@ -49,9 +49,6 @@ enum mmc_drv_op { struct mmc_queue_req { struct mmc_blk_request brq; struct scatterlist *sg; - char *bounce_buf; - struct scatterlist *bounce_sg; - unsigned int bounce_sg_len; struct mmc_async_req areq; enum mmc_drv_op drv_op; int drv_op_result; @@ -81,11 +78,8 @@ extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, extern void mmc_cleanup_queue(struct mmc_queue *); extern void mmc_queue_suspend(struct mmc_queue *); extern void mmc_queue_resume(struct mmc_queue *); - extern unsigned int mmc_queue_map_sg(struct mmc_queue *, struct mmc_queue_req *); -extern void mmc_queue_bounce_pre(struct mmc_queue_req *); -extern void mmc_queue_bounce_post(struct mmc_queue_req *); extern int mmc_access_rpmb(struct mmc_queue *); diff --git a/drivers/mmc/host/cavium.c b/drivers/mmc/host/cavium.c index 27fb625cbcf3..fbd29f00fca0 100644 --- a/drivers/mmc/host/cavium.c +++ b/drivers/mmc/host/cavium.c @@ -1038,7 +1038,7 @@ int cvm_mmc_of_slot_probe(struct device *dev, struct cvm_mmc_host *host) */ mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_POWER_OFF_CARD | - MMC_CAP_3_3V_DDR | MMC_CAP_NO_BOUNCE_BUFF; + MMC_CAP_3_3V_DDR; if (host->use_sg) mmc->max_segs = 16; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 59ab194cb009..c763b404510f 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -702,11 +702,7 @@ static int pxamci_probe(struct platform_device *pdev) pxamci_init_ocr(host); - /* - * This architecture used to disable bounce buffers through its - * defconfig, now it is done at runtime as a host property. - */ - mmc->caps = MMC_CAP_NO_BOUNCE_BUFF; + mmc->caps = 0; host->cmdat = 0; if (!cpu_is_pxa25x()) { mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index f3f2d07feb2a..9a43763a68ad 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -316,7 +316,7 @@ struct mmc_host { #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ -#define MMC_CAP_NO_BOUNCE_BUFF (1 << 21) /* Disable bounce buffers on host */ +/* (1 << 21) is free for reuse */ #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ -- cgit v1.2.3 From f450f28e70a2378d9d6ded0932fe480055888cfa Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 22 Sep 2017 13:42:47 -0500 Subject: reset: socfpga: fix for 64-bit compilation The SoCFPGA Stratix10 reset controller has 32-bit registers. Thus, we cannot use BITS_PER_LONG in computing the register and bit offset. Instead, we should be using the width of the hardware register for the calculation. Signed-off-by: Dinh Nguyen Signed-off-by: Philipp Zabel --- drivers/reset/reset-socfpga.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index c60904ff40b8..3907bbc9c6cf 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -40,8 +40,9 @@ static int socfpga_reset_assert(struct reset_controller_dev *rcdev, struct socfpga_reset_data *data = container_of(rcdev, struct socfpga_reset_data, rcdev); - int bank = id / BITS_PER_LONG; - int offset = id % BITS_PER_LONG; + int reg_width = sizeof(u32); + int bank = id / (reg_width * BITS_PER_BYTE); + int offset = id % (reg_width * BITS_PER_BYTE); unsigned long flags; u32 reg; @@ -61,8 +62,9 @@ static int socfpga_reset_deassert(struct reset_controller_dev *rcdev, struct socfpga_reset_data, rcdev); - int bank = id / BITS_PER_LONG; - int offset = id % BITS_PER_LONG; + int reg_width = sizeof(u32); + int bank = id / (reg_width * BITS_PER_BYTE); + int offset = id % (reg_width * BITS_PER_BYTE); unsigned long flags; u32 reg; @@ -81,8 +83,9 @@ static int socfpga_reset_status(struct reset_controller_dev *rcdev, { struct socfpga_reset_data *data = container_of(rcdev, struct socfpga_reset_data, rcdev); - int bank = id / BITS_PER_LONG; - int offset = id % BITS_PER_LONG; + int reg_width = sizeof(u32); + int bank = id / (reg_width * BITS_PER_BYTE); + int offset = id % (reg_width * BITS_PER_BYTE); u32 reg; reg = readl(data->membase + (bank * BANK_INCREMENT)); @@ -132,7 +135,7 @@ static int socfpga_reset_probe(struct platform_device *pdev) spin_lock_init(&data->lock); data->rcdev.owner = THIS_MODULE; - data->rcdev.nr_resets = NR_BANKS * BITS_PER_LONG; + data->rcdev.nr_resets = NR_BANKS * (sizeof(u32) * BITS_PER_BYTE); data->rcdev.ops = &socfpga_reset_ops; data->rcdev.of_node = pdev->dev.of_node; -- cgit v1.2.3 From 57522c4c87de20d8f7ad4e142a3a4334066d55ff Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 3 Oct 2017 12:51:58 +0300 Subject: drm/i915/cnl: Reprogram DMC firmware after S3/S4 resume The DMC firmware program memory is lost after S3/S4 system suspend, so we need to reprogram it during resume. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103070 Fixes: cebfcead63de ("drm/i915/DMC/CNL: Load DMC on CNL") Cc: Anusha Srivatsa Cc: Animesh Manna Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171003095159.711-1-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_runtime_pm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 7933d1bc6a1c..3791c3f5f56d 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -2809,6 +2809,9 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume /* 6. Enable DBUF */ gen9_dbuf_enable(dev_priv); + + if (resume && dev_priv->csr.dmc_payload) + intel_csr_load_program(dev_priv); } static void cnl_display_core_uninit(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From b7208a3f3e52791571df064fb96025ad48edd1bf Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 3 Oct 2017 12:51:59 +0300 Subject: drm/i915/glk: Fix DMC/DC state idleness calculation According to BSpec GLK like BXT needs to ignore the idle state of cores before starting the DMC firmware's DC state handler. Fixes: dbb28b5c3d3c ("drm/i915/DMC/GLK: Load DMC on GLK") Cc: Anusha Srivatsa Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171003095159.711-2-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_csr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index cdfb624eb82d..ea5d5c9645a4 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -216,7 +216,7 @@ static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) mask = DC_STATE_DEBUG_MASK_MEMORY_UP; - if (IS_BROXTON(dev_priv)) + if (IS_GEN9_LP(dev_priv)) mask |= DC_STATE_DEBUG_MASK_CORES; /* The below bit doesn't need to be cleared ever afterwards */ -- cgit v1.2.3 From ca3dcd3ff5b13a31a09a0119dc484b97ec19c4c8 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 2 Oct 2017 14:27:41 +0200 Subject: mmc: meson-gx: make sure the clock is rounded down Using CLK_DIVIDER_ROUND_CLOSEST is unsafe as the mmc clock could be rounded to a rate higher the specified rate. Removing this flag ensure that, if the rate needs to be rounded, it will be rounded down. Fixes: 51c5d8447bd7 ("MMC: meson: initial support for GX platforms") Signed-off-by: Jerome Brunet Reviewed-by: Kevin Hilman Signed-off-by: Ulf Hansson --- drivers/mmc/host/meson-gx-mmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index c885c2d4b904..421c8719c202 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -531,8 +531,7 @@ static int meson_mmc_clk_init(struct meson_host *host) div->shift = __ffs(CLK_DIV_MASK); div->width = __builtin_popcountl(CLK_DIV_MASK); div->hw.init = &init; - div->flags = (CLK_DIVIDER_ONE_BASED | - CLK_DIVIDER_ROUND_CLOSEST); + div->flags = CLK_DIVIDER_ONE_BASED; clk = devm_clk_register(host->dev, &div->hw); if (WARN_ON(IS_ERR(clk))) -- cgit v1.2.3 From 3e2b0af411d4bf85bc0fbc385756fd5968adb9fd Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 2 Oct 2017 14:27:42 +0200 Subject: mmc: meson-gx: fix rx phase reset Resetting the phase when POWER_ON is set the set_ios() call means that the phase is reset almost every time the set_ios() is called, while the expected behavior was to reset the phase on a power cycle. This had gone unnoticed until now because in all mode (except hs400) the tuning is done after the last to set_ios(). In such case, the tuning result is used anyway. In HS400, there are a few calls to set_ios() after the tuning is done, overwriting the tuning result. Resetting the phase on POWER_UP instead of POWER_ON solve the problem. Fixes: d341ca88eead ("mmc: meson-gx: rework tuning function") Signed-off-by: Jerome Brunet Reviewed-by: Kevin Hilman Signed-off-by: Ulf Hansson --- drivers/mmc/host/meson-gx-mmc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 421c8719c202..08a55c2e96e1 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -745,6 +745,10 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) case MMC_POWER_UP: if (!IS_ERR(mmc->supply.vmmc)) mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); + + /* Reset rx phase */ + clk_set_phase(host->rx_clk, 0); + break; case MMC_POWER_ON: @@ -758,8 +762,6 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->vqmmc_enabled = true; } - /* Reset rx phase */ - clk_set_phase(host->rx_clk, 0); break; } -- cgit v1.2.3 From 0a44697627d17a66d7dc98f17aeca07ca79c5c20 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 2 Oct 2017 14:27:43 +0200 Subject: mmc: meson-gx: include tx phase in the tuning process It has been reported that some platforms (odroid-c2) may require a different tx phase setting to operate at high speed (hs200 and hs400) To improve the situation, this patch includes tx phase in the tuning process. Fixes: d341ca88eead ("mmc: meson-gx: rework tuning function") Reported-by: Heiner Kallweit Signed-off-by: Jerome Brunet Reviewed-by: Kevin Hilman Signed-off-by: Ulf Hansson --- drivers/mmc/host/meson-gx-mmc.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 08a55c2e96e1..85745ef179e2 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -716,6 +716,22 @@ static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct meson_host *host = mmc_priv(mmc); + int ret; + + /* + * If this is the initial tuning, try to get a sane Rx starting + * phase before doing the actual tuning. + */ + if (!mmc->doing_retune) { + ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); + + if (ret) + return ret; + } + + ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->tx_clk); + if (ret) + return ret; return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); } @@ -746,8 +762,9 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!IS_ERR(mmc->supply.vmmc)) mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); - /* Reset rx phase */ + /* Reset phases */ clk_set_phase(host->rx_clk, 0); + clk_set_phase(host->tx_clk, 270); break; -- cgit v1.2.3 From bb16ea1742c8f35a9349b7508dc45d3a922db5f5 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 2 Oct 2017 16:58:52 +0200 Subject: mmc: sdhci-xenon: Fix clock resource by adding an optional bus clock On Armada 7K/8K we need to explicitly enable the bus clock. The bus clock is optional because not all the SoCs need them but at least for Armada 7K/8K it is actually mandatory. The binding documentation is updating accordingly. Without this patch the kernel hand during boot if the mvpp2.2 network driver was not present in the kernel. Indeed the clock needed by the xenon controller was set by the network driver. Fixes: 3a3748dba881 ("mmc: sdhci-xenon: Add Marvell Xenon SDHC core functionality)" CC: Stable Tested-by: Zhoujie Wu Signed-off-by: Gregory CLEMENT Signed-off-by: Ulf Hansson --- .../bindings/mmc/marvell,xenon-sdhci.txt | 12 ++++++----- drivers/mmc/host/sdhci-xenon.c | 24 ++++++++++++++++++---- drivers/mmc/host/sdhci-xenon.h | 1 + 3 files changed, 28 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt index b878a1e305af..ed1456f5c94d 100644 --- a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt @@ -16,11 +16,13 @@ Required Properties: - clocks: Array of clocks required for SDHC. - Require at least input clock for Xenon IP core. + Require at least input clock for Xenon IP core. For Armada AP806 and + CP110, the AXI clock is also mandatory. - clock-names: Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core". + The input clock for the AXI bus must be named as "axi". - reg: * For "marvell,armada-3700-sdhci", two register areas. @@ -106,8 +108,8 @@ Example: compatible = "marvell,armada-ap806-sdhci"; reg = <0xaa0000 0x1000>; interrupts = - clocks = <&emmc_clk>; - clock-names = "core"; + clocks = <&emmc_clk>,<&axi_clk>; + clock-names = "core", "axi"; bus-width = <4>; marvell,xenon-phy-slow-mode; marvell,xenon-tun-count = <11>; @@ -126,8 +128,8 @@ Example: interrupts = vqmmc-supply = <&sd_vqmmc_regulator>; vmmc-supply = <&sd_vmmc_regulator>; - clocks = <&sdclk>; - clock-names = "core"; + clocks = <&sdclk>, <&axi_clk>; + clock-names = "core", "axi"; bus-width = <4>; marvell,xenon-tun-count = <9>; }; diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c index 2eec2e652c53..0842bbc2d7ad 100644 --- a/drivers/mmc/host/sdhci-xenon.c +++ b/drivers/mmc/host/sdhci-xenon.c @@ -466,6 +466,7 @@ static int xenon_probe(struct platform_device *pdev) { struct sdhci_pltfm_host *pltfm_host; struct sdhci_host *host; + struct xenon_priv *priv; int err; host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata, @@ -474,6 +475,7 @@ static int xenon_probe(struct platform_device *pdev) return PTR_ERR(host); pltfm_host = sdhci_priv(host); + priv = sdhci_pltfm_priv(pltfm_host); /* * Link Xenon specific mmc_host_ops function, @@ -491,9 +493,20 @@ static int xenon_probe(struct platform_device *pdev) if (err) goto free_pltfm; + priv->axi_clk = devm_clk_get(&pdev->dev, "axi"); + if (IS_ERR(priv->axi_clk)) { + err = PTR_ERR(priv->axi_clk); + if (err == -EPROBE_DEFER) + goto err_clk; + } else { + err = clk_prepare_enable(priv->axi_clk); + if (err) + goto err_clk; + } + err = mmc_of_parse(host->mmc); if (err) - goto err_clk; + goto err_clk_axi; sdhci_get_of_property(pdev); @@ -502,11 +515,11 @@ static int xenon_probe(struct platform_device *pdev) /* Xenon specific dt parse */ err = xenon_probe_dt(pdev); if (err) - goto err_clk; + goto err_clk_axi; err = xenon_sdhc_prepare(host); if (err) - goto err_clk; + goto err_clk_axi; pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); @@ -527,6 +540,8 @@ remove_sdhc: pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); xenon_sdhc_unprepare(host); +err_clk_axi: + clk_disable_unprepare(priv->axi_clk); err_clk: clk_disable_unprepare(pltfm_host->clk); free_pltfm: @@ -538,6 +553,7 @@ static int xenon_remove(struct platform_device *pdev) { struct sdhci_host *host = platform_get_drvdata(pdev); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -546,7 +562,7 @@ static int xenon_remove(struct platform_device *pdev) sdhci_remove_host(host, 0); xenon_sdhc_unprepare(host); - + clk_disable_unprepare(priv->axi_clk); clk_disable_unprepare(pltfm_host->clk); sdhci_pltfm_free(pdev); diff --git a/drivers/mmc/host/sdhci-xenon.h b/drivers/mmc/host/sdhci-xenon.h index 2bc0510c0769..9994995c7c56 100644 --- a/drivers/mmc/host/sdhci-xenon.h +++ b/drivers/mmc/host/sdhci-xenon.h @@ -83,6 +83,7 @@ struct xenon_priv { unsigned char bus_width; unsigned char timing; unsigned int clock; + struct clk *axi_clk; int phy_type; /* -- cgit v1.2.3 From b42dc0635bf0a6aa59fe4d7c826796ff659908c7 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 26 Sep 2017 09:18:27 +0300 Subject: mei: always use domain runtime pm callbacks. This patch fixes a regression caused by the new changes in the "run wake" handlers. The mei devices that support D0i3 are no longer receiving an interrupt after entering runtime suspend state and will stall. pci_dev_run_wake function now returns "true" for some devices (including mei) for which it used to return "false", arguably incorrectly as "run wake" used to mean that wakeup signals can be generated for a device in the working state of the system, so it could not be enabled or disabled before too. MEI maps runtime suspend/resume to its own defined power gating (PG) states, (D0i3 or other depending on generation), hence we need to go around the native PCI runtime service which eventually brings the device into D3cold/hot state, but the mei devices cannot wake up from D3 unlike from D0i3/PG state, which keeps irq running. To get around PCI device native runtime pm, MEI uses runtime pm domain handlers which take precedence. Cc: #4.13+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Acked-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/pci-me.c | 21 +++++++++++---------- drivers/misc/mei/pci-txe.c | 30 +++++++++++------------------- 2 files changed, 22 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 4ff40d319676..630757a4b36a 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -226,12 +226,15 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME; /* - * For not wake-able HW runtime pm framework - * can't be used on pci device level. - * Use domain runtime pm callbacks instead. - */ - if (!pci_dev_run_wake(pdev)) - mei_me_set_pm_domain(dev); + * ME maps runtime suspend/resume to D0i states, + * hence we need to go around native PCI runtime service which + * eventually brings the device into D3cold/hot state, + * but the mei device cannot wake up from D3 unlike from D0i3. + * To get around the PCI device native runtime pm, + * ME uses runtime pm domain handlers which take precedence + * over the driver's pm handlers. + */ + mei_me_set_pm_domain(dev); if (mei_pg_is_enabled(dev)) pm_runtime_put_noidle(&pdev->dev); @@ -271,8 +274,7 @@ static void mei_me_shutdown(struct pci_dev *pdev) dev_dbg(&pdev->dev, "shutdown\n"); mei_stop(dev); - if (!pci_dev_run_wake(pdev)) - mei_me_unset_pm_domain(dev); + mei_me_unset_pm_domain(dev); mei_disable_interrupts(dev); free_irq(pdev->irq, dev); @@ -300,8 +302,7 @@ static void mei_me_remove(struct pci_dev *pdev) dev_dbg(&pdev->dev, "stop\n"); mei_stop(dev); - if (!pci_dev_run_wake(pdev)) - mei_me_unset_pm_domain(dev); + mei_me_unset_pm_domain(dev); mei_disable_interrupts(dev); diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index e38a5f144373..0566f9bfa7de 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -144,12 +144,14 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME; /* - * For not wake-able HW runtime pm framework - * can't be used on pci device level. - * Use domain runtime pm callbacks instead. - */ - if (!pci_dev_run_wake(pdev)) - mei_txe_set_pm_domain(dev); + * TXE maps runtime suspend/resume to own power gating states, + * hence we need to go around native PCI runtime service which + * eventually brings the device into D3cold/hot state. + * But the TXE device cannot wake up from D3 unlike from own + * power gating. To get around PCI device native runtime pm, + * TXE uses runtime pm domain handlers which take precedence. + */ + mei_txe_set_pm_domain(dev); pm_runtime_put_noidle(&pdev->dev); @@ -186,8 +188,7 @@ static void mei_txe_shutdown(struct pci_dev *pdev) dev_dbg(&pdev->dev, "shutdown\n"); mei_stop(dev); - if (!pci_dev_run_wake(pdev)) - mei_txe_unset_pm_domain(dev); + mei_txe_unset_pm_domain(dev); mei_disable_interrupts(dev); free_irq(pdev->irq, dev); @@ -215,8 +216,7 @@ static void mei_txe_remove(struct pci_dev *pdev) mei_stop(dev); - if (!pci_dev_run_wake(pdev)) - mei_txe_unset_pm_domain(dev); + mei_txe_unset_pm_domain(dev); mei_disable_interrupts(dev); free_irq(pdev->irq, dev); @@ -318,15 +318,7 @@ static int mei_txe_pm_runtime_suspend(struct device *device) else ret = -EAGAIN; - /* - * If everything is okay we're about to enter PCI low - * power state (D3) therefor we need to disable the - * interrupts towards host. - * However if device is not wakeable we do not enter - * D-low state and we need to keep the interrupt kicking - */ - if (!ret && pci_dev_run_wake(pdev)) - mei_disable_interrupts(dev); + /* keep irq on we are staying in D0 */ dev_dbg(&pdev->dev, "rpm: txe: runtime suspend ret=%d\n", ret); -- cgit v1.2.3 From 688cb67839e852740d22cf763e5eafb27d5a6e53 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 24 Sep 2017 11:35:34 +0300 Subject: mei: me: add gemini lake devices id Add Gemini Lake (GLK) device id. Signed-off-by: Tomas Winkler Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me-regs.h | 2 ++ drivers/misc/mei/pci-me.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index c8307e8b4c16..0ccccbaf530d 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -127,6 +127,8 @@ #define MEI_DEV_ID_BXT_M 0x1A9A /* Broxton M */ #define MEI_DEV_ID_APL_I 0x5A9A /* Apollo Lake I */ +#define MEI_DEV_ID_GLK 0x319A /* Gemini Lake */ + #define MEI_DEV_ID_KBP 0xA2BA /* Kaby Point */ #define MEI_DEV_ID_KBP_2 0xA2BB /* Kaby Point 2 */ diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 630757a4b36a..78b3172c8e6e 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -93,6 +93,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, MEI_ME_PCH8_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_GLK, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)}, -- cgit v1.2.3 From 192b2d78722ffea188e5ec6ae5d55010dce05a4b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 29 Sep 2017 21:09:36 -0700 Subject: Drivers: hv: vmbus: Fix bugs in rescind handling This patch addresses the following bugs in the current rescind handling code: 1. Fixes a race condition where we may be invoking hv_process_channel_removal() on an already freed channel. 2. Prevents indefinite wait when rescinding sub-channels by correctly setting the probe_complete state. I would like to thank Dexuan for patiently reviewing earlier versions of this patch and identifying many of the issues fixed here. Greg, please apply this to 4.14-final. Fixes: '54a66265d675 ("Drivers: hv: vmbus: Fix rescind handling")' Signed-off-by: K. Y. Srinivasan Reviewed-by: Dexuan Cui Cc: stable@vger.kernel.org # (4.13 and above) Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 6 +++--- drivers/hv/channel_mgmt.c | 37 ++++++++++++++++++------------------- drivers/hv/vmbus_drv.c | 3 +-- include/linux/hyperv.h | 2 +- 4 files changed, 23 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index efd5db743319..894b67ac2cae 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -640,6 +640,7 @@ void vmbus_close(struct vmbus_channel *channel) */ return; } + mutex_lock(&vmbus_connection.channel_mutex); /* * Close all the sub-channels first and then close the * primary channel. @@ -648,16 +649,15 @@ void vmbus_close(struct vmbus_channel *channel) cur_channel = list_entry(cur, struct vmbus_channel, sc_list); vmbus_close_internal(cur_channel); if (cur_channel->rescind) { - mutex_lock(&vmbus_connection.channel_mutex); - hv_process_channel_removal(cur_channel, + hv_process_channel_removal( cur_channel->offermsg.child_relid); - mutex_unlock(&vmbus_connection.channel_mutex); } } /* * Now close the primary. */ vmbus_close_internal(channel); + mutex_unlock(&vmbus_connection.channel_mutex); } EXPORT_SYMBOL_GPL(vmbus_close); diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index bcbb031f7263..018d2e0f8ec5 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -159,7 +159,7 @@ static void vmbus_rescind_cleanup(struct vmbus_channel *channel) spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - + channel->rescind = true; list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, msglistentry) { @@ -381,14 +381,21 @@ static void vmbus_release_relid(u32 relid) true); } -void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) +void hv_process_channel_removal(u32 relid) { unsigned long flags; - struct vmbus_channel *primary_channel; + struct vmbus_channel *primary_channel, *channel; - BUG_ON(!channel->rescind); BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); + /* + * Make sure channel is valid as we may have raced. + */ + channel = relid2channel(relid); + if (!channel) + return; + + BUG_ON(!channel->rescind); if (channel->target_cpu != get_cpu()) { put_cpu(); smp_call_function_single(channel->target_cpu, @@ -515,6 +522,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) if (!fnew) { if (channel->sc_creation_callback != NULL) channel->sc_creation_callback(newchannel); + newchannel->probe_done = true; return; } @@ -834,7 +842,6 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) { struct vmbus_channel_rescind_offer *rescind; struct vmbus_channel *channel; - unsigned long flags; struct device *dev; rescind = (struct vmbus_channel_rescind_offer *)hdr; @@ -873,16 +880,6 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) return; } - spin_lock_irqsave(&channel->lock, flags); - channel->rescind = true; - spin_unlock_irqrestore(&channel->lock, flags); - - /* - * Now that we have posted the rescind state, perform - * rescind related cleanup. - */ - vmbus_rescind_cleanup(channel); - /* * Now wait for offer handling to complete. */ @@ -901,6 +898,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) if (channel->device_obj) { if (channel->chn_rescind_callback) { channel->chn_rescind_callback(channel); + vmbus_rescind_cleanup(channel); return; } /* @@ -909,6 +907,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) */ dev = get_device(&channel->device_obj->device); if (dev) { + vmbus_rescind_cleanup(channel); vmbus_device_unregister(channel->device_obj); put_device(dev); } @@ -921,16 +920,16 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) * 1. Close all sub-channels first * 2. Then close the primary channel. */ + mutex_lock(&vmbus_connection.channel_mutex); + vmbus_rescind_cleanup(channel); if (channel->state == CHANNEL_OPEN_STATE) { /* * The channel is currently not open; * it is safe for us to cleanup the channel. */ - mutex_lock(&vmbus_connection.channel_mutex); - hv_process_channel_removal(channel, - channel->offermsg.child_relid); - mutex_unlock(&vmbus_connection.channel_mutex); + hv_process_channel_removal(rescind->child_relid); } + mutex_unlock(&vmbus_connection.channel_mutex); } } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index a9d49f6f6501..937801ac2fe0 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -768,8 +768,7 @@ static void vmbus_device_release(struct device *device) struct vmbus_channel *channel = hv_dev->channel; mutex_lock(&vmbus_connection.channel_mutex); - hv_process_channel_removal(channel, - channel->offermsg.child_relid); + hv_process_channel_removal(channel->offermsg.child_relid); mutex_unlock(&vmbus_connection.channel_mutex); kfree(hv_dev); diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index c458d7b7ad19..6431087816ba 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1403,7 +1403,7 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf, const int *srv_version, int srv_vercnt, int *nego_fw_version, int *nego_srv_version); -void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); +void hv_process_channel_removal(u32 relid); void vmbus_setevent(struct vmbus_channel *channel); /* -- cgit v1.2.3 From 512cf465ee01eb23936a9e6ed0b6414eccb00853 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Fri, 29 Sep 2017 15:39:49 -0700 Subject: binder: fix use-after-free in binder_transaction() User-space normally keeps the node alive when creating a transaction since it has a reference to the target. The local strong ref keeps it alive if the sending process dies before the target process processes the transaction. If the source process is malicious or has a reference counting bug, this can fail. In this case, when we attempt to decrement the node in the failure path, the node has already been freed. This is fixed by taking a tmpref on the node while constructing the transaction. To avoid re-acquiring the node lock and inner proc lock to increment the proc's tmpref, a helper is used that does the ref increments on both the node and proc. Signed-off-by: Todd Kjos Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 93 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index ab34239a76ee..0621a95b8597 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2582,6 +2582,48 @@ static bool binder_proc_transaction(struct binder_transaction *t, return true; } +/** + * binder_get_node_refs_for_txn() - Get required refs on node for txn + * @node: struct binder_node for which to get refs + * @proc: returns @node->proc if valid + * @error: if no @proc then returns BR_DEAD_REPLY + * + * User-space normally keeps the node alive when creating a transaction + * since it has a reference to the target. The local strong ref keeps it + * alive if the sending process dies before the target process processes + * the transaction. If the source process is malicious or has a reference + * counting bug, relying on the local strong ref can fail. + * + * Since user-space can cause the local strong ref to go away, we also take + * a tmpref on the node to ensure it survives while we are constructing + * the transaction. We also need a tmpref on the proc while we are + * constructing the transaction, so we take that here as well. + * + * Return: The target_node with refs taken or NULL if no @node->proc is NULL. + * Also sets @proc if valid. If the @node->proc is NULL indicating that the + * target proc has died, @error is set to BR_DEAD_REPLY + */ +static struct binder_node *binder_get_node_refs_for_txn( + struct binder_node *node, + struct binder_proc **procp, + uint32_t *error) +{ + struct binder_node *target_node = NULL; + + binder_node_inner_lock(node); + if (node->proc) { + target_node = node; + binder_inc_node_nilocked(node, 1, 0, NULL); + binder_inc_node_tmpref_ilocked(node); + node->proc->tmp_ref++; + *procp = node->proc; + } else + *error = BR_DEAD_REPLY; + binder_node_inner_unlock(node); + + return target_node; +} + static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply, @@ -2685,43 +2727,35 @@ static void binder_transaction(struct binder_proc *proc, ref = binder_get_ref_olocked(proc, tr->target.handle, true); if (ref) { - binder_inc_node(ref->node, 1, 0, NULL); - target_node = ref->node; - } - binder_proc_unlock(proc); - if (target_node == NULL) { + target_node = binder_get_node_refs_for_txn( + ref->node, &target_proc, + &return_error); + } else { binder_user_error("%d:%d got transaction to invalid handle\n", - proc->pid, thread->pid); + proc->pid, thread->pid); return_error = BR_FAILED_REPLY; - return_error_param = -EINVAL; - return_error_line = __LINE__; - goto err_invalid_target_handle; } + binder_proc_unlock(proc); } else { mutex_lock(&context->context_mgr_node_lock); target_node = context->binder_context_mgr_node; - if (target_node == NULL) { + if (target_node) + target_node = binder_get_node_refs_for_txn( + target_node, &target_proc, + &return_error); + else return_error = BR_DEAD_REPLY; - mutex_unlock(&context->context_mgr_node_lock); - return_error_line = __LINE__; - goto err_no_context_mgr_node; - } - binder_inc_node(target_node, 1, 0, NULL); mutex_unlock(&context->context_mgr_node_lock); } - e->to_node = target_node->debug_id; - binder_node_lock(target_node); - target_proc = target_node->proc; - if (target_proc == NULL) { - binder_node_unlock(target_node); - return_error = BR_DEAD_REPLY; + if (!target_node) { + /* + * return_error is set above + */ + return_error_param = -EINVAL; return_error_line = __LINE__; goto err_dead_binder; } - binder_inner_proc_lock(target_proc); - target_proc->tmp_ref++; - binder_inner_proc_unlock(target_proc); - binder_node_unlock(target_node); + e->to_node = target_node->debug_id; if (security_binder_transaction(proc->tsk, target_proc->tsk) < 0) { return_error = BR_FAILED_REPLY; @@ -3071,6 +3105,8 @@ static void binder_transaction(struct binder_proc *proc, if (target_thread) binder_thread_dec_tmpref(target_thread); binder_proc_dec_tmpref(target_proc); + if (target_node) + binder_dec_node_tmpref(target_node); /* * write barrier to synchronize with initialization * of log entry @@ -3090,6 +3126,8 @@ err_bad_parent: err_copy_data_failed: trace_binder_transaction_failed_buffer_release(t->buffer); binder_transaction_buffer_release(target_proc, t->buffer, offp); + if (target_node) + binder_dec_node_tmpref(target_node); target_node = NULL; t->buffer->transaction = NULL; binder_alloc_free_buf(&target_proc->alloc, t->buffer); @@ -3104,13 +3142,14 @@ err_bad_call_stack: err_empty_call_stack: err_dead_binder: err_invalid_target_handle: -err_no_context_mgr_node: if (target_thread) binder_thread_dec_tmpref(target_thread); if (target_proc) binder_proc_dec_tmpref(target_proc); - if (target_node) + if (target_node) { binder_dec_node(target_node, 1, 0); + binder_dec_node_tmpref(target_node); + } binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, "%d:%d transaction failed %d/%d, size %lld-%lld line %d\n", -- cgit v1.2.3 From 8969f1f8291762c13147c1ba89d46238af01675b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 1 Oct 2017 09:37:35 +0200 Subject: nvme-pci: Use PCI bus address for data/queues in CMB Currently, NVMe PCI host driver is programming CMB dma address as I/O SQs addresses. This results in failures on systems where 1:1 outbound mapping is not used (example Broadcom iProc SOCs) because CMB BAR will be progammed with PCI bus address but NVMe PCI EP will try to access CMB using dma address. To have CMB working on systems without 1:1 outbound mapping, we program PCI bus address for I/O SQs instead of dma address. This approach will work on systems with/without 1:1 outbound mapping. Based on a report and previous patch from Abhishek Shah. Fixes: 8ffaadf7 ("NVMe: Use CMB for the IO SQes if available") Cc: stable@vger.kernel.org Reported-by: Abhishek Shah Tested-by: Abhishek Shah Reviewed-by: Keith Busch Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index cb73bc8cad3b..3f5a04c586ce 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -94,7 +94,7 @@ struct nvme_dev { struct mutex shutdown_lock; bool subsystem; void __iomem *cmb; - dma_addr_t cmb_dma_addr; + pci_bus_addr_t cmb_bus_addr; u64 cmb_size; u32 cmbsz; u32 cmbloc; @@ -1226,7 +1226,7 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq, if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) { unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth), dev->ctrl.page_size); - nvmeq->sq_dma_addr = dev->cmb_dma_addr + offset; + nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset; nvmeq->sq_cmds_io = dev->cmb + offset; } else { nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), @@ -1527,7 +1527,7 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev) resource_size_t bar_size; struct pci_dev *pdev = to_pci_dev(dev->dev); void __iomem *cmb; - dma_addr_t dma_addr; + int bar; dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ); if (!(NVME_CMB_SZ(dev->cmbsz))) @@ -1540,7 +1540,8 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev) szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz)); size = szu * NVME_CMB_SZ(dev->cmbsz); offset = szu * NVME_CMB_OFST(dev->cmbloc); - bar_size = pci_resource_len(pdev, NVME_CMB_BIR(dev->cmbloc)); + bar = NVME_CMB_BIR(dev->cmbloc); + bar_size = pci_resource_len(pdev, bar); if (offset > bar_size) return NULL; @@ -1553,12 +1554,11 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev) if (size > bar_size - offset) size = bar_size - offset; - dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(dev->cmbloc)) + offset; - cmb = ioremap_wc(dma_addr, size); + cmb = ioremap_wc(pci_resource_start(pdev, bar) + offset, size); if (!cmb) return NULL; - dev->cmb_dma_addr = dma_addr; + dev->cmb_bus_addr = pci_bus_address(pdev, bar) + offset; dev->cmb_size = size; return cmb; } -- cgit v1.2.3 From 986e7b7e4991a5d3abab26f97a671512e09e4417 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 29 Sep 2017 11:25:08 +0800 Subject: regulator: axp20x: Fix poly-phase bit offset for AXP803 DCDC5/6 The bit offset used to check if DCDC5 and DCDC6 are tied together in poly-phase output is wrong. It was checking against a reserved bit, which is always false. In reality, neither the reference design layout nor actually produced boards tie these two buck regulators together. But we should still fix it, just in case. Fixes: 1dbe0ccb0631 ("regulator: axp20x-regulator: add support for AXP803") Signed-off-by: Chen-Yu Tsai Tested-by: Maxime Ripard Acked-by: Maxime Ripard Signed-off-by: Mark Brown --- drivers/regulator/axp20x-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index f18b36dd57dd..376a99b7cf5d 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -590,7 +590,7 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id) case AXP803_DCDC3: return !!(reg & BIT(6)); case AXP803_DCDC6: - return !!(reg & BIT(7)); + return !!(reg & BIT(5)); } break; -- cgit v1.2.3 From 8279aaf59006fb19ca8caa3f0f0b8bfc33a0dd1a Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 4 Oct 2017 11:44:16 +0200 Subject: drm/i915: Remove use_mmio_flip modparm, v2. This has been unused since commit afa8ce5b3080 ("drm/i915: Nuke legacy flip queueing code"). Changes since v1: - Rebase on top of all the changes to modparams. Cc: Chris Wilson Signed-off-by: Maarten Lankhorst Reviewed-by: Chris Wilson \o/-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171004094416.31306-1-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/i915_params.c | 3 --- drivers/gpu/drm/i915/i915_params.h | 1 - drivers/gpu/drm/i915/intel_lrc.c | 3 +-- 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 9dff323a83d3..b4faeb6aa2bd 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -146,9 +146,6 @@ i915_param_named(disable_display, bool, 0400, i915_param_named_unsafe(enable_cmd_parser, bool, 0400, "Enable command parsing (true=enabled [default], false=disabled)"); -i915_param_named_unsafe(use_mmio_flip, int, 0600, - "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)"); - i915_param_named(mmio_debug, int, 0600, "Enable the MMIO debug code for the first N failures (default: off). " "This may negatively affect performance."); diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 4f3f8d650194..c7292268ed43 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -49,7 +49,6 @@ param(int, guc_log_level, -1) \ param(char *, guc_firmware_path, NULL) \ param(char *, huc_firmware_path, NULL) \ - param(int, use_mmio_flip, 0) \ param(int, mmio_debug, 0) \ param(int, edp_vswing, 0) \ param(int, reset, 2) \ diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7d6da130b184..6ea5ecf08230 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -244,8 +244,7 @@ int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, int enabl return 0; if (HAS_LOGICAL_RING_CONTEXTS(dev_priv) && - USES_PPGTT(dev_priv) && - i915_modparams.use_mmio_flip >= 0) + USES_PPGTT(dev_priv)) return 1; return 0; -- cgit v1.2.3 From 32ced39c1b122679f829cfdac5a679b3a5aefeaf Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 28 Sep 2017 15:40:39 -0700 Subject: drm/i915: Transform whitelisting WAs into a simple reg write RING_FORCE_TO_NONPRIV registers do not live in the logical context. They are simply global privileged MMIO registers that happen to be powercontext saved and restored (meaning only they can survive RC6). Therefore, there is absolutely no need to save them so that they can be restored everytime we create a new logical context. Suggested-by: Chris Wilson Signed-off-by: Oscar Mateo Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/1506638439-6903-1-git-send-email-oscar.mateo@intel.com Acked-by: Michel Thierry Tested-by: Chris Wilson #bxt Reviewed-by: Mika Kuoppala Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index a28e2a864cf1..a75f5e889927 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -845,8 +845,8 @@ static int wa_ring_whitelist_reg(struct intel_engine_cs *engine, if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS)) return -EINVAL; - WA_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index), - i915_mmio_reg_offset(reg)); + I915_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index), + i915_mmio_reg_offset(reg)); wa->hw_whitelist_count[engine->id]++; return 0; -- cgit v1.2.3 From 53221e11c7a0e85004c1a28f74e4e173f098d262 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Oct 2017 13:41:52 +0100 Subject: drm/i915: Move MMCD_MISC_CTRL from context w/a to standard Looking at gem_workarounds shows us that MMCD_MISC_CTRL is not restored following a suspend-resume cycle. This implies that MMCD_MISC_CTRL is not stored in the context, but is an ordinary register w/a that we need to restore during init_hw. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Oscar Mateo Link: https://patchwork.freedesktop.org/patch/msgid/20171004124153.14142-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/intel_engine_cs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index a75f5e889927..8625feb0939e 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -980,7 +980,11 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) GEN9_PBE_COMPRESSED_HASH_SELECTION); WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR); - WA_SET_BIT(MMCD_MISC_CTRL, MMCD_PCLA | MMCD_HOTSPOT_EN); + + I915_WRITE(MMCD_MISC_CTRL, + I915_READ(MMCD_MISC_CTRL) | + MMCD_PCLA | + MMCD_HOTSPOT_EN); } /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */ -- cgit v1.2.3 From 8d488bbec73fa36907e1b327e919bcd522b4a57f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Oct 2017 13:41:53 +0100 Subject: drm/i915: Remove WA_(SET|CLR)_BIT These macros are of dubious merit when coupled with the per-context w/a set. Instead of tweaking the value in the context, they tweak the value based on the mmio at the time of recording; they are almost by definition not per-context! Having removed the last users, remove the macros to avoid temptation in the future. v2: Kill WA_WRITE as well (now also unused). Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Oscar Mateo Link: https://patchwork.freedesktop.org/patch/msgid/20171004124153.14142-2-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/intel_engine_cs.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 8625feb0939e..e804a9b816f1 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -830,11 +830,6 @@ static int wa_add(struct drm_i915_private *dev_priv, #define WA_SET_FIELD_MASKED(addr, mask, value) \ WA_REG(addr, mask, _MASKED_FIELD(mask, value)) -#define WA_SET_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) | (mask)) -#define WA_CLR_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) & ~(mask)) - -#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) - static int wa_ring_whitelist_reg(struct intel_engine_cs *engine, i915_reg_t reg) { -- cgit v1.2.3 From 6c1fa341d60285cf3f2c7ca99b4abe7a32b53ff5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 13:50:54 +0100 Subject: drm/i915: Fix some tracepoints to capture full 64b The tracepoints need some tlc, in particular we've neglected to update them for the 64b era. v2: Prefix hexadecimal output with 0x. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171003125055.11370-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_trace.h | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 92f4c5bb7aa7..cca73636a747 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -345,7 +345,7 @@ TRACE_EVENT(i915_gem_object_create, TP_STRUCT__entry( __field(struct drm_i915_gem_object *, obj) - __field(u32, size) + __field(u64, size) ), TP_fast_assign( @@ -353,7 +353,7 @@ TRACE_EVENT(i915_gem_object_create, __entry->size = obj->base.size; ), - TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) + TP_printk("obj=%p, size=0x%llx", __entry->obj, __entry->size) ); TRACE_EVENT(i915_gem_shrink, @@ -384,7 +384,7 @@ TRACE_EVENT(i915_vma_bind, __field(struct drm_i915_gem_object *, obj) __field(struct i915_address_space *, vm) __field(u64, offset) - __field(u32, size) + __field(u64, size) __field(unsigned, flags) ), @@ -396,7 +396,7 @@ TRACE_EVENT(i915_vma_bind, __entry->flags = flags; ), - TP_printk("obj=%p, offset=%016llx size=%x%s vm=%p", + TP_printk("obj=%p, offset=0x%016llx size=0x%llx%s vm=%p", __entry->obj, __entry->offset, __entry->size, __entry->flags & PIN_MAPPABLE ? ", mappable" : "", __entry->vm) @@ -410,7 +410,7 @@ TRACE_EVENT(i915_vma_unbind, __field(struct drm_i915_gem_object *, obj) __field(struct i915_address_space *, vm) __field(u64, offset) - __field(u32, size) + __field(u64, size) ), TP_fast_assign( @@ -420,18 +420,18 @@ TRACE_EVENT(i915_vma_unbind, __entry->size = vma->node.size; ), - TP_printk("obj=%p, offset=%016llx size=%x vm=%p", + TP_printk("obj=%p, offset=0x%016llx size=0x%llx vm=%p", __entry->obj, __entry->offset, __entry->size, __entry->vm) ); TRACE_EVENT(i915_gem_object_pwrite, - TP_PROTO(struct drm_i915_gem_object *obj, u32 offset, u32 len), + TP_PROTO(struct drm_i915_gem_object *obj, u64 offset, u64 len), TP_ARGS(obj, offset, len), TP_STRUCT__entry( __field(struct drm_i915_gem_object *, obj) - __field(u32, offset) - __field(u32, len) + __field(u64, offset) + __field(u64, len) ), TP_fast_assign( @@ -440,18 +440,18 @@ TRACE_EVENT(i915_gem_object_pwrite, __entry->len = len; ), - TP_printk("obj=%p, offset=%u, len=%u", + TP_printk("obj=%p, offset=0x%llx, len=0x%llx", __entry->obj, __entry->offset, __entry->len) ); TRACE_EVENT(i915_gem_object_pread, - TP_PROTO(struct drm_i915_gem_object *obj, u32 offset, u32 len), + TP_PROTO(struct drm_i915_gem_object *obj, u64 offset, u64 len), TP_ARGS(obj, offset, len), TP_STRUCT__entry( __field(struct drm_i915_gem_object *, obj) - __field(u32, offset) - __field(u32, len) + __field(u64, offset) + __field(u64, len) ), TP_fast_assign( @@ -460,17 +460,17 @@ TRACE_EVENT(i915_gem_object_pread, __entry->len = len; ), - TP_printk("obj=%p, offset=%u, len=%u", + TP_printk("obj=%p, offset=0x%llx, len=0x%llx", __entry->obj, __entry->offset, __entry->len) ); TRACE_EVENT(i915_gem_object_fault, - TP_PROTO(struct drm_i915_gem_object *obj, u32 index, bool gtt, bool write), + TP_PROTO(struct drm_i915_gem_object *obj, u64 index, bool gtt, bool write), TP_ARGS(obj, index, gtt, write), TP_STRUCT__entry( __field(struct drm_i915_gem_object *, obj) - __field(u32, index) + __field(u64, index) __field(bool, gtt) __field(bool, write) ), @@ -482,7 +482,7 @@ TRACE_EVENT(i915_gem_object_fault, __entry->write = write; ), - TP_printk("obj=%p, %s index=%u %s", + TP_printk("obj=%p, %s index=%llu %s", __entry->obj, __entry->gtt ? "GTT" : "CPU", __entry->index, @@ -515,14 +515,14 @@ DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy, ); TRACE_EVENT(i915_gem_evict, - TP_PROTO(struct i915_address_space *vm, u32 size, u32 align, unsigned int flags), + TP_PROTO(struct i915_address_space *vm, u64 size, u64 align, unsigned int flags), TP_ARGS(vm, size, align, flags), TP_STRUCT__entry( __field(u32, dev) __field(struct i915_address_space *, vm) - __field(u32, size) - __field(u32, align) + __field(u64, size) + __field(u64, align) __field(unsigned int, flags) ), @@ -534,7 +534,7 @@ TRACE_EVENT(i915_gem_evict, __entry->flags = flags; ), - TP_printk("dev=%d, vm=%p, size=%d, align=%d %s", + TP_printk("dev=%d, vm=%p, size=0x%llx, align=0x%llx %s", __entry->dev, __entry->vm, __entry->size, __entry->align, __entry->flags & PIN_MAPPABLE ? ", mappable" : "") ); @@ -593,7 +593,7 @@ TRACE_EVENT(i915_gem_evict_node, __entry->flags = flags; ), - TP_printk("dev=%d, vm=%p, start=%llx size=%llx, color=%lx, flags=%x", + TP_printk("dev=%d, vm=%p, start=0x%llx size=0x%llx, color=0x%lx, flags=%x", __entry->dev, __entry->vm, __entry->start, __entry->size, __entry->color, __entry->flags) -- cgit v1.2.3 From 65921223942435f993ca56cd0a04e686700766bf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 13:50:55 +0100 Subject: drm/i915: Remove defunct trace points trace_i915_gem_evict_everything and trace_i915_gem_ring_flush stopped being used when their parent functions were removed. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20171003125055.11370-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_trace.h | 72 +++++++++------------------------------ 1 file changed, 17 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index cca73636a747..9cab91ddeb79 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -539,38 +539,6 @@ TRACE_EVENT(i915_gem_evict, __entry->flags & PIN_MAPPABLE ? ", mappable" : "") ); -TRACE_EVENT(i915_gem_evict_everything, - TP_PROTO(struct drm_device *dev), - TP_ARGS(dev), - - TP_STRUCT__entry( - __field(u32, dev) - ), - - TP_fast_assign( - __entry->dev = dev->primary->index; - ), - - TP_printk("dev=%d", __entry->dev) -); - -TRACE_EVENT(i915_gem_evict_vm, - TP_PROTO(struct i915_address_space *vm), - TP_ARGS(vm), - - TP_STRUCT__entry( - __field(u32, dev) - __field(struct i915_address_space *, vm) - ), - - TP_fast_assign( - __entry->dev = vm->i915->drm.primary->index; - __entry->vm = vm; - ), - - TP_printk("dev=%d, vm=%p", __entry->dev, __entry->vm) -); - TRACE_EVENT(i915_gem_evict_node, TP_PROTO(struct i915_address_space *vm, struct drm_mm_node *node, unsigned int flags), TP_ARGS(vm, node, flags), @@ -599,6 +567,23 @@ TRACE_EVENT(i915_gem_evict_node, __entry->color, __entry->flags) ); +TRACE_EVENT(i915_gem_evict_vm, + TP_PROTO(struct i915_address_space *vm), + TP_ARGS(vm), + + TP_STRUCT__entry( + __field(u32, dev) + __field(struct i915_address_space *, vm) + ), + + TP_fast_assign( + __entry->dev = vm->i915->drm.primary->index; + __entry->vm = vm; + ), + + TP_printk("dev=%d, vm=%p", __entry->dev, __entry->vm) +); + TRACE_EVENT(i915_gem_ring_sync_to, TP_PROTO(struct drm_i915_gem_request *to, struct drm_i915_gem_request *from), @@ -649,29 +634,6 @@ TRACE_EVENT(i915_gem_request_queue, __entry->flags) ); -TRACE_EVENT(i915_gem_ring_flush, - TP_PROTO(struct drm_i915_gem_request *req, u32 invalidate, u32 flush), - TP_ARGS(req, invalidate, flush), - - TP_STRUCT__entry( - __field(u32, dev) - __field(u32, ring) - __field(u32, invalidate) - __field(u32, flush) - ), - - TP_fast_assign( - __entry->dev = req->i915->drm.primary->index; - __entry->ring = req->engine->id; - __entry->invalidate = invalidate; - __entry->flush = flush; - ), - - TP_printk("dev=%u, ring=%x, invalidate=%04x, flush=%04x", - __entry->dev, __entry->ring, - __entry->invalidate, __entry->flush) -); - DECLARE_EVENT_CLASS(i915_gem_request, TP_PROTO(struct drm_i915_gem_request *req), TP_ARGS(req), -- cgit v1.2.3 From 783874b050768d361239e444ba0fa396bb6d463f Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Wed, 13 Sep 2017 15:45:56 +0200 Subject: dm crypt: reject sector_size feature if device length is not aligned to it If a crypt mapping uses optional sector_size feature, additional restrictions to mapped device segment size must be applied in constructor, otherwise the device activation will fail later. Fixes: 8f0009a225 ("dm crypt: optionally support larger encryption sector size") Cc: stable@vger.kernel.org # 4.12+ Signed-off-by: Milan Broz Signed-off-by: Mike Snitzer --- drivers/md/dm-crypt.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 75341fdca4b6..96ab46512e1f 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -2585,6 +2585,10 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar ti->error = "Invalid feature value for sector_size"; return -EINVAL; } + if (ti->len & ((cc->sector_size >> SECTOR_SHIFT) - 1)) { + ti->error = "Device size is not multiple of sector_size feature"; + return -EINVAL; + } cc->sector_shift = __ffs(cc->sector_size) - SECTOR_SHIFT; } else if (!strcasecmp(opt_string, "iv_large_sectors")) set_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags); -- cgit v1.2.3 From 5dcbeca615ef12047a5f4097b91030cbf995b1d2 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 19 Sep 2017 12:01:08 +0200 Subject: clk: samsung: exynos4: Enable VPLL and EPLL clocks for suspend/resume cycle Commit 6edfa11cb396 ("clk: samsung: Add enable/disable operation for PLL36XX clocks") added enable/disable operations to PLL clocks. Prior that VPLL and EPPL clocks were always enabled because the enable bit was never touched. Those clocks have to be enabled during suspend/resume cycle, because otherwise board fails to enter sleep mode. This patch enables them unconditionally before entering system suspend state. System restore function will set them to the previous state saved in the register cache done before that unconditional enable. Fixes: 6edfa11cb396 ("clk: samsung: Add enable/disable operation for PLL36XX clocks") CC: stable@vger.kernel.org # v4.13 Signed-off-by: Marek Szyprowski Reviewed-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Acked-by: Sylwester Nawrocki Signed-off-by: Stephen Boyd --- drivers/clk/samsung/clk-exynos4.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index e40b77583c47..d8d3cb67b402 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -294,6 +294,18 @@ static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = { #define PLL_ENABLED (1 << 31) #define PLL_LOCKED (1 << 29) +static void exynos4_clk_enable_pll(u32 reg) +{ + u32 pll_con = readl(reg_base + reg); + pll_con |= PLL_ENABLED; + writel(pll_con, reg_base + reg); + + while (!(pll_con & PLL_LOCKED)) { + cpu_relax(); + pll_con = readl(reg_base + reg); + } +} + static void exynos4_clk_wait_for_pll(u32 reg) { u32 pll_con; @@ -315,6 +327,9 @@ static int exynos4_clk_suspend(void) samsung_clk_save(reg_base, exynos4_save_pll, ARRAY_SIZE(exynos4_clk_pll_regs)); + exynos4_clk_enable_pll(EPLL_CON0); + exynos4_clk_enable_pll(VPLL_CON0); + if (exynos4_soc == EXYNOS4210) { samsung_clk_save(reg_base, exynos4_save_soc, ARRAY_SIZE(exynos4210_clk_save)); -- cgit v1.2.3 From 37f6b42e9c2966b08c7df5cfddc0d73c39cead4a Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 2 Oct 2017 18:28:44 +0100 Subject: ACPI/IORT: Fix PCI ACS enablement commit f6810c15cf97 ("iommu/arm-smmu: Clean up early-probing workarounds") removed kernel code that was allowing to initialize and probe the SMMU devices early (ie earlier than PCI devices, through linker script callback entries) in the boot process because it was not needed any longer in that the SMMU devices/drivers now support deferred probing. Since the SMMUs probe routines are also in charge of requesting global PCI ACS kernel enablement, commit f6810c15cf97 ("iommu/arm-smmu: Clean up early-probing workarounds") also postponed PCI ACS enablement to SMMUs devices probe time, which is too late given that PCI devices needs to detect if PCI ACS is enabled to init the respective capability through the following call path: pci_device_add() -> pci_init_capabilities() -> pci_enable_acs() Add code in the ACPI IORT SMMU platform devices initialization path (that is called before ACPI PCI enumeration) to detect if there exists firmware mappings to map root complexes ids to SMMU ids and if so enable ACS for the system. Fixes: f6810c15cf97 ("iommu/arm-smmu: Clean up early-probing workarounds") Reviewed-by: Robin Murphy Tested-by: Nate Watterson Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Hanjun Guo Cc: Sudeep Holla Cc: Zhou Wang Cc: Alex Williamson Signed-off-by: Catalin Marinas --- drivers/acpi/arm64/iort.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 9565d572f8dd..de56394dd161 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -1178,12 +1178,44 @@ dev_put: return ret; } +static bool __init iort_enable_acs(struct acpi_iort_node *iort_node) +{ + if (iort_node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { + struct acpi_iort_node *parent; + struct acpi_iort_id_mapping *map; + int i; + + map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, iort_node, + iort_node->mapping_offset); + + for (i = 0; i < iort_node->mapping_count; i++, map++) { + if (!map->output_reference) + continue; + + parent = ACPI_ADD_PTR(struct acpi_iort_node, + iort_table, map->output_reference); + /* + * If we detect a RC->SMMU mapping, make sure + * we enable ACS on the system. + */ + if ((parent->type == ACPI_IORT_NODE_SMMU) || + (parent->type == ACPI_IORT_NODE_SMMU_V3)) { + pci_request_acs(); + return true; + } + } + } + + return false; +} + static void __init iort_init_platform_devices(void) { struct acpi_iort_node *iort_node, *iort_end; struct acpi_table_iort *iort; struct fwnode_handle *fwnode; int i, ret; + bool acs_enabled = false; /* * iort_table and iort both point to the start of IORT table, but @@ -1203,6 +1235,9 @@ static void __init iort_init_platform_devices(void) return; } + if (!acs_enabled) + acs_enabled = iort_enable_acs(iort_node); + if ((iort_node->type == ACPI_IORT_NODE_SMMU) || (iort_node->type == ACPI_IORT_NODE_SMMU_V3)) { -- cgit v1.2.3 From de7e095a4b6b9dbc643beb39f28b3022fec28220 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 15:33:22 +0000 Subject: drm/i915: Make intel_uncore.h header self-contained We're trying to resolve inter-header dependencies. Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004153327.32608-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uncore.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 03786f931905..66eae2ce2f29 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -25,6 +25,12 @@ #ifndef __INTEL_UNCORE_H__ #define __INTEL_UNCORE_H__ +#include +#include +#include + +#include "i915_reg.h" + struct drm_i915_private; enum forcewake_domain_id { -- cgit v1.2.3 From c23b4f460eb4a44ffbc69af1269e7e212e193a25 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 15:33:23 +0000 Subject: drm/i915/uc: Drop unnecessary forward declaration We don't need it here. Signed-off-by: Michal Wajdeczko Cc: Sagar Arun Kamble Cc: Joonas Lahtinen Reviewed-by: Sagar Arun Kamble Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004153327.32608-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uc.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 6966349ed737..38ec88016df9 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -30,8 +30,6 @@ #include "intel_guc_ct.h" #include "i915_vma.h" -struct drm_i915_gem_request; - /* * This structure primarily describes the GEM object shared with the GuC. * The specs sometimes refer to this object as a "GuC context", but we use -- cgit v1.2.3 From 1fc556fa346948c337d1b04d809443f65e77e04f Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Wed, 4 Oct 2017 15:33:24 +0000 Subject: drm/i915/uc: Create intel_uc_init_mmio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds new function intel_uc_init_mmio which will initialize MMIO access related variables prior to uc load/init. v2: Removed unnecessary export of guc_send_init_regs. Created intel_uc_init_mmio that currently wraps guc_init_send_regs. (Michal) v3 (Michal): add kerneldoc (Joonas) Signed-off-by: Sagar Arun Kamble Cc: Michal Wajdeczko Cc: Michał Winiarski Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004153327.32608-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 2 ++ drivers/gpu/drm/i915/intel_uc.c | 15 +++++++++++++-- drivers/gpu/drm/i915/intel_uc.h | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5cc24344c266..74a456fe487f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1007,6 +1007,8 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) intel_uncore_init(dev_priv); + intel_uc_init_mmio(dev_priv); + ret = intel_engines_init_mmio(dev_priv); if (ret) goto err_uncore; diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 277477890240..8151a9dc12ea 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -288,6 +288,19 @@ static void guc_init_send_regs(struct intel_guc *guc) guc->send_regs.fw_domains = fw_domains; } +/** + * intel_uc_init_mmio - setup uC MMIO access + * + * @dev_priv: device private + * + * Setup minimal state necessary for MMIO accesses later in the + * initialization sequence. + */ +void intel_uc_init_mmio(struct drm_i915_private *dev_priv) +{ + guc_init_send_regs(&dev_priv->guc); +} + static void guc_capture_load_err_log(struct intel_guc *guc) { if (!guc->log.vma || i915_modparams.guc_log_level < 0) @@ -309,8 +322,6 @@ static int guc_enable_communication(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); - guc_init_send_regs(guc); - if (HAS_GUC_CT(dev_priv)) return intel_guc_enable_ct(guc); diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 38ec88016df9..388528f510c5 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -202,6 +202,7 @@ struct intel_huc { /* intel_uc.c */ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv); void intel_uc_init_early(struct drm_i915_private *dev_priv); +void intel_uc_init_mmio(struct drm_i915_private *dev_priv); void intel_uc_init_fw(struct drm_i915_private *dev_priv); void intel_uc_fini_fw(struct drm_i915_private *dev_priv); int intel_uc_init_hw(struct drm_i915_private *dev_priv); -- cgit v1.2.3 From a16b4313ae56ec4d19d0c846487810ff3811a742 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 15:33:25 +0000 Subject: drm/i915/uc: Move uC fw helper code into dedicated files This is a prerequisite to unblock next steps. v2: correct include order (Joonas) v3: use common function prefix (Joonas) add kerneldoc (Michal) Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Sagar Arun Kamble Reviewed-by: Sagar Arun Kamble Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004153327.32608-5-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/intel_uc.c | 159 +----------------------------- drivers/gpu/drm/i915/intel_uc.h | 67 +------------ drivers/gpu/drm/i915/intel_uc_fw.c | 193 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uc_fw.h | 98 +++++++++++++++++++ 5 files changed, 297 insertions(+), 221 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_uc_fw.c create mode 100644 drivers/gpu/drm/i915/intel_uc_fw.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 5182e3d5557d..4850f260aead 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -59,6 +59,7 @@ i915-y += i915_cmd_parser.o \ # general-purpose microcontroller (GuC) support i915-y += intel_uc.o \ + intel_uc_fw.o \ intel_guc_ct.o \ intel_guc_log.o \ intel_guc_loader.o \ diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 8151a9dc12ea..25694ddfa72b 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -26,19 +26,6 @@ #include "intel_uc.h" #include -/* Cleans up uC firmware by releasing the firmware GEM obj. - */ -static void __intel_uc_fw_fini(struct intel_uc_fw *uc_fw) -{ - struct drm_i915_gem_object *obj; - - obj = fetch_and_zero(&uc_fw->obj); - if (obj) - i915_gem_object_put(obj); - - uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE; -} - /* Reset GuC providing us with fresh state for both GuC and HuC. */ static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv) @@ -112,154 +99,16 @@ void intel_uc_init_early(struct drm_i915_private *dev_priv) guc->notify = gen8_guc_raise_irq; } -static void fetch_uc_fw(struct drm_i915_private *dev_priv, - struct intel_uc_fw *uc_fw) -{ - struct pci_dev *pdev = dev_priv->drm.pdev; - struct drm_i915_gem_object *obj; - const struct firmware *fw = NULL; - struct uc_css_header *css; - size_t size; - int err; - - if (!uc_fw->path) - return; - - uc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING; - - DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n", - intel_uc_fw_status_repr(uc_fw->fetch_status)); - - err = request_firmware(&fw, uc_fw->path, &pdev->dev); - if (err) - goto fail; - if (!fw) - goto fail; - - DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n", - uc_fw->path, fw); - - /* Check the size of the blob before examining buffer contents */ - if (fw->size < sizeof(struct uc_css_header)) { - DRM_NOTE("Firmware header is missing\n"); - goto fail; - } - - css = (struct uc_css_header *)fw->data; - - /* Firmware bits always start from header */ - uc_fw->header_offset = 0; - uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw - - css->key_size_dw - css->exponent_size_dw) * sizeof(u32); - - if (uc_fw->header_size != sizeof(struct uc_css_header)) { - DRM_NOTE("CSS header definition mismatch\n"); - goto fail; - } - - /* then, uCode */ - uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size; - uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32); - - /* now RSA */ - if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) { - DRM_NOTE("RSA key size is bad\n"); - goto fail; - } - uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size; - uc_fw->rsa_size = css->key_size_dw * sizeof(u32); - - /* At least, it should have header, uCode and RSA. Size of all three. */ - size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size; - if (fw->size < size) { - DRM_NOTE("Missing firmware components\n"); - goto fail; - } - - /* - * The GuC firmware image has the version number embedded at a - * well-known offset within the firmware blob; note that major / minor - * version are TWO bytes each (i.e. u16), although all pointers and - * offsets are defined in terms of bytes (u8). - */ - switch (uc_fw->type) { - case INTEL_UC_FW_TYPE_GUC: - /* Header and uCode will be loaded to WOPCM. Size of the two. */ - size = uc_fw->header_size + uc_fw->ucode_size; - - /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */ - if (size > intel_guc_wopcm_size(dev_priv)) { - DRM_ERROR("Firmware is too large to fit in WOPCM\n"); - goto fail; - } - uc_fw->major_ver_found = css->guc.sw_version >> 16; - uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF; - break; - - case INTEL_UC_FW_TYPE_HUC: - uc_fw->major_ver_found = css->huc.sw_version >> 16; - uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF; - break; - - default: - DRM_ERROR("Unknown firmware type %d\n", uc_fw->type); - err = -ENOEXEC; - goto fail; - } - - if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0) { - DRM_NOTE("Skipping %s firmware version check\n", - intel_uc_fw_type_repr(uc_fw->type)); - } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted || - uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) { - DRM_NOTE("%s firmware version %d.%d, required %d.%d\n", - intel_uc_fw_type_repr(uc_fw->type), - uc_fw->major_ver_found, uc_fw->minor_ver_found, - uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted); - err = -ENOEXEC; - goto fail; - } - - DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n", - uc_fw->major_ver_found, uc_fw->minor_ver_found, - uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted); - - obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size); - if (IS_ERR(obj)) { - err = PTR_ERR(obj); - goto fail; - } - - uc_fw->obj = obj; - uc_fw->size = fw->size; - - DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n", - uc_fw->obj); - - release_firmware(fw); - uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS; - return; - -fail: - DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n", - uc_fw->path, err); - DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n", - err, fw, uc_fw->obj); - - release_firmware(fw); /* OK even if fw is NULL */ - uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL; -} - void intel_uc_init_fw(struct drm_i915_private *dev_priv) { - fetch_uc_fw(dev_priv, &dev_priv->huc.fw); - fetch_uc_fw(dev_priv, &dev_priv->guc.fw); + intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw); + intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw); } void intel_uc_fini_fw(struct drm_i915_private *dev_priv) { - __intel_uc_fw_fini(&dev_priv->guc.fw); - __intel_uc_fw_fini(&dev_priv->huc.fw); + intel_uc_fw_fini(&dev_priv->guc.fw); + intel_uc_fw_fini(&dev_priv->huc.fw); } static inline i915_reg_t guc_send_reg(struct intel_guc *guc, u32 i) diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 388528f510c5..f0d5a3f310b5 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -24,6 +24,7 @@ #ifndef _INTEL_UC_H_ #define _INTEL_UC_H_ +#include "intel_uc_fw.h" #include "intel_guc_fwif.h" #include "i915_guc_reg.h" #include "intel_ringbuffer.h" @@ -70,72 +71,6 @@ struct i915_guc_client { uint64_t submissions[I915_NUM_ENGINES]; }; -enum intel_uc_fw_status { - INTEL_UC_FIRMWARE_FAIL = -1, - INTEL_UC_FIRMWARE_NONE = 0, - INTEL_UC_FIRMWARE_PENDING, - INTEL_UC_FIRMWARE_SUCCESS -}; - -/* User-friendly representation of an enum */ -static inline -const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status) -{ - switch (status) { - case INTEL_UC_FIRMWARE_FAIL: - return "FAIL"; - case INTEL_UC_FIRMWARE_NONE: - return "NONE"; - case INTEL_UC_FIRMWARE_PENDING: - return "PENDING"; - case INTEL_UC_FIRMWARE_SUCCESS: - return "SUCCESS"; - } - return ""; -} - -enum intel_uc_fw_type { - INTEL_UC_FW_TYPE_GUC, - INTEL_UC_FW_TYPE_HUC -}; - -/* User-friendly representation of an enum */ -static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type) -{ - switch (type) { - case INTEL_UC_FW_TYPE_GUC: - return "GuC"; - case INTEL_UC_FW_TYPE_HUC: - return "HuC"; - } - return "uC"; -} - -/* - * This structure encapsulates all the data needed during the process - * of fetching, caching, and loading the firmware image into the GuC. - */ -struct intel_uc_fw { - const char *path; - size_t size; - struct drm_i915_gem_object *obj; - enum intel_uc_fw_status fetch_status; - enum intel_uc_fw_status load_status; - - uint16_t major_ver_wanted; - uint16_t minor_ver_wanted; - uint16_t major_ver_found; - uint16_t minor_ver_found; - - enum intel_uc_fw_type type; - uint32_t header_size; - uint32_t header_offset; - uint32_t rsa_size; - uint32_t rsa_offset; - uint32_t ucode_size; - uint32_t ucode_offset; -}; - struct intel_guc_log { uint32_t flags; struct i915_vma *vma; diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c new file mode 100644 index 000000000000..766b1cbdfbd7 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_uc_fw.c @@ -0,0 +1,193 @@ +/* + * Copyright © 2016-2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include + +#include "intel_uc_fw.h" +#include "i915_drv.h" + +/** + * intel_uc_fw_fetch - fetch uC firmware + * + * @dev_priv: device private + * @uc_fw: uC firmware + * + * Fetch uC firmware into GEM obj. + */ +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, + struct intel_uc_fw *uc_fw) +{ + struct pci_dev *pdev = dev_priv->drm.pdev; + struct drm_i915_gem_object *obj; + const struct firmware *fw = NULL; + struct uc_css_header *css; + size_t size; + int err; + + if (!uc_fw->path) + return; + + uc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING; + + DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n", + intel_uc_fw_status_repr(uc_fw->fetch_status)); + + err = request_firmware(&fw, uc_fw->path, &pdev->dev); + if (err) + goto fail; + if (!fw) + goto fail; + + DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n", + uc_fw->path, fw); + + /* Check the size of the blob before examining buffer contents */ + if (fw->size < sizeof(struct uc_css_header)) { + DRM_NOTE("Firmware header is missing\n"); + goto fail; + } + + css = (struct uc_css_header *)fw->data; + + /* Firmware bits always start from header */ + uc_fw->header_offset = 0; + uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw - + css->key_size_dw - css->exponent_size_dw) * + sizeof(u32); + + if (uc_fw->header_size != sizeof(struct uc_css_header)) { + DRM_NOTE("CSS header definition mismatch\n"); + goto fail; + } + + /* then, uCode */ + uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size; + uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32); + + /* now RSA */ + if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) { + DRM_NOTE("RSA key size is bad\n"); + goto fail; + } + uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size; + uc_fw->rsa_size = css->key_size_dw * sizeof(u32); + + /* At least, it should have header, uCode and RSA. Size of all three. */ + size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size; + if (fw->size < size) { + DRM_NOTE("Missing firmware components\n"); + goto fail; + } + + /* + * The GuC firmware image has the version number embedded at a + * well-known offset within the firmware blob; note that major / minor + * version are TWO bytes each (i.e. u16), although all pointers and + * offsets are defined in terms of bytes (u8). + */ + switch (uc_fw->type) { + case INTEL_UC_FW_TYPE_GUC: + /* Header and uCode will be loaded to WOPCM. Size of the two. */ + size = uc_fw->header_size + uc_fw->ucode_size; + + /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */ + if (size > intel_guc_wopcm_size(dev_priv)) { + DRM_ERROR("Firmware is too large to fit in WOPCM\n"); + goto fail; + } + uc_fw->major_ver_found = css->guc.sw_version >> 16; + uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF; + break; + + case INTEL_UC_FW_TYPE_HUC: + uc_fw->major_ver_found = css->huc.sw_version >> 16; + uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF; + break; + + default: + DRM_ERROR("Unknown firmware type %d\n", uc_fw->type); + err = -ENOEXEC; + goto fail; + } + + if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0) { + DRM_NOTE("Skipping %s firmware version check\n", + intel_uc_fw_type_repr(uc_fw->type)); + } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted || + uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) { + DRM_NOTE("%s firmware version %d.%d, required %d.%d\n", + intel_uc_fw_type_repr(uc_fw->type), + uc_fw->major_ver_found, uc_fw->minor_ver_found, + uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted); + err = -ENOEXEC; + goto fail; + } + + DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n", + uc_fw->major_ver_found, uc_fw->minor_ver_found, + uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted); + + obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto fail; + } + + uc_fw->obj = obj; + uc_fw->size = fw->size; + + DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n", + uc_fw->obj); + + release_firmware(fw); + uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS; + return; + +fail: + DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n", + uc_fw->path, err); + DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n", + err, fw, uc_fw->obj); + + release_firmware(fw); /* OK even if fw is NULL */ + uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL; +} + +/** + * intel_uc_fw_fini - cleanup uC firmware + * + * @uc_fw: uC firmware + * + * Cleans up uC firmware by releasing the firmware GEM obj. + */ +void intel_uc_fw_fini(struct intel_uc_fw *uc_fw) +{ + struct drm_i915_gem_object *obj; + + obj = fetch_and_zero(&uc_fw->obj); + if (obj) + i915_gem_object_put(obj); + + uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE; +} diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h new file mode 100644 index 000000000000..849b2ce685c0 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -0,0 +1,98 @@ +/* + * Copyright © 2014-2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef _INTEL_UC_FW_H_ +#define _INTEL_UC_FW_H_ + +struct drm_i915_private; + +enum intel_uc_fw_status { + INTEL_UC_FIRMWARE_FAIL = -1, + INTEL_UC_FIRMWARE_NONE = 0, + INTEL_UC_FIRMWARE_PENDING, + INTEL_UC_FIRMWARE_SUCCESS +}; + +enum intel_uc_fw_type { + INTEL_UC_FW_TYPE_GUC, + INTEL_UC_FW_TYPE_HUC +}; + +/* + * This structure encapsulates all the data needed during the process + * of fetching, caching, and loading the firmware image into the uC. + */ +struct intel_uc_fw { + const char *path; + size_t size; + struct drm_i915_gem_object *obj; + enum intel_uc_fw_status fetch_status; + enum intel_uc_fw_status load_status; + + uint16_t major_ver_wanted; + uint16_t minor_ver_wanted; + uint16_t major_ver_found; + uint16_t minor_ver_found; + + enum intel_uc_fw_type type; + uint32_t header_size; + uint32_t header_offset; + uint32_t rsa_size; + uint32_t rsa_offset; + uint32_t ucode_size; + uint32_t ucode_offset; +}; + +static inline +const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status) +{ + switch (status) { + case INTEL_UC_FIRMWARE_FAIL: + return "FAIL"; + case INTEL_UC_FIRMWARE_NONE: + return "NONE"; + case INTEL_UC_FIRMWARE_PENDING: + return "PENDING"; + case INTEL_UC_FIRMWARE_SUCCESS: + return "SUCCESS"; + } + return ""; +} + +static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type) +{ + switch (type) { + case INTEL_UC_FW_TYPE_GUC: + return "GuC"; + case INTEL_UC_FW_TYPE_HUC: + return "HuC"; + } + return "uC"; +} + +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, + struct intel_uc_fw *uc_fw); +void intel_uc_fw_fini(struct intel_uc_fw *uc_fw); + +#endif -- cgit v1.2.3 From d56d63d78c69d880517b5bb72e5ee2be3ead7b18 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 15:33:26 +0000 Subject: drm/i915/huc: Move HuC declarations into dedicated header We want to keep each uC specific code in separate files. Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Sagar Arun Kamble Reviewed-by: Sagar Arun Kamble Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004153327.32608-6-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_huc.h | 39 +++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uc.h | 13 +------------ 2 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_huc.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_huc.h b/drivers/gpu/drm/i915/intel_huc.h new file mode 100644 index 000000000000..d58422b0c85f --- /dev/null +++ b/drivers/gpu/drm/i915/intel_huc.h @@ -0,0 +1,39 @@ +/* + * Copyright © 2014-2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef _INTEL_HUC_H_ +#define _INTEL_HUC_H_ + +struct intel_huc { + /* Generic uC firmware management */ + struct intel_uc_fw fw; + + /* HuC-specific additions */ +}; + +void intel_huc_select_fw(struct intel_huc *huc); +void intel_huc_init_hw(struct intel_huc *huc); +void intel_huc_auth(struct intel_huc *huc); + +#endif diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index f0d5a3f310b5..4fa091e90b5f 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -30,6 +30,7 @@ #include "intel_ringbuffer.h" #include "intel_guc_ct.h" #include "i915_vma.h" +#include "intel_huc.h" /* * This structure primarily describes the GEM object shared with the GuC. @@ -127,13 +128,6 @@ struct intel_guc { void (*notify)(struct intel_guc *guc); }; -struct intel_huc { - /* Generic uC firmware management */ - struct intel_uc_fw fw; - - /* HuC-specific additions */ -}; - /* intel_uc.c */ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv); void intel_uc_init_early(struct drm_i915_private *dev_priv); @@ -186,9 +180,4 @@ static inline u32 guc_ggtt_offset(struct i915_vma *vma) return offset; } -/* intel_huc.c */ -void intel_huc_select_fw(struct intel_huc *huc); -void intel_huc_init_hw(struct intel_huc *huc); -void intel_huc_auth(struct intel_huc *huc); - #endif -- cgit v1.2.3 From 3af7a9c6446b4489d208e501d95c5745d89f6628 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 15:33:27 +0000 Subject: drm/i915/guc: Move Guc early init into own function We don't want to make aggregate uc functions to be too detailed. This will also make future patch easier. Signed-off-by: Michal Wajdeczko Cc: Sagar Arun Kamble Cc: Joonas Lahtinen Reviewed-by: Sagar Arun Kamble Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004153327.32608-7-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 25694ddfa72b..e7875277ba97 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -88,10 +88,8 @@ static void gen8_guc_raise_irq(struct intel_guc *guc) I915_WRITE(GUC_SEND_INTERRUPT, GUC_SEND_TRIGGER); } -void intel_uc_init_early(struct drm_i915_private *dev_priv) +static void guc_init_early(struct intel_guc *guc) { - struct intel_guc *guc = &dev_priv->guc; - intel_guc_ct_init_early(&guc->ct); mutex_init(&guc->send_mutex); @@ -99,6 +97,11 @@ void intel_uc_init_early(struct drm_i915_private *dev_priv) guc->notify = gen8_guc_raise_irq; } +void intel_uc_init_early(struct drm_i915_private *dev_priv) +{ + guc_init_early(&dev_priv->guc); +} + void intel_uc_init_fw(struct drm_i915_private *dev_priv) { intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw); -- cgit v1.2.3 From 1e998343f95b46497c56a21de1b14a302256f973 Mon Sep 17 00:00:00 2001 From: Jeff McGee Date: Tue, 3 Oct 2017 21:34:45 +0100 Subject: drm/i915/preempt: Fix WaEnablePreemptionGranularityControlByUMD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WA applies to all production Gen9 and requires both enabling and whitelisting of the per-context preemption control register. v2: Extend to Cannonlake. Signed-off-by: Jeff McGee Signed-off-by: Michał Winiarski Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_engine_cs.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index e804a9b816f1..6245970eb3ab 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1075,8 +1075,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) if (ret) return ret; - /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl */ - ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1); + /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */ + I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, + _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); + ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1); if (ret) return ret; @@ -1138,14 +1140,6 @@ static int skl_init_workarounds(struct intel_engine_cs *engine) if (ret) return ret; - /* - * Actual WA is to disable percontext preemption granularity control - * until D0 which is the default case so this is equivalent to - * !WaDisablePerCtxtPreemptionGranularityControl:skl - */ - I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, - _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); - /* WaEnableGapsTsvCreditFix:skl */ I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE)); @@ -1278,6 +1272,8 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine) WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX); /* WaEnablePreemptionGranularityControlByUMD:cnl */ + I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, + _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1); if (ret) return ret; -- cgit v1.2.3 From 5152defe4a53ad15e6d96c422440152302c8abd7 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Tue, 3 Oct 2017 21:34:46 +0100 Subject: drm/i915/preempt: Default to disabled mid-command preemption levels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supporting fine-granularity preemption levels may require changes in userspace batch buffer programming. Therefore, we need to fallback to safe default values, rather that use hardware defaults. Userspace is still able to enable fine-granularity, since we're whitelisting the register controlling it in WaEnablePreemptionGranularityControlByUMD. v2: Extend w/a to cover Cannonlake v3: Fix commentary to include both fake w/a names. Signed-off-by: Michał Winiarski Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ drivers/gpu/drm/i915/intel_engine_cs.c | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 39ad9327e2a0..e7dba5539b11 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7003,6 +7003,12 @@ enum { #define GEN9_CS_DEBUG_MODE1 _MMIO(0x20ec) #define GEN9_CTX_PREEMPT_REG _MMIO(0x2248) #define GEN8_CS_CHICKEN1 _MMIO(0x2580) +#define GEN9_PREEMPT_3D_OBJECT_LEVEL (1<<0) +#define GEN9_PREEMPT_GPGPU_LEVEL(hi, lo) (((hi) << 2) | ((lo) << 1)) +#define GEN9_PREEMPT_GPGPU_MID_THREAD_LEVEL GEN9_PREEMPT_GPGPU_LEVEL(0, 0) +#define GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL GEN9_PREEMPT_GPGPU_LEVEL(0, 1) +#define GEN9_PREEMPT_GPGPU_COMMAND_LEVEL GEN9_PREEMPT_GPGPU_LEVEL(1, 0) +#define GEN9_PREEMPT_GPGPU_LEVEL_MASK GEN9_PREEMPT_GPGPU_LEVEL(1, 1) /* GEN7 chicken */ #define GEN7_COMMON_SLICE_CHICKEN1 _MMIO(0x7010) diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 6245970eb3ab..dd64e3d13aa9 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1070,6 +1070,24 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES)); + /* + * Supporting preemption with fine-granularity requires changes in the + * batch buffer programming. Since we can't break old userspace, we + * need to set our default preemption level to safe value. Userspace is + * still able to use more fine-grained preemption levels, since in + * WaEnablePreemptionGranularityControlByUMD we're whitelisting the + * per-ctx register. As such, WaDisable{3D,GPGPU}MidCmdPreemption are + * not real HW workarounds, but merely a way to start using preemption + * while maintaining old contract with userspace. + */ + + /* WaDisable3DMidCmdPreemption:skl,bxt,glk,cfl,[cnl] */ + WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); + + /* WaDisableGPGPUMidCmdPreemption:skl,bxt,blk,cfl,[cnl] */ + WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, + GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); + /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */ ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG); if (ret) @@ -1271,6 +1289,13 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine) /* FtrEnableFastAnisoL1BankingFix: cnl */ WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX); + /* WaDisable3DMidCmdPreemption:cnl */ + WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); + + /* WaDisableGPGPUMidCmdPreemption:cnl */ + WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, + GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); + /* WaEnablePreemptionGranularityControlByUMD:cnl */ I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); -- cgit v1.2.3 From d6c0511300dcff19969844495ba293c4efb50b42 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 21:34:47 +0100 Subject: drm/i915/execlists: Distinguish the incomplete context notifies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let the listener know that the context we just scheduled out was not complete, and will be scheduled back in at a later point. v2: Handle CONTEXT_STATUS_PREEMPTED in gvt by aliasing it to CONTEXT_STATUS_OUT for the moment, gvt can expand upon the difference later. Signed-off-by: Chris Wilson Cc: "Zhenyu Wang" Cc: "Wang, Zhi A" Cc: Michał Winiarski Cc: Mika Kuoppala Cc: Tvrtko Ursulin Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gvt/scheduler.c | 1 + drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/intel_lrc.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index d5892d24f0b6..f6ded475bb2c 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -174,6 +174,7 @@ static int shadow_context_status_change(struct notifier_block *nb, atomic_set(&workload->shadow_ctx_active, 1); break; case INTEL_CONTEXT_SCHEDULE_OUT: + case INTEL_CONTEXT_SCHEDULE_PREEMPTED: atomic_set(&workload->shadow_ctx_active, 0); break; default: diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6ea5ecf08230..a89bc1f148fb 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -617,7 +617,7 @@ execlist_cancel_port_requests(struct intel_engine_execlists *execlists) while (num_ports-- && port_isset(port)) { struct drm_i915_gem_request *rq = port_request(port); - execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); + execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_PREEMPTED); i915_gem_request_put(rq); memset(port, 0, sizeof(*port)); diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 314adee7127a..689fde1a63a9 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -61,6 +61,7 @@ enum { INTEL_CONTEXT_SCHEDULE_IN = 0, INTEL_CONTEXT_SCHEDULE_OUT, + INTEL_CONTEXT_SCHEDULE_PREEMPTED, }; /* Logical Rings */ -- cgit v1.2.3 From e7af3116836fb7feb985497f2c7776751fb27ef3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 21:34:48 +0100 Subject: drm/i915: Introduce a preempt context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add another perma-pinned context for using for preemption at any time. We cannot just reuse the existing kernel context, as first and foremost we need to ensure that we can preempt the kernel context itself, so require a distinct context id. Similar to the kernel context, we may want to interrupt execution and switch to the preempt context at any time, and so it needs to be permanently pinned and available. To compensate for yet another permanent allocation, we shrink the existing context and the new context by reducing their ringbuffer to the minimum. v2: Assert that we never allocate a request from the preemption context. v3: Limit perma-pin to engines that may preempt. v4: Onion cleanup for early driver death v5: Onion ordering in main driver cleanup as well. Signed-off-by: Chris Wilson Reviewed-by: Michał Winiarski Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 6 ++- drivers/gpu/drm/i915/i915_gem_context.c | 76 ++++++++++++++++++++++++--------- drivers/gpu/drm/i915/i915_gem_request.c | 7 +++ drivers/gpu/drm/i915/intel_engine_cs.c | 22 +++++++++- 4 files changed, 87 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7ca11318ac69..31292afb961d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -783,6 +783,7 @@ struct intel_csr { func(has_l3_dpf); \ func(has_llc); \ func(has_logical_ring_contexts); \ + func(has_logical_ring_preemption); \ func(has_overlay); \ func(has_pipe_cxsr); \ func(has_pooled_eu); \ @@ -2251,8 +2252,11 @@ struct drm_i915_private { wait_queue_head_t gmbus_wait_queue; struct pci_dev *bridge_dev; - struct i915_gem_context *kernel_context; struct intel_engine_cs *engine[I915_NUM_ENGINES]; + /* Context used internally to idle the GPU and setup initial state */ + struct i915_gem_context *kernel_context; + /* Context only to be used for injecting preemption commands */ + struct i915_gem_context *preempt_context; struct i915_vma *semaphore; struct drm_dma_handle *status_page_dmah; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 921ee369c74d..2bb8e58706ba 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -416,14 +416,43 @@ out: return ctx; } +static struct i915_gem_context * +create_kernel_context(struct drm_i915_private *i915, int prio) +{ + struct i915_gem_context *ctx; + + ctx = i915_gem_create_context(i915, NULL); + if (IS_ERR(ctx)) + return ctx; + + i915_gem_context_clear_bannable(ctx); + ctx->priority = prio; + ctx->ring_size = PAGE_SIZE; + + GEM_BUG_ON(!i915_gem_context_is_kernel(ctx)); + + return ctx; +} + +static void +destroy_kernel_context(struct i915_gem_context **ctxp) +{ + struct i915_gem_context *ctx; + + /* Keep the context ref so that we can free it immediately ourselves */ + ctx = i915_gem_context_get(fetch_and_zero(ctxp)); + GEM_BUG_ON(!i915_gem_context_is_kernel(ctx)); + + context_close(ctx); + i915_gem_context_free(ctx); +} + int i915_gem_contexts_init(struct drm_i915_private *dev_priv) { struct i915_gem_context *ctx; + int err; - /* Init should only be called once per module load. Eventually the - * restriction on the context_disabled check can be loosened. */ - if (WARN_ON(dev_priv->kernel_context)) - return 0; + GEM_BUG_ON(dev_priv->kernel_context); INIT_LIST_HEAD(&dev_priv->contexts.list); INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker); @@ -441,28 +470,38 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv) BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX); ida_init(&dev_priv->contexts.hw_ida); - ctx = i915_gem_create_context(dev_priv, NULL); + /* lowest priority; idle task */ + ctx = create_kernel_context(dev_priv, I915_PRIORITY_MIN); if (IS_ERR(ctx)) { - DRM_ERROR("Failed to create default global context (error %ld)\n", - PTR_ERR(ctx)); - return PTR_ERR(ctx); + DRM_ERROR("Failed to create default global context\n"); + err = PTR_ERR(ctx); + goto err; } - - /* For easy recognisablity, we want the kernel context to be 0 and then + /* + * For easy recognisablity, we want the kernel context to be 0 and then * all user contexts will have non-zero hw_id. */ GEM_BUG_ON(ctx->hw_id); - - i915_gem_context_clear_bannable(ctx); - ctx->priority = I915_PRIORITY_MIN; /* lowest priority; idle task */ dev_priv->kernel_context = ctx; - GEM_BUG_ON(!i915_gem_context_is_kernel(ctx)); + /* highest priority; preempting task */ + ctx = create_kernel_context(dev_priv, INT_MAX); + if (IS_ERR(ctx)) { + DRM_ERROR("Failed to create default preempt context\n"); + err = PTR_ERR(ctx); + goto err_kernel_context; + } + dev_priv->preempt_context = ctx; DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->engine[RCS]->context_size ? "logical" : "fake"); return 0; + +err_kernel_context: + destroy_kernel_context(&dev_priv->kernel_context); +err: + return err; } void i915_gem_contexts_lost(struct drm_i915_private *dev_priv) @@ -507,15 +546,10 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv) void i915_gem_contexts_fini(struct drm_i915_private *i915) { - struct i915_gem_context *ctx; - lockdep_assert_held(&i915->drm.struct_mutex); - /* Keep the context so that we can free it immediately ourselves */ - ctx = i915_gem_context_get(fetch_and_zero(&i915->kernel_context)); - GEM_BUG_ON(!i915_gem_context_is_kernel(ctx)); - context_close(ctx); - i915_gem_context_free(ctx); + destroy_kernel_context(&i915->preempt_context); + destroy_kernel_context(&i915->kernel_context); /* Must free all deferred contexts (via flush_workqueue) first */ ida_destroy(&i915->contexts.hw_ida); diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 14956d899911..b100b38f1dd2 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -587,6 +587,13 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, lockdep_assert_held(&dev_priv->drm.struct_mutex); + /* + * Preempt contexts are reserved for exclusive use to inject a + * preemption context switch. They are never to be used for any trivial + * request! + */ + GEM_BUG_ON(ctx == dev_priv->preempt_context); + /* ABI: Before userspace accesses the GPU (e.g. execbuffer), report * EIO if the GPU is already wedged. */ diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index dd64e3d13aa9..8b8053d8e24b 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -613,9 +613,22 @@ int intel_engine_init_common(struct intel_engine_cs *engine) if (IS_ERR(ring)) return PTR_ERR(ring); + /* + * Similarly the preempt context must always be available so that + * we can interrupt the engine at any time. + */ + if (INTEL_INFO(engine->i915)->has_logical_ring_preemption) { + ring = engine->context_pin(engine, + engine->i915->preempt_context); + if (IS_ERR(ring)) { + ret = PTR_ERR(ring); + goto err_unpin_kernel; + } + } + ret = intel_engine_init_breadcrumbs(engine); if (ret) - goto err_unpin; + goto err_unpin_preempt; ret = i915_gem_render_state_init(engine); if (ret) @@ -634,7 +647,10 @@ err_rs_fini: i915_gem_render_state_fini(engine); err_breadcrumbs: intel_engine_fini_breadcrumbs(engine); -err_unpin: +err_unpin_preempt: + if (INTEL_INFO(engine->i915)->has_logical_ring_preemption) + engine->context_unpin(engine, engine->i915->preempt_context); +err_unpin_kernel: engine->context_unpin(engine, engine->i915->kernel_context); return ret; } @@ -660,6 +676,8 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine) intel_engine_cleanup_cmd_parser(engine); i915_gem_batch_pool_fini(&engine->batch_pool); + if (INTEL_INFO(engine->i915)->has_logical_ring_preemption) + engine->context_unpin(engine, engine->i915->preempt_context); engine->context_unpin(engine, engine->i915->kernel_context); } -- cgit v1.2.3 From 3ad7b52d962e7c7da11128be4108f606460ae4d2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 21:34:49 +0100 Subject: drm/i915/execlists: Move bdw GPGPU w/a to emit_bb Move the re-enabling of MI arbitration from a per-bb w/a buffer to the emission of the batch buffer itself. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-5-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index a89bc1f148fb..1703bf6c98d6 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1158,24 +1158,6 @@ static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) return batch; } -/* - * This batch is started immediately after indirect_ctx batch. Since we ensure - * that indirect_ctx ends on a cacheline this batch is aligned automatically. - * - * The number of DWORDS written are returned using this field. - * - * This batch is terminated with MI_BATCH_BUFFER_END and so we need not add padding - * to align it with cacheline as padding after MI_BATCH_BUFFER_END is redundant. - */ -static u32 *gen8_init_perctx_bb(struct intel_engine_cs *engine, u32 *batch) -{ - /* WaDisableCtxRestoreArbitration:bdw,chv */ - *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; - *batch++ = MI_BATCH_BUFFER_END; - - return batch; -} - static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) { /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt,glk */ @@ -1290,7 +1272,7 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine) break; case 8: wa_bb_fn[0] = gen8_init_indirectctx_bb; - wa_bb_fn[1] = gen8_init_perctx_bb; + wa_bb_fn[1] = NULL; break; default: MISSING_CASE(INTEL_GEN(engine->i915)); @@ -1534,13 +1516,15 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, if (IS_ERR(cs)) return PTR_ERR(cs); + /* WaDisableCtxRestoreArbitration:bdw,chv */ + *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; + /* FIXME(BDW): Address space and security selectors. */ *cs++ = MI_BATCH_BUFFER_START_GEN8 | (flags & I915_DISPATCH_SECURE ? 0 : BIT(8)) | (flags & I915_DISPATCH_RS ? MI_BATCH_RESOURCE_STREAMER : 0); *cs++ = lower_32_bits(offset); *cs++ = upper_32_bits(offset); - *cs++ = MI_NOOP; intel_ring_advance(req, cs); return 0; -- cgit v1.2.3 From 1f181225f8ec4ca59b53239aa06475d7c5b936b3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 21:34:50 +0100 Subject: drm/i915/execlists: Keep request->priority for its lifetime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With preemption, we will want to "unsubmit" a request, taking it back from the hw and returning it to the priority sorted execution list. In order to know where to insert it into that list, we need to remember its adjust priority (which may change even as it was being executed). This also affects reset for execlists as we are now unsubmitting the requests following the reset (rather than directly writing the ELSP for the inflight contexts). This turns reset into an accidental preemption point, as after the reset we may choose a different pair of contexts to submit to hw. GuC is not updated as this series doesn't add preemption to the GuC submission, and so it can keep benefiting from the early pruning of the DFS inside execlists_schedule() for a little longer. We also need to find a way of reducing the cost of that DFS... v2: Include priority in error-state Signed-off-by: Chris Wilson Cc: Michał Winiarski Reviewed-by: Michał Winiarski Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-6-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gpu_error.c | 10 ++++++---- drivers/gpu/drm/i915/intel_lrc.c | 14 ++++++++++---- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 31292afb961d..1fc7080bfa7b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -982,6 +982,7 @@ struct i915_gpu_state { pid_t pid; u32 handle; u32 hw_id; + int priority; int ban_score; int active; int guilty; @@ -1004,6 +1005,7 @@ struct i915_gpu_state { long jiffies; pid_t pid; u32 context; + int priority; int ban_score; u32 seqno; u32 head; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index c14552ab270b..dc91b32d699e 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -377,9 +377,9 @@ static void error_print_request(struct drm_i915_error_state_buf *m, if (!erq->seqno) return; - err_printf(m, "%s pid %d, ban score %d, seqno %8x:%08x, emitted %dms ago, head %08x, tail %08x\n", + err_printf(m, "%s pid %d, ban score %d, seqno %8x:%08x, prio %d, emitted %dms ago, head %08x, tail %08x\n", prefix, erq->pid, erq->ban_score, - erq->context, erq->seqno, + erq->context, erq->seqno, erq->priority, jiffies_to_msecs(jiffies - erq->jiffies), erq->head, erq->tail); } @@ -388,9 +388,9 @@ static void error_print_context(struct drm_i915_error_state_buf *m, const char *header, const struct drm_i915_error_context *ctx) { - err_printf(m, "%s%s[%d] user_handle %d hw_id %d, ban score %d guilty %d active %d\n", + err_printf(m, "%s%s[%d] user_handle %d hw_id %d, prio %d, ban score %d guilty %d active %d\n", header, ctx->comm, ctx->pid, ctx->handle, ctx->hw_id, - ctx->ban_score, ctx->guilty, ctx->active); + ctx->priority, ctx->ban_score, ctx->guilty, ctx->active); } static void error_print_engine(struct drm_i915_error_state_buf *m, @@ -1271,6 +1271,7 @@ static void record_request(struct drm_i915_gem_request *request, struct drm_i915_error_request *erq) { erq->context = request->ctx->hw_id; + erq->priority = request->priotree.priority; erq->ban_score = atomic_read(&request->ctx->ban_score); erq->seqno = request->global_seqno; erq->jiffies = request->emitted_jiffies; @@ -1364,6 +1365,7 @@ static void record_context(struct drm_i915_error_context *e, e->handle = ctx->user_handle; e->hw_id = ctx->hw_id; + e->priority = ctx->priority; e->ban_score = atomic_read(&ctx->ban_score); e->guilty = atomic_read(&ctx->guilty_count); e->active = atomic_read(&ctx->active_count); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 1703bf6c98d6..5821762d9007 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -584,8 +584,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine) } INIT_LIST_HEAD(&rq->priotree.link); - rq->priotree.priority = INT_MAX; - __i915_gem_request_submit(rq); trace_i915_gem_request_in(rq, port_index(port, execlists)); last = rq; @@ -793,6 +791,7 @@ static void intel_lrc_irq_handler(unsigned long data) execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); trace_i915_gem_request_out(rq); + rq->priotree.priority = INT_MAX; i915_gem_request_put(rq); execlists_port_complete(execlists, port); @@ -845,11 +844,15 @@ static void execlists_submit_request(struct drm_i915_gem_request *request) spin_unlock_irqrestore(&engine->timeline->lock, flags); } +static struct drm_i915_gem_request *pt_to_request(struct i915_priotree *pt) +{ + return container_of(pt, struct drm_i915_gem_request, priotree); +} + static struct intel_engine_cs * pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked) { - struct intel_engine_cs *engine = - container_of(pt, struct drm_i915_gem_request, priotree)->engine; + struct intel_engine_cs *engine = pt_to_request(pt)->engine; GEM_BUG_ON(!locked); @@ -905,6 +908,9 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) * engines. */ list_for_each_entry(p, &pt->signalers_list, signal_link) { + if (i915_gem_request_completed(pt_to_request(p->signaler))) + continue; + GEM_BUG_ON(p->signaler->priority < pt->priority); if (prio > READ_ONCE(p->signaler->priority)) list_move_tail(&p->dfs_link, &dfs); -- cgit v1.2.3 From bf64e0b00e1ff30449cc68e7bc7498adb6faa343 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 21:34:51 +0100 Subject: drm/i915: Expand I915_PARAM_HAS_SCHEDULER into a capability bitmask In the next few patches, we wish to enable different features for the scheduler, some which may subtlety change ABI (e.g. allow requests to be reordered under different circumstances). So we need to make sure userspace is cognizant of the changes (if they care), by which we employ the usual method of a GETPARAM. We already have an I915_PARAM_HAS_SCHEDULER (which notes the existing ability to reorder requests to avoid bubbles), and now we wish to extend that to be a bitmask to describe the different capabilities implemented. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-7-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 5 +++-- include/uapi/drm/i915_drm.h | 9 ++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 74a456fe487f..006332805702 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -367,8 +367,9 @@ static int i915_getparam(struct drm_device *dev, void *data, value = i915_gem_mmap_gtt_version(); break; case I915_PARAM_HAS_SCHEDULER: - value = dev_priv->engine[RCS] && - dev_priv->engine[RCS]->schedule; + value = 0; + if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) + value |= I915_SCHEDULER_CAP_ENABLED; break; case I915_PARAM_MMAP_VERSION: /* Remember to bump this if the version changes! */ diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index fe25a01c81f2..aa4a3b20ef6b 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -397,10 +397,17 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_MIN_EU_IN_POOL 39 #define I915_PARAM_MMAP_GTT_VERSION 40 -/* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution +/* + * Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution * priorities and the driver will attempt to execute batches in priority order. + * The param returns a capability bitmask, nonzero implies that the scheduler + * is enabled, with different features present according to the mask. */ #define I915_PARAM_HAS_SCHEDULER 41 +#define I915_SCHEDULER_CAP_ENABLED (1ul << 0) +#define I915_SCHEDULER_CAP_PRIORITY (1ul << 1) +#define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2) + #define I915_PARAM_HUC_STATUS 42 /* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to opt-out of -- cgit v1.2.3 From beecec9017901849352cfd2886981fe462f9fed0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 21:34:52 +0100 Subject: drm/i915/execlists: Preemption! When we write to ELSP, it triggers a context preemption at the earliest arbitration point (3DPRIMITIVE, some PIPECONTROLs, a few other operations and the explicit MI_ARB_CHECK). If this is to the same context, it triggers a LITE_RESTORE where the RING_TAIL is merely updated (used currently to chain requests from the same context together, avoiding bubbles). However, if it is to a different context, a full context-switch is performed and it will start to execute the new context saving the image of the old for later execution. Previously we avoided preemption by only submitting a new context when the old was idle. But now we wish embrace it, and if the new request has a higher priority than the currently executing request, we write to the ELSP regardless, thus triggering preemption, but we tell the GPU to switch to our special preemption context (not the target). In the context-switch interrupt handler, we know that the previous contexts have finished execution and so can unwind all the incomplete requests and compute the new highest priority request to execute. It would be feasible to avoid the switch-to-idle intermediate by programming the ELSP with the target context. The difficulty is in tracking which request that should be whilst maintaining the dependency change, the error comes in with coalesced requests. As we only track the most recent request and its priority, we may run into the issue of being tricked in preempting a high priority request that was followed by a low priority request from the same context (e.g. for PI); worse still that earlier request may be our own dependency and the order then broken by preemption. By injecting the switch-to-idle and then recomputing the priority queue, we avoid the issue with tracking in-flight coalesced requests. Having tried the preempt-to-busy approach, and failed to find a way around the coalesced priority issue, Michal's original proposal to inject an idle context (based on handling GuC preemption) succeeds. The current heuristic for deciding when to preempt are only if the new request is of higher priority, and has the privileged priority of greater than 0. Note that the scheduler remains unfair! v2: Disable for gen8 (bdw/bsw) as we need additional w/a for GPGPU. Since, the feature is now conditional and not always available when we have a scheduler, make it known via the HAS_SCHEDULER GETPARAM (now a capability mask). v3: Stylistic tweaks. v4: Appease Joonas with a snippet of kerneldoc, only to fuel to fire of the preempt vs preempting debate. Suggested-by: Michal Winiarski Signed-off-by: Chris Wilson Cc: Michal Winiarski Cc: Tvrtko Ursulin Cc: Arkadiusz Hiler Cc: Mika Kuoppala Cc: Ben Widawsky Cc: Zhenyu Wang Cc: Zhi Wang Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-8-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 9 +- drivers/gpu/drm/i915/i915_irq.c | 6 +- drivers/gpu/drm/i915/i915_pci.c | 2 + drivers/gpu/drm/i915/intel_lrc.c | 157 +++++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 + 5 files changed, 143 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 006332805702..7614880edad8 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -368,9 +368,16 @@ static int i915_getparam(struct drm_device *dev, void *data, break; case I915_PARAM_HAS_SCHEDULER: value = 0; - if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) + if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) { value |= I915_SCHEDULER_CAP_ENABLED; + + if (INTEL_INFO(dev_priv)->has_logical_ring_preemption && + i915_modparams.enable_execlists && + !i915_modparams.enable_guc_submission) + value |= I915_SCHEDULER_CAP_PREEMPTION; + } break; + case I915_PARAM_MMAP_VERSION: /* Remember to bump this if the version changes! */ case I915_PARAM_HAS_GEM: diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e5997e818673..de777139f6a1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1382,10 +1382,8 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) bool tasklet = false; if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) { - if (port_count(&execlists->port[0])) { - __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - tasklet = true; - } + __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); + tasklet = true; } if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) { diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index d3a6fe5e3c10..745b6a6e0188 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -424,6 +424,7 @@ static const struct intel_device_info intel_cherryview_info __initconst = { #define GEN9_FEATURES \ GEN8_FEATURES, \ + .has_logical_ring_preemption = 1, \ .has_csr = 1, \ .has_guc = 1, \ .has_ipc = 1, \ @@ -477,6 +478,7 @@ static const struct intel_device_info intel_skylake_gt4_info __initconst = { .has_rc6 = 1, \ .has_dp_mst = 1, \ .has_logical_ring_contexts = 1, \ + .has_logical_ring_preemption = 1, \ .has_guc = 1, \ .has_aliasing_ppgtt = 1, \ .has_full_ppgtt = 1, \ diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5821762d9007..c5b76082d695 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -208,9 +208,9 @@ /* Typical size of the average request (2 pipecontrols and a MI_BB) */ #define EXECLISTS_REQUEST_SIZE 64 /* bytes */ - #define WA_TAIL_DWORDS 2 #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS) +#define PREEMPT_ID 0x1 static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, struct intel_engine_cs *engine); @@ -429,6 +429,12 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq) return ce->lrc_desc; } +static inline void elsp_write(u64 desc, u32 __iomem *elsp) +{ + writel(upper_32_bits(desc), elsp); + writel(lower_32_bits(desc), elsp); +} + static void execlists_submit_ports(struct intel_engine_cs *engine) { struct execlist_port *port = engine->execlists.port; @@ -454,8 +460,7 @@ static void execlists_submit_ports(struct intel_engine_cs *engine) desc = 0; } - writel(upper_32_bits(desc), elsp); - writel(lower_32_bits(desc), elsp); + elsp_write(desc, elsp); } } @@ -488,26 +493,43 @@ static void port_assign(struct execlist_port *port, port_set(port, port_pack(i915_gem_request_get(rq), port_count(port))); } +static void inject_preempt_context(struct intel_engine_cs *engine) +{ + struct intel_context *ce = + &engine->i915->preempt_context->engine[engine->id]; + u32 __iomem *elsp = + engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine)); + unsigned int n; + + GEM_BUG_ON(engine->i915->preempt_context->hw_id != PREEMPT_ID); + GEM_BUG_ON(!IS_ALIGNED(ce->ring->size, WA_TAIL_BYTES)); + + memset(ce->ring->vaddr + ce->ring->tail, 0, WA_TAIL_BYTES); + ce->ring->tail += WA_TAIL_BYTES; + ce->ring->tail &= (ce->ring->size - 1); + ce->lrc_reg_state[CTX_RING_TAIL+1] = ce->ring->tail; + + for (n = execlists_num_ports(&engine->execlists); --n; ) + elsp_write(0, elsp); + + elsp_write(ce->lrc_desc, elsp); +} + +static bool can_preempt(struct intel_engine_cs *engine) +{ + return INTEL_INFO(engine->i915)->has_logical_ring_preemption; +} + static void execlists_dequeue(struct intel_engine_cs *engine) { - struct drm_i915_gem_request *last; struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port *port = execlists->port; const struct execlist_port * const last_port = &execlists->port[execlists->port_mask]; + struct drm_i915_gem_request *last = port_request(port); struct rb_node *rb; bool submit = false; - last = port_request(port); - if (last) - /* WaIdleLiteRestore:bdw,skl - * Apply the wa NOOPs to prevent ring:HEAD == req:TAIL - * as we resubmit the request. See gen8_emit_breadcrumb() - * for where we prepare the padding after the end of the - * request. - */ - last->tail = last->wa_tail; - /* Hardware submission is through 2 ports. Conceptually each port * has a (RING_START, RING_HEAD, RING_TAIL) tuple. RING_START is * static for a context, and unique to each, so we only execute @@ -532,7 +554,65 @@ static void execlists_dequeue(struct intel_engine_cs *engine) spin_lock_irq(&engine->timeline->lock); rb = execlists->first; GEM_BUG_ON(rb_first(&execlists->queue) != rb); - while (rb) { + if (!rb) + goto unlock; + + if (last) { + /* + * Don't resubmit or switch until all outstanding + * preemptions (lite-restore) are seen. Then we + * know the next preemption status we see corresponds + * to this ELSP update. + */ + if (port_count(&port[0]) > 1) + goto unlock; + + if (can_preempt(engine) && + rb_entry(rb, struct i915_priolist, node)->priority > + max(last->priotree.priority, 0)) { + /* + * Switch to our empty preempt context so + * the state of the GPU is known (idle). + */ + inject_preempt_context(engine); + execlists->preempt = true; + goto unlock; + } else { + /* + * In theory, we could coalesce more requests onto + * the second port (the first port is active, with + * no preemptions pending). However, that means we + * then have to deal with the possible lite-restore + * of the second port (as we submit the ELSP, there + * may be a context-switch) but also we may complete + * the resubmission before the context-switch. Ergo, + * coalescing onto the second port will cause a + * preemption event, but we cannot predict whether + * that will affect port[0] or port[1]. + * + * If the second port is already active, we can wait + * until the next context-switch before contemplating + * new requests. The GPU will be busy and we should be + * able to resubmit the new ELSP before it idles, + * avoiding pipeline bubbles (momentary pauses where + * the driver is unable to keep up the supply of new + * work). + */ + if (port_count(&port[1])) + goto unlock; + + /* WaIdleLiteRestore:bdw,skl + * Apply the wa NOOPs to prevent + * ring:HEAD == req:TAIL as we resubmit the + * request. See gen8_emit_breadcrumb() for + * where we prepare the padding after the + * end of the request. + */ + last->tail = last->wa_tail; + } + } + + do { struct i915_priolist *p = rb_entry(rb, typeof(*p), node); struct drm_i915_gem_request *rq, *rn; @@ -595,11 +675,12 @@ static void execlists_dequeue(struct intel_engine_cs *engine) INIT_LIST_HEAD(&p->requests); if (p->priority != I915_PRIORITY_NORMAL) kmem_cache_free(engine->i915->priorities, p); - } + } while (rb); done: execlists->first = rb; if (submit) port_assign(port, last); +unlock: spin_unlock_irq(&engine->timeline->lock); if (submit) @@ -680,13 +761,6 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) spin_unlock_irqrestore(&engine->timeline->lock, flags); } -static bool execlists_elsp_ready(const struct intel_engine_cs *engine) -{ - const struct execlist_port *port = engine->execlists.port; - - return port_count(&port[0]) + port_count(&port[1]) < 2; -} - /* * Check the unread Context Status Buffers and manage the submission of new * contexts to the ELSP accordingly. @@ -695,7 +769,7 @@ static void intel_lrc_irq_handler(unsigned long data) { struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; struct intel_engine_execlists * const execlists = &engine->execlists; - struct execlist_port *port = execlists->port; + struct execlist_port * const port = execlists->port; struct drm_i915_private *dev_priv = engine->i915; /* We can skip acquiring intel_runtime_pm_get() here as it was taken @@ -780,6 +854,23 @@ static void intel_lrc_irq_handler(unsigned long data) if (!(status & GEN8_CTX_STATUS_COMPLETED_MASK)) continue; + if (status & GEN8_CTX_STATUS_ACTIVE_IDLE && + buf[2*head + 1] == PREEMPT_ID) { + execlist_cancel_port_requests(execlists); + + spin_lock_irq(&engine->timeline->lock); + unwind_incomplete_requests(engine); + spin_unlock_irq(&engine->timeline->lock); + + GEM_BUG_ON(!execlists->preempt); + execlists->preempt = false; + continue; + } + + if (status & GEN8_CTX_STATUS_PREEMPTED && + execlists->preempt) + continue; + /* Check the context/desc id for this event matches */ GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); @@ -811,7 +902,7 @@ static void intel_lrc_irq_handler(unsigned long data) } } - if (execlists_elsp_ready(engine)) + if (!execlists->preempt) execlists_dequeue(engine); intel_uncore_forcewake_put(dev_priv, execlists->fw_domains); @@ -824,7 +915,7 @@ static void insert_request(struct intel_engine_cs *engine, struct i915_priolist *p = lookup_priolist(engine, pt, prio); list_add_tail(&pt->link, &ptr_mask_bits(p, 1)->requests); - if (ptr_unmask_bits(p, 1) && execlists_elsp_ready(engine)) + if (ptr_unmask_bits(p, 1)) tasklet_hi_schedule(&engine->execlists.irq_tasklet); } @@ -954,8 +1045,6 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) } spin_unlock_irq(&engine->timeline->lock); - - /* XXX Do we need to preempt to make room for us and our deps? */ } static struct intel_ring * @@ -1151,6 +1240,8 @@ static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) i915_ggtt_offset(engine->scratch) + 2 * CACHELINE_BYTES); + *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; + /* Pad to end of cacheline */ while ((unsigned long)batch % CACHELINE_BYTES) *batch++ = MI_NOOP; @@ -1166,6 +1257,8 @@ static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) { + *batch++ = MI_ARB_ON_OFF | MI_ARB_DISABLE; + /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt,glk */ batch = gen8_emit_flush_coherentl3_wa(engine, batch); @@ -1211,6 +1304,8 @@ static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) *batch++ = 0; } + *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; + /* Pad to end of cacheline */ while ((unsigned long)batch % CACHELINE_BYTES) *batch++ = MI_NOOP; @@ -1364,6 +1459,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift); clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); execlists->csb_head = -1; + execlists->preempt = false; /* After a GPU reset, we may have requests to replay */ if (!i915_modparams.enable_guc_submission && execlists->first) @@ -1659,7 +1755,8 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, */ static void gen8_emit_wa_tail(struct drm_i915_gem_request *request, u32 *cs) { - *cs++ = MI_NOOP; + /* Ensure there's always at least one preemption point per-request. */ + *cs++ = MI_ARB_CHECK; *cs++ = MI_NOOP; request->wa_tail = intel_ring_offset(request, cs); } @@ -1680,7 +1777,6 @@ static void gen8_emit_breadcrumb(struct drm_i915_gem_request *request, u32 *cs) gen8_emit_wa_tail(request, cs); } - static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS; static void gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request, @@ -1708,7 +1804,6 @@ static void gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request, gen8_emit_wa_tail(request, cs); } - static const int gen8_emit_breadcrumb_render_sz = 8 + WA_TAIL_DWORDS; static int gen8_init_rcs_context(struct drm_i915_gem_request *req) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 56d7ae9f298b..0fedda17488c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -238,6 +238,11 @@ struct intel_engine_execlists { #define EXECLIST_MAX_PORTS 2 } port[EXECLIST_MAX_PORTS]; + /** + * @preempt: are we currently handling a preempting context switch? + */ + bool preempt; + /** * @port_mask: number of execlist ports - 1 */ -- cgit v1.2.3 From ac14fbd460d0ec16e7750e40dcd8199b0ff83d0a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Oct 2017 21:34:53 +0100 Subject: drm/i915/scheduler: Support user-defined priorities Use a priority stored in the context as the initial value when submitting a request. This allows us to change the default priority on a per-context basis, allowing different contexts to be favoured with GPU time at the expense of lower importance work. The user can adjust the context's priority via I915_CONTEXT_PARAM_PRIORITY, with more positive values being higher priority (they will be serviced earlier, after their dependencies have been resolved). Any prerequisite work for an execbuf will have its priority raised to match the new request as required. Normal users can specify any value in the range of -1023 to 0 [default], i.e. they can reduce the priority of their workloads (and temporarily boost it back to normal if so desired). Privileged users can specify any value in the range of -1023 to 1023, [default is 0], i.e. they can raise their priority above all overs and so potentially starve the system. Note that the existing schedulers are not fair, nor load balancing, the execution is strictly by priority on a first-come, first-served basis, and the driver may choose to boost some requests above the range available to users. This priority was originally based around nice(2), but evolved to allow clients to adjust their priority within a small range, and allow for a privileged high priority range. For example, this can be used to implement EGL_IMG_context_priority https://www.khronos.org/registry/egl/extensions/IMG/EGL_IMG_context_priority.txt EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of the context to be created. This attribute is a hint, as an implementation may not support multiple contexts at some priority levels and system policy may limit access to high priority contexts to appropriate system privilege level. The default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is EGL_CONTEXT_PRIORITY_MEDIUM_IMG." so we can map PRIORITY_HIGH -> 1023 [privileged, will failback to 0] PRIORITY_MED -> 0 [default] PRIORITY_LOW -> -1023 They also map onto the priorities used by VkQueue (and a VkQueue is essentially a timeline, our i915_gem_context under full-ppgtt). v2: s/CAP_SYS_ADMIN/CAP_SYS_NICE/ v3: Report min/max user priorities as defines in the uapi, and rebase internal priorities on the exposed values. Testcase: igt/gem_exec_schedule Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171003203453.15692-9-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_gem_context.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_request.h | 14 ++++++++++---- include/uapi/drm/i915_drm.h | 7 +++++++ 4 files changed, 41 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7614880edad8..66fc156b294a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -370,6 +370,7 @@ static int i915_getparam(struct drm_device *dev, void *data, value = 0; if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) { value |= I915_SCHEDULER_CAP_ENABLED; + value |= I915_SCHEDULER_CAP_PRIORITY; if (INTEL_INFO(dev_priv)->has_logical_ring_preemption && i915_modparams.enable_execlists && diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 2bb8e58706ba..5bf96a258509 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -1070,6 +1070,9 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, case I915_CONTEXT_PARAM_BANNABLE: args->value = i915_gem_context_is_bannable(ctx); break; + case I915_CONTEXT_PARAM_PRIORITY: + args->value = ctx->priority; + break; default: ret = -EINVAL; break; @@ -1125,6 +1128,26 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, else i915_gem_context_clear_bannable(ctx); break; + + case I915_CONTEXT_PARAM_PRIORITY: + { + int priority = args->value; + + if (args->size) + ret = -EINVAL; + else if (!to_i915(dev)->engine[RCS]->schedule) + ret = -ENODEV; + else if (priority > I915_CONTEXT_MAX_USER_PRIORITY || + priority < I915_CONTEXT_MIN_USER_PRIORITY) + ret = -EINVAL; + else if (priority > I915_CONTEXT_DEFAULT_PRIORITY && + !capable(CAP_SYS_NICE)) + ret = -EPERM; + else + ctx->priority = priority; + } + break; + default: ret = -EINVAL; break; diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h index 6b9e992d01de..26249f39de67 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.h +++ b/drivers/gpu/drm/i915/i915_gem_request.h @@ -30,6 +30,8 @@ #include "i915_gem.h" #include "i915_sw_fence.h" +#include + struct drm_file; struct drm_i915_gem_object; struct drm_i915_gem_request; @@ -69,10 +71,14 @@ struct i915_priotree { struct list_head waiters_list; /* those after us, they depend upon us */ struct list_head link; int priority; -#define I915_PRIORITY_MAX 1024 -#define I915_PRIORITY_NORMAL 0 -#define I915_PRIORITY_MIN (-I915_PRIORITY_MAX) -#define I915_PRIORITY_INVALID INT_MIN +}; + +enum { + I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1, + I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY, + I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1, + + I915_PRIORITY_INVALID = INT_MIN }; struct i915_gem_capture_list { diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index aa4a3b20ef6b..7266b53191ee 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -402,6 +402,9 @@ typedef struct drm_i915_irq_wait { * priorities and the driver will attempt to execute batches in priority order. * The param returns a capability bitmask, nonzero implies that the scheduler * is enabled, with different features present according to the mask. + * + * The initial priority for each batch is supplied by the context and is + * controlled via I915_CONTEXT_PARAM_PRIORITY. */ #define I915_PARAM_HAS_SCHEDULER 41 #define I915_SCHEDULER_CAP_ENABLED (1ul << 0) @@ -1367,6 +1370,10 @@ struct drm_i915_gem_context_param { #define I915_CONTEXT_PARAM_GTT_SIZE 0x3 #define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4 #define I915_CONTEXT_PARAM_BANNABLE 0x5 +#define I915_CONTEXT_PARAM_PRIORITY 0x6 +#define I915_CONTEXT_MAX_USER_PRIORITY 1023 /* inclusive */ +#define I915_CONTEXT_DEFAULT_PRIORITY 0 +#define I915_CONTEXT_MIN_USER_PRIORITY -1023 /* inclusive */ __u64 value; }; -- cgit v1.2.3 From e19cd282ebedb801e572efae5df2f88d573932ce Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Sun, 1 Oct 2017 09:54:35 +0300 Subject: IB/mlx5: Fix label order in error path handling When UAR get_page fails, it needs to continue to cleanup debugfs for congestion control parameters. Labels for error path were incorrectly ordered. This patch fixes to do correct cleanup on debugfs init failure and uar get page failure. Fixes: 4a2da0b8c078 ("IB/mlx5: Add debug control parameters for congestion control") Signed-off-by: Parav Pandit Reviewed-by: Mark Bloch Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford --- drivers/infiniband/hw/mlx5/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index d6fbad8f34aa..552f7bd4ecc3 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -4174,9 +4174,9 @@ err_bfreg: err_uar_page: mlx5_put_uars_page(dev->mdev, dev->mdev->priv.uar); -err_cnt: - mlx5_ib_cleanup_cong_debugfs(dev); err_cong: + mlx5_ib_cleanup_cong_debugfs(dev); +err_cnt: if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) mlx5_ib_dealloc_counters(dev); -- cgit v1.2.3 From efe63c220e57ce74e240670399912e609ac125d9 Mon Sep 17 00:00:00 2001 From: "Amrani, Ram" Date: Tue, 3 Oct 2017 14:47:26 +0300 Subject: RDMA/qedr: Parse VLAN ID correctly and ignore the value of zero Rename vlan_id field name to vlan as it contains more than the vlan_id. Mask out non vlan id fields from vlan tag of the QED LL2 RX GSI vlan output. As it is expected to be vlan id only. Ignore vlan_id with value of zero. Fixes: abd49676c707 ("qed: Add RoCE ll2 & GSI support") Signed-off-by: Ram Amrani Signed-off-by: Michal Kalderon Signed-off-by: Doug Ledford --- drivers/infiniband/hw/qedr/qedr.h | 2 +- drivers/infiniband/hw/qedr/qedr_cm.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qedr/qedr.h b/drivers/infiniband/hw/qedr/qedr.h index b2bb42e2805d..254083b524bd 100644 --- a/drivers/infiniband/hw/qedr/qedr.h +++ b/drivers/infiniband/hw/qedr/qedr.h @@ -387,7 +387,7 @@ struct qedr_qp { u8 wqe_size; u8 smac[ETH_ALEN]; - u16 vlan_id; + u16 vlan; int rc; } *rqe_wr_id; diff --git a/drivers/infiniband/hw/qedr/qedr_cm.c b/drivers/infiniband/hw/qedr/qedr_cm.c index 4689e802b332..5ebbe4952386 100644 --- a/drivers/infiniband/hw/qedr/qedr_cm.c +++ b/drivers/infiniband/hw/qedr/qedr_cm.c @@ -105,7 +105,7 @@ void qedr_ll2_complete_rx_packet(void *cxt, qp->rqe_wr_id[qp->rq.gsi_cons].rc = data->u.data_length_error ? -EINVAL : 0; - qp->rqe_wr_id[qp->rq.gsi_cons].vlan_id = data->vlan; + qp->rqe_wr_id[qp->rq.gsi_cons].vlan = data->vlan; /* note: length stands for data length i.e. GRH is excluded */ qp->rqe_wr_id[qp->rq.gsi_cons].sg_list[0].length = data->length.data_length; @@ -694,6 +694,7 @@ int qedr_gsi_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) struct qedr_cq *cq = get_qedr_cq(ibcq); struct qedr_qp *qp = dev->gsi_qp; unsigned long flags; + u16 vlan_id; int i = 0; spin_lock_irqsave(&cq->cq_lock, flags); @@ -712,9 +713,12 @@ int qedr_gsi_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) wc[i].wc_flags |= IB_WC_GRH | IB_WC_IP_CSUM_OK; ether_addr_copy(wc[i].smac, qp->rqe_wr_id[qp->rq.cons].smac); wc[i].wc_flags |= IB_WC_WITH_SMAC; - if (qp->rqe_wr_id[qp->rq.cons].vlan_id) { + + vlan_id = qp->rqe_wr_id[qp->rq.cons].vlan & + VLAN_VID_MASK; + if (vlan_id) { wc[i].wc_flags |= IB_WC_WITH_VLAN; - wc[i].vlan_id = qp->rqe_wr_id[qp->rq.cons].vlan_id; + wc[i].vlan_id = vlan_id; } qedr_inc_sw_cons(&qp->rq); -- cgit v1.2.3 From 1736b4c99d1c53abec042d41b702aeabeb65d86a Mon Sep 17 00:00:00 2001 From: "Amrani, Ram" Date: Tue, 3 Oct 2017 14:47:27 +0300 Subject: RDMA/qedr: Parse vlan priority as sl Parse the vlan priority from the vlan tag and configure it to the WC's sl field. Fixes: abd49676c707 ("qed: Add RoCE ll2 & GSI support") Signed-off-by: Ram Amrani Signed-off-by: Michal Kalderon Signed-off-by: Doug Ledford --- drivers/infiniband/hw/qedr/qedr_cm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qedr/qedr_cm.c b/drivers/infiniband/hw/qedr/qedr_cm.c index 5ebbe4952386..ad8965397cf7 100644 --- a/drivers/infiniband/hw/qedr/qedr_cm.c +++ b/drivers/infiniband/hw/qedr/qedr_cm.c @@ -719,6 +719,8 @@ int qedr_gsi_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) if (vlan_id) { wc[i].wc_flags |= IB_WC_WITH_VLAN; wc[i].vlan_id = vlan_id; + wc[i].sl = (qp->rqe_wr_id[qp->rq.cons].vlan & + VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; } qedr_inc_sw_cons(&qp->rq); -- cgit v1.2.3 From 43bfc24ec1d69853d706cb3ebfdb9088846b9b50 Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Tue, 3 Oct 2017 11:11:49 -0500 Subject: i40iw: Add missing memory barriers Remove duplicate set_64bit_val call to offset 24. Replace some instances of set_64bit_val with i40iw_insert_wqe_hdr as valid bit needs a write barrier and should be the last write operation for the WQE. Fixes: 786c6adb3a94 ("i40iw: add puda code") Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 2 +- drivers/infiniband/hw/i40iw/i40iw_p.h | 2 ++ drivers/infiniband/hw/i40iw/i40iw_puda.c | 11 ++++------- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c index d1f5345f04f0..42ca5346777d 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -48,7 +48,7 @@ * @wqe: cqp wqe for header * @header: header for the cqp wqe */ -static inline void i40iw_insert_wqe_hdr(u64 *wqe, u64 header) +void i40iw_insert_wqe_hdr(u64 *wqe, u64 header) { wmb(); /* make sure WQE is populated before polarity is set */ set_64bit_val(wqe, 24, header); diff --git a/drivers/infiniband/hw/i40iw/i40iw_p.h b/drivers/infiniband/hw/i40iw/i40iw_p.h index e217a1259f57..5498ad01c280 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_p.h +++ b/drivers/infiniband/hw/i40iw/i40iw_p.h @@ -59,6 +59,8 @@ enum i40iw_status_code i40iw_sc_mr_fast_register(struct i40iw_sc_qp *qp, struct i40iw_fast_reg_stag_info *info, bool post_sq); +void i40iw_insert_wqe_hdr(u64 *wqe, u64 header); + /* HMC/FPM functions */ enum i40iw_status_code i40iw_sc_init_iw_hmc(struct i40iw_sc_dev *dev, u8 hmc_fn_id); diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c index c2cab20c4bc5..59f70676f0e0 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_puda.c +++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c @@ -123,12 +123,11 @@ static void i40iw_puda_post_recvbuf(struct i40iw_puda_rsrc *rsrc, u32 wqe_idx, get_64bit_val(wqe, 24, &offset24); offset24 = (offset24) ? 0 : LS_64(1, I40IWQPSQ_VALID); - set_64bit_val(wqe, 24, offset24); set_64bit_val(wqe, 0, buf->mem.pa); set_64bit_val(wqe, 8, LS_64(buf->mem.size, I40IWQPSQ_FRAG_LEN)); - set_64bit_val(wqe, 24, offset24); + i40iw_insert_wqe_hdr(wqe, offset24); } /** @@ -409,9 +408,7 @@ enum i40iw_status_code i40iw_puda_send(struct i40iw_sc_qp *qp, set_64bit_val(wqe, 8, LS_64(info->len, I40IWQPSQ_FRAG_LEN)); set_64bit_val(wqe, 16, header[0]); - /* Ensure all data is written before writing valid bit */ - wmb(); - set_64bit_val(wqe, 24, header[1]); + i40iw_insert_wqe_hdr(wqe, header[1]); i40iw_debug_buf(qp->dev, I40IW_DEBUG_PUDA, "PUDA SEND WQE", wqe, 32); i40iw_qp_post_wr(&qp->qp_uk); @@ -539,7 +536,7 @@ static enum i40iw_status_code i40iw_puda_qp_wqe(struct i40iw_sc_dev *dev, struct LS_64(2, I40IW_CQPSQ_QP_NEXTIWSTATE) | LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID); - set_64bit_val(wqe, 24, header); + i40iw_insert_wqe_hdr(wqe, header); i40iw_debug_buf(cqp->dev, I40IW_DEBUG_PUDA, "PUDA CQE", wqe, 32); i40iw_sc_cqp_post_sq(cqp); @@ -655,7 +652,7 @@ static enum i40iw_status_code i40iw_puda_cq_wqe(struct i40iw_sc_dev *dev, struct LS_64(1, I40IW_CQPSQ_CQ_ENCEQEMASK) | LS_64(1, I40IW_CQPSQ_CQ_CEQIDVALID) | LS_64(cqp->polarity, I40IW_CQPSQ_WQEVALID); - set_64bit_val(wqe, 24, header); + i40iw_insert_wqe_hdr(wqe, header); i40iw_debug_buf(dev, I40IW_DEBUG_PUDA, "PUDA CQE", wqe, I40IW_CQP_WQE_SIZE * 8); -- cgit v1.2.3 From 789f903fd75036f937409a9a1616a5a5e5cc5bae Mon Sep 17 00:00:00 2001 From: Mustafa Ismail Date: Tue, 3 Oct 2017 11:11:50 -0500 Subject: i40iw: Fix port number for query QP Port number 0 is an invalid port number. Set it to 1 as there is one port per i40iw device. Fixes: d37498417947 ("i40iw: add files for iwarp interface") Signed-off-by: Mustafa Ismail Signed-off-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c index 28b3d02d511b..62be0a41ad0b 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c @@ -826,12 +826,14 @@ static int i40iw_query_qp(struct ib_qp *ibqp, attr->cap.max_inline_data = I40IW_MAX_INLINE_DATA_SIZE; attr->cap.max_send_sge = I40IW_MAX_WQ_FRAGMENT_COUNT; attr->cap.max_recv_sge = I40IW_MAX_WQ_FRAGMENT_COUNT; + attr->port_num = 1; init_attr->event_handler = iwqp->ibqp.event_handler; init_attr->qp_context = iwqp->ibqp.qp_context; init_attr->send_cq = iwqp->ibqp.send_cq; init_attr->recv_cq = iwqp->ibqp.recv_cq; init_attr->srq = iwqp->ibqp.srq; init_attr->cap = attr->cap; + init_attr->port_num = 1; return 0; } -- cgit v1.2.3 From 2a8408e5372503fe4df9b5bbb49fb3af0c212c67 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 3 Oct 2017 12:51:58 +0300 Subject: drm/i915/cnl: Reprogram DMC firmware after S3/S4 resume The DMC firmware program memory is lost after S3/S4 system suspend, so we need to reprogram it during resume. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103070 Fixes: cebfcead63de ("drm/i915/DMC/CNL: Load DMC on CNL") Cc: Anusha Srivatsa Cc: Animesh Manna Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171003095159.711-1-imre.deak@intel.com (cherry picked from commit 57522c4c87de20d8f7ad4e142a3a4334066d55ff) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_runtime_pm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index b66d8e136aa3..b3a087cb0860 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -2782,6 +2782,9 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume /* 6. Enable DBUF */ gen9_dbuf_enable(dev_priv); + + if (resume && dev_priv->csr.dmc_payload) + intel_csr_load_program(dev_priv); } #undef CNL_PROCMON_IDX -- cgit v1.2.3 From 069d40f5834ad26a58f269225a7e13af17019062 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 3 Oct 2017 12:51:59 +0300 Subject: drm/i915/glk: Fix DMC/DC state idleness calculation According to BSpec GLK like BXT needs to ignore the idle state of cores before starting the DMC firmware's DC state handler. Fixes: dbb28b5c3d3c ("drm/i915/DMC/GLK: Load DMC on GLK") Cc: Anusha Srivatsa Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171003095159.711-2-imre.deak@intel.com (cherry picked from commit b7208a3f3e52791571df064fb96025ad48edd1bf) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_csr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 965988f79a55..92c1f8e166dc 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -216,7 +216,7 @@ static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) mask = DC_STATE_DEBUG_MASK_MEMORY_UP; - if (IS_BROXTON(dev_priv)) + if (IS_GEN9_LP(dev_priv)) mask |= DC_STATE_DEBUG_MASK_CORES; /* The below bit doesn't need to be cleared ever afterwards */ -- cgit v1.2.3 From e0a86312874e36033cd94fb977dd603a292875c8 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 4 Oct 2017 23:10:59 +0100 Subject: Update James Hogan's email address Update my imgtec.com and personal email address to my kernel.org one in a few places as MIPS will soon no longer be part of Imagination Technologies, and add mappings in .mailcap so get_maintainer.pl reports the right address. Signed-off-by: James Hogan Signed-off-by: Linus Torvalds --- .mailmap | 2 ++ Documentation/ABI/testing/sysfs-power | 2 +- MAINTAINERS | 6 +++--- drivers/i2c/busses/i2c-img-scb.c | 2 +- drivers/media/rc/ir-sharp-decoder.c | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/.mailmap b/.mailmap index 5273cfd70ad6..c7b10caecc4e 100644 --- a/.mailmap +++ b/.mailmap @@ -68,6 +68,8 @@ Jacob Shin James Bottomley James Bottomley James E Wilson +James Hogan +James Hogan James Ketrenos Javi Merino diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power index 713cab1d5f12..a1d1612f3651 100644 --- a/Documentation/ABI/testing/sysfs-power +++ b/Documentation/ABI/testing/sysfs-power @@ -127,7 +127,7 @@ Description: What; /sys/power/pm_trace_dev_match Date: October 2010 -Contact: James Hogan +Contact: James Hogan Description: The /sys/power/pm_trace_dev_match file contains the name of the device associated with the last PM event point saved in the RTC diff --git a/MAINTAINERS b/MAINTAINERS index 65b0c88d5ee0..3f05fc6961ad 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6738,7 +6738,7 @@ F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt F: drivers/auxdisplay/img-ascii-lcd.c IMGTEC IR DECODER DRIVER -M: James Hogan +M: James Hogan S: Maintained F: drivers/media/rc/img-ir/ @@ -7562,7 +7562,7 @@ F: arch/arm64/include/asm/kvm* F: arch/arm64/kvm/ KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips) -M: James Hogan +M: James Hogan L: linux-mips@linux-mips.org S: Supported F: arch/mips/include/uapi/asm/kvm* @@ -8885,7 +8885,7 @@ F: Documentation/devicetree/bindings/media/meson-ao-cec.txt T: git git://linuxtv.org/media_tree.git METAG ARCHITECTURE -M: James Hogan +M: James Hogan L: linux-metag@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git S: Odd Fixes diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c index 84fb35f6837f..eb1d91b986fd 100644 --- a/drivers/i2c/busses/i2c-img-scb.c +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -1459,6 +1459,6 @@ static struct platform_driver img_scb_i2c_driver = { }; module_platform_driver(img_scb_i2c_driver); -MODULE_AUTHOR("James Hogan "); +MODULE_AUTHOR("James Hogan "); MODULE_DESCRIPTION("IMG host I2C driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c index ed43a4212479..129b558acc92 100644 --- a/drivers/media/rc/ir-sharp-decoder.c +++ b/drivers/media/rc/ir-sharp-decoder.c @@ -245,5 +245,5 @@ module_init(ir_sharp_decode_init); module_exit(ir_sharp_decode_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("James Hogan "); +MODULE_AUTHOR("James Hogan "); MODULE_DESCRIPTION("Sharp IR protocol decoder"); -- cgit v1.2.3 From 5ea2355a100a3c6304901d058aee06d3a6be69bc Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Tue, 3 Oct 2017 17:22:11 +0300 Subject: drm/i915/mst: Use MST sideband message transactions for dpms control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the POWER_DOWN_PHY and POWER_UP_PHY sideband message transactions to set power states for downstream sinks. Apart from giving us the ability to set power state for individual sinks, this fixes the below test for me. $ xrandr --display :0 --output DP-2-2-8 --off $ xrandr --display :0 --output DP-2-2-1 --off $ xrandr --display :0 --output DP-2-2-8 --auto #Black screen $ xrandr --display :0 --output DP-2-2-1 --auto v2: Modify and document the dpms and port disable order (Ville) Add comment explaining is_mst = !crtc_state equivalence(Ville, Maarten) v3 by Jani: rebase References: https://bugs.freedesktop.org/show_bug.cgi?id=90963 References: https://bugs.freedesktop.org/show_bug.cgi?id=88124 Cc: Ville Syrjälä Cc: Lyude Cc: Maarten Lankhorst Reviewed-by: Lyude Paul Acked-by: Maarten Lankhorst Signed-off-by: Dhinakaran Pandiyan Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171003142211.860-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 18 ++++++++++++++---- drivers/gpu/drm/i915/intel_dp_mst.c | 10 ++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 65f4b6786791..511aa60e0176 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2162,7 +2162,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, intel_prepare_dp_ddi_buffers(encoder); intel_ddi_init_dp_buf_reg(encoder); - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); + if (!link_mst) + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) intel_dp_stop_link_train(intel_dp); @@ -2236,12 +2237,21 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, uint32_t val; bool wait = false; - /* old_crtc_state and old_conn_state are NULL when called from DP_MST */ - if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { + /* + * old_crtc_state and old_conn_state are NULL when called from + * DP_MST. The main connector associated with this port is never + * bound to a crtc for MST. + */ + bool is_mst = !old_crtc_state; struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); + /* + * Power down sink before disabling the port, otherwise we end + * up getting interrupts from the sink on detecting link loss. + */ + if (!is_mst) + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); } val = I915_READ(DDI_BUF_CTL(port)); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 9a396f483f8b..3c131e2544cf 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -162,14 +162,19 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port); + /* + * Power down mst path before disabling the port, otherwise we end + * up getting interrupts from the sink upon detecting link loss. + */ + drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, + false); + intel_dp->active_mst_links--; intel_mst->connector = NULL; if (intel_dp->active_mst_links == 0) { intel_dig_port->base.post_disable(&intel_dig_port->base, NULL, NULL); - - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); } DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); } @@ -196,6 +201,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); + drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true); if (intel_dp->active_mst_links == 0) intel_dig_port->base.pre_enable(&intel_dig_port->base, pipe_config, NULL); -- cgit v1.2.3 From cbacf02e7796fea02e5c6e46c90ed7cbe9e6f2c0 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Wed, 4 Oct 2017 09:48:26 -0700 Subject: drm/i915/edp: Get the Panel Power Off timestamp after panel is off Kernel stores the time in jiffies at which the eDP panel is turned off. This should be obtained after the panel is off (after the wait_panel_off). When we next attempt to turn the panel on, we use the difference between the timestamp at which we want to turn the panel on and timestamp at which panel was turned off to ensure that this is equal to panel power cycle delay and if not we wait for the remaining time. Not waiting for the panel power cycle delay can cause the panel to not turn on giving rise to AUX timeouts for the attempted AUX transactions. v2: * Separate lines for bugzilla (Jani Nikula) * Suggested by tag (Daniel Vetter) Cc: Daniel Vetter Cc: Jani Nikula Cc: stable@vger.kernel.org Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101518 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101144 Suggested-by: Daniel Vetter Signed-off-by: Manasi Navare Reviewed-by: Daniel Vetter Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507135706-17147-1-git-send-email-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 90e756c76f10..0fd41cdc68f1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2308,8 +2308,8 @@ static void edp_panel_off(struct intel_dp *intel_dp) I915_WRITE(pp_ctrl_reg, pp); POSTING_READ(pp_ctrl_reg); - intel_dp->panel_power_off_time = ktime_get_boottime(); wait_panel_off(intel_dp); + intel_dp->panel_power_off_time = ktime_get_boottime(); /* We got a reference when we enabled the VDD. */ intel_display_power_put(dev_priv, intel_dp->aux_power_domain); -- cgit v1.2.3 From c02b8fb4073d1b9aa5af909a91b51056b819d946 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 3 Oct 2017 16:37:25 -0700 Subject: drm/i915/edp: Increase the T12 delay quirk to 1300ms For this specific PCI device, the eDP panel requires a higher panel power cycle delay of 1300ms where the minimum spec requirement of panel power cycle delay is 500ms. This fix in combination with correct timestamp at which we get the panel power off time fixes the dP AUX CH timeouts seen on various IGT tests. Fixes: c99a259b4b5192ba ("drm/i915/edp: Add a T12 panel delay quirk to fix DP AUX CH timeouts") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101144 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101518 Cc: Daniel Vetter Cc: Jani Nikula Cc: Ville Syrjala Signed-off-by: Manasi Navare Acked-by: Daniel Vetter Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507073845-13420-2-git-send-email-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0fd41cdc68f1..ca48bce23a6f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5286,7 +5286,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, * seems sufficient to avoid this problem. */ if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) { - vbt.t11_t12 = max_t(u16, vbt.t11_t12, 900 * 10); + vbt.t11_t12 = max_t(u16, vbt.t11_t12, 1300 * 10); DRM_DEBUG_KMS("Increasing T12 panel delay as per the quirk to %d\n", vbt.t11_t12); } -- cgit v1.2.3 From 211735521f323b8d556472a8f85cea8831c7b161 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 28 Jun 2017 11:08:43 +0530 Subject: drm/tilcdc: tilcdc_panel: make of_device_ids const. of_device_ids are not supposed to change at runtime. All functions working with of_device_ids provided by work with const of_device_ids. So mark the non-const structs as const. File size before: text data bss dec hex filename 1531 592 0 2123 84b drivers/gpu/drm/tilcdc/tilcdc_panel.o File size after constify: text data bss dec hex filename 1915 176 0 2091 82b drivers/gpu/drm/tilcdc/tilcdc_panel.o Signed-off-by: Arvind Yadav Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 1813a3623ce6..8eebb5f826a6 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -418,7 +418,7 @@ static int panel_remove(struct platform_device *pdev) return 0; } -static struct of_device_id panel_of_match[] = { +static const struct of_device_id panel_of_match[] = { { .compatible = "ti,tilcdc,panel", }, { }, }; -- cgit v1.2.3 From cafdee68fbd87ff8c2730117d65f095c33b506fe Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 28 Jun 2017 11:12:00 +0530 Subject: drm/tilcdc: tilcdc_tfp410: make of_device_ids const. of_device_ids are not supposed to change at runtime. All functions working with of_device_ids provided by work with const of_device_ids. So mark the non-const structs as const. File size before: text data bss dec hex filename 1496 592 0 2088 828 drivers/gpu/drm/tilcdc/tilcdc_tfp410.o File size after constify: text data bss dec hex filename 1880 176 0 2056 808 drivers/gpu/drm/tilcdc/tilcdc_tfp410.o Signed-off-by: Arvind Yadav Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c index 1e2dfb1b1d6b..7e3643462a08 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c @@ -289,8 +289,6 @@ static const struct tilcdc_module_ops tfp410_module_ops = { * Device: */ -static struct of_device_id tfp410_of_match[]; - static int tfp410_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -375,7 +373,7 @@ static int tfp410_remove(struct platform_device *pdev) return 0; } -static struct of_device_id tfp410_of_match[] = { +static const struct of_device_id tfp410_of_match[] = { { .compatible = "ti,tilcdc,tfp410", }, { }, }; -- cgit v1.2.3 From 61dd13b44435166c5136bd1e5b76a265bd9cddaf Mon Sep 17 00:00:00 2001 From: Cihangir Akturk Date: Thu, 3 Aug 2017 14:58:38 +0300 Subject: drm/tilcdc: switch to drm_*{get,put} helpers drm_*_reference() and drm_*_unreference() functions are just compatibility alias for drm_*_get() and drm_*_put() adn should not be used by new code. So convert all users of compatibility functions to use the new APIs. Signed-off-by: Cihangir Akturk Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 406fe4544b83..d2589f310437 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -75,7 +75,7 @@ static void unref_worker(struct drm_flip_work *work, void *val) struct drm_device *dev = tilcdc_crtc->base.dev; mutex_lock(&dev->mode_config.mutex); - drm_framebuffer_unreference(val); + drm_framebuffer_put(val); mutex_unlock(&dev->mode_config.mutex); } @@ -456,7 +456,7 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc) set_scanout(crtc, fb); - drm_framebuffer_reference(fb); + drm_framebuffer_get(fb); crtc->hwmode = crtc->state->adjusted_mode; } @@ -633,7 +633,7 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc, return -EBUSY; } - drm_framebuffer_reference(fb); + drm_framebuffer_get(fb); crtc->primary->fb = fb; tilcdc_crtc->event = event; -- cgit v1.2.3 From 46a956ab3c5be9141b75c0a6d8a754bdd4426577 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 26 May 2017 13:20:17 +0300 Subject: drm/tilcdc: Turn raster off in crtc reset, if it was on in the HW This forces the HW to be in sync with the empty state. This should help with the problem when LCDC is already enabled (e.g. by the bootloader) at the initialization phase and the enable fails when a new mode is applied. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index d2589f310437..0533fbeefafc 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -728,11 +728,39 @@ static void tilcdc_crtc_disable_vblank(struct drm_crtc *crtc) { } +static void tilcdc_crtc_reset(struct drm_crtc *crtc) +{ + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); + struct drm_device *dev = crtc->dev; + int ret; + + drm_atomic_helper_crtc_reset(crtc); + + /* Turn the raster off if it for some reason is on. */ + pm_runtime_get_sync(dev->dev); + if (tilcdc_read(dev, LCDC_RASTER_CTRL_REG) & LCDC_RASTER_ENABLE) { + /* Enable DMA Frame Done Interrupt */ + tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_FRAME_DONE); + tilcdc_clear_irqstatus(dev, 0xffffffff); + + tilcdc_crtc->frame_done = false; + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); + + ret = wait_event_timeout(tilcdc_crtc->frame_done_wq, + tilcdc_crtc->frame_done, + msecs_to_jiffies(500)); + if (ret == 0) + dev_err(dev->dev, "%s: timeout waiting for framedone\n", + __func__); + } + pm_runtime_put_sync(dev->dev); +} + static const struct drm_crtc_funcs tilcdc_crtc_funcs = { .destroy = tilcdc_crtc_destroy, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, - .reset = drm_atomic_helper_crtc_reset, + .reset = tilcdc_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, .enable_vblank = tilcdc_crtc_enable_vblank, -- cgit v1.2.3 From 125fcc19dad5a0ac9d3f2e4ceb7827951d31ccc7 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 29 May 2017 22:06:26 +0300 Subject: drm/tilcdc: Remove WARN_ON(!drm_modeset_is_locked(&crtc->mutex)) checks Remove WARN_ON(!drm_modeset_is_locked(&crtc->mutex)) checks from tilcdc_crtc_enable(), tilcdc_crtc_disable(), and tilcdc_crtc_update_fb(). Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 0533fbeefafc..4bc5d848cdd1 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -467,7 +467,6 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); unsigned long flags; - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); mutex_lock(&tilcdc_crtc->enable_lock); if (tilcdc_crtc->enabled || tilcdc_crtc->shutdown) { mutex_unlock(&tilcdc_crtc->enable_lock); @@ -564,7 +563,6 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown) static void tilcdc_crtc_disable(struct drm_crtc *crtc) { - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); tilcdc_crtc_off(crtc, false); } @@ -626,8 +624,6 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc, struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct drm_device *dev = crtc->dev; - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); - if (tilcdc_crtc->event) { dev_err(dev->dev, "already pending page flip!\n"); return -EBUSY; -- cgit v1.2.3 From ba3fd954f0b4c2df1e0d7e243cb6735c6f4c5bdc Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 29 May 2017 22:09:44 +0300 Subject: drm/tilcdc: Use tilcdc_crtc_shutdown() in tilcdc_crtc_destroy() Use tilcdc_crtc_shutdown() instead of tilcdc_crtc_disable() in tilcdc_crtc_destroy() and remove the modeset locking. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 4bc5d848cdd1..704db2443b5e 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -606,9 +606,7 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct tilcdc_drm_private *priv = crtc->dev->dev_private; - drm_modeset_lock(&crtc->mutex, NULL); - tilcdc_crtc_disable(crtc); - drm_modeset_unlock(&crtc->mutex); + tilcdc_crtc_shutdown(crtc); flush_workqueue(priv->wq); -- cgit v1.2.3 From e91ef99b95439fc634e9c9753887d363a848f452 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 5 Oct 2017 11:59:27 +0100 Subject: drm/i915/selftests: Remember to create the fake preempt context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the fake device we have our own set of mock contexts that need to match the real contexts we normally create. Currently this requires us to manually instantiate them for the selftests, which I forgot. Reported-by: Matthew Auld Fixes: e7af3116836f ("drm/i915: Introduce a preempt context") Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Joonas Lahtinen Cc: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20171005105927.22991-1-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 2388424a14da..d01b7ec2d68d 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -239,8 +239,14 @@ struct drm_i915_private *mock_gem_device(void) if (!i915->kernel_context) goto err_engine; + i915->preempt_context = mock_context(i915, NULL); + if (!i915->preempt_context) + goto err_kernel_context; + return i915; +err_kernel_context: + i915_gem_context_put(i915->kernel_context); err_engine: for_each_engine(engine, i915, id) mock_engine_free(engine); -- cgit v1.2.3 From 69a330007091ea8a801dd9fcd897ec52f9529586 Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Mon, 2 Oct 2017 11:28:35 +0200 Subject: RAS/CEC: Use the right length for "cec_disable" parse_cec_param() compares a string with "cec_disable" using only 7 characters of the 11-character-long string. The proper solution for this would be: #define CEC_DISABLE "cec_disable" strncmp(str, CEC_DISABLE, strlen(CEC_DISABLE)) but when comparing a string against a string constant strncmp() has no advantage over strcmp() because the comparison is guaranteed to be bound by the string constant. So just replace str strncmp() with strcmp(). [ tglx: Made it use strcmp and updated the changelog ] Fixes: 011d82611172 ("RAS: Add a Corrected Errors Collector") Signed-off-by: Nicolas Iooss Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20170903075440.30250-1-nicolas.iooss_linux@m4x.org --- drivers/ras/cec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c index d0e5d6ee882c..e2c1988cd7c0 100644 --- a/drivers/ras/cec.c +++ b/drivers/ras/cec.c @@ -523,7 +523,7 @@ int __init parse_cec_param(char *str) if (*str == '=') str++; - if (!strncmp(str, "cec_disable", 7)) + if (!strcmp(str, "cec_disable")) ce_arr.disabled = 1; else return 0; -- cgit v1.2.3 From 463a9215f3ca7600b5fff6d903913906ae4548a9 Mon Sep 17 00:00:00 2001 From: Pierre-Yves MORDRET Date: Thu, 21 Sep 2017 15:30:09 +0200 Subject: i2c: stm32f7: fix setup structure I2C drive setup structure is not properly allocated. Make it static instead of pointer to store driver data. Fixes: aeb068c5721485 ("i2c: i2c-stm32f7: add driver") Signed-off-by: Pierre-Yves MORDRET Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-stm32f7.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 47c67b0ca896..42ebdb1665e1 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -215,7 +215,7 @@ struct stm32f7_i2c_dev { unsigned int msg_num; unsigned int msg_id; struct stm32f7_i2c_msg f7_msg; - struct stm32f7_i2c_setup *setup; + struct stm32f7_i2c_setup setup; struct stm32f7_i2c_timings timing; }; @@ -537,7 +537,7 @@ static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev) writel_relaxed(timing, i2c_dev->base + STM32F7_I2C_TIMINGR); /* Enable I2C */ - if (i2c_dev->setup->analog_filter) + if (i2c_dev->setup.analog_filter) stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_ANFOFF); else @@ -887,22 +887,19 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) } setup = of_device_get_match_data(&pdev->dev); - i2c_dev->setup->rise_time = setup->rise_time; - i2c_dev->setup->fall_time = setup->fall_time; - i2c_dev->setup->dnf = setup->dnf; - i2c_dev->setup->analog_filter = setup->analog_filter; + i2c_dev->setup = *setup; ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns", &rise_time); if (!ret) - i2c_dev->setup->rise_time = rise_time; + i2c_dev->setup.rise_time = rise_time; ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-falling-time-ns", &fall_time); if (!ret) - i2c_dev->setup->fall_time = fall_time; + i2c_dev->setup.fall_time = fall_time; - ret = stm32f7_i2c_setup_timing(i2c_dev, i2c_dev->setup); + ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup); if (ret) goto clk_free; -- cgit v1.2.3 From cb09d943c70da7c8097006db1dc163b2d99338f6 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 21 Sep 2017 16:23:16 +0300 Subject: i2c: i801: Add support for Intel Cedar Fork Add PCI ID for Intel Cedar Fork PCH. Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- Documentation/i2c/busses/i2c-i801 | 1 + drivers/i2c/busses/Kconfig | 1 + drivers/i2c/busses/i2c-i801.c | 4 ++++ 3 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 0500193434cb..d47702456926 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 @@ -36,6 +36,7 @@ Supported adapters: * Intel Gemini Lake (SOC) * Intel Cannon Lake-H (PCH) * Intel Cannon Lake-LP (PCH) + * Intel Cedar Fork (PCH) Datasheets: Publicly available at the Intel website On Intel Patsburg and later chipsets, both the normal host SMBus controller diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c06dce2c1da7..45a3f3ca29b3 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -131,6 +131,7 @@ config I2C_I801 Gemini Lake (SOC) Cannon Lake-H (PCH) Cannon Lake-LP (PCH) + Cedar Fork (PCH) This driver can also be built as a module. If so, the module will be called i2c-i801. diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index e114e4e00d29..9e12a53ef7b8 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -68,6 +68,7 @@ * Gemini Lake (SOC) 0x31d4 32 hard yes yes yes * Cannon Lake-H (PCH) 0xa323 32 hard yes yes yes * Cannon Lake-LP (PCH) 0x9da3 32 hard yes yes yes + * Cedar Fork (PCH) 0x18df 32 hard yes yes yes * * Features supported by this driver: * Software PEC no @@ -204,6 +205,7 @@ /* Older devices have their ID defined in */ #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 +#define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df #define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 @@ -1025,6 +1027,7 @@ static const struct pci_device_id i801_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) }, @@ -1513,6 +1516,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS: case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS: case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS: + case PCI_DEVICE_ID_INTEL_CDF_SMBUS: case PCI_DEVICE_ID_INTEL_DNV_SMBUS: case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS: priv->features |= FEATURE_I2C_BLOCK_READ; -- cgit v1.2.3 From a91aee523fb282f8868ba6b918f781679c3ea301 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 21 Sep 2017 08:24:27 +0200 Subject: i2c: ensure termination of *_device_id tables Make sure (of/i2c/platform)_device_id tables are NULL terminated. Found by coccinelle spatch "misc/of_table.cocci" Signed-off-by: Thomas Meyer Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-sprd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c index 22e08ae1704f..25fcc3c1e32b 100644 --- a/drivers/i2c/busses/i2c-sprd.c +++ b/drivers/i2c/busses/i2c-sprd.c @@ -627,6 +627,7 @@ static const struct dev_pm_ops sprd_i2c_pm_ops = { static const struct of_device_id sprd_i2c_of_match[] = { { .compatible = "sprd,sc9860-i2c", }, + {}, }; static struct platform_driver sprd_i2c_driver = { -- cgit v1.2.3 From 25f2f440989c7079fdd8fccd54592cc077b63ae5 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 18 Sep 2017 09:15:39 +0100 Subject: i2c: i2c-stm32f7: make structure stm32f7_setup static const The structure stm32f7_setup is local to the source and does not need to be in global scope, make it static const. Cleans up sparse warning: symbol 'stm32f7_setup' was not declared. Should it be static? Signed-off-by: Colin Ian King Acked-by: Pierre-Yves MORDRET Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-stm32f7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 42ebdb1665e1..d4a6e9c2e9aa 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -265,7 +265,7 @@ static struct stm32f7_i2c_spec i2c_specs[] = { }, }; -struct stm32f7_i2c_setup stm32f7_setup = { +static const struct stm32f7_i2c_setup stm32f7_setup = { .rise_time = STM32F7_I2C_RISE_TIME_DEFAULT, .fall_time = STM32F7_I2C_FALL_TIME_DEFAULT, .dnf = STM32F7_I2C_DNF_DEFAULT, -- cgit v1.2.3 From 764d2997ec0edbb48f12e6477ccaceecd999091d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 Oct 2017 14:07:22 +0200 Subject: drm/i915/selftests: fix check for intel IOMMU An earlier bugfix tried to work around this build failure: drivers/gpu/drm/i915/selftests/mock_gem_device.c: In function 'mock_gem_device': drivers/gpu/drm/i915/selftests/mock_gem_device.c:151:20: error: 'struct dev_archdata' has no member named 'iommu' Checking for CONFIG_IOMMU_API is not sufficient as a compile-time test since that may be enabled in configurations that have neither INTEL_IOMMU not AMD_IOMMU enabled. This changes the check to INTEL_IOMMU instead, as this is the only case we actually care about. Fixes: f46f156ea770 ("drm/i915/selftests: Only touch archdata.iommu when it exists") Signed-off-by: Arnd Bergmann Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171005120749.400818-1-arnd@arndb.de --- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index d01b7ec2d68d..0c8225d677e9 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -146,7 +146,7 @@ struct drm_i915_private *mock_gem_device(void) dev_set_name(&pdev->dev, "mock"); dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); -#if IS_ENABLED(CONFIG_IOMMU_API) +#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU) /* hack to disable iommu for the fake device; force identity mapping */ pdev->dev.archdata.iommu = (void *)-1; #endif -- cgit v1.2.3 From 83482ca3b4fe7312bf3d1f25c7a4e9ff66585eab Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 Oct 2017 14:08:26 +0200 Subject: drm/i915: avoid potential uninitialized variable use One of the recent changes introduced a warning about undefined behavior in the sanity checking: drivers/gpu/drm/i915/intel_ddi.c: In function 'intel_ddi_hdmi_level': drivers/gpu/drm/i915/intel_ddi.c:654:6: error: 'n_hdmi_entries' may be used uninitialized in this function [-Werror=maybe-uninitialized] It seems that the new cnl specific get_buf_trans functions can return uninitialized data if the voltage level is set to an unexpected value. This changes the code to always return '1' in that error case, which seems like the safest choice as we use one less than the number as an array index later on. Fixes: cc9cabfdec38 ("drm/i915/cnl: Move voltage check into ddi buf trans functions.") Signed-off-by: Arnd Bergmann [danvet: shut up gcc comment added.] Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171005120835.437022-1-arnd@arndb.de --- drivers/gpu/drm/i915/intel_ddi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 511aa60e0176..f7c91bb9d13e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -602,8 +602,10 @@ cnl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) } else if (voltage == VOLTAGE_INFO_1_05V) { *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_1_05V); return cnl_ddi_translations_hdmi_1_05V; - } else + } else { + *n_entries = 1; /* shut up gcc */ MISSING_CASE(voltage); + } return NULL; } @@ -621,8 +623,10 @@ cnl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries) } else if (voltage == VOLTAGE_INFO_1_05V) { *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_1_05V); return cnl_ddi_translations_dp_1_05V; - } else + } else { + *n_entries = 1; /* shut up gcc */ MISSING_CASE(voltage); + } return NULL; } @@ -641,8 +645,10 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) } else if (voltage == VOLTAGE_INFO_1_05V) { *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_1_05V); return cnl_ddi_translations_edp_1_05V; - } else + } else { + *n_entries = 1; /* shut up gcc */ MISSING_CASE(voltage); + } return NULL; } else { return cnl_get_buf_trans_dp(dev_priv, n_entries); -- cgit v1.2.3 From 3cf1934abe88103fcbeff88bbaee8a094502e6cb Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Wed, 4 Oct 2017 08:39:52 -0700 Subject: drm/i915/cnl: Do not add an extra page for precaution in the Gen10 LRC size BSpec indicates exactly 16752 DWORDs (17 pages), plus one page for PPHWSP. Please notice that, when looking at the BSpec context image table, the right filter has to be applied (e.g. "CNL") as some rows are excluded for specific GENs. BSpec: 1383 v2: Update count and add BSpec tag (Joonas) v3: Warning about filters in the commit message (Joonas) Suggested-by: Joonas Lahtinen Fixes: 7fd0b1a ("drm/i915/cnl: Add Gen10 LRC size") Signed-off-by: Oscar Mateo Cc: Rodrigo Vivi Cc: Daniele Ceraolo Spurio Cc: Ben Widawsky Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1507131592-29209-1-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_engine_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 8b8053d8e24b..807a7aafc089 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -39,7 +39,7 @@ #define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE) #define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE) -#define GEN10_LR_CONTEXT_RENDER_SIZE (19 * PAGE_SIZE) +#define GEN10_LR_CONTEXT_RENDER_SIZE (18 * PAGE_SIZE) #define GEN8_LR_CONTEXT_OTHER_SIZE ( 2 * PAGE_SIZE) -- cgit v1.2.3 From 41dcf197ad5373a7dd0a4b6572aec2e3ec6a0e49 Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Mon, 2 Oct 2017 17:17:35 -0500 Subject: dm raid: fix incorrect status output at the end of a "recover" process There are three important fields that indicate the overall health and status of an array: dev_health, sync_ratio, and sync_action. They tell us the condition of the devices in the array, and the degree to which the array is synchronized. This commit fixes a condition that is reported incorrectly. When a member of the array is being rebuilt or a new device is added, the "recover" process is used to synchronize it with the rest of the array. When the process is complete, but the sync thread hasn't yet been reaped, it is possible for the state of MD to be: mddev->recovery = [ MD_RECOVERY_RUNNING MD_RECOVERY_RECOVER MD_RECOVERY_DONE ] curr_resync_completed = (but not MaxSector) and all rdevs to be In_sync. This causes the 'array_in_sync' output parameter that is passed to rs_get_progress() to be computed incorrectly and reported as 'false' -- or not in-sync. This in turn causes the dev_health status characters to be reported as all 'a', rather than the proper 'A'. This can cause erroneous output for several seconds at a time when tools will want to be checking the condition due to events that are raised at the end of a sync process. Fix this by properly calculating the 'array_in_sync' return parameter in rs_get_progress(). Also, remove an unnecessary intermediate 'recovery_cp' variable in rs_get_progress(). Signed-off-by: Jonathan Brassow Signed-off-by: Mike Snitzer --- Documentation/device-mapper/dm-raid.txt | 1 + drivers/md/dm-raid.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt index 4a0a7469fdd7..32df07e29f68 100644 --- a/Documentation/device-mapper/dm-raid.txt +++ b/Documentation/device-mapper/dm-raid.txt @@ -344,3 +344,4 @@ Version History (wrong raid10_copies/raid10_format sequence) 1.11.1 Add raid4/5/6 journal write-back support via journal_mode option 1.12.1 fix for MD deadlock between mddev_suspend() and md_write_start() available +1.13.0 Fix dev_health status at end of "recover" (was 'a', now 'A') diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 5bfe285ea9d1..43094ea89e37 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3297,11 +3297,10 @@ static const char *__raid_dev_status(struct raid_set *rs, struct md_rdev *rdev, static sector_t rs_get_progress(struct raid_set *rs, sector_t resync_max_sectors, bool *array_in_sync) { - sector_t r, recovery_cp, curr_resync_completed; + sector_t r, curr_resync_completed; struct mddev *mddev = &rs->md; curr_resync_completed = mddev->curr_resync_completed ?: mddev->recovery_cp; - recovery_cp = mddev->recovery_cp; *array_in_sync = false; if (rs_is_raid0(rs)) { @@ -3330,9 +3329,11 @@ static sector_t rs_get_progress(struct raid_set *rs, } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) r = curr_resync_completed; else - r = recovery_cp; + r = mddev->recovery_cp; - if (r == MaxSector) { + if ((r == MaxSector) || + (test_bit(MD_RECOVERY_DONE, &mddev->recovery) && + (mddev->curr_resync_completed == resync_max_sectors))) { /* * Sync complete. */ @@ -3892,7 +3893,7 @@ static void raid_resume(struct dm_target *ti) static struct target_type raid_target = { .name = "raid", - .version = {1, 12, 1}, + .version = {1, 13, 0}, .module = THIS_MODULE, .ctr = raid_ctr, .dtr = raid_dtr, -- cgit v1.2.3 From d62e2bf3897023c61db6b47138f615b5ba425563 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 18:13:39 +0000 Subject: drm/i915/guc: Move GuC log declarations into dedicated header Move GuC log declarations into dedicated header as we want to keep component specific code in separate files. v2: fix includes (Chris) update commit message (Joonas) Suggested-by: Joonas Lahtinen Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Sagar Arun Kamble Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004181343.66348-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc_log.c | 3 ++ drivers/gpu/drm/i915/intel_guc_log.h | 59 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uc.h | 26 +--------------- 3 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_guc_log.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c index 6571d96704ad..b7317a13354a 100644 --- a/drivers/gpu/drm/i915/intel_guc_log.c +++ b/drivers/gpu/drm/i915/intel_guc_log.c @@ -21,8 +21,11 @@ * IN THE SOFTWARE. * */ + #include #include + +#include "intel_guc_log.h" #include "i915_drv.h" static void guc_log_capture_logs(struct intel_guc *guc); diff --git a/drivers/gpu/drm/i915/intel_guc_log.h b/drivers/gpu/drm/i915/intel_guc_log.h new file mode 100644 index 000000000000..b5ec374d9b15 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_log.h @@ -0,0 +1,59 @@ +/* + * Copyright © 2014-2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef _INTEL_GUC_LOG_H_ +#define _INTEL_GUC_LOG_H_ + +#include + +#include "intel_guc_fwif.h" + +struct drm_i915_private; +struct intel_guc; + +struct intel_guc_log { + uint32_t flags; + struct i915_vma *vma; + /* The runtime stuff gets created only when GuC logging gets enabled */ + struct { + void *buf_addr; + struct workqueue_struct *flush_wq; + struct work_struct flush_work; + struct rchan *relay_chan; + } runtime; + /* logging related stats */ + u32 capture_miss_count; + u32 flush_interrupt_count; + u32 prev_overflow_count[GUC_MAX_LOG_BUFFER]; + u32 total_overflow_count[GUC_MAX_LOG_BUFFER]; + u32 flush_count[GUC_MAX_LOG_BUFFER]; +}; + +int intel_guc_log_create(struct intel_guc *guc); +void intel_guc_log_destroy(struct intel_guc *guc); +int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val); +void i915_guc_log_register(struct drm_i915_private *dev_priv); +void i915_guc_log_unregister(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 4fa091e90b5f..86ae5070185e 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -29,6 +29,7 @@ #include "i915_guc_reg.h" #include "intel_ringbuffer.h" #include "intel_guc_ct.h" +#include "intel_guc_log.h" #include "i915_vma.h" #include "intel_huc.h" @@ -72,24 +73,6 @@ struct i915_guc_client { uint64_t submissions[I915_NUM_ENGINES]; }; -struct intel_guc_log { - uint32_t flags; - struct i915_vma *vma; - /* The runtime stuff gets created only when GuC logging gets enabled */ - struct { - void *buf_addr; - struct workqueue_struct *flush_wq; - struct work_struct flush_work; - struct rchan *relay_chan; - } runtime; - /* logging related stats */ - u32 capture_miss_count; - u32 flush_interrupt_count; - u32 prev_overflow_count[GUC_MAX_LOG_BUFFER]; - u32 total_overflow_count[GUC_MAX_LOG_BUFFER]; - u32 flush_count[GUC_MAX_LOG_BUFFER]; -}; - struct intel_guc { struct intel_uc_fw fw; struct intel_guc_log log; @@ -165,13 +148,6 @@ void i915_guc_submission_disable(struct drm_i915_private *dev_priv); void i915_guc_submission_fini(struct drm_i915_private *dev_priv); struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); -/* intel_guc_log.c */ -int intel_guc_log_create(struct intel_guc *guc); -void intel_guc_log_destroy(struct intel_guc *guc); -int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val); -void i915_guc_log_register(struct drm_i915_private *dev_priv); -void i915_guc_log_unregister(struct drm_i915_private *dev_priv); - static inline u32 guc_ggtt_offset(struct i915_vma *vma) { u32 offset = i915_ggtt_offset(vma); -- cgit v1.2.3 From 9f436c46ea09347e0ee050e819f486bbab047e6c Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 18:13:40 +0000 Subject: drm/i915/guc: Move GuC submission declarations into dedicated header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move GuC submission declarations into dedicated header as we want to keep uC specific code in separate files. v2: fix include (Chris) update commit message (Joonas) Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Sagar Arun Kamble Cc: MichaĹ Winiarski Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004181343.66348-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/i915_guc_submission.c | 7 +-- drivers/gpu/drm/i915/i915_guc_submission.h | 80 ++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uc.c | 1 + drivers/gpu/drm/i915/intel_uc.h | 45 ----------------- 5 files changed, 86 insertions(+), 48 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_guc_submission.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b4a6ac60e7c6..44aae25d12c7 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -30,6 +30,7 @@ #include #include #include "intel_drv.h" +#include "i915_guc_submission.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) { diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 04f1281d81a5..97dfe962547e 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -21,12 +21,13 @@ * IN THE SOFTWARE. * */ -#include -#include "i915_drv.h" -#include "intel_uc.h" +#include #include +#include "i915_guc_submission.h" +#include "i915_drv.h" + /** * DOC: GuC-based command submission * diff --git a/drivers/gpu/drm/i915/i915_guc_submission.h b/drivers/gpu/drm/i915/i915_guc_submission.h new file mode 100644 index 000000000000..a7e61e6246ff --- /dev/null +++ b/drivers/gpu/drm/i915/i915_guc_submission.h @@ -0,0 +1,80 @@ +/* + * Copyright © 2014-2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef _I915_GUC_SUBMISSION_H_ +#define _I915_GUC_SUBMISSION_H_ + +#include + +#include "i915_gem.h" + +struct drm_i915_private; + +/* + * This structure primarily describes the GEM object shared with the GuC. + * The specs sometimes refer to this object as a "GuC context", but we use + * the term "client" to avoid confusion with hardware contexts. This + * GEM object is held for the entire lifetime of our interaction with + * the GuC, being allocated before the GuC is loaded with its firmware. + * Because there's no way to update the address used by the GuC after + * initialisation, the shared object must stay pinned into the GGTT as + * long as the GuC is in use. We also keep the first page (only) mapped + * into kernel address space, as it includes shared data that must be + * updated on every request submission. + * + * The single GEM object described here is actually made up of several + * separate areas, as far as the GuC is concerned. The first page (kept + * kmap'd) includes the "process descriptor" which holds sequence data for + * the doorbell, and one cacheline which actually *is* the doorbell; a + * write to this will "ring the doorbell" (i.e. send an interrupt to the + * GuC). The subsequent pages of the client object constitute the work + * queue (a circular array of work items), again described in the process + * descriptor. Work queue pages are mapped momentarily as required. + */ +struct i915_guc_client { + struct i915_vma *vma; + void *vaddr; + struct i915_gem_context *owner; + struct intel_guc *guc; + + /* bitmap of (host) engine ids */ + uint32_t engines; + uint32_t priority; + u32 stage_id; + uint32_t proc_desc_offset; + + u16 doorbell_id; + unsigned long doorbell_offset; + + spinlock_t wq_lock; + /* Per-engine counts of GuC submissions */ + uint64_t submissions[I915_NUM_ENGINES]; +}; + +int i915_guc_submission_init(struct drm_i915_private *dev_priv); +int i915_guc_submission_enable(struct drm_i915_private *dev_priv); +void i915_guc_submission_disable(struct drm_i915_private *dev_priv); +void i915_guc_submission_fini(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index e7875277ba97..770bac462441 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -24,6 +24,7 @@ #include "i915_drv.h" #include "intel_uc.h" +#include "i915_guc_submission.h" #include /* Reset GuC providing us with fresh state for both GuC and HuC. diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 86ae5070185e..2f741a97007e 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -33,46 +33,6 @@ #include "i915_vma.h" #include "intel_huc.h" -/* - * This structure primarily describes the GEM object shared with the GuC. - * The specs sometimes refer to this object as a "GuC context", but we use - * the term "client" to avoid confusion with hardware contexts. This - * GEM object is held for the entire lifetime of our interaction with - * the GuC, being allocated before the GuC is loaded with its firmware. - * Because there's no way to update the address used by the GuC after - * initialisation, the shared object must stay pinned into the GGTT as - * long as the GuC is in use. We also keep the first page (only) mapped - * into kernel address space, as it includes shared data that must be - * updated on every request submission. - * - * The single GEM object described here is actually made up of several - * separate areas, as far as the GuC is concerned. The first page (kept - * kmap'd) includes the "process descriptor" which holds sequence data for - * the doorbell, and one cacheline which actually *is* the doorbell; a - * write to this will "ring the doorbell" (i.e. send an interrupt to the - * GuC). The subsequent pages of the client object constitute the work - * queue (a circular array of work items), again described in the process - * descriptor. Work queue pages are mapped momentarily as required. - */ -struct i915_guc_client { - struct i915_vma *vma; - void *vaddr; - struct i915_gem_context *owner; - struct intel_guc *guc; - - uint32_t engines; /* bitmap of (host) engine ids */ - uint32_t priority; - u32 stage_id; - uint32_t proc_desc_offset; - - u16 doorbell_id; - unsigned long doorbell_offset; - - spinlock_t wq_lock; - /* Per-engine counts of GuC submissions */ - uint64_t submissions[I915_NUM_ENGINES]; -}; - struct intel_guc { struct intel_uc_fw fw; struct intel_guc_log log; @@ -141,11 +101,6 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv); int intel_guc_resume(struct drm_i915_private *dev_priv); u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv); -/* i915_guc_submission.c */ -int i915_guc_submission_init(struct drm_i915_private *dev_priv); -int i915_guc_submission_enable(struct drm_i915_private *dev_priv); -void i915_guc_submission_disable(struct drm_i915_private *dev_priv); -void i915_guc_submission_fini(struct drm_i915_private *dev_priv); struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); static inline u32 guc_ggtt_offset(struct i915_vma *vma) -- cgit v1.2.3 From 9bf384c5f21235d039bccf5d6e497c2c27986367 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 18:13:41 +0000 Subject: drm/i915/guc: Move GuC core definitions into dedicated files Move GuC core definitions into dedicated files as we want to keep GuC specific code in separated files. v2: move all functions in single patch (Joonas) fix old checkpatch issues (Sagar) v3: rebased Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Sagar Arun Kamble Reviewed-by: Sagar Arun Kamble #1 Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004181343.66348-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_guc_submission.c | 94 ---------- drivers/gpu/drm/i915/intel_guc.c | 264 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_guc.h | 109 ++++++++++++ drivers/gpu/drm/i915/intel_uc.c | 146 +--------------- drivers/gpu/drm/i915/intel_uc.h | 78 +-------- 6 files changed, 377 insertions(+), 315 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_guc.c create mode 100644 drivers/gpu/drm/i915/intel_guc.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 4850f260aead..51d0d2929a4b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -60,6 +60,7 @@ i915-y += i915_cmd_parser.o \ # general-purpose microcontroller (GuC) support i915-y += intel_uc.o \ intel_uc_fw.o \ + intel_guc.o \ intel_guc_ct.o \ intel_guc_log.o \ intel_guc_loader.o \ diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 97dfe962547e..7460ab4a214c 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -644,48 +644,6 @@ static void i915_guc_irq_handler(unsigned long data) * path of i915_guc_submit() above. */ -/** - * intel_guc_allocate_vma() - Allocate a GGTT VMA for GuC usage - * @guc: the guc - * @size: size of area to allocate (both virtual space and memory) - * - * This is a wrapper to create an object for use with the GuC. In order to - * use it inside the GuC, an object needs to be pinned lifetime, so we allocate - * both some backing storage and a range inside the Global GTT. We must pin - * it in the GGTT somewhere other than than [0, GUC_WOPCM_TOP) because that - * range is reserved inside GuC. - * - * Return: A i915_vma if successful, otherwise an ERR_PTR. - */ -struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - struct drm_i915_gem_object *obj; - struct i915_vma *vma; - int ret; - - obj = i915_gem_object_create(dev_priv, size); - if (IS_ERR(obj)) - return ERR_CAST(obj); - - vma = i915_vma_instance(obj, &dev_priv->ggtt.base, NULL); - if (IS_ERR(vma)) - goto err; - - ret = i915_vma_pin(vma, 0, PAGE_SIZE, - PIN_GLOBAL | PIN_OFFSET_BIAS | GUC_WOPCM_TOP); - if (ret) { - vma = ERR_PTR(ret); - goto err; - } - - return vma; - -err: - i915_gem_object_put(obj); - return vma; -} - /* Check that a doorbell register is in the expected state */ static bool doorbell_ok(struct intel_guc *guc, u16 db_id) { @@ -1213,55 +1171,3 @@ void i915_guc_submission_disable(struct drm_i915_private *dev_priv) guc_client_free(guc->execbuf_client); guc->execbuf_client = NULL; } - -/** - * intel_guc_suspend() - notify GuC entering suspend state - * @dev_priv: i915 device private - */ -int intel_guc_suspend(struct drm_i915_private *dev_priv) -{ - struct intel_guc *guc = &dev_priv->guc; - struct i915_gem_context *ctx; - u32 data[3]; - - if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) - return 0; - - gen9_disable_guc_interrupts(dev_priv); - - ctx = dev_priv->kernel_context; - - data[0] = INTEL_GUC_ACTION_ENTER_S_STATE; - /* any value greater than GUC_POWER_D0 */ - data[1] = GUC_POWER_D1; - /* first page is shared data with GuC */ - data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + LRC_GUCSHR_PN * PAGE_SIZE; - - return intel_guc_send(guc, data, ARRAY_SIZE(data)); -} - -/** - * intel_guc_resume() - notify GuC resuming from suspend state - * @dev_priv: i915 device private - */ -int intel_guc_resume(struct drm_i915_private *dev_priv) -{ - struct intel_guc *guc = &dev_priv->guc; - struct i915_gem_context *ctx; - u32 data[3]; - - if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) - return 0; - - if (i915_modparams.guc_log_level >= 0) - gen9_enable_guc_interrupts(dev_priv); - - ctx = dev_priv->kernel_context; - - data[0] = INTEL_GUC_ACTION_EXIT_S_STATE; - data[1] = GUC_POWER_D0; - /* first page is shared data with GuC */ - data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + LRC_GUCSHR_PN * PAGE_SIZE; - - return intel_guc_send(guc, data, ARRAY_SIZE(data)); -} diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c new file mode 100644 index 000000000000..bbe4c328e9fd --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc.c @@ -0,0 +1,264 @@ +/* + * Copyright © 2014-2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "intel_guc.h" +#include "i915_drv.h" + +static void gen8_guc_raise_irq(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + + I915_WRITE(GUC_SEND_INTERRUPT, GUC_SEND_TRIGGER); +} + +static inline i915_reg_t guc_send_reg(struct intel_guc *guc, u32 i) +{ + GEM_BUG_ON(!guc->send_regs.base); + GEM_BUG_ON(!guc->send_regs.count); + GEM_BUG_ON(i >= guc->send_regs.count); + + return _MMIO(guc->send_regs.base + 4 * i); +} + +void intel_guc_init_send_regs(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + enum forcewake_domains fw_domains = 0; + unsigned int i; + + guc->send_regs.base = i915_mmio_reg_offset(SOFT_SCRATCH(0)); + guc->send_regs.count = SOFT_SCRATCH_COUNT - 1; + + for (i = 0; i < guc->send_regs.count; i++) { + fw_domains |= intel_uncore_forcewake_for_reg(dev_priv, + guc_send_reg(guc, i), + FW_REG_READ | FW_REG_WRITE); + } + guc->send_regs.fw_domains = fw_domains; +} + +void intel_guc_init_early(struct intel_guc *guc) +{ + intel_guc_ct_init_early(&guc->ct); + + mutex_init(&guc->send_mutex); + guc->send = intel_guc_send_nop; + guc->notify = gen8_guc_raise_irq; +} + +int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len) +{ + WARN(1, "Unexpected send: action=%#x\n", *action); + return -ENODEV; +} + +/* + * This function implements the MMIO based host to GuC interface. + */ +int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + u32 status; + int i; + int ret; + + GEM_BUG_ON(!len); + GEM_BUG_ON(len > guc->send_regs.count); + + /* If CT is available, we expect to use MMIO only during init/fini */ + GEM_BUG_ON(HAS_GUC_CT(dev_priv) && + *action != INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER && + *action != INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER); + + mutex_lock(&guc->send_mutex); + intel_uncore_forcewake_get(dev_priv, guc->send_regs.fw_domains); + + for (i = 0; i < len; i++) + I915_WRITE(guc_send_reg(guc, i), action[i]); + + POSTING_READ(guc_send_reg(guc, i - 1)); + + intel_guc_notify(guc); + + /* + * No GuC command should ever take longer than 10ms. + * Fast commands should still complete in 10us. + */ + ret = __intel_wait_for_register_fw(dev_priv, + guc_send_reg(guc, 0), + INTEL_GUC_RECV_MASK, + INTEL_GUC_RECV_MASK, + 10, 10, &status); + if (status != INTEL_GUC_STATUS_SUCCESS) { + /* + * Either the GuC explicitly returned an error (which + * we convert to -EIO here) or no response at all was + * received within the timeout limit (-ETIMEDOUT) + */ + if (ret != -ETIMEDOUT) + ret = -EIO; + + DRM_WARN("INTEL_GUC_SEND: Action 0x%X failed;" + " ret=%d status=0x%08X response=0x%08X\n", + action[0], ret, status, I915_READ(SOFT_SCRATCH(15))); + } + + intel_uncore_forcewake_put(dev_priv, guc->send_regs.fw_domains); + mutex_unlock(&guc->send_mutex); + + return ret; +} + +int intel_guc_sample_forcewake(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + u32 action[2]; + + action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE; + /* WaRsDisableCoarsePowerGating:skl,bxt */ + if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv)) + action[1] = 0; + else + /* bit 0 and 1 are for Render and Media domain separately */ + action[1] = GUC_FORCEWAKE_RENDER | GUC_FORCEWAKE_MEDIA; + + return intel_guc_send(guc, action, ARRAY_SIZE(action)); +} + +/** + * intel_guc_auth_huc() - Send action to GuC to authenticate HuC ucode + * @guc: intel_guc structure + * @rsa_offset: rsa offset w.r.t ggtt base of huc vma + * + * Triggers a HuC firmware authentication request to the GuC via intel_guc_send + * INTEL_GUC_ACTION_AUTHENTICATE_HUC interface. This function is invoked by + * intel_huc_auth(). + * + * Return: non-zero code on error + */ +int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset) +{ + u32 action[] = { + INTEL_GUC_ACTION_AUTHENTICATE_HUC, + rsa_offset + }; + + return intel_guc_send(guc, action, ARRAY_SIZE(action)); +} + +/** + * intel_guc_suspend() - notify GuC entering suspend state + * @dev_priv: i915 device private + */ +int intel_guc_suspend(struct drm_i915_private *dev_priv) +{ + struct intel_guc *guc = &dev_priv->guc; + struct i915_gem_context *ctx; + u32 data[3]; + + if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) + return 0; + + gen9_disable_guc_interrupts(dev_priv); + + ctx = dev_priv->kernel_context; + + data[0] = INTEL_GUC_ACTION_ENTER_S_STATE; + /* any value greater than GUC_POWER_D0 */ + data[1] = GUC_POWER_D1; + /* first page is shared data with GuC */ + data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + + LRC_GUCSHR_PN * PAGE_SIZE; + + return intel_guc_send(guc, data, ARRAY_SIZE(data)); +} + +/** + * intel_guc_resume() - notify GuC resuming from suspend state + * @dev_priv: i915 device private + */ +int intel_guc_resume(struct drm_i915_private *dev_priv) +{ + struct intel_guc *guc = &dev_priv->guc; + struct i915_gem_context *ctx; + u32 data[3]; + + if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) + return 0; + + if (i915_modparams.guc_log_level >= 0) + gen9_enable_guc_interrupts(dev_priv); + + ctx = dev_priv->kernel_context; + + data[0] = INTEL_GUC_ACTION_EXIT_S_STATE; + data[1] = GUC_POWER_D0; + /* first page is shared data with GuC */ + data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + + LRC_GUCSHR_PN * PAGE_SIZE; + + return intel_guc_send(guc, data, ARRAY_SIZE(data)); +} + +/** + * intel_guc_allocate_vma() - Allocate a GGTT VMA for GuC usage + * @guc: the guc + * @size: size of area to allocate (both virtual space and memory) + * + * This is a wrapper to create an object for use with the GuC. In order to + * use it inside the GuC, an object needs to be pinned lifetime, so we allocate + * both some backing storage and a range inside the Global GTT. We must pin + * it in the GGTT somewhere other than than [0, GUC_WOPCM_TOP) because that + * range is reserved inside GuC. + * + * Return: A i915_vma if successful, otherwise an ERR_PTR. + */ +struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + int ret; + + obj = i915_gem_object_create(dev_priv, size); + if (IS_ERR(obj)) + return ERR_CAST(obj); + + vma = i915_vma_instance(obj, &dev_priv->ggtt.base, NULL); + if (IS_ERR(vma)) + goto err; + + ret = i915_vma_pin(vma, 0, PAGE_SIZE, + PIN_GLOBAL | PIN_OFFSET_BIAS | GUC_WOPCM_TOP); + if (ret) { + vma = ERR_PTR(ret); + goto err; + } + + return vma; + +err: + i915_gem_object_put(obj); + return vma; +} diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h new file mode 100644 index 000000000000..094d64980882 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -0,0 +1,109 @@ +/* + * Copyright © 2014-2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef _INTEL_GUC_H_ +#define _INTEL_GUC_H_ + +#include "intel_uncore.h" +#include "intel_guc_fwif.h" +#include "intel_guc_ct.h" +#include "intel_guc_log.h" +#include "intel_uc_fw.h" +#include "i915_guc_reg.h" +#include "i915_vma.h" + +struct intel_guc { + struct intel_uc_fw fw; + struct intel_guc_log log; + struct intel_guc_ct ct; + + /* Log snapshot if GuC errors during load */ + struct drm_i915_gem_object *load_err_log; + + /* intel_guc_recv interrupt related state */ + bool interrupts_enabled; + + struct i915_vma *ads_vma; + struct i915_vma *stage_desc_pool; + void *stage_desc_pool_vaddr; + struct ida stage_ids; + + struct i915_guc_client *execbuf_client; + + DECLARE_BITMAP(doorbell_bitmap, GUC_NUM_DOORBELLS); + uint32_t db_cacheline; /* Cyclic counter mod pagesize */ + + /* GuC's FW specific registers used in MMIO send */ + struct { + u32 base; + unsigned int count; + enum forcewake_domains fw_domains; + } send_regs; + + /* To serialize the intel_guc_send actions */ + struct mutex send_mutex; + + /* GuC's FW specific send function */ + int (*send)(struct intel_guc *guc, const u32 *data, u32 len); + + /* GuC's FW specific notify function */ + void (*notify)(struct intel_guc *guc); +}; + +static +inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len) +{ + return guc->send(guc, action, len); +} + +static inline void intel_guc_notify(struct intel_guc *guc) +{ + guc->notify(guc); +} + +static inline u32 guc_ggtt_offset(struct i915_vma *vma) +{ + u32 offset = i915_ggtt_offset(vma); + + GEM_BUG_ON(offset < GUC_WOPCM_TOP); + GEM_BUG_ON(range_overflows_t(u64, offset, vma->size, GUC_GGTT_TOP)); + + return offset; +} + +void intel_guc_init_early(struct intel_guc *guc); +void intel_guc_init_send_regs(struct intel_guc *guc); +int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len); +int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len); +int intel_guc_sample_forcewake(struct intel_guc *guc); +int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset); +int intel_guc_suspend(struct drm_i915_private *dev_priv); +int intel_guc_resume(struct drm_i915_private *dev_priv); +struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); + +int intel_guc_select_fw(struct intel_guc *guc); +int intel_guc_init_hw(struct intel_guc *guc); +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 770bac462441..cb9f13f54a80 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -82,25 +82,9 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv) i915_modparams.enable_guc_submission = HAS_GUC_SCHED(dev_priv); } -static void gen8_guc_raise_irq(struct intel_guc *guc) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - - I915_WRITE(GUC_SEND_INTERRUPT, GUC_SEND_TRIGGER); -} - -static void guc_init_early(struct intel_guc *guc) -{ - intel_guc_ct_init_early(&guc->ct); - - mutex_init(&guc->send_mutex); - guc->send = intel_guc_send_nop; - guc->notify = gen8_guc_raise_irq; -} - void intel_uc_init_early(struct drm_i915_private *dev_priv) { - guc_init_early(&dev_priv->guc); + intel_guc_init_early(&dev_priv->guc); } void intel_uc_init_fw(struct drm_i915_private *dev_priv) @@ -115,32 +99,6 @@ void intel_uc_fini_fw(struct drm_i915_private *dev_priv) intel_uc_fw_fini(&dev_priv->huc.fw); } -static inline i915_reg_t guc_send_reg(struct intel_guc *guc, u32 i) -{ - GEM_BUG_ON(!guc->send_regs.base); - GEM_BUG_ON(!guc->send_regs.count); - GEM_BUG_ON(i >= guc->send_regs.count); - - return _MMIO(guc->send_regs.base + 4 * i); -} - -static void guc_init_send_regs(struct intel_guc *guc) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - enum forcewake_domains fw_domains = 0; - unsigned int i; - - guc->send_regs.base = i915_mmio_reg_offset(SOFT_SCRATCH(0)); - guc->send_regs.count = SOFT_SCRATCH_COUNT - 1; - - for (i = 0; i < guc->send_regs.count; i++) { - fw_domains |= intel_uncore_forcewake_for_reg(dev_priv, - guc_send_reg(guc, i), - FW_REG_READ | FW_REG_WRITE); - } - guc->send_regs.fw_domains = fw_domains; -} - /** * intel_uc_init_mmio - setup uC MMIO access * @@ -151,7 +109,7 @@ static void guc_init_send_regs(struct intel_guc *guc) */ void intel_uc_init_mmio(struct drm_i915_private *dev_priv) { - guc_init_send_regs(&dev_priv->guc); + intel_guc_init_send_regs(&dev_priv->guc); } static void guc_capture_load_err_log(struct intel_guc *guc) @@ -192,27 +150,6 @@ static void guc_disable_communication(struct intel_guc *guc) guc->send = intel_guc_send_nop; } -/** - * intel_guc_auth_huc() - Send action to GuC to authenticate HuC ucode - * @guc: intel_guc structure - * @rsa_offset: rsa offset w.r.t ggtt base of huc vma - * - * Triggers a HuC firmware authentication request to the GuC via intel_guc_send - * INTEL_GUC_ACTION_AUTHENTICATE_HUC interface. This function is invoked by - * intel_huc_auth(). - * - * Return: non-zero code on error - */ -int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset) -{ - u32 action[] = { - INTEL_GUC_ACTION_AUTHENTICATE_HUC, - rsa_offset - }; - - return intel_guc_send(guc, action, ARRAY_SIZE(action)); -} - int intel_uc_init_hw(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; @@ -344,82 +281,3 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv) i915_ggtt_disable_guc(dev_priv); } - -int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len) -{ - WARN(1, "Unexpected send: action=%#x\n", *action); - return -ENODEV; -} - -/* - * This function implements the MMIO based host to GuC interface. - */ -int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - u32 status; - int i; - int ret; - - GEM_BUG_ON(!len); - GEM_BUG_ON(len > guc->send_regs.count); - - /* If CT is available, we expect to use MMIO only during init/fini */ - GEM_BUG_ON(HAS_GUC_CT(dev_priv) && - *action != INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER && - *action != INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER); - - mutex_lock(&guc->send_mutex); - intel_uncore_forcewake_get(dev_priv, guc->send_regs.fw_domains); - - for (i = 0; i < len; i++) - I915_WRITE(guc_send_reg(guc, i), action[i]); - - POSTING_READ(guc_send_reg(guc, i - 1)); - - intel_guc_notify(guc); - - /* - * No GuC command should ever take longer than 10ms. - * Fast commands should still complete in 10us. - */ - ret = __intel_wait_for_register_fw(dev_priv, - guc_send_reg(guc, 0), - INTEL_GUC_RECV_MASK, - INTEL_GUC_RECV_MASK, - 10, 10, &status); - if (status != INTEL_GUC_STATUS_SUCCESS) { - /* - * Either the GuC explicitly returned an error (which - * we convert to -EIO here) or no response at all was - * received within the timeout limit (-ETIMEDOUT) - */ - if (ret != -ETIMEDOUT) - ret = -EIO; - - DRM_WARN("INTEL_GUC_SEND: Action 0x%X failed;" - " ret=%d status=0x%08X response=0x%08X\n", - action[0], ret, status, I915_READ(SOFT_SCRATCH(15))); - } - - intel_uncore_forcewake_put(dev_priv, guc->send_regs.fw_domains); - mutex_unlock(&guc->send_mutex); - - return ret; -} - -int intel_guc_sample_forcewake(struct intel_guc *guc) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - u32 action[2]; - - action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE; - /* WaRsDisableCoarsePowerGating:skl,bxt */ - if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv)) - action[1] = 0; - else - /* bit 0 and 1 are for Render and Media domain separately */ - action[1] = GUC_FORCEWAKE_RENDER | GUC_FORCEWAKE_MEDIA; - - return intel_guc_send(guc, action, ARRAY_SIZE(action)); -} diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 2f741a97007e..e18d3bb02088 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -24,54 +24,9 @@ #ifndef _INTEL_UC_H_ #define _INTEL_UC_H_ -#include "intel_uc_fw.h" -#include "intel_guc_fwif.h" -#include "i915_guc_reg.h" -#include "intel_ringbuffer.h" -#include "intel_guc_ct.h" -#include "intel_guc_log.h" -#include "i915_vma.h" +#include "intel_guc.h" #include "intel_huc.h" -struct intel_guc { - struct intel_uc_fw fw; - struct intel_guc_log log; - struct intel_guc_ct ct; - - /* Log snapshot if GuC errors during load */ - struct drm_i915_gem_object *load_err_log; - - /* intel_guc_recv interrupt related state */ - bool interrupts_enabled; - - struct i915_vma *ads_vma; - struct i915_vma *stage_desc_pool; - void *stage_desc_pool_vaddr; - struct ida stage_ids; - - struct i915_guc_client *execbuf_client; - - DECLARE_BITMAP(doorbell_bitmap, GUC_NUM_DOORBELLS); - uint32_t db_cacheline; /* Cyclic counter mod pagesize */ - - /* GuC's FW specific registers used in MMIO send */ - struct { - u32 base; - unsigned int count; - enum forcewake_domains fw_domains; - } send_regs; - - /* To serialize the intel_guc_send actions */ - struct mutex send_mutex; - - /* GuC's FW specific send function */ - int (*send)(struct intel_guc *guc, const u32 *data, u32 len); - - /* GuC's FW specific notify function */ - void (*notify)(struct intel_guc *guc); -}; - -/* intel_uc.c */ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv); void intel_uc_init_early(struct drm_i915_private *dev_priv); void intel_uc_init_mmio(struct drm_i915_private *dev_priv); @@ -79,36 +34,5 @@ void intel_uc_init_fw(struct drm_i915_private *dev_priv); void intel_uc_fini_fw(struct drm_i915_private *dev_priv); int intel_uc_init_hw(struct drm_i915_private *dev_priv); void intel_uc_fini_hw(struct drm_i915_private *dev_priv); -int intel_guc_sample_forcewake(struct intel_guc *guc); -int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len); -int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len); -int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset); - -static inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len) -{ - return guc->send(guc, action, len); -} - -static inline void intel_guc_notify(struct intel_guc *guc) -{ - guc->notify(guc); -} - -/* intel_guc_loader.c */ -int intel_guc_select_fw(struct intel_guc *guc); -int intel_guc_init_hw(struct intel_guc *guc); -int intel_guc_suspend(struct drm_i915_private *dev_priv); -int intel_guc_resume(struct drm_i915_private *dev_priv); -u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv); - -struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); - -static inline u32 guc_ggtt_offset(struct i915_vma *vma) -{ - u32 offset = i915_ggtt_offset(vma); - GEM_BUG_ON(offset < GUC_WOPCM_TOP); - GEM_BUG_ON(range_overflows_t(u64, offset, vma->size, GUC_GGTT_TOP)); - return offset; -} #endif -- cgit v1.2.3 From ddf79d88f3935604f3b7e3031a2325b7682a0518 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 18:13:42 +0000 Subject: drm/i915/uc: Fix includes order Fix includes order and make sure we only include required headers. Suggested-by: Chris Wilson Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004181343.66348-5-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index cb9f13f54a80..7b938e822fde 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -22,10 +22,9 @@ * */ -#include "i915_drv.h" #include "intel_uc.h" +#include "i915_drv.h" #include "i915_guc_submission.h" -#include /* Reset GuC providing us with fresh state for both GuC and HuC. */ -- cgit v1.2.3 From 959a3b6f57996af1c20232abeb7b0efd355134cc Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 4 Oct 2017 18:13:43 +0000 Subject: drm/i915/uc: Unify initialization of the uC firmware helper Unify initialization of the uC firmware helper as we want to maximize code reuse. Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171004181343.66348-6-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc_loader.c | 5 +---- drivers/gpu/drm/i915/intel_huc.c | 5 +---- drivers/gpu/drm/i915/intel_uc_fw.h | 9 +++++++++ 3 files changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index c9e25be4db40..c7a800a3798d 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -386,10 +386,7 @@ int intel_guc_select_fw(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); - guc->fw.path = NULL; - guc->fw.fetch_status = INTEL_UC_FIRMWARE_NONE; - guc->fw.load_status = INTEL_UC_FIRMWARE_NONE; - guc->fw.type = INTEL_UC_FW_TYPE_GUC; + intel_uc_fw_init(&guc->fw, INTEL_UC_FW_TYPE_GUC); if (i915_modparams.guc_firmware_path) { guc->fw.path = i915_modparams.guc_firmware_path; diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index 8b4b53525422..3f796fed35af 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c @@ -150,10 +150,7 @@ void intel_huc_select_fw(struct intel_huc *huc) { struct drm_i915_private *dev_priv = huc_to_i915(huc); - huc->fw.path = NULL; - huc->fw.fetch_status = INTEL_UC_FIRMWARE_NONE; - huc->fw.load_status = INTEL_UC_FIRMWARE_NONE; - huc->fw.type = INTEL_UC_FW_TYPE_HUC; + intel_uc_fw_init(&huc->fw, INTEL_UC_FW_TYPE_HUC); if (i915_modparams.huc_firmware_path) { huc->fw.path = i915_modparams.huc_firmware_path; diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index 849b2ce685c0..fcaf59718300 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -91,6 +91,15 @@ static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type) return "uC"; } +static inline +void intel_uc_fw_init(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type) +{ + uc_fw->path = NULL; + uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE; + uc_fw->load_status = INTEL_UC_FIRMWARE_NONE; + uc_fw->type = type; +} + void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, struct intel_uc_fw *uc_fw); void intel_uc_fw_fini(struct intel_uc_fw *uc_fw); -- cgit v1.2.3 From 51c4fa6903f958dff1221b2986329b9c6de9db57 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Oct 2017 13:52:10 +0300 Subject: drm/i915: push DDI CRT underrun reporting on enable to encoder CRT being the only PCH encoder, we can simplify the crtc enable by pushing the PCH encoder specific parts to CRT encoder. v2: add separate hsw_enable_crt (Daniel), rebase Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b117fb524fc571837c83292194fc2ad35e588ec9.1507200657.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_crt.c | 51 +++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_display.c | 14 +--------- 2 files changed, 51 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 954070255b4d..6d57c92ac999 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -227,6 +227,52 @@ static void hsw_post_disable_crt(struct intel_encoder *encoder, intel_ddi_fdi_post_disable(encoder, old_crtc_state, old_conn_state); } +static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config, + const struct drm_connector_state *conn_state) +{ + struct drm_crtc *crtc = pipe_config->base.crtc; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + WARN_ON(!intel_crtc->config->has_pch_encoder); + + intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); +} + +static void hsw_pre_enable_crt(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config, + const struct drm_connector_state *conn_state) +{ + struct drm_crtc *crtc = pipe_config->base.crtc; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + + WARN_ON(!intel_crtc->config->has_pch_encoder); + + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); +} + +static void hsw_enable_crt(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config, + const struct drm_connector_state *conn_state) +{ + struct drm_crtc *crtc = pipe_config->base.crtc; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + + WARN_ON(!intel_crtc->config->has_pch_encoder); + + intel_crt_set_dpms(encoder, pipe_config, DRM_MODE_DPMS_ON); + + intel_wait_for_vblank(dev_priv, pipe); + intel_wait_for_vblank(dev_priv, pipe); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); +} + static void intel_enable_crt(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) @@ -897,7 +943,6 @@ void intel_crt_init(struct drm_i915_private *dev_priv) } else { crt->base.disable = intel_disable_crt; } - crt->base.enable = intel_enable_crt; if (I915_HAS_HOTPLUG(dev_priv) && !dmi_check_system(intel_spurious_crt_detect)) crt->base.hpd_pin = HPD_CRT; @@ -905,11 +950,15 @@ void intel_crt_init(struct drm_i915_private *dev_priv) crt->base.port = PORT_E; crt->base.get_config = hsw_crt_get_config; crt->base.get_hw_state = intel_ddi_get_hw_state; + crt->base.pre_pll_enable = hsw_pre_pll_enable_crt; + crt->base.pre_enable = hsw_pre_enable_crt; + crt->base.enable = hsw_enable_crt; crt->base.post_disable = hsw_post_disable_crt; } else { crt->base.port = PORT_NONE; crt->base.get_config = intel_crt_get_config; crt->base.get_hw_state = intel_crt_get_hw_state; + crt->base.enable = intel_enable_crt; } intel_connector->get_hw_state = intel_connector_get_hw_state; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cdb2e25a577c..6f275c930fd5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5488,9 +5488,6 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, if (WARN_ON(intel_crtc->active)) return; - if (intel_crtc->config->has_pch_encoder) - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); - intel_encoders_pre_pll_enable(crtc, pipe_config, old_state); if (intel_crtc->config->shared_dpll) @@ -5524,9 +5521,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, intel_crtc->active = true; - if (intel_crtc->config->has_pch_encoder) - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - else + if (!intel_crtc->config->has_pch_encoder) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); intel_encoders_pre_enable(crtc, pipe_config, old_state); @@ -5581,13 +5576,6 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false); } - if (intel_crtc->config->has_pch_encoder) { - intel_wait_for_vblank(dev_priv, pipe); - intel_wait_for_vblank(dev_priv, pipe); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); - } - /* If we change the relative order between pipe/planes enabling, we need * to change the workaround. */ hsw_workaround_pipe = pipe_config->hsw_workaround_pipe; -- cgit v1.2.3 From 3daa3cee6ebc3e55da5ad70d61482029905f4b7d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Oct 2017 13:52:11 +0300 Subject: drm/i915: push DDI CRT underrun reporting on disable to encoder CRT being the only PCH encoder, we can simplify the crtc disable by pushing the PCH encoder specific parts to CRT encoder. v2: add hsw_disable_crt (Daniel), rebase Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1ecbbb946f7b3782ee3d97f0ec2fe4758c349311.1507200657.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_crt.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 6 ------ 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 6d57c92ac999..b43e8e16da37 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -213,6 +213,19 @@ static void pch_post_disable_crt(struct intel_encoder *encoder, intel_disable_crt(encoder, old_crtc_state, old_conn_state); } +static void hsw_disable_crt(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + struct drm_crtc *crtc = old_crtc_state->base.crtc; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + WARN_ON(!intel_crtc->config->has_pch_encoder); + + intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); +} + static void hsw_post_disable_crt(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) @@ -225,6 +238,10 @@ static void hsw_post_disable_crt(struct intel_encoder *encoder, lpt_disable_iclkip(dev_priv); intel_ddi_fdi_post_disable(encoder, old_crtc_state, old_conn_state); + + WARN_ON(!old_crtc_state->has_pch_encoder); + + intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder, @@ -953,6 +970,7 @@ void intel_crt_init(struct drm_i915_private *dev_priv) crt->base.pre_pll_enable = hsw_pre_pll_enable_crt; crt->base.pre_enable = hsw_pre_enable_crt; crt->base.enable = hsw_enable_crt; + crt->base.disable = hsw_disable_crt; crt->base.post_disable = hsw_post_disable_crt; } else { crt->base.port = PORT_NONE; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6f275c930fd5..9058cdfb0649 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5669,9 +5669,6 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; - if (intel_crtc->config->has_pch_encoder) - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); - intel_encoders_disable(crtc, old_crtc_state, old_state); drm_crtc_vblank_off(crtc); @@ -5696,9 +5693,6 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state, intel_ddi_disable_pipe_clock(intel_crtc->config); intel_encoders_post_disable(crtc, old_crtc_state, old_state); - - if (old_crtc_state->has_pch_encoder) - intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } static void i9xx_pfit_enable(struct intel_crtc *crtc) -- cgit v1.2.3 From 364a3fe1823549625f2f1ff1cb26733667052da7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Oct 2017 13:52:12 +0300 Subject: drm/i915: push DDI and DSI underrun reporting on enable to encoder Simplify CRTC enable. v2: Don't forget DSI (Daniel) Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1ad8f3ccaed99a5f03e3d53345221a25ad0be50f.1507200657.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 8 ++++++++ drivers/gpu/drm/i915/intel_display.c | 3 --- drivers/gpu/drm/i915/intel_dsi.c | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f7c91bb9d13e..ce4b7335a78a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2213,8 +2213,16 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { + struct drm_crtc *crtc = pipe_config->base.crtc; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; int type = encoder->type; + WARN_ON(intel_crtc->config->has_pch_encoder); + + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { intel_ddi_pre_enable_dp(encoder, pipe_config->port_clock, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9058cdfb0649..b55944d8149b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5521,9 +5521,6 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, intel_crtc->active = true; - if (!intel_crtc->config->has_pch_encoder) - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); - intel_encoders_pre_enable(crtc, pipe_config, old_state); if (intel_crtc->config->has_pch_encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 20a7b004ffd7..66bbedc5fa01 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -790,14 +790,19 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct drm_crtc *crtc = pipe_config->base.crtc; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; enum port port; u32 val; bool glk_cold_boot = false; DRM_DEBUG_KMS("\n"); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + /* * The BIOS may leave the PLL in a wonky state where it doesn't * lock. It needs to be fully powered down to fix it. -- cgit v1.2.3 From 27d81c28eef1d44ddb95980e681d28807e9bce54 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Oct 2017 13:52:13 +0300 Subject: drm/i915: push DDI FDI link training on enable to CRT encoder Reduce encoder specific checks from CRTC code. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/6903136894ffcf47f7511900f3c8d53f760ef6b1.1507200657.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_crt.c | 2 ++ drivers/gpu/drm/i915/intel_display.c | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index b43e8e16da37..2abe556ccaf5 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -269,6 +269,8 @@ static void hsw_pre_enable_crt(struct intel_encoder *encoder, WARN_ON(!intel_crtc->config->has_pch_encoder); intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); + + dev_priv->display.fdi_link_train(intel_crtc, pipe_config); } static void hsw_enable_crt(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b55944d8149b..9f2bf3b3f759 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5523,9 +5523,6 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, intel_encoders_pre_enable(crtc, pipe_config, old_state); - if (intel_crtc->config->has_pch_encoder) - dev_priv->display.fdi_link_train(intel_crtc, pipe_config); - if (!transcoder_is_dsi(cpu_transcoder)) intel_ddi_enable_pipe_clock(pipe_config); -- cgit v1.2.3 From c5ce4ef3282bd42fd54cf581591d54f2b0a10c3b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Oct 2017 13:52:14 +0300 Subject: drm/i915/crt: clean up encoder hook assignment Only assign the hooks once instead of overwriting for DDI. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/796b631d018fdd5aa2a3608c6a9b9fa196a50f76.1507200657.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_crt.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 2abe556ccaf5..668e8c3e791d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -955,16 +955,11 @@ void intel_crt_init(struct drm_i915_private *dev_priv) crt->base.power_domain = POWER_DOMAIN_PORT_CRT; - crt->base.compute_config = intel_crt_compute_config; - if (HAS_PCH_SPLIT(dev_priv)) { - crt->base.disable = pch_disable_crt; - crt->base.post_disable = pch_post_disable_crt; - } else { - crt->base.disable = intel_disable_crt; - } if (I915_HAS_HOTPLUG(dev_priv) && !dmi_check_system(intel_spurious_crt_detect)) crt->base.hpd_pin = HPD_CRT; + + crt->base.compute_config = intel_crt_compute_config; if (HAS_DDI(dev_priv)) { crt->base.port = PORT_E; crt->base.get_config = hsw_crt_get_config; @@ -975,6 +970,12 @@ void intel_crt_init(struct drm_i915_private *dev_priv) crt->base.disable = hsw_disable_crt; crt->base.post_disable = hsw_post_disable_crt; } else { + if (HAS_PCH_SPLIT(dev_priv)) { + crt->base.disable = pch_disable_crt; + crt->base.post_disable = pch_post_disable_crt; + } else { + crt->base.disable = intel_disable_crt; + } crt->base.port = PORT_NONE; crt->base.get_config = intel_crt_get_config; crt->base.get_hw_state = intel_crt_get_hw_state; -- cgit v1.2.3 From 0c3767b28186c8129f2a2cfec06a93dcd6102391 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 5 Oct 2017 16:15:20 +0200 Subject: drm/i915: Use crtc_state_is_legacy_gamma in intel_color_check crtc_state_is_legacy_gamma also checks for CTM, which was missing from intel_color_check. By using the same condition for commit and check we reduce the chance of mismatches. This was spotted by KASAN while trying to rework kms_color igt test. [ 72.008660] ================================================================== [ 72.009326] BUG: KASAN: slab-out-of-bounds in bdw_load_gamma_lut.isra.3+0x15c/0x360 [i915] [ 72.009519] Read of size 2 at addr ffff880220216e50 by task kms_color/1158 [ 72.009900] CPU: 2 PID: 1158 Comm: kms_color Tainted: G U W 4.14.0-rc3-patser+ #5281 [ 72.009921] Hardware name: GIGABYTE GB-BKi3A-7100/MFLP3AP-00, BIOS F1 07/27/2016 [ 72.009941] Call Trace: [ 72.009968] dump_stack+0xc5/0x151 [ 72.009996] ? _atomic_dec_and_lock+0x10f/0x10f [ 72.010024] ? show_regs_print_info+0x3c/0x3c [ 72.010072] print_address_description+0x7f/0x240 [ 72.010108] kasan_report+0x216/0x370 [ 72.010308] ? bdw_load_gamma_lut.isra.3+0x15c/0x360 [i915] [ 72.010349] __asan_load2+0x74/0x80 [ 72.010552] bdw_load_gamma_lut.isra.3+0x15c/0x360 [i915] [ 72.010772] broadwell_load_luts+0x1f0/0x300 [i915] [ 72.010997] intel_color_load_luts+0x36/0x40 [i915] [ 72.011205] intel_begin_crtc_commit+0xa1/0x310 [i915] [ 72.011283] drm_atomic_helper_commit_planes_on_crtc+0xa6/0x320 [drm_kms_helper] [ 72.011316] ? wait_for_completion_io+0x460/0x460 [ 72.011524] intel_update_crtc+0xe3/0x100 [i915] [ 72.011720] skl_update_crtcs+0x360/0x3f0 [i915] [ 72.011945] ? intel_update_crtcs+0xf0/0xf0 [i915] [ 72.012010] ? drm_atomic_helper_wait_for_dependencies+0x3d9/0x400 [drm_kms_helper] [ 72.012231] intel_atomic_commit_tail+0x8db/0x1500 [i915] [ 72.012273] ? __lock_is_held+0x9c/0xc0 [ 72.012494] ? skl_update_crtcs+0x3f0/0x3f0 [i915] [ 72.012518] ? find_next_bit+0xb/0x10 [ 72.012544] ? cpumask_next+0x1a/0x20 [ 72.012745] ? i915_sw_fence_complete+0x9d/0xe0 [i915] [ 72.012938] ? __i915_sw_fence_complete+0x5d0/0x5d0 [i915] [ 72.013176] intel_atomic_commit+0x528/0x570 [i915] [ 72.013280] ? drm_atomic_get_property+0xc00/0xc00 [drm] [ 72.013466] ? intel_atomic_commit_tail+0x1500/0x1500 [i915] [ 72.013496] ? kmem_cache_alloc_trace+0x266/0x280 [ 72.013714] ? intel_atomic_commit_tail+0x1500/0x1500 [i915] [ 72.013812] drm_atomic_commit+0x77/0x80 [drm] [ 72.013911] set_property_atomic+0x14a/0x210 [drm] [ 72.014015] ? drm_object_property_get_value+0x70/0x70 [drm] [ 72.014080] ? mutex_unlock+0xd/0x10 [ 72.014292] ? intel_atomic_commit_tail+0x1500/0x1500 [i915] [ 72.014379] drm_mode_obj_set_property_ioctl+0x1cf/0x310 [drm] [ 72.014481] ? drm_mode_obj_find_prop_id+0xa0/0xa0 [drm] [ 72.014510] ? lock_release+0x6c0/0x6c0 [ 72.014602] ? drm_is_current_master+0x46/0x60 [drm] [ 72.014706] drm_ioctl_kernel+0x148/0x1d0 [drm] [ 72.014799] ? drm_mode_obj_find_prop_id+0xa0/0xa0 [drm] [ 72.014898] ? drm_ioctl_permit+0x100/0x100 [drm] [ 72.014936] ? kasan_check_write+0x14/0x20 [ 72.015039] drm_ioctl+0x441/0x660 [drm] [ 72.015129] ? drm_mode_obj_find_prop_id+0xa0/0xa0 [drm] [ 72.015235] ? drm_getstats+0x20/0x20 [drm] [ 72.015287] ? ___might_sleep+0x159/0x340 [ 72.015311] ? find_held_lock+0xcf/0xf0 [ 72.015341] ? __schedule_bug+0x110/0x110 [ 72.015405] do_vfs_ioctl+0xa88/0xb10 [ 72.015449] ? ioctl_preallocate+0x1a0/0x1a0 [ 72.015487] ? selinux_capable+0x20/0x20 [ 72.015525] ? rcu_dynticks_momentary_idle+0x40/0x40 [ 72.015607] SyS_ioctl+0x4e/0x80 [ 72.015647] entry_SYSCALL_64_fastpath+0x18/0xad [ 72.015670] RIP: 0033:0x7ff74a3d04d7 [ 72.015691] RSP: 002b:00007ffc594bec08 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 72.015734] RAX: ffffffffffffffda RBX: ffffffff8718f54a RCX: 00007ff74a3d04d7 [ 72.015756] RDX: 00007ffc594bec40 RSI: 00000000c01864ba RDI: 0000000000000003 [ 72.015777] RBP: ffff880211c0ff98 R08: 0000000000000086 R09: 0000000000000000 [ 72.015799] R10: 00007ff74a691b58 R11: 0000000000000246 R12: 0000000000000355 [ 72.015821] R13: 00000000ff00eb00 R14: 0000000000000a00 R15: 00007ff746082000 [ 72.015857] ? trace_hardirqs_off_caller+0xfa/0x110 Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20171005141520.23990-1-maarten.lankhorst@linux.intel.com [mlankhorst: s/crtc_state_is_legacy/&_gamma/ (danvet)] Reviewed-by: Daniel Vetter Fixes: 82cf435b3134 ("drm/i915: Implement color management on bdw/skl/bxt/kbl") Cc: # v4.7+ --- drivers/gpu/drm/i915/intel_color.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index ff9ecd211abb..b8315bca852b 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -74,7 +74,7 @@ #define I9XX_CSC_COEFF_1_0 \ ((7 << 12) | I9XX_CSC_COEFF_FP(CTM_COEFF_1_0, 8)) -static bool crtc_state_is_legacy(struct drm_crtc_state *state) +static bool crtc_state_is_legacy_gamma(struct drm_crtc_state *state) { return !state->degamma_lut && !state->ctm && @@ -288,7 +288,7 @@ static void cherryview_load_csc_matrix(struct drm_crtc_state *state) } mode = (state->ctm ? CGM_PIPE_MODE_CSC : 0); - if (!crtc_state_is_legacy(state)) { + if (!crtc_state_is_legacy_gamma(state)) { mode |= (state->degamma_lut ? CGM_PIPE_MODE_DEGAMMA : 0) | (state->gamma_lut ? CGM_PIPE_MODE_GAMMA : 0); } @@ -469,7 +469,7 @@ static void broadwell_load_luts(struct drm_crtc_state *state) struct intel_crtc_state *intel_state = to_intel_crtc_state(state); enum pipe pipe = to_intel_crtc(state->crtc)->pipe; - if (crtc_state_is_legacy(state)) { + if (crtc_state_is_legacy_gamma(state)) { haswell_load_luts(state); return; } @@ -529,7 +529,7 @@ static void glk_load_luts(struct drm_crtc_state *state) glk_load_degamma_lut(state); - if (crtc_state_is_legacy(state)) { + if (crtc_state_is_legacy_gamma(state)) { haswell_load_luts(state); return; } @@ -551,7 +551,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state) uint32_t i, lut_size; uint32_t word0, word1; - if (crtc_state_is_legacy(state)) { + if (crtc_state_is_legacy_gamma(state)) { /* Turn off degamma/gamma on CGM block. */ I915_WRITE(CGM_PIPE_MODE(pipe), (state->ctm ? CGM_PIPE_MODE_CSC : 0)); @@ -632,12 +632,10 @@ int intel_color_check(struct drm_crtc *crtc, return 0; /* - * We also allow no degamma lut and a gamma lut at the legacy + * We also allow no degamma lut/ctm and a gamma lut at the legacy * size (256 entries). */ - if (!crtc_state->degamma_lut && - crtc_state->gamma_lut && - crtc_state->gamma_lut->length == LEGACY_LUT_LENGTH) + if (crtc_state_is_legacy_gamma(crtc_state)) return 0; return -EINVAL; -- cgit v1.2.3 From baf41bc35f2bdb953da532645fd82009c2d12acf Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Wed, 13 Sep 2017 16:46:14 +0300 Subject: iwlwifi: mvm: do not print security error in monitor mode In monitor mode we are not expected to decrypt encrypted packets (not having the keys). Hence we are expected to get an unknown rx security status. Keeping the print in monitor mode causes a print for each captured packet flooding the dmesg. Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 7 +++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 +++ drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 4 +++- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 4 +++- 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3bcaa82f59b2..a9ac872226fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1077,6 +1077,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) mvm->vif_count = 0; mvm->rx_ba_sessions = 0; mvm->fwrt.dump.conf = FW_DBG_INVALID; + mvm->monitor_on = false; /* keep statistics ticking */ iwl_mvm_accu_radio_stats(mvm); @@ -1437,6 +1438,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, mvm->p2p_device_vif = vif; } + if (vif->type == NL80211_IFTYPE_MONITOR) + mvm->monitor_on = true; + iwl_mvm_vif_dbgfs_register(mvm, vif); goto out_unlock; @@ -1526,6 +1530,9 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, iwl_mvm_power_update_mac(mvm); iwl_mvm_mac_ctxt_remove(mvm, vif); + if (vif->type == NL80211_IFTYPE_MONITOR) + mvm->monitor_on = false; + out_release: mutex_unlock(&mvm->mutex); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 83303bac0e4b..d75da37a79f3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1015,6 +1015,9 @@ struct iwl_mvm { bool drop_bcn_ap_mode; struct delayed_work cs_tx_unblock_dwork; + + /* does a monitor vif exist (only one can exist hence bool) */ + bool monitor_on; #ifdef CONFIG_ACPI struct iwl_mvm_sar_profile sar_profiles[IWL_MVM_SAR_PROFILE_NUM]; struct iwl_mvm_geo_profile geo_profiles[IWL_NUM_GEO_PROFILES]; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 184c749766f2..2d14a58cbdd7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -244,7 +244,9 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm, return 0; default: - IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); + /* Expected in monitor (not having the keys) */ + if (!mvm->monitor_on) + IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); } return 0; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 77f77bc5d083..248699c2c4bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -277,7 +277,9 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, stats->flag |= RX_FLAG_DECRYPTED; return 0; default: - IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status); + /* Expected in monitor (not having the keys) */ + if (!mvm->monitor_on) + IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status); } return 0; -- cgit v1.2.3 From 1efc3843a4ee1331bc20df685a79b47fa0f547d2 Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Tue, 12 Sep 2017 12:32:25 +0300 Subject: iwlwifi: stop dbgc recording before stopping DMA Today we stop the device and the DMA without stopping the dbgc recording before. This causes host crashes when the DMA rate is high. Stop dbgc recording when clearing the fw debug configuration to fix this. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 7 ++----- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 6afc7a799892..f5dd7d83cd0a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1086,7 +1086,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { /* stop recording */ - iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100); + iwl_fw_dbg_stop_recording(fwrt); iwl_fw_error_dump(fwrt); @@ -1104,10 +1104,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) u32 in_sample = iwl_read_prph(fwrt->trans, DBGC_IN_SAMPLE); u32 out_ctrl = iwl_read_prph(fwrt->trans, DBGC_OUT_CTRL); - /* stop recording */ - iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0); - udelay(100); - iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0); + iwl_fw_dbg_stop_recording(fwrt); /* wait before we collect the data till the DBGC stop */ udelay(500); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 0f810ea89d31..9c889a32fe24 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -68,6 +68,8 @@ #include #include #include "runtime.h" +#include "iwl-prph.h" +#include "iwl-io.h" #include "file.h" #include "error-dump.h" @@ -194,8 +196,21 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, iwl_fw_dbg_get_trigger((fwrt)->fw,\ (trig))) +static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt) +{ + if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100); + } else { + iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0); + udelay(100); + iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0); + } +} + static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt) { + iwl_fw_dbg_stop_recording(fwrt); + fwrt->dump.conf = FW_DBG_INVALID; } -- cgit v1.2.3 From 1442a9a9f2e441b15393c2d89286303b103a57e8 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 18 Sep 2017 14:39:26 +0300 Subject: iwlwifi: mvm: return -ENODATA when reading the temperature with the FW down It seems that libsensors treats -EIO as a special non-recoverable failure when it tries to read the temperature while the firmware is not running. To solve that, change the error code to a milder -ENODATA. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=196941 Fixes: c221daf219b1 ("iwlwifi: mvm: add registration to thermal zone") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index 4d907f60bce9..1232f63278eb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -631,7 +631,7 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device, if (!iwl_mvm_firmware_running(mvm) || mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) { - ret = -EIO; + ret = -ENODATA; goto out; } -- cgit v1.2.3 From d8c73e455d7b973d1346bb5632b4a41819b090c9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Sep 2017 11:03:50 +0200 Subject: iwlwifi: nvm-parse: unify channel flags printing The current channel flags printing is very strange and messy, in LAR we sometimes print the channel number and sometimes the frequency, in both we print a calculated value (whether ad-hoc is supported or not) etc. Unify all this to * print the channel number, not the frequency * remove the band print (2.4/5.2 GHz, it's obvious) * remove the calculated Ad-Hoc print Doing all of this also gets the length of the string to a max of 101 characters, which is below the max of 110 for tracing, and thus avoids the warning that came up on certain channels with certain flag combinations. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 98 +++++++++------------- 1 file changed, 39 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 3014beef4873..35638404c24e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -206,8 +206,36 @@ enum iwl_nvm_channel_flags { NVM_CHANNEL_DC_HIGH = BIT(12), }; +static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level, + int chan, u16 flags) +{ #define CHECK_AND_PRINT_I(x) \ - ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "") + ((flags & NVM_CHANNEL_##x) ? " " #x : "") + + if (!(flags & NVM_CHANNEL_VALID)) { + IWL_DEBUG_DEV(dev, level, "Ch. %d: 0x%x: No traffic\n", + chan, flags); + return; + } + + /* Note: already can print up to 101 characters, 110 is the limit! */ + IWL_DEBUG_DEV(dev, level, + "Ch. %d: 0x%x:%s%s%s%s%s%s%s%s%s%s%s%s\n", + chan, flags, + CHECK_AND_PRINT_I(VALID), + CHECK_AND_PRINT_I(IBSS), + CHECK_AND_PRINT_I(ACTIVE), + CHECK_AND_PRINT_I(RADAR), + CHECK_AND_PRINT_I(INDOOR_ONLY), + CHECK_AND_PRINT_I(GO_CONCURRENT), + CHECK_AND_PRINT_I(UNIFORM), + CHECK_AND_PRINT_I(20MHZ), + CHECK_AND_PRINT_I(40MHZ), + CHECK_AND_PRINT_I(80MHZ), + CHECK_AND_PRINT_I(160MHZ), + CHECK_AND_PRINT_I(DC_HIGH)); +#undef CHECK_AND_PRINT_I +} static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, u16 nvm_flags, const struct iwl_cfg *cfg) @@ -302,12 +330,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, * supported, hence we still want to add them to * the list of supported channels to cfg80211. */ - IWL_DEBUG_EEPROM(dev, - "Ch. %d Flags %x [%sGHz] - No traffic\n", - nvm_chan[ch_idx], - ch_flags, - (ch_idx >= num_2ghz_channels) ? - "5.2" : "2.4"); + iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, + nvm_chan[ch_idx], ch_flags); continue; } @@ -337,27 +361,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, else channel->flags = 0; - IWL_DEBUG_EEPROM(dev, - "Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n", - channel->hw_value, - is_5ghz ? "5.2" : "2.4", - ch_flags, - CHECK_AND_PRINT_I(VALID), - CHECK_AND_PRINT_I(IBSS), - CHECK_AND_PRINT_I(ACTIVE), - CHECK_AND_PRINT_I(RADAR), - CHECK_AND_PRINT_I(INDOOR_ONLY), - CHECK_AND_PRINT_I(GO_CONCURRENT), - CHECK_AND_PRINT_I(UNIFORM), - CHECK_AND_PRINT_I(20MHZ), - CHECK_AND_PRINT_I(40MHZ), - CHECK_AND_PRINT_I(80MHZ), - CHECK_AND_PRINT_I(160MHZ), - CHECK_AND_PRINT_I(DC_HIGH), - channel->max_power, - ((ch_flags & NVM_CHANNEL_IBSS) && - !(ch_flags & NVM_CHANNEL_RADAR)) - ? "" : "not "); + iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, + channel->hw_value, ch_flags); + IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n", + channel->hw_value, channel->max_power); } return n_channels; @@ -873,12 +880,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, new_rule = false; if (!(ch_flags & NVM_CHANNEL_VALID)) { - IWL_DEBUG_DEV(dev, IWL_DL_LAR, - "Ch. %d Flags %x [%sGHz] - No traffic\n", - nvm_chan[ch_idx], - ch_flags, - (ch_idx >= NUM_2GHZ_CHANNELS) ? - "5.2" : "2.4"); + iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, + nvm_chan[ch_idx], ch_flags); continue; } @@ -914,31 +917,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, prev_center_freq = center_freq; prev_reg_rule_flags = reg_rule_flags; - IWL_DEBUG_DEV(dev, IWL_DL_LAR, - "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x)\n", - center_freq, - band == NL80211_BAND_5GHZ ? "5.2" : "2.4", - CHECK_AND_PRINT_I(VALID), - CHECK_AND_PRINT_I(IBSS), - CHECK_AND_PRINT_I(ACTIVE), - CHECK_AND_PRINT_I(RADAR), - CHECK_AND_PRINT_I(INDOOR_ONLY), - CHECK_AND_PRINT_I(GO_CONCURRENT), - CHECK_AND_PRINT_I(UNIFORM), - CHECK_AND_PRINT_I(20MHZ), - CHECK_AND_PRINT_I(40MHZ), - CHECK_AND_PRINT_I(80MHZ), - CHECK_AND_PRINT_I(160MHZ), - CHECK_AND_PRINT_I(DC_HIGH), - ch_flags); - IWL_DEBUG_DEV(dev, IWL_DL_LAR, - "Ch. %d [%sGHz] reg_flags 0x%x: %s\n", - center_freq, - band == NL80211_BAND_5GHZ ? "5.2" : "2.4", - reg_rule_flags, - ((ch_flags & NVM_CHANNEL_ACTIVE) && - !(ch_flags & NVM_CHANNEL_RADAR)) - ? "Ad-Hoc" : ""); + iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, + nvm_chan[ch_idx], ch_flags); } regd->n_reg_rules = valid_rules; -- cgit v1.2.3 From 44fd09dad5d2b78efbabbbbf623774e561e36cca Mon Sep 17 00:00:00 2001 From: Chaya Rachel Ivgi Date: Mon, 4 Sep 2017 14:40:06 +0300 Subject: iwlwifi: nvm: set the correct offsets to 3168 series The driver currently handles two NVM formats, one for 7000 family and below, and one for 8000 family and above. The 3168 series uses something in between, so currently the driver uses incorrect offsets for it. Fix the incorrect offsets. Fixes: c4836b056d83 ("iwlwifi: Add PCI IDs for the new 3168 series") Signed-off-by: Chaya Rachel Ivgi Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 1 + drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 2 +- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 2 +- drivers/net/wireless/intel/iwlwifi/cfg/a000.c | 2 +- .../net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | 2 ++ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 16 +++++++-- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 39 +++++++++++++--------- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 21 ++++++++---- 9 files changed, 59 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c index 45e2efc70d19..ce741beec1fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c @@ -309,6 +309,7 @@ const struct iwl_cfg iwl3168_2ac_cfg = { .nvm_calib_ver = IWL3168_TX_POWER_VERSION, .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, .dccm_len = IWL7265_DCCM_LEN, + .nvm_type = IWL_NVM_SDP, }; const struct iwl_cfg iwl7265_2ac_cfg = { diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c index 2e6c52664cee..c2a5936ccede 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -164,7 +164,7 @@ static const struct iwl_tt_params iwl8000_tt_params = { .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, \ .thermal_params = &iwl8000_tt_params, \ .apmg_not_supported = true, \ - .ext_nvm = true, \ + .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true #define IWL_DEVICE_8000 \ diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index 2babe0a1f18b..e8b5ff42f5a8 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -148,7 +148,7 @@ static const struct iwl_tt_params iwl9000_tt_params = { .vht_mu_mimo_supported = true, \ .mac_addr_from_csr = true, \ .rf_id = true, \ - .ext_nvm = true, \ + .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true const struct iwl_cfg iwl9160_2ac_cfg = { diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c index 76ba1f8bc72f..a440140ed8dd 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c @@ -133,7 +133,7 @@ static const struct iwl_ht_params iwl_a000_ht_params = { .use_tfh = true, \ .rf_id = true, \ .gen2 = true, \ - .ext_nvm = true, \ + .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true const struct iwl_cfg iwla000_2ac_cfg_hr = { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index 00bc7a25dece..3fd07bc80f54 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -108,6 +108,7 @@ enum iwl_nvm_access_target { * @NVM_SECTION_TYPE_REGULATORY: regulatory section * @NVM_SECTION_TYPE_CALIBRATION: calibration section * @NVM_SECTION_TYPE_PRODUCTION: production section + * @NVM_SECTION_TYPE_REGULATORY_SDP: regulatory section used by 3168 series * @NVM_SECTION_TYPE_MAC_OVERRIDE: MAC override section * @NVM_SECTION_TYPE_PHY_SKU: PHY SKU section * @NVM_MAX_NUM_SECTIONS: number of sections @@ -117,6 +118,7 @@ enum iwl_nvm_section_type { NVM_SECTION_TYPE_REGULATORY = 3, NVM_SECTION_TYPE_CALIBRATION = 4, NVM_SECTION_TYPE_PRODUCTION = 5, + NVM_SECTION_TYPE_REGULATORY_SDP = 8, NVM_SECTION_TYPE_MAC_OVERRIDE = 11, NVM_SECTION_TYPE_PHY_SKU = 12, NVM_MAX_NUM_SECTIONS = 13, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 3e057b539d5b..71cb1ecde0f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -108,6 +108,18 @@ enum iwl_led_mode { IWL_LED_DISABLE, }; +/** + * enum iwl_nvm_type - nvm formats + * @IWL_NVM: the regular format + * @IWL_NVM_EXT: extended NVM format + * @IWL_NVM_SDP: NVM format used by 3168 series + */ +enum iwl_nvm_type { + IWL_NVM, + IWL_NVM_EXT, + IWL_NVM_SDP, +}; + /* * This is the threshold value of plcp error rate per 100mSecs. It is * used to set and check for the validity of plcp_delta. @@ -320,7 +332,7 @@ struct iwl_pwr_tx_backoff { * @integrated: discrete or integrated * @gen2: a000 and on transport operation * @cdb: CDB support - * @ext_nvm: extended NVM format + * @nvm_type: see &enum iwl_nvm_type * * We enable the driver to be backward compatible wrt. hardware features. * API differences in uCode shouldn't be handled here but through TLVs @@ -342,6 +354,7 @@ struct iwl_cfg { const struct iwl_tt_params *thermal_params; enum iwl_device_family device_family; enum iwl_led_mode led_mode; + enum iwl_nvm_type nvm_type; u32 max_data_size; u32 max_inst_size; netdev_features_t features; @@ -369,7 +382,6 @@ struct iwl_cfg { use_tfh:1, gen2:1, cdb:1, - ext_nvm:1, dbgc_supported:1; u8 valid_tx_ant; u8 valid_rx_ant; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 35638404c24e..c3a5d8ccc95e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -77,7 +77,7 @@ #include "iwl-csr.h" /* NVM offsets (in words) definitions */ -enum wkp_nvm_offsets { +enum nvm_offsets { /* NVM HW-Section offset (in words) definitions */ SUBSYSTEM_ID = 0x0A, HW_ADDR = 0x15, @@ -92,7 +92,10 @@ enum wkp_nvm_offsets { /* NVM calibration section offset (in words) definitions */ NVM_CALIB_SECTION = 0x2B8, - XTAL_CALIB = 0x316 - NVM_CALIB_SECTION + XTAL_CALIB = 0x316 - NVM_CALIB_SECTION, + + /* NVM REGULATORY -Section offset (in words) definitions */ + NVM_CHANNELS_SDP = 0, }; enum ext_nvm_offsets { @@ -243,7 +246,7 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, u32 flags = IEEE80211_CHAN_NO_HT40; u32 last_5ghz_ht = LAST_5GHZ_HT; - if (cfg->ext_nvm) + if (cfg->nvm_type == IWL_NVM_EXT) last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) { @@ -296,7 +299,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, int num_of_ch, num_2ghz_channels; const u8 *nvm_chan; - if (!cfg->ext_nvm) { + if (cfg->nvm_type != IWL_NVM_EXT) { num_of_ch = IWL_NUM_CHANNELS; nvm_chan = &iwl_nvm_channels[0]; num_2ghz_channels = NUM_2GHZ_CHANNELS; @@ -491,7 +494,7 @@ IWL_EXPORT_SYMBOL(iwl_init_sbands); static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, const __le16 *phy_sku) { - if (!cfg->ext_nvm) + if (cfg->nvm_type != IWL_NVM_EXT) return le16_to_cpup(nvm_sw + SKU); return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); @@ -499,7 +502,7 @@ static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) { - if (!cfg->ext_nvm) + if (cfg->nvm_type != IWL_NVM_EXT) return le16_to_cpup(nvm_sw + NVM_VERSION); else return le32_to_cpup((__le32 *)(nvm_sw + @@ -509,7 +512,7 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, const __le16 *phy_sku) { - if (!cfg->ext_nvm) + if (cfg->nvm_type != IWL_NVM_EXT) return le16_to_cpup(nvm_sw + RADIO_CFG); return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM)); @@ -520,7 +523,7 @@ static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw) { int n_hw_addr; - if (!cfg->ext_nvm) + if (cfg->nvm_type != IWL_NVM_EXT) return le16_to_cpup(nvm_sw + N_HW_ADDRS); n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); @@ -532,7 +535,7 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg, struct iwl_nvm_data *data, u32 radio_cfg) { - if (!cfg->ext_nvm) { + if (cfg->nvm_type != IWL_NVM_EXT) { data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg); data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg); data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg); @@ -641,7 +644,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans, { if (cfg->mac_addr_from_csr) { iwl_set_hw_address_from_csr(trans, data); - } else if (!cfg->ext_nvm) { + } else if (cfg->nvm_type != IWL_NVM_EXT) { const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR); /* The byte order is little endian 16 bit, meaning 214365 */ @@ -713,7 +716,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, u16 lar_config; const __le16 *ch_section; - if (!cfg->ext_nvm) + if (cfg->nvm_type != IWL_NVM_EXT) data = kzalloc(sizeof(*data) + sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, @@ -747,7 +750,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); - if (!cfg->ext_nvm) { + if (cfg->nvm_type != IWL_NVM_EXT) { /* Checking for required sections */ if (!nvm_calib) { IWL_ERR(trans, @@ -755,11 +758,15 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, kfree(data); return NULL; } + + ch_section = cfg->nvm_type == IWL_NVM_SDP ? + ®ulatory[NVM_CHANNELS_SDP] : + &nvm_sw[NVM_CHANNELS]; + /* in family 8000 Xtal calibration values moved to OTP */ data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); lar_enabled = true; - ch_section = &nvm_sw[NVM_CHANNELS]; } else { u16 lar_offset = data->nvm_version < 0xE39 ? NVM_LAR_OFFSET_OLD : @@ -793,7 +800,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan, u32 flags = NL80211_RRF_NO_HT40; u32 last_5ghz_ht = LAST_5GHZ_HT; - if (cfg->ext_nvm) + if (cfg->nvm_type == IWL_NVM_EXT) last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; if (ch_idx < NUM_2GHZ_CHANNELS && @@ -841,7 +848,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, int ch_idx; u16 ch_flags; u32 reg_rule_flags, prev_reg_rule_flags = 0; - const u8 *nvm_chan = cfg->ext_nvm ? + const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ? iwl_ext_nvm_channels : iwl_nvm_channels; struct ieee80211_regdomain *regd; int size_of_regd; @@ -850,7 +857,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, int center_freq, prev_center_freq = 0; int valid_rules = 0; bool new_rule; - int max_num_ch = cfg->ext_nvm ? + int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS; if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index d75da37a79f3..949e63418299 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1162,7 +1162,7 @@ static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm) * Enable LAR only if it is supported by the FW (TLV) && * enabled in the NVM */ - if (mvm->cfg->ext_nvm) + if (mvm->cfg->nvm_type == IWL_NVM_EXT) return nvm_lar && tlv_lar; else return tlv_lar; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index 422aa6be9932..fb25b6f29323 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -295,18 +295,24 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) const __be16 *hw; const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku; bool lar_enabled; + int regulatory_type; /* Checking for required sections */ - if (!mvm->trans->cfg->ext_nvm) { + if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) { if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n"); return NULL; } } else { + if (mvm->trans->cfg->nvm_type == IWL_NVM_SDP) + regulatory_type = NVM_SECTION_TYPE_REGULATORY_SDP; + else + regulatory_type = NVM_SECTION_TYPE_REGULATORY; + /* SW and REGULATORY sections are mandatory */ if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || - !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) { + !mvm->nvm_sections[regulatory_type].data) { IWL_ERR(mvm, "Can't parse empty family 8000 OTP/NVM sections\n"); return NULL; @@ -330,11 +336,14 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data; sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; - regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data; mac_override = (const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data; phy_sku = (const __le16 *)sections[NVM_SECTION_TYPE_PHY_SKU].data; + regulatory = mvm->trans->cfg->nvm_type == IWL_NVM_SDP ? + (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY_SDP].data : + (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data; + lar_enabled = !iwlwifi_mod_params.lar_disable && fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_LAR_SUPPORT); @@ -394,7 +403,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); /* Maximal size depends on NVM version */ - if (!mvm->trans->cfg->ext_nvm) + if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) max_section_size = IWL_MAX_NVM_SECTION_SIZE; else max_section_size = IWL_MAX_EXT_NVM_SECTION_SIZE; @@ -465,7 +474,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) break; } - if (!mvm->trans->cfg->ext_nvm) { + if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) { section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1)); section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2)); @@ -740,7 +749,7 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm) struct ieee80211_regdomain *regd; char mcc[3]; - if (mvm->cfg->ext_nvm) { + if (mvm->cfg->nvm_type == IWL_NVM_EXT) { tlv_lar = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_LAR_SUPPORT); nvm_lar = mvm->nvm_data->lar_enabled; -- cgit v1.2.3 From faf654864b25f4ca4efd416145d37b794c0b805f Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 6 Oct 2017 11:49:40 +0300 Subject: drm/i915: Unify uC variable types to avoid flooding checkpatch.pl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the code motion mostly done, convert all the uC code away from uint??_t at once (only a couple dozen variables), so that reading the checkpatch.pl output should actually pinpoint if a new uint??_t was accidentally introduced. v2: - Include intel_uc_fw.h too (Sagar) Signed-off-by: Joonas Lahtinen Cc: Michal Wajdeczko Cc: Chris Wilson Cc: Michał Winiarski Cc: Sagar Arun Kamble Cc: Anusha Srivatsa Cc: Sujaritha Sundaresan Reviewed-by: Sagar Arun Kamble Reviewed-by: Michal Wajdeczko Link: https://patchwork.freedesktop.org/patch/msgid/20171006084940.15910-1-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/i915_guc_submission.c | 10 +++---- drivers/gpu/drm/i915/i915_guc_submission.h | 8 ++--- drivers/gpu/drm/i915/intel_guc.h | 3 +- drivers/gpu/drm/i915/intel_guc_fwif.h | 48 +++++++++++++++--------------- drivers/gpu/drm/i915/intel_guc_log.c | 3 +- drivers/gpu/drm/i915/intel_guc_log.h | 2 +- drivers/gpu/drm/i915/intel_uc_fw.h | 20 ++++++------- 7 files changed, 48 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 7460ab4a214c..a2fad82532e4 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -338,7 +338,7 @@ static void guc_stage_desc_init(struct intel_guc *guc, for_each_engine_masked(engine, dev_priv, client->engines, tmp) { struct intel_context *ce = &ctx->engine[engine->id]; - uint32_t guc_engine_id = engine->guc_id; + u32 guc_engine_id = engine->guc_id; struct guc_execlist_context *lrc = &desc->lrc[guc_engine_id]; /* TODO: We have a design issue to be solved here. Only when we @@ -388,13 +388,13 @@ static void guc_stage_desc_init(struct intel_guc *guc, gfx_addr = guc_ggtt_offset(client->vma); desc->db_trigger_phy = sg_dma_address(client->vma->pages->sgl) + client->doorbell_offset; - desc->db_trigger_cpu = (uintptr_t)__get_doorbell(client); + desc->db_trigger_cpu = (u64)__get_doorbell(client); desc->db_trigger_uk = gfx_addr + client->doorbell_offset; desc->process_desc = gfx_addr + client->proc_desc_offset; desc->wq_addr = gfx_addr + GUC_DB_SIZE; desc->wq_size = GUC_WQ_SIZE; - desc->desc_private = (uintptr_t)client; + desc->desc_private = (u64)client; } static void guc_stage_desc_fini(struct intel_guc *guc, @@ -755,8 +755,8 @@ static int guc_init_doorbell_hw(struct intel_guc *guc) */ static struct i915_guc_client * guc_client_alloc(struct drm_i915_private *dev_priv, - uint32_t engines, - uint32_t priority, + u32 engines, + u32 priority, struct i915_gem_context *ctx) { struct i915_guc_client *client; diff --git a/drivers/gpu/drm/i915/i915_guc_submission.h b/drivers/gpu/drm/i915/i915_guc_submission.h index a7e61e6246ff..cb4353b59059 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.h +++ b/drivers/gpu/drm/i915/i915_guc_submission.h @@ -59,17 +59,17 @@ struct i915_guc_client { struct intel_guc *guc; /* bitmap of (host) engine ids */ - uint32_t engines; - uint32_t priority; + u32 engines; + u32 priority; u32 stage_id; - uint32_t proc_desc_offset; + u32 proc_desc_offset; u16 doorbell_id; unsigned long doorbell_offset; spinlock_t wq_lock; /* Per-engine counts of GuC submissions */ - uint64_t submissions[I915_NUM_ENGINES]; + u64 submissions[I915_NUM_ENGINES]; }; int i915_guc_submission_init(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 094d64980882..aa9a7b55be6e 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -52,7 +52,8 @@ struct intel_guc { struct i915_guc_client *execbuf_client; DECLARE_BITMAP(doorbell_bitmap, GUC_NUM_DOORBELLS); - uint32_t db_cacheline; /* Cyclic counter mod pagesize */ + /* Cyclic counter mod pagesize */ + u32 db_cacheline; /* GuC's FW specific registers used in MMIO send */ struct { diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 7eb6b4fa1d6f..1c0a2a3de121 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -178,49 +178,49 @@ */ struct uc_css_header { - uint32_t module_type; + u32 module_type; /* header_size includes all non-uCode bits, including css_header, rsa * key, modulus key and exponent data. */ - uint32_t header_size_dw; - uint32_t header_version; - uint32_t module_id; - uint32_t module_vendor; + u32 header_size_dw; + u32 header_version; + u32 module_id; + u32 module_vendor; union { struct { - uint8_t day; - uint8_t month; - uint16_t year; + u8 day; + u8 month; + u16 year; }; - uint32_t date; + u32 date; }; - uint32_t size_dw; /* uCode plus header_size_dw */ - uint32_t key_size_dw; - uint32_t modulus_size_dw; - uint32_t exponent_size_dw; + u32 size_dw; /* uCode plus header_size_dw */ + u32 key_size_dw; + u32 modulus_size_dw; + u32 exponent_size_dw; union { struct { - uint8_t hour; - uint8_t min; - uint16_t sec; + u8 hour; + u8 min; + u16 sec; }; - uint32_t time; + u32 time; }; char username[8]; char buildnumber[12]; union { struct { - uint32_t branch_client_version; - uint32_t sw_version; + u32 branch_client_version; + u32 sw_version; } guc; struct { - uint32_t sw_version; - uint32_t reserved; + u32 sw_version; + u32 reserved; } huc; }; - uint32_t prod_preprod_fw; - uint32_t reserved[12]; - uint32_t header_info; + u32 prod_preprod_fw; + u32 reserved[12]; + u32 header_info; } __packed; struct guc_doorbell_info { diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c index b7317a13354a..76d3eb1e4614 100644 --- a/drivers/gpu/drm/i915/intel_guc_log.c +++ b/drivers/gpu/drm/i915/intel_guc_log.c @@ -528,7 +528,8 @@ int intel_guc_log_create(struct intel_guc *guc) { struct i915_vma *vma; unsigned long offset; - uint32_t size, flags; + u32 flags; + u32 size; int ret; GEM_BUG_ON(guc->log.vma); diff --git a/drivers/gpu/drm/i915/intel_guc_log.h b/drivers/gpu/drm/i915/intel_guc_log.h index b5ec374d9b15..f512cf79339b 100644 --- a/drivers/gpu/drm/i915/intel_guc_log.h +++ b/drivers/gpu/drm/i915/intel_guc_log.h @@ -33,7 +33,7 @@ struct drm_i915_private; struct intel_guc; struct intel_guc_log { - uint32_t flags; + u32 flags; struct i915_vma *vma; /* The runtime stuff gets created only when GuC logging gets enabled */ struct { diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index fcaf59718300..c3e9af4b9bf0 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -50,18 +50,18 @@ struct intel_uc_fw { enum intel_uc_fw_status fetch_status; enum intel_uc_fw_status load_status; - uint16_t major_ver_wanted; - uint16_t minor_ver_wanted; - uint16_t major_ver_found; - uint16_t minor_ver_found; + u16 major_ver_wanted; + u16 minor_ver_wanted; + u16 major_ver_found; + u16 minor_ver_found; enum intel_uc_fw_type type; - uint32_t header_size; - uint32_t header_offset; - uint32_t rsa_size; - uint32_t rsa_offset; - uint32_t ucode_size; - uint32_t ucode_offset; + u32 header_size; + u32 header_offset; + u32 rsa_size; + u32 rsa_offset; + u32 ucode_size; + u32 ucode_offset; }; static inline -- cgit v1.2.3 From ead92edbd67c5f51dda7ac90136fbd05464203b6 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 6 Oct 2017 09:02:09 +0000 Subject: drm/i915/huc: Fix includes in intel_huc.c Fix includes order and make sure we only include required headers. While here, make intel_huc.h header self-contained. Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006090209.67852-1-michal.wajdeczko@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_huc.c | 6 ++++-- drivers/gpu/drm/i915/intel_huc.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index 3f796fed35af..4b4cf56d29ad 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c @@ -21,9 +21,11 @@ * IN THE SOFTWARE. * */ -#include + +#include + +#include "intel_huc.h" #include "i915_drv.h" -#include "intel_uc.h" /** * DOC: HuC Firmware diff --git a/drivers/gpu/drm/i915/intel_huc.h b/drivers/gpu/drm/i915/intel_huc.h index d58422b0c85f..aaa38b9e5817 100644 --- a/drivers/gpu/drm/i915/intel_huc.h +++ b/drivers/gpu/drm/i915/intel_huc.h @@ -25,6 +25,8 @@ #ifndef _INTEL_HUC_H_ #define _INTEL_HUC_H_ +#include "intel_uc_fw.h" + struct intel_huc { /* Generic uC firmware management */ struct intel_uc_fw fw; -- cgit v1.2.3 From bb8920f5bea53317c15d1c14f2704f2deaeb9ffd Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 6 Oct 2017 13:08:44 +0000 Subject: drm/i915: Fix pointer-to-int conversion Commit faf654864b25 ("drm/i915: Unify uC variable types to avoid flooding checkpatch.pl") breaks 32-bit kernel builds. Lets use cast helper to make compiler happy. v2: introduce ptr_to_u64 (Chris) Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006130844.49012-1-michal.wajdeczko@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_guc_submission.c | 4 ++-- drivers/gpu/drm/i915/i915_utils.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index a2fad82532e4..31381a327347 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -388,13 +388,13 @@ static void guc_stage_desc_init(struct intel_guc *guc, gfx_addr = guc_ggtt_offset(client->vma); desc->db_trigger_phy = sg_dma_address(client->vma->pages->sgl) + client->doorbell_offset; - desc->db_trigger_cpu = (u64)__get_doorbell(client); + desc->db_trigger_cpu = ptr_to_u64(__get_doorbell(client)); desc->db_trigger_uk = gfx_addr + client->doorbell_offset; desc->process_desc = gfx_addr + client->proc_desc_offset; desc->wq_addr = gfx_addr + GUC_DB_SIZE; desc->wq_size = GUC_WQ_SIZE; - desc->desc_private = (u64)client; + desc->desc_private = ptr_to_u64(client); } static void guc_stage_desc_fini(struct intel_guc *guc, diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 12fc250b47b9..c242327d5217 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -99,6 +99,11 @@ __T; \ }) +static inline u64 ptr_to_u64(const void *ptr) +{ + return (uintptr_t)ptr; +} + #define u64_to_ptr(T, x) ({ \ typecheck(u64, x); \ (T *)(uintptr_t)(x); \ -- cgit v1.2.3 From 7c26240e8a19240924b029215989f28995f16d8c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Oct 2017 11:40:38 +0100 Subject: drm/i915: Try harder to finish the idle-worker If a worker requeues itself, it may switch to a different kworker pool, which flush_work() considers as complete. To be strict, we then need to keep flushing the work until it is no longer pending. References: https://bugs.freedesktop.org/show_bug.cgi?id=102456 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006104038.22337-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +-- drivers/gpu/drm/i915/i915_gem.c | 3 +-- drivers/gpu/drm/i915/i915_utils.h | 13 +++++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 44aae25d12c7..84ab77c02d3e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4259,8 +4259,7 @@ fault_irq_set(struct drm_i915_private *i915, mutex_unlock(&i915->drm.struct_mutex); /* Flush idle worker to disarm irq */ - while (flush_delayed_work(&i915->gt.idle_work)) - ; + drain_delayed_work(&i915->gt.idle_work); return 0; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ab8c6946fea4..c48700f7bc6e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4547,8 +4547,7 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv) /* As the idle_work is rearming if it detects a race, play safe and * repeat the flush until it is definitely idle. */ - while (flush_delayed_work(&dev_priv->gt.idle_work)) - ; + drain_delayed_work(&dev_priv->gt.idle_work); /* Assert that we sucessfully flushed all the work and * reset the GPU back to its idle, low power state. diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index c242327d5217..af3d7cc53fa1 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -124,4 +124,17 @@ static inline void __list_del_many(struct list_head *head, WRITE_ONCE(head->next, first); } +/* + * Wait until the work is finally complete, even if it tries to postpone + * by requeueing itself. Note, that if the worker never cancels itself, + * we will spin forever. + */ +static inline void drain_delayed_work(struct delayed_work *dw) +{ + do { + while (flush_delayed_work(dw)) + ; + } while (delayed_work_pending(dw)); +} + #endif /* !__I915_UTILS_H */ -- cgit v1.2.3 From 320671f94ada80ff036cc9d5dcd730ba4f3e0f1a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 2 Oct 2017 11:04:16 +0100 Subject: drm/i915: Silence compiler warning for hsw_power_well_enable() Not all compilers are able to determine that pg is guarded by wait_fuses and so may think that pg is used uninitialized. Reported-by: Geert Uytterhoeven Fixes: b2891eb2531e ("drm/i915/hsw+: Add has_fuses power well attribute") Signed-off-by: Chris Wilson Cc: Imre Deak Cc: Arkadiusz Hiler Link: https://patchwork.freedesktop.org/patch/msgid/20171002100416.25865-1-chris@chris-wilson.co.uk Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 3791c3f5f56d..c4e1aba83c3e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -368,7 +368,7 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, { enum i915_power_well_id id = power_well->id; bool wait_fuses = power_well->hsw.has_fuses; - enum skl_power_gate pg; + enum skl_power_gate uninitialized_var(pg); u32 val; if (wait_fuses) { -- cgit v1.2.3 From 6151b8b37b119e8e3a8401b080d532520c95faf4 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 6 Oct 2017 17:05:49 +0200 Subject: ppp: fix race in ppp device destruction ppp_release() tries to ensure that netdevices are unregistered before decrementing the unit refcount and running ppp_destroy_interface(). This is all fine as long as the the device is unregistered by ppp_release(): the unregister_netdevice() call, followed by rtnl_unlock(), guarantee that the unregistration process completes before rtnl_unlock() returns. However, the device may be unregistered by other means (like ppp_nl_dellink()). If this happens right before ppp_release() calling rtnl_lock(), then ppp_release() has to wait for the concurrent unregistration code to release the lock. But rtnl_unlock() releases the lock before completing the device unregistration process. This allows ppp_release() to proceed and eventually call ppp_destroy_interface() before the unregistration process completes. Calling free_netdev() on this partially unregistered device will BUG(): ------------[ cut here ]------------ kernel BUG at net/core/dev.c:8141! invalid opcode: 0000 [#1] SMP CPU: 1 PID: 1557 Comm: pppd Not tainted 4.14.0-rc2+ #4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1.fc26 04/01/2014 Call Trace: ppp_destroy_interface+0xd8/0xe0 [ppp_generic] ppp_disconnect_channel+0xda/0x110 [ppp_generic] ppp_unregister_channel+0x5e/0x110 [ppp_generic] pppox_unbind_sock+0x23/0x30 [pppox] pppoe_connect+0x130/0x440 [pppoe] SYSC_connect+0x98/0x110 ? do_fcntl+0x2c0/0x5d0 SyS_connect+0xe/0x10 entry_SYSCALL_64_fastpath+0x1a/0xa5 RIP: free_netdev+0x107/0x110 RSP: ffffc28a40573d88 ---[ end trace ed294ff0cc40eeff ]--- We could set the ->needs_free_netdev flag on PPP devices and move the ppp_destroy_interface() logic in the ->priv_destructor() callback. But that'd be quite intrusive as we'd first need to unlink from the other channels and units that depend on the device (the ones that used the PPPIOCCONNECT and PPPIOCATTACH ioctls). Instead, we can just let the netdevice hold a reference on its ppp_file. This reference is dropped in ->priv_destructor(), at the very end of the unregistration process, so that neither ppp_release() nor ppp_disconnect_channel() can call ppp_destroy_interface() in the interim. Reported-by: Beniamino Galvani Fixes: 8cb775bc0a34 ("ppp: fix device unregistration upon netns deletion") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller --- drivers/net/ppp/ppp_generic.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index c3f77e3b7819..e365866600ba 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -1339,7 +1339,17 @@ ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64) static int ppp_dev_init(struct net_device *dev) { + struct ppp *ppp; + netdev_lockdep_set_classes(dev); + + ppp = netdev_priv(dev); + /* Let the netdevice take a reference on the ppp file. This ensures + * that ppp_destroy_interface() won't run before the device gets + * unregistered. + */ + atomic_inc(&ppp->file.refcnt); + return 0; } @@ -1362,6 +1372,15 @@ static void ppp_dev_uninit(struct net_device *dev) wake_up_interruptible(&ppp->file.rwait); } +static void ppp_dev_priv_destructor(struct net_device *dev) +{ + struct ppp *ppp; + + ppp = netdev_priv(dev); + if (atomic_dec_and_test(&ppp->file.refcnt)) + ppp_destroy_interface(ppp); +} + static const struct net_device_ops ppp_netdev_ops = { .ndo_init = ppp_dev_init, .ndo_uninit = ppp_dev_uninit, @@ -1387,6 +1406,7 @@ static void ppp_setup(struct net_device *dev) dev->tx_queue_len = 3; dev->type = ARPHRD_PPP; dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; + dev->priv_destructor = ppp_dev_priv_destructor; netif_keep_dst(dev); } -- cgit v1.2.3 From 8d550824c6f52506754f11cb6be51aa153cc580d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Oct 2017 12:56:17 +0100 Subject: drm/i915: Order two completing nop_submit_request If two nop's (requests in-flight following a wedged device) complete at the same time, the global_seqno value written to the HWSP is undefined as the two threads are not serialized. v2: Use irqsafe spinlock. We expect the callback may be called from inside another irq spinlock, so we can't unconditionally restore irqs. Fixes: ce1135c7de64 ("drm/i915: Complete requests in nop_submit_request") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20171006115617.18432-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c48700f7bc6e..50cc3c2cef06 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3014,10 +3014,15 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv) static void nop_submit_request(struct drm_i915_gem_request *request) { + unsigned long flags; + GEM_BUG_ON(!i915_terminally_wedged(&request->i915->gpu_error)); dma_fence_set_error(&request->fence, -EIO); - i915_gem_request_submit(request); + + spin_lock_irqsave(&request->engine->timeline->lock, flags); + __i915_gem_request_submit(request); intel_engine_init_global_seqno(request->engine, request->global_seqno); + spin_unlock_irqrestore(&request->engine->timeline->lock, flags); } static void engine_set_wedged(struct intel_engine_cs *engine) -- cgit v1.2.3 From fbce4d97fd4333bcffd00a73b9d98412be630332 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 4 Oct 2017 10:28:56 +0200 Subject: scsi: fixup kernel warning during rmmod() Calling rmmod() on a FC driver will results in warnings like WARNING: CPU: 60 PID: 14640 at fs/sysfs/group.c:237 device_del+0x54/0x240() sysfs group ffffffff81eff140 not found for kobject '3:0:0:3' The problem here is that during scsi_remove_target() we will iterate over all devices, but fail to remove any of those as the call to scsi_device_get() fails the check to module_is_live(). Hence the devices will not be removed at this point, but all intermediate structures like fc rport etc. will be. Later on during scsi_forget_host() the devices are removed for real, but the device parent is already removed and causes this warning. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Kyle Fortin Tested-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_sysfs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index bf53356f41f0..f796bd61f3f0 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1376,13 +1376,19 @@ static void __scsi_remove_target(struct scsi_target *starget) spin_lock_irqsave(shost->host_lock, flags); restart: list_for_each_entry(sdev, &shost->__devices, siblings) { + /* + * We cannot call scsi_device_get() here, as + * we might've been called from rmmod() causing + * scsi_device_get() to fail the module_is_live() + * check. + */ if (sdev->channel != starget->channel || sdev->id != starget->id || - scsi_device_get(sdev)) + !get_device(&sdev->sdev_gendev)) continue; spin_unlock_irqrestore(shost->host_lock, flags); scsi_remove_device(sdev); - scsi_device_put(sdev); + put_device(&sdev->sdev_gendev); spin_lock_irqsave(shost->host_lock, flags); goto restart; } -- cgit v1.2.3 From d1b3f51ee1eab3a6db1b09a60e61280c48eb0b01 Mon Sep 17 00:00:00 2001 From: Satish Kharat Date: Thu, 5 Oct 2017 16:41:21 -0700 Subject: scsi: libfc: fix a deadlock in fc_rport_work In places like fc_rport_recv_plogi_req and fcoe_ctlr_vn_add we always take the lport disc_mutex lock before the rports mutex (rp_mutex) lock. Gaurding list_del_rcu(&rdata->peers) with disc.disc_mutex in fc_rport_work is correct but the rp_mutex lock can and should to be dropped before taking that lock else results in a deadlock. Signed-off-by: Satish Kharat Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/libfc/fc_rport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 520325867e2b..31d31aad3de1 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -383,11 +383,11 @@ static void fc_rport_work(struct work_struct *work) fc_rport_enter_flogi(rdata); mutex_unlock(&rdata->rp_mutex); } else { + mutex_unlock(&rdata->rp_mutex); FC_RPORT_DBG(rdata, "work delete\n"); mutex_lock(&lport->disc.disc_mutex); list_del_rcu(&rdata->peers); mutex_unlock(&lport->disc.disc_mutex); - mutex_unlock(&rdata->rp_mutex); kref_put(&rdata->kref, fc_rport_destroy); } } else { -- cgit v1.2.3 From ae97988fc89e6a26da0b4aaab23027318fe311b1 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 29 Sep 2017 14:36:15 +0800 Subject: drm/amd/powerplay: tidy up ret checks in amd_powerplay.c (v3) v2: squash in regression fix (Rex) v3: Squash in regression fix (Rex) Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 76 +++++++++++++-------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 38ae400c3a35..6e0b35245555 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -231,7 +231,7 @@ int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id) ret = pp_check(pp_handle); - if (ret != 0) + if (!ret) return ret; hwmgr = pp_handle->hwmgr; @@ -253,7 +253,7 @@ static int pp_set_powergating_state(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -380,7 +380,7 @@ static int pp_dpm_force_performance_level(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -415,7 +415,7 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level( ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -434,7 +434,7 @@ static uint32_t pp_dpm_get_sclk(void *handle, bool low) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -458,7 +458,7 @@ static uint32_t pp_dpm_get_mclk(void *handle, bool low) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -481,7 +481,7 @@ static void pp_dpm_powergate_vce(void *handle, bool gate) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return; hwmgr = pp_handle->hwmgr; @@ -503,7 +503,7 @@ static void pp_dpm_powergate_uvd(void *handle, bool gate) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return; hwmgr = pp_handle->hwmgr; @@ -525,7 +525,7 @@ static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; mutex_lock(&pp_handle->pp_lock); @@ -545,7 +545,7 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -587,7 +587,7 @@ static void pp_dpm_set_fan_control_mode(void *handle, uint32_t mode) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return; hwmgr = pp_handle->hwmgr; @@ -610,7 +610,7 @@ static uint32_t pp_dpm_get_fan_control_mode(void *handle) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -633,7 +633,7 @@ static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -656,7 +656,7 @@ static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -680,7 +680,7 @@ static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -702,7 +702,7 @@ static int pp_dpm_get_temperature(void *handle) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -727,7 +727,7 @@ static int pp_dpm_get_pp_num_states(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -772,7 +772,7 @@ static int pp_dpm_get_pp_table(void *handle, char **table) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -795,7 +795,7 @@ static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -837,7 +837,7 @@ static int pp_dpm_force_clock_level(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -861,7 +861,7 @@ static int pp_dpm_print_clock_levels(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -884,7 +884,7 @@ static int pp_dpm_get_sclk_od(void *handle) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -907,7 +907,7 @@ static int pp_dpm_set_sclk_od(void *handle, uint32_t value) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -931,7 +931,7 @@ static int pp_dpm_get_mclk_od(void *handle) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -954,7 +954,7 @@ static int pp_dpm_set_mclk_od(void *handle, uint32_t value) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -978,7 +978,7 @@ static int pp_dpm_read_sensor(void *handle, int idx, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -1004,7 +1004,7 @@ pp_dpm_get_vce_clock_state(void *handle, unsigned idx) ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return NULL; hwmgr = pp_handle->hwmgr; @@ -1185,7 +1185,7 @@ int amd_powerplay_reset(void *handle) int ret; ret = pp_check(instance); - if (ret != 0) + if (!ret) return ret; ret = pp_hw_fini(instance); @@ -1210,7 +1210,7 @@ int amd_powerplay_display_configuration_change(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -1229,7 +1229,7 @@ int amd_powerplay_get_display_power_level(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -1254,7 +1254,7 @@ int amd_powerplay_get_current_clocks(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -1271,7 +1271,7 @@ int amd_powerplay_get_current_clocks(void *handle, ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks, PHM_PerformanceLevelDesignation_Activity); - if (ret != 0) { + if (ret) { pr_info("Error in phm_get_clock_info \n"); mutex_unlock(&pp_handle->pp_lock); return -EINVAL; @@ -1305,7 +1305,7 @@ int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, s ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; @@ -1328,7 +1328,7 @@ int amd_powerplay_get_clock_by_type_with_latency(void *handle, int ret = 0; ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; if (!clocks) @@ -1350,7 +1350,7 @@ int amd_powerplay_get_clock_by_type_with_voltage(void *handle, int ret = 0; ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; if (!clocks) @@ -1374,7 +1374,7 @@ int amd_powerplay_set_watermarks_for_clocks_ranges(void *handle, int ret = 0; ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; if (!wm_with_clock_ranges) @@ -1398,7 +1398,7 @@ int amd_powerplay_display_clock_voltage_request(void *handle, int ret = 0; ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; if (!clock) @@ -1422,7 +1422,7 @@ int amd_powerplay_get_display_mode_validation_clocks(void *handle, ret = pp_check(pp_handle); - if (ret != 0) + if (ret) return ret; hwmgr = pp_handle->hwmgr; -- cgit v1.2.3 From 3811f8f00c5fef3754091b5c5254355bed1d9022 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 26 Sep 2017 13:39:38 +0800 Subject: drm/amd/powerplay: move set_clockgating_by_smu to pp func table Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 4 +++ drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 23 +++++++----- drivers/gpu/drm/amd/amdgpu/vi.c | 22 +++++++----- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 44 +++++++++++------------ drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 1 - 5 files changed, 54 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index f79f9ea58b17..7279fb5c3abc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h @@ -356,6 +356,10 @@ enum amdgpu_pcie_gen { ((adev)->powerplay.pp_funcs->switch_power_profile(\ (adev)->powerplay.pp_handle, type)) +#define amdgpu_dpm_set_clockgating_by_smu(adev, msg_id) \ + ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\ + (adev)->powerplay.pp_handle, msg_id)) + struct amdgpu_dpm { struct amdgpu_ps *ps; /* number of valid power states */ diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 1640dd796618..147e92b3a959 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -5984,7 +5984,6 @@ static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev, { uint32_t msg_id, pp_state = 0; uint32_t pp_support_state = 0; - void *pp_handle = adev->powerplay.pp_handle; if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) { if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) { @@ -6002,7 +6001,8 @@ static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev, PP_BLOCK_GFX_CG, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) { @@ -6023,7 +6023,8 @@ static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev, PP_BLOCK_GFX_MG, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } return 0; @@ -6035,7 +6036,6 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, uint32_t msg_id, pp_state = 0; uint32_t pp_support_state = 0; - void *pp_handle = adev->powerplay.pp_handle; if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) { if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) { @@ -6053,7 +6053,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, PP_BLOCK_GFX_CG, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS)) { @@ -6072,7 +6073,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, PP_BLOCK_GFX_3D, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) { @@ -6093,7 +6095,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, PP_BLOCK_GFX_MG, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & AMD_CG_SUPPORT_GFX_RLC_LS) { @@ -6108,7 +6111,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, PP_BLOCK_GFX_RLC, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CP_LS) { @@ -6122,7 +6126,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, PP_BLOCK_GFX_CP, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 9ff69b90df36..f3cfef48aa99 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -1254,7 +1254,6 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, uint32_t msg_id, pp_state = 0; uint32_t pp_support_state = 0; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - void *pp_handle = adev->powerplay.pp_handle; if (adev->cg_flags & (AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_MC_MGCG)) { if (adev->cg_flags & AMD_CG_SUPPORT_MC_LS) { @@ -1271,7 +1270,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, PP_BLOCK_SYS_MC, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & (AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_SDMA_MGCG)) { @@ -1289,7 +1289,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, PP_BLOCK_SYS_SDMA, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_HDP_MGCG)) { @@ -1307,7 +1308,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, PP_BLOCK_SYS_HDP, pp_support_state, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } @@ -1321,7 +1323,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, PP_BLOCK_SYS_BIF, PP_STATE_SUPPORT_LS, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG) { if (state == AMD_CG_STATE_UNGATE) @@ -1333,7 +1336,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, PP_BLOCK_SYS_BIF, PP_STATE_SUPPORT_CG, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS) { @@ -1347,7 +1351,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, PP_BLOCK_SYS_DRM, PP_STATE_SUPPORT_LS, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } if (adev->cg_flags & AMD_CG_SUPPORT_ROM_MGCG) { @@ -1361,7 +1366,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, PP_BLOCK_SYS_ROM, PP_STATE_SUPPORT_CG, pp_state); - amd_set_clockgating_by_smu(pp_handle, msg_id); + if (adev->powerplay.pp_funcs->set_clockgating_by_smu) + amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); } return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 6e0b35245555..71bb7d932c86 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -222,28 +222,6 @@ static int pp_sw_reset(void *handle) return 0; } - -int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id) -{ - struct pp_hwmgr *hwmgr; - struct pp_instance *pp_handle = (struct pp_instance *)handle; - int ret = 0; - - ret = pp_check(pp_handle); - - if (!ret) - return ret; - - hwmgr = pp_handle->hwmgr; - - if (hwmgr->hwmgr_func->update_clock_gatings == NULL) { - pr_info("%s was not implemented.\n", __func__); - return 0; - } - - return hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id); -} - static int pp_set_powergating_state(void *handle, enum amd_powergating_state state) { @@ -335,6 +313,27 @@ static int pp_dpm_fw_loading_complete(void *handle) return 0; } +static int pp_set_clockgating_by_smu(void *handle, uint32_t msg_id) +{ + struct pp_hwmgr *hwmgr; + struct pp_instance *pp_handle = (struct pp_instance *)handle; + int ret = 0; + + ret = pp_check(pp_handle); + + if (ret) + return ret; + + hwmgr = pp_handle->hwmgr; + + if (hwmgr->hwmgr_func->update_clock_gatings == NULL) { + pr_info("%s was not implemented.\n", __func__); + return 0; + } + + return hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id); +} + static void pp_dpm_en_umd_pstate(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level *level) { @@ -1177,6 +1176,7 @@ const struct amd_pm_funcs pp_dpm_funcs = { .get_power_profile_state = pp_dpm_get_power_profile_state, .set_power_profile_state = pp_dpm_set_power_profile_state, .switch_power_profile = pp_dpm_switch_power_profile, + .set_clockgating_by_smu = pp_set_clockgating_by_smu, }; int amd_powerplay_reset(void *handle) diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index e52adc873413..95932cc88460 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -304,6 +304,5 @@ int amd_powerplay_display_clock_voltage_request(void *handle, int amd_powerplay_get_display_mode_validation_clocks(void *handle, struct amd_pp_simple_clock_info *output); -int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id); #endif /* _AMD_POWERPLAY_H_ */ -- cgit v1.2.3 From e1827a307e96ec51a657a2b7e68a8ffc36ae2a43 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Thu, 28 Sep 2017 16:12:51 +0800 Subject: drm/amd/powerplay: delete flag PP_VALID don't need to check pp_valid, all pp export functions are moved to ip_funcs and pp_funcs. so just need to check the function point. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 3 +-- drivers/gpu/drm/amd/powerplay/inc/pp_instance.h | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 71bb7d932c86..3c8ef4bfc205 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -37,7 +37,7 @@ static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, static inline int pp_check(struct pp_instance *handle) { - if (handle == NULL || handle->pp_valid != PP_VALID) + if (handle == NULL) return -EINVAL; if (handle->hwmgr == NULL || handle->hwmgr->smumgr_funcs == NULL) @@ -64,7 +64,6 @@ static int amd_powerplay_create(struct amd_pp_init *pp_init, if (instance == NULL) return -ENOMEM; - instance->pp_valid = PP_VALID; instance->chip_family = pp_init->chip_family; instance->chip_id = pp_init->chip_id; instance->pm_en = pp_init->pm_en; diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h index 25fb1460a194..7d1eec5d2e7a 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h +++ b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h @@ -25,10 +25,7 @@ #include "hwmgr.h" -#define PP_VALID 0x1F1F1F1F - struct pp_instance { - uint32_t pp_valid; uint32_t chip_family; uint32_t chip_id; bool pm_en; -- cgit v1.2.3 From 1321fd2c010e7ccb474cda6b8793747c7a3a775b Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 12 Sep 2017 22:42:12 +0200 Subject: drm/syncobj: extract two helpers from drm_syncobj_create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For amdgpu. drm_syncobj_create is renamed to drm_syncobj_create_as_handle, and new helpers drm_syncobj_create and drm_syncobj_get_handle are added. Reviewed-by: Dave Airlie Signed-off-by: Marek Olšák Signed-off-by: Alex Deucher --- drivers/gpu/drm/drm_syncobj.c | 49 +++++++++++++++++++++++++++++++++++++++---- include/drm/drm_syncobj.h | 4 ++++ 2 files changed, 49 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0422b8c2c2e7..0bb174109b96 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -262,8 +262,14 @@ void drm_syncobj_free(struct kref *kref) } EXPORT_SYMBOL(drm_syncobj_free); -static int drm_syncobj_create(struct drm_file *file_private, - u32 *handle, uint32_t flags) +/** + * drm_syncobj_create - create a new syncobj + * @out_syncobj: returned syncobj + * @flags: DRM_SYNCOBJ_* flags + * @fence: if non-NULL, the syncobj will represent this fence + */ +int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, + struct dma_fence *fence) { int ret; struct drm_syncobj *syncobj; @@ -284,6 +290,25 @@ static int drm_syncobj_create(struct drm_file *file_private, } } + if (fence) + drm_syncobj_replace_fence(syncobj, fence); + + *out_syncobj = syncobj; + return 0; +} +EXPORT_SYMBOL(drm_syncobj_create); + +/** + * drm_syncobj_get_handle - get a handle from a syncobj + */ +int drm_syncobj_get_handle(struct drm_file *file_private, + struct drm_syncobj *syncobj, u32 *handle) +{ + int ret; + + /* take a reference to put in the idr */ + drm_syncobj_get(syncobj); + idr_preload(GFP_KERNEL); spin_lock(&file_private->syncobj_table_lock); ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT); @@ -299,6 +324,22 @@ static int drm_syncobj_create(struct drm_file *file_private, *handle = ret; return 0; } +EXPORT_SYMBOL(drm_syncobj_get_handle); + +static int drm_syncobj_create_as_handle(struct drm_file *file_private, + u32 *handle, uint32_t flags) +{ + int ret; + struct drm_syncobj *syncobj; + + ret = drm_syncobj_create(&syncobj, flags, NULL); + if (ret) + return ret; + + ret = drm_syncobj_get_handle(file_private, syncobj, handle); + drm_syncobj_put(syncobj); + return ret; +} static int drm_syncobj_destroy(struct drm_file *file_private, u32 handle) @@ -522,8 +563,8 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data, if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED) return -EINVAL; - return drm_syncobj_create(file_private, - &args->handle, args->flags); + return drm_syncobj_create_as_handle(file_private, + &args->handle, args->flags); } int diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index c00fee539822..e7f0035bb8f8 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -136,5 +136,9 @@ int drm_syncobj_find_fence(struct drm_file *file_private, u32 handle, struct dma_fence **fence); void drm_syncobj_free(struct kref *kref); +int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, + struct dma_fence *fence); +int drm_syncobj_get_handle(struct drm_file *file_private, + struct drm_syncobj *syncobj, u32 *handle); #endif -- cgit v1.2.3 From 684fd0af4732f373503c6af2973b4faa352db4e2 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 12 Sep 2017 22:42:13 +0200 Subject: drm/syncobj: add a new helper drm_syncobj_get_fd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Dave Airlie Signed-off-by: Marek Olšák Signed-off-by: Alex Deucher --- drivers/gpu/drm/drm_syncobj.c | 33 +++++++++++++++++++-------------- include/drm/drm_syncobj.h | 1 + 2 files changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0bb174109b96..62adc7acafcc 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -386,33 +386,38 @@ static int drm_syncobj_alloc_file(struct drm_syncobj *syncobj) return 0; } -static int drm_syncobj_handle_to_fd(struct drm_file *file_private, - u32 handle, int *p_fd) +int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) { - struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); int ret; int fd; - if (!syncobj) - return -EINVAL; - fd = get_unused_fd_flags(O_CLOEXEC); - if (fd < 0) { - drm_syncobj_put(syncobj); + if (fd < 0) return fd; - } if (!syncobj->file) { ret = drm_syncobj_alloc_file(syncobj); - if (ret) - goto out_put_fd; + if (ret) { + put_unused_fd(fd); + return ret; + } } fd_install(fd, syncobj->file); - drm_syncobj_put(syncobj); *p_fd = fd; return 0; -out_put_fd: - put_unused_fd(fd); +} +EXPORT_SYMBOL(drm_syncobj_get_fd); + +static int drm_syncobj_handle_to_fd(struct drm_file *file_private, + u32 handle, int *p_fd) +{ + struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); + int ret; + + if (!syncobj) + return -EINVAL; + + ret = drm_syncobj_get_fd(syncobj, p_fd); drm_syncobj_put(syncobj); return ret; } diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index e7f0035bb8f8..43e2f382d2f0 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -140,5 +140,6 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, struct dma_fence *fence); int drm_syncobj_get_handle(struct drm_file *file_private, struct drm_syncobj *syncobj, u32 *handle); +int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd); #endif -- cgit v1.2.3 From 7ca24cf2d2269bde25e21c02a77fe81995a081ae Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 12 Sep 2017 22:42:14 +0200 Subject: drm/amdgpu: add FENCE_TO_HANDLE ioctl that returns syncobj or sync_file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for being able to convert an amdgpu fence into one of the handles. Mesa will use this. Reviewed-by: Dave Airlie Signed-off-by: Marek Olšák Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 61 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 1 + include/uapi/drm/amdgpu_drm.h | 16 +++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 0725ab940f49..a23b8af95319 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1311,6 +1311,8 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index c6a214f1e991..ab83dfcabb41 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -25,6 +25,7 @@ * Jerome Glisse */ #include +#include #include #include #include @@ -1330,6 +1331,66 @@ static struct dma_fence *amdgpu_cs_get_fence(struct amdgpu_device *adev, return fence; } +int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + struct amdgpu_device *adev = dev->dev_private; + struct amdgpu_fpriv *fpriv = filp->driver_priv; + union drm_amdgpu_fence_to_handle *info = data; + struct dma_fence *fence; + struct drm_syncobj *syncobj; + struct sync_file *sync_file; + int fd, r; + + if (amdgpu_kms_vram_lost(adev, fpriv)) + return -ENODEV; + + fence = amdgpu_cs_get_fence(adev, filp, &info->in.fence); + if (IS_ERR(fence)) + return PTR_ERR(fence); + + switch (info->in.what) { + case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ: + r = drm_syncobj_create(&syncobj, 0, fence); + dma_fence_put(fence); + if (r) + return r; + r = drm_syncobj_get_handle(filp, syncobj, &info->out.handle); + drm_syncobj_put(syncobj); + return r; + + case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD: + r = drm_syncobj_create(&syncobj, 0, fence); + dma_fence_put(fence); + if (r) + return r; + r = drm_syncobj_get_fd(syncobj, (int*)&info->out.handle); + drm_syncobj_put(syncobj); + return r; + + case AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD: + fd = get_unused_fd_flags(O_CLOEXEC); + if (fd < 0) { + dma_fence_put(fence); + return fd; + } + + sync_file = sync_file_create(fence); + dma_fence_put(fence); + if (!sync_file) { + put_unused_fd(fd); + return -ENOMEM; + } + + fd_install(fd, sync_file->file); + info->out.handle = fd; + return 0; + + default: + return -EINVAL; + } +} + /** * amdgpu_cs_wait_all_fence - wait on all fences to signal * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 9816f50a7498..ad02d3fbb44c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -70,9 +70,10 @@ * - 3.18.0 - Export gpu always on cu bitmap * - 3.19.0 - Add support for UVD MJPEG decode * - 3.20.0 - Add support for local BOs + * - 3.21.0 - Add DRM_AMDGPU_FENCE_TO_HANDLE ioctl */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 20 +#define KMS_DRIVER_MINOR 21 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 4fd06f8d9768..51841259e23f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1024,6 +1024,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_VM, amdgpu_vm_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_BO_LIST, amdgpu_bo_list_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_FENCE_TO_HANDLE, amdgpu_cs_fence_to_handle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), /* KMS */ DRM_IOCTL_DEF_DRV(AMDGPU_GEM_MMAP, amdgpu_gem_mmap_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_GEM_WAIT_IDLE, amdgpu_gem_wait_idle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index e055776f2f4c..4c6e8c482ee4 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -52,6 +52,7 @@ extern "C" { #define DRM_AMDGPU_GEM_USERPTR 0x11 #define DRM_AMDGPU_WAIT_FENCES 0x12 #define DRM_AMDGPU_VM 0x13 +#define DRM_AMDGPU_FENCE_TO_HANDLE 0x14 #define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) #define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap) @@ -67,6 +68,7 @@ extern "C" { #define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr) #define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences) #define DRM_IOCTL_AMDGPU_VM DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm) +#define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle) #define AMDGPU_GEM_DOMAIN_CPU 0x1 #define AMDGPU_GEM_DOMAIN_GTT 0x2 @@ -515,6 +517,20 @@ struct drm_amdgpu_cs_chunk_sem { __u32 handle; }; +#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0 +#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1 +#define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2 + +union drm_amdgpu_fence_to_handle { + struct { + struct drm_amdgpu_fence fence; + __u32 what; + } in; + struct { + __u32 handle; + } out; +}; + struct drm_amdgpu_cs_chunk_data { union { struct drm_amdgpu_cs_chunk_ib ib_data; -- cgit v1.2.3 From c3fa35a4e5d1a06a5f70e5ac34a05da139aa71f4 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 28 Sep 2017 14:46:17 +0100 Subject: drm/radeon: make functions alloc_pasid and free_pasid static The functions alloc_pasid and free_pasid are local to the source and do not need to be in global scope, so make them static. Cleans up sparse warnings: warning: symbol 'alloc_pasid' was not declared. Should it be static? warning: symbol 'free_pasid' was not declared. Should it be static? Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_kfd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index a2ac8ac0930d..385b4d76956d 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c @@ -352,7 +352,7 @@ static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd) */ static DEFINE_IDA(pasid_ida); -int alloc_pasid(unsigned int bits) +static int alloc_pasid(unsigned int bits) { int pasid = -EINVAL; @@ -367,7 +367,7 @@ int alloc_pasid(unsigned int bits) return pasid; } -void free_pasid(unsigned int pasid) +static void free_pasid(unsigned int pasid) { ida_simple_remove(&pasid_ida, pasid); } -- cgit v1.2.3 From a50ecc54ff1a53c410eafe21454ff1d88d76c35c Mon Sep 17 00:00:00 2001 From: ozeng Date: Wed, 27 Sep 2017 17:53:12 -0400 Subject: drm/amdgpu: Fixed a potential circular lock The dead circular lock senario captured is as followed. The idea of the fix is moving read_user_wptr outside of acquire_queue...release_queue critical section [ 63.477482] WARNING: possible circular locking dependency detected [ 63.484091] 4.12.0-kfd-ozeng #3 Not tainted [ 63.488531] ------------------------------------------------------ [ 63.495146] HelloWorldLoop/2526 is trying to acquire lock: [ 63.501011] (&mm->mmap_sem){++++++}, at: [] __might_fault+0x3e/0x90 [ 63.509472] but task is already holding lock: [ 63.515716] (&adev->srbm_mutex){+.+...}, at: [] lock_srbm+0x2b/0x50 [amdgpu] [ 63.525099] which lock already depends on the new lock. [ 63.533841] the existing dependency chain (in reverse order) is: [ 63.541839] -> #2 (&adev->srbm_mutex){+.+...}: [ 63.548178] lock_acquire+0x6d/0x90 [ 63.552461] __mutex_lock+0x70/0x8c0 [ 63.556826] mutex_lock_nested+0x16/0x20 [ 63.561603] gfx_v8_0_kiq_resume+0x1039/0x14a0 [amdgpu] [ 63.567817] gfx_v8_0_hw_init+0x204d/0x2210 [amdgpu] [ 63.573675] amdgpu_device_init+0xdea/0x1790 [amdgpu] [ 63.579640] amdgpu_driver_load_kms+0x63/0x220 [amdgpu] [ 63.585743] drm_dev_register+0x145/0x1e0 [ 63.590605] amdgpu_pci_probe+0x11e/0x160 [amdgpu] [ 63.596266] local_pci_probe+0x40/0xa0 [ 63.600803] pci_device_probe+0x134/0x150 [ 63.605650] driver_probe_device+0x2a1/0x460 [ 63.610785] __driver_attach+0xdc/0xe0 [ 63.615321] bus_for_each_dev+0x5f/0x90 [ 63.619984] driver_attach+0x19/0x20 [ 63.624337] bus_add_driver+0x40/0x270 [ 63.628908] driver_register+0x5b/0xe0 [ 63.633446] __pci_register_driver+0x5b/0x60 [ 63.638586] rtsx_pci_switch_output_voltage+0x1d/0x20 [rtsx_pci] [ 63.645564] do_one_initcall+0x4c/0x1b0 [ 63.650205] do_init_module+0x56/0x1ea [ 63.654767] load_module+0x208c/0x27d0 [ 63.659335] SYSC_finit_module+0x96/0xd0 [ 63.664058] SyS_finit_module+0x9/0x10 [ 63.668629] entry_SYSCALL_64_fastpath+0x1f/0xbe [ 63.674088] -> #1 (reservation_ww_class_mutex){+.+.+.}: [ 63.681257] lock_acquire+0x6d/0x90 [ 63.685551] __ww_mutex_lock.constprop.11+0x8c/0xed0 [ 63.691426] ww_mutex_lock+0x67/0x70 [ 63.695802] amdgpu_verify_access+0x6d/0x100 [amdgpu] [ 63.701743] ttm_bo_mmap+0x8e/0x100 [ttm] [ 63.706615] amdgpu_bo_mmap+0xd/0x60 [amdgpu] [ 63.711814] amdgpu_mmap+0x35/0x40 [amdgpu] [ 63.716904] mmap_region+0x3b5/0x5a0 [ 63.721255] do_mmap+0x400/0x4d0 [ 63.725260] vm_mmap_pgoff+0xb0/0xf0 [ 63.729625] SyS_mmap_pgoff+0x19e/0x260 [ 63.734292] SyS_mmap+0x1d/0x20 [ 63.738199] entry_SYSCALL_64_fastpath+0x1f/0xbe [ 63.743681] -> #0 (&mm->mmap_sem){++++++}: [ 63.749641] __lock_acquire+0x1401/0x1420 [ 63.754491] lock_acquire+0x6d/0x90 [ 63.758750] __might_fault+0x6b/0x90 [ 63.763176] kgd_hqd_load+0x24f/0x270 [amdgpu] [ 63.768432] load_mqd+0x4b/0x50 [amdkfd] [ 63.773192] create_queue_nocpsch+0x535/0x620 [amdkfd] [ 63.779237] pqm_create_queue+0x34d/0x4f0 [amdkfd] [ 63.784835] kfd_ioctl_create_queue+0x282/0x670 [amdkfd] [ 63.790973] kfd_ioctl+0x310/0x4d0 [amdkfd] [ 63.795944] do_vfs_ioctl+0x90/0x6e0 [ 63.800268] SyS_ioctl+0x74/0x80 [ 63.804207] entry_SYSCALL_64_fastpath+0x1f/0xbe [ 63.809607] other info that might help us debug this: [ 63.818026] Chain exists of: &mm->mmap_sem --> reservation_ww_class_mutex --> &adev->srbm_mutex [ 63.830382] Possible unsafe locking scenario: [ 63.836605] CPU0 CPU1 [ 63.841364] ---- ---- [ 63.846123] lock(&adev->srbm_mutex); [ 63.850061] lock(reservation_ww_class_mutex); [ 63.857475] lock(&adev->srbm_mutex); [ 63.864084] lock(&mm->mmap_sem); [ 63.867657] *** DEADLOCK *** [ 63.873884] 3 locks held by HelloWorldLoop/2526: [ 63.878739] #0: (&process->mutex){+.+.+.}, at: [] kfd_ioctl_create_queue+0x24a/0x670 [amdkfd] [ 63.889543] #1: (&dqm->lock){+.+...}, at: [] create_queue_nocpsch+0x3b/0x620 [amdkfd] [ 63.899684] #2: (&adev->srbm_mutex){+.+...}, at: [] lock_srbm+0x2b/0x50 [amdgpu] [ 63.909500] stack backtrace: [ 63.914187] CPU: 3 PID: 2526 Comm: HelloWorldLoop Not tainted 4.12.0-kfd-ozeng #3 [ 63.922184] Hardware name: AMD Carrizo/Gardenia, BIOS WGA5819N_Weekly_15_08_1 08/19/2015 [ 63.930865] Call Trace: [ 63.933464] dump_stack+0x85/0xc9 [ 63.936999] print_circular_bug+0x1f9/0x207 [ 63.941442] __lock_acquire+0x1401/0x1420 [ 63.945745] ? lock_srbm+0x2b/0x50 [amdgpu] [ 63.950185] lock_acquire+0x6d/0x90 [ 63.953885] ? __might_fault+0x3e/0x90 [ 63.957899] __might_fault+0x6b/0x90 [ 63.961699] ? __might_fault+0x3e/0x90 [ 63.965755] kgd_hqd_load+0x24f/0x270 [amdgpu] [ 63.970577] load_mqd+0x4b/0x50 [amdkfd] [ 63.974745] create_queue_nocpsch+0x535/0x620 [amdkfd] [ 63.980242] pqm_create_queue+0x34d/0x4f0 [amdkfd] [ 63.985320] kfd_ioctl_create_queue+0x282/0x670 [amdkfd] [ 63.991021] kfd_ioctl+0x310/0x4d0 [amdkfd] [ 63.995499] ? kfd_ioctl_destroy_queue+0x70/0x70 [amdkfd] [ 64.001234] do_vfs_ioctl+0x90/0x6e0 [ 64.005065] ? up_read+0x1a/0x40 [ 64.008496] SyS_ioctl+0x74/0x80 [ 64.011955] entry_SYSCALL_64_fastpath+0x1f/0xbe [ 64.016863] RIP: 0033:0x7f4b3bd35f07 [ 64.020696] RSP: 002b:00007ffe7689ec38 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 64.028786] RAX: ffffffffffffffda RBX: 00000000002a2000 RCX: 00007f4b3bd35f07 [ 64.036414] RDX: 00007ffe7689ecb0 RSI: 00000000c0584b02 RDI: 0000000000000005 [ 64.044045] RBP: 00007f4a3212d000 R08: 00007f4b3c919000 R09: 0000000000080000 [ 64.051674] R10: 00007f4b376b64b8 R11: 0000000000000246 R12: 00007f4a3212d000 [ 64.059324] R13: 0000000000000015 R14: 0000000000000064 R15: 00007ffe7689ef50 Signed-off-by: Oak Zeng Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 10 +++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index dc7e25cce741..47d1c132ac40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c @@ -338,6 +338,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, struct cik_mqd *m; uint32_t *mqd_hqd; uint32_t reg, wptr_val, data; + bool valid_wptr = false; m = get_mqd(mqd); @@ -356,7 +357,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1); WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data); - if (read_user_wptr(mm, wptr, wptr_val)) + /* read_user_ptr may take the mm->mmap_sem. + * release srbm_mutex to avoid circular dependency between + * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex. + */ + release_queue(kgd); + valid_wptr = read_user_wptr(mm, wptr, wptr_val); + acquire_queue(kgd, pipe_id, queue_id); + if (valid_wptr) WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index c678c69936a0..056929b8ccd0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c @@ -292,6 +292,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, struct vi_mqd *m; uint32_t *mqd_hqd; uint32_t reg, wptr_val, data; + bool valid_wptr = false; m = get_mqd(mqd); @@ -339,7 +340,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1); WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data); - if (read_user_wptr(mm, wptr, wptr_val)) + /* read_user_ptr may take the mm->mmap_sem. + * release srbm_mutex to avoid circular dependency between + * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex. + */ + release_queue(kgd); + valid_wptr = read_user_wptr(mm, wptr, wptr_val); + acquire_queue(kgd, pipe_id, queue_id); + if (valid_wptr) WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); -- cgit v1.2.3 From 64e66cffdb3e83d438d5ed8aa0593fbbdb2975fc Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 26 Sep 2017 11:35:30 +0800 Subject: drm/amd/powerplay: fixed wrong return value on error (v2) v2: squash in typo fix (Tom) Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c index d2f695692f77..598a194737a9 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c @@ -1243,8 +1243,8 @@ int vega10_enable_didt_config(struct pp_hwmgr *hwmgr) } if (0 == result) { - PP_ASSERT_WITH_CODE((!vega10_enable_smc_features(hwmgr, true, data->smu_features[GNLD_DIDT].smu_feature_bitmap)), - "[EnableDiDtConfig] Attempt to Enable DiDt feature Failed!", return result); + result = vega10_enable_smc_features(hwmgr, true, data->smu_features[GNLD_DIDT].smu_feature_bitmap); + PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDtConfig] Attempt to Enable DiDt feature Failed!", return result); data->smu_features[GNLD_DIDT].enabled = true; } } @@ -1290,8 +1290,8 @@ int vega10_disable_didt_config(struct pp_hwmgr *hwmgr) } if (0 == result) { - PP_ASSERT_WITH_CODE((0 != vega10_enable_smc_features(hwmgr, false, data->smu_features[GNLD_DIDT].smu_feature_bitmap)), - "[DisableDiDtConfig] Attempt to Disable DiDt feature Failed!", return result); + result = vega10_enable_smc_features(hwmgr, false, data->smu_features[GNLD_DIDT].smu_feature_bitmap); + PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDtConfig] Attempt to Disable DiDt feature Failed!", return result); data->smu_features[GNLD_DIDT].enabled = false; } } -- cgit v1.2.3 From d0d9db8864af8dca3bb9586402d6334e5bab8f4d Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 26 Sep 2017 11:37:34 +0800 Subject: drm/amd/powerplay: added new raven ppsmc messages Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h index 901c960cfe21..2b3497135bbd 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h +++ b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h @@ -70,7 +70,12 @@ #define PPSMC_MSG_SetPhyclkVoltageByFreq 0x26 #define PPSMC_MSG_SetDppclkVoltageByFreq 0x27 #define PPSMC_MSG_SetSoftMinVcn 0x28 -#define PPSMC_Message_Count 0x29 +#define PPSMC_MSG_GetGfxclkFrequency 0x2A +#define PPSMC_MSG_GetFclkFrequency 0x2B +#define PPSMC_MSG_GetMinGfxclkFrequency 0x2C +#define PPSMC_MSG_GetMaxGfxclkFrequency 0x2D +#define PPSMC_MSG_SoftReset 0x2E +#define PPSMC_Message_Count 0x2F typedef uint16_t PPSMC_Result; -- cgit v1.2.3 From 2b95315a584f8edd6021af1ce4e6282dd6b8fd9c Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 26 Sep 2017 11:43:35 +0800 Subject: drm/amd/powerplay: get raven max/min gfx clocks (v2) v2: squash in rebase fix (Tom) Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | 20 ++++++++++++++++++++ drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h | 2 ++ 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c index 6f0b2e5b68c7..1ba69d65ed8b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c @@ -421,6 +421,26 @@ static int rv_populate_clock_table(struct pp_hwmgr *hwmgr) rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_phyclk, ARRAY_SIZE(VddPhyClk), &VddPhyClk[0]); + PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr, + PPSMC_MSG_GetMinGfxclkFrequency), + "Attempt to get min GFXCLK Failed!", + return -1); + PP_ASSERT_WITH_CODE(!rv_read_arg_from_smc(hwmgr, + &result), + "Attempt to get min GFXCLK Failed!", + return -1); + rv_data->gfx_min_freq_limit = result * 100; + + PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr, + PPSMC_MSG_GetMaxGfxclkFrequency), + "Attempt to get max GFXCLK Failed!", + return -1); + PP_ASSERT_WITH_CODE(!rv_read_arg_from_smc(hwmgr, + &result), + "Attempt to get max GFXCLK Failed!", + return -1); + rv_data->gfx_max_freq_limit = result * 100; + return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h index 68d61bd95ca0..9dc503055394 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h @@ -283,6 +283,8 @@ struct rv_hwmgr { uint32_t vclk_soft_min; uint32_t dclk_soft_min; uint32_t gfx_actual_soft_min_freq; + uint32_t gfx_min_freq_limit; + uint32_t gfx_max_freq_limit; bool vcn_power_gated; bool vcn_dpg_mode; -- cgit v1.2.3 From 88ed3377d0a6175233414dcd21b751a40f86fa29 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 26 Sep 2017 11:49:28 +0800 Subject: drm/amd/powerplay: get raven current sclk and mclk (v2) v2: squash in rebase fix (Tom) Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c index 1ba69d65ed8b..a0c36f2a0cd3 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c @@ -850,13 +850,37 @@ static int rv_thermal_get_temperature(struct pp_hwmgr *hwmgr) static int rv_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value, int *size) { + uint32_t sclk, mclk; + int ret = 0; + switch (idx) { + case AMDGPU_PP_SENSOR_GFX_SCLK: + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency); + if (!ret) { + rv_read_arg_from_smc(hwmgr, &sclk); + /* in units of 10KHZ */ + *((uint32_t *)value) = sclk * 100; + *size = 4; + } + break; + case AMDGPU_PP_SENSOR_GFX_MCLK: + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency); + if (!ret) { + rv_read_arg_from_smc(hwmgr, &mclk); + /* in units of 10KHZ */ + *((uint32_t *)value) = mclk * 100; + *size = 4; + } + break; case AMDGPU_PP_SENSOR_GPU_TEMP: *((uint32_t *)value) = rv_thermal_get_temperature(hwmgr); - return 0; + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + + return ret; } static const struct pp_hwmgr_func rv_hwmgr_funcs = { -- cgit v1.2.3 From 5f628d997d1e41c34dd65bfb7ceb0459868cc925 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 26 Sep 2017 11:51:58 +0800 Subject: drm/amd/powerplay: get raven sclk and mclk levels (v2) v2: squash in rebase fix (Tom) Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | 48 +++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c index a0c36f2a0cd3..938010842c7d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c @@ -619,7 +619,53 @@ static int rv_force_clock_level(struct pp_hwmgr *hwmgr, static int rv_print_clock_levels(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf) { - return 0; + struct rv_hwmgr *data = (struct rv_hwmgr *)(hwmgr->backend); + struct rv_voltage_dependency_table *mclk_table = + data->clock_vol_info.vdd_dep_on_fclk; + int i, now, size = 0; + + switch (type) { + case PP_SCLK: + PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr, + PPSMC_MSG_GetGfxclkFrequency), + "Attempt to get current GFXCLK Failed!", + return -1); + PP_ASSERT_WITH_CODE(!rv_read_arg_from_smc(hwmgr, + &now), + "Attempt to get current GFXCLK Failed!", + return -1); + + size += sprintf(buf + size, "0: %uMhz %s\n", + data->gfx_min_freq_limit / 100, + ((data->gfx_min_freq_limit / 100) + == now) ? "*" : ""); + size += sprintf(buf + size, "1: %uMhz %s\n", + data->gfx_max_freq_limit / 100, + ((data->gfx_max_freq_limit / 100) + == now) ? "*" : ""); + break; + case PP_MCLK: + PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr, + PPSMC_MSG_GetFclkFrequency), + "Attempt to get current MEMCLK Failed!", + return -1); + PP_ASSERT_WITH_CODE(!rv_read_arg_from_smc(hwmgr, + &now), + "Attempt to get current MEMCLK Failed!", + return -1); + + for (i = 0; i < mclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, + mclk_table->entries[i].clk / 100, + ((mclk_table->entries[i].clk / 100) + == now) ? "*" : ""); + break; + default: + break; + } + + return size; } static int rv_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, -- cgit v1.2.3 From de1960369115bc997689cefc53a548b3db50a78c Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Sat, 30 Sep 2017 09:13:47 +0800 Subject: drm/amd/powerplay: fix typo on avfs disable Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 6a859542382b..48de45ec0eaf 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -2364,7 +2364,7 @@ static int vega10_avfs_enable(struct pp_hwmgr *hwmgr, bool enable) } else { PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr, false, - data->smu_features[GNLD_AVFS].smu_feature_id), + data->smu_features[GNLD_AVFS].smu_feature_bitmap), "[avfs_control] Attempt to Disable AVFS feature Failed!", return -1); data->smu_features[GNLD_AVFS].enabled = false; -- cgit v1.2.3 From 1756f1bbddad4552cb4e8773c54960a4cc4ba107 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Wed, 4 Oct 2017 13:44:52 -0400 Subject: drm/amd/powerplay: Partially revert changes and fix smu7_notify_smc_display() This partially reverts 0b6b4cbf77c995a34a4ec3d705a636434dadc51a and fixes the noise issues on Tonga. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 8dbe9148aad3..4826b2991b7e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -3825,14 +3825,11 @@ static int smu7_notify_link_speed_change_after_state_change( static int smu7_notify_smc_display(struct pp_hwmgr *hwmgr) { struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - int ret = 0; - if (hwmgr->feature_mask & PP_VBI_TIME_SUPPORT_MASK) { + if (hwmgr->feature_mask & PP_VBI_TIME_SUPPORT_MASK) smum_send_msg_to_smc_with_parameter(hwmgr, (PPSMC_Msg)PPSMC_MSG_SetVBITimeout, data->frame_time_x2); - ret = (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_HasDisplay) == 0) ? 0 : -EINVAL; - } - return ret; + return (smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_HasDisplay) == 0) ? 0 : -EINVAL; } static int smu7_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input) -- cgit v1.2.3 From 4b6aca2f59dca3228a370ddefc94f3a44e57c772 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 6 Oct 2017 12:17:16 +0800 Subject: drm/amd/powerplay: fix mclk can't switch on Tonga regression issue caused by commit 47047263c52779f1f3393c32e3e53661b53a372e ("drm/amd/powerplay: delete eventmgr related files.") Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 1 - drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 35e80c969737..ce59e0e67cb2 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -292,7 +292,6 @@ int hwmgr_hw_fini(struct pp_instance *handle) phm_stop_thermal_controller(hwmgr); psm_set_boot_states(hwmgr); - phm_display_configuration_changed(hwmgr); psm_adjust_power_state_dynamic(hwmgr, false, NULL); phm_disable_dynamic_state_management(hwmgr); phm_disable_clock_power_gatings(hwmgr); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c index 167cdc321db2..ffa44bbb218e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c @@ -224,6 +224,8 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, if (skip) return 0; + phm_display_configuration_changed(hwmgr); + if (new_ps != NULL) requested = new_ps; else @@ -232,7 +234,6 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, pcurrent = hwmgr->current_ps; phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); - if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, &pcurrent->hardware, &requested->hardware, &equal))) equal = false; @@ -241,6 +242,9 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware); memcpy(hwmgr->current_ps, hwmgr->request_ps, hwmgr->ps_size); } + + phm_notify_smc_display_config_after_ps_adjustment(hwmgr); + return 0; } -- cgit v1.2.3 From d0e62855fa7aea4736297abcbe4f0777f1332883 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Sun, 1 Oct 2017 20:00:07 -0400 Subject: drm/amdgpu: add uvd enc registers in header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add UVD encode write/read/size/base registers definition for uvd6.3 HEVC ecoding Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h index 378f4b6b43da..344237256d02 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h +++ b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h @@ -36,6 +36,16 @@ #define mmUVD_UDEC_DBW_ADDR_CONFIG 0x3bd5 #define mmUVD_POWER_STATUS_U 0x3bfd #define mmUVD_NO_OP 0x3bff +#define mmUVD_RB_BASE_LO2 0x3c21 +#define mmUVD_RB_BASE_HI2 0x3c22 +#define mmUVD_RB_SIZE2 0x3c23 +#define mmUVD_RB_RPTR2 0x3c24 +#define mmUVD_RB_WPTR2 0x3c25 +#define mmUVD_RB_BASE_LO 0x3c26 +#define mmUVD_RB_BASE_HI 0x3c27 +#define mmUVD_RB_SIZE 0x3c28 +#define mmUVD_RB_RPTR 0x3c29 +#define mmUVD_RB_WPTR 0x3c2a #define mmUVD_LMI_RBC_RB_64BIT_BAR_LOW 0x3c69 #define mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH 0x3c68 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW 0x3c67 @@ -43,6 +53,11 @@ #define mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW 0x3c5f #define mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH 0x3c5e #define mmUVD_SEMA_CNTL 0x3d00 +#define mmUVD_RB_WPTR3 0x3d1c +#define mmUVD_RB_RPTR3 0x3d1b +#define mmUVD_RB_BASE_LO3 0x3d1d +#define mmUVD_RB_BASE_HI3 0x3d1e +#define mmUVD_RB_SIZE3 0x3d1f #define mmUVD_LMI_EXT40_ADDR 0x3d26 #define mmUVD_CTX_INDEX 0x3d28 #define mmUVD_CTX_DATA 0x3d29 -- cgit v1.2.3 From 8ed841505892042749dbfb8544382c4fba323bc3 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 14:17:34 -0400 Subject: drm/amdgpu: add uvd enc command in header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add UVD encode command interface definition for uvd6.3 HEVC encoding Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vid.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/vid.h b/drivers/gpu/drm/amd/amdgpu/vid.h index a6485254a169..dbf3703cbd1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/vid.h +++ b/drivers/gpu/drm/amd/amdgpu/vid.h @@ -465,6 +465,16 @@ #define VCE_CMD_UPDATE_PTB 0x00000107 #define VCE_CMD_FLUSH_TLB 0x00000108 +/* HEVC ENC */ +#define HEVC_ENC_CMD_NO_OP 0x00000000 +#define HEVC_ENC_CMD_END 0x00000001 +#define HEVC_ENC_CMD_FENCE 0x00000003 +#define HEVC_ENC_CMD_TRAP 0x00000004 +#define HEVC_ENC_CMD_IB_VM 0x00000102 +#define HEVC_ENC_CMD_WAIT_GE 0x00000106 +#define HEVC_ENC_CMD_UPDATE_PTB 0x00000107 +#define HEVC_ENC_CMD_FLUSH_TLB 0x00000108 + /* mmPA_SC_RASTER_CONFIG mask */ #define RB_MAP_PKR0(x) ((x) << 0) #define RB_MAP_PKR0_MASK (0x3 << 0) -- cgit v1.2.3 From c0f2f2e66cfdfe8219592d2625dbf347eaf826d5 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 16:14:26 -0400 Subject: drm/amdgpu: add new uvd enc ring methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new UVD encode ring methods get/set/emit/flush/sync to support uvd6.3 HEVC encoding Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 117 ++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 31db356476f8..d6429157ffb6 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -61,6 +61,22 @@ static uint64_t uvd_v6_0_ring_get_rptr(struct amdgpu_ring *ring) return RREG32(mmUVD_RBC_RB_RPTR); } +/** + * uvd_v6_0_enc_ring_get_rptr - get enc read pointer + * + * @ring: amdgpu_ring pointer + * + * Returns the current hardware enc read pointer + */ +static uint64_t uvd_v6_0_enc_ring_get_rptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + if (ring == &adev->uvd.ring_enc[0]) + return RREG32(mmUVD_RB_RPTR); + else + return RREG32(mmUVD_RB_RPTR2); +} /** * uvd_v6_0_ring_get_wptr - get write pointer * @@ -75,6 +91,23 @@ static uint64_t uvd_v6_0_ring_get_wptr(struct amdgpu_ring *ring) return RREG32(mmUVD_RBC_RB_WPTR); } +/** + * uvd_v6_0_enc_ring_get_wptr - get enc write pointer + * + * @ring: amdgpu_ring pointer + * + * Returns the current hardware enc write pointer + */ +static uint64_t uvd_v6_0_enc_ring_get_wptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + if (ring == &adev->uvd.ring_enc[0]) + return RREG32(mmUVD_RB_WPTR); + else + return RREG32(mmUVD_RB_WPTR2); +} + /** * uvd_v6_0_ring_set_wptr - set write pointer * @@ -89,6 +122,25 @@ static void uvd_v6_0_ring_set_wptr(struct amdgpu_ring *ring) WREG32(mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); } +/** + * uvd_v6_0_enc_ring_set_wptr - set enc write pointer + * + * @ring: amdgpu_ring pointer + * + * Commits the enc write pointer to the hardware + */ +static void uvd_v6_0_enc_ring_set_wptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + if (ring == &adev->uvd.ring_enc[0]) + WREG32(mmUVD_RB_WPTR, + lower_32_bits(ring->wptr)); + else + WREG32(mmUVD_RB_WPTR2, + lower_32_bits(ring->wptr)); +} + static int uvd_v6_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -576,6 +628,26 @@ static void uvd_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq amdgpu_ring_write(ring, 2); } +/** + * uvd_v6_0_enc_ring_emit_fence - emit an enc fence & trap command + * + * @ring: amdgpu_ring pointer + * @fence: fence to emit + * + * Write enc a fence and a trap command to the ring. + */ +static void uvd_v6_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, + u64 seq, unsigned flags) +{ + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); + + amdgpu_ring_write(ring, HEVC_ENC_CMD_FENCE); + amdgpu_ring_write(ring, addr); + amdgpu_ring_write(ring, upper_32_bits(addr)); + amdgpu_ring_write(ring, seq); + amdgpu_ring_write(ring, HEVC_ENC_CMD_TRAP); +} + /** * uvd_v6_0_ring_emit_hdp_flush - emit an hdp flush * @@ -667,6 +739,24 @@ static void uvd_v6_0_ring_emit_ib(struct amdgpu_ring *ring, amdgpu_ring_write(ring, ib->length_dw); } +/** + * uvd_v6_0_enc_ring_emit_ib - enc execute indirect buffer + * + * @ring: amdgpu_ring pointer + * @ib: indirect buffer to execute + * + * Write enc ring commands to execute the indirect buffer + */ +static void uvd_v6_0_enc_ring_emit_ib(struct amdgpu_ring *ring, + struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch) +{ + amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM); + amdgpu_ring_write(ring, vm_id); + amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); + amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); + amdgpu_ring_write(ring, ib->length_dw); +} + static void uvd_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring, unsigned vm_id, uint64_t pd_addr) { @@ -718,6 +808,33 @@ static void uvd_v6_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) amdgpu_ring_write(ring, 0xE); } +static void uvd_v6_0_enc_ring_emit_pipeline_sync(struct amdgpu_ring *ring) +{ + uint32_t seq = ring->fence_drv.sync_seq; + uint64_t addr = ring->fence_drv.gpu_addr; + + amdgpu_ring_write(ring, HEVC_ENC_CMD_WAIT_GE); + amdgpu_ring_write(ring, lower_32_bits(addr)); + amdgpu_ring_write(ring, upper_32_bits(addr)); + amdgpu_ring_write(ring, seq); +} + +static void uvd_v6_0_enc_ring_insert_end(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, HEVC_ENC_CMD_END); +} + +static void uvd_v6_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring, + unsigned int vm_id, uint64_t pd_addr) +{ + amdgpu_ring_write(ring, HEVC_ENC_CMD_UPDATE_PTB); + amdgpu_ring_write(ring, vm_id); + amdgpu_ring_write(ring, pd_addr >> 12); + + amdgpu_ring_write(ring, HEVC_ENC_CMD_FLUSH_TLB); + amdgpu_ring_write(ring, vm_id); +} + static bool uvd_v6_0_is_idle(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; -- cgit v1.2.3 From 06a7e9cb576c9ce31cc6da6d4d09476d81e41058 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 17:29:06 -0400 Subject: drm/amdgpu: add uvd enc rings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UVD 6.3 has two UVD encode rings. Add the ring structures and initialize the hw ring buffers. Currently only ASIC Polaris10/11/12 uses UVD6.3 encode engine on HEVC encoding. Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 54 +++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index d6429157ffb6..12697ddb2007 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -47,6 +47,18 @@ static int uvd_v6_0_set_clockgating_state(void *handle, static void uvd_v6_0_enable_mgcg(struct amdgpu_device *adev, bool enable); +/** +* uvd_v6_0_enc_support - get encode support status +* +* @adev: amdgpu_device pointer +* +* Returns the current hardware encode support status +*/ +static inline bool uvd_v6_0_enc_support(struct amdgpu_device *adev) +{ + return ((adev->asic_type >= CHIP_POLARIS10) && (adev->asic_type <= CHIP_POLARIS12)); +} + /** * uvd_v6_0_ring_get_rptr - get read pointer * @@ -146,6 +158,11 @@ static int uvd_v6_0_early_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; uvd_v6_0_set_ring_funcs(adev); + + if (uvd_v6_0_enc_support(adev)) { + adev->uvd.num_enc_rings = 2; + } + uvd_v6_0_set_irq_funcs(adev); return 0; @@ -154,7 +171,7 @@ static int uvd_v6_0_early_init(void *handle) static int uvd_v6_0_sw_init(void *handle) { struct amdgpu_ring *ring; - int r; + int i, r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* UVD TRAP */ @@ -173,19 +190,36 @@ static int uvd_v6_0_sw_init(void *handle) ring = &adev->uvd.ring; sprintf(ring->name, "uvd"); r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); + if (r) + return r; + + if (uvd_v6_0_enc_support(adev)) { + for (i = 0; i < adev->uvd.num_enc_rings; ++i) { + ring = &adev->uvd.ring_enc[i]; + sprintf(ring->name, "uvd_enc%d", i); + r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); + if (r) + return r; + } + } return r; } static int uvd_v6_0_sw_fini(void *handle) { - int r; + int i, r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; r = amdgpu_uvd_suspend(adev); if (r) return r; + if (uvd_v6_0_enc_support(adev)) { + for (i = 0; i < adev->uvd.num_enc_rings; ++i) + amdgpu_ring_fini(&adev->uvd.ring_enc[i]); + } + return amdgpu_uvd_sw_fini(adev); } @@ -566,6 +600,22 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0); + if (uvd_v6_0_enc_support(adev)) { + ring = &adev->uvd.ring_enc[0]; + WREG32(mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); + WREG32(mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); + WREG32(mmUVD_RB_BASE_LO, ring->gpu_addr); + WREG32(mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); + WREG32(mmUVD_RB_SIZE, ring->ring_size / 4); + + ring = &adev->uvd.ring_enc[1]; + WREG32(mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); + WREG32(mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); + WREG32(mmUVD_RB_BASE_LO2, ring->gpu_addr); + WREG32(mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); + WREG32(mmUVD_RB_SIZE2, ring->ring_size / 4); + } + return 0; } -- cgit v1.2.3 From 296191c5e88fc920f3e624ceb27dd544c76a1284 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 15:20:23 -0400 Subject: drm/amdgpu: add uvd enc into run queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 12697ddb2007..7c39b4754026 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -183,6 +183,18 @@ static int uvd_v6_0_sw_init(void *handle) if (r) return r; + if (uvd_v6_0_enc_support(adev)) { + struct amd_sched_rq *rq; + ring = &adev->uvd.ring_enc[0]; + rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; + r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity_enc, + rq, amdgpu_sched_jobs); + if (r) { + DRM_ERROR("Failed setting up UVD ENC run queue.\n"); + return r; + } + } + r = amdgpu_uvd_resume(adev); if (r) return r; @@ -216,6 +228,8 @@ static int uvd_v6_0_sw_fini(void *handle) return r; if (uvd_v6_0_enc_support(adev)) { + amd_sched_entity_fini(&adev->uvd.ring_enc[0].sched, &adev->uvd.entity_enc); + for (i = 0; i < adev->uvd.num_enc_rings; ++i) amdgpu_ring_fini(&adev->uvd.ring_enc[i]); } -- cgit v1.2.3 From c259ee6e3058f2a1b30aac1e77d2c6e8699eccd9 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 16:37:11 -0400 Subject: drm/amdgpu: add uvd enc vm functions (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add UVD encode ring vm functions to handle frame ecoding. v2: squash in warning fix (James) Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 46 +++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 7c39b4754026..5f9e9ec53b89 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -38,6 +38,8 @@ #include "vi.h" static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev); +static void uvd_v6_0_set_enc_ring_funcs(struct amdgpu_device *adev); + static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev); static int uvd_v6_0_start(struct amdgpu_device *adev); static void uvd_v6_0_stop(struct amdgpu_device *adev); @@ -161,6 +163,7 @@ static int uvd_v6_0_early_init(void *handle) if (uvd_v6_0_enc_support(adev)) { adev->uvd.num_enc_rings = 2; + uvd_v6_0_set_enc_ring_funcs(adev); } uvd_v6_0_set_irq_funcs(adev); @@ -290,8 +293,12 @@ static int uvd_v6_0_hw_init(void *handle) amdgpu_ring_commit(ring); done: - if (!r) - DRM_INFO("UVD initialized successfully.\n"); + if (!r) { + if (uvd_v6_0_enc_support(adev)) + DRM_INFO("UVD and UVD ENC initialized successfully.\n"); + else + DRM_INFO("UVD initialized successfully.\n"); + } return r; } @@ -1334,6 +1341,31 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_vm_funcs = { .end_use = amdgpu_uvd_ring_end_use, }; +static const struct amdgpu_ring_funcs uvd_v6_0_enc_ring_vm_funcs = { + .type = AMDGPU_RING_TYPE_UVD_ENC, + .align_mask = 0x3f, + .nop = HEVC_ENC_CMD_NO_OP, + .support_64bit_ptrs = false, + .get_rptr = uvd_v6_0_enc_ring_get_rptr, + .get_wptr = uvd_v6_0_enc_ring_get_wptr, + .set_wptr = uvd_v6_0_enc_ring_set_wptr, + .emit_frame_size = + 4 + /* uvd_v6_0_enc_ring_emit_pipeline_sync */ + 6 + /* uvd_v6_0_enc_ring_emit_vm_flush */ + 5 + 5 + /* uvd_v6_0_enc_ring_emit_fence x2 vm fence */ + 1, /* uvd_v6_0_enc_ring_insert_end */ + .emit_ib_size = 5, /* uvd_v6_0_enc_ring_emit_ib */ + .emit_ib = uvd_v6_0_enc_ring_emit_ib, + .emit_fence = uvd_v6_0_enc_ring_emit_fence, + .emit_vm_flush = uvd_v6_0_enc_ring_emit_vm_flush, + .emit_pipeline_sync = uvd_v6_0_enc_ring_emit_pipeline_sync, + .insert_nop = amdgpu_ring_insert_nop, + .insert_end = uvd_v6_0_enc_ring_insert_end, + .pad_ib = amdgpu_ring_generic_pad_ib, + .begin_use = amdgpu_uvd_ring_begin_use, + .end_use = amdgpu_uvd_ring_end_use, +}; + static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) { if (adev->asic_type >= CHIP_POLARIS10) { @@ -1345,6 +1377,16 @@ static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) } } +static void uvd_v6_0_set_enc_ring_funcs(struct amdgpu_device *adev) +{ + int i; + + for (i = 0; i < adev->uvd.num_enc_rings; ++i) + adev->uvd.ring_enc[i].funcs = &uvd_v6_0_enc_ring_vm_funcs; + + DRM_INFO("UVD ENC is enabled in VM mode\n"); +} + static const struct amdgpu_irq_src_funcs uvd_v6_0_irq_funcs = { .set = uvd_v6_0_set_interrupt_state, .process = uvd_v6_0_process_interrupt, -- cgit v1.2.3 From 2a91f272e34c721bbb8f148c5f15a0a454dac2fd Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 16:40:12 -0400 Subject: drm/amdgpu: add uvd enc ring test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add UVD encode ring test functions. And enable UVD encode ring test during UVD encode hardware initialization. Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 55 ++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 5f9e9ec53b89..019aed1e6b73 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -155,6 +155,46 @@ static void uvd_v6_0_enc_ring_set_wptr(struct amdgpu_ring *ring) lower_32_bits(ring->wptr)); } +/** + * uvd_v6_0_enc_ring_test_ring - test if UVD ENC ring is working + * + * @ring: the engine to test on + * + */ +static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + uint32_t rptr = amdgpu_ring_get_rptr(ring); + unsigned i; + int r; + + r = amdgpu_ring_alloc(ring, 16); + if (r) { + DRM_ERROR("amdgpu: uvd enc failed to lock ring %d (%d).\n", + ring->idx, r); + return r; + } + amdgpu_ring_write(ring, HEVC_ENC_CMD_END); + amdgpu_ring_commit(ring); + + for (i = 0; i < adev->usec_timeout; i++) { + if (amdgpu_ring_get_rptr(ring) != rptr) + break; + DRM_UDELAY(1); + } + + if (i < adev->usec_timeout) { + DRM_INFO("ring test on %d succeeded in %d usecs\n", + ring->idx, i); + } else { + DRM_ERROR("amdgpu: ring %d test failed\n", + ring->idx); + r = -ETIMEDOUT; + } + + return r; +} + static int uvd_v6_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -252,7 +292,7 @@ static int uvd_v6_0_hw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_ring *ring = &adev->uvd.ring; uint32_t tmp; - int r; + int i, r; amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); @@ -292,6 +332,18 @@ static int uvd_v6_0_hw_init(void *handle) amdgpu_ring_commit(ring); + if (uvd_v6_0_enc_support(adev)) { + for (i = 0; i < adev->uvd.num_enc_rings; ++i) { + ring = &adev->uvd.ring_enc[i]; + ring->ready = true; + r = amdgpu_ring_test_ring(ring); + if (r) { + ring->ready = false; + goto done; + } + } + } + done: if (!r) { if (uvd_v6_0_enc_support(adev)) @@ -1359,6 +1411,7 @@ static const struct amdgpu_ring_funcs uvd_v6_0_enc_ring_vm_funcs = { .emit_fence = uvd_v6_0_enc_ring_emit_fence, .emit_vm_flush = uvd_v6_0_enc_ring_emit_vm_flush, .emit_pipeline_sync = uvd_v6_0_enc_ring_emit_pipeline_sync, + .test_ring = uvd_v6_0_enc_ring_test_ring, .insert_nop = amdgpu_ring_insert_nop, .insert_end = uvd_v6_0_enc_ring_insert_end, .pad_ib = amdgpu_ring_generic_pad_ib, -- cgit v1.2.3 From e0128efb08b3d628d767ec8578e77cdd7ecc8f81 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 16:42:27 -0400 Subject: drm/amdgpu: add uvd enc ib test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generate create/destroy messages to test UVD encode indirect buffer function. And enable UVD encode IB test during device initialization. Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 172 ++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 019aed1e6b73..5fd14c972fe7 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -195,6 +195,177 @@ static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) return r; } +/** + * uvd_v6_0_enc_get_create_msg - generate a UVD ENC create msg + * + * @adev: amdgpu_device pointer + * @ring: ring we should submit the msg to + * @handle: session handle to use + * @fence: optional fence to return + * + * Open up a stream for HW test + */ +static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct dma_fence **fence) +{ + const unsigned ib_size_dw = 16; + struct amdgpu_job *job; + struct amdgpu_ib *ib; + struct dma_fence *f = NULL; + uint64_t dummy; + int i, r; + + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); + if (r) + return r; + + ib = &job->ibs[0]; + dummy = ib->gpu_addr + 1024; + + ib->length_dw = 0; + ib->ptr[ib->length_dw++] = 0x00000018; + ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ + ib->ptr[ib->length_dw++] = handle; + ib->ptr[ib->length_dw++] = 0x00010000; + ib->ptr[ib->length_dw++] = upper_32_bits(dummy); + ib->ptr[ib->length_dw++] = dummy; + + ib->ptr[ib->length_dw++] = 0x00000014; + ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ + ib->ptr[ib->length_dw++] = 0x0000001c; + ib->ptr[ib->length_dw++] = 0x00000001; + ib->ptr[ib->length_dw++] = 0x00000000; + + ib->ptr[ib->length_dw++] = 0x00000008; + ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */ + + for (i = ib->length_dw; i < ib_size_dw; ++i) + ib->ptr[i] = 0x0; + + r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); + job->fence = dma_fence_get(f); + if (r) + goto err; + + amdgpu_job_free(job); + if (fence) + *fence = dma_fence_get(f); + dma_fence_put(f); + return 0; + +err: + amdgpu_job_free(job); + return r; +} + +/** + * uvd_v6_0_enc_get_destroy_msg - generate a UVD ENC destroy msg + * + * @adev: amdgpu_device pointer + * @ring: ring we should submit the msg to + * @handle: session handle to use + * @fence: optional fence to return + * + * Close up a stream for HW test or if userspace failed to do so + */ +int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, + bool direct, struct dma_fence **fence) +{ + const unsigned ib_size_dw = 16; + struct amdgpu_job *job; + struct amdgpu_ib *ib; + struct dma_fence *f = NULL; + uint64_t dummy; + int i, r; + + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); + if (r) + return r; + + ib = &job->ibs[0]; + dummy = ib->gpu_addr + 1024; + + ib->length_dw = 0; + ib->ptr[ib->length_dw++] = 0x00000018; + ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ + ib->ptr[ib->length_dw++] = handle; + ib->ptr[ib->length_dw++] = 0x00010000; + ib->ptr[ib->length_dw++] = upper_32_bits(dummy); + ib->ptr[ib->length_dw++] = dummy; + + ib->ptr[ib->length_dw++] = 0x00000014; + ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ + ib->ptr[ib->length_dw++] = 0x0000001c; + ib->ptr[ib->length_dw++] = 0x00000001; + ib->ptr[ib->length_dw++] = 0x00000000; + + ib->ptr[ib->length_dw++] = 0x00000008; + ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */ + + for (i = ib->length_dw; i < ib_size_dw; ++i) + ib->ptr[i] = 0x0; + + if (direct) { + r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); + job->fence = dma_fence_get(f); + if (r) + goto err; + + amdgpu_job_free(job); + } else { + r = amdgpu_job_submit(job, ring, &ring->adev->vce.entity, + AMDGPU_FENCE_OWNER_UNDEFINED, &f); + if (r) + goto err; + } + + if (fence) + *fence = dma_fence_get(f); + dma_fence_put(f); + return 0; + +err: + amdgpu_job_free(job); + return r; +} + +/** + * uvd_v6_0_enc_ring_test_ib - test if UVD ENC IBs are working + * + * @ring: the engine to test on + * + */ +static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) +{ + struct dma_fence *fence = NULL; + long r; + + r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL); + if (r) { + DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); + goto error; + } + + r = uvd_v6_0_enc_get_destroy_msg(ring, 1, true, &fence); + if (r) { + DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); + goto error; + } + + r = dma_fence_wait_timeout(fence, false, timeout); + if (r == 0) { + DRM_ERROR("amdgpu: IB test timed out.\n"); + r = -ETIMEDOUT; + } else if (r < 0) { + DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); + } else { + DRM_INFO("ib test on ring %d succeeded\n", ring->idx); + r = 0; + } +error: + dma_fence_put(fence); + return r; +} static int uvd_v6_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -1412,6 +1583,7 @@ static const struct amdgpu_ring_funcs uvd_v6_0_enc_ring_vm_funcs = { .emit_vm_flush = uvd_v6_0_enc_ring_emit_vm_flush, .emit_pipeline_sync = uvd_v6_0_enc_ring_emit_pipeline_sync, .test_ring = uvd_v6_0_enc_ring_test_ring, + .test_ib = uvd_v6_0_enc_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, .insert_end = uvd_v6_0_enc_ring_insert_end, .pad_ib = amdgpu_ring_generic_pad_ib, -- cgit v1.2.3 From 65da0d40e561a717fee065d69d6e4f8d5b34db32 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Fri, 29 Sep 2017 16:47:31 -0400 Subject: drm/amdgpu: add uvd enc irq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add UVD encode IRQ handle and enable the UVD encode trap Signed-off-by: James Zhu Reviewed-and-Tested-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 40 +++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 5fd14c972fe7..60af7310a234 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -393,6 +393,15 @@ static int uvd_v6_0_sw_init(void *handle) if (r) return r; + /* UVD ENC TRAP */ + if (uvd_v6_0_enc_support(adev)) { + for (i = 0; i < adev->uvd.num_enc_rings; ++i) { + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 119, &adev->uvd.irq); + if (r) + return r; + } + } + r = amdgpu_uvd_sw_init(adev); if (r) return r; @@ -1236,8 +1245,31 @@ static int uvd_v6_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { + bool int_handled = true; DRM_DEBUG("IH: UVD TRAP\n"); - amdgpu_fence_process(&adev->uvd.ring); + + switch (entry->src_id) { + case 124: + amdgpu_fence_process(&adev->uvd.ring); + break; + case 119: + if (likely(uvd_v6_0_enc_support(adev))) + amdgpu_fence_process(&adev->uvd.ring_enc[0]); + else + int_handled = false; + break; + case 120: + if (likely(uvd_v6_0_enc_support(adev))) + amdgpu_fence_process(&adev->uvd.ring_enc[1]); + else + int_handled = false; + break; + } + + if (false == int_handled) + DRM_ERROR("Unhandled interrupt: %d %d\n", + entry->src_id, entry->src_data[0]); + return 0; } @@ -1619,7 +1651,11 @@ static const struct amdgpu_irq_src_funcs uvd_v6_0_irq_funcs = { static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev) { - adev->uvd.irq.num_types = 1; + if (uvd_v6_0_enc_support(adev)) + adev->uvd.irq.num_types = adev->uvd.num_enc_rings + 1; + else + adev->uvd.irq.num_types = 1; + adev->uvd.irq.funcs = &uvd_v6_0_irq_funcs; } -- cgit v1.2.3 From f9ebec52b5f115a0b06cdabe3036b858bfbb588a Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 18 Sep 2017 15:45:11 +0200 Subject: drm/ttm: remove unsued options from ttm_mem_global_alloc_page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nobody is actually using that, remove it. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_memory.c | 6 ++---- drivers/gpu/drm/ttm/ttm_page_alloc.c | 3 +-- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 3 +-- include/drm/ttm/ttm_memory.h | 3 +-- 4 files changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index 29855be96be0..4f9978cbc5bc 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -546,8 +546,7 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, EXPORT_SYMBOL(ttm_mem_global_alloc); int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, - struct page *page, - bool no_wait, bool interruptible) + struct page *page) { struct ttm_mem_zone *zone = NULL; @@ -564,8 +563,7 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL) zone = glob->zone_kernel; #endif - return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, no_wait, - interruptible); + return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, false, false); } void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 052e1f102113..74f465ea914b 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -882,8 +882,7 @@ int ttm_pool_populate(struct ttm_tt *ttm) return -ENOMEM; } - ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i], - false, false); + ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i]); if (unlikely(ret != 0)) { ttm_pool_unpopulate(ttm); return -ENOMEM; diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 06bc14b55e66..b8905bdd4143 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -902,8 +902,7 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev) return -ENOMEM; } - ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i], - false, false); + ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i]); if (unlikely(ret != 0)) { ttm_dma_unpopulate(ttm_dma, dev); return -ENOMEM; diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h index c4520890f267..8184ff144176 100644 --- a/include/drm/ttm/ttm_memory.h +++ b/include/drm/ttm/ttm_memory.h @@ -150,8 +150,7 @@ extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, extern void ttm_mem_global_free(struct ttm_mem_global *glob, uint64_t amount); extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, - struct page *page, - bool no_wait, bool interruptible); + struct page *page); extern void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page); extern size_t ttm_round_pot(size_t size); -- cgit v1.2.3 From d188bfa5532ce5b426681d8530ff1a9683eea0ad Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 4 Jul 2017 16:56:24 +0200 Subject: drm/ttm: add support for different pool sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correctly handle different page sizes in the memory accounting. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_memory.c | 10 +++++----- drivers/gpu/drm/ttm/ttm_page_alloc.c | 5 +++-- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 7 ++++--- include/drm/ttm/ttm_memory.h | 4 ++-- 4 files changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index 4f9978cbc5bc..e96374990398 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -546,7 +546,7 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, EXPORT_SYMBOL(ttm_mem_global_alloc); int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, - struct page *page) + struct page *page, uint64_t size) { struct ttm_mem_zone *zone = NULL; @@ -563,10 +563,11 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL) zone = glob->zone_kernel; #endif - return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, false, false); + return ttm_mem_global_alloc_zone(glob, zone, size, false, false); } -void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page) +void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page, + uint64_t size) { struct ttm_mem_zone *zone = NULL; @@ -577,10 +578,9 @@ void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page) if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL) zone = glob->zone_kernel; #endif - ttm_mem_global_free_zone(glob, zone, PAGE_SIZE); + ttm_mem_global_free_zone(glob, zone, size); } - size_t ttm_round_pot(size_t size) { if ((size & (size - 1)) == 0) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 74f465ea914b..e11fd76e06f4 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -882,7 +882,8 @@ int ttm_pool_populate(struct ttm_tt *ttm) return -ENOMEM; } - ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i]); + ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i], + PAGE_SIZE); if (unlikely(ret != 0)) { ttm_pool_unpopulate(ttm); return -ENOMEM; @@ -909,7 +910,7 @@ void ttm_pool_unpopulate(struct ttm_tt *ttm) for (i = 0; i < ttm->num_pages; ++i) { if (ttm->pages[i]) { ttm_mem_global_free_page(ttm->glob->mem_glob, - ttm->pages[i]); + ttm->pages[i], PAGE_SIZE); ttm_put_pages(&ttm->pages[i], 1, ttm->page_flags, ttm->caching_state); diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index b8905bdd4143..53626578004c 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -902,7 +902,8 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev) return -ENOMEM; } - ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i]); + ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i], + pool->size); if (unlikely(ret != 0)) { ttm_dma_unpopulate(ttm_dma, dev); return -ENOMEM; @@ -967,13 +968,13 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) if (is_cached) { list_for_each_entry_safe(d_page, next, &ttm_dma->pages_list, page_list) { ttm_mem_global_free_page(ttm->glob->mem_glob, - d_page->p); + d_page->p, pool->size); ttm_dma_page_put(pool, d_page); } } else { for (i = 0; i < count; i++) { ttm_mem_global_free_page(ttm->glob->mem_glob, - ttm->pages[i]); + ttm->pages[i], pool->size); } } diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h index 8184ff144176..2c1e3598effe 100644 --- a/include/drm/ttm/ttm_memory.h +++ b/include/drm/ttm/ttm_memory.h @@ -150,9 +150,9 @@ extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, extern void ttm_mem_global_free(struct ttm_mem_global *glob, uint64_t amount); extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, - struct page *page); + struct page *page, uint64_t size); extern void ttm_mem_global_free_page(struct ttm_mem_global *glob, - struct page *page); + struct page *page, uint64_t size); extern size_t ttm_round_pot(size_t size); extern uint64_t ttm_get_kernel_zone_memory_size(struct ttm_mem_global *glob); #endif -- cgit v1.2.3 From 648bc3574716400acc06f99915815f80d9563783 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 6 Jul 2017 09:59:43 +0200 Subject: drm/ttm: add transparent huge page support for DMA allocations v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to allocate huge pages when it makes sense. v2: fix comment and use ifdef Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 217 ++++++++++++++++++++++++------- 1 file changed, 169 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 53626578004c..e5ef10d34748 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -60,21 +60,25 @@ #define NUM_PAGES_TO_ALLOC (PAGE_SIZE/sizeof(struct page *)) #define SMALL_ALLOCATION 4 #define FREE_ALL_PAGES (~0U) +#define VADDR_FLAG_HUGE_POOL 1UL enum pool_type { IS_UNDEFINED = 0, IS_WC = 1 << 1, IS_UC = 1 << 2, IS_CACHED = 1 << 3, - IS_DMA32 = 1 << 4 + IS_DMA32 = 1 << 4, + IS_HUGE = 1 << 5 }; /* - * The pool structure. There are usually six pools: + * The pool structure. There are up to nine pools: * - generic (not restricted to DMA32): * - write combined, uncached, cached. * - dma32 (up to 2^32 - so up 4GB): * - write combined, uncached, cached. + * - huge (not restricted to DMA32): + * - write combined, uncached, cached. * for each 'struct device'. The 'cached' is for pages that are actively used. * The other ones can be shrunk by the shrinker API if neccessary. * @pools: The 'struct device->dma_pools' link. @@ -114,13 +118,14 @@ struct dma_pool { * The accounting page keeping track of the allocated page along with * the DMA address. * @page_list: The link to the 'page_list' in 'struct dma_pool'. - * @vaddr: The virtual address of the page + * @vaddr: The virtual address of the page and a flag if the page belongs to a + * huge pool * @dma: The bus address of the page. If the page is not allocated * via the DMA API, it will be -1. */ struct dma_page { struct list_head page_list; - void *vaddr; + unsigned long vaddr; struct page *p; dma_addr_t dma; }; @@ -319,7 +324,8 @@ static int ttm_set_pages_caching(struct dma_pool *pool, static void __ttm_dma_free_page(struct dma_pool *pool, struct dma_page *d_page) { dma_addr_t dma = d_page->dma; - dma_free_coherent(pool->dev, pool->size, d_page->vaddr, dma); + d_page->vaddr &= ~VADDR_FLAG_HUGE_POOL; + dma_free_coherent(pool->dev, pool->size, (void *)d_page->vaddr, dma); kfree(d_page); d_page = NULL; @@ -327,19 +333,22 @@ static void __ttm_dma_free_page(struct dma_pool *pool, struct dma_page *d_page) static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool) { struct dma_page *d_page; + void *vaddr; d_page = kmalloc(sizeof(struct dma_page), GFP_KERNEL); if (!d_page) return NULL; - d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size, - &d_page->dma, - pool->gfp_flags); - if (d_page->vaddr) { - if (is_vmalloc_addr(d_page->vaddr)) - d_page->p = vmalloc_to_page(d_page->vaddr); + vaddr = dma_alloc_coherent(pool->dev, pool->size, &d_page->dma, + pool->gfp_flags); + if (vaddr) { + if (is_vmalloc_addr(vaddr)) + d_page->p = vmalloc_to_page(vaddr); else - d_page->p = virt_to_page(d_page->vaddr); + d_page->p = virt_to_page(vaddr); + d_page->vaddr = (unsigned long)vaddr; + if (pool->type & IS_HUGE) + d_page->vaddr |= VADDR_FLAG_HUGE_POOL; } else { kfree(d_page); d_page = NULL; @@ -371,11 +380,40 @@ static void ttm_pool_update_free_locked(struct dma_pool *pool, } /* set memory back to wb and free the pages. */ +static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page) +{ + struct page *page = d_page->p; + unsigned i, num_pages; + int ret; + + /* Don't set WB on WB page pool. */ + if (!(pool->type & IS_CACHED)) { + num_pages = pool->size / PAGE_SIZE; + for (i = 0; i < num_pages; ++i, ++page) { + ret = set_pages_array_wb(&page, 1); + if (ret) { + pr_err("%s: Failed to set %d pages to wb!\n", + pool->dev_name, 1); + } + } + } + + list_del(&d_page->page_list); + __ttm_dma_free_page(pool, d_page); +} + static void ttm_dma_pages_put(struct dma_pool *pool, struct list_head *d_pages, struct page *pages[], unsigned npages) { struct dma_page *d_page, *tmp; + if (pool->type & IS_HUGE) { + list_for_each_entry_safe(d_page, tmp, d_pages, page_list) + ttm_dma_page_put(pool, d_page); + + return; + } + /* Don't set WB on WB page pool. */ if (npages && !(pool->type & IS_CACHED) && set_pages_array_wb(pages, npages)) @@ -388,17 +426,6 @@ static void ttm_dma_pages_put(struct dma_pool *pool, struct list_head *d_pages, } } -static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page) -{ - /* Don't set WB on WB page pool. */ - if (!(pool->type & IS_CACHED) && set_pages_array_wb(&d_page->p, 1)) - pr_err("%s: Failed to set %d pages to wb!\n", - pool->dev_name, 1); - - list_del(&d_page->page_list); - __ttm_dma_free_page(pool, d_page); -} - /* * Free pages from pool. * @@ -567,8 +594,8 @@ static int ttm_dma_pool_match(struct device *dev, void *res, void *match_data) static struct dma_pool *ttm_dma_pool_init(struct device *dev, gfp_t flags, enum pool_type type) { - char *n[] = {"wc", "uc", "cached", " dma32", "unknown",}; - enum pool_type t[] = {IS_WC, IS_UC, IS_CACHED, IS_DMA32, IS_UNDEFINED}; + const char *n[] = {"wc", "uc", "cached", " dma32", "huge"}; + enum pool_type t[] = {IS_WC, IS_UC, IS_CACHED, IS_DMA32, IS_HUGE}; struct device_pools *sec_pool = NULL; struct dma_pool *pool = NULL, **ptr; unsigned i; @@ -605,11 +632,18 @@ static struct dma_pool *ttm_dma_pool_init(struct device *dev, gfp_t flags, pool->npages_free = pool->npages_in_use = 0; pool->nfrees = 0; pool->gfp_flags = flags; - pool->size = PAGE_SIZE; + if (type & IS_HUGE) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + pool->size = HPAGE_PMD_SIZE; +#else + BUG(); +#endif + else + pool->size = PAGE_SIZE; pool->type = type; pool->nrefills = 0; p = pool->name; - for (i = 0; i < 5; i++) { + for (i = 0; i < ARRAY_SIZE(t); i++) { if (type & t[i]) { p += snprintf(p, sizeof(pool->name) - (p - pool->name), "%s", n[i]); @@ -713,7 +747,7 @@ static int ttm_dma_pool_alloc_new_pages(struct dma_pool *pool, struct dma_page *dma_p; struct page *p; int r = 0; - unsigned i, cpages; + unsigned i, j, npages, cpages; unsigned max_cpages = min(count, (unsigned)(PAGE_SIZE/sizeof(struct page *))); @@ -751,28 +785,32 @@ static int ttm_dma_pool_alloc_new_pages(struct dma_pool *pool, goto out; } p = dma_p->p; + list_add(&dma_p->page_list, d_pages); + #ifdef CONFIG_HIGHMEM /* gfp flags of highmem page should never be dma32 so we * we should be fine in such case */ - if (!PageHighMem(p)) + if (PageHighMem(p)) + continue; #endif - { - caching_array[cpages++] = p; + + npages = pool->size / PAGE_SIZE; + for (j = 0; j < npages; ++j) { + caching_array[cpages++] = p + j; if (cpages == max_cpages) { /* Note: Cannot hold the spinlock */ r = ttm_set_pages_caching(pool, caching_array, - cpages); + cpages); if (r) { ttm_dma_handle_caching_state_failure( - pool, d_pages, caching_array, - cpages); + pool, d_pages, caching_array, + cpages); goto out; } cpages = 0; } } - list_add(&dma_p->page_list, d_pages); } if (cpages) { @@ -860,6 +898,26 @@ static int ttm_dma_pool_get_pages(struct dma_pool *pool, return r; } +static gfp_t ttm_dma_pool_gfp_flags(struct ttm_dma_tt *ttm_dma, bool huge) +{ + struct ttm_tt *ttm = &ttm_dma->ttm; + gfp_t gfp_flags; + + if (ttm->page_flags & TTM_PAGE_FLAG_DMA32) + gfp_flags = GFP_USER | GFP_DMA32; + else + gfp_flags = GFP_HIGHUSER; + if (ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC) + gfp_flags |= __GFP_ZERO; + + if (huge) { + gfp_flags |= GFP_TRANSHUGE; + gfp_flags &= ~__GFP_MOVABLE; + } + + return gfp_flags; +} + /* * On success pages list will hold count number of correctly * cached pages. On failure will hold the negative return value (-ENOMEM, etc). @@ -868,6 +926,7 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev) { struct ttm_tt *ttm = &ttm_dma->ttm; struct ttm_mem_global *mem_glob = ttm->glob->mem_glob; + unsigned long num_pages = ttm->num_pages; struct dma_pool *pool; enum pool_type type; unsigned i; @@ -876,26 +935,61 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev) if (ttm->state != tt_unpopulated) return 0; + INIT_LIST_HEAD(&ttm_dma->pages_list); + i = 0; + type = ttm_to_type(ttm->page_flags, ttm->caching_state); - pool = ttm_dma_find_pool(dev, type); + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + if (ttm->page_flags & TTM_PAGE_FLAG_DMA32) + goto skip_huge; + + pool = ttm_dma_find_pool(dev, type | IS_HUGE); if (!pool) { - gfp_t gfp_flags; + gfp_t gfp_flags = ttm_dma_pool_gfp_flags(ttm_dma, true); - if (ttm->page_flags & TTM_PAGE_FLAG_DMA32) - gfp_flags = GFP_USER | GFP_DMA32; - else - gfp_flags = GFP_HIGHUSER; - if (ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC) - gfp_flags |= __GFP_ZERO; + pool = ttm_dma_pool_init(dev, gfp_flags, type | IS_HUGE); + if (IS_ERR_OR_NULL(pool)) + goto skip_huge; + } - pool = ttm_dma_pool_init(dev, gfp_flags, type); - if (IS_ERR_OR_NULL(pool)) { + while (num_pages >= HPAGE_PMD_NR) { + unsigned j; + + ret = ttm_dma_pool_get_pages(pool, ttm_dma, i); + if (ret != 0) + break; + + ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i], + pool->size); + if (unlikely(ret != 0)) { + ttm_dma_unpopulate(ttm_dma, dev); return -ENOMEM; } + + for (j = i + 1; j < (i + HPAGE_PMD_NR); ++j) { + ttm->pages[j] = ttm->pages[j - 1] + 1; + ttm_dma->dma_address[j] = ttm_dma->dma_address[j - 1] + + PAGE_SIZE; + } + + i += HPAGE_PMD_NR; + num_pages -= HPAGE_PMD_NR; } - INIT_LIST_HEAD(&ttm_dma->pages_list); - for (i = 0; i < ttm->num_pages; ++i) { +skip_huge: +#endif + + pool = ttm_dma_find_pool(dev, type); + if (!pool) { + gfp_t gfp_flags = ttm_dma_pool_gfp_flags(ttm_dma, false); + + pool = ttm_dma_pool_init(dev, gfp_flags, type); + if (IS_ERR_OR_NULL(pool)) + return -ENOMEM; + } + + while (num_pages) { ret = ttm_dma_pool_get_pages(pool, ttm_dma, i); if (ret != 0) { ttm_dma_unpopulate(ttm_dma, dev); @@ -908,6 +1002,9 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev) ttm_dma_unpopulate(ttm_dma, dev); return -ENOMEM; } + + ++i; + --num_pages; } if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { @@ -931,10 +1028,33 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) struct dma_page *d_page, *next; enum pool_type type; bool is_cached = false; - unsigned count = 0, i, npages = 0; + unsigned count, i, npages = 0; unsigned long irq_flags; type = ttm_to_type(ttm->page_flags, ttm->caching_state); + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + pool = ttm_dma_find_pool(dev, type | IS_HUGE); + if (pool) { + count = 0; + list_for_each_entry_safe(d_page, next, &ttm_dma->pages_list, + page_list) { + if (!(d_page->vaddr & VADDR_FLAG_HUGE_POOL)) + continue; + + count++; + ttm_mem_global_free_page(ttm->glob->mem_glob, + d_page->p, pool->size); + ttm_dma_page_put(pool, d_page); + } + + spin_lock_irqsave(&pool->lock, irq_flags); + pool->npages_in_use -= count; + pool->nfrees += count; + spin_unlock_irqrestore(&pool->lock, irq_flags); + } +#endif + pool = ttm_dma_find_pool(dev, type); if (!pool) return; @@ -943,6 +1063,7 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) ttm_to_type(ttm->page_flags, tt_cached)) == pool); /* make sure pages array match list and count number of pages */ + count = 0; list_for_each_entry(d_page, &ttm_dma->pages_list, page_list) { ttm->pages[count] = d_page->p; count++; -- cgit v1.2.3 From c38e0691107d14a8a39e9be7cb46c312bdfbd22d Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 18 Sep 2017 14:01:45 +0200 Subject: drm/amdgpu: minor coding style fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix two minor 80 char issues. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index c91d5c7a273d..bca9eebb6947 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2541,7 +2541,8 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size) * @adev: amdgpu_device pointer * @fragment_size_default: the default fragment size if it's set auto */ -void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, uint32_t fragment_size_default) +void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, + uint32_t fragment_size_default) { if (amdgpu_vm_fragment_size == -1) adev->vm_manager.fragment_size = fragment_size_default; @@ -2555,7 +2556,8 @@ void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, uint32_t fragment_s * @adev: amdgpu_device pointer * @vm_size: the default vm size if it's set auto */ -void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size, uint32_t fragment_size_default) +void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size, + uint32_t fragment_size_default) { /* adjust vm size firstly */ if (amdgpu_vm_size == -1) -- cgit v1.2.3 From 515c6faf85970af529953ec137b4b6fcb3272e25 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Thu, 28 Sep 2017 11:21:15 +0200 Subject: drm/amd/sched: rename amd_sched_entity_pop_job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function does not actually remove the job from the FIFO, so "peek" describes it better. Signed-off-by: Nicolai Hähnle Reviewed-by: Christian König Reviewed-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 97c94f9683fa..742d724cd720 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -308,7 +308,7 @@ static bool amd_sched_entity_add_dependency_cb(struct amd_sched_entity *entity) } static struct amd_sched_job * -amd_sched_entity_pop_job(struct amd_sched_entity *entity) +amd_sched_entity_peek_job(struct amd_sched_entity *entity) { struct amd_gpu_scheduler *sched = entity->sched; struct amd_sched_job *sched_job; @@ -600,7 +600,7 @@ static int amd_sched_main(void *param) if (!entity) continue; - sched_job = amd_sched_entity_pop_job(entity); + sched_job = amd_sched_entity_peek_job(entity); if (!sched_job) continue; -- cgit v1.2.3 From 1650c14b459ff9c85767746f1ef795a780653128 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Thu, 28 Sep 2017 11:35:05 +0200 Subject: drm/amd/sched: fix an outdated comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolai Hähnle Reviewed-by: Christian König Reviewed-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 742d724cd720..6e899c593b7e 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -354,8 +354,7 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job) return added; } -/* job_finish is called after hw fence signaled, and - * the job had already been deleted from ring_mirror_list +/* job_finish is called after hw fence signaled */ static void amd_sched_job_finish(struct work_struct *work) { -- cgit v1.2.3 From 214a91e6bfabaa6cbfa692df8732000aab050795 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Thu, 28 Sep 2017 11:37:02 +0200 Subject: drm/amd/sched: move adding finish callback to amd_sched_job_begin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The finish callback is responsible for removing the job from the ring mirror list, among other things. It makes sense to add it as callback in the place where the job is added to the ring mirror list. Signed-off-by: Nicolai Hähnle Reviewed-by: Christian König Reviewed-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 6e899c593b7e..e793312e351c 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -395,6 +395,9 @@ static void amd_sched_job_begin(struct amd_sched_job *s_job) { struct amd_gpu_scheduler *sched = s_job->sched; + dma_fence_add_callback(&s_job->s_fence->finished, &s_job->finish_cb, + amd_sched_job_finish_cb); + spin_lock(&sched->job_list_lock); list_add_tail(&s_job->node, &sched->ring_mirror_list); if (sched->timeout != MAX_SCHEDULE_TIMEOUT && @@ -487,8 +490,6 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job) struct amd_sched_entity *entity = sched_job->s_entity; trace_amd_sched_job(sched_job); - dma_fence_add_callback(&sched_job->s_fence->finished, &sched_job->finish_cb, - amd_sched_job_finish_cb); wait_event(entity->sched->job_scheduled, amd_sched_entity_in(sched_job)); } -- cgit v1.2.3 From 29d253553559dba919315be847f4f2cce29edd42 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Thu, 28 Sep 2017 11:51:32 +0200 Subject: drm/amd/sched: NULL out the s_fence field after run_job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amd_sched_process_job drops the fence reference, so NULL out the s_fence field before adding it as a callback to guard against accidentally using s_fence after it may have be freed. v2: add a clarifying comment Signed-off-by: Nicolai Hähnle Reviewed-by: Christian König Reviewed-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index e793312e351c..4693be20e30a 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -611,6 +611,10 @@ static int amd_sched_main(void *param) fence = sched->ops->run_job(sched_job); amd_sched_fence_scheduled(s_fence); + + /* amd_sched_process_job drops the job's reference of the fence. */ + sched_job->s_fence = NULL; + if (fence) { s_fence->parent = dma_fence_get(fence); r = dma_fence_add_callback(fence, &s_fence->cb, -- cgit v1.2.3 From 79867462634836ee5c39a2cdf624719feeb189bd Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Thu, 28 Sep 2017 11:57:32 +0200 Subject: drm/amd/sched: fix deadlock caused by unsignaled fences of deleted jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Highly concurrent Piglit runs can trigger a race condition where a pending SDMA job on a buffer object is never executed because the corresponding process is killed (perhaps due to a crash). Since the job's fences were never signaled, the buffer object was effectively leaked. Worse, the buffer was stuck wherever it happened to be at the time, possibly in VRAM. The symptom was user space processes stuck in interruptible waits with kernel stacks like: [] dma_fence_default_wait+0x112/0x250 [] dma_fence_wait_timeout+0x39/0xf0 [] reservation_object_wait_timeout_rcu+0x1c2/0x300 [] ttm_bo_cleanup_refs_and_unlock+0xff/0x1a0 [ttm] [] ttm_mem_evict_first+0xba/0x1a0 [ttm] [] ttm_bo_mem_space+0x341/0x4c0 [ttm] [] ttm_bo_validate+0xd4/0x150 [ttm] [] ttm_bo_init_reserved+0x2ed/0x420 [ttm] [] amdgpu_bo_create_restricted+0x1f3/0x470 [amdgpu] [] amdgpu_bo_create+0xda/0x220 [amdgpu] [] amdgpu_gem_object_create+0xaa/0x140 [amdgpu] [] amdgpu_gem_create_ioctl+0x97/0x120 [amdgpu] [] drm_ioctl+0x1fa/0x480 [drm] [] amdgpu_drm_ioctl+0x4f/0x90 [amdgpu] [] do_vfs_ioctl+0xa3/0x5f0 [] SyS_ioctl+0x79/0x90 [] entry_SYSCALL_64_fastpath+0x1e/0xad [] 0xffffffffffffffff Note: The correctness of this change depends on the earlier commit "drm/amd/sched: move adding finish callback to amd_sched_job_begin" v2: set an error on the finished fence Signed-off-by: Nicolai Hähnle Reviewed-by: Christian König Reviewed-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 4693be20e30a..08e1332d814a 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -227,8 +227,14 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, */ kthread_park(sched->thread); kthread_unpark(sched->thread); - while (kfifo_out(&entity->job_queue, &job, sizeof(job))) + while (kfifo_out(&entity->job_queue, &job, sizeof(job))) { + struct amd_sched_fence *s_fence = job->s_fence; + amd_sched_fence_scheduled(s_fence); + dma_fence_set_error(&s_fence->finished, -ESRCH); + amd_sched_fence_finished(s_fence); + dma_fence_put(&s_fence->finished); sched->ops->free_job(job); + } } kfifo_free(&entity->job_queue); -- cgit v1.2.3 From 279f5a00c9a9b39f4f6e9813e6d4da8c181d34c8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 5 Oct 2017 20:10:05 +0100 Subject: drm/i915/execlists: Add a comment for the extra MI_ARB_ENABLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Michel Thierry noticed that we were applying WaDisableCtxRestoreArbitration even to gen9, which does not require the w/a. The rationale is that we need to enable MI arbitration for execlists to work, and to be safe we do that before every batch (in addition to every context switch into the batch). Since this is not clear from the single line comment suggesting the MI_ARB_ENABLE is solely for the w/a, add a little more detail. Signed-off-by: Chris Wilson Cc: Michel Thierry Cc: Joonas Lahtinen Cc: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/20171005191005.13462-1-chris@chris-wilson.co.uk Reviewed-by: Michel Thierry --- drivers/gpu/drm/i915/intel_lrc.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index c5b76082d695..721432ddf403 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1618,7 +1618,23 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, if (IS_ERR(cs)) return PTR_ERR(cs); - /* WaDisableCtxRestoreArbitration:bdw,chv */ + /* + * WaDisableCtxRestoreArbitration:bdw,chv + * + * We don't need to perform MI_ARB_ENABLE as often as we do (in + * particular all the gen that do not need the w/a at all!), if we + * took care to make sure that on every switch into this context + * (both ordinary and for preemption) that arbitrartion was enabled + * we would be fine. However, there doesn't seem to be a downside to + * being paranoid and making sure it is set before each batch and + * every context-switch. + * + * Note that if we fail to enable arbitration before the request + * is complete, then we do not see the context-switch interrupt and + * the engine hangs (with RING_HEAD == RING_TAIL). + * + * That satisfies both the GPGPU w/a and our heavy-handed paranoia. + */ *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; /* FIXME(BDW): Address space and security selectors. */ -- cgit v1.2.3 From 532f419cde077ffe9616c97902af177fbb868b17 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 12 Sep 2017 11:35:39 +0200 Subject: crypto: stm32 - Try to fix hash padding gcc warns that the length for the extra unaligned data in the hash function may be used unaligned. In theory this could happen if we pass a zero-length sg_list, or if sg_is_last() was never true: In file included from drivers/crypto/stm32/stm32-hash.c:23: drivers/crypto/stm32/stm32-hash.c: In function 'stm32_hash_one_request': include/uapi/linux/kernel.h:12:49: error: 'ncp' may be used uninitialized in this function [-Werror=maybe-uninitialized] #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) Neither of these can happen in practice, so the warning is harmless. However while trying to suppress the warning, I noticed multiple problems with that code: - On big-endian kernels, we byte-swap the data like we do for register accesses, however this is a data stream and almost certainly needs to use a single writesl() instead of series of writel() to give the correct hash. - If the length is not a multiple of four bytes, we skip the last word entirely, since we write the truncated length using stm32_hash_set_nblw(). - If we change the code to round the length up rather than down, the last bytes contain stale data, so it needs some form of padding. This tries to address all four problems, by correctly initializing the length to zero, using endian-safe copy functions, adding zero-padding and passing the padded length. I have done no testing on this patch, so please review carefully and if possible test with an unaligned length and big-endian kernel builds. Fixes: 8a1012d3f2ab ("crypto: stm32 - Support for STM32 HASH module") Signed-off-by: Arnd Bergmann Signed-off-by: Herbert Xu --- drivers/crypto/stm32/stm32-hash.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c index b585ce54a802..4835dd4a9e50 100644 --- a/drivers/crypto/stm32/stm32-hash.c +++ b/drivers/crypto/stm32/stm32-hash.c @@ -553,9 +553,9 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev) { struct stm32_hash_request_ctx *rctx = ahash_request_ctx(hdev->req); struct scatterlist sg[1], *tsg; - int err = 0, len = 0, reg, ncp; + int err = 0, len = 0, reg, ncp = 0; unsigned int i; - const u32 *buffer = (const u32 *)rctx->buffer; + u32 *buffer = (void *)rctx->buffer; rctx->sg = hdev->req->src; rctx->total = hdev->req->nbytes; @@ -620,10 +620,13 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev) reg |= HASH_CR_DMAA; stm32_hash_write(hdev, HASH_CR, reg); - for (i = 0; i < DIV_ROUND_UP(ncp, sizeof(u32)); i++) - stm32_hash_write(hdev, HASH_DIN, buffer[i]); - - stm32_hash_set_nblw(hdev, ncp); + if (ncp) { + memset(buffer + ncp, 0, + DIV_ROUND_UP(ncp, sizeof(u32)) - ncp); + writesl(hdev->io_base + HASH_DIN, buffer, + DIV_ROUND_UP(ncp, sizeof(u32))); + } + stm32_hash_set_nblw(hdev, DIV_ROUND_UP(ncp, sizeof(u32))); reg = stm32_hash_read(hdev, HASH_STR); reg |= HASH_STR_DCAL; stm32_hash_write(hdev, HASH_STR, reg); -- cgit v1.2.3 From 465c403cb50868a86164bfe5b3bf6ddd70c395e1 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:14 +0100 Subject: drm/i915: introduce simple gemfs Not a fully blown gemfs, just our very own tmpfs kernel mount. Doing so moves us away from the shmemfs shm_mnt, and gives us the much needed flexibility to do things like set our own mount options, namely huge= which should allow us to enable the use of transparent-huge-pages for our shmem backed objects. v2: various improvements suggested by Joonas v3: move gemfs instance to i915.mm and simplify now that we have file_setup_with_mnt v4: fallback to tmpfs shm_mnt upon failure to setup gemfs v5: make tmpfs fallback kinder v5: better gemfs failure message flags variable Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Dave Hansen Cc: Kirill A. Shutemov Cc: Hugh Dickins Cc: linux-mm@kvack.org Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-3-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.h | 5 +++ drivers/gpu/drm/i915/i915_gem.c | 33 ++++++++++++++- drivers/gpu/drm/i915/i915_gemfs.c | 52 ++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gemfs.h | 34 ++++++++++++++++ drivers/gpu/drm/i915/selftests/mock_gem_device.c | 4 ++ 6 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/i915_gemfs.c create mode 100644 drivers/gpu/drm/i915/i915_gemfs.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 51d0d2929a4b..66d23b619db1 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -47,6 +47,7 @@ i915-y += i915_cmd_parser.o \ i915_gem_tiling.o \ i915_gem_timeline.o \ i915_gem_userptr.o \ + i915_gemfs.o \ i915_trace_points.o \ i915_vma.o \ intel_breadcrumbs.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1fc7080bfa7b..ec6f320cc4f5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1511,6 +1511,11 @@ struct i915_gem_mm { /** Usable portion of the GTT for GEM */ dma_addr_t stolen_base; /* limited to low memory (32-bit) */ + /** + * tmpfs instance used for shmem backed objects + */ + struct vfsmount *gemfs; + /** PPGTT used for aliasing the PPGTT with the GTT */ struct i915_hw_ppgtt *aliasing_ppgtt; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 50cc3c2cef06..1da1f52d12cc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -35,6 +35,7 @@ #include "intel_drv.h" #include "intel_frontbuffer.h" #include "intel_mocs.h" +#include "i915_gemfs.h" #include #include #include @@ -4256,6 +4257,30 @@ static const struct drm_i915_gem_object_ops i915_gem_object_ops = { .pwrite = i915_gem_object_pwrite_gtt, }; +static int i915_gem_object_create_shmem(struct drm_device *dev, + struct drm_gem_object *obj, + size_t size) +{ + struct drm_i915_private *i915 = to_i915(dev); + unsigned long flags = VM_NORESERVE; + struct file *filp; + + drm_gem_private_object_init(dev, obj, size); + + if (i915->mm.gemfs) + filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size, + flags); + else + filp = shmem_file_setup("i915", size, flags); + + if (IS_ERR(filp)) + return PTR_ERR(filp); + + obj->filp = filp; + + return 0; +} + struct drm_i915_gem_object * i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size) { @@ -4280,7 +4305,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size) if (obj == NULL) return ERR_PTR(-ENOMEM); - ret = drm_gem_object_init(&dev_priv->drm, &obj->base, size); + ret = i915_gem_object_create_shmem(&dev_priv->drm, &obj->base, size); if (ret) goto fail; @@ -4919,6 +4944,10 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) spin_lock_init(&dev_priv->fb_tracking.lock); + err = i915_gemfs_init(dev_priv); + if (err) + DRM_NOTE("Unable to create a private tmpfs mount, hugepage support will be disabled(%d).\n", err); + return 0; err_priorities: @@ -4957,6 +4986,8 @@ void i915_gem_load_cleanup(struct drm_i915_private *dev_priv) /* And ensure that our DESTROY_BY_RCU slabs are truly destroyed */ rcu_barrier(); + + i915_gemfs_fini(dev_priv); } int i915_gem_freeze(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_gemfs.c b/drivers/gpu/drm/i915/i915_gemfs.c new file mode 100644 index 000000000000..168d0bd98f60 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gemfs.c @@ -0,0 +1,52 @@ +/* + * Copyright © 2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include +#include + +#include "i915_drv.h" +#include "i915_gemfs.h" + +int i915_gemfs_init(struct drm_i915_private *i915) +{ + struct file_system_type *type; + struct vfsmount *gemfs; + + type = get_fs_type("tmpfs"); + if (!type) + return -ENODEV; + + gemfs = kern_mount(type); + if (IS_ERR(gemfs)) + return PTR_ERR(gemfs); + + i915->mm.gemfs = gemfs; + + return 0; +} + +void i915_gemfs_fini(struct drm_i915_private *i915) +{ + kern_unmount(i915->mm.gemfs); +} diff --git a/drivers/gpu/drm/i915/i915_gemfs.h b/drivers/gpu/drm/i915/i915_gemfs.h new file mode 100644 index 000000000000..cca8bdc5b93e --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gemfs.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef __I915_GEMFS_H__ +#define __I915_GEMFS_H__ + +struct drm_i915_private; + +int i915_gemfs_init(struct drm_i915_private *i915); + +void i915_gemfs_fini(struct drm_i915_private *i915); + +#endif diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 0c8225d677e9..e189d2b5f6c1 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -83,6 +83,8 @@ static void mock_device_release(struct drm_device *dev) kmem_cache_destroy(i915->vmas); kmem_cache_destroy(i915->objects); + i915_gemfs_fini(i915); + drm_dev_fini(&i915->drm); put_device(&i915->drm.pdev->dev); } @@ -243,6 +245,8 @@ struct drm_i915_private *mock_gem_device(void) if (!i915->preempt_context) goto err_kernel_context; + WARN_ON(i915_gemfs_init(i915)); + return i915; err_kernel_context: -- cgit v1.2.3 From b901bb89324ae65573c5f5c0a126cb864096b77c Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:15 +0100 Subject: drm/i915/gemfs: enable THP Enable transparent-huge-pages through gemfs by mounting with huge=within_size. v2: sprinkle within_size comment Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-4-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gemfs.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gemfs.c b/drivers/gpu/drm/i915/i915_gemfs.c index 168d0bd98f60..e2993857df37 100644 --- a/drivers/gpu/drm/i915/i915_gemfs.c +++ b/drivers/gpu/drm/i915/i915_gemfs.c @@ -24,6 +24,7 @@ #include #include +#include #include "i915_drv.h" #include "i915_gemfs.h" @@ -41,6 +42,27 @@ int i915_gemfs_init(struct drm_i915_private *i915) if (IS_ERR(gemfs)) return PTR_ERR(gemfs); + /* + * Enable huge-pages for objects that are at least HPAGE_PMD_SIZE, most + * likely 2M. Note that within_size may overallocate huge-pages, if say + * we allocate an object of size 2M + 4K, we may get 2M + 2M, but under + * memory pressure shmem should split any huge-pages which can be + * shrunk. + */ + + if (has_transparent_hugepage()) { + struct super_block *sb = gemfs->mnt_sb; + char options[] = "huge=within_size"; + int flags = 0; + int err; + + err = sb->s_op->remount_fs(sb, &flags, options); + if (err) { + kern_unmount(gemfs); + return err; + } + } + i915->mm.gemfs = gemfs; return 0; -- cgit v1.2.3 From 2a9654b2cdd8f9ef51b91dfd4448973a47284825 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:16 +0100 Subject: drm/i915: introduce page_sizes field to dev_info In preparation for huge gtt pages expose page_sizes as part of the device info, to indicate the page sizes supported by the HW. Currently only 4K is supported. v2: s/page_size_mask/page_sizes/ v3: introduce I915_GTT_MAX_PAGE_SIZE Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Mika Kuoppala Cc: Chris Wilson Reviewed-by: Joonas Lahtinen Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-5-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem_gtt.h | 8 +++++++- drivers/gpu/drm/i915/i915_pci.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/selftests/mock_gem_device.c | 3 +++ 4 files changed, 30 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ec6f320cc4f5..3d4dee817381 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -869,6 +869,8 @@ struct intel_device_info { u8 num_sprites[I915_MAX_PIPES]; u8 num_scalers[I915_MAX_PIPES]; + unsigned int page_sizes; /* page sizes supported by the HW */ + #define DEFINE_FLAG(name) u8 name:1 DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG); #undef DEFINE_FLAG diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index f62fb903dc24..50218c141c21 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -42,7 +42,13 @@ #include "i915_gem_request.h" #include "i915_selftest.h" -#define I915_GTT_PAGE_SIZE 4096UL +#define I915_GTT_PAGE_SIZE_4K BIT(12) +#define I915_GTT_PAGE_SIZE_64K BIT(16) +#define I915_GTT_PAGE_SIZE_2M BIT(21) + +#define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K +#define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M + #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE #define I915_FENCE_REG_NONE -1 diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 745b6a6e0188..7938006cf03a 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -58,6 +58,10 @@ .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 } /* Keep in gen based order, and chronological order within a gen */ + +#define GEN_DEFAULT_PAGE_SIZES \ + .page_sizes = I915_GTT_PAGE_SIZE_4K + #define GEN2_FEATURES \ .gen = 2, .num_pipes = 1, \ .has_overlay = 1, .overlay_needs_physical = 1, \ @@ -67,6 +71,7 @@ .ring_mask = RENDER_RING, \ .has_snoop = true, \ GEN_DEFAULT_PIPEOFFSETS, \ + GEN_DEFAULT_PAGE_SIZES, \ CURSOR_OFFSETS static const struct intel_device_info intel_i830_info __initconst = { @@ -100,6 +105,7 @@ static const struct intel_device_info intel_i865g_info __initconst = { .ring_mask = RENDER_RING, \ .has_snoop = true, \ GEN_DEFAULT_PIPEOFFSETS, \ + GEN_DEFAULT_PAGE_SIZES, \ CURSOR_OFFSETS static const struct intel_device_info intel_i915g_info __initconst = { @@ -163,6 +169,7 @@ static const struct intel_device_info intel_pineview_info __initconst = { .ring_mask = RENDER_RING, \ .has_snoop = true, \ GEN_DEFAULT_PIPEOFFSETS, \ + GEN_DEFAULT_PAGE_SIZES, \ CURSOR_OFFSETS static const struct intel_device_info intel_i965g_info __initconst = { @@ -205,6 +212,7 @@ static const struct intel_device_info intel_gm45_info __initconst = { .ring_mask = RENDER_RING | BSD_RING, \ .has_snoop = true, \ GEN_DEFAULT_PIPEOFFSETS, \ + GEN_DEFAULT_PAGE_SIZES, \ CURSOR_OFFSETS static const struct intel_device_info intel_ironlake_d_info __initconst = { @@ -228,6 +236,7 @@ static const struct intel_device_info intel_ironlake_m_info __initconst = { .has_rc6p = 1, \ .has_aliasing_ppgtt = 1, \ GEN_DEFAULT_PIPEOFFSETS, \ + GEN_DEFAULT_PAGE_SIZES, \ CURSOR_OFFSETS #define SNB_D_PLATFORM \ @@ -271,6 +280,7 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info __initconst = .has_aliasing_ppgtt = 1, \ .has_full_ppgtt = 1, \ GEN_DEFAULT_PIPEOFFSETS, \ + GEN_DEFAULT_PAGE_SIZES, \ IVB_CURSOR_OFFSETS #define IVB_D_PLATFORM \ @@ -327,6 +337,7 @@ static const struct intel_device_info intel_valleyview_info __initconst = { .has_snoop = true, .ring_mask = RENDER_RING | BSD_RING | BLT_RING, .display_mmio_offset = VLV_DISPLAY_BASE, + GEN_DEFAULT_PAGE_SIZES, GEN_DEFAULT_PIPEOFFSETS, CURSOR_OFFSETS }; @@ -365,6 +376,7 @@ static const struct intel_device_info intel_haswell_gt3_info __initconst = { #define GEN8_FEATURES \ G75_FEATURES, \ BDW_COLORS, \ + GEN_DEFAULT_PAGE_SIZES, \ .has_logical_ring_contexts = 1, \ .has_full_48bit_ppgtt = 1, \ .has_64bit_reloc = 1, \ @@ -417,13 +429,18 @@ static const struct intel_device_info intel_cherryview_info __initconst = { .has_reset_engine = 1, .has_snoop = true, .display_mmio_offset = VLV_DISPLAY_BASE, + GEN_DEFAULT_PAGE_SIZES, GEN_CHV_PIPEOFFSETS, CURSOR_OFFSETS, CHV_COLORS, }; +#define GEN9_DEFAULT_PAGE_SIZES \ + .page_sizes = I915_GTT_PAGE_SIZE_4K + #define GEN9_FEATURES \ GEN8_FEATURES, \ + GEN9_DEFAULT_PAGE_SIZES, \ .has_logical_ring_preemption = 1, \ .has_csr = 1, \ .has_guc = 1, \ @@ -486,6 +503,7 @@ static const struct intel_device_info intel_skylake_gt4_info __initconst = { .has_reset_engine = 1, \ .has_snoop = true, \ .has_ipc = 1, \ + GEN9_DEFAULT_PAGE_SIZES, \ GEN_DEFAULT_PIPEOFFSETS, \ IVB_CURSOR_OFFSETS, \ BDW_COLORS diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index e189d2b5f6c1..f46c3a35d61a 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -174,6 +174,9 @@ struct drm_i915_private *mock_gem_device(void) mkwrite_device_info(i915)->gen = -1; + mkwrite_device_info(i915)->page_sizes = + I915_GTT_PAGE_SIZE_4K; + spin_lock_init(&i915->mm.object_stat_lock); mock_uncore_init(i915); -- cgit v1.2.3 From b91b09eea7a15ab417aa9ed6502b3be12f5283f8 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:17 +0100 Subject: drm/i915: push set_pages down to the callers Each backend is now responsible for calling __i915_gem_object_set_pages upon successfully gathering its backing storage. This eliminates the inconsistency between the async and sync paths, which stands out even more when we start throwing around an sg_mask in a later patch. Suggested-by: Chris Wilson Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Joonas Lahtinen Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-6-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-5-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 45 +++++++++++++----------- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 15 +++++--- drivers/gpu/drm/i915/i915_gem_internal.c | 15 ++++---- drivers/gpu/drm/i915/i915_gem_object.h | 2 +- drivers/gpu/drm/i915/i915_gem_stolen.c | 16 ++++++--- drivers/gpu/drm/i915/i915_gem_userptr.c | 12 +++---- drivers/gpu/drm/i915/selftests/huge_gem_object.c | 14 ++++---- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 12 ++++--- 8 files changed, 77 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1da1f52d12cc..42f2ca1e136b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -162,8 +162,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, return 0; } -static struct sg_table * -i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) +static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) { struct address_space *mapping = obj->base.filp->f_mapping; drm_dma_handle_t *phys; @@ -171,9 +170,10 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) struct scatterlist *sg; char *vaddr; int i; + int err; if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) - return ERR_PTR(-EINVAL); + return -EINVAL; /* Always aligning to the object size, allows a single allocation * to handle all possible callers, and given typical object sizes, @@ -183,7 +183,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) roundup_pow_of_two(obj->base.size), roundup_pow_of_two(obj->base.size)); if (!phys) - return ERR_PTR(-ENOMEM); + return -ENOMEM; vaddr = phys->vaddr; for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { @@ -192,7 +192,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) page = shmem_read_mapping_page(mapping, i); if (IS_ERR(page)) { - st = ERR_CAST(page); + err = PTR_ERR(page); goto err_phys; } @@ -209,13 +209,13 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) st = kmalloc(sizeof(*st), GFP_KERNEL); if (!st) { - st = ERR_PTR(-ENOMEM); + err = -ENOMEM; goto err_phys; } if (sg_alloc_table(st, 1, GFP_KERNEL)) { kfree(st); - st = ERR_PTR(-ENOMEM); + err = -ENOMEM; goto err_phys; } @@ -227,11 +227,15 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) sg_dma_len(sg) = obj->base.size; obj->phys_handle = phys; - return st; + + __i915_gem_object_set_pages(obj, st); + + return 0; err_phys: drm_pci_free(obj->base.dev, phys); - return st; + + return err; } static void __start_cpu_write(struct drm_i915_gem_object *obj) @@ -2292,8 +2296,7 @@ static bool i915_sg_trim(struct sg_table *orig_st) return true; } -static struct sg_table * -i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) +static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) { struct drm_i915_private *dev_priv = to_i915(obj->base.dev); const unsigned long page_count = obj->base.size / PAGE_SIZE; @@ -2317,12 +2320,12 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) st = kmalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) - return ERR_PTR(-ENOMEM); + return -ENOMEM; rebuild_st: if (sg_alloc_table(st, page_count, GFP_KERNEL)) { kfree(st); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } /* Get the list of pages out of our struct file. They'll be pinned @@ -2430,7 +2433,9 @@ rebuild_st: if (i915_gem_object_needs_bit17_swizzle(obj)) i915_gem_object_do_bit_17_swizzle(obj, st); - return st; + __i915_gem_object_set_pages(obj, st); + + return 0; err_sg: sg_mark_end(sg); @@ -2451,7 +2456,7 @@ err_pages: if (ret == -ENOSPC) ret = -ENOMEM; - return ERR_PTR(ret); + return ret; } void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, @@ -2474,19 +2479,17 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj) { - struct sg_table *pages; + int err; if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) { DRM_DEBUG("Attempting to obtain a purgeable object\n"); return -EFAULT; } - pages = obj->ops->get_pages(obj); - if (unlikely(IS_ERR(pages))) - return PTR_ERR(pages); + err = obj->ops->get_pages(obj); + GEM_BUG_ON(!err && IS_ERR_OR_NULL(obj->mm.pages)); - __i915_gem_object_set_pages(obj, pages); - return 0; + return err; } /* Ensure that the associated pages are gathered from the backing storage diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 6176e589cf09..4c4dc85159fb 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -256,11 +256,18 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, return drm_gem_dmabuf_export(dev, &exp_info); } -static struct sg_table * -i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) +static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) { - return dma_buf_map_attachment(obj->base.import_attach, - DMA_BIDIRECTIONAL); + struct sg_table *pages; + + pages = dma_buf_map_attachment(obj->base.import_attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + __i915_gem_object_set_pages(obj, pages); + + return 0; } static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c index c1f64ddaf8aa..f59764da4254 100644 --- a/drivers/gpu/drm/i915/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/i915_gem_internal.c @@ -44,8 +44,7 @@ static void internal_free_pages(struct sg_table *st) kfree(st); } -static struct sg_table * -i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) +static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) { struct drm_i915_private *i915 = to_i915(obj->base.dev); struct sg_table *st; @@ -78,12 +77,12 @@ i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) create_st: st = kmalloc(sizeof(*st), GFP_KERNEL); if (!st) - return ERR_PTR(-ENOMEM); + return -ENOMEM; npages = obj->base.size / PAGE_SIZE; if (sg_alloc_table(st, npages, GFP_KERNEL)) { kfree(st); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } sg = st->sgl; @@ -132,13 +131,17 @@ create_st: * object are only valid whilst active and pinned. */ obj->mm.madv = I915_MADV_DONTNEED; - return st; + + __i915_gem_object_set_pages(obj, st); + + return 0; err: sg_set_page(sg, NULL, 0, 0); sg_mark_end(sg); internal_free_pages(st); - return ERR_PTR(-ENOMEM); + + return -ENOMEM; } static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index c30d8f808185..036e847b27f0 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -69,7 +69,7 @@ struct drm_i915_gem_object_ops { * being released or under memory pressure (where we attempt to * reap pages for the shrinker). */ - struct sg_table *(*get_pages)(struct drm_i915_gem_object *); + int (*get_pages)(struct drm_i915_gem_object *); void (*put_pages)(struct drm_i915_gem_object *, struct sg_table *); int (*pwrite)(struct drm_i915_gem_object *, diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 507c9f0d8df1..537ecb224db0 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -539,12 +539,18 @@ i915_pages_create_for_stolen(struct drm_device *dev, return st; } -static struct sg_table * -i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj) +static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj) { - return i915_pages_create_for_stolen(obj->base.dev, - obj->stolen->start, - obj->stolen->size); + struct sg_table *pages = + i915_pages_create_for_stolen(obj->base.dev, + obj->stolen->start, + obj->stolen->size); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + __i915_gem_object_set_pages(obj, pages); + + return 0; } static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 2d4996de7331..70ad7489827d 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -434,6 +434,8 @@ alloc_table: return ERR_PTR(ret); } + __i915_gem_object_set_pages(obj, st); + return st; } @@ -521,7 +523,6 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) pages = __i915_gem_userptr_alloc_pages(obj, pvec, npages); if (!IS_ERR(pages)) { - __i915_gem_object_set_pages(obj, pages); pinned = 0; pages = NULL; } @@ -582,8 +583,7 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj) return ERR_PTR(-EAGAIN); } -static struct sg_table * -i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) +static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) { const int num_pages = obj->base.size >> PAGE_SHIFT; struct mm_struct *mm = obj->userptr.mm->mm; @@ -612,9 +612,9 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) if (obj->userptr.work) { /* active flag should still be held for the pending work */ if (IS_ERR(obj->userptr.work)) - return ERR_CAST(obj->userptr.work); + return PTR_ERR(obj->userptr.work); else - return ERR_PTR(-EAGAIN); + return -EAGAIN; } pvec = NULL; @@ -650,7 +650,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) release_pages(pvec, pinned, 0); kvfree(pvec); - return pages; + return PTR_ERR_OR_ZERO(pages); } static void diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c index c5c7e8efbdd3..41c15f3aa467 100644 --- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c +++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c @@ -37,8 +37,7 @@ static void huge_free_pages(struct drm_i915_gem_object *obj, kfree(pages); } -static struct sg_table * -huge_get_pages(struct drm_i915_gem_object *obj) +static int huge_get_pages(struct drm_i915_gem_object *obj) { #define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY) const unsigned long nreal = obj->scratch / PAGE_SIZE; @@ -49,11 +48,11 @@ huge_get_pages(struct drm_i915_gem_object *obj) pages = kmalloc(sizeof(*pages), GFP); if (!pages) - return ERR_PTR(-ENOMEM); + return -ENOMEM; if (sg_alloc_table(pages, npages, GFP)) { kfree(pages); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } sg = pages->sgl; @@ -81,11 +80,14 @@ huge_get_pages(struct drm_i915_gem_object *obj) if (i915_gem_gtt_prepare_pages(obj, pages)) goto err; - return pages; + __i915_gem_object_set_pages(obj, pages); + + return 0; err: huge_free_pages(obj, pages); - return ERR_PTR(-ENOMEM); + + return -ENOMEM; #undef GFP } diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 6b132caffa18..aa1db375d59a 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -39,8 +39,7 @@ static void fake_free_pages(struct drm_i915_gem_object *obj, kfree(pages); } -static struct sg_table * -fake_get_pages(struct drm_i915_gem_object *obj) +static int fake_get_pages(struct drm_i915_gem_object *obj) { #define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY) #define PFN_BIAS 0x1000 @@ -50,12 +49,12 @@ fake_get_pages(struct drm_i915_gem_object *obj) pages = kmalloc(sizeof(*pages), GFP); if (!pages) - return ERR_PTR(-ENOMEM); + return -ENOMEM; rem = round_up(obj->base.size, BIT(31)) >> 31; if (sg_alloc_table(pages, rem, GFP)) { kfree(pages); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } rem = obj->base.size; @@ -72,7 +71,10 @@ fake_get_pages(struct drm_i915_gem_object *obj) GEM_BUG_ON(rem); obj->mm.madv = I915_MADV_DONTNEED; - return pages; + + __i915_gem_object_set_pages(obj, pages); + + return 0; #undef GFP } -- cgit v1.2.3 From a5c08166265adc172a4cbde8ed26a1a96ce77fb7 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:18 +0100 Subject: drm/i915: introduce page_size members In preparation for supporting huge gtt pages for the ppgtt, we introduce page size members for gem objects. We fill in the page sizes by scanning the sg table. v2: pass the sg_mask to set_pages v3: calculate the sg_mask inline with populating the sg_table where possible, and pass to set_pages along with the pages. v4: bunch of improvements from Joonas v5: fix num_pages blunder introduce i915_sg_page_sizes helper v6: prefer GEM_BUG_ON(sizes == 0) Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Daniel Vetter Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-7-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-6-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 22 ++++++++++++- drivers/gpu/drm/i915/i915_gem.c | 42 +++++++++++++++++++++--- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 5 ++- drivers/gpu/drm/i915/i915_gem_internal.c | 5 ++- drivers/gpu/drm/i915/i915_gem_object.h | 17 ++++++++++ drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- drivers/gpu/drm/i915/i915_gem_userptr.c | 5 ++- drivers/gpu/drm/i915/selftests/huge_gem_object.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 5 ++- 9 files changed, 93 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3d4dee817381..799a90abd81f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2872,6 +2872,21 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg) (((__iter).curr += PAGE_SIZE) >= (__iter).max) ? \ (__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0 : 0) +static inline unsigned int i915_sg_page_sizes(struct scatterlist *sg) +{ + unsigned int page_sizes; + + page_sizes = 0; + while (sg) { + GEM_BUG_ON(sg->offset); + GEM_BUG_ON(!IS_ALIGNED(sg->length, PAGE_SIZE)); + page_sizes |= sg->length; + sg = __sg_next(sg); + } + + return page_sizes; +} + static inline unsigned int i915_sg_segment_size(void) { unsigned int size = swiotlb_max_segment(); @@ -3101,6 +3116,10 @@ intel_info(const struct drm_i915_private *dev_priv) #define USES_PPGTT(dev_priv) (i915_modparams.enable_ppgtt) #define USES_FULL_PPGTT(dev_priv) (i915_modparams.enable_ppgtt >= 2) #define USES_FULL_48BIT_PPGTT(dev_priv) (i915_modparams.enable_ppgtt == 3) +#define HAS_PAGE_SIZES(dev_priv, sizes) ({ \ + GEM_BUG_ON((sizes) == 0); \ + ((sizes) & ~(dev_priv)->info.page_sizes) == 0; \ +}) #define HAS_OVERLAY(dev_priv) ((dev_priv)->info.has_overlay) #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \ @@ -3517,7 +3536,8 @@ i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, unsigned long n); void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, - struct sg_table *pages); + struct sg_table *pages, + unsigned int sg_mask); int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj); static inline int __must_check diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 42f2ca1e136b..34398696824c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -228,7 +228,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) obj->phys_handle = phys; - __i915_gem_object_set_pages(obj, st); + __i915_gem_object_set_pages(obj, st, sg->length); return 0; @@ -2266,6 +2266,8 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, if (!IS_ERR(pages)) obj->ops->put_pages(obj, pages); + obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0; + unlock: mutex_unlock(&obj->mm.lock); } @@ -2308,6 +2310,7 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) struct page *page; unsigned long last_pfn = 0; /* suppress gcc warning */ unsigned int max_segment = i915_sg_segment_size(); + unsigned int sg_mask; gfp_t noreclaim; int ret; @@ -2339,6 +2342,7 @@ rebuild_st: sg = st->sgl; st->nents = 0; + sg_mask = 0; for (i = 0; i < page_count; i++) { const unsigned int shrink[] = { I915_SHRINK_BOUND | I915_SHRINK_UNBOUND | I915_SHRINK_PURGEABLE, @@ -2391,8 +2395,10 @@ rebuild_st: if (!i || sg->length >= max_segment || page_to_pfn(page) != last_pfn + 1) { - if (i) + if (i) { + sg_mask |= sg->length; sg = sg_next(sg); + } st->nents++; sg_set_page(sg, page, PAGE_SIZE, 0); } else { @@ -2403,8 +2409,10 @@ rebuild_st: /* Check that the i965g/gm workaround works. */ WARN_ON((gfp & __GFP_DMA32) && (last_pfn >= 0x00100000UL)); } - if (sg) /* loop terminated early; short sg table */ + if (sg) { /* loop terminated early; short sg table */ + sg_mask |= sg->length; sg_mark_end(sg); + } /* Trim unused sg entries to avoid wasting memory. */ i915_sg_trim(st); @@ -2433,7 +2441,7 @@ rebuild_st: if (i915_gem_object_needs_bit17_swizzle(obj)) i915_gem_object_do_bit_17_swizzle(obj, st); - __i915_gem_object_set_pages(obj, st); + __i915_gem_object_set_pages(obj, st, sg_mask); return 0; @@ -2460,8 +2468,13 @@ err_pages: } void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, - struct sg_table *pages) + struct sg_table *pages, + unsigned int sg_mask) { + struct drm_i915_private *i915 = to_i915(obj->base.dev); + unsigned long supported = INTEL_INFO(i915)->page_sizes; + int i; + lockdep_assert_held(&obj->mm.lock); obj->mm.get_page.sg_pos = pages->sgl; @@ -2475,6 +2488,25 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, __i915_gem_object_pin_pages(obj); obj->mm.quirked = true; } + + GEM_BUG_ON(!sg_mask); + obj->mm.page_sizes.phys = sg_mask; + + /* + * Calculate the supported page-sizes which fit into the given sg_mask. + * This will give us the page-sizes which we may be able to use + * opportunistically when later inserting into the GTT. For example if + * phys=2G, then in theory we should be able to use 1G, 2M, 64K or 4K + * pages, although in practice this will depend on a number of other + * factors. + */ + obj->mm.page_sizes.sg = 0; + for_each_set_bit(i, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) { + if (obj->mm.page_sizes.phys & ~0u << i) + obj->mm.page_sizes.sg |= BIT(i); + } + + GEM_BUG_ON(!HAS_PAGE_SIZES(i915, obj->mm.page_sizes.sg)); } static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj) diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 4c4dc85159fb..e542a9d80077 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -259,13 +259,16 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) { struct sg_table *pages; + unsigned int sg_mask; pages = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL); if (IS_ERR(pages)) return PTR_ERR(pages); - __i915_gem_object_set_pages(obj, pages); + sg_mask = i915_sg_page_sizes(pages->sgl); + + __i915_gem_object_set_pages(obj, pages, sg_mask); return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c index f59764da4254..bdc23c4c8783 100644 --- a/drivers/gpu/drm/i915/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/i915_gem_internal.c @@ -49,6 +49,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) struct drm_i915_private *i915 = to_i915(obj->base.dev); struct sg_table *st; struct scatterlist *sg; + unsigned int sg_mask; unsigned int npages; int max_order; gfp_t gfp; @@ -87,6 +88,7 @@ create_st: sg = st->sgl; st->nents = 0; + sg_mask = 0; do { int order = min(fls(npages) - 1, max_order); @@ -104,6 +106,7 @@ create_st: } while (1); sg_set_page(sg, page, PAGE_SIZE << order, 0); + sg_mask |= PAGE_SIZE << order; st->nents++; npages -= 1 << order; @@ -132,7 +135,7 @@ create_st: */ obj->mm.madv = I915_MADV_DONTNEED; - __i915_gem_object_set_pages(obj, st); + __i915_gem_object_set_pages(obj, st, sg_mask); return 0; diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 036e847b27f0..110672952a1c 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -169,6 +169,23 @@ struct drm_i915_gem_object { struct sg_table *pages; void *mapping; + struct i915_page_sizes { + /** + * The sg mask of the pages sg_table. i.e the mask of + * of the lengths for each sg entry. + */ + unsigned int phys; + + /** + * The gtt page sizes we are allowed to use given the + * sg mask and the supported page sizes. This will + * express the smallest unit we can use for the whole + * object, as well as the larger sizes we may be able + * to use opportunistically. + */ + unsigned int sg; + } page_sizes; + struct i915_gem_object_page_iter { struct scatterlist *sg_pos; unsigned int sg_idx; /* in pages, but 32bit eek! */ diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 537ecb224db0..54fd4cfa9d07 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -548,7 +548,7 @@ static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj) if (IS_ERR(pages)) return PTR_ERR(pages); - __i915_gem_object_set_pages(obj, pages); + __i915_gem_object_set_pages(obj, pages, obj->stolen->size); return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 70ad7489827d..41e16e19c3f3 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -405,6 +405,7 @@ __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj, { unsigned int max_segment = i915_sg_segment_size(); struct sg_table *st; + unsigned int sg_mask; int ret; st = kmalloc(sizeof(*st), GFP_KERNEL); @@ -434,7 +435,9 @@ alloc_table: return ERR_PTR(ret); } - __i915_gem_object_set_pages(obj, st); + sg_mask = i915_sg_page_sizes(st->sgl); + + __i915_gem_object_set_pages(obj, st, sg_mask); return st; } diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c index 41c15f3aa467..a2632df39173 100644 --- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c +++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c @@ -80,7 +80,7 @@ static int huge_get_pages(struct drm_i915_gem_object *obj) if (i915_gem_gtt_prepare_pages(obj, pages)) goto err; - __i915_gem_object_set_pages(obj, pages); + __i915_gem_object_set_pages(obj, pages, PAGE_SIZE); return 0; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index aa1db375d59a..883bc19e3aaf 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -45,6 +45,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) #define PFN_BIAS 0x1000 struct sg_table *pages; struct scatterlist *sg; + unsigned int sg_mask; typeof(obj->base.size) rem; pages = kmalloc(sizeof(*pages), GFP); @@ -57,6 +58,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) return -ENOMEM; } + sg_mask = 0; rem = obj->base.size; for (sg = pages->sgl; sg; sg = sg_next(sg)) { unsigned long len = min_t(typeof(rem), rem, BIT(31)); @@ -65,6 +67,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) sg_set_page(sg, pfn_to_page(PFN_BIAS), len, 0); sg_dma_address(sg) = page_to_phys(sg_page(sg)); sg_dma_len(sg) = len; + sg_mask |= len; rem -= len; } @@ -72,7 +75,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) obj->mm.madv = I915_MADV_DONTNEED; - __i915_gem_object_set_pages(obj, pages); + __i915_gem_object_set_pages(obj, pages, sg_mask); return 0; #undef GFP -- cgit v1.2.3 From fa3f46afd38cece52f6ff70603b15c1aeb6ec225 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:19 +0100 Subject: drm/i915: introduce vm set_pages/clear_pages Move the setting/clearing of the vma->pages to a vm operation. Doing so neatens things up a little, but more importantly gives us a sane place to also set/clear the vma->pages_sizes, which we introduce later in preparation for supporting huge-pages. v2: remove redundant vma->pages check v3: GEM_BUG_ON(vma->pages) following i915_vma_remove Suggested-by: Chris Wilson Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-8-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-7-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 70 +++++++++++++++++++------------ drivers/gpu/drm/i915/i915_gem_gtt.h | 2 + drivers/gpu/drm/i915/i915_vma.c | 27 +++++++----- drivers/gpu/drm/i915/selftests/mock_gtt.c | 11 ++--- 4 files changed, 66 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 4c82ceb8d318..c534b74eee32 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -205,8 +205,6 @@ static int ppgtt_bind_vma(struct i915_vma *vma, return ret; } - vma->pages = vma->obj->mm.pages; - /* Currently applicable only to VLV */ pte_flags = 0; if (vma->obj->gt_ro) @@ -222,6 +220,26 @@ static void ppgtt_unbind_vma(struct i915_vma *vma) vma->vm->clear_range(vma->vm, vma->node.start, vma->size); } +static int ppgtt_set_pages(struct i915_vma *vma) +{ + GEM_BUG_ON(vma->pages); + + vma->pages = vma->obj->mm.pages; + + return 0; +} + +static void clear_pages(struct i915_vma *vma) +{ + GEM_BUG_ON(!vma->pages); + + if (vma->pages != vma->obj->mm.pages) { + sg_free_table(vma->pages); + kfree(vma->pages); + } + vma->pages = NULL; +} + static gen8_pte_t gen8_pte_encode(dma_addr_t addr, enum i915_cache_level level) { @@ -1452,6 +1470,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ppgtt->base.cleanup = gen8_ppgtt_cleanup; ppgtt->base.unbind_vma = ppgtt_unbind_vma; ppgtt->base.bind_vma = ppgtt_bind_vma; + ppgtt->base.set_pages = ppgtt_set_pages; + ppgtt->base.clear_pages = clear_pages; ppgtt->debug_dump = gen8_dump_ppgtt; return 0; @@ -1894,6 +1914,8 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ppgtt->base.insert_entries = gen6_ppgtt_insert_entries; ppgtt->base.unbind_vma = ppgtt_unbind_vma; ppgtt->base.bind_vma = ppgtt_bind_vma; + ppgtt->base.set_pages = ppgtt_set_pages; + ppgtt->base.clear_pages = clear_pages; ppgtt->base.cleanup = gen6_ppgtt_cleanup; ppgtt->debug_dump = gen6_dump_ppgtt; @@ -2405,12 +2427,6 @@ static int ggtt_bind_vma(struct i915_vma *vma, struct drm_i915_gem_object *obj = vma->obj; u32 pte_flags; - if (unlikely(!vma->pages)) { - int ret = i915_get_ggtt_vma_pages(vma); - if (ret) - return ret; - } - /* Currently applicable only to VLV */ pte_flags = 0; if (obj->gt_ro) @@ -2447,12 +2463,6 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, u32 pte_flags; int ret; - if (unlikely(!vma->pages)) { - ret = i915_get_ggtt_vma_pages(vma); - if (ret) - return ret; - } - /* Currently applicable only to VLV */ pte_flags = 0; if (vma->obj->gt_ro) @@ -2467,7 +2477,7 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, vma->node.start, vma->size); if (ret) - goto err_pages; + return ret; } appgtt->base.insert_entries(&appgtt->base, vma, cache_level, @@ -2481,17 +2491,6 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, } return 0; - -err_pages: - if (!(vma->flags & (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND))) { - if (vma->pages != vma->obj->mm.pages) { - GEM_BUG_ON(!vma->pages); - sg_free_table(vma->pages); - kfree(vma->pages); - } - vma->pages = NULL; - } - return ret; } static void aliasing_gtt_unbind_vma(struct i915_vma *vma) @@ -2529,6 +2528,19 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL); } +static int ggtt_set_pages(struct i915_vma *vma) +{ + int ret; + + GEM_BUG_ON(vma->pages); + + ret = i915_get_ggtt_vma_pages(vma); + if (ret) + return ret; + + return 0; +} + static void i915_gtt_color_adjust(const struct drm_mm_node *node, unsigned long color, u64 *start, @@ -3151,6 +3163,8 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) ggtt->base.cleanup = gen6_gmch_remove; ggtt->base.bind_vma = ggtt_bind_vma; ggtt->base.unbind_vma = ggtt_unbind_vma; + ggtt->base.set_pages = ggtt_set_pages; + ggtt->base.clear_pages = clear_pages; ggtt->base.insert_page = gen8_ggtt_insert_page; ggtt->base.clear_range = nop_clear_range; if (!USES_FULL_PPGTT(dev_priv) || intel_scanout_needs_vtd_wa(dev_priv)) @@ -3209,6 +3223,8 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt) ggtt->base.insert_entries = gen6_ggtt_insert_entries; ggtt->base.bind_vma = ggtt_bind_vma; ggtt->base.unbind_vma = ggtt_unbind_vma; + ggtt->base.set_pages = ggtt_set_pages; + ggtt->base.clear_pages = clear_pages; ggtt->base.cleanup = gen6_gmch_remove; ggtt->invalidate = gen6_ggtt_invalidate; @@ -3254,6 +3270,8 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt) ggtt->base.clear_range = i915_ggtt_clear_range; ggtt->base.bind_vma = ggtt_bind_vma; ggtt->base.unbind_vma = ggtt_unbind_vma; + ggtt->base.set_pages = ggtt_set_pages; + ggtt->base.clear_pages = clear_pages; ggtt->base.cleanup = i915_gmch_remove; ggtt->invalidate = gmch_ggtt_invalidate; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 50218c141c21..f22491b4e6dc 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -335,6 +335,8 @@ struct i915_address_space { int (*bind_vma)(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags); + int (*set_pages)(struct i915_vma *vma); + void (*clear_pages)(struct i915_vma *vma); I915_SELFTEST_DECLARE(struct fault_attr fault_attr); }; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 02d1a5eacb00..49bf49571e47 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -266,6 +266,8 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, if (bind_flags == 0) return 0; + GEM_BUG_ON(!vma->pages); + trace_i915_vma_bind(vma, bind_flags); ret = vma->vm->bind_vma(vma, cache_level, bind_flags); if (ret) @@ -471,25 +473,31 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) if (ret) return ret; + GEM_BUG_ON(vma->pages); + + ret = vma->vm->set_pages(vma); + if (ret) + goto err_unpin; + if (flags & PIN_OFFSET_FIXED) { u64 offset = flags & PIN_OFFSET_MASK; if (!IS_ALIGNED(offset, alignment) || range_overflows(offset, size, end)) { ret = -EINVAL; - goto err_unpin; + goto err_clear; } ret = i915_gem_gtt_reserve(vma->vm, &vma->node, size, offset, obj->cache_level, flags); if (ret) - goto err_unpin; + goto err_clear; } else { ret = i915_gem_gtt_insert(vma->vm, &vma->node, size, alignment, obj->cache_level, start, end, flags); if (ret) - goto err_unpin; + goto err_clear; GEM_BUG_ON(vma->node.start < start); GEM_BUG_ON(vma->node.start + vma->node.size > end); @@ -504,6 +512,8 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) return 0; +err_clear: + vma->vm->clear_pages(vma); err_unpin: i915_gem_object_unpin_pages(obj); return ret; @@ -517,6 +527,8 @@ i915_vma_remove(struct i915_vma *vma) GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); GEM_BUG_ON(vma->flags & (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND)); + vma->vm->clear_pages(vma); + drm_mm_remove_node(&vma->node); list_move_tail(&vma->vm_link, &vma->vm->unbound_list); @@ -569,8 +581,8 @@ int __i915_vma_do_pin(struct i915_vma *vma, err_remove: if ((bound & I915_VMA_BIND_MASK) == 0) { - GEM_BUG_ON(vma->pages); i915_vma_remove(vma); + GEM_BUG_ON(vma->pages); } err_unpin: __i915_vma_unpin(vma); @@ -695,13 +707,6 @@ int i915_vma_unbind(struct i915_vma *vma) } vma->flags &= ~(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND); - if (vma->pages != obj->mm.pages) { - GEM_BUG_ON(!vma->pages); - sg_free_table(vma->pages); - kfree(vma->pages); - } - vma->pages = NULL; - i915_vma_remove(vma); destroy: diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c index f2118cf535a0..336e1afb250f 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gtt.c +++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c @@ -43,7 +43,6 @@ static int mock_bind_ppgtt(struct i915_vma *vma, u32 flags) { GEM_BUG_ON(flags & I915_VMA_GLOBAL_BIND); - vma->pages = vma->obj->mm.pages; vma->flags |= I915_VMA_LOCAL_BIND; return 0; } @@ -84,6 +83,8 @@ mock_ppgtt(struct drm_i915_private *i915, ppgtt->base.insert_entries = mock_insert_entries; ppgtt->base.bind_vma = mock_bind_ppgtt; ppgtt->base.unbind_vma = mock_unbind_ppgtt; + ppgtt->base.set_pages = ppgtt_set_pages; + ppgtt->base.clear_pages = clear_pages; ppgtt->base.cleanup = mock_cleanup; return ppgtt; @@ -93,12 +94,6 @@ static int mock_bind_ggtt(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags) { - int err; - - err = i915_get_ggtt_vma_pages(vma); - if (err) - return err; - vma->flags |= I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND; return 0; } @@ -124,6 +119,8 @@ void mock_init_ggtt(struct drm_i915_private *i915) ggtt->base.insert_entries = mock_insert_entries; ggtt->base.bind_vma = mock_bind_ggtt; ggtt->base.unbind_vma = mock_unbind_ggtt; + ggtt->base.set_pages = ggtt_set_pages; + ggtt->base.clear_pages = clear_pages; ggtt->base.cleanup = mock_cleanup; i915_address_space_init(&ggtt->base, i915, "global"); -- cgit v1.2.3 From 7464284b357776b19e4cfb50d0d3724bdff035df Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:20 +0100 Subject: drm/i915: align the vma start to the largest gtt page size For the 48b PPGTT try to align the vma start address to the required page size boundary to guarantee we use said page size in the gtt. If we are dealing with multiple page sizes, we can't guarantee anything and just align to the largest. For soft pinning and objects which need to be tightly packed into the lower 32bits we don't force any alignment. v2: various improvements suggested by Chris v3: use set_pages and better placement of page_sizes v4: prefer upper_32_bits() v5: assign vma->page_sizes = vma->obj->page_sizes directly prefer sizeof(vma->page_sizes) v6: fixup checking of end to exclude GGTT (which are assumed to be limited to 4G). Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-9-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-8-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++++++ drivers/gpu/drm/i915/i915_vma.c | 16 ++++++++++++++++ drivers/gpu/drm/i915/i915_vma.h | 1 + 3 files changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index c534b74eee32..fb7ac66814ab 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -226,6 +226,8 @@ static int ppgtt_set_pages(struct i915_vma *vma) vma->pages = vma->obj->mm.pages; + vma->page_sizes = vma->obj->mm.page_sizes; + return 0; } @@ -238,6 +240,8 @@ static void clear_pages(struct i915_vma *vma) kfree(vma->pages); } vma->pages = NULL; + + memset(&vma->page_sizes, 0, sizeof(vma->page_sizes)); } static gen8_pte_t gen8_pte_encode(dma_addr_t addr, @@ -2538,6 +2542,8 @@ static int ggtt_set_pages(struct i915_vma *vma) if (ret) return ret; + vma->page_sizes = vma->obj->mm.page_sizes; + return 0; } diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 49bf49571e47..5d4164406b63 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -493,6 +493,22 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) if (ret) goto err_clear; } else { + /* + * We only support huge gtt pages through the 48b PPGTT, + * however we also don't want to force any alignment for + * objects which need to be tightly packed into the low 32bits. + * + * Note that we assume that GGTT are limited to 4GiB for the + * forseeable future. See also i915_ggtt_offset(). + */ + if (upper_32_bits(end - 1) && + vma->page_sizes.sg > I915_GTT_PAGE_SIZE) { + u64 page_alignment = + rounddown_pow_of_two(vma->page_sizes.sg); + + alignment = max(alignment, page_alignment); + } + ret = i915_gem_gtt_insert(vma->vm, &vma->node, size, alignment, obj->cache_level, start, end, flags); diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index e811067c7724..c59ba76613a3 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -55,6 +55,7 @@ struct i915_vma { void __iomem *iomap; u64 size; u64 display_alignment; + struct i915_page_sizes page_sizes; u32 fence_size; u32 fence_alignment; -- cgit v1.2.3 From 855822be74a957073143268bf976739de016937f Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:21 +0100 Subject: drm/i915: align 64K objects to 2M We can't mix 64K and 4K pte's in the same page-table, so for now we align 64K objects to 2M to avoid any potential mixing. This is potentially wasteful but in reality shouldn't be too bad since this only applies to the virtual address space of a 48b PPGTT. v2: don't separate logically connected ops Suggested-by: Chris Wilson Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-10-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-9-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_vma.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 5d4164406b63..72e86b32ab41 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -503,10 +503,20 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) */ if (upper_32_bits(end - 1) && vma->page_sizes.sg > I915_GTT_PAGE_SIZE) { + /* + * We can't mix 64K and 4K PTEs in the same page-table + * (2M block), and so to avoid the ugliness and + * complexity of coloring we opt for just aligning 64K + * objects to 2M. + */ u64 page_alignment = - rounddown_pow_of_two(vma->page_sizes.sg); + rounddown_pow_of_two(vma->page_sizes.sg | + I915_GTT_PAGE_SIZE_2M); alignment = max(alignment, page_alignment); + + if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) + size = round_up(size, I915_GTT_PAGE_SIZE_2M); } ret = i915_gem_gtt_insert(vma->vm, &vma->node, -- cgit v1.2.3 From 9a6330cff9b4b0691c7554fe873b09e7f6d377a9 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:22 +0100 Subject: drm/i915: enable IPS bit for 64K pages Before we can enable 64K pages through the IPS bit, we must first enable it through MMIO, otherwise the page-walker will simply ignore it. v2: add comment mentioning that 64K is BDW+ v3: move to more suitable home Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-11-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-10-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 17 +++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ 2 files changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index fb7ac66814ab..74fc9ac11cd5 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1987,6 +1987,23 @@ static void gtt_write_workarounds(struct drm_i915_private *dev_priv) I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL); else if (IS_GEN9_LP(dev_priv)) I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT); + + /* + * To support 64K PTEs we need to first enable the use of the + * Intermediate-Page-Size(IPS) bit of the PDE field via some magical + * mmio, otherwise the page-walker will simply ignore the IPS bit. This + * shouldn't be needed after GEN10. + * + * 64K pages were first introduced from BDW+, although technically they + * only *work* from gen9+. For pre-BDW we instead have the option for + * 32K pages, but we don't currently have any support for it in our + * driver. + */ + if (HAS_PAGE_SIZES(dev_priv, I915_GTT_PAGE_SIZE_64K) && + INTEL_GEN(dev_priv) <= 10) + I915_WRITE(GEN8_GAMW_ECO_DEV_RW_IA, + I915_READ(GEN8_GAMW_ECO_DEV_RW_IA) | + GAMW_ECO_ENABLE_64K_IPS_FIELD); } int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e7dba5539b11..50e65c98ca6c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2371,6 +2371,9 @@ enum i915_power_well_id { #define GEN9_GAMT_ECO_REG_RW_IA _MMIO(0x4ab0) #define GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS (1<<18) +#define GEN8_GAMW_ECO_DEV_RW_IA _MMIO(0x4080) +#define GAMW_ECO_ENABLE_64K_IPS_FIELD 0xF + #define GAMT_CHKN_BIT_REG _MMIO(0x4ab8) #define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1<<28) #define GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT (1<<24) -- cgit v1.2.3 From 8cb0983678e05939457d867e09bddb6883db5268 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:23 +0100 Subject: drm/i915: disable GTT cache for 2M pages When SW enables the use of 2M/1G pages, it must disable the GTT cache. v2: don't disable for Cherryview which doesn't even support 48b PPGTT! v3: explicitly check that the system does support 2M/1G pages v4: split WA and decision logic Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-12-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-11-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 171b21f6c4ad..9d0ca2656a23 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -8453,6 +8453,9 @@ static void skl_init_clock_gating(struct drm_i915_private *dev_priv) static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) { + /* The GTT cache must be disabled if the system is using 2M pages. */ + bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv, + I915_GTT_PAGE_SIZE_2M); enum pipe pipe; ilk_init_lp_watermarks(dev_priv); @@ -8487,12 +8490,8 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) /* WaProgramL3SqcReg1Default:bdw */ gen8_set_l3sqc_credits(dev_priv, 30, 2); - /* - * WaGttCachingOffByDefault:bdw - * GTT cache may not work with big pages, so if those - * are ever enabled GTT cache may need to be disabled. - */ - I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL); + /* WaGttCachingOffByDefault:bdw */ + I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0); /* WaKVMNotificationOnConfigChange:bdw */ I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1) -- cgit v1.2.3 From 0a03852e049af91da9ae70326c44bb5d9b0d377a Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:24 +0100 Subject: drm/i915: support 2M pages for the 48b PPGTT Support inserting 2M gtt pages into the 48b PPGTT. v2: sanity check sg->length against page_size v3: don't recalculate rem on each loop whitespace breakup Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-13-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-12-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 76 +++++++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 + 2 files changed, 74 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 74fc9ac11cd5..79ba485c5d42 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1013,6 +1013,69 @@ static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm, cache_level); } +static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma, + struct i915_page_directory_pointer **pdps, + struct sgt_dma *iter, + enum i915_cache_level cache_level) +{ + const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level); + u64 start = vma->node.start; + dma_addr_t rem = iter->sg->length; + + do { + struct gen8_insert_pte idx = gen8_insert_pte(start); + struct i915_page_directory_pointer *pdp = pdps[idx.pml4e]; + struct i915_page_directory *pd = pdp->page_directory[idx.pdpe]; + unsigned int page_size; + gen8_pte_t encode = pte_encode; + gen8_pte_t *vaddr; + u16 index, max; + + if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M && + IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) && + rem >= I915_GTT_PAGE_SIZE_2M && !idx.pte) { + index = idx.pde; + max = I915_PDES; + page_size = I915_GTT_PAGE_SIZE_2M; + + encode |= GEN8_PDE_PS_2M; + + vaddr = kmap_atomic_px(pd); + } else { + struct i915_page_table *pt = pd->page_table[idx.pde]; + + index = idx.pte; + max = GEN8_PTES; + page_size = I915_GTT_PAGE_SIZE; + + vaddr = kmap_atomic_px(pt); + } + + do { + GEM_BUG_ON(iter->sg->length < page_size); + vaddr[index++] = encode | iter->dma; + + start += page_size; + iter->dma += page_size; + rem -= page_size; + if (iter->dma >= iter->max) { + iter->sg = __sg_next(iter->sg); + if (!iter->sg) + break; + + rem = iter->sg->length; + iter->dma = sg_dma_address(iter->sg); + iter->max = iter->dma + rem; + + if (unlikely(!IS_ALIGNED(iter->dma, page_size))) + break; + } + } while (rem >= page_size && index < max); + + kunmap_atomic(vaddr); + } while (iter->sg); +} + static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm, struct i915_vma *vma, enum i915_cache_level cache_level, @@ -1025,11 +1088,16 @@ static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm, .max = iter.dma + iter.sg->length, }; struct i915_page_directory_pointer **pdps = ppgtt->pml4.pdps; - struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start); - while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++], &iter, - &idx, cache_level)) - GEM_BUG_ON(idx.pml4e >= GEN8_PML4ES_PER_PML4); + if (vma->page_sizes.sg > I915_GTT_PAGE_SIZE) { + gen8_ppgtt_insert_huge_entries(vma, pdps, &iter, cache_level); + } else { + struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start); + + while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++], + &iter, &idx, cache_level)) + GEM_BUG_ON(idx.pml4e >= GEN8_PML4ES_PER_PML4); + } } static void gen8_free_page_tables(struct i915_address_space *vm, diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index f22491b4e6dc..b9d7036c3665 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -154,6 +154,8 @@ typedef u64 gen8_ppgtt_pml4e_t; #define GEN8_PPAT_GET_AGE(x) ((x) & (3 << 4)) #define CHV_PPAT_GET_SNOOP(x) ((x) & (1 << 6)) +#define GEN8_PDE_PS_2M BIT(7) + struct sg_table; struct intel_rotation_info { -- cgit v1.2.3 From aa095871e4a7ba9fcf87ffd762c044e1f9f634f1 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:25 +0100 Subject: drm/i915: add support for 64K scratch page Before we can fully enable 64K pages, we need to first support a 64K scratch page if we intend to support the case where we have object sizes < 2M, since any scratch PTE must also point to a 64K region. Without this our 64K usage is limited to objects which completely fill the page-table, and therefore don't need any scratch. v2: add reminder about why 48b PPGTT Reported-by: Chris Wilson Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-14-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-13-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 64 ++++++++++++++++++++++++++++++------- drivers/gpu/drm/i915/i915_gem_gtt.h | 1 + 2 files changed, 54 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 79ba485c5d42..7eae6ab8c5fd 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -519,22 +519,63 @@ static void fill_page_dma_32(struct i915_address_space *vm, static int setup_scratch_page(struct i915_address_space *vm, gfp_t gfp) { - struct page *page; + struct page *page = NULL; dma_addr_t addr; + int order; - page = alloc_page(gfp | __GFP_ZERO); - if (unlikely(!page)) - return -ENOMEM; + /* + * In order to utilize 64K pages for an object with a size < 2M, we will + * need to support a 64K scratch page, given that every 16th entry for a + * page-table operating in 64K mode must point to a properly aligned 64K + * region, including any PTEs which happen to point to scratch. + * + * This is only relevant for the 48b PPGTT where we support + * huge-gtt-pages, see also i915_vma_insert(). + * + * TODO: we should really consider write-protecting the scratch-page and + * sharing between ppgtt + */ + if (i915_vm_is_48bit(vm) && + HAS_PAGE_SIZES(vm->i915, I915_GTT_PAGE_SIZE_64K)) { + order = get_order(I915_GTT_PAGE_SIZE_64K); + page = alloc_pages(gfp | __GFP_ZERO, order); + if (page) { + addr = dma_map_page(vm->dma, page, 0, + I915_GTT_PAGE_SIZE_64K, + PCI_DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(vm->dma, addr))) { + __free_pages(page, order); + page = NULL; + } - addr = dma_map_page(vm->dma, page, 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(vm->dma, addr))) { - __free_page(page); - return -ENOMEM; + if (!IS_ALIGNED(addr, I915_GTT_PAGE_SIZE_64K)) { + dma_unmap_page(vm->dma, addr, + I915_GTT_PAGE_SIZE_64K, + PCI_DMA_BIDIRECTIONAL); + __free_pages(page, order); + page = NULL; + } + } + } + + if (!page) { + order = 0; + page = alloc_page(gfp | __GFP_ZERO); + if (unlikely(!page)) + return -ENOMEM; + + addr = dma_map_page(vm->dma, page, 0, PAGE_SIZE, + PCI_DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(vm->dma, addr))) { + __free_page(page); + return -ENOMEM; + } } vm->scratch_page.page = page; vm->scratch_page.daddr = addr; + vm->scratch_page.order = order; + return 0; } @@ -542,8 +583,9 @@ static void cleanup_scratch_page(struct i915_address_space *vm) { struct i915_page_dma *p = &vm->scratch_page; - dma_unmap_page(vm->dma, p->daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - __free_page(p->page); + dma_unmap_page(vm->dma, p->daddr, BIT(p->order) << PAGE_SHIFT, + PCI_DMA_BIDIRECTIONAL); + __free_pages(p->page, p->order); } static struct i915_page_table *alloc_pt(struct i915_address_space *vm) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index b9d7036c3665..e9de3f05b0c9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -215,6 +215,7 @@ struct i915_vma; struct i915_page_dma { struct page *page; + int order; union { dma_addr_t daddr; -- cgit v1.2.3 From 17a00cf73c31cca85531ec409508a2921c077851 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:26 +0100 Subject: drm/i915: support 64K pages for the 48b PPGTT Support inserting 64K pages into the 48b PPGTT. v2: check for 64K scratch v3: we should only have to re-adjust maybe_64K at every sg interval Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-15-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-14-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_gtt.h | 7 +++++++ 2 files changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7eae6ab8c5fd..118aad90468f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1069,6 +1069,7 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma, struct i915_page_directory_pointer *pdp = pdps[idx.pml4e]; struct i915_page_directory *pd = pdp->page_directory[idx.pdpe]; unsigned int page_size; + bool maybe_64K = false; gen8_pte_t encode = pte_encode; gen8_pte_t *vaddr; u16 index, max; @@ -1090,6 +1091,13 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma, max = GEN8_PTES; page_size = I915_GTT_PAGE_SIZE; + if (!index && + vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K && + IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) && + (IS_ALIGNED(rem, I915_GTT_PAGE_SIZE_64K) || + rem >= (max - index) << PAGE_SHIFT)) + maybe_64K = true; + vaddr = kmap_atomic_px(pt); } @@ -1109,12 +1117,35 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma, iter->dma = sg_dma_address(iter->sg); iter->max = iter->dma + rem; + if (maybe_64K && index < max && + !(IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) && + (IS_ALIGNED(rem, I915_GTT_PAGE_SIZE_64K) || + rem >= (max - index) << PAGE_SHIFT))) + maybe_64K = false; + if (unlikely(!IS_ALIGNED(iter->dma, page_size))) break; } } while (rem >= page_size && index < max); kunmap_atomic(vaddr); + + /* + * Is it safe to mark the 2M block as 64K? -- Either we have + * filled whole page-table with 64K entries, or filled part of + * it and have reached the end of the sg table and we have + * enough padding. + */ + if (maybe_64K && + (index == max || + (i915_vm_has_scratch_64K(vma->vm) && + !iter->sg && IS_ALIGNED(vma->node.start + + vma->node.size, + I915_GTT_PAGE_SIZE_2M)))) { + vaddr = kmap_atomic_px(pd); + vaddr[idx.pde] |= GEN8_PDE_IPS_64K; + kunmap_atomic(vaddr); + } } while (iter->sg); } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index e9de3f05b0c9..93211a96fdad 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -154,6 +154,7 @@ typedef u64 gen8_ppgtt_pml4e_t; #define GEN8_PPAT_GET_AGE(x) ((x) & (3 << 4)) #define CHV_PPAT_GET_SNOOP(x) ((x) & (1 << 6)) +#define GEN8_PDE_IPS_64K BIT(11) #define GEN8_PDE_PS_2M BIT(7) struct sg_table; @@ -352,6 +353,12 @@ i915_vm_is_48bit(const struct i915_address_space *vm) return (vm->total - 1) >> 32; } +static inline bool +i915_vm_has_scratch_64K(struct i915_address_space *vm) +{ + return vm->scratch_page.order == get_order(I915_GTT_PAGE_SIZE_64K); +} + /* The Graphics Translation Table is the way in which GEN hardware translates a * Graphics Virtual Address into a Physical Address. In addition to the normal * collateral associated with any va->pa translations GEN hardware also has a -- cgit v1.2.3 From d9ec12f8e302731df6482d85a9c1f25b84a43de5 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:27 +0100 Subject: drm/i915: accurate page size tracking for the ppgtt Now that we support multiple page sizes for the ppgtt, it would be useful to track the real usage for debugging purposes. Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-16-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-15-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 11 +++++++++++ drivers/gpu/drm/i915/i915_gem_object.h | 10 ++++++++++ 2 files changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 118aad90468f..4c605785e2b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1053,6 +1053,8 @@ static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm, gen8_ppgtt_insert_pte_entries(ppgtt, &ppgtt->pdp, &iter, &idx, cache_level); + + vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; } static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma, @@ -1145,7 +1147,10 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma, vaddr = kmap_atomic_px(pd); vaddr[idx.pde] |= GEN8_PDE_IPS_64K; kunmap_atomic(vaddr); + page_size = I915_GTT_PAGE_SIZE_64K; } + + vma->page_sizes.gtt |= page_size; } while (iter->sg); } @@ -1170,6 +1175,8 @@ static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm, while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++], &iter, &idx, cache_level)) GEM_BUG_ON(idx.pml4e >= GEN8_PML4ES_PER_PML4); + + vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; } } @@ -1891,6 +1898,8 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, } } while (1); kunmap_atomic(vaddr); + + vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; } static int gen6_alloc_va_range(struct i915_address_space *vm, @@ -2598,6 +2607,8 @@ static int ggtt_bind_vma(struct i915_vma *vma, vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags); intel_runtime_pm_put(i915); + vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; + /* * Without aliasing PPGTT there's no difference between * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 110672952a1c..e4e6dd93889d 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -169,6 +169,7 @@ struct drm_i915_gem_object { struct sg_table *pages; void *mapping; + /* TODO: whack some of this into the error state */ struct i915_page_sizes { /** * The sg mask of the pages sg_table. i.e the mask of @@ -184,6 +185,15 @@ struct drm_i915_gem_object { * to use opportunistically. */ unsigned int sg; + + /** + * The actual gtt page size usage. Since we can have + * multiple vma associated with this object we need to + * prevent any trampling of state, hence a copy of this + * struct also lives in each vma, therefore the gtt + * value here should only be read/write through the vma. + */ + unsigned int gtt; } page_sizes; struct i915_gem_object_page_iter { -- cgit v1.2.3 From 7393b7ee3a9c19776fd7b42369ea93994173abd9 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:28 +0100 Subject: drm/i915/debugfs: include some gtt page size metrics Good to know, mostly for debugging purposes. v2: some improvements from Chris Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-17-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-16-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 61 ++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 84ab77c02d3e..f7817c667958 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -119,6 +119,36 @@ static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj) return size; } +static const char * +stringify_page_sizes(unsigned int page_sizes, char *buf, size_t len) +{ + size_t x = 0; + + switch (page_sizes) { + case 0: + return ""; + case I915_GTT_PAGE_SIZE_4K: + return "4K"; + case I915_GTT_PAGE_SIZE_64K: + return "64K"; + case I915_GTT_PAGE_SIZE_2M: + return "2M"; + default: + if (!buf) + return "M"; + + if (page_sizes & I915_GTT_PAGE_SIZE_2M) + x += snprintf(buf + x, len - x, "2M, "); + if (page_sizes & I915_GTT_PAGE_SIZE_64K) + x += snprintf(buf + x, len - x, "64K, "); + if (page_sizes & I915_GTT_PAGE_SIZE_4K) + x += snprintf(buf + x, len - x, "4K, "); + buf[x-2] = '\0'; + + return buf; + } +} + static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { @@ -156,9 +186,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) if (!drm_mm_node_allocated(&vma->node)) continue; - seq_printf(m, " (%sgtt offset: %08llx, size: %08llx", + seq_printf(m, " (%sgtt offset: %08llx, size: %08llx, pages: %s", i915_vma_is_ggtt(vma) ? "g" : "pp", - vma->node.start, vma->node.size); + vma->node.start, vma->node.size, + stringify_page_sizes(vma->page_sizes.gtt, NULL, 0)); if (i915_vma_is_ggtt(vma)) { switch (vma->ggtt_view.type) { case I915_GGTT_VIEW_NORMAL: @@ -403,10 +434,12 @@ static int i915_gem_object_info(struct seq_file *m, void *data) struct drm_i915_private *dev_priv = node_to_i915(m->private); struct drm_device *dev = &dev_priv->drm; struct i915_ggtt *ggtt = &dev_priv->ggtt; - u32 count, mapped_count, purgeable_count, dpy_count; - u64 size, mapped_size, purgeable_size, dpy_size; + u32 count, mapped_count, purgeable_count, dpy_count, huge_count; + u64 size, mapped_size, purgeable_size, dpy_size, huge_size; struct drm_i915_gem_object *obj; + unsigned int page_sizes = 0; struct drm_file *file; + char buf[80]; int ret; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -420,6 +453,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) size = count = 0; mapped_size = mapped_count = 0; purgeable_size = purgeable_count = 0; + huge_size = huge_count = 0; list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { size += obj->base.size; ++count; @@ -433,6 +467,12 @@ static int i915_gem_object_info(struct seq_file *m, void *data) mapped_count++; mapped_size += obj->base.size; } + + if (obj->mm.page_sizes.sg > I915_GTT_PAGE_SIZE) { + huge_count++; + huge_size += obj->base.size; + page_sizes |= obj->mm.page_sizes.sg; + } } seq_printf(m, "%u unbound objects, %llu bytes\n", count, size); @@ -455,6 +495,12 @@ static int i915_gem_object_info(struct seq_file *m, void *data) mapped_count++; mapped_size += obj->base.size; } + + if (obj->mm.page_sizes.sg > I915_GTT_PAGE_SIZE) { + huge_count++; + huge_size += obj->base.size; + page_sizes |= obj->mm.page_sizes.sg; + } } seq_printf(m, "%u bound objects, %llu bytes\n", count, size); @@ -462,11 +508,18 @@ static int i915_gem_object_info(struct seq_file *m, void *data) purgeable_count, purgeable_size); seq_printf(m, "%u mapped objects, %llu bytes\n", mapped_count, mapped_size); + seq_printf(m, "%u huge-paged objects (%s) %llu bytes\n", + huge_count, + stringify_page_sizes(page_sizes, buf, sizeof(buf)), + huge_size); seq_printf(m, "%u display objects (pinned), %llu bytes\n", dpy_count, dpy_size); seq_printf(m, "%llu [%llu] gtt total\n", ggtt->base.total, ggtt->mappable_end); + seq_printf(m, "Supported page sizes: %s\n", + stringify_page_sizes(INTEL_INFO(dev_priv)->page_sizes, + buf, sizeof(buf))); seq_putc(m, '\n'); print_batch_pool_stats(m, dev_priv); -- cgit v1.2.3 From 4049866f0913110bf7de597c1177de7a1cc459cb Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:29 +0100 Subject: drm/i915/selftests: huge page tests v2: mock test page support configurations and add MI_STORE_DWORD test v3: run all mockable huge page tests on all platforms via the mock_device v4: add pin_update regression test various improvements suggested by Chris v5: fix issues reported by kbuild test single sg spanning multiple page sizes don't explode when running the live-tests through the appgtt v6: lots of improvements from Chris v7: run on each engine for igt_write_huge add simple tmpfs fallback test v8: size_t is bad don't break the i386 build Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-18-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-17-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/i915_gem_object.h | 2 + drivers/gpu/drm/i915/selftests/huge_pages.c | 1715 ++++++++++++++++++++ .../gpu/drm/i915/selftests/i915_live_selftests.h | 1 + .../gpu/drm/i915/selftests/i915_mock_selftests.h | 1 + 5 files changed, 1720 insertions(+) create mode 100644 drivers/gpu/drm/i915/selftests/huge_pages.c (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 34398696824c..f8c3ac1c8c67 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5412,6 +5412,7 @@ err_unlock: #include "selftests/scatterlist.c" #include "selftests/mock_gem_device.c" #include "selftests/huge_gem_object.c" +#include "selftests/huge_pages.c" #include "selftests/i915_gem_object.c" #include "selftests/i915_gem_coherency.c" #endif diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index e4e6dd93889d..956c911c2cbf 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -196,6 +196,8 @@ struct drm_i915_gem_object { unsigned int gtt; } page_sizes; + I915_SELFTEST_DECLARE(unsigned int page_mask); + struct i915_gem_object_page_iter { struct scatterlist *sg_pos; unsigned int sg_idx; /* in pages, but 32bit eek! */ diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c new file mode 100644 index 000000000000..b8495882e5b0 --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c @@ -0,0 +1,1715 @@ +/* + * Copyright © 2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "../i915_selftest.h" + +#include + +#include "mock_drm.h" + +static const unsigned int page_sizes[] = { + I915_GTT_PAGE_SIZE_2M, + I915_GTT_PAGE_SIZE_64K, + I915_GTT_PAGE_SIZE_4K, +}; + +static unsigned int get_largest_page_size(struct drm_i915_private *i915, + u64 rem) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(page_sizes); ++i) { + unsigned int page_size = page_sizes[i]; + + if (HAS_PAGE_SIZES(i915, page_size) && rem >= page_size) + return page_size; + } + + return 0; +} + +static void huge_pages_free_pages(struct sg_table *st) +{ + struct scatterlist *sg; + + for (sg = st->sgl; sg; sg = __sg_next(sg)) { + if (sg_page(sg)) + __free_pages(sg_page(sg), get_order(sg->length)); + } + + sg_free_table(st); + kfree(st); +} + +static int get_huge_pages(struct drm_i915_gem_object *obj) +{ +#define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY) + unsigned int page_mask = obj->mm.page_mask; + struct sg_table *st; + struct scatterlist *sg; + unsigned int sg_mask; + u64 rem; + + st = kmalloc(sizeof(*st), GFP); + if (!st) + return -ENOMEM; + + if (sg_alloc_table(st, obj->base.size >> PAGE_SHIFT, GFP)) { + kfree(st); + return -ENOMEM; + } + + rem = obj->base.size; + sg = st->sgl; + st->nents = 0; + sg_mask = 0; + + /* + * Our goal here is simple, we want to greedily fill the object from + * largest to smallest page-size, while ensuring that we use *every* + * page-size as per the given page-mask. + */ + do { + unsigned int bit = ilog2(page_mask); + unsigned int page_size = BIT(bit); + int order = get_order(page_size); + + do { + struct page *page; + + GEM_BUG_ON(order >= MAX_ORDER); + page = alloc_pages(GFP | __GFP_ZERO, order); + if (!page) + goto err; + + sg_set_page(sg, page, page_size, 0); + sg_mask |= page_size; + st->nents++; + + rem -= page_size; + if (!rem) { + sg_mark_end(sg); + break; + } + + sg = __sg_next(sg); + } while ((rem - ((page_size-1) & page_mask)) >= page_size); + + page_mask &= (page_size-1); + } while (page_mask); + + if (i915_gem_gtt_prepare_pages(obj, st)) + goto err; + + obj->mm.madv = I915_MADV_DONTNEED; + + GEM_BUG_ON(sg_mask != obj->mm.page_mask); + __i915_gem_object_set_pages(obj, st, sg_mask); + + return 0; + +err: + sg_set_page(sg, NULL, 0, 0); + sg_mark_end(sg); + huge_pages_free_pages(st); + + return -ENOMEM; +} + +static void put_huge_pages(struct drm_i915_gem_object *obj, + struct sg_table *pages) +{ + i915_gem_gtt_finish_pages(obj, pages); + huge_pages_free_pages(pages); + + obj->mm.dirty = false; + obj->mm.madv = I915_MADV_WILLNEED; +} + +static const struct drm_i915_gem_object_ops huge_page_ops = { + .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | + I915_GEM_OBJECT_IS_SHRINKABLE, + .get_pages = get_huge_pages, + .put_pages = put_huge_pages, +}; + +static struct drm_i915_gem_object * +huge_pages_object(struct drm_i915_private *i915, + u64 size, + unsigned int page_mask) +{ + struct drm_i915_gem_object *obj; + + GEM_BUG_ON(!size); + GEM_BUG_ON(!IS_ALIGNED(size, BIT(__ffs(page_mask)))); + + if (size >> PAGE_SHIFT > INT_MAX) + return ERR_PTR(-E2BIG); + + if (overflows_type(size, obj->base.size)) + return ERR_PTR(-E2BIG); + + obj = i915_gem_object_alloc(i915); + if (!obj) + return ERR_PTR(-ENOMEM); + + drm_gem_private_object_init(&i915->drm, &obj->base, size); + i915_gem_object_init(obj, &huge_page_ops); + + obj->base.write_domain = I915_GEM_DOMAIN_CPU; + obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->cache_level = I915_CACHE_NONE; + + obj->mm.page_mask = page_mask; + + return obj; +} + +static int fake_get_huge_pages(struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + const u64 max_len = rounddown_pow_of_two(UINT_MAX); + struct sg_table *st; + struct scatterlist *sg; + unsigned int sg_mask; + u64 rem; + + st = kmalloc(sizeof(*st), GFP); + if (!st) + return -ENOMEM; + + if (sg_alloc_table(st, obj->base.size >> PAGE_SHIFT, GFP)) { + kfree(st); + return -ENOMEM; + } + + /* Use optimal page sized chunks to fill in the sg table */ + rem = obj->base.size; + sg = st->sgl; + st->nents = 0; + sg_mask = 0; + do { + unsigned int page_size = get_largest_page_size(i915, rem); + unsigned int len = min(page_size * div_u64(rem, page_size), + max_len); + + GEM_BUG_ON(!page_size); + + sg->offset = 0; + sg->length = len; + sg_dma_len(sg) = len; + sg_dma_address(sg) = page_size; + + sg_mask |= len; + + st->nents++; + + rem -= len; + if (!rem) { + sg_mark_end(sg); + break; + } + + sg = sg_next(sg); + } while (1); + + obj->mm.madv = I915_MADV_DONTNEED; + + __i915_gem_object_set_pages(obj, st, sg_mask); + + return 0; +} + +static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct sg_table *st; + struct scatterlist *sg; + unsigned int page_size; + + st = kmalloc(sizeof(*st), GFP); + if (!st) + return -ENOMEM; + + if (sg_alloc_table(st, 1, GFP)) { + kfree(st); + return -ENOMEM; + } + + sg = st->sgl; + st->nents = 1; + + page_size = get_largest_page_size(i915, obj->base.size); + GEM_BUG_ON(!page_size); + + sg->offset = 0; + sg->length = obj->base.size; + sg_dma_len(sg) = obj->base.size; + sg_dma_address(sg) = page_size; + + obj->mm.madv = I915_MADV_DONTNEED; + + __i915_gem_object_set_pages(obj, st, sg->length); + + return 0; +#undef GFP +} + +static void fake_free_huge_pages(struct drm_i915_gem_object *obj, + struct sg_table *pages) +{ + sg_free_table(pages); + kfree(pages); +} + +static void fake_put_huge_pages(struct drm_i915_gem_object *obj, + struct sg_table *pages) +{ + fake_free_huge_pages(obj, pages); + obj->mm.dirty = false; + obj->mm.madv = I915_MADV_WILLNEED; +} + +static const struct drm_i915_gem_object_ops fake_ops = { + .flags = I915_GEM_OBJECT_IS_SHRINKABLE, + .get_pages = fake_get_huge_pages, + .put_pages = fake_put_huge_pages, +}; + +static const struct drm_i915_gem_object_ops fake_ops_single = { + .flags = I915_GEM_OBJECT_IS_SHRINKABLE, + .get_pages = fake_get_huge_pages_single, + .put_pages = fake_put_huge_pages, +}; + +static struct drm_i915_gem_object * +fake_huge_pages_object(struct drm_i915_private *i915, u64 size, bool single) +{ + struct drm_i915_gem_object *obj; + + GEM_BUG_ON(!size); + GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE)); + + if (size >> PAGE_SHIFT > UINT_MAX) + return ERR_PTR(-E2BIG); + + if (overflows_type(size, obj->base.size)) + return ERR_PTR(-E2BIG); + + obj = i915_gem_object_alloc(i915); + if (!obj) + return ERR_PTR(-ENOMEM); + + drm_gem_private_object_init(&i915->drm, &obj->base, size); + + if (single) + i915_gem_object_init(obj, &fake_ops_single); + else + i915_gem_object_init(obj, &fake_ops); + + obj->base.write_domain = I915_GEM_DOMAIN_CPU; + obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->cache_level = I915_CACHE_NONE; + + return obj; +} + +static int igt_check_page_sizes(struct i915_vma *vma) +{ + struct drm_i915_private *i915 = to_i915(vma->obj->base.dev); + unsigned int supported = INTEL_INFO(i915)->page_sizes; + struct drm_i915_gem_object *obj = vma->obj; + int err = 0; + + if (!HAS_PAGE_SIZES(i915, vma->page_sizes.sg)) { + pr_err("unsupported page_sizes.sg=%u, supported=%u\n", + vma->page_sizes.sg & ~supported, supported); + err = -EINVAL; + } + + if (!HAS_PAGE_SIZES(i915, vma->page_sizes.gtt)) { + pr_err("unsupported page_sizes.gtt=%u, supported=%u\n", + vma->page_sizes.gtt & ~supported, supported); + err = -EINVAL; + } + + if (vma->page_sizes.phys != obj->mm.page_sizes.phys) { + pr_err("vma->page_sizes.phys(%u) != obj->mm.page_sizes.phys(%u)\n", + vma->page_sizes.phys, obj->mm.page_sizes.phys); + err = -EINVAL; + } + + if (vma->page_sizes.sg != obj->mm.page_sizes.sg) { + pr_err("vma->page_sizes.sg(%u) != obj->mm.page_sizes.sg(%u)\n", + vma->page_sizes.sg, obj->mm.page_sizes.sg); + err = -EINVAL; + } + + if (obj->mm.page_sizes.gtt) { + pr_err("obj->page_sizes.gtt(%u) should never be set\n", + obj->mm.page_sizes.gtt); + err = -EINVAL; + } + + return err; +} + +static int igt_mock_exhaust_device_supported_pages(void *arg) +{ + struct i915_hw_ppgtt *ppgtt = arg; + struct drm_i915_private *i915 = ppgtt->base.i915; + unsigned int saved_mask = INTEL_INFO(i915)->page_sizes; + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + int i, j, single; + int err; + + /* + * Sanity check creating objects with every valid page support + * combination for our mock device. + */ + + for (i = 1; i < BIT(ARRAY_SIZE(page_sizes)); i++) { + unsigned int combination = 0; + + for (j = 0; j < ARRAY_SIZE(page_sizes); j++) { + if (i & BIT(j)) + combination |= page_sizes[j]; + } + + mkwrite_device_info(i915)->page_sizes = combination; + + for (single = 0; single <= 1; ++single) { + obj = fake_huge_pages_object(i915, combination, !!single); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto out_device; + } + + if (obj->base.size != combination) { + pr_err("obj->base.size=%zu, expected=%u\n", + obj->base.size, combination); + err = -EINVAL; + goto out_put; + } + + vma = i915_vma_instance(obj, &ppgtt->base, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } + + err = i915_vma_pin(vma, 0, 0, PIN_USER); + if (err) + goto out_close; + + err = igt_check_page_sizes(vma); + + if (vma->page_sizes.sg != combination) { + pr_err("page_sizes.sg=%u, expected=%u\n", + vma->page_sizes.sg, combination); + err = -EINVAL; + } + + i915_vma_unpin(vma); + i915_vma_close(vma); + + i915_gem_object_put(obj); + + if (err) + goto out_device; + } + } + + goto out_device; + +out_close: + i915_vma_close(vma); +out_put: + i915_gem_object_put(obj); +out_device: + mkwrite_device_info(i915)->page_sizes = saved_mask; + + return err; +} + +static int igt_mock_ppgtt_misaligned_dma(void *arg) +{ + struct i915_hw_ppgtt *ppgtt = arg; + struct drm_i915_private *i915 = ppgtt->base.i915; + unsigned long supported = INTEL_INFO(i915)->page_sizes; + struct drm_i915_gem_object *obj; + int bit; + int err; + + /* + * Sanity check dma misalignment for huge pages -- the dma addresses we + * insert into the paging structures need to always respect the page + * size alignment. + */ + + bit = ilog2(I915_GTT_PAGE_SIZE_64K); + + for_each_set_bit_from(bit, &supported, + ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) { + IGT_TIMEOUT(end_time); + unsigned int page_size = BIT(bit); + unsigned int flags = PIN_USER | PIN_OFFSET_FIXED; + unsigned int offset; + unsigned int size = + round_up(page_size, I915_GTT_PAGE_SIZE_2M) << 1; + struct i915_vma *vma; + + obj = fake_huge_pages_object(i915, size, true); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + if (obj->base.size != size) { + pr_err("obj->base.size=%zu, expected=%u\n", + obj->base.size, size); + err = -EINVAL; + goto out_put; + } + + err = i915_gem_object_pin_pages(obj); + if (err) + goto out_put; + + /* Force the page size for this object */ + obj->mm.page_sizes.sg = page_size; + + vma = i915_vma_instance(obj, &ppgtt->base, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_unpin; + } + + err = i915_vma_pin(vma, 0, 0, flags); + if (err) { + i915_vma_close(vma); + goto out_unpin; + } + + + err = igt_check_page_sizes(vma); + + if (vma->page_sizes.gtt != page_size) { + pr_err("page_sizes.gtt=%u, expected %u\n", + vma->page_sizes.gtt, page_size); + err = -EINVAL; + } + + i915_vma_unpin(vma); + + if (err) { + i915_vma_close(vma); + goto out_unpin; + } + + /* + * Try all the other valid offsets until the next + * boundary -- should always fall back to using 4K + * pages. + */ + for (offset = 4096; offset < page_size; offset += 4096) { + err = i915_vma_unbind(vma); + if (err) { + i915_vma_close(vma); + goto out_unpin; + } + + err = i915_vma_pin(vma, 0, 0, flags | offset); + if (err) { + i915_vma_close(vma); + goto out_unpin; + } + + err = igt_check_page_sizes(vma); + + if (vma->page_sizes.gtt != I915_GTT_PAGE_SIZE_4K) { + pr_err("page_sizes.gtt=%u, expected %lu\n", + vma->page_sizes.gtt, I915_GTT_PAGE_SIZE_4K); + err = -EINVAL; + } + + i915_vma_unpin(vma); + + if (err) { + i915_vma_close(vma); + goto out_unpin; + } + + if (igt_timeout(end_time, + "%s timed out at offset %x with page-size %x\n", + __func__, offset, page_size)) + break; + } + + i915_vma_close(vma); + + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); + } + + return 0; + +out_unpin: + i915_gem_object_unpin_pages(obj); +out_put: + i915_gem_object_put(obj); + + return err; +} + +static void close_object_list(struct list_head *objects, + struct i915_hw_ppgtt *ppgtt) +{ + struct drm_i915_gem_object *obj, *on; + + list_for_each_entry_safe(obj, on, objects, st_link) { + struct i915_vma *vma; + + vma = i915_vma_instance(obj, &ppgtt->base, NULL); + if (!IS_ERR(vma)) + i915_vma_close(vma); + + list_del(&obj->st_link); + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); + } +} + +static int igt_mock_ppgtt_huge_fill(void *arg) +{ + struct i915_hw_ppgtt *ppgtt = arg; + struct drm_i915_private *i915 = ppgtt->base.i915; + unsigned long max_pages = ppgtt->base.total >> PAGE_SHIFT; + unsigned long page_num; + bool single = false; + LIST_HEAD(objects); + IGT_TIMEOUT(end_time); + int err; + + for_each_prime_number_from(page_num, 1, max_pages) { + struct drm_i915_gem_object *obj; + u64 size = page_num << PAGE_SHIFT; + struct i915_vma *vma; + unsigned int expected_gtt = 0; + int i; + + obj = fake_huge_pages_object(i915, size, single); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + break; + } + + if (obj->base.size != size) { + pr_err("obj->base.size=%zd, expected=%llu\n", + obj->base.size, size); + i915_gem_object_put(obj); + err = -EINVAL; + break; + } + + err = i915_gem_object_pin_pages(obj); + if (err) { + i915_gem_object_put(obj); + break; + } + + list_add(&obj->st_link, &objects); + + vma = i915_vma_instance(obj, &ppgtt->base, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + break; + } + + err = i915_vma_pin(vma, 0, 0, PIN_USER); + if (err) + break; + + err = igt_check_page_sizes(vma); + if (err) { + i915_vma_unpin(vma); + break; + } + + /* + * Figure out the expected gtt page size knowing that we go from + * largest to smallest page size sg chunks, and that we align to + * the largest page size. + */ + for (i = 0; i < ARRAY_SIZE(page_sizes); ++i) { + unsigned int page_size = page_sizes[i]; + + if (HAS_PAGE_SIZES(i915, page_size) && + size >= page_size) { + expected_gtt |= page_size; + size &= page_size-1; + } + } + + GEM_BUG_ON(!expected_gtt); + GEM_BUG_ON(size); + + if (expected_gtt & I915_GTT_PAGE_SIZE_4K) + expected_gtt &= ~I915_GTT_PAGE_SIZE_64K; + + i915_vma_unpin(vma); + + if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) { + if (!IS_ALIGNED(vma->node.start, + I915_GTT_PAGE_SIZE_2M)) { + pr_err("node.start(%llx) not aligned to 2M\n", + vma->node.start); + err = -EINVAL; + break; + } + + if (!IS_ALIGNED(vma->node.size, + I915_GTT_PAGE_SIZE_2M)) { + pr_err("node.size(%llx) not aligned to 2M\n", + vma->node.size); + err = -EINVAL; + break; + } + } + + if (vma->page_sizes.gtt != expected_gtt) { + pr_err("gtt=%u, expected=%u, size=%zd, single=%s\n", + vma->page_sizes.gtt, expected_gtt, + obj->base.size, yesno(!!single)); + err = -EINVAL; + break; + } + + if (igt_timeout(end_time, + "%s timed out at size %zd\n", + __func__, obj->base.size)) + break; + + single = !single; + } + + close_object_list(&objects, ppgtt); + + if (err == -ENOMEM || err == -ENOSPC) + err = 0; + + return err; +} + +static int igt_mock_ppgtt_64K(void *arg) +{ + struct i915_hw_ppgtt *ppgtt = arg; + struct drm_i915_private *i915 = ppgtt->base.i915; + struct drm_i915_gem_object *obj; + const struct object_info { + unsigned int size; + unsigned int gtt; + unsigned int offset; + } objects[] = { + /* Cases with forced padding/alignment */ + { + .size = SZ_64K, + .gtt = I915_GTT_PAGE_SIZE_64K, + .offset = 0, + }, + { + .size = SZ_64K + SZ_4K, + .gtt = I915_GTT_PAGE_SIZE_4K, + .offset = 0, + }, + { + .size = SZ_64K - SZ_4K, + .gtt = I915_GTT_PAGE_SIZE_4K, + .offset = 0, + }, + { + .size = SZ_2M, + .gtt = I915_GTT_PAGE_SIZE_64K, + .offset = 0, + }, + { + .size = SZ_2M - SZ_4K, + .gtt = I915_GTT_PAGE_SIZE_4K, + .offset = 0, + }, + { + .size = SZ_2M + SZ_4K, + .gtt = I915_GTT_PAGE_SIZE_64K | I915_GTT_PAGE_SIZE_4K, + .offset = 0, + }, + { + .size = SZ_2M + SZ_64K, + .gtt = I915_GTT_PAGE_SIZE_64K, + .offset = 0, + }, + { + .size = SZ_2M - SZ_64K, + .gtt = I915_GTT_PAGE_SIZE_64K, + .offset = 0, + }, + /* Try without any forced padding/alignment */ + { + .size = SZ_64K, + .offset = SZ_2M, + .gtt = I915_GTT_PAGE_SIZE_4K, + }, + { + .size = SZ_128K, + .offset = SZ_2M - SZ_64K, + .gtt = I915_GTT_PAGE_SIZE_4K, + }, + }; + struct i915_vma *vma; + int i, single; + int err; + + /* + * Sanity check some of the trickiness with 64K pages -- either we can + * safely mark the whole page-table(2M block) as 64K, or we have to + * always fallback to 4K. + */ + + if (!HAS_PAGE_SIZES(i915, I915_GTT_PAGE_SIZE_64K)) + return 0; + + for (i = 0; i < ARRAY_SIZE(objects); ++i) { + unsigned int size = objects[i].size; + unsigned int expected_gtt = objects[i].gtt; + unsigned int offset = objects[i].offset; + unsigned int flags = PIN_USER; + + for (single = 0; single <= 1; single++) { + obj = fake_huge_pages_object(i915, size, !!single); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + err = i915_gem_object_pin_pages(obj); + if (err) + goto out_object_put; + + /* + * Disable 2M pages -- We only want to use 64K/4K pages + * for this test. + */ + obj->mm.page_sizes.sg &= ~I915_GTT_PAGE_SIZE_2M; + + vma = i915_vma_instance(obj, &ppgtt->base, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_object_unpin; + } + + if (offset) + flags |= PIN_OFFSET_FIXED | offset; + + err = i915_vma_pin(vma, 0, 0, flags); + if (err) + goto out_vma_close; + + err = igt_check_page_sizes(vma); + if (err) + goto out_vma_unpin; + + if (!offset && vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) { + if (!IS_ALIGNED(vma->node.start, + I915_GTT_PAGE_SIZE_2M)) { + pr_err("node.start(%llx) not aligned to 2M\n", + vma->node.start); + err = -EINVAL; + goto out_vma_unpin; + } + + if (!IS_ALIGNED(vma->node.size, + I915_GTT_PAGE_SIZE_2M)) { + pr_err("node.size(%llx) not aligned to 2M\n", + vma->node.size); + err = -EINVAL; + goto out_vma_unpin; + } + } + + if (vma->page_sizes.gtt != expected_gtt) { + pr_err("gtt=%u, expected=%u, i=%d, single=%s\n", + vma->page_sizes.gtt, expected_gtt, i, + yesno(!!single)); + err = -EINVAL; + goto out_vma_unpin; + } + + i915_vma_unpin(vma); + i915_vma_close(vma); + + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); + } + } + + return 0; + +out_vma_unpin: + i915_vma_unpin(vma); +out_vma_close: + i915_vma_close(vma); +out_object_unpin: + i915_gem_object_unpin_pages(obj); +out_object_put: + i915_gem_object_put(obj); + + return err; +} + +static struct i915_vma * +gpu_write_dw(struct i915_vma *vma, u64 offset, u32 val) +{ + struct drm_i915_private *i915 = to_i915(vma->obj->base.dev); + const int gen = INTEL_GEN(vma->vm->i915); + unsigned int count = vma->size >> PAGE_SHIFT; + struct drm_i915_gem_object *obj; + struct i915_vma *batch; + unsigned int size; + u32 *cmd; + int n; + int err; + + size = (1 + 4 * count) * sizeof(u32); + size = round_up(size, PAGE_SIZE); + obj = i915_gem_object_create_internal(i915, size); + if (IS_ERR(obj)) + return ERR_CAST(obj); + + cmd = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(cmd)) { + err = PTR_ERR(cmd); + goto err; + } + + offset += vma->node.start; + + for (n = 0; n < count; n++) { + if (gen >= 8) { + *cmd++ = MI_STORE_DWORD_IMM_GEN4; + *cmd++ = lower_32_bits(offset); + *cmd++ = upper_32_bits(offset); + *cmd++ = val; + } else if (gen >= 4) { + *cmd++ = MI_STORE_DWORD_IMM_GEN4 | + (gen < 6 ? 1 << 22 : 0); + *cmd++ = 0; + *cmd++ = offset; + *cmd++ = val; + } else { + *cmd++ = MI_STORE_DWORD_IMM | 1 << 22; + *cmd++ = offset; + *cmd++ = val; + } + + offset += PAGE_SIZE; + } + + *cmd = MI_BATCH_BUFFER_END; + + i915_gem_object_unpin_map(obj); + + err = i915_gem_object_set_to_gtt_domain(obj, false); + if (err) + goto err; + + batch = i915_vma_instance(obj, vma->vm, NULL); + if (IS_ERR(batch)) { + err = PTR_ERR(batch); + goto err; + } + + err = i915_vma_pin(batch, 0, 0, PIN_USER); + if (err) + goto err; + + return batch; + +err: + i915_gem_object_put(obj); + + return ERR_PTR(err); +} + +static int gpu_write(struct i915_vma *vma, + struct i915_gem_context *ctx, + struct intel_engine_cs *engine, + u32 dword, + u32 value) +{ + struct drm_i915_gem_request *rq; + struct i915_vma *batch; + int flags = 0; + int err; + + GEM_BUG_ON(!intel_engine_can_store_dword(engine)); + + err = i915_gem_object_set_to_gtt_domain(vma->obj, true); + if (err) + return err; + + rq = i915_gem_request_alloc(engine, ctx); + if (IS_ERR(rq)) + return PTR_ERR(rq); + + batch = gpu_write_dw(vma, dword * sizeof(u32), value); + if (IS_ERR(batch)) { + err = PTR_ERR(batch); + goto err_request; + } + + i915_vma_move_to_active(batch, rq, 0); + i915_gem_object_set_active_reference(batch->obj); + i915_vma_unpin(batch); + i915_vma_close(batch); + + err = rq->engine->emit_flush(rq, EMIT_INVALIDATE); + if (err) + goto err_request; + + err = i915_switch_context(rq); + if (err) + goto err_request; + + err = rq->engine->emit_bb_start(rq, + batch->node.start, batch->node.size, + flags); + if (err) + goto err_request; + + i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE); + + reservation_object_lock(vma->resv, NULL); + reservation_object_add_excl_fence(vma->resv, &rq->fence); + reservation_object_unlock(vma->resv); + +err_request: + __i915_add_request(rq, err == 0); + + return err; +} + +static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val) +{ + unsigned int needs_flush; + unsigned long n; + int err; + + err = i915_gem_obj_prepare_shmem_read(obj, &needs_flush); + if (err) + return err; + + for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) { + u32 *ptr = kmap_atomic(i915_gem_object_get_page(obj, n)); + + if (needs_flush & CLFLUSH_BEFORE) + drm_clflush_virt_range(ptr, PAGE_SIZE); + + if (ptr[dword] != val) { + pr_err("n=%lu ptr[%u]=%u, val=%u\n", + n, dword, ptr[dword], val); + kunmap_atomic(ptr); + err = -EINVAL; + break; + } + + kunmap_atomic(ptr); + } + + i915_gem_obj_finish_shmem_access(obj); + + return err; +} + +static int igt_write_huge(struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct i915_gem_context *ctx = i915->kernel_context; + struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base; + struct intel_engine_cs *engine; + struct i915_vma *vma; + unsigned int flags = PIN_USER | PIN_OFFSET_FIXED; + unsigned int max_page_size; + unsigned int id; + u64 max; + u64 num; + u64 size; + int err = 0; + + GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); + + size = obj->base.size; + if (obj->mm.page_sizes.sg & I915_GTT_PAGE_SIZE_64K) + size = round_up(size, I915_GTT_PAGE_SIZE_2M); + + max_page_size = rounddown_pow_of_two(obj->mm.page_sizes.sg); + max = div_u64((vm->total - size), max_page_size); + + vma = i915_vma_instance(obj, vm, NULL); + if (IS_ERR(vma)) + return PTR_ERR(vma); + + for_each_engine(engine, i915, id) { + IGT_TIMEOUT(end_time); + + if (!intel_engine_can_store_dword(engine)) { + pr_info("store-dword-imm not supported on engine=%u\n", + id); + continue; + } + + /* + * Try various offsets until we timeout -- we want to avoid + * issues hidden by effectively always using offset = 0. + */ + for_each_prime_number_from(num, 0, max) { + u64 offset = num * max_page_size; + u32 dword; + + err = i915_vma_unbind(vma); + if (err) + goto out_vma_close; + + err = i915_vma_pin(vma, size, max_page_size, flags | offset); + if (err) { + /* + * The ggtt may have some pages reserved so + * refrain from erroring out. + */ + if (err == -ENOSPC && i915_is_ggtt(vm)) { + err = 0; + continue; + } + + goto out_vma_close; + } + + err = igt_check_page_sizes(vma); + if (err) + goto out_vma_unpin; + + dword = offset_in_page(num) / 4; + + err = gpu_write(vma, ctx, engine, dword, num + 1); + if (err) { + pr_err("gpu-write failed at offset=%llx", offset); + goto out_vma_unpin; + } + + err = cpu_check(obj, dword, num + 1); + if (err) { + pr_err("cpu-check failed at offset=%llx", offset); + goto out_vma_unpin; + } + + i915_vma_unpin(vma); + + if (num > 0 && + igt_timeout(end_time, + "%s timed out on engine=%u at offset=%llx, max_page_size=%x\n", + __func__, id, offset, max_page_size)) + break; + } + } + +out_vma_unpin: + if (i915_vma_is_pinned(vma)) + i915_vma_unpin(vma); +out_vma_close: + i915_vma_close(vma); + + return err; +} + +static int igt_ppgtt_exhaust_huge(void *arg) +{ + struct drm_i915_private *i915 = arg; + unsigned long supported = INTEL_INFO(i915)->page_sizes; + static unsigned int pages[ARRAY_SIZE(page_sizes)]; + struct drm_i915_gem_object *obj; + unsigned int size_mask; + unsigned int page_mask; + int n, i; + int err; + + /* + * Sanity check creating objects with a varying mix of page sizes -- + * ensuring that our writes lands in the right place. + */ + + n = 0; + for_each_set_bit(i, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) + pages[n++] = BIT(i); + + for (size_mask = 2; size_mask < BIT(n); size_mask++) { + unsigned int size = 0; + + for (i = 0; i < n; i++) { + if (size_mask & BIT(i)) + size |= pages[i]; + } + + /* + * For our page mask we want to enumerate all the page-size + * combinations which will fit into our chosen object size. + */ + for (page_mask = 2; page_mask <= size_mask; page_mask++) { + unsigned int page_sizes = 0; + + for (i = 0; i < n; i++) { + if (page_mask & BIT(i)) + page_sizes |= pages[i]; + } + + /* + * Ensure that we can actually fill the given object + * with our chosen page mask. + */ + if (!IS_ALIGNED(size, BIT(__ffs(page_sizes)))) + continue; + + obj = huge_pages_object(i915, size, page_sizes); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto out_device; + } + + err = i915_gem_object_pin_pages(obj); + if (err) { + i915_gem_object_put(obj); + + if (err == -ENOMEM) { + pr_info("unable to get pages, size=%u, pages=%u\n", + size, page_sizes); + err = 0; + break; + } + + pr_err("pin_pages failed, size=%u, pages=%u\n", + size_mask, page_mask); + + goto out_device; + } + + /* Force the page-size for the gtt insertion */ + obj->mm.page_sizes.sg = page_sizes; + + err = igt_write_huge(obj); + if (err) { + pr_err("exhaust write-huge failed with size=%u\n", + size); + goto out_unpin; + } + + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); + } + } + + goto out_device; + +out_unpin: + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); +out_device: + mkwrite_device_info(i915)->page_sizes = supported; + + return err; +} + +static int igt_ppgtt_internal_huge(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_object *obj; + static const unsigned int sizes[] = { + SZ_64K, + SZ_128K, + SZ_256K, + SZ_512K, + SZ_1M, + SZ_2M, + }; + int i; + int err; + + /* + * Sanity check that the HW uses huge pages correctly through internal + * -- ensure that our writes land in the right place. + */ + + for (i = 0; i < ARRAY_SIZE(sizes); ++i) { + unsigned int size = sizes[i]; + + obj = i915_gem_object_create_internal(i915, size); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + err = i915_gem_object_pin_pages(obj); + if (err) + goto out_put; + + if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_64K) { + pr_info("internal unable to allocate huge-page(s) with size=%u\n", + size); + goto out_unpin; + } + + err = igt_write_huge(obj); + if (err) { + pr_err("internal write-huge failed with size=%u\n", + size); + goto out_unpin; + } + + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); + } + + return 0; + +out_unpin: + i915_gem_object_unpin_pages(obj); +out_put: + i915_gem_object_put(obj); + + return err; +} + +static inline bool igt_can_allocate_thp(struct drm_i915_private *i915) +{ + return i915->mm.gemfs && has_transparent_hugepage(); +} + +static int igt_ppgtt_gemfs_huge(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_object *obj; + static const unsigned int sizes[] = { + SZ_2M, + SZ_4M, + SZ_8M, + SZ_16M, + SZ_32M, + }; + int i; + int err; + + /* + * Sanity check that the HW uses huge pages correctly through gemfs -- + * ensure that our writes land in the right place. + */ + + if (!igt_can_allocate_thp(i915)) { + pr_info("missing THP support, skipping\n"); + return 0; + } + + for (i = 0; i < ARRAY_SIZE(sizes); ++i) { + unsigned int size = sizes[i]; + + obj = i915_gem_object_create(i915, size); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + err = i915_gem_object_pin_pages(obj); + if (err) + goto out_put; + + if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_2M) { + pr_info("finishing test early, gemfs unable to allocate huge-page(s) with size=%u\n", + size); + goto out_unpin; + } + + err = igt_write_huge(obj); + if (err) { + pr_err("gemfs write-huge failed with size=%u\n", + size); + goto out_unpin; + } + + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); + } + + return 0; + +out_unpin: + i915_gem_object_unpin_pages(obj); +out_put: + i915_gem_object_put(obj); + + return err; +} + +static int igt_ppgtt_pin_update(void *arg) +{ + struct drm_i915_private *dev_priv = arg; + unsigned long supported = INTEL_INFO(dev_priv)->page_sizes; + struct i915_hw_ppgtt *ppgtt = dev_priv->kernel_context->ppgtt; + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + unsigned int flags = PIN_USER | PIN_OFFSET_FIXED; + int first, last; + int err; + + /* + * Make sure there's no funny business when doing a PIN_UPDATE -- in the + * past we had a subtle issue with being able to incorrectly do multiple + * alloc va ranges on the same object when doing a PIN_UPDATE, which + * resulted in some pretty nasty bugs, though only when using + * huge-gtt-pages. + */ + + if (!USES_FULL_48BIT_PPGTT(dev_priv)) { + pr_info("48b PPGTT not supported, skipping\n"); + return 0; + } + + first = ilog2(I915_GTT_PAGE_SIZE_64K); + last = ilog2(I915_GTT_PAGE_SIZE_2M); + + for_each_set_bit_from(first, &supported, last + 1) { + unsigned int page_size = BIT(first); + + obj = i915_gem_object_create_internal(dev_priv, page_size); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + vma = i915_vma_instance(obj, &ppgtt->base, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } + + err = i915_vma_pin(vma, SZ_2M, 0, flags); + if (err) + goto out_close; + + if (vma->page_sizes.sg < page_size) { + pr_info("Unable to allocate page-size %x, finishing test early\n", + page_size); + goto out_unpin; + } + + err = igt_check_page_sizes(vma); + if (err) + goto out_unpin; + + if (vma->page_sizes.gtt != page_size) { + dma_addr_t addr = i915_gem_object_get_dma_address(obj, 0); + + /* + * The only valid reason for this to ever fail would be + * if the dma-mapper screwed us over when we did the + * dma_map_sg(), since it has the final say over the dma + * address. + */ + if (IS_ALIGNED(addr, page_size)) { + pr_err("page_sizes.gtt=%u, expected=%u\n", + vma->page_sizes.gtt, page_size); + err = -EINVAL; + } else { + pr_info("dma address misaligned, finishing test early\n"); + } + + goto out_unpin; + } + + err = i915_vma_bind(vma, I915_CACHE_NONE, PIN_UPDATE); + if (err) + goto out_unpin; + + i915_vma_unpin(vma); + i915_vma_close(vma); + + i915_gem_object_put(obj); + } + + obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + vma = i915_vma_instance(obj, &ppgtt->base, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } + + err = i915_vma_pin(vma, 0, 0, flags); + if (err) + goto out_close; + + /* + * Make sure we don't end up with something like where the pde is still + * pointing to the 2M page, and the pt we just filled-in is dangling -- + * we can check this by writing to the first page where it would then + * land in the now stale 2M page. + */ + + err = gpu_write(vma, dev_priv->kernel_context, dev_priv->engine[RCS], + 0, 0xdeadbeaf); + if (err) + goto out_unpin; + + err = cpu_check(obj, 0, 0xdeadbeaf); + +out_unpin: + i915_vma_unpin(vma); +out_close: + i915_vma_close(vma); +out_put: + i915_gem_object_put(obj); + + return err; +} + +static int igt_tmpfs_fallback(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct vfsmount *gemfs = i915->mm.gemfs; + struct i915_gem_context *ctx = i915->kernel_context; + struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base; + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + u32 *vaddr; + int err = 0; + + /* + * Make sure that we don't burst into a ball of flames upon falling back + * to tmpfs, which we rely on if on the off-chance we encouter a failure + * when setting up gemfs. + */ + + i915->mm.gemfs = NULL; + + obj = i915_gem_object_create(i915, PAGE_SIZE); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto out_restore; + } + + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto out_put; + } + *vaddr = 0xdeadbeaf; + + i915_gem_object_unpin_map(obj); + + vma = i915_vma_instance(obj, vm, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } + + err = i915_vma_pin(vma, 0, 0, PIN_USER); + if (err) + goto out_close; + + err = igt_check_page_sizes(vma); + + i915_vma_unpin(vma); +out_close: + i915_vma_close(vma); +out_put: + i915_gem_object_put(obj); +out_restore: + i915->mm.gemfs = gemfs; + + return err; +} + +static int igt_shrink_thp(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx = i915->kernel_context; + struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base; + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + unsigned int flags = PIN_USER; + int err; + + /* + * Sanity check shrinking huge-paged object -- make sure nothing blows + * up. + */ + + if (!igt_can_allocate_thp(i915)) { + pr_info("missing THP support, skipping\n"); + return 0; + } + + obj = i915_gem_object_create(i915, SZ_2M); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + vma = i915_vma_instance(obj, vm, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto out_put; + } + + err = i915_vma_pin(vma, 0, 0, flags); + if (err) + goto out_close; + + if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_2M) { + pr_info("failed to allocate THP, finishing test early\n"); + goto out_unpin; + } + + err = igt_check_page_sizes(vma); + if (err) + goto out_unpin; + + err = gpu_write(vma, i915->kernel_context, i915->engine[RCS], 0, + 0xdeadbeaf); + if (err) + goto out_unpin; + + i915_vma_unpin(vma); + + /* + * Now that the pages are *unpinned* shrink-all should invoke + * shmem to truncate our pages. + */ + i915_gem_shrink_all(i915); + if (!IS_ERR_OR_NULL(obj->mm.pages)) { + pr_err("shrink-all didn't truncate the pages\n"); + err = -EINVAL; + goto out_close; + } + + if (obj->mm.page_sizes.sg || obj->mm.page_sizes.phys) { + pr_err("residual page-size bits left\n"); + err = -EINVAL; + goto out_close; + } + + err = i915_vma_pin(vma, 0, 0, flags); + if (err) + goto out_close; + + err = cpu_check(obj, 0, 0xdeadbeaf); + +out_unpin: + i915_vma_unpin(vma); +out_close: + i915_vma_close(vma); +out_put: + i915_gem_object_put(obj); + + return err; +} + +int i915_gem_huge_page_mock_selftests(void) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_mock_exhaust_device_supported_pages), + SUBTEST(igt_mock_ppgtt_misaligned_dma), + SUBTEST(igt_mock_ppgtt_huge_fill), + SUBTEST(igt_mock_ppgtt_64K), + }; + int saved_ppgtt = i915_modparams.enable_ppgtt; + struct drm_i915_private *dev_priv; + struct pci_dev *pdev; + struct i915_hw_ppgtt *ppgtt; + int err; + + dev_priv = mock_gem_device(); + if (!dev_priv) + return -ENOMEM; + + /* Pretend to be a device which supports the 48b PPGTT */ + i915_modparams.enable_ppgtt = 3; + + pdev = dev_priv->drm.pdev; + dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(39)); + + mutex_lock(&dev_priv->drm.struct_mutex); + ppgtt = i915_ppgtt_create(dev_priv, ERR_PTR(-ENODEV), "mock"); + if (IS_ERR(ppgtt)) { + err = PTR_ERR(ppgtt); + goto out_unlock; + } + + if (!i915_vm_is_48bit(&ppgtt->base)) { + pr_err("failed to create 48b PPGTT\n"); + err = -EINVAL; + goto out_close; + } + + /* If we were ever hit this then it's time to mock the 64K scratch */ + if (!i915_vm_has_scratch_64K(&ppgtt->base)) { + pr_err("PPGTT missing 64K scratch page\n"); + err = -EINVAL; + goto out_close; + } + + err = i915_subtests(tests, ppgtt); + +out_close: + i915_ppgtt_close(&ppgtt->base); + i915_ppgtt_put(ppgtt); + +out_unlock: + mutex_unlock(&dev_priv->drm.struct_mutex); + + i915_modparams.enable_ppgtt = saved_ppgtt; + + drm_dev_unref(&dev_priv->drm); + + return err; +} + +int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_shrink_thp), + SUBTEST(igt_ppgtt_pin_update), + SUBTEST(igt_tmpfs_fallback), + SUBTEST(igt_ppgtt_exhaust_huge), + SUBTEST(igt_ppgtt_gemfs_huge), + SUBTEST(igt_ppgtt_internal_huge), + }; + int err; + + if (!USES_PPGTT(dev_priv)) { + pr_info("PPGTT not supported, skipping live-selftests\n"); + return 0; + } + + mutex_lock(&dev_priv->drm.struct_mutex); + err = i915_subtests(tests, dev_priv); + mutex_unlock(&dev_priv->drm.struct_mutex); + + return err; +} diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h index 18b174d855ca..64acd7eccc5c 100644 --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h @@ -15,5 +15,6 @@ selftest(objects, i915_gem_object_live_selftests) selftest(dmabuf, i915_gem_dmabuf_live_selftests) selftest(coherency, i915_gem_coherency_live_selftests) selftest(gtt, i915_gem_gtt_live_selftests) +selftest(hugepages, i915_gem_huge_page_live_selftests) selftest(contexts, i915_gem_context_live_selftests) selftest(hangcheck, intel_hangcheck_live_selftests) diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h index fc74687501ba..9961b44f76ed 100644 --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h @@ -21,3 +21,4 @@ selftest(dmabuf, i915_gem_dmabuf_mock_selftests) selftest(vma, i915_vma_mock_selftests) selftest(evict, i915_gem_evict_mock_selftests) selftest(gtt, i915_gem_gtt_mock_selftests) +selftest(hugepages, i915_gem_huge_page_mock_selftests) -- cgit v1.2.3 From 7924d9d4dc9ffff32bf099db8c638e11e5457cd7 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:30 +0100 Subject: drm/i915/selftests: mix huge pages Try to mix sg page sizes for 4K, 64K and 2M pages. v2: s/BIT(x) >> 12/BIT(x) >> PAGE_SHIFT/ Suggested-by: Chris Wilson Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-19-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-18-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/selftests/scatterlist.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c index 1cc5d2931753..cd6d2a16071f 100644 --- a/drivers/gpu/drm/i915/selftests/scatterlist.c +++ b/drivers/gpu/drm/i915/selftests/scatterlist.c @@ -189,6 +189,20 @@ static unsigned int random(unsigned long n, return 1 + (prandom_u32_state(rnd) % 1024); } +static unsigned int random_page_size_pages(unsigned long n, + unsigned long count, + struct rnd_state *rnd) +{ + /* 4K, 64K, 2M */ + static unsigned int page_count[] = { + BIT(12) >> PAGE_SHIFT, + BIT(16) >> PAGE_SHIFT, + BIT(21) >> PAGE_SHIFT, + }; + + return page_count[(prandom_u32_state(rnd) % 3)]; +} + static inline bool page_contiguous(struct page *first, struct page *last, unsigned long npages) @@ -252,6 +266,7 @@ static const npages_fn_t npages_funcs[] = { grow, shrink, random, + random_page_size_pages, NULL, }; -- cgit v1.2.3 From da9fe3f31a920658debd231ff10b0fbe0f2f34ed Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:31 +0100 Subject: drm/i915: disable platform support for vGPU huge gtt pages Currently gvt gtt handling doesn't support huge page entries, so disable for now. v2: remove useless 48b PPGTT check Suggested-by: Zhenyu Wang Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Zhenyu Wang Reviewed-by: Zhenyu Wang Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-20-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-19-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f8c3ac1c8c67..82a10036fb38 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4822,6 +4822,15 @@ int i915_gem_init(struct drm_i915_private *dev_priv) mutex_lock(&dev_priv->drm.struct_mutex); + /* + * We need to fallback to 4K pages since gvt gtt handling doesn't + * support huge page entries - we will need to check either hypervisor + * mm can support huge guest page or just do emulation in gvt. + */ + if (intel_vgpu_active(dev_priv)) + mkwrite_device_info(dev_priv)->page_sizes = + I915_GTT_PAGE_SIZE_4K; + dev_priv->mm.unordered_timeline = dma_fence_context_alloc(1); if (!i915_modparams.enable_execlists) { -- cgit v1.2.3 From f1f3f98272b9bb1ba87c2ccbc811b038574cec43 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:32 +0100 Subject: drm/i915: enable platform support for 64K pages For gen9+ enable platform level support for 64K pages. Also enable for mock testing. Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-21-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-20-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_pci.c | 3 ++- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 7938006cf03a..8d349aec1902 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -436,7 +436,8 @@ static const struct intel_device_info intel_cherryview_info __initconst = { }; #define GEN9_DEFAULT_PAGE_SIZES \ - .page_sizes = I915_GTT_PAGE_SIZE_4K + .page_sizes = I915_GTT_PAGE_SIZE_4K | \ + I915_GTT_PAGE_SIZE_64K #define GEN9_FEATURES \ GEN8_FEATURES, \ diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index f46c3a35d61a..7a9735dac912 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -175,7 +175,8 @@ struct drm_i915_private *mock_gem_device(void) mkwrite_device_info(i915)->gen = -1; mkwrite_device_info(i915)->page_sizes = - I915_GTT_PAGE_SIZE_4K; + I915_GTT_PAGE_SIZE_4K | + I915_GTT_PAGE_SIZE_64K; spin_lock_init(&i915->mm.object_stat_lock); mock_uncore_init(i915); -- cgit v1.2.3 From a883241c3922000b21b58b5740c55badfe09940f Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Fri, 6 Oct 2017 23:18:33 +0100 Subject: drm/i915: enable platform support for 2M pages For gen8+ platforms which support the 48b PPGTT, enable platform level support for 2M pages. Also enable for mock testing. Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006145041.21673-22-matthew.auld@intel.com Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171006221833.32439-21-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_pci.c | 6 ++++-- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 8d349aec1902..bf467f30c99b 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -376,7 +376,8 @@ static const struct intel_device_info intel_haswell_gt3_info __initconst = { #define GEN8_FEATURES \ G75_FEATURES, \ BDW_COLORS, \ - GEN_DEFAULT_PAGE_SIZES, \ + .page_sizes = I915_GTT_PAGE_SIZE_4K | \ + I915_GTT_PAGE_SIZE_2M, \ .has_logical_ring_contexts = 1, \ .has_full_48bit_ppgtt = 1, \ .has_64bit_reloc = 1, \ @@ -437,7 +438,8 @@ static const struct intel_device_info intel_cherryview_info __initconst = { #define GEN9_DEFAULT_PAGE_SIZES \ .page_sizes = I915_GTT_PAGE_SIZE_4K | \ - I915_GTT_PAGE_SIZE_64K + I915_GTT_PAGE_SIZE_64K | \ + I915_GTT_PAGE_SIZE_2M #define GEN9_FEATURES \ GEN8_FEATURES, \ diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 7a9735dac912..04eb9362f4f8 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -176,7 +176,8 @@ struct drm_i915_private *mock_gem_device(void) mkwrite_device_info(i915)->page_sizes = I915_GTT_PAGE_SIZE_4K | - I915_GTT_PAGE_SIZE_64K; + I915_GTT_PAGE_SIZE_64K | + I915_GTT_PAGE_SIZE_2M; spin_lock_init(&i915->mm.object_stat_lock); mock_uncore_init(i915); -- cgit v1.2.3 From 80ac93c274411a55ae731f259f75e4ca5e499e8b Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Tue, 3 Oct 2017 11:17:05 -0500 Subject: gpio: omap: Fix lost edge interrupts Now acking of edge irqs happens the following way: - omap_gpio_irq_handler - "isr" = read irq status - omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask); ^ clear edge status, so irq can be accepted - loop while "isr" generic_handle_irq() - handle_edge_irq() - desc->irq_data.chip->irq_ack(&desc->irq_data); - omap_gpio_ack_irq() it might be that at this moment edge IRQ was triggered again and it will be cleared and IRQ will be lost. Use handle_simple_irq and clear edge interrupts early without disabling them in omap_gpio_irq_handler to avoid loosing interrupts. [1] https://marc.info/?l=linux-omap&m=149004465313534&w=2 Signed-off-by: Grygorii Strashko Signed-off-by: Ladislav Michl Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 22d7d4838265..3233b72b6828 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -518,7 +518,13 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type) if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) irq_set_handler_locked(d, handle_level_irq); else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) - irq_set_handler_locked(d, handle_edge_irq); + /* + * Edge IRQs are already cleared/acked in irq_handler and + * not need to be masked, as result handle_edge_irq() + * logic is excessed here and may cause lose of interrupts. + * So just use handle_simple_irq. + */ + irq_set_handler_locked(d, handle_simple_irq); return 0; @@ -678,7 +684,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) { void __iomem *isr_reg = NULL; - u32 isr; + u32 enabled, isr, level_mask; unsigned int bit; struct gpio_bank *bank = gpiobank; unsigned long wa_lock_flags; @@ -691,23 +697,21 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) pm_runtime_get_sync(bank->chip.parent); while (1) { - u32 isr_saved, level_mask = 0; - u32 enabled; - raw_spin_lock_irqsave(&bank->lock, lock_flags); enabled = omap_get_gpio_irqbank_mask(bank); - isr_saved = isr = readl_relaxed(isr_reg) & enabled; + isr = readl_relaxed(isr_reg) & enabled; if (bank->level_mask) level_mask = bank->level_mask & enabled; + else + level_mask = 0; /* clear edge sensitive interrupts before handler(s) are called so that we don't miss any interrupt occurred while executing them */ - omap_disable_gpio_irqbank(bank, isr_saved & ~level_mask); - omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask); - omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask); + if (isr & ~level_mask) + omap_clear_gpio_irqbank(bank, isr & ~level_mask); raw_spin_unlock_irqrestore(&bank->lock, lock_flags); -- cgit v1.2.3 From 845e405e5e6c9dc9ed10306a4b5bfeaefebc2e84 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Tue, 3 Oct 2017 12:00:49 -0500 Subject: pinctrl: cherryview: fix issues caused by dynamic gpio irqs mapping New GPIO IRQs are allocated and mapped dynamically by default when GPIO IRQ infrastructure is used by cherryview-pinctrl driver. This causes issues on some Intel platforms [1][2] with broken BIOS which hardcodes Linux IRQ numbers in their ACPI tables. On such platforms cherryview-pinctrl driver should allocate and map all GPIO IRQs at probe time. Side effect - "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n" can be seen at boot log. NOTE. It still may fail if boot sequence will changed and some interrupt controller will be probed before cherryview-pinctrl which will shift Linux IRQ numbering (expected with CONFIG_SPARCE_IRQ enabled). [1] https://bugzilla.kernel.org/show_bug.cgi?id=194945 [2] https://lkml.org/lkml/2017/9/28/153 Cc: Andy Shevchenko Cc: Chris Gorman Cc: Mika Westerberg Cc: Heikki Krogerus Signed-off-by: Grygorii Strashko Reported-by: Chris Gorman Reported-by: Mika Westerberg Tested-by: Chris Gorman Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/pinctrl-cherryview.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 04e929fd0ffe..fadbca907c7c 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1577,6 +1577,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) struct gpio_chip *chip = &pctrl->chip; bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); int ret, i, offset; + int irq_base; *chip = chv_gpio_chip; @@ -1622,7 +1623,18 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) /* Clear all interrupts */ chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); - ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, + if (!need_valid_mask) { + irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, + chip->ngpio, NUMA_NO_NODE); + if (irq_base < 0) { + dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); + return irq_base; + } + } else { + irq_base = 0; + } + + ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, irq_base, handle_bad_irq, IRQ_TYPE_NONE); if (ret) { dev_err(pctrl->dev, "failed to add IRQ chip\n"); -- cgit v1.2.3 From 5151b4afb41dd7c5e13a130efcc95326a49da8c6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 7 Oct 2017 16:53:20 -0700 Subject: iio: adc: dln2-adc: fix build error The dln2-adc driver uses interface(s) that are controlled by the IIO_TRIGGERED_BUFFER Kconfig symbol, so the driver needs to select that symbol to prevent the build error. drivers/iio/adc/dln2-adc.o: In function `dln2_adc_probe': dln2-adc.c:(.text+0x528): undefined reference to `devm_iio_triggered_buffer_setup' Signed-off-by: Randy Dunlap Reported-by: kbuild test robot Cc: Jonathan Cameron Cc: linux-iio@vger.kernel.org Cc: Jack Andersen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 57625653fcb6..1d13bf03c758 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -243,6 +243,8 @@ config DA9150_GPADC config DLN2_ADC tristate "Diolan DLN-2 ADC driver support" depends on MFD_DLN2 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Diolan DLN-2 ADC. -- cgit v1.2.3 From a69518cf0b4cbf02c6bc1239cdeb8750a9eb8077 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sun, 8 Oct 2017 11:53:26 +0200 Subject: mlxsw: spectrum_router: Avoid expensive lookup during route removal In commit fc922bb0dd94 ("mlxsw: spectrum_router: Use one LPM tree for all virtual routers") I increased the scale of supported VRFs by having all of them share the same LPM tree. In order to avoid look-ups for prefix lengths that don't exist, each route removal would trigger an aggregation across all the active virtual routers to see which prefix lengths are in use and which aren't and structure the tree accordingly. With the way the data structures are currently laid out, this is a very expensive operation. When preformed repeatedly - due to the invocation of the abort mechanism - and with enough VRFs, this can result in a hung task. For now, avoid this optimization until it can be properly re-added in net-next. Fixes: fc922bb0dd94 ("mlxsw: spectrum_router: Use one LPM tree for all virtual routers") Signed-off-by: Ido Schimmel Reported-by: David Ahern Tested-by: David Ahern Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 032089efc1a0..c16718d296d3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -3505,20 +3505,6 @@ static int mlxsw_sp_fib_lpm_tree_link(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp_fib_lpm_tree_unlink(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fib *fib) { - struct mlxsw_sp_prefix_usage req_prefix_usage = {{ 0 } }; - struct mlxsw_sp_lpm_tree *lpm_tree; - - /* Aggregate prefix lengths across all virtual routers to make - * sure we only have used prefix lengths in the LPM tree. - */ - mlxsw_sp_vrs_prefixes(mlxsw_sp, fib->proto, &req_prefix_usage); - lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage, - fib->proto); - if (IS_ERR(lpm_tree)) - goto err_tree_get; - mlxsw_sp_vrs_lpm_tree_replace(mlxsw_sp, fib, lpm_tree); - -err_tree_get: if (!mlxsw_sp_prefix_usage_none(&fib->prefix_usage)) return; mlxsw_sp_vr_lpm_tree_unbind(mlxsw_sp, fib); -- cgit v1.2.3 From c3b16f16a4dffd8516a2020ce2539ebf8b2d6e33 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 29 Sep 2017 10:07:40 -0400 Subject: drm/radeon: move ci_send_msg_to_smc to where it's used It's used in ci_dpm.c so move it there and make it static. Reviewed-by: Rodrigo Vivi Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/radeon/ci_dpm.h | 1 - drivers/gpu/drm/radeon/ci_smc.c | 21 --------------------- 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index c97fbb2ab48b..7e1b04dc5593 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -184,6 +184,7 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev, u32 target_tdp); static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate); +static PPSMC_Result ci_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg); static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev, PPSMC_Msg msg, u32 parameter); @@ -1651,6 +1652,27 @@ static int ci_notify_hw_of_power_source(struct radeon_device *rdev, } #endif +static PPSMC_Result ci_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg) +{ + u32 tmp; + int i; + + if (!ci_is_smc_running(rdev)) + return PPSMC_Result_Failed; + + WREG32(SMC_MESSAGE_0, msg); + + for (i = 0; i < rdev->usec_timeout; i++) { + tmp = RREG32(SMC_RESP_0); + if (tmp != 0) + break; + udelay(1); + } + tmp = RREG32(SMC_RESP_0); + + return (PPSMC_Result)tmp; +} + static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev, PPSMC_Msg msg, u32 parameter) { diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h index 723220ffbea2..dff2a63df38f 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.h +++ b/drivers/gpu/drm/radeon/ci_dpm.h @@ -330,7 +330,6 @@ int ci_program_jump_on_start(struct radeon_device *rdev); void ci_stop_smc_clock(struct radeon_device *rdev); void ci_start_smc_clock(struct radeon_device *rdev); bool ci_is_smc_running(struct radeon_device *rdev); -PPSMC_Result ci_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg); PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev); int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit); int ci_read_smc_sram_dword(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c index 3356a21d97ec..371121913756 100644 --- a/drivers/gpu/drm/radeon/ci_smc.c +++ b/drivers/gpu/drm/radeon/ci_smc.c @@ -163,27 +163,6 @@ bool ci_is_smc_running(struct radeon_device *rdev) return false; } -PPSMC_Result ci_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg) -{ - u32 tmp; - int i; - - if (!ci_is_smc_running(rdev)) - return PPSMC_Result_Failed; - - WREG32(SMC_MESSAGE_0, msg); - - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(SMC_RESP_0); - if (tmp != 0) - break; - udelay(1); - } - tmp = RREG32(SMC_RESP_0); - - return (PPSMC_Result)tmp; -} - #if 0 PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev) { -- cgit v1.2.3 From d3f04c98ead2b89887e1e3c09b26e4917bacdd9e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 29 Sep 2017 11:35:52 -0400 Subject: drm/radeon/dp: make radeon_dp_get_dp_link_config static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not used outside this file any longer. Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_dp.c | 8 ++++---- drivers/gpu/drm/radeon/radeon_mode.h | 4 ---- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 432cb46f6a34..a904c80c30e6 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -304,10 +304,10 @@ static int convert_bpc_to_bpp(int bpc) /***** radeon specific DP functions *****/ -int radeon_dp_get_dp_link_config(struct drm_connector *connector, - const u8 dpcd[DP_DPCD_SIZE], - unsigned pix_clock, - unsigned *dp_lanes, unsigned *dp_rate) +static int radeon_dp_get_dp_link_config(struct drm_connector *connector, + const u8 dpcd[DP_DPCD_SIZE], + unsigned pix_clock, + unsigned *dp_lanes, unsigned *dp_rate) { int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); static const unsigned link_rates[3] = { 162000, 270000, 540000 }; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index da44ac234f64..ca0a7ed28c9b 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -762,10 +762,6 @@ extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, struct drm_connector *connector); -extern int radeon_dp_get_dp_link_config(struct drm_connector *connector, - const u8 *dpcd, - unsigned pix_clock, - unsigned *dp_lanes, unsigned *dp_rate); extern void radeon_dp_set_rx_power_state(struct drm_connector *connector, u8 power_state); extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector); -- cgit v1.2.3 From bd998c2e0df0469707503023d50d46cf0b10c787 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Oct 2017 11:01:12 +0200 Subject: USB: serial: console: fix use-after-free on disconnect A clean-up patch removing two redundant NULL-checks from the console disconnect handler inadvertently also removed a third check. This could lead to the struct usb_serial being prematurely freed by the console code when a driver accepts but does not register any ports for an interface which also lacks endpoint descriptors. Fixes: 0e517c93dc02 ("USB: serial: console: clean up sanity checks") Cc: stable # 4.11 Reported-by: Andrey Konovalov Acked-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index fdf89800ebc3..ed8ba3ef5c79 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -265,7 +265,7 @@ static struct console usbcons = { void usb_serial_console_disconnect(struct usb_serial *serial) { - if (serial->port[0] == usbcons_info.port) { + if (serial->port[0] && serial->port[0] == usbcons_info.port) { usb_serial_console_exit(); usb_serial_put(serial); } -- cgit v1.2.3 From 299d7572e46f98534033a9e65973f13ad1ce9047 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Oct 2017 11:01:13 +0200 Subject: USB: serial: console: fix use-after-free after failed setup Make sure to reset the USB-console port pointer when console setup fails in order to avoid having the struct usb_serial be prematurely freed by the console code when the device is later disconnected. Fixes: 73e487fdb75f ("[PATCH] USB console: fix disconnection issues") Cc: stable # 2.6.18 Acked-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/console.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index ed8ba3ef5c79..43a862a90a77 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -186,6 +186,7 @@ static int usb_console_setup(struct console *co, char *options) tty_kref_put(tty); reset_open_count: port->port.count = 0; + info->port = NULL; usb_autopm_put_interface(serial->interface); error_get_interface: usb_serial_put(serial); -- cgit v1.2.3 From 78279127253a6c36ed8829eb2b7bc28ef48d9717 Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Mon, 9 Oct 2017 14:46:41 +0800 Subject: drm/atomic: Unref duplicated drm_atomic_state in drm_atomic_helper_resume() Kmemleak reported memory leak after suspend and resume: unreferenced object 0xffffffc0e31d8880 (size 128): comm "bash", pid 181, jiffies 4294763583 (age 24.694s) hex dump (first 32 bytes): 01 00 00 00 00 00 00 00 00 20 a2 eb c0 ff ff ff ......... ...... 01 00 00 00 00 00 00 00 80 87 1d e3 c0 ff ff ff ................ backtrace: [] __save_stack_trace+0x48/0x6c [] create_object+0x138/0x254 [] kmemleak_alloc+0x58/0x8c [] kmem_cache_alloc_trace+0x188/0x254 [] drm_atomic_state_alloc+0x3c/0x88 [] drm_atomic_helper_duplicate_state+0x28/0x158 [] drm_atomic_helper_suspend+0x5c/0xf0 Problem here is that we are duplicating the drm_atomic_state in drm_atomic_helper_suspend(), but not unreference it in the resume path. Fixes: 1494276000db ("drm/atomic-helper: Implement subsystem-level suspend/resume") Signed-off-by: Jeffy Chen Reviewed-by: Maarten Lankhorst Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20171009064641.15174-1-jeffy.chen@rock-chips.com Fixes: 0853695c3ba4 ("drm: Add reference counting to drm_atomic_state") Cc: # v4.10+ (cherry picked from commit 6d281b1f79e194c02125da29ea77316810261ca8) --- drivers/gpu/drm/drm_atomic_helper.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 4e53aae9a1fb..0028591f3f95 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2960,6 +2960,7 @@ out: drm_modeset_backoff(&ctx); } + drm_atomic_state_put(state); drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); -- cgit v1.2.3 From 09aa97c78a784df2f781ff03b57b7dd6f1339edc Mon Sep 17 00:00:00 2001 From: Himanshu Jha Date: Mon, 9 Oct 2017 03:00:28 +0530 Subject: skd: Use kmem_cache_free Use kmem_cache_free instead of kfree for freeing the memory previously allocated with kmem_cache_zalloc/kmem_cache_alloc/kmem_cache_node. Signed-off-by: Himanshu Jha Signed-off-by: Jens Axboe --- drivers/block/skd_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c index 7cedb4295e9d..64d0fc17c174 100644 --- a/drivers/block/skd_main.c +++ b/drivers/block/skd_main.c @@ -2604,7 +2604,7 @@ static void *skd_alloc_dma(struct skd_device *skdev, struct kmem_cache *s, return NULL; *dma_handle = dma_map_single(dev, buf, s->size, dir); if (dma_mapping_error(dev, *dma_handle)) { - kfree(buf); + kmem_cache_free(s, buf); buf = NULL; } return buf; -- cgit v1.2.3 From e0f06bba9629987fb3ec1d6928bf17ef689702e8 Mon Sep 17 00:00:00 2001 From: Mark D Rustad Date: Wed, 31 Aug 2016 10:34:28 -0700 Subject: ixgbe: Return error when getting PHY address if PHY access is not supported In cases where PHY register access is not supported, don't mislead a caller into thinking that it is supported by returning a PHY address. Instead, return -EOPNOTSUPP when PHY access is not supported. Signed-off-by: Mark Rustad Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index d962368d08d0..822cdb4f2c25 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -8529,6 +8529,10 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) return ixgbe_ptp_set_ts_config(adapter, req); case SIOCGHWTSTAMP: return ixgbe_ptp_get_ts_config(adapter, req); + case SIOCGMIIPHY: + if (!adapter->hw.phy.ops.read_reg) + return -EOPNOTSUPP; + /* fall through */ default: return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); } -- cgit v1.2.3 From a39221ce969b316d3c3dcf7fcff8c0d8cf223007 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Mon, 3 Jul 2017 13:02:55 +0200 Subject: ixgbe: fix masking of bits read from IXGBE_VXLANCTRL register In ixgbe_clear_udp_tunnel_port(), we read the IXGBE_VXLANCTRL register and then try to mask some bits out of the value, using the logical instead of bitwise and operator. Fixes: a21d0822ff69 ("ixgbe: add support for geneve Rx offload") Signed-off-by: Sabrina Dubroca Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 822cdb4f2c25..4d76afd13868 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -4881,7 +4881,7 @@ static void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *adapter, u32 mask) IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))) return; - vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) && ~mask; + vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) & ~mask; IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl); if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK) -- cgit v1.2.3 From f4986d250ada29ae0c65c209a9d8f97968ea7eae Mon Sep 17 00:00:00 2001 From: Ding Tianhong Date: Fri, 18 Aug 2017 14:21:04 +0800 Subject: Revert commit 1a8b6d76dc5b ("net:add one common config...") The new flag PCI_DEV_FLAGS_NO_RELAXED_ORDERING has been added to indicate that Relaxed Ordering Attributes (RO) should not be used for Transaction Layer Packets (TLP) targeted toward these affected Root Port, it will clear the bit4 in the PCIe Device Control register, so the PCIe device drivers could query PCIe configuration space to determine if it can send TLPs to Root Port with the Relaxed Ordering Attributes set. With this new flag we don't need the config ARCH_WANT_RELAX_ORDER to control the Relaxed Ordering Attributes for the ixgbe drivers just like the commit 1a8b6d76dc5b ("net:add one common config...") did, so revert this commit. Signed-off-by: Ding Tianhong Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- arch/Kconfig | 3 --- arch/sparc/Kconfig | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/arch/Kconfig b/arch/Kconfig index 1aafb4efbb51..d789a89cb32c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -937,9 +937,6 @@ config STRICT_MODULE_RWX and non-text memory will be made non-executable. This provides protection against certain security exploits (e.g. writing to text) -config ARCH_WANT_RELAX_ORDER - bool - config ARCH_HAS_REFCOUNT bool help diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 0be3828752e5..4e83f950713e 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -44,7 +44,6 @@ config SPARC select ARCH_HAS_SG_CHAIN select CPU_NO_EFFICIENT_FFS select LOCKDEP_SMALL if LOCKDEP - select ARCH_WANT_RELAX_ORDER config SPARC32 def_bool !64BIT diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 2c19070d2a0b..e8c1788aed1f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -366,7 +366,7 @@ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) } IXGBE_WRITE_FLUSH(hw); -#ifndef CONFIG_ARCH_WANT_RELAX_ORDER +#ifndef CONFIG_SPARC /* Disable relaxed ordering */ for (i = 0; i < hw->mac.max_tx_queues; i++) { u32 regval; -- cgit v1.2.3 From 5e0fac63a694918870af9d6eaf716af19e7f5652 Mon Sep 17 00:00:00 2001 From: Ding Tianhong Date: Fri, 18 Aug 2017 14:21:05 +0800 Subject: net: ixgbe: Use new PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag The ixgbe driver use the compile check to determine if it can send TLPs to Root Port with the Relaxed Ordering Attribute set, this is too inconvenient, now the new flag PCI_DEV_FLAGS_NO_RELAXED_ORDERING has been added to the kernel and we could check the bit4 in the PCIe Device Control register to determine whether we should use the Relaxed Ordering Attributes or not, so use this new way in the ixgbe driver. Signed-off-by: Ding Tianhong Acked-by: Emil Tantilov Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c | 22 ---------------------- drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 19 ------------------- 2 files changed, 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c index 523f9d05a810..8a32eb7d47b9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c @@ -175,31 +175,9 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) **/ static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) { -#ifndef CONFIG_SPARC - u32 regval; - u32 i; -#endif s32 ret_val; ret_val = ixgbe_start_hw_generic(hw); - -#ifndef CONFIG_SPARC - /* Disable relaxed ordering */ - for (i = 0; ((i < hw->mac.max_tx_queues) && - (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { - regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); - regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); - } - - for (i = 0; ((i < hw->mac.max_rx_queues) && - (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { - regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); - regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | - IXGBE_DCA_RXCTRL_HEAD_WRO_EN); - IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); - } -#endif if (ret_val) return ret_val; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index e8c1788aed1f..6e6ab6f6875e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -366,25 +366,6 @@ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) } IXGBE_WRITE_FLUSH(hw); -#ifndef CONFIG_SPARC - /* Disable relaxed ordering */ - for (i = 0; i < hw->mac.max_tx_queues; i++) { - u32 regval; - - regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); - regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); - } - - for (i = 0; i < hw->mac.max_rx_queues; i++) { - u32 regval; - - regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); - regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | - IXGBE_DCA_RXCTRL_HEAD_WRO_EN); - IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); - } -#endif return 0; } -- cgit v1.2.3 From e30a154b5262b967b133b06ac40777e651045898 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Apr 2016 18:37:25 +0300 Subject: drm/i915: Read timings from the correct transcoder in intel_crtc_mode_get() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_crtc->config->cpu_transcoder isn't yet filled out when intel_crtc_mode_get() gets called during output probing, so we should not use it there. Instead intel_crtc_mode_get() figures out the correct transcoder on its own, and that's what we should use. If the BIOS boots LVDS on pipe B, intel_crtc_mode_get() would actually end up reading the timings from pipe A instead (since PIPE_A==0), which clearly isn't what we want. It looks to me like this may have been broken by commit eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") as that one removed the early initialization of cpu_transcoder from intel_crtc_init(). Cc: stable@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Rob Kramer Cc: Daniel Vetter Reported-by: Rob Kramer Fixes: eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") References: https://lists.freedesktop.org/archives/dri-devel/2016-April/104142.html Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1459525046-19425-1-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9f2bf3b3f759..10501e855756 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10253,13 +10253,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; + enum transcoder cpu_transcoder; struct drm_display_mode *mode; struct intel_crtc_state *pipe_config; - int htot = I915_READ(HTOTAL(cpu_transcoder)); - int hsync = I915_READ(HSYNC(cpu_transcoder)); - int vtot = I915_READ(VTOTAL(cpu_transcoder)); - int vsync = I915_READ(VSYNC(cpu_transcoder)); + u32 htot, hsync, vtot, vsync; enum pipe pipe = intel_crtc->pipe; mode = kzalloc(sizeof(*mode), GFP_KERNEL); @@ -10287,6 +10284,13 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, i9xx_crtc_clock_get(intel_crtc, pipe_config); mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; + + cpu_transcoder = pipe_config->cpu_transcoder; + htot = I915_READ(HTOTAL(cpu_transcoder)); + hsync = I915_READ(HSYNC(cpu_transcoder)); + vtot = I915_READ(VTOTAL(cpu_transcoder)); + vsync = I915_READ(VSYNC(cpu_transcoder)); + mode->hdisplay = (htot & 0xffff) + 1; mode->htotal = ((htot & 0xffff0000) >> 16) + 1; mode->hsync_start = (hsync & 0xffff) + 1; -- cgit v1.2.3 From d0d37254680fb15fdefe03a0986cfc1e22bcbfc4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Apr 2016 21:48:50 +0300 Subject: drm/i915: Use intel_get_pipe_timings() and intel_mode_from_pipe_config() in intel_crtc_mode_get() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminate the duplicate code for pipe timing readout in intel_crtc_mode_get() by using the functions we use for the normal state readout. v2: Store dotclock in adjusted_mode instead of the final mode Cc: dri-devel@lists.freedesktop.org Cc: Rob Kramer Cc: Daniel Vetter Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Tested-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1459536530-17754-1-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 10501e855756..15844bf92434 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10253,10 +10253,8 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum transcoder cpu_transcoder; struct drm_display_mode *mode; struct intel_crtc_state *pipe_config; - u32 htot, hsync, vtot, vsync; enum pipe pipe = intel_crtc->pipe; mode = kzalloc(sizeof(*mode), GFP_KERNEL); @@ -10283,24 +10281,12 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe)); i9xx_crtc_clock_get(intel_crtc, pipe_config); - mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; - - cpu_transcoder = pipe_config->cpu_transcoder; - htot = I915_READ(HTOTAL(cpu_transcoder)); - hsync = I915_READ(HSYNC(cpu_transcoder)); - vtot = I915_READ(VTOTAL(cpu_transcoder)); - vsync = I915_READ(VSYNC(cpu_transcoder)); + pipe_config->base.adjusted_mode.crtc_clock = + pipe_config->port_clock / pipe_config->pixel_multiplier; - mode->hdisplay = (htot & 0xffff) + 1; - mode->htotal = ((htot & 0xffff0000) >> 16) + 1; - mode->hsync_start = (hsync & 0xffff) + 1; - mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; - mode->vdisplay = (vtot & 0xffff) + 1; - mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->vsync_start = (vsync & 0xffff) + 1; - mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; + intel_get_pipe_timings(intel_crtc, pipe_config); - drm_mode_set_name(mode); + intel_mode_from_pipe_config(mode, pipe_config); kfree(pipe_config); -- cgit v1.2.3 From 8e679021c5b9465ac5b0d7efd26baab9b10a2dbd Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 7 Sep 2017 10:32:48 -0700 Subject: ixgbe: incorrect XDP ring accounting in ethtool tx_frame param Changing the TX ring parameters with an XDP program attached may cause the XDP queues to be cleared and the TX rings to be incorrectly configured. Fix by doing correct ring accounting in setup call. Fixes: 33fdc82f0883 ("ixgbe: add support for XDP_TX action") Signed-off-by: John Fastabend Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 72c565712a5f..c3e7a8191128 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -1048,7 +1048,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_ring *temp_ring; - int i, err = 0; + int i, j, err = 0; u32 new_rx_count, new_tx_count; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) @@ -1085,8 +1085,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev, } /* allocate temporary buffer to store rings in */ - i = max_t(int, adapter->num_tx_queues, adapter->num_rx_queues); - i = max_t(int, i, adapter->num_xdp_queues); + i = max_t(int, adapter->num_tx_queues + adapter->num_xdp_queues, + adapter->num_rx_queues); temp_ring = vmalloc(i * sizeof(struct ixgbe_ring)); if (!temp_ring) { @@ -1118,8 +1118,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev, } } - for (i = 0; i < adapter->num_xdp_queues; i++) { - memcpy(&temp_ring[i], adapter->xdp_ring[i], + for (j = 0; j < adapter->num_xdp_queues; j++, i++) { + memcpy(&temp_ring[i], adapter->xdp_ring[j], sizeof(struct ixgbe_ring)); temp_ring[i].count = new_tx_count; @@ -1139,10 +1139,10 @@ static int ixgbe_set_ringparam(struct net_device *netdev, memcpy(adapter->tx_ring[i], &temp_ring[i], sizeof(struct ixgbe_ring)); } - for (i = 0; i < adapter->num_xdp_queues; i++) { - ixgbe_free_tx_resources(adapter->xdp_ring[i]); + for (j = 0; j < adapter->num_xdp_queues; j++, i++) { + ixgbe_free_tx_resources(adapter->xdp_ring[j]); - memcpy(adapter->xdp_ring[i], &temp_ring[i], + memcpy(adapter->xdp_ring[j], &temp_ring[i], sizeof(struct ixgbe_ring)); } -- cgit v1.2.3 From bef27bdb6cfbc8c74c776f9455d4d3a4a76a4872 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 10:20:19 +0100 Subject: drm/i915: Assert we do not try to expand VMA for hugepage inside GGTT We only apply the hugepage PD redirection inside the ppGTT, so during i915_vma_insert() we want to exclude the GGTT from the additional alignment constraints (thereby avoiding the extra GTT pressure from fragmentation). Add an assert to document that intention alongside the comment. v2: After discussion with Matthew, make it a blanket GGTT ban (previously we allowed the expansion for appgtt, and so indirectly ggtt). There are issues we need to fix before allowing the current appgtt to be used with hugepages, and if we do, we probably want more care over when to expand/align, as the mappable aperture inside the ggtt is precious. Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Joonas Lahtinen Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20171009092019.20747-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_vma.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 72e86b32ab41..2bad88cc927b 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -513,6 +513,13 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) rounddown_pow_of_two(vma->page_sizes.sg | I915_GTT_PAGE_SIZE_2M); + /* + * Check we don't expand for the limited Global GTT + * (mappable aperture is even more precious!). This + * also checks that we exclude the aliasing-ppgtt. + */ + GEM_BUG_ON(i915_vma_is_ggtt(vma)); + alignment = max(alignment, page_alignment); if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) -- cgit v1.2.3 From f636edb214a5ffdc533d5c7198a66957322c1b40 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 12:02:57 +0100 Subject: drm/i915: Make i915_engine_info pretty printer to standalone We can use drm_printer to hide the differences between printk and seq_printf, and so make the i915_engine_info pretty printer able to be called from different contexts and not just debugfs. For instance, I want to use the pretty printer to debug kselftests. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171009110301.21705-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_debugfs.c | 148 +---------------------------- drivers/gpu/drm/i915/intel_engine_cs.c | 160 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 4 + 3 files changed, 168 insertions(+), 144 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f7817c667958..9ec2bcd9a695 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3292,9 +3292,9 @@ static int i915_display_info(struct seq_file *m, void *unused) static int i915_engine_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct i915_gpu_error *error = &dev_priv->gpu_error; struct intel_engine_cs *engine; enum intel_engine_id id; + struct drm_printer p; intel_runtime_pm_get(dev_priv); @@ -3303,149 +3303,9 @@ static int i915_engine_info(struct seq_file *m, void *unused) seq_printf(m, "Global active requests: %d\n", dev_priv->gt.active_requests); - for_each_engine(engine, dev_priv, id) { - struct intel_breadcrumbs *b = &engine->breadcrumbs; - struct drm_i915_gem_request *rq; - struct rb_node *rb; - u64 addr; - - seq_printf(m, "%s\n", engine->name); - seq_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n", - intel_engine_get_seqno(engine), - intel_engine_last_submit(engine), - engine->hangcheck.seqno, - jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp), - engine->timeline->inflight_seqnos); - seq_printf(m, "\tReset count: %d\n", - i915_reset_engine_count(error, engine)); - - rcu_read_lock(); - - seq_printf(m, "\tRequests:\n"); - - rq = list_first_entry(&engine->timeline->requests, - struct drm_i915_gem_request, link); - if (&rq->link != &engine->timeline->requests) - print_request(m, rq, "\t\tfirst "); - - rq = list_last_entry(&engine->timeline->requests, - struct drm_i915_gem_request, link); - if (&rq->link != &engine->timeline->requests) - print_request(m, rq, "\t\tlast "); - - rq = i915_gem_find_active_request(engine); - if (rq) { - print_request(m, rq, "\t\tactive "); - seq_printf(m, - "\t\t[head %04x, postfix %04x, tail %04x, batch 0x%08x_%08x]\n", - rq->head, rq->postfix, rq->tail, - rq->batch ? upper_32_bits(rq->batch->node.start) : ~0u, - rq->batch ? lower_32_bits(rq->batch->node.start) : ~0u); - } - - seq_printf(m, "\tRING_START: 0x%08x [0x%08x]\n", - I915_READ(RING_START(engine->mmio_base)), - rq ? i915_ggtt_offset(rq->ring->vma) : 0); - seq_printf(m, "\tRING_HEAD: 0x%08x [0x%08x]\n", - I915_READ(RING_HEAD(engine->mmio_base)) & HEAD_ADDR, - rq ? rq->ring->head : 0); - seq_printf(m, "\tRING_TAIL: 0x%08x [0x%08x]\n", - I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR, - rq ? rq->ring->tail : 0); - seq_printf(m, "\tRING_CTL: 0x%08x [%s]\n", - I915_READ(RING_CTL(engine->mmio_base)), - I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? "waiting" : ""); - - rcu_read_unlock(); - - addr = intel_engine_get_active_head(engine); - seq_printf(m, "\tACTHD: 0x%08x_%08x\n", - upper_32_bits(addr), lower_32_bits(addr)); - addr = intel_engine_get_last_batch_head(engine); - seq_printf(m, "\tBBADDR: 0x%08x_%08x\n", - upper_32_bits(addr), lower_32_bits(addr)); - - if (i915_modparams.enable_execlists) { - const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; - struct intel_engine_execlists * const execlists = &engine->execlists; - u32 ptr, read, write; - unsigned int idx; - - seq_printf(m, "\tExeclist status: 0x%08x %08x\n", - I915_READ(RING_EXECLIST_STATUS_LO(engine)), - I915_READ(RING_EXECLIST_STATUS_HI(engine))); - - ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine)); - read = GEN8_CSB_READ_PTR(ptr); - write = GEN8_CSB_WRITE_PTR(ptr); - seq_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s\n", - read, execlists->csb_head, - write, - intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)), - yesno(test_bit(ENGINE_IRQ_EXECLIST, - &engine->irq_posted))); - if (read >= GEN8_CSB_ENTRIES) - read = 0; - if (write >= GEN8_CSB_ENTRIES) - write = 0; - if (read > write) - write += GEN8_CSB_ENTRIES; - while (read < write) { - idx = ++read % GEN8_CSB_ENTRIES; - seq_printf(m, "\tExeclist CSB[%d]: 0x%08x [0x%08x in hwsp], context: %d [%d in hwsp]\n", - idx, - I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)), - hws[idx * 2], - I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx)), - hws[idx * 2 + 1]); - } - - rcu_read_lock(); - for (idx = 0; idx < execlists_num_ports(execlists); idx++) { - unsigned int count; - - rq = port_unpack(&execlists->port[idx], &count); - if (rq) { - seq_printf(m, "\t\tELSP[%d] count=%d, ", - idx, count); - print_request(m, rq, "rq: "); - } else { - seq_printf(m, "\t\tELSP[%d] idle\n", - idx); - } - } - rcu_read_unlock(); - - spin_lock_irq(&engine->timeline->lock); - for (rb = execlists->first; rb; rb = rb_next(rb)) { - struct i915_priolist *p = - rb_entry(rb, typeof(*p), node); - - list_for_each_entry(rq, &p->requests, - priotree.link) - print_request(m, rq, "\t\tQ "); - } - spin_unlock_irq(&engine->timeline->lock); - } else if (INTEL_GEN(dev_priv) > 6) { - seq_printf(m, "\tPP_DIR_BASE: 0x%08x\n", - I915_READ(RING_PP_DIR_BASE(engine))); - seq_printf(m, "\tPP_DIR_BASE_READ: 0x%08x\n", - I915_READ(RING_PP_DIR_BASE_READ(engine))); - seq_printf(m, "\tPP_DIR_DCLV: 0x%08x\n", - I915_READ(RING_PP_DIR_DCLV(engine))); - } - - spin_lock_irq(&b->rb_lock); - for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { - struct intel_wait *w = rb_entry(rb, typeof(*w), node); - - seq_printf(m, "\t%s [%d] waiting for %x\n", - w->tsk->comm, w->tsk->pid, w->seqno); - } - spin_unlock_irq(&b->rb_lock); - - seq_puts(m, "\n"); - } + p = drm_seq_file_printer(m); + for_each_engine(engine, dev_priv, id) + intel_engine_dump(engine, &p); intel_runtime_pm_put(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 807a7aafc089..a59b2a30ff5a 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -22,6 +22,8 @@ * */ +#include + #include "i915_drv.h" #include "intel_ringbuffer.h" #include "intel_lrc.h" @@ -1616,6 +1618,164 @@ bool intel_engine_can_store_dword(struct intel_engine_cs *engine) } } +static void print_request(struct drm_printer *m, + struct drm_i915_gem_request *rq, + const char *prefix) +{ + drm_printf(m, "%s%x [%x:%x] prio=%d @ %dms: %s\n", prefix, + rq->global_seqno, rq->ctx->hw_id, rq->fence.seqno, + rq->priotree.priority, + jiffies_to_msecs(jiffies - rq->emitted_jiffies), + rq->timeline->common->name); +} + +void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) +{ + struct intel_breadcrumbs *b = &engine->breadcrumbs; + struct i915_gpu_error *error = &engine->i915->gpu_error; + struct drm_i915_private *dev_priv = engine->i915; + struct drm_i915_gem_request *rq; + struct rb_node *rb; + u64 addr; + + drm_printf(m, "%s\n", engine->name); + drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n", + intel_engine_get_seqno(engine), + intel_engine_last_submit(engine), + engine->hangcheck.seqno, + jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp), + engine->timeline->inflight_seqnos); + drm_printf(m, "\tReset count: %d\n", + i915_reset_engine_count(error, engine)); + + rcu_read_lock(); + + drm_printf(m, "\tRequests:\n"); + + rq = list_first_entry(&engine->timeline->requests, + struct drm_i915_gem_request, link); + if (&rq->link != &engine->timeline->requests) + print_request(m, rq, "\t\tfirst "); + + rq = list_last_entry(&engine->timeline->requests, + struct drm_i915_gem_request, link); + if (&rq->link != &engine->timeline->requests) + print_request(m, rq, "\t\tlast "); + + rq = i915_gem_find_active_request(engine); + if (rq) { + print_request(m, rq, "\t\tactive "); + drm_printf(m, + "\t\t[head %04x, postfix %04x, tail %04x, batch 0x%08x_%08x]\n", + rq->head, rq->postfix, rq->tail, + rq->batch ? upper_32_bits(rq->batch->node.start) : ~0u, + rq->batch ? lower_32_bits(rq->batch->node.start) : ~0u); + } + + drm_printf(m, "\tRING_START: 0x%08x [0x%08x]\n", + I915_READ(RING_START(engine->mmio_base)), + rq ? i915_ggtt_offset(rq->ring->vma) : 0); + drm_printf(m, "\tRING_HEAD: 0x%08x [0x%08x]\n", + I915_READ(RING_HEAD(engine->mmio_base)) & HEAD_ADDR, + rq ? rq->ring->head : 0); + drm_printf(m, "\tRING_TAIL: 0x%08x [0x%08x]\n", + I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR, + rq ? rq->ring->tail : 0); + drm_printf(m, "\tRING_CTL: 0x%08x [%s]\n", + I915_READ(RING_CTL(engine->mmio_base)), + I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? "waiting" : ""); + + rcu_read_unlock(); + + addr = intel_engine_get_active_head(engine); + drm_printf(m, "\tACTHD: 0x%08x_%08x\n", + upper_32_bits(addr), lower_32_bits(addr)); + addr = intel_engine_get_last_batch_head(engine); + drm_printf(m, "\tBBADDR: 0x%08x_%08x\n", + upper_32_bits(addr), lower_32_bits(addr)); + + if (i915_modparams.enable_execlists) { + const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; + struct intel_engine_execlists * const execlists = &engine->execlists; + u32 ptr, read, write; + unsigned int idx; + + drm_printf(m, "\tExeclist status: 0x%08x %08x\n", + I915_READ(RING_EXECLIST_STATUS_LO(engine)), + I915_READ(RING_EXECLIST_STATUS_HI(engine))); + + ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine)); + read = GEN8_CSB_READ_PTR(ptr); + write = GEN8_CSB_WRITE_PTR(ptr); + drm_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s\n", + read, execlists->csb_head, + write, + intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)), + yesno(test_bit(ENGINE_IRQ_EXECLIST, + &engine->irq_posted))); + if (read >= GEN8_CSB_ENTRIES) + read = 0; + if (write >= GEN8_CSB_ENTRIES) + write = 0; + if (read > write) + write += GEN8_CSB_ENTRIES; + while (read < write) { + idx = ++read % GEN8_CSB_ENTRIES; + drm_printf(m, "\tExeclist CSB[%d]: 0x%08x [0x%08x in hwsp], context: %d [%d in hwsp]\n", + idx, + I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)), + hws[idx * 2], + I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx)), + hws[idx * 2 + 1]); + } + + rcu_read_lock(); + for (idx = 0; idx < execlists_num_ports(execlists); idx++) { + unsigned int count; + + rq = port_unpack(&execlists->port[idx], &count); + if (rq) { + drm_printf(m, "\t\tELSP[%d] count=%d, ", + idx, count); + print_request(m, rq, "rq: "); + } else { + drm_printf(m, "\t\tELSP[%d] idle\n", + idx); + } + } + rcu_read_unlock(); + + spin_lock_irq(&engine->timeline->lock); + for (rb = execlists->first; rb; rb = rb_next(rb)) { + struct i915_priolist *p = + rb_entry(rb, typeof(*p), node); + + list_for_each_entry(rq, &p->requests, + priotree.link) + print_request(m, rq, "\t\tQ "); + } + spin_unlock_irq(&engine->timeline->lock); + } else if (INTEL_GEN(dev_priv) > 6) { + drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n", + I915_READ(RING_PP_DIR_BASE(engine))); + drm_printf(m, "\tPP_DIR_BASE_READ: 0x%08x\n", + I915_READ(RING_PP_DIR_BASE_READ(engine))); + drm_printf(m, "\tPP_DIR_DCLV: 0x%08x\n", + I915_READ(RING_PP_DIR_DCLV(engine))); + } + + spin_lock_irq(&b->rb_lock); + for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { + struct intel_wait *w = rb_entry(rb, typeof(*w), node); + + drm_printf(m, "\t%s [%d] waiting for %x\n", + w->tsk->comm, w->tsk->pid, w->seqno); + } + spin_unlock_irq(&b->rb_lock); + + drm_printf(m, "\n"); +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/mock_engine.c" #endif diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 0fedda17488c..17186f067408 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -7,6 +7,8 @@ #include "i915_gem_timeline.h" #include "i915_selftest.h" +struct drm_printer; + #define I915_CMD_HASH_ORDER 9 /* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill, @@ -839,4 +841,6 @@ void intel_engines_reset_default_submission(struct drm_i915_private *i915); bool intel_engine_can_store_dword(struct intel_engine_cs *engine); +void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *p); + #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3 From 95a19ab4d7f8afbfca0564102d7d0bea2196c12c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 12:02:58 +0100 Subject: drm/i915/selftests: Pretty print engine state when requests fail to start During hangcheck testing, we try to execute requests following the GPU reset, and in particular want to try and debug when those fail. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171009110301.21705-2-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index 08159b268893..7e1bdd88eda3 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -624,8 +624,11 @@ static int igt_wait_reset(void *arg) __i915_add_request(rq, true); if (!wait_for_hang(&h, rq)) { + struct drm_printer p = drm_info_printer(i915->drm.dev); + pr_err("Failed to start request %x, at %x\n", rq->fence.seqno, hws_seqno(&h, rq)); + intel_engine_dump(rq->engine, &p); i915_reset(i915, 0); i915_gem_set_wedged(i915); @@ -716,8 +719,12 @@ static int igt_reset_queue(void *arg) __i915_add_request(rq, true); if (!wait_for_hang(&h, prev)) { + struct drm_printer p = drm_info_printer(i915->drm.dev); + pr_err("Failed to start request %x, at %x\n", prev->fence.seqno, hws_seqno(&h, prev)); + intel_engine_dump(rq->engine, &p); + i915_gem_request_put(rq); i915_gem_request_put(prev); @@ -818,8 +825,11 @@ static int igt_handle_error(void *arg) __i915_add_request(rq, true); if (!wait_for_hang(&h, rq)) { + struct drm_printer p = drm_info_printer(i915->drm.dev); + pr_err("Failed to start request %x, at %x\n", rq->fence.seqno, hws_seqno(&h, rq)); + intel_engine_dump(rq->engine, &p); i915_reset(i915, 0); i915_gem_set_wedged(i915); -- cgit v1.2.3 From 1749d90ff6e0cd0fc97aac5b08782ca1ac9665cf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 12:02:59 +0100 Subject: drm/i915: Hold forcewake for the duration of reset+restart Resetting the engine requires us to hold the forcewake wakeref to prevent RC6 trying to happen in the middle of the reset sequence. The consequence of an unwanted RC6 event in the middle is that random state is then saved to the powercontext and restored later, which may overwrite the mmio state we need to preserve (e.g. PD_DIR_BASE in the legacy ringbuffer reset_ring_common()). This was noticed in the live_hangcheck selftests when Haswell would sporadically fail to restart during igt_reset_queue(). Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171009110301.21705-3-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gem.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 82a10036fb38..eba23c239aae 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2832,7 +2832,17 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) { struct drm_i915_gem_request *request = NULL; - /* Prevent the signaler thread from updating the request + /* + * During the reset sequence, we must prevent the engine from + * entering RC6. As the context state is undefined until we restart + * the engine, if it does enter RC6 during the reset, the state + * written to the powercontext is undefined and so we may lose + * GPU state upon resume, i.e. fail to restart after a reset. + */ + intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); + + /* + * Prevent the signaler thread from updating the request * state (by calling dma_fence_signal) as we are processing * the reset. The write from the GPU of the seqno is * asynchronous and the signaler thread may see a different @@ -2843,7 +2853,8 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) */ kthread_park(engine->breadcrumbs.signaler); - /* Prevent request submission to the hardware until we have + /* + * Prevent request submission to the hardware until we have * completed the reset in i915_gem_reset_finish(). If a request * is completed by one engine, it may then queue a request * to a second via its engine->irq_tasklet *just* as we are @@ -3033,6 +3044,8 @@ void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { tasklet_enable(&engine->execlists.irq_tasklet); kthread_unpark(engine->breadcrumbs.signaler); + + intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); } void i915_gem_reset_finish(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From ff97d3ae6951101a85e5153cb128292d7119d15c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 12:03:00 +0100 Subject: drm/i915/selftests: Hold the rpm wakeref for the reset tests The lowlevel reset functions expect the caller to be holding the rpm wakeref for the device access across the reset. We were not explicitly doing this in the sefltest, so for simplicity acquire the wakeref for the duration of all subtests. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171009110301.21705-4-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index 7e1bdd88eda3..71ce06680d66 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -878,9 +878,16 @@ int intel_hangcheck_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_reset_queue), SUBTEST(igt_handle_error), }; + int err; if (!intel_has_gpu_reset(i915)) return 0; - return i915_subtests(tests, i915); + intel_runtime_pm_get(i915); + + err = i915_subtests(tests, i915); + + intel_runtime_pm_put(i915); + + return err; } -- cgit v1.2.3 From 67e6456485c7c04838a5dad720886726ae5590e0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 12:03:01 +0100 Subject: drm/i915: Provide an assert for when we expect forcewake to be held Add assert_forcewakes_active() (the complementary function to assert_forcewakes_inactive) that documents the requirement of a function for its callers to be holding the forcewake ref (i.e. the function is part of a sequence over which RC6 must be prevented). One such example is during ringbuffer reset, where RC6 must be held across the whole reinitialisation sequence. v2: Include debug information in the WARN so we know which fw domain is missing. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20171009110301.21705-5-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 11 ++++++++++- drivers/gpu/drm/i915/intel_uncore.c | 18 +++++++++++++++++- drivers/gpu/drm/i915/intel_uncore.h | 2 ++ 3 files changed, 29 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 05c08b0bc172..4285f09ff8b8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -579,7 +579,16 @@ out: static void reset_ring_common(struct intel_engine_cs *engine, struct drm_i915_gem_request *request) { - /* Try to restore the logical GPU state to match the continuation + /* + * RC6 must be prevented until the reset is complete and the engine + * reinitialised. If it occurs in the middle of this sequence, the + * state written to/loaded from the power context is ill-defined (e.g. + * the PP_BASE_DIR may be lost). + */ + assert_forcewakes_active(engine->i915, FORCEWAKE_ALL); + + /* + * Try to restore the logical GPU state to match the continuation * of the request queue. If we skip the context/PD restore, then * the next request may try to execute assuming that its context * is valid and loaded on the GPU and so may try to access invalid diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index b3c3f94fc7e4..983617b5b338 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -626,7 +626,23 @@ void assert_forcewakes_inactive(struct drm_i915_private *dev_priv) if (!dev_priv->uncore.funcs.force_wake_get) return; - WARN_ON(dev_priv->uncore.fw_domains_active); + WARN(dev_priv->uncore.fw_domains_active, + "Expected all fw_domains to be inactive, but %08x are still on\n", + dev_priv->uncore.fw_domains_active); +} + +void assert_forcewakes_active(struct drm_i915_private *dev_priv, + enum forcewake_domains fw_domains) +{ + if (!dev_priv->uncore.funcs.force_wake_get) + return; + + assert_rpm_wakelock_held(dev_priv); + + fw_domains &= dev_priv->uncore.fw_domains; + WARN(fw_domains & ~dev_priv->uncore.fw_domains_active, + "Expected %08x fw_domains to be active, but %08x are off\n", + fw_domains, fw_domains & ~dev_priv->uncore.fw_domains_active); } /* We give fast paths for the really cool registers */ diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 66eae2ce2f29..582771251b57 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -137,6 +137,8 @@ void intel_uncore_resume_early(struct drm_i915_private *dev_priv); u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv); void assert_forcewakes_inactive(struct drm_i915_private *dev_priv); +void assert_forcewakes_active(struct drm_i915_private *dev_priv, + enum forcewake_domains fw_domains); const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id); enum forcewake_domains -- cgit v1.2.3 From b4563f595ed44514467cfb3566b8b6519f328354 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 09:43:55 +0100 Subject: drm/i915: Pin fence for iomap Acquire the fence register for the iomap in i915_vma_pin_iomap() on behalf of the caller. We probably want for the caller to specify whether the fence should be pinned for their usage, but at the moment all callers do want the associated fence, or none, so take it on their behalf. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171009084401.29090-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_vma.c | 35 +++++++++++++++++++++--- drivers/gpu/drm/i915/i915_vma.h | 7 +---- drivers/gpu/drm/i915/selftests/i915_gem_object.c | 8 ------ 3 files changed, 32 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 2bad88cc927b..595209a2f159 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -280,13 +280,16 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, void __iomem *i915_vma_pin_iomap(struct i915_vma *vma) { void __iomem *ptr; + int err; /* Access through the GTT requires the device to be awake. */ assert_rpm_wakelock_held(vma->vm->i915); lockdep_assert_held(&vma->vm->i915->drm.struct_mutex); - if (WARN_ON(!i915_vma_is_map_and_fenceable(vma))) - return IO_ERR_PTR(-ENODEV); + if (WARN_ON(!i915_vma_is_map_and_fenceable(vma))) { + err = -ENODEV; + goto err; + } GEM_BUG_ON(!i915_vma_is_ggtt(vma)); GEM_BUG_ON((vma->flags & I915_VMA_GLOBAL_BIND) == 0); @@ -296,14 +299,38 @@ void __iomem *i915_vma_pin_iomap(struct i915_vma *vma) ptr = io_mapping_map_wc(&i915_vm_to_ggtt(vma->vm)->mappable, vma->node.start, vma->node.size); - if (ptr == NULL) - return IO_ERR_PTR(-ENOMEM); + if (ptr == NULL) { + err = -ENOMEM; + goto err; + } vma->iomap = ptr; } __i915_vma_pin(vma); + + err = i915_vma_get_fence(vma); + if (err) + goto err_unpin; + + i915_vma_pin_fence(vma); + return ptr; + +err_unpin: + __i915_vma_unpin(vma); +err: + return IO_ERR_PTR(err); +} + +void i915_vma_unpin_iomap(struct i915_vma *vma) +{ + lockdep_assert_held(&vma->obj->base.dev->struct_mutex); + + GEM_BUG_ON(vma->iomap == NULL); + + i915_vma_unpin_fence(vma); + i915_vma_unpin(vma); } void i915_vma_unpin_and_release(struct i915_vma **p_vma) diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index c59ba76613a3..864d84ab916d 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -322,12 +322,7 @@ void __iomem *i915_vma_pin_iomap(struct i915_vma *vma); * Callers must hold the struct_mutex. This function is only valid to be * called on a VMA previously iomapped by the caller with i915_vma_pin_iomap(). */ -static inline void i915_vma_unpin_iomap(struct i915_vma *vma) -{ - lockdep_assert_held(&vma->obj->base.dev->struct_mutex); - GEM_BUG_ON(vma->iomap == NULL); - i915_vma_unpin(vma); -} +void i915_vma_unpin_iomap(struct i915_vma *vma); static inline struct page *i915_vma_first_page(struct i915_vma *vma) { diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/selftests/i915_gem_object.c index 8f011c447e41..1b8774a42e48 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c @@ -251,14 +251,6 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj, return PTR_ERR(io); } - err = i915_vma_get_fence(vma); - if (err) { - pr_err("Failed to get fence for partial view: offset=%lu\n", - page); - i915_vma_unpin_iomap(vma); - return err; - } - iowrite32(page, io + n * PAGE_SIZE/sizeof(*io)); i915_vma_unpin_iomap(vma); -- cgit v1.2.3 From 3bd4073524fa1586435725ad45ff971a6c2b2537 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 09:43:56 +0100 Subject: drm/i915: Consolidate get_fence with pin_fence Following the pattern now used for obj->mm.pages, use just pin_fence and unpin_fence to control access to the fence registers. I.e. instead of calling get_fence(); pin_fence(), we now just need to call pin_fence(). This will make it easier to reduce the locking requirements around fence registers. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171009084401.29090-2-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_gem.c | 3 ++- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 10 ++++----- drivers/gpu/drm/i915/i915_gem_fence_reg.c | 33 +++++++++++++++++++++++++----- drivers/gpu/drm/i915/i915_vma.c | 4 +--- drivers/gpu/drm/i915/i915_vma.h | 20 ++++++++---------- drivers/gpu/drm/i915/intel_display.c | 3 +-- 7 files changed, 45 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 799a90abd81f..5d322cf490c4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3759,8 +3759,6 @@ i915_vm_to_ppgtt(struct i915_address_space *vm) } /* i915_gem_fence_reg.c */ -int __must_check i915_vma_get_fence(struct i915_vma *vma); -int __must_check i915_vma_put_fence(struct i915_vma *vma); struct drm_i915_fence_reg * i915_reserve_fence(struct drm_i915_private *dev_priv); void i915_unreserve_fence(struct drm_i915_fence_reg *fence); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eba23c239aae..37eba9da3fca 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1910,7 +1910,7 @@ int i915_gem_fault(struct vm_fault *vmf) if (ret) goto err_unpin; - ret = i915_vma_get_fence(vma); + ret = i915_vma_pin_fence(vma); if (ret) goto err_unpin; @@ -1926,6 +1926,7 @@ int i915_gem_fault(struct vm_fault *vmf) min_t(u64, vma->size, area->vm_end - area->vm_start), &ggtt->mappable); + i915_vma_unpin_fence(vma); err_unpin: __i915_vma_unpin(vma); err_unlock: diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d733c4d5a500..1df54e5fbb6e 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -367,12 +367,12 @@ eb_pin_vma(struct i915_execbuffer *eb, return false; if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) { - if (unlikely(i915_vma_get_fence(vma))) { + if (unlikely(i915_vma_pin_fence(vma))) { i915_vma_unpin(vma); return false; } - if (i915_vma_pin_fence(vma)) + if (vma->fence) exec_flags |= __EXEC_OBJECT_HAS_FENCE; } @@ -385,7 +385,7 @@ static inline void __eb_unreserve_vma(struct i915_vma *vma, unsigned int flags) GEM_BUG_ON(!(flags & __EXEC_OBJECT_HAS_PIN)); if (unlikely(flags & __EXEC_OBJECT_HAS_FENCE)) - i915_vma_unpin_fence(vma); + __i915_vma_unpin_fence(vma); __i915_vma_unpin(vma); } @@ -563,13 +563,13 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb, } if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) { - err = i915_vma_get_fence(vma); + err = i915_vma_pin_fence(vma); if (unlikely(err)) { i915_vma_unpin(vma); return err; } - if (i915_vma_pin_fence(vma)) + if (vma->fence) exec_flags |= __EXEC_OBJECT_HAS_FENCE; } diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.c b/drivers/gpu/drm/i915/i915_gem_fence_reg.c index 2783d63bd1ad..af824b8d73ea 100644 --- a/drivers/gpu/drm/i915/i915_gem_fence_reg.c +++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.c @@ -280,8 +280,7 @@ static int fence_update(struct drm_i915_fence_reg *fence, * * 0 on success, negative error code on failure. */ -int -i915_vma_put_fence(struct i915_vma *vma) +int i915_vma_put_fence(struct i915_vma *vma) { struct drm_i915_fence_reg *fence = vma->fence; @@ -299,6 +298,8 @@ static struct drm_i915_fence_reg *fence_find(struct drm_i915_private *dev_priv) struct drm_i915_fence_reg *fence; list_for_each_entry(fence, &dev_priv->mm.fence_list, link) { + GEM_BUG_ON(fence->vma && fence->vma->fence != fence); + if (fence->pin_count) continue; @@ -313,7 +314,7 @@ static struct drm_i915_fence_reg *fence_find(struct drm_i915_private *dev_priv) } /** - * i915_vma_get_fence - set up fencing for a vma + * i915_vma_pin_fence - set up fencing for a vma * @vma: vma to map through a fence reg * * When mapping objects through the GTT, userspace wants to be able to write @@ -331,10 +332,11 @@ static struct drm_i915_fence_reg *fence_find(struct drm_i915_private *dev_priv) * 0 on success, negative error code on failure. */ int -i915_vma_get_fence(struct i915_vma *vma) +i915_vma_pin_fence(struct i915_vma *vma) { struct drm_i915_fence_reg *fence; struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL; + int err; /* Note that we revoke fences on runtime suspend. Therefore the user * must keep the device awake whilst using the fence. @@ -344,6 +346,8 @@ i915_vma_get_fence(struct i915_vma *vma) /* Just update our place in the LRU if our fence is getting reused. */ if (vma->fence) { fence = vma->fence; + GEM_BUG_ON(fence->vma != vma); + fence->pin_count++; if (!fence->dirty) { list_move_tail(&fence->link, &fence->i915->mm.fence_list); @@ -353,10 +357,25 @@ i915_vma_get_fence(struct i915_vma *vma) fence = fence_find(vma->vm->i915); if (IS_ERR(fence)) return PTR_ERR(fence); + + GEM_BUG_ON(fence->pin_count); + fence->pin_count++; } else return 0; - return fence_update(fence, set); + err = fence_update(fence, set); + if (err) + goto out_unpin; + + GEM_BUG_ON(fence->vma != set); + GEM_BUG_ON(vma->fence != (set ? fence : NULL)); + + if (set) + return 0; + +out_unpin: + fence->pin_count--; + return err; } /** @@ -429,6 +448,8 @@ void i915_gem_revoke_fences(struct drm_i915_private *dev_priv) for (i = 0; i < dev_priv->num_fence_regs; i++) { struct drm_i915_fence_reg *fence = &dev_priv->fence_regs[i]; + GEM_BUG_ON(fence->vma && fence->vma->fence != fence); + if (fence->vma) i915_gem_release_mmap(fence->vma->obj); } @@ -450,6 +471,8 @@ void i915_gem_restore_fences(struct drm_i915_private *dev_priv) struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; struct i915_vma *vma = reg->vma; + GEM_BUG_ON(vma && vma->fence != reg); + /* * Commit delayed tiling changes if we have an object still * attached to the fence, otherwise just clear the fence. diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 595209a2f159..2b0083c34914 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -309,12 +309,10 @@ void __iomem *i915_vma_pin_iomap(struct i915_vma *vma) __i915_vma_pin(vma); - err = i915_vma_get_fence(vma); + err = i915_vma_pin_fence(vma); if (err) goto err_unpin; - i915_vma_pin_fence(vma); - return ptr; err_unpin: diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 864d84ab916d..13d7ba7ee21e 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -345,15 +345,13 @@ static inline struct page *i915_vma_first_page(struct i915_vma *vma) * * True if the vma has a fence, false otherwise. */ -static inline bool -i915_vma_pin_fence(struct i915_vma *vma) +int i915_vma_pin_fence(struct i915_vma *vma); +int __must_check i915_vma_put_fence(struct i915_vma *vma); + +static inline void __i915_vma_unpin_fence(struct i915_vma *vma) { - lockdep_assert_held(&vma->obj->base.dev->struct_mutex); - if (vma->fence) { - vma->fence->pin_count++; - return true; - } else - return false; + GEM_BUG_ON(vma->fence->pin_count <= 0); + vma->fence->pin_count--; } /** @@ -368,10 +366,8 @@ static inline void i915_vma_unpin_fence(struct i915_vma *vma) { lockdep_assert_held(&vma->obj->base.dev->struct_mutex); - if (vma->fence) { - GEM_BUG_ON(vma->fence->pin_count <= 0); - vma->fence->pin_count--; - } + if (vma->fence) + __i915_vma_unpin_fence(vma); } #endif diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 15844bf92434..a1182eeee5af 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2219,8 +2219,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) * something and try to run the system in a "less than optimal" * mode that matches the user configuration. */ - if (i915_vma_get_fence(vma) == 0) - i915_vma_pin_fence(vma); + i915_vma_pin_fence(vma); } i915_vma_get(vma); -- cgit v1.2.3 From a65adaf8a834504a4acdc0deca7fa790771add8a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 09:43:57 +0100 Subject: drm/i915: Track user GTT faulting per-vma We don't wish to refault the entire object (other vma) when unbinding one partial vma. To do this track which vma have been faulted into the user's address space. v2: Use a local vma_offset to tidy up a multiline unmap_mapping_range(). Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171009084401.29090-3-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_gem.c | 50 +++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/i915_gem_fence_reg.c | 7 +++-- drivers/gpu/drm/i915/i915_gem_object.h | 1 + drivers/gpu/drm/i915/i915_vma.c | 28 ++++++++++++++++- drivers/gpu/drm/i915/i915_vma.h | 21 ++++++++++++- 7 files changed, 88 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9ec2bcd9a695..5b58d2b897c7 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -98,7 +98,7 @@ static char get_tiling_flag(struct drm_i915_gem_object *obj) static char get_global_flag(struct drm_i915_gem_object *obj) { - return !list_empty(&obj->userfault_link) ? 'g' : ' '; + return obj->userfault_count ? 'g' : ' '; } static char get_pin_mapped_flag(struct drm_i915_gem_object *obj) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 37eba9da3fca..9cb8f85cbaad 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1914,18 +1914,22 @@ int i915_gem_fault(struct vm_fault *vmf) if (ret) goto err_unpin; - /* Mark as being mmapped into userspace for later revocation */ - assert_rpm_wakelock_held(dev_priv); - if (list_empty(&obj->userfault_link)) - list_add(&obj->userfault_link, &dev_priv->mm.userfault_list); - /* Finally, remap it using the new GTT offset */ ret = remap_io_mapping(area, area->vm_start + (vma->ggtt_view.partial.offset << PAGE_SHIFT), (ggtt->mappable_base + vma->node.start) >> PAGE_SHIFT, min_t(u64, vma->size, area->vm_end - area->vm_start), &ggtt->mappable); + if (ret) + goto err_fence; + /* Mark as being mmapped into userspace for later revocation */ + assert_rpm_wakelock_held(dev_priv); + if (!i915_vma_set_userfault(vma) && !obj->userfault_count++) + list_add(&obj->userfault_link, &dev_priv->mm.userfault_list); + GEM_BUG_ON(!obj->userfault_count); + +err_fence: i915_vma_unpin_fence(vma); err_unpin: __i915_vma_unpin(vma); @@ -1978,6 +1982,25 @@ err: return ret; } +static void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj) +{ + struct i915_vma *vma; + + GEM_BUG_ON(!obj->userfault_count); + + obj->userfault_count = 0; + list_del(&obj->userfault_link); + drm_vma_node_unmap(&obj->base.vma_node, + obj->base.dev->anon_inode->i_mapping); + + list_for_each_entry(vma, &obj->vma_list, obj_link) { + if (!i915_vma_is_ggtt(vma)) + break; + + i915_vma_unset_userfault(vma); + } +} + /** * i915_gem_release_mmap - remove physical page mappings * @obj: obj in question @@ -2008,12 +2031,10 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj) lockdep_assert_held(&i915->drm.struct_mutex); intel_runtime_pm_get(i915); - if (list_empty(&obj->userfault_link)) + if (!obj->userfault_count) goto out; - list_del_init(&obj->userfault_link); - drm_vma_node_unmap(&obj->base.vma_node, - obj->base.dev->anon_inode->i_mapping); + __i915_gem_object_release_mmap(obj); /* Ensure that the CPU's PTE are revoked and there are not outstanding * memory transactions from userspace before we return. The TLB @@ -2041,11 +2062,8 @@ void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv) */ list_for_each_entry_safe(obj, on, - &dev_priv->mm.userfault_list, userfault_link) { - list_del_init(&obj->userfault_link); - drm_vma_node_unmap(&obj->base.vma_node, - obj->base.dev->anon_inode->i_mapping); - } + &dev_priv->mm.userfault_list, userfault_link) + __i915_gem_object_release_mmap(obj); /* The fence will be lost when the device powers down. If any were * in use by hardware (i.e. they are pinned), we should not be powering @@ -2068,7 +2086,7 @@ void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv) if (!reg->vma) continue; - GEM_BUG_ON(!list_empty(®->vma->obj->userfault_link)); + GEM_BUG_ON(i915_vma_has_userfault(reg->vma)); reg->dirty = true; } } @@ -4276,7 +4294,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, mutex_init(&obj->mm.lock); INIT_LIST_HEAD(&obj->global_link); - INIT_LIST_HEAD(&obj->userfault_link); INIT_LIST_HEAD(&obj->vma_list); INIT_LIST_HEAD(&obj->lut_list); INIT_LIST_HEAD(&obj->batch_pool_link); @@ -4457,6 +4474,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, llist_for_each_entry_safe(obj, on, freed, freed) { GEM_BUG_ON(obj->bind_count); + GEM_BUG_ON(obj->userfault_count); GEM_BUG_ON(atomic_read(&obj->frontbuffer_bits)); GEM_BUG_ON(!list_empty(&obj->lut_list)); diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 4df039ef2ce3..933ee8ecfa54 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -82,7 +82,7 @@ mark_free(struct drm_mm_scan *scan, if (i915_vma_is_pinned(vma)) return false; - if (flags & PIN_NONFAULT && !list_empty(&vma->obj->userfault_link)) + if (flags & PIN_NONFAULT && i915_vma_has_userfault(vma)) return false; list_add(&vma->evict_link, unwind); diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.c b/drivers/gpu/drm/i915/i915_gem_fence_reg.c index af824b8d73ea..012250f25255 100644 --- a/drivers/gpu/drm/i915/i915_gem_fence_reg.c +++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.c @@ -240,7 +240,8 @@ static int fence_update(struct drm_i915_fence_reg *fence, /* Ensure that all userspace CPU access is completed before * stealing the fence. */ - i915_gem_release_mmap(fence->vma->obj); + GEM_BUG_ON(fence->vma->fence != fence); + i915_vma_revoke_mmap(fence->vma); fence->vma->fence = NULL; fence->vma = NULL; @@ -451,7 +452,7 @@ void i915_gem_revoke_fences(struct drm_i915_private *dev_priv) GEM_BUG_ON(fence->vma && fence->vma->fence != fence); if (fence->vma) - i915_gem_release_mmap(fence->vma->obj); + i915_vma_revoke_mmap(fence->vma); } } @@ -479,7 +480,7 @@ void i915_gem_restore_fences(struct drm_i915_private *dev_priv) */ if (vma && !i915_gem_object_is_tiled(vma->obj)) { GEM_BUG_ON(!reg->dirty); - GEM_BUG_ON(!list_empty(&vma->obj->userfault_link)); + GEM_BUG_ON(i915_vma_has_userfault(vma)); list_move(®->link, &dev_priv->mm.fence_list); vma->fence = NULL; diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 956c911c2cbf..d67f1cbe842d 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -123,6 +123,7 @@ struct drm_i915_gem_object { /** * Whether the object is currently in the GGTT mmap. */ + unsigned int userfault_count; struct list_head userfault_link; struct list_head batch_pool_link; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 2b0083c34914..4dce2e0197d9 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -690,6 +690,30 @@ static void __i915_vma_iounmap(struct i915_vma *vma) vma->iomap = NULL; } +void i915_vma_revoke_mmap(struct i915_vma *vma) +{ + struct drm_vma_offset_node *node = &vma->obj->base.vma_node; + u64 vma_offset; + + lockdep_assert_held(&vma->vm->i915->drm.struct_mutex); + + if (!i915_vma_has_userfault(vma)) + return; + + GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma)); + GEM_BUG_ON(!vma->obj->userfault_count); + + vma_offset = vma->ggtt_view.partial.offset << PAGE_SHIFT; + unmap_mapping_range(vma->vm->i915->drm.anon_inode->i_mapping, + drm_vma_node_offset_addr(node) + vma_offset, + vma->size, + 1); + + i915_vma_unset_userfault(vma); + if (!--vma->obj->userfault_count) + list_del(&vma->obj->userfault_link); +} + int i915_vma_unbind(struct i915_vma *vma) { struct drm_i915_gem_object *obj = vma->obj; @@ -753,11 +777,13 @@ int i915_vma_unbind(struct i915_vma *vma) return ret; /* Force a pagefault for domain tracking on next user access */ - i915_gem_release_mmap(obj); + i915_vma_revoke_mmap(vma); __i915_vma_iounmap(vma); vma->flags &= ~I915_VMA_CAN_FENCE; } + GEM_BUG_ON(vma->fence); + GEM_BUG_ON(i915_vma_has_userfault(vma)); if (likely(!vma->vm->closed)) { trace_i915_vma_unbind(vma); diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 13d7ba7ee21e..1e2bc9b3c3ac 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -66,7 +66,7 @@ struct i915_vma { * that exist in the ctx->handle_vmas LUT for this vma. */ unsigned int open_count; - unsigned int flags; + unsigned long flags; /** * How many users have pinned this object in GTT space. The following * users can each hold at most one reference: pwrite/pread, execbuffer @@ -88,6 +88,8 @@ struct i915_vma { #define I915_VMA_GGTT BIT(8) #define I915_VMA_CAN_FENCE BIT(9) #define I915_VMA_CLOSED BIT(10) +#define I915_VMA_USERFAULT_BIT 11 +#define I915_VMA_USERFAULT BIT(I915_VMA_USERFAULT_BIT) unsigned int active; struct i915_gem_active last_read[I915_NUM_ENGINES]; @@ -146,6 +148,22 @@ static inline bool i915_vma_is_closed(const struct i915_vma *vma) return vma->flags & I915_VMA_CLOSED; } +static inline bool i915_vma_set_userfault(struct i915_vma *vma) +{ + GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma)); + return __test_and_set_bit(I915_VMA_USERFAULT_BIT, &vma->flags); +} + +static inline void i915_vma_unset_userfault(struct i915_vma *vma) +{ + return __clear_bit(I915_VMA_USERFAULT_BIT, &vma->flags); +} + +static inline bool i915_vma_has_userfault(const struct i915_vma *vma) +{ + return test_bit(I915_VMA_USERFAULT_BIT, &vma->flags); +} + static inline unsigned int i915_vma_get_active(const struct i915_vma *vma) { return vma->active; @@ -244,6 +262,7 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long cache_level); bool i915_vma_misplaced(const struct i915_vma *vma, u64 size, u64 alignment, u64 flags); void __i915_vma_set_map_and_fenceable(struct i915_vma *vma); +void i915_vma_revoke_mmap(struct i915_vma *vma); int __must_check i915_vma_unbind(struct i915_vma *vma); void i915_vma_unlink_ctx(struct i915_vma *vma); void i915_vma_close(struct i915_vma *vma); -- cgit v1.2.3 From f34a93bbb33d988df36bb99f791f0bf8a7017041 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 09:43:58 +0100 Subject: drm/i915: Check PIN_NONFAULT overlaps in evict_for_node If the caller says that he doesn't want to evict any other faulting vma, honour that flag. The logic was used in evict_something, but not the more specific evict_for_node, now being used as a preliminary probe since commit 606fec956c0e ("drm/i915: Prefer random replacement before eviction search"). Fixes: 606fec956c0e ("drm/i915: Prefer random replacement before eviction search") Fixes: 821188778b9b ("drm/i915: Choose not to evict faultable objects from the GGTT") References: https://bugs.freedesktop.org/show_bug.cgi?id=102490 Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171009084401.29090-4-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_evict.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 933ee8ecfa54..a5a5b7e6daae 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -315,6 +315,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm, break; } + if (flags & PIN_NONFAULT && i915_vma_has_userfault(vma)) { + ret = -ENOSPC; + break; + } + /* Overlap of objects in the same batch? */ if (i915_vma_is_pinned(vma)) { ret = -ENOSPC; -- cgit v1.2.3 From 3c755c5b56a79cf0a2681abf705cebfb10737db2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 09:43:59 +0100 Subject: drm/i915: Try a minimal attempt to insert the whole object for relocations As we have a lightweight fallback to insert a single page into the aperture, try to avoid any heavier evictions when attempting to insert the entire object. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171009084401.29090-5-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 1df54e5fbb6e..3d7190764f10 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -974,7 +974,9 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj, return ERR_PTR(err); vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, - PIN_MAPPABLE | PIN_NONBLOCK); + PIN_MAPPABLE | + PIN_NONBLOCK | + PIN_NONFAULT); if (IS_ERR(vma)) { memset(&cache->node, 0, sizeof(cache->node)); err = drm_mm_insert_node_in_range -- cgit v1.2.3 From a3259ca9f85bc59720abc1b6dbbec6ce563e0877 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 09:44:00 +0100 Subject: drm/i915: Avoid evicting user fault mappable vma for pread/pwrite Both pread/pwrite GTT paths provide a fast fallback in case we cannot map the whole object at a time. Currently, we use the fallback for very large objects and for active objects that would require remapping, but we can also add active fault mappable objects to the list that we want to avoid evicting. The rationale is that such fault mappable objects are in active use and to evict requires tearing down the CPU PTE and forcing a page fault on the next access; more costly, and intefers with other processes, than our per-page GTT fallback. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171009084401.29090-6-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9cb8f85cbaad..6f5c0d6da06a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1055,7 +1055,9 @@ i915_gem_gtt_pread(struct drm_i915_gem_object *obj, intel_runtime_pm_get(i915); vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, - PIN_MAPPABLE | PIN_NONBLOCK); + PIN_MAPPABLE | + PIN_NONFAULT | + PIN_NONBLOCK); if (!IS_ERR(vma)) { node.start = i915_ggtt_offset(vma); node.allocated = false; @@ -1239,7 +1241,9 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, intel_runtime_pm_get(i915); vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, - PIN_MAPPABLE | PIN_NONBLOCK); + PIN_MAPPABLE | + PIN_NONFAULT | + PIN_NONBLOCK); if (!IS_ERR(vma)) { node.start = i915_ggtt_offset(vma); node.allocated = false; -- cgit v1.2.3 From 43ae70d97c5195f48d903df31ecac4c5397b2f1e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Oct 2017 09:44:01 +0100 Subject: drm/i915: Early rejection of mappable GGTT pin attempts for large bo Currently, we reject attempting to pin a large bo into the mappable aperture, but only after trying to create the vma. Under debug kernels, repeatedly creating and freeing that vma for an oversized bo consumes one-third of the runtime for pwrite/pread tests as it is spent on kmalloc/kfree tracking. If we move the rejection to before creating that vma, we lose some accuracy of checking against the fence_size as opposed to object size, though the fence can never be smaller than the object. Note that the vma creation itself will reject an attempt to create a vma larger than the GTT so we can remove one redundant test. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171009084401.29090-7-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem.c | 65 ++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6f5c0d6da06a..b43fae4b83e6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4036,42 +4036,47 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, lockdep_assert_held(&obj->base.dev->struct_mutex); + if (!view && flags & PIN_MAPPABLE) { + /* If the required space is larger than the available + * aperture, we will not able to find a slot for the + * object and unbinding the object now will be in + * vain. Worse, doing so may cause us to ping-pong + * the object in and out of the Global GTT and + * waste a lot of cycles under the mutex. + */ + if (obj->base.size > dev_priv->ggtt.mappable_end) + return ERR_PTR(-E2BIG); + + /* If NONBLOCK is set the caller is optimistically + * trying to cache the full object within the mappable + * aperture, and *must* have a fallback in place for + * situations where we cannot bind the object. We + * can be a little more lax here and use the fallback + * more often to avoid costly migrations of ourselves + * and other objects within the aperture. + * + * Half-the-aperture is used as a simple heuristic. + * More interesting would to do search for a free + * block prior to making the commitment to unbind. + * That caters for the self-harm case, and with a + * little more heuristics (e.g. NOFAULT, NOEVICT) + * we could try to minimise harm to others. + */ + if (flags & PIN_NONBLOCK && + obj->base.size > dev_priv->ggtt.mappable_end / 2) + return ERR_PTR(-ENOSPC); + } + vma = i915_vma_instance(obj, vm, view); if (unlikely(IS_ERR(vma))) return vma; if (i915_vma_misplaced(vma, size, alignment, flags)) { - if (flags & PIN_NONBLOCK && - (i915_vma_is_pinned(vma) || i915_vma_is_active(vma))) - return ERR_PTR(-ENOSPC); + if (flags & PIN_NONBLOCK) { + if (i915_vma_is_pinned(vma) || i915_vma_is_active(vma)) + return ERR_PTR(-ENOSPC); - if (flags & PIN_MAPPABLE) { - /* If the required space is larger than the available - * aperture, we will not able to find a slot for the - * object and unbinding the object now will be in - * vain. Worse, doing so may cause us to ping-pong - * the object in and out of the Global GTT and - * waste a lot of cycles under the mutex. - */ - if (vma->fence_size > dev_priv->ggtt.mappable_end) - return ERR_PTR(-E2BIG); - - /* If NONBLOCK is set the caller is optimistically - * trying to cache the full object within the mappable - * aperture, and *must* have a fallback in place for - * situations where we cannot bind the object. We - * can be a little more lax here and use the fallback - * more often to avoid costly migrations of ourselves - * and other objects within the aperture. - * - * Half-the-aperture is used as a simple heuristic. - * More interesting would to do search for a free - * block prior to making the commitment to unbind. - * That caters for the self-harm case, and with a - * little more heuristics (e.g. NOFAULT, NOEVICT) - * we could try to minimise harm to others. - */ - if (flags & PIN_NONBLOCK && + if (flags & PIN_MAPPABLE && vma->fence_size > dev_priv->ggtt.mappable_end / 2) return ERR_PTR(-ENOSPC); } -- cgit v1.2.3 From 84e8978e62fea661787a216e7fe9abac8f1e056e Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Mon, 9 Oct 2017 12:00:24 +0100 Subject: drm/i915: s/sg_mask/sg_page_sizes/ It's a little unclear what the sg_mask actually is, so prefer the more meaningful name of sg_page_sizes. Suggested-by: Joonas Lahtinen Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171009110024.29114-1-matthew.auld@intel.com Reviewed-by: Chris Wilson Reviewed-by: Joonas Lahtinen Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 28 +++++++++++++-------------- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 6 +++--- drivers/gpu/drm/i915/i915_gem_internal.c | 8 ++++---- drivers/gpu/drm/i915/i915_gem_userptr.c | 6 +++--- drivers/gpu/drm/i915/selftests/huge_pages.c | 18 ++++++++--------- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 8 ++++---- 7 files changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5d322cf490c4..770305bdeabb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3537,7 +3537,7 @@ i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, - unsigned int sg_mask); + unsigned int sg_page_sizes); int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj); static inline int __must_check diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b43fae4b83e6..e829e8c900e8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2333,7 +2333,7 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) struct page *page; unsigned long last_pfn = 0; /* suppress gcc warning */ unsigned int max_segment = i915_sg_segment_size(); - unsigned int sg_mask; + unsigned int sg_page_sizes; gfp_t noreclaim; int ret; @@ -2365,7 +2365,7 @@ rebuild_st: sg = st->sgl; st->nents = 0; - sg_mask = 0; + sg_page_sizes = 0; for (i = 0; i < page_count; i++) { const unsigned int shrink[] = { I915_SHRINK_BOUND | I915_SHRINK_UNBOUND | I915_SHRINK_PURGEABLE, @@ -2419,7 +2419,7 @@ rebuild_st: sg->length >= max_segment || page_to_pfn(page) != last_pfn + 1) { if (i) { - sg_mask |= sg->length; + sg_page_sizes |= sg->length; sg = sg_next(sg); } st->nents++; @@ -2433,7 +2433,7 @@ rebuild_st: WARN_ON((gfp & __GFP_DMA32) && (last_pfn >= 0x00100000UL)); } if (sg) { /* loop terminated early; short sg table */ - sg_mask |= sg->length; + sg_page_sizes |= sg->length; sg_mark_end(sg); } @@ -2464,7 +2464,7 @@ rebuild_st: if (i915_gem_object_needs_bit17_swizzle(obj)) i915_gem_object_do_bit_17_swizzle(obj, st); - __i915_gem_object_set_pages(obj, st, sg_mask); + __i915_gem_object_set_pages(obj, st, sg_page_sizes); return 0; @@ -2492,7 +2492,7 @@ err_pages: void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, - unsigned int sg_mask) + unsigned int sg_page_sizes) { struct drm_i915_private *i915 = to_i915(obj->base.dev); unsigned long supported = INTEL_INFO(i915)->page_sizes; @@ -2512,16 +2512,16 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, obj->mm.quirked = true; } - GEM_BUG_ON(!sg_mask); - obj->mm.page_sizes.phys = sg_mask; + GEM_BUG_ON(!sg_page_sizes); + obj->mm.page_sizes.phys = sg_page_sizes; /* - * Calculate the supported page-sizes which fit into the given sg_mask. - * This will give us the page-sizes which we may be able to use - * opportunistically when later inserting into the GTT. For example if - * phys=2G, then in theory we should be able to use 1G, 2M, 64K or 4K - * pages, although in practice this will depend on a number of other - * factors. + * Calculate the supported page-sizes which fit into the given + * sg_page_sizes. This will give us the page-sizes which we may be able + * to use opportunistically when later inserting into the GTT. For + * example if phys=2G, then in theory we should be able to use 1G, 2M, + * 64K or 4K pages, although in practice this will depend on a number of + * other factors. */ obj->mm.page_sizes.sg = 0; for_each_set_bit(i, &supported, ilog2(I915_GTT_MAX_PAGE_SIZE) + 1) { diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index e542a9d80077..864439a214c8 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -259,16 +259,16 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) { struct sg_table *pages; - unsigned int sg_mask; + unsigned int sg_page_sizes; pages = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL); if (IS_ERR(pages)) return PTR_ERR(pages); - sg_mask = i915_sg_page_sizes(pages->sgl); + sg_page_sizes = i915_sg_page_sizes(pages->sgl); - __i915_gem_object_set_pages(obj, pages, sg_mask); + __i915_gem_object_set_pages(obj, pages, sg_page_sizes); return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c index bdc23c4c8783..ee83ec838ee7 100644 --- a/drivers/gpu/drm/i915/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/i915_gem_internal.c @@ -49,7 +49,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) struct drm_i915_private *i915 = to_i915(obj->base.dev); struct sg_table *st; struct scatterlist *sg; - unsigned int sg_mask; + unsigned int sg_page_sizes; unsigned int npages; int max_order; gfp_t gfp; @@ -88,7 +88,7 @@ create_st: sg = st->sgl; st->nents = 0; - sg_mask = 0; + sg_page_sizes = 0; do { int order = min(fls(npages) - 1, max_order); @@ -106,7 +106,7 @@ create_st: } while (1); sg_set_page(sg, page, PAGE_SIZE << order, 0); - sg_mask |= PAGE_SIZE << order; + sg_page_sizes |= PAGE_SIZE << order; st->nents++; npages -= 1 << order; @@ -135,7 +135,7 @@ create_st: */ obj->mm.madv = I915_MADV_DONTNEED; - __i915_gem_object_set_pages(obj, st, sg_mask); + __i915_gem_object_set_pages(obj, st, sg_page_sizes); return 0; diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 41e16e19c3f3..c36a84b070b6 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -405,7 +405,7 @@ __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj, { unsigned int max_segment = i915_sg_segment_size(); struct sg_table *st; - unsigned int sg_mask; + unsigned int sg_page_sizes; int ret; st = kmalloc(sizeof(*st), GFP_KERNEL); @@ -435,9 +435,9 @@ alloc_table: return ERR_PTR(ret); } - sg_mask = i915_sg_page_sizes(st->sgl); + sg_page_sizes = i915_sg_page_sizes(st->sgl); - __i915_gem_object_set_pages(obj, st, sg_mask); + __i915_gem_object_set_pages(obj, st, sg_page_sizes); return st; } diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c index b8495882e5b0..b8b9d0822199 100644 --- a/drivers/gpu/drm/i915/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c @@ -68,7 +68,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj) unsigned int page_mask = obj->mm.page_mask; struct sg_table *st; struct scatterlist *sg; - unsigned int sg_mask; + unsigned int sg_page_sizes; u64 rem; st = kmalloc(sizeof(*st), GFP); @@ -83,7 +83,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj) rem = obj->base.size; sg = st->sgl; st->nents = 0; - sg_mask = 0; + sg_page_sizes = 0; /* * Our goal here is simple, we want to greedily fill the object from @@ -104,7 +104,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj) goto err; sg_set_page(sg, page, page_size, 0); - sg_mask |= page_size; + sg_page_sizes |= page_size; st->nents++; rem -= page_size; @@ -124,8 +124,8 @@ static int get_huge_pages(struct drm_i915_gem_object *obj) obj->mm.madv = I915_MADV_DONTNEED; - GEM_BUG_ON(sg_mask != obj->mm.page_mask); - __i915_gem_object_set_pages(obj, st, sg_mask); + GEM_BUG_ON(sg_page_sizes != obj->mm.page_mask); + __i915_gem_object_set_pages(obj, st, sg_page_sizes); return 0; @@ -192,7 +192,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj) const u64 max_len = rounddown_pow_of_two(UINT_MAX); struct sg_table *st; struct scatterlist *sg; - unsigned int sg_mask; + unsigned int sg_page_sizes; u64 rem; st = kmalloc(sizeof(*st), GFP); @@ -208,7 +208,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj) rem = obj->base.size; sg = st->sgl; st->nents = 0; - sg_mask = 0; + sg_page_sizes = 0; do { unsigned int page_size = get_largest_page_size(i915, rem); unsigned int len = min(page_size * div_u64(rem, page_size), @@ -221,7 +221,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj) sg_dma_len(sg) = len; sg_dma_address(sg) = page_size; - sg_mask |= len; + sg_page_sizes |= len; st->nents++; @@ -236,7 +236,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj) obj->mm.madv = I915_MADV_DONTNEED; - __i915_gem_object_set_pages(obj, st, sg_mask); + __i915_gem_object_set_pages(obj, st, sg_page_sizes); return 0; } diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 883bc19e3aaf..9da0c9f99916 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -45,7 +45,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) #define PFN_BIAS 0x1000 struct sg_table *pages; struct scatterlist *sg; - unsigned int sg_mask; + unsigned int sg_page_sizes; typeof(obj->base.size) rem; pages = kmalloc(sizeof(*pages), GFP); @@ -58,7 +58,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) return -ENOMEM; } - sg_mask = 0; + sg_page_sizes = 0; rem = obj->base.size; for (sg = pages->sgl; sg; sg = sg_next(sg)) { unsigned long len = min_t(typeof(rem), rem, BIT(31)); @@ -67,7 +67,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) sg_set_page(sg, pfn_to_page(PFN_BIAS), len, 0); sg_dma_address(sg) = page_to_phys(sg_page(sg)); sg_dma_len(sg) = len; - sg_mask |= len; + sg_page_sizes |= len; rem -= len; } @@ -75,7 +75,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) obj->mm.madv = I915_MADV_DONTNEED; - __i915_gem_object_set_pages(obj, pages, sg_mask); + __i915_gem_object_set_pages(obj, pages, sg_page_sizes); return 0; #undef GFP -- cgit v1.2.3 From f7974880cf869ddbd0ba9a8e2ab11dff4a667f96 Mon Sep 17 00:00:00 2001 From: John Einar Reitan Date: Mon, 9 Oct 2017 15:49:36 +0200 Subject: sync_file: Return consistent status in SYNC_IOC_FILE_INFO sync_file_ioctl_fence_info has a race between filling the status of the underlying fences and the overall status of the sync_file. If fence transitions in the time frame between its sync_fill_fence_info and the later dma_fence_is_signaled for the sync_file, the returned information is inconsistent showing non-signaled underlying fences but an overall signaled state. This patch changes sync_file_ioctl_fence_info to track what has been encoded and using that as the overall sync_file status. Tested-by: Vamsidhar Reddy Gaddam Signed-off-by: John Einar Reitan Cc: Sumit Semwal Cc: Gustavo Padovan Cc: dri-devel@lists.freedesktop.org Reviewed-by: Chris Wilson Signed-off-by: Gustavo Padovan Link: https://patchwork.freedesktop.org/patch/msgid/20171009134936.27219-1-john.reitan@arm.com --- drivers/dma-buf/sync_file.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 66fb40d0ebdb..03830634e141 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -383,7 +383,7 @@ err_put_fd: return err; } -static void sync_fill_fence_info(struct dma_fence *fence, +static int sync_fill_fence_info(struct dma_fence *fence, struct sync_fence_info *info) { strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), @@ -399,6 +399,8 @@ static void sync_fill_fence_info(struct dma_fence *fence, test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags) ? ktime_to_ns(fence->timestamp) : ktime_set(0, 0); + + return info->status; } static long sync_file_ioctl_fence_info(struct sync_file *sync_file, @@ -424,8 +426,12 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, * sync_fence_info and return the actual number of fences on * info->num_fences. */ - if (!info.num_fences) + if (!info.num_fences) { + info.status = dma_fence_is_signaled(sync_file->fence); goto no_fences; + } else { + info.status = 1; + } if (info.num_fences < num_fences) return -EINVAL; @@ -435,8 +441,10 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, if (!fence_info) return -ENOMEM; - for (i = 0; i < num_fences; i++) - sync_fill_fence_info(fences[i], &fence_info[i]); + for (i = 0; i < num_fences; i++) { + int status = sync_fill_fence_info(fences[i], &fence_info[i]); + info.status = info.status <= 0 ? info.status : status; + } if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info, size)) { @@ -446,7 +454,6 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, no_fences: sync_file_get_name(sync_file, info.name, sizeof(info.name)); - info.status = dma_fence_is_signaled(sync_file->fence); info.num_fences = num_fences; if (copy_to_user((void __user *)arg, &info, sizeof(info))) -- cgit v1.2.3 From d7ba25bd9ef802ff02414e9105f4222d1795f27a Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Wed, 4 Oct 2017 09:48:26 -0700 Subject: drm/i915/edp: Get the Panel Power Off timestamp after panel is off Kernel stores the time in jiffies at which the eDP panel is turned off. This should be obtained after the panel is off (after the wait_panel_off). When we next attempt to turn the panel on, we use the difference between the timestamp at which we want to turn the panel on and timestamp at which panel was turned off to ensure that this is equal to panel power cycle delay and if not we wait for the remaining time. Not waiting for the panel power cycle delay can cause the panel to not turn on giving rise to AUX timeouts for the attempted AUX transactions. v2: * Separate lines for bugzilla (Jani Nikula) * Suggested by tag (Daniel Vetter) Cc: Daniel Vetter Cc: Jani Nikula Cc: stable@vger.kernel.org Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101518 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101144 Suggested-by: Daniel Vetter Signed-off-by: Manasi Navare Reviewed-by: Daniel Vetter Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507135706-17147-1-git-send-email-manasi.d.navare@intel.com (cherry picked from commit cbacf02e7796fea02e5c6e46c90ed7cbe9e6f2c0) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 64134947c0aa..c0f8d7e66049 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2307,8 +2307,8 @@ static void edp_panel_off(struct intel_dp *intel_dp) I915_WRITE(pp_ctrl_reg, pp); POSTING_READ(pp_ctrl_reg); - intel_dp->panel_power_off_time = ktime_get_boottime(); wait_panel_off(intel_dp); + intel_dp->panel_power_off_time = ktime_get_boottime(); /* We got a reference when we enabled the VDD. */ intel_display_power_put(dev_priv, intel_dp->aux_power_domain); -- cgit v1.2.3 From 7313f5a93d2017f789909a7a727a6cab48ea6d20 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 3 Oct 2017 16:37:25 -0700 Subject: drm/i915/edp: Increase the T12 delay quirk to 1300ms For this specific PCI device, the eDP panel requires a higher panel power cycle delay of 1300ms where the minimum spec requirement of panel power cycle delay is 500ms. This fix in combination with correct timestamp at which we get the panel power off time fixes the dP AUX CH timeouts seen on various IGT tests. Fixes: c99a259b4b5192ba ("drm/i915/edp: Add a T12 panel delay quirk to fix DP AUX CH timeouts") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101144 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101518 Cc: Daniel Vetter Cc: Jani Nikula Cc: Ville Syrjala Signed-off-by: Manasi Navare Acked-by: Daniel Vetter Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507073845-13420-2-git-send-email-manasi.d.navare@intel.com (cherry picked from commit c02b8fb4073d1b9aa5af909a91b51056b819d946) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c0f8d7e66049..203198659ab2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5273,7 +5273,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, * seems sufficient to avoid this problem. */ if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) { - vbt.t11_t12 = max_t(u16, vbt.t11_t12, 900 * 10); + vbt.t11_t12 = max_t(u16, vbt.t11_t12, 1300 * 10); DRM_DEBUG_KMS("Increasing T12 panel delay as per the quirk to %d\n", vbt.t11_t12); } -- cgit v1.2.3 From d6a55c63e6adcb58957bbdce2d390088970273da Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 5 Oct 2017 16:15:20 +0200 Subject: drm/i915: Use crtc_state_is_legacy_gamma in intel_color_check crtc_state_is_legacy_gamma also checks for CTM, which was missing from intel_color_check. By using the same condition for commit and check we reduce the chance of mismatches. This was spotted by KASAN while trying to rework kms_color igt test. [ 72.008660] ================================================================== [ 72.009326] BUG: KASAN: slab-out-of-bounds in bdw_load_gamma_lut.isra.3+0x15c/0x360 [i915] [ 72.009519] Read of size 2 at addr ffff880220216e50 by task kms_color/1158 [ 72.009900] CPU: 2 PID: 1158 Comm: kms_color Tainted: G U W 4.14.0-rc3-patser+ #5281 [ 72.009921] Hardware name: GIGABYTE GB-BKi3A-7100/MFLP3AP-00, BIOS F1 07/27/2016 [ 72.009941] Call Trace: [ 72.009968] dump_stack+0xc5/0x151 [ 72.009996] ? _atomic_dec_and_lock+0x10f/0x10f [ 72.010024] ? show_regs_print_info+0x3c/0x3c [ 72.010072] print_address_description+0x7f/0x240 [ 72.010108] kasan_report+0x216/0x370 [ 72.010308] ? bdw_load_gamma_lut.isra.3+0x15c/0x360 [i915] [ 72.010349] __asan_load2+0x74/0x80 [ 72.010552] bdw_load_gamma_lut.isra.3+0x15c/0x360 [i915] [ 72.010772] broadwell_load_luts+0x1f0/0x300 [i915] [ 72.010997] intel_color_load_luts+0x36/0x40 [i915] [ 72.011205] intel_begin_crtc_commit+0xa1/0x310 [i915] [ 72.011283] drm_atomic_helper_commit_planes_on_crtc+0xa6/0x320 [drm_kms_helper] [ 72.011316] ? wait_for_completion_io+0x460/0x460 [ 72.011524] intel_update_crtc+0xe3/0x100 [i915] [ 72.011720] skl_update_crtcs+0x360/0x3f0 [i915] [ 72.011945] ? intel_update_crtcs+0xf0/0xf0 [i915] [ 72.012010] ? drm_atomic_helper_wait_for_dependencies+0x3d9/0x400 [drm_kms_helper] [ 72.012231] intel_atomic_commit_tail+0x8db/0x1500 [i915] [ 72.012273] ? __lock_is_held+0x9c/0xc0 [ 72.012494] ? skl_update_crtcs+0x3f0/0x3f0 [i915] [ 72.012518] ? find_next_bit+0xb/0x10 [ 72.012544] ? cpumask_next+0x1a/0x20 [ 72.012745] ? i915_sw_fence_complete+0x9d/0xe0 [i915] [ 72.012938] ? __i915_sw_fence_complete+0x5d0/0x5d0 [i915] [ 72.013176] intel_atomic_commit+0x528/0x570 [i915] [ 72.013280] ? drm_atomic_get_property+0xc00/0xc00 [drm] [ 72.013466] ? intel_atomic_commit_tail+0x1500/0x1500 [i915] [ 72.013496] ? kmem_cache_alloc_trace+0x266/0x280 [ 72.013714] ? intel_atomic_commit_tail+0x1500/0x1500 [i915] [ 72.013812] drm_atomic_commit+0x77/0x80 [drm] [ 72.013911] set_property_atomic+0x14a/0x210 [drm] [ 72.014015] ? drm_object_property_get_value+0x70/0x70 [drm] [ 72.014080] ? mutex_unlock+0xd/0x10 [ 72.014292] ? intel_atomic_commit_tail+0x1500/0x1500 [i915] [ 72.014379] drm_mode_obj_set_property_ioctl+0x1cf/0x310 [drm] [ 72.014481] ? drm_mode_obj_find_prop_id+0xa0/0xa0 [drm] [ 72.014510] ? lock_release+0x6c0/0x6c0 [ 72.014602] ? drm_is_current_master+0x46/0x60 [drm] [ 72.014706] drm_ioctl_kernel+0x148/0x1d0 [drm] [ 72.014799] ? drm_mode_obj_find_prop_id+0xa0/0xa0 [drm] [ 72.014898] ? drm_ioctl_permit+0x100/0x100 [drm] [ 72.014936] ? kasan_check_write+0x14/0x20 [ 72.015039] drm_ioctl+0x441/0x660 [drm] [ 72.015129] ? drm_mode_obj_find_prop_id+0xa0/0xa0 [drm] [ 72.015235] ? drm_getstats+0x20/0x20 [drm] [ 72.015287] ? ___might_sleep+0x159/0x340 [ 72.015311] ? find_held_lock+0xcf/0xf0 [ 72.015341] ? __schedule_bug+0x110/0x110 [ 72.015405] do_vfs_ioctl+0xa88/0xb10 [ 72.015449] ? ioctl_preallocate+0x1a0/0x1a0 [ 72.015487] ? selinux_capable+0x20/0x20 [ 72.015525] ? rcu_dynticks_momentary_idle+0x40/0x40 [ 72.015607] SyS_ioctl+0x4e/0x80 [ 72.015647] entry_SYSCALL_64_fastpath+0x18/0xad [ 72.015670] RIP: 0033:0x7ff74a3d04d7 [ 72.015691] RSP: 002b:00007ffc594bec08 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 72.015734] RAX: ffffffffffffffda RBX: ffffffff8718f54a RCX: 00007ff74a3d04d7 [ 72.015756] RDX: 00007ffc594bec40 RSI: 00000000c01864ba RDI: 0000000000000003 [ 72.015777] RBP: ffff880211c0ff98 R08: 0000000000000086 R09: 0000000000000000 [ 72.015799] R10: 00007ff74a691b58 R11: 0000000000000246 R12: 0000000000000355 [ 72.015821] R13: 00000000ff00eb00 R14: 0000000000000a00 R15: 00007ff746082000 [ 72.015857] ? trace_hardirqs_off_caller+0xfa/0x110 Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20171005141520.23990-1-maarten.lankhorst@linux.intel.com [mlankhorst: s/crtc_state_is_legacy/&_gamma/ (danvet)] Reviewed-by: Daniel Vetter Fixes: 82cf435b3134 ("drm/i915: Implement color management on bdw/skl/bxt/kbl") Cc: # v4.7+ (cherry picked from commit 0c3767b28186c8129f2a2cfec06a93dcd6102391) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_color.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index ff9ecd211abb..b8315bca852b 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -74,7 +74,7 @@ #define I9XX_CSC_COEFF_1_0 \ ((7 << 12) | I9XX_CSC_COEFF_FP(CTM_COEFF_1_0, 8)) -static bool crtc_state_is_legacy(struct drm_crtc_state *state) +static bool crtc_state_is_legacy_gamma(struct drm_crtc_state *state) { return !state->degamma_lut && !state->ctm && @@ -288,7 +288,7 @@ static void cherryview_load_csc_matrix(struct drm_crtc_state *state) } mode = (state->ctm ? CGM_PIPE_MODE_CSC : 0); - if (!crtc_state_is_legacy(state)) { + if (!crtc_state_is_legacy_gamma(state)) { mode |= (state->degamma_lut ? CGM_PIPE_MODE_DEGAMMA : 0) | (state->gamma_lut ? CGM_PIPE_MODE_GAMMA : 0); } @@ -469,7 +469,7 @@ static void broadwell_load_luts(struct drm_crtc_state *state) struct intel_crtc_state *intel_state = to_intel_crtc_state(state); enum pipe pipe = to_intel_crtc(state->crtc)->pipe; - if (crtc_state_is_legacy(state)) { + if (crtc_state_is_legacy_gamma(state)) { haswell_load_luts(state); return; } @@ -529,7 +529,7 @@ static void glk_load_luts(struct drm_crtc_state *state) glk_load_degamma_lut(state); - if (crtc_state_is_legacy(state)) { + if (crtc_state_is_legacy_gamma(state)) { haswell_load_luts(state); return; } @@ -551,7 +551,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state) uint32_t i, lut_size; uint32_t word0, word1; - if (crtc_state_is_legacy(state)) { + if (crtc_state_is_legacy_gamma(state)) { /* Turn off degamma/gamma on CGM block. */ I915_WRITE(CGM_PIPE_MODE(pipe), (state->ctm ? CGM_PIPE_MODE_CSC : 0)); @@ -632,12 +632,10 @@ int intel_color_check(struct drm_crtc *crtc, return 0; /* - * We also allow no degamma lut and a gamma lut at the legacy + * We also allow no degamma lut/ctm and a gamma lut at the legacy * size (256 entries). */ - if (!crtc_state->degamma_lut && - crtc_state->gamma_lut && - crtc_state->gamma_lut->length == LEGACY_LUT_LENGTH) + if (crtc_state_is_legacy_gamma(crtc_state)) return 0; return -EINVAL; -- cgit v1.2.3 From de3ded0ae677749b4fc9f59d15b26b9f077340ac Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 2 Oct 2017 11:04:16 +0100 Subject: drm/i915: Silence compiler warning for hsw_power_well_enable() Not all compilers are able to determine that pg is guarded by wait_fuses and so may think that pg is used uninitialized. Reported-by: Geert Uytterhoeven Fixes: b2891eb2531e ("drm/i915/hsw+: Add has_fuses power well attribute") Signed-off-by: Chris Wilson Cc: Imre Deak Cc: Arkadiusz Hiler Link: https://patchwork.freedesktop.org/patch/msgid/20171002100416.25865-1-chris@chris-wilson.co.uk Reviewed-by: Imre Deak (cherry picked from commit 320671f94ada80ff036cc9d5dcd730ba4f3e0f1a) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index b3a087cb0860..49577eba8e7e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -368,7 +368,7 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, { enum i915_power_well_id id = power_well->id; bool wait_fuses = power_well->hsw.has_fuses; - enum skl_power_gate pg; + enum skl_power_gate uninitialized_var(pg); u32 val; if (wait_fuses) { -- cgit v1.2.3 From b85577b72837ee8d9213e93d2c8b67ef78a47803 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Oct 2017 12:56:17 +0100 Subject: drm/i915: Order two completing nop_submit_request If two nop's (requests in-flight following a wedged device) complete at the same time, the global_seqno value written to the HWSP is undefined as the two threads are not serialized. v2: Use irqsafe spinlock. We expect the callback may be called from inside another irq spinlock, so we can't unconditionally restore irqs. Fixes: ce1135c7de64 ("drm/i915: Complete requests in nop_submit_request") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20171006115617.18432-1-chris@chris-wilson.co.uk (cherry picked from commit 8d550824c6f52506754f11cb6be51aa153cc580d) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_gem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 19404c96eeb1..af289d35b77a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3013,10 +3013,15 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv) static void nop_submit_request(struct drm_i915_gem_request *request) { + unsigned long flags; + GEM_BUG_ON(!i915_terminally_wedged(&request->i915->gpu_error)); dma_fence_set_error(&request->fence, -EIO); - i915_gem_request_submit(request); + + spin_lock_irqsave(&request->engine->timeline->lock, flags); + __i915_gem_request_submit(request); intel_engine_init_global_seqno(request->engine, request->global_seqno); + spin_unlock_irqrestore(&request->engine->timeline->lock, flags); } static void engine_set_wedged(struct intel_engine_cs *engine) -- cgit v1.2.3 From 7b50f7b24cd6c98541f1af53bddc5b6e861ee8c8 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Apr 2016 18:37:25 +0300 Subject: drm/i915: Read timings from the correct transcoder in intel_crtc_mode_get() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_crtc->config->cpu_transcoder isn't yet filled out when intel_crtc_mode_get() gets called during output probing, so we should not use it there. Instead intel_crtc_mode_get() figures out the correct transcoder on its own, and that's what we should use. If the BIOS boots LVDS on pipe B, intel_crtc_mode_get() would actually end up reading the timings from pipe A instead (since PIPE_A==0), which clearly isn't what we want. It looks to me like this may have been broken by commit eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") as that one removed the early initialization of cpu_transcoder from intel_crtc_init(). Cc: stable@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: Rob Kramer Cc: Daniel Vetter Reported-by: Rob Kramer Fixes: eccb140bca67 ("drm/i915: hw state readout&check support for cpu_transcoder") References: https://lists.freedesktop.org/archives/dri-devel/2016-April/104142.html Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1459525046-19425-1-git-send-email-ville.syrjala@linux.intel.com (cherry picked from commit e30a154b5262b967b133b06ac40777e651045898) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 64f7b51ed97c..5c7828c52d12 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10245,13 +10245,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; + enum transcoder cpu_transcoder; struct drm_display_mode *mode; struct intel_crtc_state *pipe_config; - int htot = I915_READ(HTOTAL(cpu_transcoder)); - int hsync = I915_READ(HSYNC(cpu_transcoder)); - int vtot = I915_READ(VTOTAL(cpu_transcoder)); - int vsync = I915_READ(VSYNC(cpu_transcoder)); + u32 htot, hsync, vtot, vsync; enum pipe pipe = intel_crtc->pipe; mode = kzalloc(sizeof(*mode), GFP_KERNEL); @@ -10279,6 +10276,13 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, i9xx_crtc_clock_get(intel_crtc, pipe_config); mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; + + cpu_transcoder = pipe_config->cpu_transcoder; + htot = I915_READ(HTOTAL(cpu_transcoder)); + hsync = I915_READ(HSYNC(cpu_transcoder)); + vtot = I915_READ(VTOTAL(cpu_transcoder)); + vsync = I915_READ(VSYNC(cpu_transcoder)); + mode->hdisplay = (htot & 0xffff) + 1; mode->htotal = ((htot & 0xffff0000) >> 16) + 1; mode->hsync_start = (hsync & 0xffff) + 1; -- cgit v1.2.3 From 1a2ace56cea2d752b212e198c5e70ff0c0f39b59 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 9 Oct 2017 11:44:53 -0500 Subject: net: thunderx: mark expected switch fall-throughs in nicvf_main() In preparation to enabling -Wimplicit-fallthrough, mark switch cases where we are expecting to fall through. Cc: Sunil Goutham Cc: Robert Richter Cc: linux-arm-kernel@lists.infradead.org Cc: netdev@vger.kernel.org Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller --- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 49b80da51ba7..805ab45e9b5a 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -565,8 +565,10 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, return true; default: bpf_warn_invalid_xdp_action(action); + /* fall through */ case XDP_ABORTED: trace_xdp_exception(nic->netdev, prog, action); + /* fall through */ case XDP_DROP: /* Check if it's a recycled page, if not * unmap the DMA mapping. -- cgit v1.2.3 From 639812a1ed9bf49ae2c026086fbf975339cd1eef Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 9 Oct 2017 13:12:10 -0400 Subject: nbd: don't set the device size until we're connected A user reported a regression with using the normal ioctl interface on newer kernels. This happens because I was setting the device size before the device was actually connected, which caused us to error out and close everything down. This didn't happen on netlink because we hold the device lock the whole time we're setting things up, but we don't do that for the ioctl path. This fixes the problem. Cc: stable@vger.kernel.org Fixes: 29eaadc ("nbd: stop using the bdev everywhere") Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 883dfebd3014..baebbdfd74d5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -243,7 +243,6 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize, struct nbd_config *config = nbd->config; config->blksize = blocksize; config->bytesize = blocksize * nr_blocks; - nbd_size_update(nbd); } static void nbd_complete_rq(struct request *req) @@ -1094,6 +1093,7 @@ static int nbd_start_device(struct nbd_device *nbd) args->index = i; queue_work(recv_workqueue, &args->work); } + nbd_size_update(nbd); return error; } -- cgit v1.2.3 From 6d16dac85c081825af58111023428c43d1da7e1a Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Thu, 31 Aug 2017 15:55:00 -0400 Subject: drm/amdgpu: Set the correct value for PDEs/PTEs of ATC memory on Raven MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without the additional bits set in PDEs/PTEs, the ATC memory access would have failed on Raven. Signed-off-by: Yong Zhao Acked-by: Alex Deucher Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 9 ++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index fee0a32ac56f..b500bb6a8491 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -328,9 +328,10 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, AMDGPU_GEM_CREATE_SHADOW); if (vm->pte_support_ats) { - init_value = AMDGPU_PTE_SYSTEM; + init_value = AMDGPU_PTE_DEFAULT_ATC; if (level != adev->vm_manager.num_level - 1) init_value |= AMDGPU_PDE_PTE; + } /* walk over the address space and allocate the page tables */ @@ -2017,7 +2018,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, list_del(&mapping->list); if (vm->pte_support_ats) - init_pte_value = AMDGPU_PTE_SYSTEM; + init_pte_value = AMDGPU_PTE_DEFAULT_ATC; r = amdgpu_vm_bo_update_mapping(adev, NULL, NULL, vm, mapping->start, mapping->last, @@ -2629,7 +2630,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, if (adev->asic_type == CHIP_RAVEN) { vm->pte_support_ats = true; - init_pde_value = AMDGPU_PTE_SYSTEM | AMDGPU_PDE_PTE; + init_pde_value = AMDGPU_PTE_DEFAULT_ATC + | AMDGPU_PDE_PTE; + } } else vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode & diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index d68f39b4e5e7..aa914256b4bc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -73,6 +73,16 @@ struct amdgpu_bo_list_entry; #define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57) #define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL) +/* For Raven */ +#define AMDGPU_MTYPE_CC 2 + +#define AMDGPU_PTE_DEFAULT_ATC (AMDGPU_PTE_SYSTEM \ + | AMDGPU_PTE_SNOOPED \ + | AMDGPU_PTE_EXECUTABLE \ + | AMDGPU_PTE_READABLE \ + | AMDGPU_PTE_WRITEABLE \ + | AMDGPU_PTE_MTYPE(AMDGPU_MTYPE_CC)) + /* How to programm VM fault handling */ #define AMDGPU_VM_FAULT_STOP_NEVER 0 #define AMDGPU_VM_FAULT_STOP_FIRST 1 -- cgit v1.2.3 From a05502e5cfa9abe17a16592be82c2f5692c91f35 Mon Sep 17 00:00:00 2001 From: Horace Chen Date: Fri, 29 Sep 2017 14:41:57 +0800 Subject: drm/amdgpu: Reserve shared memory on VRAM for SR-IOV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SR-IOV need to reserve a piece of shared VRAM at the exact place to exchange data betweem PF and VF. The start address and size of the shared mem are passed to guest through VBIOS structure VRAM_UsageByFirmware. VRAM_UsageByFirmware is a general feature in VBIOS, it indicates that VBIOS need to reserve a piece of memory on the VRAM. Because the mem address is specified. Reserve it early in amdgpu_ttm_init to make sure that it can monoplize the space. Signed-off-by: Horace Chen Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 18 ++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 76 ++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 ++++ 4 files changed, 116 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index a23b8af95319..5c4bed7778d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1378,6 +1378,18 @@ struct amdgpu_atcs { struct amdgpu_atcs_functions functions; }; +/* + * Firmware VRAM reservation + */ +struct amdgpu_fw_vram_usage { + u64 start_offset; + u64 size; + struct amdgpu_bo *reserved_bo; + void *va; +}; + +int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev); + /* * CGS */ @@ -1582,6 +1594,8 @@ struct amdgpu_device { struct delayed_work late_init_work; struct amdgpu_virt virt; + /* firmware VRAM reservation */ + struct amdgpu_fw_vram_usage fw_vram_usage; /* link all shadow bo */ struct list_head shadow_list; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index ce443586a0c7..f66d33e4baca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -1807,6 +1807,8 @@ int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device *adev) uint16_t data_offset; int usage_bytes = 0; struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; + u64 start_addr; + u64 size; if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); @@ -1815,7 +1817,21 @@ int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device *adev) le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware), le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb)); - usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; + start_addr = firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware; + size = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb; + + if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == + (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << + ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { + /* Firmware request VRAM reservation for SR-IOV */ + adev->fw_vram_usage.start_offset = (start_addr & + (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; + adev->fw_vram_usage.size = size << 10; + /* Use the default scratch size */ + usage_bytes = 0; + } else { + usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; + } } ctx->scratch_size_bytes = 0; if (usage_bytes == 0) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1949d8aedf49..7b3e3b5461c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -657,6 +657,81 @@ void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc) mc->gart_size >> 20, mc->gart_start, mc->gart_end); } +/* + * Firmware Reservation functions + */ +/** + * amdgpu_fw_reserve_vram_fini - free fw reserved vram + * + * @adev: amdgpu_device pointer + * + * free fw reserved vram if it has been reserved. + */ +void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev) +{ + amdgpu_bo_free_kernel(&adev->fw_vram_usage.reserved_bo, + NULL, &adev->fw_vram_usage.va); +} + +/** + * amdgpu_fw_reserve_vram_init - create bo vram reservation from fw + * + * @adev: amdgpu_device pointer + * + * create bo vram reservation from fw. + */ +int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev) +{ + int r = 0; + u64 gpu_addr; + u64 vram_size = adev->mc.visible_vram_size; + + adev->fw_vram_usage.va = NULL; + adev->fw_vram_usage.reserved_bo = NULL; + + if (adev->fw_vram_usage.size > 0 && + adev->fw_vram_usage.size <= vram_size) { + + r = amdgpu_bo_create(adev, adev->fw_vram_usage.size, + PAGE_SIZE, true, 0, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, 0, + &adev->fw_vram_usage.reserved_bo); + if (r) + goto error_create; + + r = amdgpu_bo_reserve(adev->fw_vram_usage.reserved_bo, false); + if (r) + goto error_reserve; + r = amdgpu_bo_pin_restricted(adev->fw_vram_usage.reserved_bo, + AMDGPU_GEM_DOMAIN_VRAM, + adev->fw_vram_usage.start_offset, + (adev->fw_vram_usage.start_offset + + adev->fw_vram_usage.size), &gpu_addr); + if (r) + goto error_pin; + r = amdgpu_bo_kmap(adev->fw_vram_usage.reserved_bo, + &adev->fw_vram_usage.va); + if (r) + goto error_kmap; + + amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo); + } + return r; + +error_kmap: + amdgpu_bo_unpin(adev->fw_vram_usage.reserved_bo); +error_pin: + amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo); +error_reserve: + amdgpu_bo_unref(&adev->fw_vram_usage.reserved_bo); +error_create: + adev->fw_vram_usage.va = NULL; + adev->fw_vram_usage.reserved_bo = NULL; + return r; +} + + /* * GPU helpers function. */ @@ -2300,6 +2375,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) /* evict vram memory */ amdgpu_bo_evict_vram(adev); amdgpu_ib_pool_fini(adev); + amdgpu_fw_reserve_vram_fini(adev); amdgpu_fence_driver_fini(adev); amdgpu_fbdev_fini(adev); r = amdgpu_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 15a28578d458..1f68a146e26c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1255,6 +1255,15 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) /* Change the size here instead of the init above so only lpfn is affected */ amdgpu_ttm_set_active_vram_size(adev, adev->mc.visible_vram_size); + /* + *The reserved vram for firmware must be pinned to the specified + *place on the VRAM, so reserve it early. + */ + r = amdgpu_fw_reserve_vram_init(adev); + if (r) { + return r; + } + r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &adev->stolen_vga_memory, -- cgit v1.2.3 From c6e839a3e299bbff991a3b4136f96ccaca4b276f Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 19 Sep 2017 15:20:42 +0200 Subject: drm/ttm: allocate/free multiple pages in a single call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Totally surprisingly this is more efficient than doing it page by page. Signed-off-by: Christian König Acked-by: Felix Kuehling Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index e11fd76e06f4..482dd9aa2c84 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -873,15 +873,14 @@ int ttm_pool_populate(struct ttm_tt *ttm) if (ttm->state != tt_unpopulated) return 0; - for (i = 0; i < ttm->num_pages; ++i) { - ret = ttm_get_pages(&ttm->pages[i], 1, - ttm->page_flags, - ttm->caching_state); - if (ret != 0) { - ttm_pool_unpopulate(ttm); - return -ENOMEM; - } + ret = ttm_get_pages(ttm->pages, ttm->num_pages, ttm->page_flags, + ttm->caching_state); + if (unlikely(ret != 0)) { + ttm_pool_unpopulate(ttm); + return ret; + } + for (i = 0; i < ttm->num_pages; ++i) { ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i], PAGE_SIZE); if (unlikely(ret != 0)) { @@ -908,14 +907,14 @@ void ttm_pool_unpopulate(struct ttm_tt *ttm) unsigned i; for (i = 0; i < ttm->num_pages; ++i) { - if (ttm->pages[i]) { - ttm_mem_global_free_page(ttm->glob->mem_glob, - ttm->pages[i], PAGE_SIZE); - ttm_put_pages(&ttm->pages[i], 1, - ttm->page_flags, - ttm->caching_state); - } + if (!ttm->pages[i]) + continue; + + ttm_mem_global_free_page(ttm->glob->mem_glob, ttm->pages[i], + PAGE_SIZE); } + ttm_put_pages(ttm->pages, ttm->num_pages, ttm->page_flags, + ttm->caching_state); ttm->state = tt_unpopulated; } EXPORT_SYMBOL(ttm_pool_unpopulate); -- cgit v1.2.3 From 6056a1a565547743c5a87dc3d9c51d086acf9c27 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 20 Sep 2017 14:07:02 +0200 Subject: drm/ttm: DMA map/unmap consecutive pages as a whole v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of mapping them bit by bit map/unmap all consecutive pages as in one call. v2: test for consecutive pages instead of using compound page order. Signed-off-by: Christian König Acked-by: Felix Kuehling Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 48 +++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 482dd9aa2c84..6c852e81660b 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -922,16 +922,26 @@ EXPORT_SYMBOL(ttm_pool_unpopulate); #if defined(CONFIG_SWIOTLB) || defined(CONFIG_INTEL_IOMMU) int ttm_populate_and_map_pages(struct device *dev, struct ttm_dma_tt *tt) { - unsigned i; + unsigned i, j; int r; r = ttm_pool_populate(&tt->ttm); if (r) return r; - for (i = 0; i < tt->ttm.num_pages; i++) { + for (i = 0; i < tt->ttm.num_pages; ++i) { + struct page *p = tt->ttm.pages[i]; + size_t num_pages = 1; + + for (j = i + 1; j < tt->ttm.num_pages; ++j) { + if (++p != tt->ttm.pages[j]) + break; + + ++num_pages; + } + tt->dma_address[i] = dma_map_page(dev, tt->ttm.pages[i], - 0, PAGE_SIZE, + 0, num_pages * PAGE_SIZE, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, tt->dma_address[i])) { while (i--) { @@ -942,6 +952,11 @@ int ttm_populate_and_map_pages(struct device *dev, struct ttm_dma_tt *tt) ttm_pool_unpopulate(&tt->ttm); return -EFAULT; } + + for (j = 1; j < num_pages; ++j) { + tt->dma_address[i + 1] = tt->dma_address[i] + PAGE_SIZE; + ++i; + } } return 0; } @@ -949,13 +964,28 @@ EXPORT_SYMBOL(ttm_populate_and_map_pages); void ttm_unmap_and_unpopulate_pages(struct device *dev, struct ttm_dma_tt *tt) { - unsigned i; - - for (i = 0; i < tt->ttm.num_pages; i++) { - if (tt->dma_address[i]) { - dma_unmap_page(dev, tt->dma_address[i], - PAGE_SIZE, DMA_BIDIRECTIONAL); + unsigned i, j; + + for (i = 0; i < tt->ttm.num_pages;) { + struct page *p = tt->ttm.pages[i]; + size_t num_pages = 1; + + if (!tt->dma_address[i] || !tt->ttm.pages[i]) { + ++i; + continue; } + + for (j = i + 1; j < tt->ttm.num_pages; ++j) { + if (++p != tt->ttm.pages[j]) + break; + + ++num_pages; + } + + dma_unmap_page(dev, tt->dma_address[i], num_pages * PAGE_SIZE, + DMA_BIDIRECTIONAL); + + i += num_pages; } ttm_pool_unpopulate(&tt->ttm); } -- cgit v1.2.3 From 9fc8fc709b356c85034cbcb3b84c9d8b77865f52 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 18 Sep 2017 13:58:30 +0200 Subject: drm/amdgpu: add VM support for huge pages v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert GTT mappings into linear ones for huge page handling. v2: use fragment size as minimum for linear conversion Signed-off-by: Christian König Reviewed-by: Felix Kuehling Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b500bb6a8491..eb4a01c14eee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1699,6 +1699,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, struct drm_mm_node *nodes, struct dma_fence **fence) { + unsigned min_linear_pages = 1 << adev->vm_manager.fragment_size; uint64_t pfn, start = mapping->start; int r; @@ -1733,6 +1734,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, } do { + dma_addr_t *dma_addr = NULL; uint64_t max_entries; uint64_t addr, last; @@ -1746,15 +1748,32 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, } if (pages_addr) { + uint64_t count; + max_entries = min(max_entries, 16ull * 1024ull); - addr = 0; + for (count = 1; count < max_entries; ++count) { + uint64_t idx = pfn + count; + + if (pages_addr[idx] != + (pages_addr[idx - 1] + PAGE_SIZE)) + break; + } + + if (count < min_linear_pages) { + addr = pfn << PAGE_SHIFT; + dma_addr = pages_addr; + } else { + addr = pages_addr[pfn]; + max_entries = count; + } + } else if (flags & AMDGPU_PTE_VALID) { addr += adev->vm_manager.vram_base_offset; + addr += pfn << PAGE_SHIFT; } - addr += pfn << PAGE_SHIFT; last = min((uint64_t)mapping->last, start + max_entries - 1); - r = amdgpu_vm_bo_update_mapping(adev, exclusive, pages_addr, vm, + r = amdgpu_vm_bo_update_mapping(adev, exclusive, dma_addr, vm, start, last, flags, addr, fence); if (r) -- cgit v1.2.3 From b82485fd384a56c27fae44e649552eca6334237a Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 15 Sep 2017 21:05:19 -0400 Subject: drm/amdgpu: add helper to convert a ttm bo to amdgpu_bo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 8 +++----- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 5 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 +++++---- 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 6982baeccd14..8b4ed8a98a18 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -40,9 +40,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) { struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); - struct amdgpu_bo *bo; - - bo = container_of(tbo, struct amdgpu_bo, tbo); + struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); amdgpu_bo_kunmap(bo); @@ -884,7 +882,7 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) return; - abo = container_of(bo, struct amdgpu_bo, tbo); + abo = ttm_to_amdgpu_bo(bo); amdgpu_vm_bo_invalidate(adev, abo, evict); amdgpu_bo_kunmap(abo); @@ -911,7 +909,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) return 0; - abo = container_of(bo, struct amdgpu_bo, tbo); + abo = ttm_to_amdgpu_bo(bo); /* Remember that this BO was accessed by the CPU */ abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 39b6bf6fb051..c26ef53604af 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -94,6 +94,11 @@ struct amdgpu_bo { }; }; +static inline struct amdgpu_bo *ttm_to_amdgpu_bo(struct ttm_buffer_object *tbo) +{ + return container_of(tbo, struct amdgpu_bo, tbo); +} + /** * amdgpu_mem_type_to_domain - return domain corresponding to mem_type * @mem_type: ttm memory type diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 1f68a146e26c..10952c3e5eb6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -44,6 +44,7 @@ #include #include #include "amdgpu.h" +#include "amdgpu_object.h" #include "amdgpu_trace.h" #include "bif/bif_4_1_d.h" @@ -209,7 +210,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, placement->num_busy_placement = 1; return; } - abo = container_of(bo, struct amdgpu_bo, tbo); + abo = ttm_to_amdgpu_bo(bo); switch (bo->mem.mem_type) { case TTM_PL_VRAM: if (adev->mman.buffer_funcs && @@ -257,7 +258,7 @@ gtt: static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) { - struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo); + struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); if (amdgpu_ttm_tt_get_usermm(bo->ttm)) return -EPERM; @@ -484,7 +485,7 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, int r; /* Can't move a pinned BO */ - abo = container_of(bo, struct amdgpu_bo, tbo); + abo = ttm_to_amdgpu_bo(bo); if (WARN_ON_ONCE(abo->pin_count > 0)) return -EINVAL; @@ -1142,7 +1143,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, unsigned long offset, void *buf, int len, int write) { - struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo); + struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); struct drm_mm_node *nodes = abo->tbo.mem.mm_node; uint32_t value = 0; -- cgit v1.2.3 From 177ae09b5d699a5ebd1cafcee78889db968abf54 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 15 Sep 2017 20:44:06 -0400 Subject: drm/amdgpu: introduce AMDGPU_GEM_CREATE_EXPLICIT_SYNC v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a flag to signal that access to a BO will be synchronized through an external mechanism. Currently all buffers shared between contexts are subject to implicit synchronization. However, this is only required for protocols that currently don't support an explicit synchronization mechanism (DRI2/3). This patch introduces the AMDGPU_GEM_CREATE_EXPLICIT_SYNC, so that users can specify when it is safe to disable implicit sync. v2: only disable explicit sync in amdgpu_cs_ioctl Reviewed-by: Christian König Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 4 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 8 ++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 7 +++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 8 ++++---- include/uapi/drm/amdgpu_drm.h | 2 ++ 8 files changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index ab83dfcabb41..38027a00f8ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -705,7 +705,8 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) list_for_each_entry(e, &p->validated, tv.head) { struct reservation_object *resv = e->robj->tbo.resv; - r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp); + r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp, + amdgpu_bo_explicit_sync(e->robj)); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index b0d45c8e6bb3..21e99366cab3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -212,7 +212,9 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, AMDGPU_GEM_CREATE_NO_CPU_ACCESS | AMDGPU_GEM_CREATE_CPU_GTT_USWC | AMDGPU_GEM_CREATE_VRAM_CLEARED | - AMDGPU_GEM_CREATE_VM_ALWAYS_VALID)) + AMDGPU_GEM_CREATE_VM_ALWAYS_VALID | + AMDGPU_GEM_CREATE_EXPLICIT_SYNC)) + return -EINVAL; /* reject invalid gem domains */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index c26ef53604af..428aae048f4b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -193,6 +193,14 @@ static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo) } } +/** + * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced + */ +static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo) +{ + return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC; +} + int amdgpu_bo_create(struct amdgpu_device *adev, unsigned long size, int byte_align, bool kernel, u32 domain, u64 flags, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index c586f44312f9..a4bf21f8f1c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -169,14 +169,14 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, * * @sync: sync object to add fences from reservation object to * @resv: reservation object with embedded fence - * @shared: true if we should only sync to the exclusive fence + * @explicit_sync: true if we should only sync to the exclusive fence * * Sync to the fence */ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync, struct reservation_object *resv, - void *owner) + void *owner, bool explicit_sync) { struct reservation_object_list *flist; struct dma_fence *f; @@ -191,6 +191,9 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, f = reservation_object_get_excl(resv); r = amdgpu_sync_fence(adev, sync, f); + if (explicit_sync) + return r; + flist = reservation_object_get_list(resv); if (!flist || r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h index dc7687993317..70d7e3a279a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h @@ -45,7 +45,8 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync, struct reservation_object *resv, - void *owner); + void *owner, + bool explicit_sync); struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, struct amdgpu_ring *ring); struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 10952c3e5eb6..a2282bacf960 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1489,7 +1489,8 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, job->vm_needs_flush = vm_needs_flush; if (resv) { r = amdgpu_sync_resv(adev, &job->sync, resv, - AMDGPU_FENCE_OWNER_UNDEFINED); + AMDGPU_FENCE_OWNER_UNDEFINED, + false); if (r) { DRM_ERROR("sync failed (%d).\n", r); goto error_free; @@ -1581,7 +1582,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, if (resv) { r = amdgpu_sync_resv(adev, &job->sync, resv, - AMDGPU_FENCE_OWNER_UNDEFINED); + AMDGPU_FENCE_OWNER_UNDEFINED, false); if (r) { DRM_ERROR("sync failed (%d).\n", r); goto error_free; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index eb4a01c14eee..c559d76ff695 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1035,7 +1035,7 @@ static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm, int r; amdgpu_sync_create(&sync); - amdgpu_sync_resv(adev, &sync, vm->root.base.bo->tbo.resv, owner); + amdgpu_sync_resv(adev, &sync, vm->root.base.bo->tbo.resv, owner, false); r = amdgpu_sync_wait(&sync, true); amdgpu_sync_free(&sync); @@ -1176,11 +1176,11 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, amdgpu_ring_pad_ib(ring, params.ib); amdgpu_sync_resv(adev, &job->sync, parent->base.bo->tbo.resv, - AMDGPU_FENCE_OWNER_VM); + AMDGPU_FENCE_OWNER_VM, false); if (shadow) amdgpu_sync_resv(adev, &job->sync, shadow->tbo.resv, - AMDGPU_FENCE_OWNER_VM); + AMDGPU_FENCE_OWNER_VM, false); WARN_ON(params.ib->length_dw > ndw); r = amdgpu_job_submit(job, ring, &vm->entity, @@ -1644,7 +1644,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, goto error_free; r = amdgpu_sync_resv(adev, &job->sync, vm->root.base.bo->tbo.resv, - owner); + owner, false); if (r) goto error_free; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 4c6e8c482ee4..b62484af8ccb 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -91,6 +91,8 @@ extern "C" { #define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS (1 << 5) /* Flag that BO is always valid in this VM */ #define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID (1 << 6) +/* Flag that BO sharing will be explicitly synchronized */ +#define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7) struct drm_amdgpu_gem_create_in { /** the requested memory size */ -- cgit v1.2.3 From c2636dc53abd8269a0930bccd564f2f195dba729 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Thu, 22 Dec 2016 17:06:50 -0500 Subject: drm/amdgpu: add parameter to allocate high priority contexts v11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new context creation parameter to express a global context priority. The priority ranking in descending order is as follows: * AMDGPU_CTX_PRIORITY_HIGH_HW * AMDGPU_CTX_PRIORITY_HIGH_SW * AMDGPU_CTX_PRIORITY_NORMAL * AMDGPU_CTX_PRIORITY_LOW_SW * AMDGPU_CTX_PRIORITY_LOW_HW The driver will attempt to schedule work to the hardware according to the priorities. No latency or throughput guarantees are provided by this patch. This interface intends to service the EGL_IMG_context_priority extension, and vulkan equivalents. Setting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER. v2: Instead of using flags, repurpose __pad v3: Swap enum values of _NORMAL _HIGH for backwards compatibility v4: Validate usermode priority and store it v5: Move priority validation into amdgpu_ctx_ioctl(), headline reword v6: add UAPI note regarding priorities requiring CAP_SYS_ADMIN v7: remove ctx->priority v8: added AMDGPU_CTX_PRIORITY_LOW, s/CAP_SYS_ADMIN/CAP_SYS_NICE v9: change the priority parameter to __s32 v10: split priorities into _SW and _HW v11: Allow DRM_MASTER without CAP_SYS_NICE Reviewed-by: Emil Velikov Reviewed-by: Christian König Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 61 +++++++++++++++++++++++++-- drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 5 ++- include/uapi/drm/amdgpu_drm.h | 10 ++++- 3 files changed, 70 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 75c933b1a432..52388b1b52c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -23,13 +23,40 @@ */ #include +#include #include "amdgpu.h" -static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) +static int amdgpu_ctx_priority_permit(struct drm_file *filp, + enum amd_sched_priority priority) +{ + /* NORMAL and below are accessible by everyone */ + if (priority <= AMD_SCHED_PRIORITY_NORMAL) + return 0; + + if (capable(CAP_SYS_NICE)) + return 0; + + if (drm_is_current_master(filp)) + return 0; + + return -EACCES; +} + +static int amdgpu_ctx_init(struct amdgpu_device *adev, + enum amd_sched_priority priority, + struct drm_file *filp, + struct amdgpu_ctx *ctx) { unsigned i, j; int r; + if (priority < 0 || priority >= AMD_SCHED_PRIORITY_MAX) + return -EINVAL; + + r = amdgpu_ctx_priority_permit(filp, priority); + if (r) + return r; + memset(ctx, 0, sizeof(*ctx)); ctx->adev = adev; kref_init(&ctx->refcount); @@ -51,7 +78,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) struct amdgpu_ring *ring = adev->rings[i]; struct amd_sched_rq *rq; - rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; + rq = &ring->sched.sched_rq[priority]; if (ring == &adev->gfx.kiq.ring) continue; @@ -100,6 +127,8 @@ static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) static int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, + struct drm_file *filp, + enum amd_sched_priority priority, uint32_t *id) { struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; @@ -117,8 +146,9 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, kfree(ctx); return r; } + *id = (uint32_t)r; - r = amdgpu_ctx_init(adev, ctx); + r = amdgpu_ctx_init(adev, priority, filp, ctx); if (r) { idr_remove(&mgr->ctx_handles, *id); *id = 0; @@ -188,11 +218,30 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev, return 0; } +static enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) +{ + switch (amdgpu_priority) { + case AMDGPU_CTX_PRIORITY_HIGH_HW: + return AMD_SCHED_PRIORITY_HIGH_HW; + case AMDGPU_CTX_PRIORITY_HIGH_SW: + return AMD_SCHED_PRIORITY_HIGH_SW; + case AMDGPU_CTX_PRIORITY_NORMAL: + return AMD_SCHED_PRIORITY_NORMAL; + case AMDGPU_CTX_PRIORITY_LOW_SW: + case AMDGPU_CTX_PRIORITY_LOW_HW: + return AMD_SCHED_PRIORITY_LOW; + default: + WARN(1, "Invalid context priority %d\n", amdgpu_priority); + return AMD_SCHED_PRIORITY_NORMAL; + } +} + int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { int r; uint32_t id; + enum amd_sched_priority priority; union drm_amdgpu_ctx *args = data; struct amdgpu_device *adev = dev->dev_private; @@ -200,10 +249,14 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, r = 0; id = args->in.ctx_id; + priority = amdgpu_to_sched_priority(args->in.priority); + + if (priority >= AMD_SCHED_PRIORITY_MAX) + return -EINVAL; switch (args->in.op) { case AMDGPU_CTX_OP_ALLOC_CTX: - r = amdgpu_ctx_alloc(adev, fpriv, &id); + r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id); args->out.alloc.ctx_id = id; break; case AMDGPU_CTX_OP_FREE_CTX: diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index f9d8f28efd16..38e622ce06de 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h @@ -115,7 +115,10 @@ struct amd_sched_backend_ops { enum amd_sched_priority { AMD_SCHED_PRIORITY_MIN, - AMD_SCHED_PRIORITY_NORMAL = AMD_SCHED_PRIORITY_MIN, + AMD_SCHED_PRIORITY_LOW = AMD_SCHED_PRIORITY_MIN, + AMD_SCHED_PRIORITY_NORMAL, + AMD_SCHED_PRIORITY_HIGH_SW, + AMD_SCHED_PRIORITY_HIGH_HW, AMD_SCHED_PRIORITY_KERNEL, AMD_SCHED_PRIORITY_MAX }; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index b62484af8ccb..94ef0af492dc 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -168,13 +168,21 @@ union drm_amdgpu_bo_list { /* unknown cause */ #define AMDGPU_CTX_UNKNOWN_RESET 3 +/* Context priority level */ +#define AMDGPU_CTX_PRIORITY_LOW_HW -1023 +#define AMDGPU_CTX_PRIORITY_LOW_SW -512 +#define AMDGPU_CTX_PRIORITY_NORMAL 0 +/* Selecting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER */ +#define AMDGPU_CTX_PRIORITY_HIGH_SW 512 +#define AMDGPU_CTX_PRIORITY_HIGH_HW 1023 + struct drm_amdgpu_ctx_in { /** AMDGPU_CTX_OP_* */ __u32 op; /** For future use, no flags defined so far */ __u32 flags; __u32 ctx_id; - __u32 _pad; + __s32 priority; }; union drm_amdgpu_ctx_out { -- cgit v1.2.3 From b2ff0e8ac4ce1fb647ae40feb4cf26bc9301e0c9 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Mon, 20 Feb 2017 17:53:19 -0500 Subject: drm/amdgpu: add framework for HW specific priority settings v9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an initial framework for changing the HW priorities of rings. The framework allows requesting priority changes for the lifetime of an amdgpu_job. After the job completes the priority will decay to the next lowest priority for which a request is still valid. A new ring function set_priority() can now be populated to take care of the HW specific programming sequence for priority changes. v2: set priority before emitting IB, and take a ref on amdgpu_job v3: use AMD_SCHED_PRIORITY_* instead of AMDGPU_CTX_PRIORITY_* v4: plug amdgpu_ring_restore_priority_cb into amdgpu_job_free_cb v5: use atomic for tracking job priorities instead of last_job v6: rename amdgpu_ring_priority_[get/put]() and align parameters v7: replace spinlocks with mutexes for KIQ compatibility v8: raise ring priority during cs_ioctl, instead of job_run v9: priority_get() before push_job() Reviewed-by: Christian König Acked-by: Christian König Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 76 ++++++++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 15 ++++++ drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 7 +++ 5 files changed, 103 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 38027a00f8ab..fe7dd44ac9fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1177,6 +1177,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, job->uf_sequence = seq; amdgpu_job_free_resources(job); + amdgpu_ring_priority_get(job->ring, + amd_sched_get_job_priority(&job->base)); trace_amdgpu_cs_ioctl(job); amd_sched_entity_push_job(&job->base); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 4510627ae83e..83d13431cbdd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -103,6 +103,7 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job) { struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); + amdgpu_ring_priority_put(job->ring, amd_sched_get_job_priority(s_job)); dma_fence_put(job->fence); amdgpu_sync_free(&job->sync); amdgpu_sync_free(&job->dep_sync); @@ -139,6 +140,8 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, job->fence_ctx = entity->fence_context; *f = dma_fence_get(&job->base.s_fence->finished); amdgpu_job_free_resources(job); + amdgpu_ring_priority_get(job->ring, + amd_sched_get_job_priority(&job->base)); amd_sched_entity_push_job(&job->base); return 0; @@ -203,6 +206,7 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) /* if gpu reset, hw fence will be replaced here */ dma_fence_put(job->fence); job->fence = dma_fence_get(fence); + amdgpu_job_free_resources(job); return fence; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 019932a7ea3a..e5ece1fae149 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -154,6 +154,75 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) ring->funcs->end_use(ring); } +/** + * amdgpu_ring_priority_put - restore a ring's priority + * + * @ring: amdgpu_ring structure holding the information + * @priority: target priority + * + * Release a request for executing at @priority + */ +void amdgpu_ring_priority_put(struct amdgpu_ring *ring, + enum amd_sched_priority priority) +{ + int i; + + if (!ring->funcs->set_priority) + return; + + if (atomic_dec_return(&ring->num_jobs[priority]) > 0) + return; + + /* no need to restore if the job is already at the lowest priority */ + if (priority == AMD_SCHED_PRIORITY_NORMAL) + return; + + mutex_lock(&ring->priority_mutex); + /* something higher prio is executing, no need to decay */ + if (ring->priority > priority) + goto out_unlock; + + /* decay priority to the next level with a job available */ + for (i = priority; i >= AMD_SCHED_PRIORITY_MIN; i--) { + if (i == AMD_SCHED_PRIORITY_NORMAL + || atomic_read(&ring->num_jobs[i])) { + ring->priority = i; + ring->funcs->set_priority(ring, i); + break; + } + } + +out_unlock: + mutex_unlock(&ring->priority_mutex); +} + +/** + * amdgpu_ring_priority_get - change the ring's priority + * + * @ring: amdgpu_ring structure holding the information + * @priority: target priority + * + * Request a ring's priority to be raised to @priority (refcounted). + */ +void amdgpu_ring_priority_get(struct amdgpu_ring *ring, + enum amd_sched_priority priority) +{ + if (!ring->funcs->set_priority) + return; + + atomic_inc(&ring->num_jobs[priority]); + + mutex_lock(&ring->priority_mutex); + if (priority <= ring->priority) + goto out_unlock; + + ring->priority = priority; + ring->funcs->set_priority(ring, priority); + +out_unlock: + mutex_unlock(&ring->priority_mutex); +} + /** * amdgpu_ring_init - init driver ring struct. * @@ -169,7 +238,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned max_dw, struct amdgpu_irq_src *irq_src, unsigned irq_type) { - int r; + int r, i; int sched_hw_submission = amdgpu_sched_hw_submission; /* Set the hw submission limit higher for KIQ because @@ -247,9 +316,14 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, } ring->max_dw = max_dw; + ring->priority = AMD_SCHED_PRIORITY_NORMAL; + mutex_init(&ring->priority_mutex); INIT_LIST_HEAD(&ring->lru_list); amdgpu_ring_lru_touch(adev, ring); + for (i = 0; i < AMD_SCHED_PRIORITY_MAX; ++i) + atomic_set(&ring->num_jobs[i], 0); + if (amdgpu_debugfs_ring_init(adev, ring)) { DRM_ERROR("Failed to register debugfs file for rings !\n"); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 491bd5512dcc..0d9ce141404c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -24,6 +24,7 @@ #ifndef __AMDGPU_RING_H__ #define __AMDGPU_RING_H__ +#include #include "gpu_scheduler.h" /* max number of rings */ @@ -56,6 +57,7 @@ struct amdgpu_device; struct amdgpu_ring; struct amdgpu_ib; struct amdgpu_cs_parser; +struct amdgpu_job; /* * Fences. @@ -147,6 +149,9 @@ struct amdgpu_ring_funcs { void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg); void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); void (*emit_tmz)(struct amdgpu_ring *ring, bool start); + /* priority functions */ + void (*set_priority) (struct amdgpu_ring *ring, + enum amd_sched_priority priority); }; struct amdgpu_ring { @@ -187,6 +192,12 @@ struct amdgpu_ring { volatile u32 *cond_exe_cpu_addr; unsigned vm_inv_eng; bool has_compute_vm_bug; + + atomic_t num_jobs[AMD_SCHED_PRIORITY_MAX]; + struct mutex priority_mutex; + /* protected by priority_mutex */ + int priority; + #if defined(CONFIG_DEBUG_FS) struct dentry *ent; #endif @@ -197,6 +208,10 @@ void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); void amdgpu_ring_commit(struct amdgpu_ring *ring); void amdgpu_ring_undo(struct amdgpu_ring *ring); +void amdgpu_ring_priority_get(struct amdgpu_ring *ring, + enum amd_sched_priority priority); +void amdgpu_ring_priority_put(struct amdgpu_ring *ring, + enum amd_sched_priority priority); int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned ring_size, struct amdgpu_irq_src *irq_src, unsigned irq_type); diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index 38e622ce06de..dbcaa2e1c5c7 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h @@ -170,4 +170,11 @@ void amd_sched_job_recovery(struct amd_gpu_scheduler *sched); bool amd_sched_dependency_optimized(struct dma_fence* fence, struct amd_sched_entity *entity); void amd_sched_job_kickout(struct amd_sched_job *s_job); + +static inline enum amd_sched_priority +amd_sched_get_job_priority(struct amd_sched_job *job) +{ + return (job->s_entity->rq - job->sched->sched_rq); +} + #endif -- cgit v1.2.3 From b8866c26ec072f1924f5cf601ebea33ca9823326 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 28 Apr 2017 20:05:51 -0400 Subject: drm/amdgpu: implement ring set_priority for gfx_v8 compute v9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Programming CP_HQD_QUEUE_PRIORITY enables a queue to take priority over other queues on the same pipe. Multiple queues on a pipe are timesliced so this gives us full precedence over other queues. Programming CP_HQD_PIPE_PRIORITY changes the SPI_ARB_PRIORITY of the wave as follows: 0x2: CS_H 0x1: CS_M 0x0: CS_L The SPI block will then dispatch work according to the policy set by SPI_ARB_PRIORITY. In the current policy CS_H is higher priority than gfx. In order to prevent getting stuck in loops of resources bouncing between GFX and high priority compute and introducing further latency, we statically reserve a portion of the pipe. v2: fix srbm_select to ring->queue and use ring->funcs->type v3: use AMD_SCHED_PRIORITY_* instead of AMDGPU_CTX_PRIORITY_* v4: switch int to enum amd_sched_priority v5: corresponding changes for srbm_lock v6: change CU reservation to PIPE_PERCENT allocation v7: use kiq instead of MMIO v8: back to MMIO, and make the implementation sleep safe. v9: corresponding changes for splitting HIGH into _HW/_SW Acked-by: Christian König Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 + drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 99 ++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 5c4bed7778d9..715ce4863bc8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1035,6 +1035,10 @@ struct amdgpu_gfx { bool in_suspend; /* NGG */ struct amdgpu_ngg ngg; + + /* pipe reservation */ + struct mutex pipe_reserve_mutex; + DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); }; int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7b3e3b5461c3..412ad99d8871 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2094,6 +2094,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, adev->vm_manager.vm_pte_num_rings = 0; adev->gart.gart_funcs = NULL; adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS); + bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); adev->smc_rreg = &amdgpu_invalid_rreg; adev->smc_wreg = &amdgpu_invalid_wreg; @@ -2122,6 +2123,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->pm.mutex); mutex_init(&adev->gfx.gpu_clock_mutex); mutex_init(&adev->srbm_mutex); + mutex_init(&adev->gfx.pipe_reserve_mutex); mutex_init(&adev->grbm_idx_mutex); mutex_init(&adev->mn_lock); mutex_init(&adev->virt.vf_errors.lock); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 147e92b3a959..51896b7353b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -6394,6 +6394,104 @@ static void gfx_v8_0_ring_set_wptr_compute(struct amdgpu_ring *ring) WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); } +static void gfx_v8_0_ring_set_pipe_percent(struct amdgpu_ring *ring, + bool acquire) +{ + struct amdgpu_device *adev = ring->adev; + int pipe_num, tmp, reg; + int pipe_percent = acquire ? SPI_WCL_PIPE_PERCENT_GFX__VALUE_MASK : 0x1; + + pipe_num = ring->me * adev->gfx.mec.num_pipe_per_mec + ring->pipe; + + /* first me only has 2 entries, GFX and HP3D */ + if (ring->me > 0) + pipe_num -= 2; + + reg = mmSPI_WCL_PIPE_PERCENT_GFX + pipe_num; + tmp = RREG32(reg); + tmp = REG_SET_FIELD(tmp, SPI_WCL_PIPE_PERCENT_GFX, VALUE, pipe_percent); + WREG32(reg, tmp); +} + +static void gfx_v8_0_pipe_reserve_resources(struct amdgpu_device *adev, + struct amdgpu_ring *ring, + bool acquire) +{ + int i, pipe; + bool reserve; + struct amdgpu_ring *iring; + + mutex_lock(&adev->gfx.pipe_reserve_mutex); + pipe = amdgpu_gfx_queue_to_bit(adev, ring->me, ring->pipe, 0); + if (acquire) + set_bit(pipe, adev->gfx.pipe_reserve_bitmap); + else + clear_bit(pipe, adev->gfx.pipe_reserve_bitmap); + + if (!bitmap_weight(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES)) { + /* Clear all reservations - everyone reacquires all resources */ + for (i = 0; i < adev->gfx.num_gfx_rings; ++i) + gfx_v8_0_ring_set_pipe_percent(&adev->gfx.gfx_ring[i], + true); + + for (i = 0; i < adev->gfx.num_compute_rings; ++i) + gfx_v8_0_ring_set_pipe_percent(&adev->gfx.compute_ring[i], + true); + } else { + /* Lower all pipes without a current reservation */ + for (i = 0; i < adev->gfx.num_gfx_rings; ++i) { + iring = &adev->gfx.gfx_ring[i]; + pipe = amdgpu_gfx_queue_to_bit(adev, + iring->me, + iring->pipe, + 0); + reserve = test_bit(pipe, adev->gfx.pipe_reserve_bitmap); + gfx_v8_0_ring_set_pipe_percent(iring, reserve); + } + + for (i = 0; i < adev->gfx.num_compute_rings; ++i) { + iring = &adev->gfx.compute_ring[i]; + pipe = amdgpu_gfx_queue_to_bit(adev, + iring->me, + iring->pipe, + 0); + reserve = test_bit(pipe, adev->gfx.pipe_reserve_bitmap); + gfx_v8_0_ring_set_pipe_percent(iring, reserve); + } + } + + mutex_unlock(&adev->gfx.pipe_reserve_mutex); +} + +static void gfx_v8_0_hqd_set_priority(struct amdgpu_device *adev, + struct amdgpu_ring *ring, + bool acquire) +{ + uint32_t pipe_priority = acquire ? 0x2 : 0x0; + uint32_t queue_priority = acquire ? 0xf : 0x0; + + mutex_lock(&adev->srbm_mutex); + vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); + + WREG32(mmCP_HQD_PIPE_PRIORITY, pipe_priority); + WREG32(mmCP_HQD_QUEUE_PRIORITY, queue_priority); + + vi_srbm_select(adev, 0, 0, 0, 0); + mutex_unlock(&adev->srbm_mutex); +} +static void gfx_v8_0_ring_set_priority_compute(struct amdgpu_ring *ring, + enum amd_sched_priority priority) +{ + struct amdgpu_device *adev = ring->adev; + bool acquire = priority == AMD_SCHED_PRIORITY_HIGH_HW; + + if (ring->funcs->type != AMDGPU_RING_TYPE_COMPUTE) + return; + + gfx_v8_0_hqd_set_priority(adev, ring, acquire); + gfx_v8_0_pipe_reserve_resources(adev, ring, acquire); +} + static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring, u64 addr, u64 seq, unsigned flags) @@ -6839,6 +6937,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { .test_ib = gfx_v8_0_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, .pad_ib = amdgpu_ring_generic_pad_ib, + .set_priority = gfx_v8_0_ring_set_priority_compute, }; static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { -- cgit v1.2.3 From b6d8a439345e71e9b1939c4d6997e09b5be9b5e1 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Wed, 24 May 2017 17:00:10 -0400 Subject: drm/amdgpu: make amdgpu_to_sched_priority detect invalid parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning invalid priorities as _NORMAL is a backwards compatibility quirk of amdgpu_ctx_ioctl(). Move this detail one layer up where it belongs. Signed-off-by: Andres Rodriguez Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 8 +++++--- drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 52388b1b52c2..d3d63f78bec9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -232,7 +232,7 @@ static enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) return AMD_SCHED_PRIORITY_LOW; default: WARN(1, "Invalid context priority %d\n", amdgpu_priority); - return AMD_SCHED_PRIORITY_NORMAL; + return AMD_SCHED_PRIORITY_INVALID; } } @@ -251,8 +251,10 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, id = args->in.ctx_id; priority = amdgpu_to_sched_priority(args->in.priority); - if (priority >= AMD_SCHED_PRIORITY_MAX) - return -EINVAL; + /* For backwards compatibility reasons, we need to accept + * ioctls with garbage in the priority field */ + if (priority == AMD_SCHED_PRIORITY_INVALID) + priority = AMD_SCHED_PRIORITY_NORMAL; switch (args->in.op) { case AMDGPU_CTX_OP_ALLOC_CTX: diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index dbcaa2e1c5c7..da040bc17e61 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h @@ -120,7 +120,8 @@ enum amd_sched_priority { AMD_SCHED_PRIORITY_HIGH_SW, AMD_SCHED_PRIORITY_HIGH_HW, AMD_SCHED_PRIORITY_KERNEL, - AMD_SCHED_PRIORITY_MAX + AMD_SCHED_PRIORITY_MAX, + AMD_SCHED_PRIORITY_INVALID = -1 }; /** -- cgit v1.2.3 From 9ebbaabee858dcecb251d64ecb1e639a1590fff6 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 2 Jun 2017 15:09:00 -0400 Subject: drm/amd/sched: allow clients to edit an entity's rq v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is useful for changing an entity's priority at runtime. v2: don't modify the order of amd_sched_entity members Reviewed-by: Christian König Signed-off-by: Andres Rodriguez Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 24 ++++++++++++++++++++++-- drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 3 +++ 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 08e1332d814a..59f1325d975c 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -133,6 +133,7 @@ int amd_sched_entity_init(struct amd_gpu_scheduler *sched, entity->rq = rq; entity->sched = sched; + spin_lock_init(&entity->rq_lock); spin_lock_init(&entity->queue_lock); r = kfifo_alloc(&entity->job_queue, jobs * sizeof(void *), GFP_KERNEL); if (r) @@ -204,7 +205,6 @@ static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity) void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, struct amd_sched_entity *entity) { - struct amd_sched_rq *rq = entity->rq; int r; if (!amd_sched_entity_is_initialized(sched, entity)) @@ -218,7 +218,7 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, else r = wait_event_killable(sched->job_scheduled, amd_sched_entity_is_idle(entity)); - amd_sched_rq_remove_entity(rq, entity); + amd_sched_entity_set_rq(entity, NULL); if (r) { struct amd_sched_job *job; @@ -257,6 +257,24 @@ static void amd_sched_entity_clear_dep(struct dma_fence *f, struct dma_fence_cb dma_fence_put(f); } +void amd_sched_entity_set_rq(struct amd_sched_entity *entity, + struct amd_sched_rq *rq) +{ + if (entity->rq == rq) + return; + + spin_lock(&entity->rq_lock); + + if (entity->rq) + amd_sched_rq_remove_entity(entity->rq, entity); + + entity->rq = rq; + if (rq) + amd_sched_rq_add_entity(rq, entity); + + spin_unlock(&entity->rq_lock); +} + bool amd_sched_dependency_optimized(struct dma_fence* fence, struct amd_sched_entity *entity) { @@ -354,7 +372,9 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job) /* first job wakes up scheduler */ if (first) { /* Add the entity to the run queue */ + spin_lock(&entity->rq_lock); amd_sched_rq_add_entity(entity->rq, entity); + spin_unlock(&entity->rq_lock); amd_sched_wakeup(sched); } return added; diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index da040bc17e61..4b528f7abbfe 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h @@ -39,6 +39,7 @@ struct amd_sched_rq; struct amd_sched_entity { struct list_head list; struct amd_sched_rq *rq; + spinlock_t rq_lock; struct amd_gpu_scheduler *sched; spinlock_t queue_lock; @@ -154,6 +155,8 @@ int amd_sched_entity_init(struct amd_gpu_scheduler *sched, void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, struct amd_sched_entity *entity); void amd_sched_entity_push_job(struct amd_sched_job *sched_job); +void amd_sched_entity_set_rq(struct amd_sched_entity *entity, + struct amd_sched_rq *rq); int amd_sched_fence_slab_init(void); void amd_sched_fence_slab_fini(void); -- cgit v1.2.3 From f3d19bf80d6c7bfe5922c09604a402ef176da41f Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Mon, 26 Jun 2017 16:12:10 -0400 Subject: drm/amdgpu: introduce AMDGPU_CTX_PRIORITY_UNSET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use _INVALID to identify bad parameters and _UNSET to represent the lack of interest in a specific value. Signed-off-by: Andres Rodriguez Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 2 ++ drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 3 ++- include/uapi/drm/amdgpu_drm.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index d3d63f78bec9..29eebdc30a4c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -230,6 +230,8 @@ static enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) case AMDGPU_CTX_PRIORITY_LOW_SW: case AMDGPU_CTX_PRIORITY_LOW_HW: return AMD_SCHED_PRIORITY_LOW; + case AMDGPU_CTX_PRIORITY_UNSET: + return AMD_SCHED_PRIORITY_UNSET; default: WARN(1, "Invalid context priority %d\n", amdgpu_priority); return AMD_SCHED_PRIORITY_INVALID; diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index 4b528f7abbfe..52c8e5447624 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h @@ -122,7 +122,8 @@ enum amd_sched_priority { AMD_SCHED_PRIORITY_HIGH_HW, AMD_SCHED_PRIORITY_KERNEL, AMD_SCHED_PRIORITY_MAX, - AMD_SCHED_PRIORITY_INVALID = -1 + AMD_SCHED_PRIORITY_INVALID = -1, + AMD_SCHED_PRIORITY_UNSET = -2 }; /** diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 94ef0af492dc..7ea33b57893a 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -169,6 +169,7 @@ union drm_amdgpu_bo_list { #define AMDGPU_CTX_UNKNOWN_RESET 3 /* Context priority level */ +#define AMDGPU_CTX_PRIORITY_UNSET -2048 #define AMDGPU_CTX_PRIORITY_LOW_HW -1023 #define AMDGPU_CTX_PRIORITY_LOW_SW -512 #define AMDGPU_CTX_PRIORITY_NORMAL 0 -- cgit v1.2.3 From c23be4ae1d50e8d93f805de7ae3e8ea49a4ad781 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Tue, 6 Jun 2017 20:20:38 -0400 Subject: drm/amdgpu: add plumbing for ctx priority changes v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce amdgpu_ctx_priority_override(). A mechanism to override a context's priority. An override can be terminated by setting the override to AMD_SCHED_PRIORITY_UNSET. v2: change refcounted interface for a direct set Signed-off-by: Andres Rodriguez Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 +++++- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 715ce4863bc8..951c8db01412 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -735,7 +735,9 @@ struct amdgpu_ctx { spinlock_t ring_lock; struct dma_fence **fences; struct amdgpu_ctx_ring rings[AMDGPU_MAX_RINGS]; - bool preamble_presented; + bool preamble_presented; + enum amd_sched_priority init_priority; + enum amd_sched_priority override_priority; }; struct amdgpu_ctx_mgr { @@ -752,6 +754,8 @@ int amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, struct dma_fence *fence, uint64_t *seq); struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, uint64_t seq); +void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, + enum amd_sched_priority priority); int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 29eebdc30a4c..d2ef24f4b56d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -72,6 +72,8 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, } ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); + ctx->init_priority = priority; + ctx->override_priority = AMD_SCHED_PRIORITY_UNSET; /* create context entity for each ring */ for (i = 0; i < adev->num_rings; i++) { @@ -362,6 +364,33 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, return fence; } +void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, + enum amd_sched_priority priority) +{ + int i; + struct amdgpu_device *adev = ctx->adev; + struct amd_sched_rq *rq; + struct amd_sched_entity *entity; + struct amdgpu_ring *ring; + enum amd_sched_priority ctx_prio; + + ctx->override_priority = priority; + + ctx_prio = (ctx->override_priority == AMD_SCHED_PRIORITY_UNSET) ? + ctx->init_priority : ctx->override_priority; + + for (i = 0; i < adev->num_rings; i++) { + ring = adev->rings[i]; + entity = &ctx->rings[i].entity; + rq = &ring->sched.sched_rq[ctx_prio]; + + if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ) + continue; + + amd_sched_entity_set_rq(entity, rq); + } +} + void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr) { mutex_init(&mgr->lock); -- cgit v1.2.3 From 52c6a62c64fac03a434cdacf6ef671c6a9e9000f Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Mon, 26 Jun 2017 16:17:13 -0400 Subject: drm/amdgpu: add interface for editing a foreign process's priority v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE ioctls are used to set the priority of a different process in the current system. When a request is dropped, the process's contexts will be restored to the priority specified at context creation time. A request can be dropped by setting the override priority to AMDGPU_CTX_PRIORITY_UNSET. An fd is used to identify the remote process. This is simpler than passing a pid number, which is vulnerable to re-use, etc. This functionality is limited to DRM_MASTER since abuse of this interface can have a negative impact on the system's performance. v2: removed unused output structure v3: change refcounted interface for a regular set operation Signed-off-by: Andres Rodriguez Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 21 +----- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 109 ++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h | 34 ++++++++++ include/uapi/drm/amdgpu_drm.h | 17 +++++ 6 files changed, 164 insertions(+), 21 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 25a95c95df14..ef9a3b6d7b62 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -25,7 +25,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \ - amdgpu_queue_mgr.o amdgpu_vf_error.o + amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o # add asic specific block amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index d2ef24f4b56d..a78b03f65c69 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -25,6 +25,7 @@ #include #include #include "amdgpu.h" +#include "amdgpu_sched.h" static int amdgpu_ctx_priority_permit(struct drm_file *filp, enum amd_sched_priority priority) @@ -220,26 +221,6 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev, return 0; } -static enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) -{ - switch (amdgpu_priority) { - case AMDGPU_CTX_PRIORITY_HIGH_HW: - return AMD_SCHED_PRIORITY_HIGH_HW; - case AMDGPU_CTX_PRIORITY_HIGH_SW: - return AMD_SCHED_PRIORITY_HIGH_SW; - case AMDGPU_CTX_PRIORITY_NORMAL: - return AMD_SCHED_PRIORITY_NORMAL; - case AMDGPU_CTX_PRIORITY_LOW_SW: - case AMDGPU_CTX_PRIORITY_LOW_HW: - return AMD_SCHED_PRIORITY_LOW; - case AMDGPU_CTX_PRIORITY_UNSET: - return AMD_SCHED_PRIORITY_UNSET; - default: - WARN(1, "Invalid context priority %d\n", amdgpu_priority); - return AMD_SCHED_PRIORITY_INVALID; - } -} - int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 51841259e23f..82e8d43b235a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -28,6 +28,7 @@ #include #include "amdgpu.h" #include +#include "amdgpu_sched.h" #include "amdgpu_uvd.h" #include "amdgpu_vce.h" @@ -1023,6 +1024,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_VM, amdgpu_vm_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_SCHED, amdgpu_sched_ioctl, DRM_MASTER), DRM_IOCTL_DEF_DRV(AMDGPU_BO_LIST, amdgpu_bo_list_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_FENCE_TO_HANDLE, amdgpu_cs_fence_to_handle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), /* KMS */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c new file mode 100644 index 000000000000..cd123306eda7 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -0,0 +1,109 @@ +/* + * Copyright 2017 Valve Corporation + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Andres Rodriguez + */ + +#include +#include +#include +#include "amdgpu.h" + +#include "amdgpu_vm.h" + +enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) +{ + switch (amdgpu_priority) { + case AMDGPU_CTX_PRIORITY_HIGH_HW: + return AMD_SCHED_PRIORITY_HIGH_HW; + case AMDGPU_CTX_PRIORITY_HIGH_SW: + return AMD_SCHED_PRIORITY_HIGH_SW; + case AMDGPU_CTX_PRIORITY_NORMAL: + return AMD_SCHED_PRIORITY_NORMAL; + case AMDGPU_CTX_PRIORITY_LOW_SW: + case AMDGPU_CTX_PRIORITY_LOW_HW: + return AMD_SCHED_PRIORITY_LOW; + case AMDGPU_CTX_PRIORITY_UNSET: + return AMD_SCHED_PRIORITY_UNSET; + default: + WARN(1, "Invalid context priority %d\n", amdgpu_priority); + return AMD_SCHED_PRIORITY_INVALID; + } +} + +static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, + int fd, + enum amd_sched_priority priority) +{ + struct file *filp = fcheck(fd); + struct drm_file *file; + struct pid *pid; + struct amdgpu_fpriv *fpriv; + struct amdgpu_ctx *ctx; + uint32_t id; + + if (!filp) + return -EINVAL; + + pid = get_pid(((struct drm_file *)filp->private_data)->pid); + + mutex_lock(&adev->ddev->filelist_mutex); + list_for_each_entry(file, &adev->ddev->filelist, lhead) { + if (file->pid != pid) + continue; + + fpriv = file->driver_priv; + idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) + amdgpu_ctx_priority_override(ctx, priority); + } + mutex_unlock(&adev->ddev->filelist_mutex); + + put_pid(pid); + + return 0; +} + +int amdgpu_sched_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + union drm_amdgpu_sched *args = data; + struct amdgpu_device *adev = dev->dev_private; + enum amd_sched_priority priority; + int r; + + priority = amdgpu_to_sched_priority(args->in.priority); + if (args->in.flags || priority == AMD_SCHED_PRIORITY_INVALID) + return -EINVAL; + + switch (args->in.op) { + case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE: + r = amdgpu_sched_process_priority_override(adev, + args->in.fd, + priority); + break; + default: + DRM_ERROR("Invalid sched op specified: %d\n", args->in.op); + r = -EINVAL; + break; + } + + return r; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h new file mode 100644 index 000000000000..b28c067d3822 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Valve Corporation + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Andres Rodriguez + */ + +#ifndef __AMDGPU_SCHED_H__ +#define __AMDGPU_SCHED_H__ + +#include + +enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority); +int amdgpu_sched_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); + +#endif // __AMDGPU_SCHED_H__ diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 7ea33b57893a..a332de1aeb42 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -53,6 +53,7 @@ extern "C" { #define DRM_AMDGPU_WAIT_FENCES 0x12 #define DRM_AMDGPU_VM 0x13 #define DRM_AMDGPU_FENCE_TO_HANDLE 0x14 +#define DRM_AMDGPU_SCHED 0x15 #define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) #define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap) @@ -69,6 +70,7 @@ extern "C" { #define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences) #define DRM_IOCTL_AMDGPU_VM DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm) #define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle) +#define DRM_IOCTL_AMDGPU_SCHED DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched) #define AMDGPU_GEM_DOMAIN_CPU 0x1 #define AMDGPU_GEM_DOMAIN_GTT 0x2 @@ -227,6 +229,21 @@ union drm_amdgpu_vm { struct drm_amdgpu_vm_out out; }; +/* sched ioctl */ +#define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1 + +struct drm_amdgpu_sched_in { + /* AMDGPU_SCHED_OP_* */ + __u32 op; + __u32 fd; + __s32 priority; + __u32 flags; +}; + +union drm_amdgpu_sched { + struct drm_amdgpu_sched_in in; +}; + /* * This is not a reliable API and you should expect it to fail for any * number of reasons and have fallback path that do not use userptr to -- cgit v1.2.3 From 2de3813880bf16deff8223add4d7e1872c7a9e77 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 22 Sep 2017 17:53:42 -0300 Subject: drm/i915: add the BXT and CNL DPLL registers to pipe_config_compare Looks like we were missing them. Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20170922205343.16006-2-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a1182eeee5af..45d6e57fbe89 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11327,6 +11327,18 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1); PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1); PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2); + PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0); + PIPE_CONF_CHECK_X(dpll_hw_state.ebb0); + PIPE_CONF_CHECK_X(dpll_hw_state.ebb4); + PIPE_CONF_CHECK_X(dpll_hw_state.pll0); + PIPE_CONF_CHECK_X(dpll_hw_state.pll1); + PIPE_CONF_CHECK_X(dpll_hw_state.pll2); + PIPE_CONF_CHECK_X(dpll_hw_state.pll3); + PIPE_CONF_CHECK_X(dpll_hw_state.pll6); + PIPE_CONF_CHECK_X(dpll_hw_state.pll8); + PIPE_CONF_CHECK_X(dpll_hw_state.pll9); + PIPE_CONF_CHECK_X(dpll_hw_state.pll10); + PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12); PIPE_CONF_CHECK_X(dsi_pll.ctrl); PIPE_CONF_CHECK_X(dsi_pll.div); -- cgit v1.2.3 From 0e005888b833ba65dcf2c7aa12958dad6b2b8618 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Thu, 5 Oct 2017 18:38:42 -0300 Subject: drm/i915: avoid division by zero on cnl_calc_wrpll_link If for some unexpected reason the registers all read zero it's better to WARN and return instead of dividing by zero and completely freezing the machine. I don't expect this to happen in the wild with the current code, but I accidentally triggered the division by zero while doing some debugging in an unusual environment. Cc: Rodrigo Vivi Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20171005213842.11423-2-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ce4b7335a78a..b307b6fe1ce3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1220,6 +1220,9 @@ static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, dco_freq += (((cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >> DPLL_CFGCR0_DCO_FRACTION_SHIFT) * ref_clock) / 0x8000; + if (WARN_ON(p0 == 0 || p1 == 0 || p2 == 0)) + return 0; + return dco_freq / (p0 * p1 * p2 * 5); } -- cgit v1.2.3 From fdfbad3256918fc5736d68384331d2dbf45ccbd6 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 9 Oct 2017 14:05:12 +0200 Subject: cdc_ether: flag the u-blox TOBY-L2 and SARA-U2 as wwan The u-blox TOBY-L2 is a LTE Cat 4 module with HSPA+ and 2G fallback. This module allows switching to different USB profiles with the 'AT+UUSBCONF' command, and provides a ECM network interface when the 'AT+UUSBCONF=2' profile is selected. The u-blox SARA-U2 is a HSPA module with 2G fallback. The default USB configuration includes a ECM network interface. Both these modules are controlled via AT commands through one of the TTYs exposed. Connecting these modules may be done just by activating the desired PDP context with 'AT+CGACT=1,' and then running DHCP on the ECM interface. Signed-off-by: Aleksander Morgado Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 29c7e2ec0dcb..52ea80bcd639 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -560,6 +560,7 @@ static const struct driver_info wwan_info = { #define NVIDIA_VENDOR_ID 0x0955 #define HP_VENDOR_ID 0x03f0 #define MICROSOFT_VENDOR_ID 0x045e +#define UBLOX_VENDOR_ID 0x1546 static const struct usb_device_id products[] = { /* BLACKLIST !! @@ -868,6 +869,18 @@ static const struct usb_device_id products[] = { USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&zte_cdc_info, +}, { + /* U-blox TOBY-L2 */ + USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1143, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&wwan_info, +}, { + /* U-blox SARA-U2 */ + USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1104, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&wwan_info, }, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- cgit v1.2.3 From 5ab894aee0f171a682bcd90dd5d1930cb53c55dc Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 9 Oct 2017 16:28:37 +0300 Subject: device property: Track owner device of device property Deletion of subdevice will remove device properties associated to parent when they share the same firmware node after commit 478573c93abd (driver core: Don't leak secondary fwnode on device removal). This was observed with a driver adding subdevice that driver wasn't able to read device properties after rmmod/modprobe cycle. Consider the lifecycle of it: parent device registration ACPI_COMPANION_SET() device_add_properties() pset_copy_set() set_secondary_fwnode(dev, &p->fwnode) device_add() parent probe read device properties ACPI_COMPANION_SET(subdevice, ACPI_COMPANION(parent)) device_add(subdevice) parent remove device_del(subdevice) device_remove_properties() set_secondary_fwnode(dev, NULL); pset_free() Parent device will have its primary firmware node pointing to an ACPI node and secondary firmware node point to device properties. ACPI_COMPANION_SET() call in parent probe will set the subdevice's firmware node to point to the same 'struct fwnode_handle' and the associated secondary firmware node, i.e. the device properties as the parent. When subdevice is deleted in parent remove that will remove those device properties and attempt to read device properties in next parent probe call will fail. Fix this by tracking the owner device of device properties and delete them only when owner device is being deleted. Fixes: 478573c93abd (driver core: Don't leak secondary fwnode on device removal) Cc: 4.9+ # 4.9+ Signed-off-by: Jarkko Nikula Signed-off-by: Rafael J. Wysocki --- drivers/base/property.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/base/property.c b/drivers/base/property.c index d0b65bbe7e15..21fcc13013a5 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -21,6 +21,7 @@ #include struct property_set { + struct device *dev; struct fwnode_handle fwnode; const struct property_entry *properties; }; @@ -891,6 +892,7 @@ static struct property_set *pset_copy_set(const struct property_set *pset) void device_remove_properties(struct device *dev) { struct fwnode_handle *fwnode; + struct property_set *pset; fwnode = dev_fwnode(dev); if (!fwnode) @@ -900,16 +902,16 @@ void device_remove_properties(struct device *dev) * the pset. If there is no real firmware node (ACPI/DT) primary * will hold the pset. */ - if (is_pset_node(fwnode)) { + pset = to_pset_node(fwnode); + if (pset) { set_primary_fwnode(dev, NULL); - pset_free_set(to_pset_node(fwnode)); } else { - fwnode = fwnode->secondary; - if (!IS_ERR(fwnode) && is_pset_node(fwnode)) { + pset = to_pset_node(fwnode->secondary); + if (pset && dev == pset->dev) set_secondary_fwnode(dev, NULL); - pset_free_set(to_pset_node(fwnode)); - } } + if (pset && dev == pset->dev) + pset_free_set(pset); } EXPORT_SYMBOL_GPL(device_remove_properties); @@ -938,6 +940,7 @@ int device_add_properties(struct device *dev, p->fwnode.ops = &pset_fwnode_ops; set_secondary_fwnode(dev, &p->fwnode); + p->dev = dev; return 0; } EXPORT_SYMBOL_GPL(device_add_properties); -- cgit v1.2.3 From 2b30297d481ad305134252557768c22391e0fed6 Mon Sep 17 00:00:00 2001 From: Andrew Duggan Date: Mon, 9 Oct 2017 20:51:05 -0700 Subject: Input: synaptics - disable kernel tracking on SMBus devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In certain situations kernel tracking seems to be getting confused and incorrectly reporting the slot of a contact. On example is when the user does a three finger click or tap and then places two fingers on the touchpad in the same area. The kernel tracking code seems to continue to think that there are three contacts on the touchpad and incorrectly alternates the slot of one of the contacts. The result that is the input subsystem reports a stream of button press and release events as the reported slot changes. Kernel tracking was originally enabled to prevent cursor jumps, but it is unclear how much of an issue kernel jumps actually are. This patch simply disabled kernel tracking for now. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1482640 Signed-off-by: Andrew Duggan Tested-by: Kamil Páral Acked-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 5af0b7d200bc..ee5466a374bf 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1709,8 +1709,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse, .sensor_pdata = { .sensor_type = rmi_sensor_touchpad, .axis_align.flip_y = true, - /* to prevent cursors jumps: */ - .kernel_tracking = true, + .kernel_tracking = false, .topbuttonpad = topbuttonpad, }, .f30_data = { -- cgit v1.2.3 From 348e4058ebf53904e817eec7a1b25327143c2ed2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:21:57 +0300 Subject: drm/i915/bios: parse DDI ports also for CHV for HDMI DDC pin and DP AUX channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While technically CHV isn't DDI, we do look at the VBT based DDI port info for HDMI DDC pin and DP AUX channel. (We call these "alternate", but they're really just something that aren't platform defaults.) In commit e4ab73a13291 ("drm/i915: Respect alternate_ddc_pin for all DDI ports") Ville writes, "IIRC there may be CHV system that might actually need this." I'm not sure why there couldn't be even more platforms that need this, but start conservative, and parse the info for CHV in addition to DDI. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100553 Reported-by: Marek Wilczewski Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d0815082cb98487618429b62414854137049b888.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b881ce8596ee..0a1159761ffd 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1240,7 +1240,7 @@ static void parse_ddi_ports(struct drm_i915_private *dev_priv, { enum port port; - if (!HAS_DDI(dev_priv)) + if (!HAS_DDI(dev_priv) && !IS_CHERRYVIEW(dev_priv)) return; if (!dev_priv->vbt.child_dev_num) -- cgit v1.2.3 From a87145ca56d14fc4b0bce68c18a5fecb01a09540 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:21:58 +0300 Subject: drm/i915/bios: refactor parse general definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Early return on failures. Rename the variable for later merging with parse_device_mappings(). Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/785abb904a572752fec68d90d34efeb67774dc1f.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 0a1159761ffd..22924612c680 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -435,21 +435,27 @@ static void parse_general_definitions(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) { - const struct bdb_general_definitions *general; - - general = find_section(bdb, BDB_GENERAL_DEFINITIONS); - if (general) { - u16 block_size = get_blocksize(general); - if (block_size >= sizeof(*general)) { - int bus_pin = general->crt_ddc_gmbus_pin; - DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); - if (intel_gmbus_is_valid_pin(dev_priv, bus_pin)) - dev_priv->vbt.crt_ddc_pin = bus_pin; - } else { - DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n", - block_size); - } + const struct bdb_general_definitions *defs; + u16 block_size; + int bus_pin; + + defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); + if (!defs) { + DRM_DEBUG_KMS("General definitions block not found\n"); + return; + } + + block_size = get_blocksize(defs); + if (block_size < sizeof(*defs)) { + DRM_DEBUG_KMS("General definitions block too small (%u)\n", + block_size); + return; } + + bus_pin = defs->crt_ddc_gmbus_pin; + DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); + if (intel_gmbus_is_valid_pin(dev_priv, bus_pin)) + dev_priv->vbt.crt_ddc_pin = bus_pin; } static const struct child_device_config * -- cgit v1.2.3 From 2d936f1cf78fe84c05642545abe052488e7adad4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:21:59 +0300 Subject: drm/i915/bios: don't initialize fields based on vbt version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In theory, these might clobber information for older VBT versions. We might have to store the BDB version for later parsing, but currently all code accessing these fields will only use them on newer platforms with new enough BDB versions. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0232d9cb258e8f83c4180cdb8aad1459a312ec2a.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 22924612c680..c91cdf131465 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1347,19 +1347,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, */ memcpy(child_dev_ptr, child, min_t(size_t, defs->child_dev_size, sizeof(*child))); - - /* - * copied full block, now init values when they are not - * available in current version - */ - if (bdb->version < 196) { - /* Set default values for bits added from v196 */ - child_dev_ptr->iboost = 0; - child_dev_ptr->hpd_invert = 0; - } - - if (bdb->version < 192) - child_dev_ptr->lspcon = 0; } return; } -- cgit v1.2.3 From 127704f5475a1913c284efa08376ec89ec513789 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:22:00 +0300 Subject: drm/i915/bios: remove an unnecessary temp variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepare for merging parse_device_mapping() into parse_general_definitions(). No functional changes. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/f1c3621e2622f4debdfb4a2f5c1959845754ac04.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index c91cdf131465..2b72a7a520ce 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1265,7 +1265,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, { const struct bdb_general_definitions *defs; const struct child_device_config *child; - struct child_device_config *child_dev_ptr; int i, child_device_num, count; u8 expected_size; u16 block_size; @@ -1337,16 +1336,14 @@ parse_device_mapping(struct drm_i915_private *dev_priv, continue; } - child_dev_ptr = dev_priv->vbt.child_dev + count; - count++; - /* * Copy as much as we know (sizeof) and is available * (child_dev_size) of the child device. Accessing the data must * depend on VBT version. */ - memcpy(child_dev_ptr, child, + memcpy(dev_priv->vbt.child_dev + count, child, min_t(size_t, defs->child_dev_size, sizeof(*child))); + count++; } return; } -- cgit v1.2.3 From 53f6b2436e7ba3d5f9b3b6b2d2b42089d64690e8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:22:01 +0300 Subject: drm/i915/bios: cleanup comments and useless return MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/4a95fb9d23d980830e3158d3c57258e6539965ce.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 2b72a7a520ce..edc218e5eead 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1311,10 +1311,8 @@ parse_device_mapping(struct drm_i915_private *dev_priv, /* get the number of child device that is present */ for (i = 0; i < child_device_num; i++) { child = child_device_ptr(defs, i); - if (!child->device_type) { - /* skip the device block if device type is invalid */ + if (!child->device_type) continue; - } count++; } if (!count) { @@ -1331,10 +1329,8 @@ parse_device_mapping(struct drm_i915_private *dev_priv, count = 0; for (i = 0; i < child_device_num; i++) { child = child_device_ptr(defs, i); - if (!child->device_type) { - /* skip the device block if device type is invalid */ + if (!child->device_type) continue; - } /* * Copy as much as we know (sizeof) and is available @@ -1345,7 +1341,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, min_t(size_t, defs->child_dev_size, sizeof(*child))); count++; } - return; } /* Common defaults which may be overridden by VBT. */ -- cgit v1.2.3 From b3ca1f43b285dd74daa8ef87cce41bc50434a865 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:22:02 +0300 Subject: drm/i915/bios: merge parse_device_mapping() into parse_general_definitions() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They're both parsing the same block, and there's no need for them to be split. The former also benefits from the range checks in the latter. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/64a292606ecbb0b8602e6c5523c5746573ec3944.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 48 +++++++++++++-------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index edc218e5eead..aaad984e35e2 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -431,33 +431,6 @@ parse_general_features(struct drm_i915_private *dev_priv, dev_priv->vbt.fdi_rx_polarity_inverted); } -static void -parse_general_definitions(struct drm_i915_private *dev_priv, - const struct bdb_header *bdb) -{ - const struct bdb_general_definitions *defs; - u16 block_size; - int bus_pin; - - defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); - if (!defs) { - DRM_DEBUG_KMS("General definitions block not found\n"); - return; - } - - block_size = get_blocksize(defs); - if (block_size < sizeof(*defs)) { - DRM_DEBUG_KMS("General definitions block too small (%u)\n", - block_size); - return; - } - - bus_pin = defs->crt_ddc_gmbus_pin; - DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); - if (intel_gmbus_is_valid_pin(dev_priv, bus_pin)) - dev_priv->vbt.crt_ddc_pin = bus_pin; -} - static const struct child_device_config * child_device_ptr(const struct bdb_general_definitions *defs, int i) { @@ -1260,20 +1233,34 @@ static void parse_ddi_ports(struct drm_i915_private *dev_priv, } static void -parse_device_mapping(struct drm_i915_private *dev_priv, - const struct bdb_header *bdb) +parse_general_definitions(struct drm_i915_private *dev_priv, + const struct bdb_header *bdb) { const struct bdb_general_definitions *defs; const struct child_device_config *child; int i, child_device_num, count; u8 expected_size; u16 block_size; + int bus_pin; defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); if (!defs) { DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); return; } + + block_size = get_blocksize(defs); + if (block_size < sizeof(*defs)) { + DRM_DEBUG_KMS("General definitions block too small (%u)\n", + block_size); + return; + } + + bus_pin = defs->crt_ddc_gmbus_pin; + DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); + if (intel_gmbus_is_valid_pin(dev_priv, bus_pin)) + dev_priv->vbt.crt_ddc_pin = bus_pin; + if (bdb->version < 106) { expected_size = 22; } else if (bdb->version < 111) { @@ -1303,8 +1290,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, return; } - /* get the block size of general definitions */ - block_size = get_blocksize(defs); /* get the number of child device */ child_device_num = (block_size - sizeof(*defs)) / defs->child_dev_size; count = 0; @@ -1522,7 +1507,6 @@ void intel_bios_init(struct drm_i915_private *dev_priv) parse_lfp_backlight(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); - parse_device_mapping(dev_priv, bdb); parse_driver_features(dev_priv, bdb); parse_edp(dev_priv, bdb); parse_psr(dev_priv, bdb); -- cgit v1.2.3 From 0ebdabe6126498f06cd1885dfbf658c46317041f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:22:03 +0300 Subject: drm/i915/bios: parse SDVO device mapping from pre-parsed child devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We parse and store the child devices in parse_general_definitions(). There is no need to parse the VBT block again for SDVO device mapping. Do the same as we do in parse_ddi_ports(). We no longer have access to child device size at this stage, but we also don't need to worry about reading past the child device anymore. Instead of a child device size check, do a mild optimization by limiting the parsing to gens 3 through 7. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c918d4173dd38a165295f1270cb16c2c01bd8cd1.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index aaad984e35e2..4d26fcc5cabb 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -442,37 +442,21 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) { struct sdvo_device_mapping *mapping; - const struct bdb_general_definitions *defs; const struct child_device_config *child; - int i, child_device_num, count; - u16 block_size; - - defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); - if (!defs) { - DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); - return; - } + int i, count = 0; /* - * Only parse SDVO mappings when the general definitions block child - * device size matches that of the *legacy* child device config - * struct. Thus, SDVO mapping will be skipped for newer VBT. + * Only parse SDVO mappings on gens that could have SDVO. This isn't + * accurate and doesn't have to be, as long as it's not too strict. */ - if (defs->child_dev_size != LEGACY_CHILD_DEVICE_CONFIG_SIZE) { - DRM_DEBUG_KMS("Unsupported child device size for SDVO mapping.\n"); + if (!IS_GEN(dev_priv, 3, 7)) { + DRM_DEBUG_KMS("Skipping SDVO device mapping\n"); return; } - /* get the block size of general definitions */ - block_size = get_blocksize(defs); - /* get the number of child device */ - child_device_num = (block_size - sizeof(*defs)) / defs->child_dev_size; - count = 0; - for (i = 0; i < child_device_num; i++) { - child = child_device_ptr(defs, i); - if (!child->device_type) { - /* skip the device block if device type is invalid */ - continue; - } + + for (i = 0, count = 0; i < dev_priv->vbt.child_dev_num; i++) { + child = dev_priv->vbt.child_dev + i; + if (child->slave_addr != SLAVE_ADDR1 && child->slave_addr != SLAVE_ADDR2) { /* @@ -523,7 +507,6 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, /* No SDVO device info is found */ DRM_DEBUG_KMS("No SDVO device info is found in VBT\n"); } - return; } static void @@ -1506,12 +1489,14 @@ void intel_bios_init(struct drm_i915_private *dev_priv) parse_lfp_panel_data(dev_priv, bdb); parse_lfp_backlight(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); - parse_sdvo_device_mapping(dev_priv, bdb); parse_driver_features(dev_priv, bdb); parse_edp(dev_priv, bdb); parse_psr(dev_priv, bdb); parse_mipi_config(dev_priv, bdb); parse_mipi_sequence(dev_priv, bdb); + + /* Further processing on pre-parsed data */ + parse_sdvo_device_mapping(dev_priv, bdb); parse_ddi_ports(dev_priv, bdb); out: -- cgit v1.2.3 From 0ead5f81d4200b63cf92be867bfbd6708056e4a8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:22:04 +0300 Subject: drm/i915/bios: don't pass bdb to parsers that don't parse VBT directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hint that you're not supposed to look at VBT in these functions. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b82c326be8c796a70bdc2bd1c479bbb6159f5cb0.1506586821.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4d26fcc5cabb..9d5b42953436 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -438,8 +438,7 @@ child_device_ptr(const struct bdb_general_definitions *defs, int i) } static void -parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, - const struct bdb_header *bdb) +parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, u8 bdb_version) { struct sdvo_device_mapping *mapping; const struct child_device_config *child; @@ -1073,7 +1072,7 @@ static void sanitize_aux_ch(struct drm_i915_private *dev_priv, } static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, - const struct bdb_header *bdb) + u8 bdb_version) { struct child_device_config *it, *child = NULL; struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port]; @@ -1177,7 +1176,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, sanitize_aux_ch(dev_priv, port); } - if (bdb->version >= 158) { + if (bdb_version >= 158) { /* The VBT HDMI level shift values match the table we have. */ hdmi_level_shift = child->hdmi_level_shifter_value; DRM_DEBUG_KMS("VBT HDMI level shift for port %c: %d\n", @@ -1187,7 +1186,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, } /* Parse the I_boost config for SKL and above */ - if (bdb->version >= 196 && child->iboost) { + if (bdb_version >= 196 && child->iboost) { info->dp_boost_level = translate_iboost(child->dp_iboost_level); DRM_DEBUG_KMS("VBT (e)DP boost level for port %c: %d\n", port_name(port), info->dp_boost_level); @@ -1197,8 +1196,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, } } -static void parse_ddi_ports(struct drm_i915_private *dev_priv, - const struct bdb_header *bdb) +static void parse_ddi_ports(struct drm_i915_private *dev_priv, u8 bdb_version) { enum port port; @@ -1208,11 +1206,11 @@ static void parse_ddi_ports(struct drm_i915_private *dev_priv, if (!dev_priv->vbt.child_dev_num) return; - if (bdb->version < 155) + if (bdb_version < 155) return; for (port = PORT_A; port < I915_MAX_PORTS; port++) - parse_ddi_port(dev_priv, port, bdb); + parse_ddi_port(dev_priv, port, bdb_version); } static void @@ -1496,8 +1494,8 @@ void intel_bios_init(struct drm_i915_private *dev_priv) parse_mipi_sequence(dev_priv, bdb); /* Further processing on pre-parsed data */ - parse_sdvo_device_mapping(dev_priv, bdb); - parse_ddi_ports(dev_priv, bdb); + parse_sdvo_device_mapping(dev_priv, bdb->version); + parse_ddi_ports(dev_priv, bdb->version); out: if (!vbt) { -- cgit v1.2.3 From eb701ce16a45ed9880897c48f05ee608d77c72e3 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 9 Oct 2017 10:24:01 +0300 Subject: mmc: sdhci-pci: Fix default d3_retune for Intel host controllers The default for d3_retune is true, but that was not being set in all cases, which results in eMMC errors because re-tuning has not been done. Fix by initializing d3_retune to true. Signed-off-by: Adrian Hunter Fixes: c959a6b00ff5 ("mmc: sdhci-pci: Don't re-tune with runtime pm for some Intel devices") Cc: stable@vger.kernel.org # v4.12+ Reported-and-tested-by: ojab Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-pci-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index d0ccc6729fd2..67d787fa3306 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -448,6 +448,8 @@ static void intel_dsm_init(struct intel_host *intel_host, struct device *dev, int err; u32 val; + intel_host->d3_retune = true; + err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns); if (err) { pr_debug("%s: DSM not supported, error %d\n", -- cgit v1.2.3 From 5a866ec0014b2baa4ecbb1eaa19c835482829d08 Mon Sep 17 00:00:00 2001 From: Maxime Chevallier Date: Tue, 10 Oct 2017 10:43:17 +0200 Subject: spi: a3700: Return correct value on timeout detection When waiting for transfer completion, a3700_spi_wait_completion returns a boolean indicating if a timeout occurred. The function was returning 'true' everytime, failing to detect any timeout. This patch makes it return 'false' when a timeout is reached. Signed-off-by: Maxime Chevallier Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-armada-3700.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index 9172cb2d2e7a..568e1c65aa82 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -387,7 +387,8 @@ static bool a3700_spi_wait_completion(struct spi_device *spi) spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0); - return true; + /* Timeout was reached */ + return false; } static bool a3700_spi_transfer_wait(struct spi_device *spi, -- cgit v1.2.3 From 3bc3e0ecef69bf8061f89b6f2971ca9d88c669ea Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 15:22:22 +0200 Subject: drm/etnaviv: remove iommu fault handler The handler has never been used, so it's really just dead code. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-By: Wladimir J. van der Laan --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index f103e787de94..f3ed07db9b2d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -22,13 +22,6 @@ #include "etnaviv_iommu.h" #include "etnaviv_mmu.h" -static int etnaviv_fault_handler(struct iommu_domain *iommu, struct device *dev, - unsigned long iova, int flags, void *arg) -{ - DBG("*** fault: iova=%08lx, flags=%d", iova, flags); - return 0; -} - int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, struct sg_table *sgt, unsigned len, int prot) { @@ -307,8 +300,6 @@ struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu) mmu->domain->geometry.aperture_end - mmu->domain->geometry.aperture_start + 1); - iommu_set_fault_handler(mmu->domain, etnaviv_fault_handler, gpu->dev); - return mmu; } -- cgit v1.2.3 From 87ceb3756030d284c1e8424877a34b5452906549 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 15:27:00 +0200 Subject: drm/etnaviv: remove iova_to_phys iommu ops They are not used in any way, so can go away. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-By: Wladimir J. van der Laan --- drivers/gpu/drm/etnaviv/etnaviv_iommu.c | 21 --------------------- drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c | 14 -------------- 2 files changed, 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index 7a7c97f599d7..f804c0aaa7a2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c @@ -66,18 +66,6 @@ static void pgtable_free(struct etnaviv_iommu_domain_pgtable *pgtable, dma_free_coherent(NULL, size, pgtable->pgtable, pgtable->paddr); } -static u32 pgtable_read(struct etnaviv_iommu_domain_pgtable *pgtable, - unsigned long iova) -{ - /* calcuate index into page table */ - unsigned int index = (iova - GPU_MEM_START) / SZ_4K; - phys_addr_t paddr; - - paddr = pgtable->pgtable[index]; - - return paddr; -} - static void pgtable_write(struct etnaviv_iommu_domain_pgtable *pgtable, unsigned long iova, phys_addr_t paddr) { @@ -164,14 +152,6 @@ static size_t etnaviv_iommuv1_unmap(struct iommu_domain *domain, return SZ_4K; } -static phys_addr_t etnaviv_iommu_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) -{ - struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); - - return pgtable_read(&etnaviv_domain->pgtable, iova); -} - static size_t etnaviv_iommuv1_dump_size(struct iommu_domain *domain) { return PT_SIZE; @@ -189,7 +169,6 @@ static const struct etnaviv_iommu_ops etnaviv_iommu_ops = { .domain_free = etnaviv_domain_free, .map = etnaviv_iommuv1_map, .unmap = etnaviv_iommuv1_unmap, - .iova_to_phys = etnaviv_iommu_iova_to_phys, .pgsize_bitmap = SZ_4K, }, .dump_size = etnaviv_iommuv1_dump_size, diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c index cbe447ac5974..d794e8c0dd7e 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c @@ -97,19 +97,6 @@ static size_t etnaviv_iommuv2_unmap(struct iommu_domain *domain, return SZ_4K; } -static phys_addr_t etnaviv_iommuv2_iova_to_phys(struct iommu_domain *domain, - dma_addr_t iova) -{ - struct etnaviv_iommuv2_domain *etnaviv_domain = - to_etnaviv_domain(domain); - int mtlb_entry, stlb_entry; - - mtlb_entry = (iova & MMUv2_MTLB_MASK) >> MMUv2_MTLB_SHIFT; - stlb_entry = (iova & MMUv2_STLB_MASK) >> MMUv2_STLB_SHIFT; - - return etnaviv_domain->stlb_cpu[mtlb_entry][stlb_entry] & ~(SZ_4K - 1); -} - static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) { u32 *p; @@ -235,7 +222,6 @@ static const struct etnaviv_iommu_ops etnaviv_iommu_ops = { .domain_free = etnaviv_iommuv2_domain_free, .map = etnaviv_iommuv2_map, .unmap = etnaviv_iommuv2_unmap, - .iova_to_phys = etnaviv_iommuv2_iova_to_phys, .pgsize_bitmap = SZ_4K, }, .dump_size = etnaviv_iommuv2_dump_size, -- cgit v1.2.3 From 1a540490e919bd64a9be35fca5147bbb7b2ac166 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 15:36:57 +0200 Subject: drm/etnaviv: iommuv1: fold pagetable alloc and free into caller Those functions are simple enough to fold them into the calling function. This also fixes a correctness issue, as the alloc/free functions didn't specifiy the device the memory was allocated for. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-By: Wladimir J. van der Laan --- drivers/gpu/drm/etnaviv/etnaviv_iommu.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index f804c0aaa7a2..522f6822abee 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c @@ -50,22 +50,6 @@ static struct etnaviv_iommu_domain *to_etnaviv_domain(struct iommu_domain *domai return container_of(domain, struct etnaviv_iommu_domain, domain); } -static int pgtable_alloc(struct etnaviv_iommu_domain_pgtable *pgtable, - size_t size) -{ - pgtable->pgtable = dma_alloc_coherent(NULL, size, &pgtable->paddr, GFP_KERNEL); - if (!pgtable->pgtable) - return -ENOMEM; - - return 0; -} - -static void pgtable_free(struct etnaviv_iommu_domain_pgtable *pgtable, - size_t size) -{ - dma_free_coherent(NULL, size, pgtable->pgtable, pgtable->paddr); -} - static void pgtable_write(struct etnaviv_iommu_domain_pgtable *pgtable, unsigned long iova, phys_addr_t paddr) { @@ -78,7 +62,7 @@ static void pgtable_write(struct etnaviv_iommu_domain_pgtable *pgtable, static int __etnaviv_iommu_init(struct etnaviv_iommu_domain *etnaviv_domain) { u32 *p; - int ret, i; + int i; etnaviv_domain->bad_page_cpu = dma_alloc_coherent(etnaviv_domain->dev, SZ_4K, @@ -91,12 +75,15 @@ static int __etnaviv_iommu_init(struct etnaviv_iommu_domain *etnaviv_domain) for (i = 0; i < SZ_4K / 4; i++) *p++ = 0xdead55aa; - ret = pgtable_alloc(&etnaviv_domain->pgtable, PT_SIZE); - if (ret < 0) { + etnaviv_domain->pgtable.pgtable = + dma_alloc_coherent(etnaviv_domain->dev, PT_SIZE, + &etnaviv_domain->pgtable.paddr, + GFP_KERNEL); + if (!etnaviv_domain->pgtable.pgtable) { dma_free_coherent(etnaviv_domain->dev, SZ_4K, etnaviv_domain->bad_page_cpu, etnaviv_domain->bad_page_dma); - return ret; + return -ENOMEM; } for (i = 0; i < PT_ENTRIES; i++) @@ -112,7 +99,9 @@ static void etnaviv_domain_free(struct iommu_domain *domain) { struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); - pgtable_free(&etnaviv_domain->pgtable, PT_SIZE); + dma_free_coherent(etnaviv_domain->dev, PT_SIZE, + etnaviv_domain->pgtable.pgtable, + etnaviv_domain->pgtable.paddr); dma_free_coherent(etnaviv_domain->dev, SZ_4K, etnaviv_domain->bad_page_cpu, -- cgit v1.2.3 From bd2442bc1b4ef3f27dda28edeeb85a8603115a21 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 15:56:01 +0200 Subject: drm/etnaviv: iommuv1: fold pgtable_write into callers A function doing a single assignment is not really helping the code flow. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-By: Wladimir J. van der Laan --- drivers/gpu/drm/etnaviv/etnaviv_iommu.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index 522f6822abee..33084cbc8b27 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c @@ -50,15 +50,6 @@ static struct etnaviv_iommu_domain *to_etnaviv_domain(struct iommu_domain *domai return container_of(domain, struct etnaviv_iommu_domain, domain); } -static void pgtable_write(struct etnaviv_iommu_domain_pgtable *pgtable, - unsigned long iova, phys_addr_t paddr) -{ - /* calcuate index into page table */ - unsigned int index = (iova - GPU_MEM_START) / SZ_4K; - - pgtable->pgtable[index] = paddr; -} - static int __etnaviv_iommu_init(struct etnaviv_iommu_domain *etnaviv_domain) { u32 *p; @@ -114,12 +105,13 @@ static int etnaviv_iommuv1_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot) { struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); + unsigned int index = (iova - GPU_MEM_START) / SZ_4K; if (size != SZ_4K) return -EINVAL; spin_lock(&etnaviv_domain->map_lock); - pgtable_write(&etnaviv_domain->pgtable, iova, paddr); + etnaviv_domain->pgtable.pgtable[index] = paddr; spin_unlock(&etnaviv_domain->map_lock); return 0; @@ -129,13 +121,13 @@ static size_t etnaviv_iommuv1_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) { struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); + unsigned int index = (iova - GPU_MEM_START) / SZ_4K; if (size != SZ_4K) return -EINVAL; spin_lock(&etnaviv_domain->map_lock); - pgtable_write(&etnaviv_domain->pgtable, iova, - etnaviv_domain->bad_page_dma); + etnaviv_domain->pgtable.pgtable[index] = etnaviv_domain->bad_page_dma; spin_unlock(&etnaviv_domain->map_lock); return SZ_4K; -- cgit v1.2.3 From 86666c54c801da7860f9d273b5e6fc30e210e219 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 15:41:38 +0200 Subject: drm/etnaviv: iommuv1: remove map_lock It wasn't protecting anything, as the single word writes used to set up or tear down a translation are already inherently atomic, so the spinlock is pure overhead. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-By: Wladimir J. van der Laan --- drivers/gpu/drm/etnaviv/etnaviv_iommu.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index 33084cbc8b27..2ffdb27e4ac2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c @@ -42,7 +42,6 @@ struct etnaviv_iommu_domain { void *bad_page_cpu; dma_addr_t bad_page_dma; struct etnaviv_iommu_domain_pgtable pgtable; - spinlock_t map_lock; }; static struct etnaviv_iommu_domain *to_etnaviv_domain(struct iommu_domain *domain) @@ -81,8 +80,6 @@ static int __etnaviv_iommu_init(struct etnaviv_iommu_domain *etnaviv_domain) etnaviv_domain->pgtable.pgtable[i] = etnaviv_domain->bad_page_dma; - spin_lock_init(&etnaviv_domain->map_lock); - return 0; } @@ -110,9 +107,7 @@ static int etnaviv_iommuv1_map(struct iommu_domain *domain, unsigned long iova, if (size != SZ_4K) return -EINVAL; - spin_lock(&etnaviv_domain->map_lock); etnaviv_domain->pgtable.pgtable[index] = paddr; - spin_unlock(&etnaviv_domain->map_lock); return 0; } @@ -126,9 +121,7 @@ static size_t etnaviv_iommuv1_unmap(struct iommu_domain *domain, if (size != SZ_4K) return -EINVAL; - spin_lock(&etnaviv_domain->map_lock); etnaviv_domain->pgtable.pgtable[index] = etnaviv_domain->bad_page_dma; - spin_unlock(&etnaviv_domain->map_lock); return SZ_4K; } -- cgit v1.2.3 From 50073cf98d16354b2426f6c712c7b2cb0df2871b Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 16:52:13 +0200 Subject: drm/etnaviv: mmu: stop using iommu map/unmap functions This is a preparation to remove the etnaviv dependency on the IOMMU subsystem by importing the relevant parts of the iommu map/unamp functions into the driver. Signed-off-by: Lucas Stach Reviewed-By: Wladimir J. van der Laan --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 74 +++++++++++++++++++++++++++++------ drivers/gpu/drm/etnaviv/etnaviv_mmu.h | 2 +- 2 files changed, 62 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index f3ed07db9b2d..e7b8b7aff9c6 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -22,6 +22,59 @@ #include "etnaviv_iommu.h" #include "etnaviv_mmu.h" +static void etnaviv_domain_unmap(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ + size_t unmapped_page, unmapped = 0; + size_t pgsize = SZ_4K; + + if (!IS_ALIGNED(iova | size, pgsize)) { + pr_err("unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n", + iova, size, pgsize); + return; + } + + while (unmapped < size) { + unmapped_page = domain->ops->unmap(domain, iova, pgsize); + if (!unmapped_page) + break; + + iova += unmapped_page; + unmapped += unmapped_page; + } +} + +static int etnaviv_domain_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot) +{ + unsigned long orig_iova = iova; + size_t pgsize = SZ_4K; + size_t orig_size = size; + int ret = 0; + + if (!IS_ALIGNED(iova | paddr | size, pgsize)) { + pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%x\n", + iova, &paddr, size, pgsize); + return -EINVAL; + } + + while (size) { + ret = domain->ops->map(domain, iova, paddr, pgsize, prot); + if (ret) + break; + + iova += pgsize; + paddr += pgsize; + size -= pgsize; + } + + /* unroll mapping in case something went wrong */ + if (ret) + etnaviv_domain_unmap(domain, orig_iova, orig_size - size); + + return ret; +} + int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, struct sg_table *sgt, unsigned len, int prot) { @@ -40,7 +93,7 @@ int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes); - ret = iommu_map(domain, da, pa, bytes, prot); + ret = etnaviv_domain_map(domain, da, pa, bytes, prot); if (ret) goto fail; @@ -55,14 +108,14 @@ fail: for_each_sg(sgt->sgl, sg, i, j) { size_t bytes = sg_dma_len(sg) + sg->offset; - iommu_unmap(domain, da, bytes); + etnaviv_domain_unmap(domain, da, bytes); da += bytes; } return ret; } -int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, - struct sg_table *sgt, unsigned len) +void etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, + struct sg_table *sgt, unsigned len) { struct iommu_domain *domain = iommu->domain; struct scatterlist *sg; @@ -71,11 +124,8 @@ int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes = sg_dma_len(sg) + sg->offset; - size_t unmapped; - unmapped = iommu_unmap(domain, da, bytes); - if (unmapped < bytes) - return unmapped; + etnaviv_domain_unmap(domain, da, bytes); VERB("unmap[%d]: %08x(%zx)", i, iova, bytes); @@ -83,8 +133,6 @@ int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, da += bytes; } - - return 0; } static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu *mmu, @@ -329,8 +377,8 @@ int etnaviv_iommu_get_suballoc_va(struct etnaviv_gpu *gpu, dma_addr_t paddr, mutex_unlock(&mmu->lock); return ret; } - ret = iommu_map(mmu->domain, vram_node->start, paddr, size, - IOMMU_READ); + ret = etnaviv_domain_map(mmu->domain, vram_node->start, paddr, + size, IOMMU_READ); if (ret < 0) { drm_mm_remove_node(vram_node); mutex_unlock(&mmu->lock); @@ -353,7 +401,7 @@ void etnaviv_iommu_put_suballoc_va(struct etnaviv_gpu *gpu, if (mmu->version == ETNAVIV_IOMMU_V2) { mutex_lock(&mmu->lock); - iommu_unmap(mmu->domain,iova, size); + etnaviv_domain_unmap(mmu->domain, iova, size); drm_mm_remove_node(vram_node); mutex_unlock(&mmu->lock); } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h index 54be289e5981..6b291b6f6a45 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h @@ -53,7 +53,7 @@ int etnaviv_iommu_attach(struct etnaviv_iommu *iommu, const char **names, int cnt); int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, struct sg_table *sgt, unsigned len, int prot); -int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, +void etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, struct sg_table *sgt, unsigned len); int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu, struct etnaviv_gem_object *etnaviv_obj, u32 memory_base, -- cgit v1.2.3 From 27d38062a20326a7b86d1f3ebba42c2a37d8415d Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 17:06:28 +0200 Subject: drm/etnaviv: mmu: mark local functions static And clean up the header file a bit. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-By: Wladimir J. van der Laan --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 8 ++++---- drivers/gpu/drm/etnaviv/etnaviv_mmu.h | 8 +------- 2 files changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index e7b8b7aff9c6..95e1671aee53 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -75,8 +75,8 @@ static int etnaviv_domain_map(struct iommu_domain *domain, unsigned long iova, return ret; } -int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, - struct sg_table *sgt, unsigned len, int prot) +static int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, + struct sg_table *sgt, unsigned len, int prot) { struct iommu_domain *domain = iommu->domain; struct scatterlist *sg; @@ -114,8 +114,8 @@ fail: return ret; } -void etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, - struct sg_table *sgt, unsigned len) +static void etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, + struct sg_table *sgt, unsigned len) { struct iommu_domain *domain = iommu->domain; struct scatterlist *sg; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h index 6b291b6f6a45..d072eda7a00d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h @@ -49,18 +49,11 @@ struct etnaviv_iommu { struct etnaviv_gem_object; -int etnaviv_iommu_attach(struct etnaviv_iommu *iommu, const char **names, - int cnt); -int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, - struct sg_table *sgt, unsigned len, int prot); -void etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, - struct sg_table *sgt, unsigned len); int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu, struct etnaviv_gem_object *etnaviv_obj, u32 memory_base, struct etnaviv_vram_mapping *mapping); void etnaviv_iommu_unmap_gem(struct etnaviv_iommu *mmu, struct etnaviv_vram_mapping *mapping); -void etnaviv_iommu_destroy(struct etnaviv_iommu *iommu); int etnaviv_iommu_get_suballoc_va(struct etnaviv_gpu *gpu, dma_addr_t paddr, struct drm_mm_node *vram_node, size_t size, @@ -73,6 +66,7 @@ size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu); void etnaviv_iommu_dump(struct etnaviv_iommu *iommu, void *buf); struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu); +void etnaviv_iommu_destroy(struct etnaviv_iommu *iommu); void etnaviv_iommu_restore(struct etnaviv_gpu *gpu); #endif /* __ETNAVIV_MMU_H__ */ -- cgit v1.2.3 From b670908384bda92c42076cf36614ee4f97763253 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 7 Sep 2017 17:06:28 +0200 Subject: drm/etnaviv: remove IOMMU dependency Using the IOMMU API to manage the internal GPU MMU has been an historical accident and it keeps getting in the way, as well as entangling the driver with the inner workings of the IOMMU subsystem. Clean this up by removing the usage of iommu_domain, which is the last piece linking etnaviv to the IOMMU subsystem. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/Kconfig | 2 - drivers/gpu/drm/etnaviv/etnaviv_drv.h | 1 - drivers/gpu/drm/etnaviv/etnaviv_iommu.c | 138 ++++++++++++++--------------- drivers/gpu/drm/etnaviv/etnaviv_iommu.h | 7 +- drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c | 106 +++++++++++----------- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 33 +++---- drivers/gpu/drm/etnaviv/etnaviv_mmu.h | 28 ++++-- 7 files changed, 158 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig index 38b477b5fbf9..a29b8f59eb15 100644 --- a/drivers/gpu/drm/etnaviv/Kconfig +++ b/drivers/gpu/drm/etnaviv/Kconfig @@ -7,8 +7,6 @@ config DRM_ETNAVIV select SHMEM select SYNC_FILE select TMPFS - select IOMMU_API - select IOMMU_SUPPORT select WANT_DEV_COREDUMP select CMA if HAVE_DMA_CONTIGUOUS select DMA_CMA if HAVE_DMA_CONTIGUOUS diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 058389f93b69..d157d9379e68 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index 2ffdb27e4ac2..14e24ac6573f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c @@ -14,7 +14,6 @@ * this program. If not, see . */ -#include #include #include #include @@ -31,127 +30,115 @@ #define GPU_MEM_START 0x80000000 -struct etnaviv_iommu_domain_pgtable { - u32 *pgtable; - dma_addr_t paddr; +struct etnaviv_iommuv1_domain { + struct etnaviv_iommu_domain base; + u32 *pgtable_cpu; + dma_addr_t pgtable_dma; }; -struct etnaviv_iommu_domain { - struct iommu_domain domain; - struct device *dev; - void *bad_page_cpu; - dma_addr_t bad_page_dma; - struct etnaviv_iommu_domain_pgtable pgtable; -}; - -static struct etnaviv_iommu_domain *to_etnaviv_domain(struct iommu_domain *domain) +static struct etnaviv_iommuv1_domain * +to_etnaviv_domain(struct etnaviv_iommu_domain *domain) { - return container_of(domain, struct etnaviv_iommu_domain, domain); + return container_of(domain, struct etnaviv_iommuv1_domain, base); } -static int __etnaviv_iommu_init(struct etnaviv_iommu_domain *etnaviv_domain) +static int __etnaviv_iommu_init(struct etnaviv_iommuv1_domain *etnaviv_domain) { u32 *p; int i; - etnaviv_domain->bad_page_cpu = dma_alloc_coherent(etnaviv_domain->dev, - SZ_4K, - &etnaviv_domain->bad_page_dma, - GFP_KERNEL); - if (!etnaviv_domain->bad_page_cpu) + etnaviv_domain->base.bad_page_cpu = dma_alloc_coherent( + etnaviv_domain->base.dev, + SZ_4K, + &etnaviv_domain->base.bad_page_dma, + GFP_KERNEL); + if (!etnaviv_domain->base.bad_page_cpu) return -ENOMEM; - p = etnaviv_domain->bad_page_cpu; + p = etnaviv_domain->base.bad_page_cpu; for (i = 0; i < SZ_4K / 4; i++) *p++ = 0xdead55aa; - etnaviv_domain->pgtable.pgtable = - dma_alloc_coherent(etnaviv_domain->dev, PT_SIZE, - &etnaviv_domain->pgtable.paddr, + etnaviv_domain->pgtable_cpu = + dma_alloc_coherent(etnaviv_domain->base.dev, PT_SIZE, + &etnaviv_domain->pgtable_dma, GFP_KERNEL); - if (!etnaviv_domain->pgtable.pgtable) { - dma_free_coherent(etnaviv_domain->dev, SZ_4K, - etnaviv_domain->bad_page_cpu, - etnaviv_domain->bad_page_dma); + if (!etnaviv_domain->pgtable_cpu) { + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, + etnaviv_domain->base.bad_page_cpu, + etnaviv_domain->base.bad_page_dma); return -ENOMEM; } for (i = 0; i < PT_ENTRIES; i++) - etnaviv_domain->pgtable.pgtable[i] = - etnaviv_domain->bad_page_dma; + etnaviv_domain->pgtable_cpu[i] = + etnaviv_domain->base.bad_page_dma; return 0; } -static void etnaviv_domain_free(struct iommu_domain *domain) +static void etnaviv_iommuv1_domain_free(struct etnaviv_iommu_domain *domain) { - struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); + struct etnaviv_iommuv1_domain *etnaviv_domain = + to_etnaviv_domain(domain); - dma_free_coherent(etnaviv_domain->dev, PT_SIZE, - etnaviv_domain->pgtable.pgtable, - etnaviv_domain->pgtable.paddr); + dma_free_coherent(etnaviv_domain->base.dev, PT_SIZE, + etnaviv_domain->pgtable_cpu, + etnaviv_domain->pgtable_dma); - dma_free_coherent(etnaviv_domain->dev, SZ_4K, - etnaviv_domain->bad_page_cpu, - etnaviv_domain->bad_page_dma); + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, + etnaviv_domain->base.bad_page_cpu, + etnaviv_domain->base.bad_page_dma); kfree(etnaviv_domain); } -static int etnaviv_iommuv1_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) +static int etnaviv_iommuv1_map(struct etnaviv_iommu_domain *domain, + unsigned long iova, phys_addr_t paddr, + size_t size, int prot) { - struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); + struct etnaviv_iommuv1_domain *etnaviv_domain = to_etnaviv_domain(domain); unsigned int index = (iova - GPU_MEM_START) / SZ_4K; if (size != SZ_4K) return -EINVAL; - etnaviv_domain->pgtable.pgtable[index] = paddr; + etnaviv_domain->pgtable_cpu[index] = paddr; return 0; } -static size_t etnaviv_iommuv1_unmap(struct iommu_domain *domain, +static size_t etnaviv_iommuv1_unmap(struct etnaviv_iommu_domain *domain, unsigned long iova, size_t size) { - struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); + struct etnaviv_iommuv1_domain *etnaviv_domain = + to_etnaviv_domain(domain); unsigned int index = (iova - GPU_MEM_START) / SZ_4K; if (size != SZ_4K) return -EINVAL; - etnaviv_domain->pgtable.pgtable[index] = etnaviv_domain->bad_page_dma; + etnaviv_domain->pgtable_cpu[index] = etnaviv_domain->base.bad_page_dma; return SZ_4K; } -static size_t etnaviv_iommuv1_dump_size(struct iommu_domain *domain) +static size_t etnaviv_iommuv1_dump_size(struct etnaviv_iommu_domain *domain) { return PT_SIZE; } -static void etnaviv_iommuv1_dump(struct iommu_domain *domain, void *buf) +static void etnaviv_iommuv1_dump(struct etnaviv_iommu_domain *domain, void *buf) { - struct etnaviv_iommu_domain *etnaviv_domain = to_etnaviv_domain(domain); + struct etnaviv_iommuv1_domain *etnaviv_domain = + to_etnaviv_domain(domain); - memcpy(buf, etnaviv_domain->pgtable.pgtable, PT_SIZE); + memcpy(buf, etnaviv_domain->pgtable_cpu, PT_SIZE); } -static const struct etnaviv_iommu_ops etnaviv_iommu_ops = { - .ops = { - .domain_free = etnaviv_domain_free, - .map = etnaviv_iommuv1_map, - .unmap = etnaviv_iommuv1_unmap, - .pgsize_bitmap = SZ_4K, - }, - .dump_size = etnaviv_iommuv1_dump_size, - .dump = etnaviv_iommuv1_dump, -}; - void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu) { - struct etnaviv_iommu_domain *etnaviv_domain = + struct etnaviv_iommuv1_domain *etnaviv_domain = to_etnaviv_domain(gpu->mmu->domain); u32 pgtable; @@ -163,7 +150,7 @@ void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu) gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_PE, gpu->memory_base); /* set page table address in MC */ - pgtable = (u32)etnaviv_domain->pgtable.paddr; + pgtable = (u32)etnaviv_domain->pgtable_dma; gpu_write(gpu, VIVS_MC_MMU_FE_PAGE_TABLE, pgtable); gpu_write(gpu, VIVS_MC_MMU_TX_PAGE_TABLE, pgtable); @@ -172,28 +159,37 @@ void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu) gpu_write(gpu, VIVS_MC_MMU_RA_PAGE_TABLE, pgtable); } -struct iommu_domain *etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu) +const struct etnaviv_iommu_domain_ops etnaviv_iommuv1_ops = { + .free = etnaviv_iommuv1_domain_free, + .map = etnaviv_iommuv1_map, + .unmap = etnaviv_iommuv1_unmap, + .dump_size = etnaviv_iommuv1_dump_size, + .dump = etnaviv_iommuv1_dump, +}; + +struct etnaviv_iommu_domain * +etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu) { - struct etnaviv_iommu_domain *etnaviv_domain; + struct etnaviv_iommuv1_domain *etnaviv_domain; + struct etnaviv_iommu_domain *domain; int ret; etnaviv_domain = kzalloc(sizeof(*etnaviv_domain), GFP_KERNEL); if (!etnaviv_domain) return NULL; - etnaviv_domain->dev = gpu->dev; + domain = &etnaviv_domain->base; - etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING; - etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops; - etnaviv_domain->domain.pgsize_bitmap = SZ_4K; - etnaviv_domain->domain.geometry.aperture_start = GPU_MEM_START; - etnaviv_domain->domain.geometry.aperture_end = GPU_MEM_START + PT_ENTRIES * SZ_4K - 1; + domain->dev = gpu->dev; + domain->base = GPU_MEM_START; + domain->size = PT_ENTRIES * SZ_4K; + domain->ops = &etnaviv_iommuv1_ops; ret = __etnaviv_iommu_init(etnaviv_domain); if (ret) goto out_free; - return &etnaviv_domain->domain; + return &etnaviv_domain->base; out_free: kfree(etnaviv_domain); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h index 8b51e7c16feb..01d59bf70d78 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h @@ -18,11 +18,14 @@ #define __ETNAVIV_IOMMU_H__ struct etnaviv_gpu; +struct etnaviv_iommu_domain; -struct iommu_domain *etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu); +struct etnaviv_iommu_domain * +etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu); void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu); -struct iommu_domain *etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu); +struct etnaviv_iommu_domain * +etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu); void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu); #endif /* __ETNAVIV_IOMMU_H__ */ diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c index d794e8c0dd7e..fc60fc8ddbf0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c @@ -14,7 +14,6 @@ * this program. If not, see . */ -#include #include #include #include @@ -40,10 +39,7 @@ #define MMUv2_MAX_STLB_ENTRIES 1024 struct etnaviv_iommuv2_domain { - struct iommu_domain domain; - struct device *dev; - void *bad_page_cpu; - dma_addr_t bad_page_dma; + struct etnaviv_iommu_domain base; /* M(aster) TLB aka first level pagetable */ u32 *mtlb_cpu; dma_addr_t mtlb_dma; @@ -52,13 +48,15 @@ struct etnaviv_iommuv2_domain { dma_addr_t stlb_dma[1024]; }; -static struct etnaviv_iommuv2_domain *to_etnaviv_domain(struct iommu_domain *domain) +static struct etnaviv_iommuv2_domain * +to_etnaviv_domain(struct etnaviv_iommu_domain *domain) { - return container_of(domain, struct etnaviv_iommuv2_domain, domain); + return container_of(domain, struct etnaviv_iommuv2_domain, base); } -static int etnaviv_iommuv2_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) +static int etnaviv_iommuv2_map(struct etnaviv_iommu_domain *domain, + unsigned long iova, phys_addr_t paddr, + size_t size, int prot) { struct etnaviv_iommuv2_domain *etnaviv_domain = to_etnaviv_domain(domain); @@ -68,7 +66,7 @@ static int etnaviv_iommuv2_map(struct iommu_domain *domain, unsigned long iova, if (size != SZ_4K) return -EINVAL; - if (prot & IOMMU_WRITE) + if (prot & ETNAVIV_PROT_WRITE) entry |= MMUv2_PTE_WRITEABLE; mtlb_entry = (iova & MMUv2_MTLB_MASK) >> MMUv2_MTLB_SHIFT; @@ -79,8 +77,8 @@ static int etnaviv_iommuv2_map(struct iommu_domain *domain, unsigned long iova, return 0; } -static size_t etnaviv_iommuv2_unmap(struct iommu_domain *domain, - unsigned long iova, size_t size) +static size_t etnaviv_iommuv2_unmap(struct etnaviv_iommu_domain *domain, + unsigned long iova, size_t size) { struct etnaviv_iommuv2_domain *etnaviv_domain = to_etnaviv_domain(domain); @@ -103,19 +101,20 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) int ret, i, j; /* allocate scratch page */ - etnaviv_domain->bad_page_cpu = dma_alloc_coherent(etnaviv_domain->dev, - SZ_4K, - &etnaviv_domain->bad_page_dma, - GFP_KERNEL); - if (!etnaviv_domain->bad_page_cpu) { + etnaviv_domain->base.bad_page_cpu = dma_alloc_coherent( + etnaviv_domain->base.dev, + SZ_4K, + &etnaviv_domain->base.bad_page_dma, + GFP_KERNEL); + if (!etnaviv_domain->base.bad_page_cpu) { ret = -ENOMEM; goto fail_mem; } - p = etnaviv_domain->bad_page_cpu; + p = etnaviv_domain->base.bad_page_cpu; for (i = 0; i < SZ_4K / 4; i++) *p++ = 0xdead55aa; - etnaviv_domain->mtlb_cpu = dma_alloc_coherent(etnaviv_domain->dev, + etnaviv_domain->mtlb_cpu = dma_alloc_coherent(etnaviv_domain->base.dev, SZ_4K, &etnaviv_domain->mtlb_dma, GFP_KERNEL); @@ -127,7 +126,7 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) /* pre-populate STLB pages (may want to switch to on-demand later) */ for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { etnaviv_domain->stlb_cpu[i] = - dma_alloc_coherent(etnaviv_domain->dev, + dma_alloc_coherent(etnaviv_domain->base.dev, SZ_4K, &etnaviv_domain->stlb_dma[i], GFP_KERNEL); @@ -146,19 +145,19 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) return 0; fail_mem: - if (etnaviv_domain->bad_page_cpu) - dma_free_coherent(etnaviv_domain->dev, SZ_4K, - etnaviv_domain->bad_page_cpu, - etnaviv_domain->bad_page_dma); + if (etnaviv_domain->base.bad_page_cpu) + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, + etnaviv_domain->base.bad_page_cpu, + etnaviv_domain->base.bad_page_dma); if (etnaviv_domain->mtlb_cpu) - dma_free_coherent(etnaviv_domain->dev, SZ_4K, + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, etnaviv_domain->mtlb_cpu, etnaviv_domain->mtlb_dma); for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { if (etnaviv_domain->stlb_cpu[i]) - dma_free_coherent(etnaviv_domain->dev, SZ_4K, + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, etnaviv_domain->stlb_cpu[i], etnaviv_domain->stlb_dma[i]); } @@ -166,23 +165,23 @@ fail_mem: return ret; } -static void etnaviv_iommuv2_domain_free(struct iommu_domain *domain) +static void etnaviv_iommuv2_domain_free(struct etnaviv_iommu_domain *domain) { struct etnaviv_iommuv2_domain *etnaviv_domain = to_etnaviv_domain(domain); int i; - dma_free_coherent(etnaviv_domain->dev, SZ_4K, - etnaviv_domain->bad_page_cpu, - etnaviv_domain->bad_page_dma); + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, + etnaviv_domain->base.bad_page_cpu, + etnaviv_domain->base.bad_page_dma); - dma_free_coherent(etnaviv_domain->dev, SZ_4K, + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, etnaviv_domain->mtlb_cpu, etnaviv_domain->mtlb_dma); for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { if (etnaviv_domain->stlb_cpu[i]) - dma_free_coherent(etnaviv_domain->dev, SZ_4K, + dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, etnaviv_domain->stlb_cpu[i], etnaviv_domain->stlb_dma[i]); } @@ -190,7 +189,7 @@ static void etnaviv_iommuv2_domain_free(struct iommu_domain *domain) vfree(etnaviv_domain); } -static size_t etnaviv_iommuv2_dump_size(struct iommu_domain *domain) +static size_t etnaviv_iommuv2_dump_size(struct etnaviv_iommu_domain *domain) { struct etnaviv_iommuv2_domain *etnaviv_domain = to_etnaviv_domain(domain); @@ -204,7 +203,7 @@ static size_t etnaviv_iommuv2_dump_size(struct iommu_domain *domain) return dump_size; } -static void etnaviv_iommuv2_dump(struct iommu_domain *domain, void *buf) +static void etnaviv_iommuv2_dump(struct etnaviv_iommu_domain *domain, void *buf) { struct etnaviv_iommuv2_domain *etnaviv_domain = to_etnaviv_domain(domain); @@ -217,17 +216,6 @@ static void etnaviv_iommuv2_dump(struct iommu_domain *domain, void *buf) memcpy(buf, etnaviv_domain->stlb_cpu[i], SZ_4K); } -static const struct etnaviv_iommu_ops etnaviv_iommu_ops = { - .ops = { - .domain_free = etnaviv_iommuv2_domain_free, - .map = etnaviv_iommuv2_map, - .unmap = etnaviv_iommuv2_unmap, - .pgsize_bitmap = SZ_4K, - }, - .dump_size = etnaviv_iommuv2_dump_size, - .dump = etnaviv_iommuv2_dump, -}; - void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu) { struct etnaviv_iommuv2_domain *etnaviv_domain = @@ -240,35 +228,45 @@ void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu) prefetch = etnaviv_buffer_config_mmuv2(gpu, (u32)etnaviv_domain->mtlb_dma, - (u32)etnaviv_domain->bad_page_dma); + (u32)etnaviv_domain->base.bad_page_dma); etnaviv_gpu_start_fe(gpu, (u32)etnaviv_cmdbuf_get_pa(gpu->buffer), prefetch); etnaviv_gpu_wait_idle(gpu, 100); gpu_write(gpu, VIVS_MMUv2_CONTROL, VIVS_MMUv2_CONTROL_ENABLE); } -struct iommu_domain *etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu) + +const struct etnaviv_iommu_domain_ops etnaviv_iommuv2_ops = { + .free = etnaviv_iommuv2_domain_free, + .map = etnaviv_iommuv2_map, + .unmap = etnaviv_iommuv2_unmap, + .dump_size = etnaviv_iommuv2_dump_size, + .dump = etnaviv_iommuv2_dump, +}; + +struct etnaviv_iommu_domain * +etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu) { struct etnaviv_iommuv2_domain *etnaviv_domain; + struct etnaviv_iommu_domain *domain; int ret; etnaviv_domain = vzalloc(sizeof(*etnaviv_domain)); if (!etnaviv_domain) return NULL; - etnaviv_domain->dev = gpu->dev; + domain = &etnaviv_domain->base; - etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING; - etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops; - etnaviv_domain->domain.pgsize_bitmap = SZ_4K; - etnaviv_domain->domain.geometry.aperture_start = 0; - etnaviv_domain->domain.geometry.aperture_end = ~0UL & ~(SZ_4K - 1); + domain->dev = gpu->dev; + domain->base = 0; + domain->size = (u64)SZ_1G * 4; + domain->ops = &etnaviv_iommuv2_ops; ret = etnaviv_iommuv2_init(etnaviv_domain); if (ret) goto out_free; - return &etnaviv_domain->domain; + return &etnaviv_domain->base; out_free: vfree(etnaviv_domain); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index 95e1671aee53..35074b944778 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -22,7 +22,7 @@ #include "etnaviv_iommu.h" #include "etnaviv_mmu.h" -static void etnaviv_domain_unmap(struct iommu_domain *domain, +static void etnaviv_domain_unmap(struct etnaviv_iommu_domain *domain, unsigned long iova, size_t size) { size_t unmapped_page, unmapped = 0; @@ -44,8 +44,9 @@ static void etnaviv_domain_unmap(struct iommu_domain *domain, } } -static int etnaviv_domain_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) +static int etnaviv_domain_map(struct etnaviv_iommu_domain *domain, + unsigned long iova, phys_addr_t paddr, + size_t size, int prot) { unsigned long orig_iova = iova; size_t pgsize = SZ_4K; @@ -78,7 +79,7 @@ static int etnaviv_domain_map(struct iommu_domain *domain, unsigned long iova, static int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova, struct sg_table *sgt, unsigned len, int prot) { - struct iommu_domain *domain = iommu->domain; + struct etnaviv_iommu_domain *domain = iommu->domain; struct scatterlist *sg; unsigned int da = iova; unsigned int i, j; @@ -117,7 +118,7 @@ fail: static void etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova, struct sg_table *sgt, unsigned len) { - struct iommu_domain *domain = iommu->domain; + struct etnaviv_iommu_domain *domain = iommu->domain; struct scatterlist *sg; unsigned int da = iova; int i; @@ -278,7 +279,7 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu, mmu->last_iova = node->start + etnaviv_obj->base.size; mapping->iova = node->start; ret = etnaviv_iommu_map(mmu, node->start, sgt, etnaviv_obj->base.size, - IOMMU_READ | IOMMU_WRITE); + ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE); if (ret < 0) { drm_mm_remove_node(node); @@ -312,7 +313,7 @@ void etnaviv_iommu_unmap_gem(struct etnaviv_iommu *mmu, void etnaviv_iommu_destroy(struct etnaviv_iommu *mmu) { drm_mm_takedown(&mmu->mm); - iommu_domain_free(mmu->domain); + mmu->domain->ops->free(mmu->domain); kfree(mmu); } @@ -344,9 +345,7 @@ struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu) mutex_init(&mmu->lock); INIT_LIST_HEAD(&mmu->mappings); - drm_mm_init(&mmu->mm, mmu->domain->geometry.aperture_start, - mmu->domain->geometry.aperture_end - - mmu->domain->geometry.aperture_start + 1); + drm_mm_init(&mmu->mm, mmu->domain->base, mmu->domain->size); return mmu; } @@ -378,7 +377,7 @@ int etnaviv_iommu_get_suballoc_va(struct etnaviv_gpu *gpu, dma_addr_t paddr, return ret; } ret = etnaviv_domain_map(mmu->domain, vram_node->start, paddr, - size, IOMMU_READ); + size, ETNAVIV_PROT_READ); if (ret < 0) { drm_mm_remove_node(vram_node); mutex_unlock(&mmu->lock); @@ -408,18 +407,10 @@ void etnaviv_iommu_put_suballoc_va(struct etnaviv_gpu *gpu, } size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu) { - struct etnaviv_iommu_ops *ops; - - ops = container_of(iommu->domain->ops, struct etnaviv_iommu_ops, ops); - - return ops->dump_size(iommu->domain); + return iommu->domain->ops->dump_size(iommu->domain); } void etnaviv_iommu_dump(struct etnaviv_iommu *iommu, void *buf) { - struct etnaviv_iommu_ops *ops; - - ops = container_of(iommu->domain->ops, struct etnaviv_iommu_ops, ops); - - ops->dump(iommu->domain, buf); + iommu->domain->ops->dump(iommu->domain, buf); } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h index d072eda7a00d..ab603f5166b1 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h @@ -17,7 +17,8 @@ #ifndef __ETNAVIV_MMU_H__ #define __ETNAVIV_MMU_H__ -#include +#define ETNAVIV_PROT_READ (1 << 0) +#define ETNAVIV_PROT_WRITE (1 << 1) enum etnaviv_iommu_version { ETNAVIV_IOMMU_V1 = 0, @@ -26,16 +27,31 @@ enum etnaviv_iommu_version { struct etnaviv_gpu; struct etnaviv_vram_mapping; +struct etnaviv_iommu_domain; -struct etnaviv_iommu_ops { - struct iommu_ops ops; - size_t (*dump_size)(struct iommu_domain *); - void (*dump)(struct iommu_domain *, void *); +struct etnaviv_iommu_domain_ops { + void (*free)(struct etnaviv_iommu_domain *); + int (*map)(struct etnaviv_iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot); + size_t (*unmap)(struct etnaviv_iommu_domain *domain, unsigned long iova, + size_t size); + size_t (*dump_size)(struct etnaviv_iommu_domain *); + void (*dump)(struct etnaviv_iommu_domain *, void *); +}; + +struct etnaviv_iommu_domain { + struct device *dev; + void *bad_page_cpu; + dma_addr_t bad_page_dma; + u64 base; + u64 size; + + const struct etnaviv_iommu_domain_ops *ops; }; struct etnaviv_iommu { struct etnaviv_gpu *gpu; - struct iommu_domain *domain; + struct etnaviv_iommu_domain *domain; enum etnaviv_iommu_version version; -- cgit v1.2.3 From 6eb3ecc33a6aaedda5ceb0824cafe34c47af2f55 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 28 Sep 2017 15:41:21 +0200 Subject: drm/etnaviv: rework clock initialization The reset path wants to initialize the clock control register regardless of the DYNAMIC_FREQUENCY_SCALING feature, so don't call clock update, but explicitly load the register. Also disabling of the debug registers is moved into the reset function, so we always get to the same state after a GPU reset. This means the clock update function should not touch the bits already set in the clock control register, but instead only update the scaling bits. Signed-off-by: Lucas Stach Reviewed-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index fc9a6a83dfc7..de34e221c2fe 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -420,9 +420,10 @@ static void etnaviv_gpu_update_clock(struct etnaviv_gpu *gpu) gpu->base_rate_shader >> gpu->freq_scale); } else { unsigned int fscale = 1 << (6 - gpu->freq_scale); - u32 clock = VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS | - VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale); + u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); + clock &= ~VIVS_HI_CLOCK_CONTROL_FSCALE_VAL__MASK; + clock |= VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale); etnaviv_gpu_load_clock(gpu, clock); } } @@ -445,9 +446,9 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) while (time_is_after_jiffies(timeout)) { /* enable clock */ - etnaviv_gpu_update_clock(gpu); - - control = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); + unsigned int fscale = 1 << (6 - gpu->freq_scale); + control = VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale); + etnaviv_gpu_load_clock(gpu, control); /* Wait for stable clock. Vivante's code waited for 1ms */ usleep_range(1000, 10000); @@ -490,6 +491,10 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) continue; } + /* disable debug registers, as they are not normally needed */ + control |= VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS; + gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control); + failed = false; break; } -- cgit v1.2.3 From 355502e03ad26e3c872a0f5c408a4accca57ba7e Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:19 +0200 Subject: drm/etnaviv: use bitmap to keep track of events This is prep work to be able to allocate multiple events in one go. Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 31 +++++++++++++------------------ drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 6 ++++-- 2 files changed, 17 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index de34e221c2fe..3b02814b9c52 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -744,10 +744,9 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) /* Setup event management */ spin_lock_init(&gpu->event_spinlock); init_completion(&gpu->event_free); - for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { - gpu->event[i].used = false; + bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS); + for (i = 0; i < ARRAY_SIZE(gpu->event); i++) complete(&gpu->event_free); - } /* Now program the hardware */ mutex_lock(&gpu->lock); @@ -931,7 +930,7 @@ static void recover_worker(struct work_struct *work) struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu, recover_work); unsigned long flags; - unsigned int i; + unsigned int i = 0; dev_err(gpu->dev, "hangcheck recover!\n"); @@ -950,14 +949,12 @@ static void recover_worker(struct work_struct *work) /* complete all events, the GPU won't do it after the reset */ spin_lock_irqsave(&gpu->event_spinlock, flags); - for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { - if (!gpu->event[i].used) - continue; + for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS) { dma_fence_signal(gpu->event[i].fence); gpu->event[i].fence = NULL; - gpu->event[i].used = false; complete(&gpu->event_free); } + bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS); spin_unlock_irqrestore(&gpu->event_spinlock, flags); gpu->completed_fence = gpu->active_fence; @@ -1148,7 +1145,7 @@ int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj, static unsigned int event_alloc(struct etnaviv_gpu *gpu) { unsigned long ret, flags; - unsigned int i, event = ~0U; + unsigned int event; ret = wait_for_completion_timeout(&gpu->event_free, msecs_to_jiffies(10 * 10000)); @@ -1158,13 +1155,11 @@ static unsigned int event_alloc(struct etnaviv_gpu *gpu) spin_lock_irqsave(&gpu->event_spinlock, flags); /* find first free event */ - for (i = 0; i < ARRAY_SIZE(gpu->event); i++) { - if (gpu->event[i].used == false) { - gpu->event[i].used = true; - event = i; - break; - } - } + event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS); + if (event < ETNA_NR_EVENTS) + set_bit(event, gpu->event_bitmap); + else + event = ~0U; spin_unlock_irqrestore(&gpu->event_spinlock, flags); @@ -1177,12 +1172,12 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event) spin_lock_irqsave(&gpu->event_spinlock, flags); - if (gpu->event[event].used == false) { + if (!test_bit(event, gpu->event_bitmap)) { dev_warn(gpu->dev, "event %u is already marked as free", event); spin_unlock_irqrestore(&gpu->event_spinlock, flags); } else { - gpu->event[event].used = false; + clear_bit(event, gpu->event_bitmap); spin_unlock_irqrestore(&gpu->event_spinlock, flags); complete(&gpu->event_free); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 689cb8f3680c..70e6590aacdf 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -88,13 +88,14 @@ struct etnaviv_chip_identity { }; struct etnaviv_event { - bool used; struct dma_fence *fence; }; struct etnaviv_cmdbuf_suballoc; struct etnaviv_cmdbuf; +#define ETNA_NR_EVENTS 30 + struct etnaviv_gpu { struct drm_device *drm; struct thermal_cooling_device *cooling; @@ -112,7 +113,8 @@ struct etnaviv_gpu { u32 memory_base; /* event management: */ - struct etnaviv_event event[30]; + DECLARE_BITMAP(event_bitmap, ETNA_NR_EVENTS); + struct etnaviv_event event[ETNA_NR_EVENTS]; struct completion event_free; spinlock_t event_spinlock; -- cgit v1.2.3 From 95a428c17212ddef40909981e118acd6f518dc93 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:20 +0200 Subject: drm/etnaviv: make it possible to allocate multiple events This makes it possible to allocate multiple events under the event spinlock. This change is needed to support 'sync'-points. Changes v2 -> v3: - wait for the completion of all events - use 10sec timeout regardless of the number of events - removed validation if there are enough free events - fixed return value evaluation of event_alloc(..) in etnaviv_gpu_submit(..) Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 47 +++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 3b02814b9c52..8d961bc238d4 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1142,28 +1142,44 @@ int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj, * event management: */ -static unsigned int event_alloc(struct etnaviv_gpu *gpu) +static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events, + unsigned int *events) { - unsigned long ret, flags; - unsigned int event; + unsigned long flags, timeout = msecs_to_jiffies(10 * 10000); + unsigned i, acquired = 0; - ret = wait_for_completion_timeout(&gpu->event_free, - msecs_to_jiffies(10 * 10000)); - if (!ret) - dev_err(gpu->dev, "wait_for_completion_timeout failed"); + for (i = 0; i < nr_events; i++) { + unsigned long ret; + + ret = wait_for_completion_timeout(&gpu->event_free, timeout); + + if (!ret) { + dev_err(gpu->dev, "wait_for_completion_timeout failed"); + goto out; + } + + acquired++; + timeout = ret; + } spin_lock_irqsave(&gpu->event_spinlock, flags); - /* find first free event */ - event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS); - if (event < ETNA_NR_EVENTS) + for (i = 0; i < nr_events; i++) { + int event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS); + + events[i] = event; set_bit(event, gpu->event_bitmap); - else - event = ~0U; + } spin_unlock_irqrestore(&gpu->event_spinlock, flags); - return event; + return 0; + +out: + for (i = 0; i < acquired; i++) + complete(&gpu->event_free); + + return -EBUSY; } static void event_free(struct etnaviv_gpu *gpu, unsigned int event) @@ -1332,10 +1348,9 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, * */ - event = event_alloc(gpu); - if (unlikely(event == ~0U)) { + ret = event_alloc(gpu, 1, &event); + if (ret) { DRM_ERROR("no free event\n"); - ret = -EBUSY; goto out_pm_put; } -- cgit v1.2.3 From 9e2c2e27301266dee805dda2e6d171931d752087 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:21 +0200 Subject: drm/etnaviv: add infrastructure to query perf counter Make it possible that userspace can query all performance domains and its signals. This information is needed to sample those signals via submit ioctl. At the moment no performance domain is available. Changes from v1 -> v2: - use a 16 bit value for signals - fix padding issues - add id member to domain and signal struct Changes v4 -> v5 - provide for each pipe an own set of pm domains Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/Makefile | 3 +- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 37 ++++++++++ drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 113 ++++++++++++++++++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_perfmon.h | 31 ++++++++ include/uapi/drm/etnaviv_drm.h | 27 ++++++- 5 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_perfmon.c create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_perfmon.h (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/Makefile b/drivers/gpu/drm/etnaviv/Makefile index 4f76c992043f..15c3bfa89a79 100644 --- a/drivers/gpu/drm/etnaviv/Makefile +++ b/drivers/gpu/drm/etnaviv/Makefile @@ -10,6 +10,7 @@ etnaviv-y := \ etnaviv_gpu.o \ etnaviv_iommu_v2.o \ etnaviv_iommu.o \ - etnaviv_mmu.o + etnaviv_mmu.o \ + etnaviv_perfmon.o obj-$(CONFIG_DRM_ETNAVIV) += etnaviv.o diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 2cb4773823c2..8721dc23312f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -23,6 +23,7 @@ #include "etnaviv_gpu.h" #include "etnaviv_gem.h" #include "etnaviv_mmu.h" +#include "etnaviv_perfmon.h" #ifdef CONFIG_DRM_ETNAVIV_REGISTER_LOGGING static bool reglog; @@ -451,6 +452,40 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data, return ret; } +static int etnaviv_ioctl_pm_query_dom(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct etnaviv_drm_private *priv = dev->dev_private; + struct drm_etnaviv_pm_domain *args = data; + struct etnaviv_gpu *gpu; + + if (args->pipe >= ETNA_MAX_PIPES) + return -EINVAL; + + gpu = priv->gpu[args->pipe]; + if (!gpu) + return -ENXIO; + + return etnaviv_pm_query_dom(gpu, args); +} + +static int etnaviv_ioctl_pm_query_sig(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct etnaviv_drm_private *priv = dev->dev_private; + struct drm_etnaviv_pm_signal *args = data; + struct etnaviv_gpu *gpu; + + if (args->pipe >= ETNA_MAX_PIPES) + return -EINVAL; + + gpu = priv->gpu[args->pipe]; + if (!gpu) + return -ENXIO; + + return etnaviv_pm_query_sig(gpu, args); +} + static const struct drm_ioctl_desc etnaviv_ioctls[] = { #define ETNA_IOCTL(n, func, flags) \ DRM_IOCTL_DEF_DRV(ETNAVIV_##n, etnaviv_ioctl_##func, flags) @@ -463,6 +498,8 @@ static const struct drm_ioctl_desc etnaviv_ioctls[] = { ETNA_IOCTL(WAIT_FENCE, wait_fence, DRM_AUTH|DRM_RENDER_ALLOW), ETNA_IOCTL(GEM_USERPTR, gem_userptr, DRM_AUTH|DRM_RENDER_ALLOW), ETNA_IOCTL(GEM_WAIT, gem_wait, DRM_AUTH|DRM_RENDER_ALLOW), + ETNA_IOCTL(PM_QUERY_DOM, pm_query_dom, DRM_AUTH|DRM_RENDER_ALLOW), + ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_AUTH|DRM_RENDER_ALLOW), }; static const struct vm_operations_struct vm_ops = { diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c new file mode 100644 index 000000000000..08ef01c2a0ef --- /dev/null +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2017 Etnaviv Project + * Copyright (C) 2017 Zodiac Inflight Innovations + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "etnaviv_gpu.h" + +struct etnaviv_pm_domain; + +struct etnaviv_pm_signal { + char name[64]; + u32 data; + + u32 (*sample)(struct etnaviv_gpu *gpu, + const struct etnaviv_pm_domain *domain, + const struct etnaviv_pm_signal *signal); +}; + +struct etnaviv_pm_domain { + char name[64]; + u8 nr_signals; + const struct etnaviv_pm_signal *signal; +}; + +struct etnaviv_pm_domain_meta { + const struct etnaviv_pm_domain *domains; + u32 nr_domains; +}; + +static const struct etnaviv_pm_domain doms_3d[] = { +}; + +static const struct etnaviv_pm_domain doms_2d[] = { +}; + +static const struct etnaviv_pm_domain doms_vg[] = { +}; + +static const struct etnaviv_pm_domain_meta doms_meta[] = { + { + .nr_domains = ARRAY_SIZE(doms_3d), + .domains = &doms_3d[0] + }, + { + .nr_domains = ARRAY_SIZE(doms_2d), + .domains = &doms_2d[0] + }, + { + .nr_domains = ARRAY_SIZE(doms_vg), + .domains = &doms_vg[0] + } +}; + +int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, + struct drm_etnaviv_pm_domain *domain) +{ + const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe]; + const struct etnaviv_pm_domain *dom; + + if (domain->iter >= meta->nr_domains) + return -EINVAL; + + dom = meta->domains + domain->iter; + + domain->id = domain->iter; + domain->nr_signals = dom->nr_signals; + strncpy(domain->name, dom->name, sizeof(domain->name)); + + domain->iter++; + if (domain->iter == meta->nr_domains) + domain->iter = 0xff; + + return 0; +} + +int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, + struct drm_etnaviv_pm_signal *signal) +{ + const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe]; + const struct etnaviv_pm_domain *dom; + const struct etnaviv_pm_signal *sig; + + if (signal->domain >= meta->nr_domains) + return -EINVAL; + + dom = meta->domains + signal->domain; + + if (signal->iter > dom->nr_signals) + return -EINVAL; + + sig = &dom->signal[signal->iter]; + + signal->id = signal->iter; + strncpy(signal->name, sig->name, sizeof(signal->name)); + + signal->iter++; + if (signal->iter == dom->nr_signals) + signal->iter = 0xffff; + + return 0; +} diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h new file mode 100644 index 000000000000..4589cadc3a4f --- /dev/null +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 Etnaviv Project + * Copyright (C) 2017 Zodiac Inflight Innovations + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef __ETNAVIV_PERFMON_H__ +#define __ETNAVIV_PERFMON_H__ + +struct etnaviv_gpu; +struct drm_etnaviv_pm_domain; +struct drm_etnaviv_pm_signal; + +int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, + struct drm_etnaviv_pm_domain *domain); + +int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, + struct drm_etnaviv_pm_signal *signal); + +#endif /* __ETNAVIV_PERFMON_H__ */ diff --git a/include/uapi/drm/etnaviv_drm.h b/include/uapi/drm/etnaviv_drm.h index 76f6f78a352b..c065c8308bbd 100644 --- a/include/uapi/drm/etnaviv_drm.h +++ b/include/uapi/drm/etnaviv_drm.h @@ -210,6 +210,27 @@ struct drm_etnaviv_gem_wait { struct drm_etnaviv_timespec timeout; /* in */ }; +/* + * Performance Monitor (PM): + */ + +struct drm_etnaviv_pm_domain { + __u32 pipe; /* in */ + __u8 iter; /* in/out, select pm domain at index iter */ + __u8 id; /* out, id of domain */ + __u16 nr_signals; /* out, how many signals does this domain provide */ + char name[64]; /* out, name of domain */ +}; + +struct drm_etnaviv_pm_signal { + __u32 pipe; /* in */ + __u8 domain; /* in, pm domain index */ + __u8 pad; + __u16 iter; /* in/out, select pm source at index iter */ + __u16 id; /* out, id of signal */ + char name[64]; /* out, name of domain */ +}; + #define DRM_ETNAVIV_GET_PARAM 0x00 /* placeholder: #define DRM_ETNAVIV_SET_PARAM 0x01 @@ -222,7 +243,9 @@ struct drm_etnaviv_gem_wait { #define DRM_ETNAVIV_WAIT_FENCE 0x07 #define DRM_ETNAVIV_GEM_USERPTR 0x08 #define DRM_ETNAVIV_GEM_WAIT 0x09 -#define DRM_ETNAVIV_NUM_IOCTLS 0x0a +#define DRM_ETNAVIV_PM_QUERY_DOM 0x0a +#define DRM_ETNAVIV_PM_QUERY_SIG 0x0b +#define DRM_ETNAVIV_NUM_IOCTLS 0x0c #define DRM_IOCTL_ETNAVIV_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GET_PARAM, struct drm_etnaviv_param) #define DRM_IOCTL_ETNAVIV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_NEW, struct drm_etnaviv_gem_new) @@ -233,6 +256,8 @@ struct drm_etnaviv_gem_wait { #define DRM_IOCTL_ETNAVIV_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_WAIT_FENCE, struct drm_etnaviv_wait_fence) #define DRM_IOCTL_ETNAVIV_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_USERPTR, struct drm_etnaviv_gem_userptr) #define DRM_IOCTL_ETNAVIV_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_WAIT, struct drm_etnaviv_gem_wait) +#define DRM_IOCTL_ETNAVIV_PM_QUERY_DOM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_DOM, struct drm_etnaviv_pm_domain) +#define DRM_IOCTL_ETNAVIV_PM_QUERY_SIG DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_SIG, struct drm_etnaviv_pm_signal) #if defined(__cplusplus) } -- cgit v1.2.3 From 8d3d56cef4412a37cea3ce32e730976620aaeb58 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:23 +0200 Subject: drm/etnaviv: add internal representation of perfmon_request Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h | 4 ++++ drivers/gpu/drm/etnaviv/etnaviv_perfmon.h | 12 ++++++++++++ 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h index 80d78076c679..1b549f0d59a0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h @@ -21,6 +21,7 @@ struct etnaviv_gpu; struct etnaviv_cmdbuf_suballoc; +struct etnaviv_perfmon_request; struct etnaviv_cmdbuf { /* suballocator this cmdbuf is allocated from */ @@ -38,6 +39,9 @@ struct etnaviv_cmdbuf { u32 exec_state; /* per GPU in-flight list */ struct list_head node; + /* perfmon requests */ + unsigned int nr_pmrs; + struct etnaviv_perfmon_request *pmrs; /* BOs attached to this command buffer */ unsigned int nr_bos; struct etnaviv_vram_mapping *bo_map[0]; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h index 4589cadc3a4f..4b2b518cfd16 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h @@ -22,6 +22,18 @@ struct etnaviv_gpu; struct drm_etnaviv_pm_domain; struct drm_etnaviv_pm_signal; +struct etnaviv_perfmon_request +{ + u32 flags; + u8 domain; + u8 signal; + u32 sequence; + + /* bo to store a value */ + u32 *bo_vma; + u32 offset; +}; + int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, struct drm_etnaviv_pm_domain *domain); -- cgit v1.2.3 From 4fc3e66adb291cc3ec4a360c75221e9fbf416938 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:24 +0200 Subject: drm/etnaviv: extend etnaviv_gpu_cmdbuf_new(..) with nr_pmrs This commits extends etnaviv_gpu_cmdbuf_new(..) to define the number of struct etnaviv_perfmon elements gets used. Changes from v1 -> v2: - make use of goto as requested by Lucas Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c | 15 ++++++++++++++- drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c index 633e0f07cbac..66ac79558bbd 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c @@ -19,6 +19,7 @@ #include "etnaviv_cmdbuf.h" #include "etnaviv_gpu.h" #include "etnaviv_mmu.h" +#include "etnaviv_perfmon.h" #define SUBALLOC_SIZE SZ_256K #define SUBALLOC_GRANULE SZ_4K @@ -87,9 +88,10 @@ void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc) struct etnaviv_cmdbuf * etnaviv_cmdbuf_new(struct etnaviv_cmdbuf_suballoc *suballoc, u32 size, - size_t nr_bos) + size_t nr_bos, size_t nr_pmrs) { struct etnaviv_cmdbuf *cmdbuf; + struct etnaviv_perfmon_request *pmrs; size_t sz = size_vstruct(nr_bos, sizeof(cmdbuf->bo_map[0]), sizeof(*cmdbuf)); int granule_offs, order, ret; @@ -98,6 +100,12 @@ etnaviv_cmdbuf_new(struct etnaviv_cmdbuf_suballoc *suballoc, u32 size, if (!cmdbuf) return NULL; + sz = sizeof(*pmrs) * nr_pmrs; + pmrs = kzalloc(sz, GFP_KERNEL); + if (!pmrs) + goto out_free_cmdbuf; + + cmdbuf->pmrs = pmrs; cmdbuf->suballoc = suballoc; cmdbuf->size = size; @@ -124,6 +132,10 @@ retry: cmdbuf->vaddr = suballoc->vaddr + cmdbuf->suballoc_offset; return cmdbuf; + +out_free_cmdbuf: + kfree(cmdbuf); + return NULL; } void etnaviv_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf) @@ -139,6 +151,7 @@ void etnaviv_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf) suballoc->free_space = 1; mutex_unlock(&suballoc->lock); wake_up_all(&suballoc->free_event); + kfree(cmdbuf->pmrs); kfree(cmdbuf); } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h index 1b549f0d59a0..b6348b9f2a9d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h @@ -53,7 +53,7 @@ void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc); struct etnaviv_cmdbuf * etnaviv_cmdbuf_new(struct etnaviv_cmdbuf_suballoc *suballoc, u32 size, - size_t nr_bos); + size_t nr_bos, size_t nr_pmrs); void etnaviv_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf); u32 etnaviv_cmdbuf_get_va(struct etnaviv_cmdbuf *buf); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index 026ef4e02f85..41abdfc7cb00 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -350,7 +350,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, stream = kvmalloc_array(1, args->stream_size, GFP_KERNEL); cmdbuf = etnaviv_cmdbuf_new(gpu->cmdbuf_suballoc, ALIGN(args->stream_size, 8) + 8, - args->nr_bos); + args->nr_bos, 0); if (!bos || !relocs || !stream || !cmdbuf) { ret = -ENOMEM; goto err_submit_cmds; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 8d961bc238d4..7b61071af0de 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -726,7 +726,7 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) } /* Create buffer: */ - gpu->buffer = etnaviv_cmdbuf_new(gpu->cmdbuf_suballoc, PAGE_SIZE, 0); + gpu->buffer = etnaviv_cmdbuf_new(gpu->cmdbuf_suballoc, PAGE_SIZE, 0, 0); if (!gpu->buffer) { ret = -ENOMEM; dev_err(gpu->dev, "could not create command buffer\n"); -- cgit v1.2.3 From 46df52cd4395b62d05b9ac99a7f320f577b5cff5 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:25 +0200 Subject: drm/etnaviv: add performance monitor request validation Check if the selected domain and signal combination exists. Changes from v4 to v5 - add exec_state parameter Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 17 +++++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_perfmon.h | 3 +++ 2 files changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index 08ef01c2a0ef..09fbd33764e8 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -111,3 +111,20 @@ int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, return 0; } + +int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r, + u32 exec_state) +{ + const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state]; + const struct etnaviv_pm_domain *dom; + + if (r->domain >= meta->nr_domains) + return -EINVAL; + + dom = meta->domains + r->domain; + + if (r->signal > dom->nr_signals) + return -EINVAL; + + return 0; +} diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h index 4b2b518cfd16..9fcd1fb2e482 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h @@ -40,4 +40,7 @@ int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, struct drm_etnaviv_pm_signal *signal); +int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r, + u32 exec_state); + #endif /* __ETNAVIV_PERFMON_H__ */ -- cgit v1.2.3 From c8e4a7fdea98ffdb6029bc591dd4b0ba31e17774 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:26 +0200 Subject: drm/etnaviv: copy pmrs from userspace Changes from v1 -> v2: - renamed submit_perfmon_request() to submit_perfmon_validate() - extended flags validation - added comment about offset 0 - moved assigment of cmdbuf->nr_pmrs below the copy_from_user of the pmrs. Changes from v2 -> v3: - fixed flags validation Changes v4 -> v5 - pass cmdbuf->exec_state to etnaviv_pm_req_validate(..) Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 69 +++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index 41abdfc7cb00..78f20a3d47d9 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -21,6 +21,7 @@ #include "etnaviv_drv.h" #include "etnaviv_gpu.h" #include "etnaviv_gem.h" +#include "etnaviv_perfmon.h" /* * Cmdstream submission: @@ -283,6 +284,54 @@ static int submit_reloc(struct etnaviv_gem_submit *submit, void *stream, return 0; } +static int submit_perfmon_validate(struct etnaviv_gem_submit *submit, + struct etnaviv_cmdbuf *cmdbuf, + const struct drm_etnaviv_gem_submit_pmr *pmrs, + u32 nr_pms) +{ + u32 i; + + for (i = 0; i < nr_pms; i++) { + const struct drm_etnaviv_gem_submit_pmr *r = pmrs + i; + struct etnaviv_gem_submit_bo *bo; + int ret; + + ret = submit_bo(submit, r->read_idx, &bo); + if (ret) + return ret; + + /* at offset 0 a sequence number gets stored used for userspace sync */ + if (r->read_offset == 0) { + DRM_ERROR("perfmon request: offset is 0"); + return -EINVAL; + } + + if (r->read_offset >= bo->obj->base.size - sizeof(u32)) { + DRM_ERROR("perfmon request: offset %u outside object", i); + return -EINVAL; + } + + if (r->flags & ~(ETNA_PM_PROCESS_PRE | ETNA_PM_PROCESS_POST)) { + DRM_ERROR("perfmon request: flags are not valid"); + return -EINVAL; + } + + if (etnaviv_pm_req_validate(r, cmdbuf->exec_state)) { + DRM_ERROR("perfmon request: domain or signal not valid"); + return -EINVAL; + } + + cmdbuf->pmrs[i].flags = r->flags; + cmdbuf->pmrs[i].domain = r->domain; + cmdbuf->pmrs[i].signal = r->signal; + cmdbuf->pmrs[i].sequence = r->sequence; + cmdbuf->pmrs[i].offset = r->read_offset; + cmdbuf->pmrs[i].bo_vma = etnaviv_gem_vmap(&bo->obj->base); + } + + return 0; +} + static void submit_cleanup(struct etnaviv_gem_submit *submit) { unsigned i; @@ -306,6 +355,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, struct etnaviv_drm_private *priv = dev->dev_private; struct drm_etnaviv_gem_submit *args = data; struct drm_etnaviv_gem_submit_reloc *relocs; + struct drm_etnaviv_gem_submit_pmr *pmrs; struct drm_etnaviv_gem_submit_bo *bos; struct etnaviv_gem_submit *submit; struct etnaviv_cmdbuf *cmdbuf; @@ -347,11 +397,12 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, */ bos = kvmalloc_array(args->nr_bos, sizeof(*bos), GFP_KERNEL); relocs = kvmalloc_array(args->nr_relocs, sizeof(*relocs), GFP_KERNEL); + pmrs = kvmalloc_array(args->nr_pmrs, sizeof(*pmrs), GFP_KERNEL); stream = kvmalloc_array(1, args->stream_size, GFP_KERNEL); cmdbuf = etnaviv_cmdbuf_new(gpu->cmdbuf_suballoc, ALIGN(args->stream_size, 8) + 8, - args->nr_bos, 0); - if (!bos || !relocs || !stream || !cmdbuf) { + args->nr_bos, args->nr_pmrs); + if (!bos || !relocs || !pmrs || !stream || !cmdbuf) { ret = -ENOMEM; goto err_submit_cmds; } @@ -373,6 +424,14 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, goto err_submit_cmds; } + ret = copy_from_user(pmrs, u64_to_user_ptr(args->pmrs), + args->nr_pmrs * sizeof(*pmrs)); + if (ret) { + ret = -EFAULT; + goto err_submit_cmds; + } + cmdbuf->nr_pmrs = args->nr_pmrs; + ret = copy_from_user(stream, u64_to_user_ptr(args->stream), args->stream_size); if (ret) { @@ -441,6 +500,10 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, if (ret) goto out; + ret = submit_perfmon_validate(submit, cmdbuf, pmrs, args->nr_pmrs); + if (ret) + goto out; + memcpy(cmdbuf->vaddr, stream, args->stream_size); cmdbuf->user_size = ALIGN(args->stream_size, 8); @@ -494,6 +557,8 @@ err_submit_cmds: kvfree(bos); if (relocs) kvfree(relocs); + if (pmrs) + kvfree(pmrs); return ret; } -- cgit v1.2.3 From 249300c740e5bf2b48425e6f0cccc63964a35892 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:27 +0200 Subject: drm/etnaviv: add performance monitor request processing Changes v4 -> v5 - make use of doms_meta array Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 17 +++++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_perfmon.h | 3 +++ 2 files changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index 09fbd33764e8..ba60cb9192c7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -16,6 +16,7 @@ */ #include "etnaviv_gpu.h" +#include "etnaviv_perfmon.h" struct etnaviv_pm_domain; @@ -128,3 +129,19 @@ int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r, return 0; } + +void etnaviv_perfmon_process(struct etnaviv_gpu *gpu, + const struct etnaviv_perfmon_request *pmr) +{ + const struct etnaviv_pm_domain_meta *meta = &doms_meta[gpu->exec_state]; + const struct etnaviv_pm_domain *dom; + const struct etnaviv_pm_signal *sig; + u32 *bo = pmr->bo_vma; + u32 val; + + dom = meta->domains + pmr->domain; + sig = &dom->signal[pmr->signal]; + val = sig->sample(gpu, dom, sig); + + *(bo + pmr->offset) = val; +} diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h index 9fcd1fb2e482..35dce194cb00 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.h @@ -43,4 +43,7 @@ int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r, u32 exec_state); +void etnaviv_perfmon_process(struct etnaviv_gpu *gpu, + const struct etnaviv_perfmon_request *pmr); + #endif /* __ETNAVIV_PERFMON_H__ */ -- cgit v1.2.3 From 357713ce9bc86c1ae7ba804731d8db542944463c Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:28 +0200 Subject: drm/etnaviv: add 'sync point' support In order to support performance counters in a sane way we need to provide a method to sync the GPU with the CPU. The GPU can process multpile command buffers/events per irq. With the help of a 'sync point' we can trigger an event and stop the GPU/FE immediately. When the CPU is done with is processing it simply needs to restart the FE and the GPU will process the command stream. Changes from v1 -> v2: - process sync point with a work item to keep irq as fast as possible Changes from v4 -> v5: - renamed pmrs_* to sync_point_* - call event_free(..) in sync_point_worker(..) Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 36 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_drv.h | 1 + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 26 +++++++++++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 6 ++++++ 4 files changed, 69 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c index ed9588f36bc9..9e7098e3207f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c @@ -250,6 +250,42 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) } } +/* Append a 'sync point' to the ring buffer. */ +void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event) +{ + struct etnaviv_cmdbuf *buffer = gpu->buffer; + unsigned int waitlink_offset = buffer->user_size - 16; + u32 dwords, target; + + /* + * We need at most 3 dwords in the return target: + * 1 event + 1 end + 1 wait + 1 link. + */ + dwords = 4; + target = etnaviv_buffer_reserve(gpu, buffer, dwords); + + /* Signal sync point event */ + CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | + VIVS_GL_EVENT_FROM_PE); + + /* Stop the FE to 'pause' the GPU */ + CMD_END(buffer); + + /* Append waitlink */ + CMD_WAIT(buffer); + CMD_LINK(buffer, 2, etnaviv_cmdbuf_get_va(buffer) + + buffer->user_size - 4); + + /* + * Kick off the 'sync point' command by replacing the previous + * WAIT with a link to the address in the ring buffer. + */ + etnaviv_buffer_replace_wait(buffer, waitlink_offset, + VIV_FE_LINK_HEADER_OP_LINK | + VIV_FE_LINK_HEADER_PREFETCH(dwords), + target); +} + /* Append a command buffer to the ring buffer. */ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event, struct etnaviv_cmdbuf *cmdbuf) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index d157d9379e68..203613ae24dc 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -100,6 +100,7 @@ int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file, u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu); u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr); void etnaviv_buffer_end(struct etnaviv_gpu *gpu); +void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event); void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event, struct etnaviv_cmdbuf *cmdbuf); void etnaviv_validate_init(void); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 7b61071af0de..cd70e7c04305 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -25,6 +25,7 @@ #include "etnaviv_gpu.h" #include "etnaviv_gem.h" #include "etnaviv_mmu.h" +#include "etnaviv_perfmon.h" #include "common.xml.h" #include "state.xml.h" #include "state_hi.xml.h" @@ -1364,6 +1365,7 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, } gpu->event[event].fence = fence; + gpu->event[event].sync_point = NULL; submit->fence = dma_fence_get(fence); gpu->active_fence = submit->fence->seqno; @@ -1409,6 +1411,24 @@ out_pm_put: return ret; } +static void etnaviv_process_sync_point(struct etnaviv_gpu *gpu, + struct etnaviv_event *event) +{ + u32 addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS); + + event->sync_point(gpu, event); + etnaviv_gpu_start_fe(gpu, addr + 2, 2); +} + +static void sync_point_worker(struct work_struct *work) +{ + struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu, + sync_point_work); + + etnaviv_process_sync_point(gpu, &gpu->event[gpu->sync_point_event]); + event_free(gpu, gpu->sync_point_event); +} + /* * Init/Cleanup: */ @@ -1455,6 +1475,11 @@ static irqreturn_t irq_handler(int irq, void *data) dev_dbg(gpu->dev, "event %u\n", event); + if (gpu->event[event].sync_point) { + gpu->sync_point_event = event; + etnaviv_queue_work(gpu->drm, &gpu->sync_point_work); + } + fence = gpu->event[event].fence; gpu->event[event].fence = NULL; dma_fence_signal(fence); @@ -1660,6 +1685,7 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master, INIT_LIST_HEAD(&gpu->active_cmd_list); INIT_WORK(&gpu->retire_work, retire_worker); + INIT_WORK(&gpu->sync_point_work, sync_point_worker); INIT_WORK(&gpu->recover_work, recover_worker); init_waitqueue_head(&gpu->fence_event); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 70e6590aacdf..3be5cb53e89f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -89,6 +89,8 @@ struct etnaviv_chip_identity { struct etnaviv_event { struct dma_fence *fence; + + void (*sync_point)(struct etnaviv_gpu *gpu, struct etnaviv_event *event); }; struct etnaviv_cmdbuf_suballoc; @@ -135,6 +137,10 @@ struct etnaviv_gpu { /* worker for handling active-list retiring: */ struct work_struct retire_work; + /* worker for handling 'sync' points: */ + struct work_struct sync_point_work; + int sync_point_event; + void __iomem *mmio; int irq; -- cgit v1.2.3 From 547d340d3f9bcd83a356c00044f260ae9d80d0e0 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:29 +0200 Subject: drm/etnaviv: clear alloced event Results in less code as the users do not set every struct member to 0/NULL. Signed-off-by: Christian Gmeiner Reviewed-by: Lucas Stach Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index cd70e7c04305..8aabdac8d00b 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1169,6 +1169,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events, int event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS); events[i] = event; + memset(&gpu->event[event], 0, sizeof(struct etnaviv_event)); set_bit(event, gpu->event_bitmap); } @@ -1365,7 +1366,6 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, } gpu->event[event].fence = fence; - gpu->event[event].sync_point = NULL; submit->fence = dma_fence_get(fence); gpu->active_fence = submit->fence->seqno; -- cgit v1.2.3 From 68dc0b295dcbadbaf2747627dc535629e17eb664 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:30 +0200 Subject: drm/etnaviv: use 'sync points' for performance monitor requests With 'sync points' we can sample the reqeustes perform signals before and/or after the submited command buffer. Changes v2 -> v3: - fixed indentation and init nr_events to 1 Changes v4 -> v5: - simplify logic around fence handling. Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 75 ++++++++++++++++++++++++++++++++--- drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 1 + 2 files changed, 70 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 8aabdac8d00b..56764b4b94aa 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1329,12 +1329,48 @@ void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu) pm_runtime_put_autosuspend(gpu->dev); } +static void sync_point_perfmon_sample(struct etnaviv_gpu *gpu, + struct etnaviv_event *event, unsigned int flags) +{ + const struct etnaviv_cmdbuf *cmdbuf = event->cmdbuf; + unsigned int i; + + for (i = 0; i < cmdbuf->nr_pmrs; i++) { + const struct etnaviv_perfmon_request *pmr = cmdbuf->pmrs + i; + + if (pmr->flags == flags) + etnaviv_perfmon_process(gpu, pmr); + } +} + +static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu, + struct etnaviv_event *event) +{ + sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE); +} + +static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, + struct etnaviv_event *event) +{ + const struct etnaviv_cmdbuf *cmdbuf = event->cmdbuf; + unsigned int i; + + sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST); + + for (i = 0; i < cmdbuf->nr_pmrs; i++) { + const struct etnaviv_perfmon_request *pmr = cmdbuf->pmrs + i; + + *pmr->bo_vma = pmr->sequence; + } +} + + /* add bo's to gpu's ring, and kick gpu: */ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, struct etnaviv_gem_submit *submit, struct etnaviv_cmdbuf *cmdbuf) { struct dma_fence *fence; - unsigned int event, i; + unsigned int i, nr_events = 1, event[3]; int ret; ret = etnaviv_gpu_pm_get_sync(gpu); @@ -1350,9 +1386,19 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, * */ - ret = event_alloc(gpu, 1, &event); + /* + * if there are performance monitor requests we need to have + * - a sync point to re-configure gpu and process ETNA_PM_PROCESS_PRE + * requests. + * - a sync point to re-configure gpu, process ETNA_PM_PROCESS_POST requests + * and update the sequence number for userspace. + */ + if (cmdbuf->nr_pmrs) + nr_events = 3; + + ret = event_alloc(gpu, nr_events, event); if (ret) { - DRM_ERROR("no free event\n"); + DRM_ERROR("no free events\n"); goto out_pm_put; } @@ -1360,12 +1406,14 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, fence = etnaviv_gpu_fence_alloc(gpu); if (!fence) { - event_free(gpu, event); + for (i = 0; i < nr_events; i++) + event_free(gpu, event[i]); + ret = -ENOMEM; goto out_unlock; } - gpu->event[event].fence = fence; + gpu->event[event[0]].fence = fence; submit->fence = dma_fence_get(fence); gpu->active_fence = submit->fence->seqno; @@ -1375,7 +1423,19 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, gpu->lastctx = cmdbuf->ctx; } - etnaviv_buffer_queue(gpu, event, cmdbuf); + if (cmdbuf->nr_pmrs) { + gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre; + gpu->event[event[1]].cmdbuf = cmdbuf; + etnaviv_sync_point_queue(gpu, event[1]); + } + + etnaviv_buffer_queue(gpu, event[0], cmdbuf); + + if (cmdbuf->nr_pmrs) { + gpu->event[event[2]].sync_point = &sync_point_perfmon_sample_post; + gpu->event[event[2]].cmdbuf = cmdbuf; + etnaviv_sync_point_queue(gpu, event[2]); + } cmdbuf->fence = fence; list_add_tail(&cmdbuf->node, &gpu->active_cmd_list); @@ -1481,6 +1541,9 @@ static irqreturn_t irq_handler(int irq, void *data) } fence = gpu->event[event].fence; + if (!fence) + continue; + gpu->event[event].fence = NULL; dma_fence_signal(fence); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 3be5cb53e89f..4f10f147297a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -89,6 +89,7 @@ struct etnaviv_chip_identity { struct etnaviv_event { struct dma_fence *fence; + struct etnaviv_cmdbuf *cmdbuf; void (*sync_point)(struct etnaviv_gpu *gpu, struct etnaviv_event *event); }; -- cgit v1.2.3 From 33deff0af3a9cb055202a2dec9640b2874802bb5 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:31 +0200 Subject: drm/etnaviv: add HI perf domain Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index ba60cb9192c7..f0cdf371663a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -17,6 +17,7 @@ #include "etnaviv_gpu.h" #include "etnaviv_perfmon.h" +#include "state_hi.xml.h" struct etnaviv_pm_domain; @@ -31,6 +32,11 @@ struct etnaviv_pm_signal { struct etnaviv_pm_domain { char name[64]; + + /* profile register */ + u32 profile_read; + u32 profile_config; + u8 nr_signals; const struct etnaviv_pm_signal *signal; }; @@ -40,7 +46,56 @@ struct etnaviv_pm_domain_meta { u32 nr_domains; }; +static u32 simple_reg_read(struct etnaviv_gpu *gpu, + const struct etnaviv_pm_domain *domain, + const struct etnaviv_pm_signal *signal) +{ + return gpu_read(gpu, signal->data); +} + +static u32 perf_reg_read(struct etnaviv_gpu *gpu, + const struct etnaviv_pm_domain *domain, + const struct etnaviv_pm_signal *signal) +{ + gpu_write(gpu, domain->profile_config, signal->data); + + return gpu_read(gpu, domain->profile_read); +} + static const struct etnaviv_pm_domain doms_3d[] = { + { + .name = "HI", + .profile_read = VIVS_MC_PROFILE_HI_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG2, + .nr_signals = 5, + .signal = (const struct etnaviv_pm_signal[]) { + { + "TOTAL_CYCLES", + VIVS_HI_PROFILE_TOTAL_CYCLES, + &simple_reg_read + }, + { + "IDLE_CYCLES", + VIVS_HI_PROFILE_IDLE_CYCLES, + &simple_reg_read + }, + { + "AXI_CYCLES_READ_REQUEST_STALLED", + VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED, + &perf_reg_read + }, + { + "AXI_CYCLES_WRITE_REQUEST_STALLED", + VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED, + &perf_reg_read + }, + { + "AXI_CYCLES_WRITE_DATA_STALLED", + VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED, + &perf_reg_read + } + } + } }; static const struct etnaviv_pm_domain doms_2d[] = { -- cgit v1.2.3 From a3d0c390ffe0930e3aad99e220356a82b79c359b Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:32 +0200 Subject: drm/etnaviv: add PE perf domain We need to iterate over all pixel pipelines to get overall value. Changes from v4 -> v5: - switch back to pixel pipe 0 to prevent GPU hang - PIXELS_RENDERED_2D is exposed for 2D pipe Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 65 +++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index f0cdf371663a..9f933feabff2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -62,6 +62,30 @@ static u32 perf_reg_read(struct etnaviv_gpu *gpu, return gpu_read(gpu, domain->profile_read); } +static u32 pipe_reg_read(struct etnaviv_gpu *gpu, + const struct etnaviv_pm_domain *domain, + const struct etnaviv_pm_signal *signal) +{ + u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); + u32 value = 0; + unsigned i; + + for (i = 0; i < gpu->identity.pixel_pipes; i++) { + clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK); + clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(i); + gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock); + gpu_write(gpu, domain->profile_config, signal->data); + value += gpu_read(gpu, domain->profile_read); + } + + /* switch back to pixel pipe 0 to prevent GPU hang */ + clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK); + clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(0); + gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock); + + return value; +} + static const struct etnaviv_pm_domain doms_3d[] = { { .name = "HI", @@ -95,10 +119,51 @@ static const struct etnaviv_pm_domain doms_3d[] = { &perf_reg_read } } + }, + { + .name = "PE", + .profile_read = VIVS_MC_PROFILE_PE_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG0, + .nr_signals = 5, + .signal = (const struct etnaviv_pm_signal[]) { + { + "PIXEL_COUNT_KILLED_BY_COLOR_PIPE", + VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE, + &pipe_reg_read + }, + { + "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE", + VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE, + &pipe_reg_read + }, + { + "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE", + VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE, + &pipe_reg_read + }, + { + "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE", + VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE, + &pipe_reg_read + } + } } }; static const struct etnaviv_pm_domain doms_2d[] = { + { + .name = "PE", + .profile_read = VIVS_MC_PROFILE_PE_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG0, + .nr_signals = 1, + .signal = (const struct etnaviv_pm_signal[]) { + { + "PIXELS_RENDERED_2D", + VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D, + &pipe_reg_read + } + } + } }; static const struct etnaviv_pm_domain doms_vg[] = { -- cgit v1.2.3 From 98b2482ec48d23ca76217f349e26a739c640529a Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:33 +0200 Subject: drm/etnaviv: add SH perf domain Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index 9f933feabff2..cdc02c3be64e 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -147,6 +147,59 @@ static const struct etnaviv_pm_domain doms_3d[] = { &pipe_reg_read } } + }, + { + .name = "SH", + .profile_read = VIVS_MC_PROFILE_SH_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG0, + .nr_signals = 9, + .signal = (const struct etnaviv_pm_signal[]) { + { + "SHADER_CYCLES", + VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES, + &perf_reg_read + }, + { + "PS_INST_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER, + &perf_reg_read + }, + { + "RENDERED_PIXEL_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_PIXEL_COUNTER, + &perf_reg_read + }, + { + "VS_INST_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_VS_INST_COUNTER, + &pipe_reg_read + }, + { + "RENDERED_VERTICE_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_VERTICE_COUNTER, + &pipe_reg_read + }, + { + "VTX_BRANCH_INST_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_VTX_BRANCH_INST_COUNTER, + &pipe_reg_read + }, + { + "VTX_TEXLD_INST_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_VTX_TEXLD_INST_COUNTER, + &pipe_reg_read + }, + { + "PXL_BRANCH_INST_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_PXL_BRANCH_INST_COUNTER, + &pipe_reg_read + }, + { + "PXL_TEXLD_INST_COUNTER", + VIVS_MC_PROFILE_CONFIG0_SH_PXL_TEXLD_INST_COUNTER, + &pipe_reg_read + } + } } }; -- cgit v1.2.3 From c3787ff6545ef2e60710e9926e3b00d596e5d7e8 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:34 +0200 Subject: drm/etnaviv: add PA perf domain Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index cdc02c3be64e..3ab5ff26c648 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -200,6 +200,44 @@ static const struct etnaviv_pm_domain doms_3d[] = { &pipe_reg_read } } + }, + { + .name = "PA", + .profile_read = VIVS_MC_PROFILE_PA_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG1, + .nr_signals = 6, + .signal = (const struct etnaviv_pm_signal[]) { + { + "INPUT_VTX_COUNTER", + VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER, + &perf_reg_read + }, + { + "INPUT_PRIM_COUNTER", + VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER, + &perf_reg_read + }, + { + "OUTPUT_PRIM_COUNTER", + VIVS_MC_PROFILE_CONFIG1_PA_OUTPUT_PRIM_COUNTER, + &perf_reg_read + }, + { + "DEPTH_CLIPPED_COUNTER", + VIVS_MC_PROFILE_CONFIG1_PA_DEPTH_CLIPPED_COUNTER, + &pipe_reg_read + }, + { + "TRIVIAL_REJECTED_COUNTER", + VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER, + &pipe_reg_read + }, + { + "CULLED_COUNTER", + VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER, + &pipe_reg_read + } + } } }; -- cgit v1.2.3 From a515264c958427eef1813c45da13086ca1784929 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:35 +0200 Subject: drm/etnaviv: add SE perf domain Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index 3ab5ff26c648..5dbd5b433dc3 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -238,6 +238,24 @@ static const struct etnaviv_pm_domain doms_3d[] = { &pipe_reg_read } } + }, + { + .name = "SE", + .profile_read = VIVS_MC_PROFILE_SE_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG1, + .nr_signals = 2, + .signal = (const struct etnaviv_pm_signal[]) { + { + "CULLED_TRIANGLE_COUNT", + VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT, + &perf_reg_read + }, + { + "CULLED_LINES_COUNT", + VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT, + &perf_reg_read + } + } } }; -- cgit v1.2.3 From 91a9a17b59c10237c6fd72161682353be94cf01d Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:36 +0200 Subject: drm/etnaviv: add RA perf domain Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index 5dbd5b433dc3..aa7fe0b954a1 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -256,6 +256,49 @@ static const struct etnaviv_pm_domain doms_3d[] = { &perf_reg_read } } + }, + { + .name = "RA", + .profile_read = VIVS_MC_PROFILE_RA_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG1, + .nr_signals = 7, + .signal = (const struct etnaviv_pm_signal[]) { + { + "VALID_PIXEL_COUNT", + VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT, + &perf_reg_read + }, + { + "TOTAL_QUAD_COUNT", + VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT, + &perf_reg_read + }, + { + "VALID_QUAD_COUNT_AFTER_EARLY_Z", + VIVS_MC_PROFILE_CONFIG1_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z, + &perf_reg_read + }, + { + "TOTAL_PRIMITIVE_COUNT", + VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_PRIMITIVE_COUNT, + &perf_reg_read + }, + { + "PIPE_CACHE_MISS_COUNTER", + VIVS_MC_PROFILE_CONFIG1_RA_PIPE_CACHE_MISS_COUNTER, + &perf_reg_read + }, + { + "PREFETCH_CACHE_MISS_COUNTER", + VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER, + &perf_reg_read + }, + { + "CULLED_QUAD_COUNT", + VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT, + &perf_reg_read + } + } } }; -- cgit v1.2.3 From 9646025ee6c340b5e5ff2e34d4ae05edc45f1dd4 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:37 +0200 Subject: drm/etnaviv: add TX perf domain Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index aa7fe0b954a1..9efa933fc7b1 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -299,6 +299,59 @@ static const struct etnaviv_pm_domain doms_3d[] = { &perf_reg_read } } + }, + { + .name = "TX", + .profile_read = VIVS_MC_PROFILE_TX_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG1, + .nr_signals = 9, + .signal = (const struct etnaviv_pm_signal[]) { + { + "TOTAL_BILINEAR_REQUESTS", + VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS, + &perf_reg_read + }, + { + "TOTAL_TRILINEAR_REQUESTS", + VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS, + &perf_reg_read + }, + { + "TOTAL_DISCARDED_TEXTURE_REQUESTS", + VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS, + &perf_reg_read + }, + { + "TOTAL_TEXTURE_REQUESTS", + VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TEXTURE_REQUESTS, + &perf_reg_read + }, + { + "MEM_READ_COUNT", + VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_COUNT, + &perf_reg_read + }, + { + "MEM_READ_IN_8B_COUNT", + VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_IN_8B_COUNT, + &perf_reg_read + }, + { + "CACHE_MISS_COUNT", + VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_COUNT, + &perf_reg_read + }, + { + "CACHE_HIT_TEXEL_COUNT", + VIVS_MC_PROFILE_CONFIG1_TX_CACHE_HIT_TEXEL_COUNT, + &perf_reg_read + }, + { + "CACHE_MISS_TEXEL_COUNT", + VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_TEXEL_COUNT, + &perf_reg_read + } + } } }; -- cgit v1.2.3 From 49168ee91dd4c47749d52ec270861026da3ccc45 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:38 +0200 Subject: drm/etnaviv: add MC perf domain Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index 9efa933fc7b1..768f5aafdd18 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -352,6 +352,29 @@ static const struct etnaviv_pm_domain doms_3d[] = { &perf_reg_read } } + }, + { + .name = "MC", + .profile_read = VIVS_MC_PROFILE_MC_READ, + .profile_config = VIVS_MC_PROFILE_CONFIG2, + .nr_signals = 3, + .signal = (const struct etnaviv_pm_signal[]) { + { + "TOTAL_READ_REQ_8B_FROM_PIPELINE", + VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE, + &perf_reg_read + }, + { + "TOTAL_READ_REQ_8B_FROM_IP", + VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP, + &perf_reg_read + }, + { + "TOTAL_WRITE_REQ_8B_FROM_PIPELINE", + VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE, + &perf_reg_read + } + } } }; -- cgit v1.2.3 From 2c8b0c5a99054ba909036d7f9c7bb7391b48b6f5 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:39 +0200 Subject: drm/etnaviv: need to disable clock gating when doing profiling As done by Vivante kernel driver. Signed-off-by: Christian Gmeiner Reviewed-by: Lucas Stach Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 56764b4b94aa..c00086d75580 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1346,6 +1346,13 @@ static void sync_point_perfmon_sample(struct etnaviv_gpu *gpu, static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu, struct etnaviv_event *event) { + u32 val; + + /* disable clock gating */ + val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); + val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; + gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val); + sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE); } @@ -1354,6 +1361,7 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, { const struct etnaviv_cmdbuf *cmdbuf = event->cmdbuf; unsigned int i; + u32 val; sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST); @@ -1362,6 +1370,11 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, *pmr->bo_vma = pmr->sequence; } + + /* enable clock gating */ + val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); + val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; + gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val); } -- cgit v1.2.3 From 04a7d18d7975f720bc0122957eafb32fe42e2dff Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:42 +0200 Subject: drm/etnaviv: enable debug registers on demand Some performance register are debug register and they need to be enabled in order to be functional. Signed-off-by: Christian Gmeiner Reviewed-by: Lucas Stach Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index c00086d75580..51b3fbea1bf0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1353,6 +1353,11 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu, val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val); + /* enable debug register */ + val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); + val &= ~VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS; + gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val); + sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE); } @@ -1371,6 +1376,11 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, *pmr->bo_vma = pmr->sequence; } + /* disable debug register */ + val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); + val |= VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS; + gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val); + /* enable clock gating */ val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; -- cgit v1.2.3 From 4fd32aa413c5ad498455a7d07ee0ec4b071a78ea Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 24 Sep 2017 15:15:43 +0200 Subject: drm/etnaviv: submit supports performance monitor requests We increment the minor driver version so userspace can detect perfmon support. Signed-off-by: Christian Gmeiner Reviewed-by: Lucas Stach Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 8721dc23312f..3fadb8d45e51 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -550,7 +550,7 @@ static struct drm_driver etnaviv_drm_driver = { .desc = "etnaviv DRM", .date = "20151214", .major = 1, - .minor = 1, + .minor = 2, }; /* -- cgit v1.2.3 From 7f9d398c16040f32ba7bc6521a89c06c9cb09442 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 28 Sep 2017 15:45:14 +0200 Subject: drm/etnaviv: remove stale comment This comment is outdated as the driver is taking care about clock gating and the pulse eater for quite some time already. Signed-off-by: Lucas Stach Reviewed-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 51b3fbea1bf0..3e0fcc1fafb5 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -435,13 +435,6 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) unsigned long timeout; bool failed = true; - /* TODO - * - * - clock gating - * - puls eater - * - what about VG? - */ - /* We hope that the GPU resets in under one second */ timeout = jiffies + msecs_to_jiffies(1000); -- cgit v1.2.3 From 13cde9f4c62accdb35f769501ae951ecd75cccc9 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 20 Sep 2017 12:24:11 +0200 Subject: drm/etnaviv: remove unused function etnaviv_gem_new We only ever do GEM object creation by handle, as there is no kernel internal use of GEM objects. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 4 ---- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 19 ------------------- 2 files changed, 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 203613ae24dc..d249acb6da08 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -91,10 +91,6 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj); void etnaviv_gem_free_object(struct drm_gem_object *obj); int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, u32 size, u32 flags, u32 *handle); -struct drm_gem_object *etnaviv_gem_new_locked(struct drm_device *dev, - u32 size, u32 flags); -struct drm_gem_object *etnaviv_gem_new(struct drm_device *dev, - u32 size, u32 flags); int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file, uintptr_t ptr, u32 size, u32 flags, u32 *handle); u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 5a634594a6ce..d0f2196ad989 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -701,25 +701,6 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, return ret; } -struct drm_gem_object *etnaviv_gem_new(struct drm_device *dev, - u32 size, u32 flags) -{ - struct drm_gem_object *obj; - int ret; - - obj = __etnaviv_gem_new(dev, size, flags); - if (IS_ERR(obj)) - return obj; - - ret = etnaviv_gem_obj_add(dev, obj); - if (ret < 0) { - drm_gem_object_put_unlocked(obj); - return ERR_PTR(ret); - } - - return obj; -} - int etnaviv_gem_new_private(struct drm_device *dev, size_t size, u32 flags, struct reservation_object *robj, const struct etnaviv_gem_ops *ops, struct etnaviv_gem_object **res) -- cgit v1.2.3 From 4046217954d4e79d57d34c56ce42dec4f87e2ce9 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 9 Oct 2017 12:03:30 +0200 Subject: drm/etnaviv: reduce reset delay After reset assertion, we only have to wait for the reset signals to propagate through the GPU before deasserting the reset again. A few hundred clock cycles should be more than enough. Replace the msleep(1), which can actually take about 30 ms on i.MX6Q in some configurations, with an usleep_range of a few microseconds. If the delay was too short, the FE would not be idle afterwards, and the reset would be retried. Signed-off-by: Philipp Zabel Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 3e0fcc1fafb5..95ee479c95cb 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -456,7 +456,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control); /* wait for reset. */ - msleep(1); + usleep_range(10, 20); /* reset soft reset bit. */ control &= ~VIVS_HI_CLOCK_CONTROL_SOFT_RESET; -- cgit v1.2.3 From 8272170f7da34e2554bed10ab76582094ea6816d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 9 Oct 2017 12:03:31 +0200 Subject: drm/etnaviv: remove unnecessary clock stabilization delay There is no reason to wait for clock stabilization here, as the clock framework guarantees that PLL clock sources are stable before clk_enable returns. Signed-off-by: Philipp Zabel Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 95ee479c95cb..8197e1d6ed11 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -444,9 +444,6 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) control = VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale); etnaviv_gpu_load_clock(gpu, control); - /* Wait for stable clock. Vivante's code waited for 1ms */ - usleep_range(1000, 10000); - /* isolate the GPU. */ control |= VIVS_HI_CLOCK_CONTROL_ISOLATE_GPU; gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control); -- cgit v1.2.3 From 7741b547b6e000b08e20667bb3bef22e1a362661 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 9 Oct 2017 18:44:00 +0200 Subject: drm/i915: Preallocate our mmu notifier workequeu to unbreak cpu hotplug deadlock 4.14-rc1 gained the fancy new cross-release support in lockdep, which seems to have uncovered a few more rules about what is allowed and isn't. This one here seems to indicate that allocating a work-queue while holding mmap_sem is a no-go, so let's try to preallocate it. Of course another way to break this chain would be somewhere in the cpu hotplug code, since this isn't the only trace we're finding now which goes through msr_create_device. Full lockdep splat: ====================================================== WARNING: possible circular locking dependency detected 4.14.0-rc1-CI-CI_DRM_3118+ #1 Tainted: G U ------------------------------------------------------ prime_mmap/1551 is trying to acquire lock: (cpu_hotplug_lock.rw_sem){++++}, at: [] apply_workqueue_attrs+0x17/0x50 but task is already holding lock: (&dev_priv->mm_lock){+.+.}, at: [] i915_gem_userptr_init__mmu_notifier+0x14a/0x270 [i915] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #6 (&dev_priv->mm_lock){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 __mutex_lock+0x86/0x9b0 mutex_lock_nested+0x1b/0x20 i915_gem_userptr_init__mmu_notifier+0x14a/0x270 [i915] i915_gem_userptr_ioctl+0x222/0x2c0 [i915] drm_ioctl_kernel+0x69/0xb0 drm_ioctl+0x2f9/0x3d0 do_vfs_ioctl+0x94/0x670 SyS_ioctl+0x41/0x70 entry_SYSCALL_64_fastpath+0x1c/0xb1 -> #5 (&mm->mmap_sem){++++}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 __might_fault+0x68/0x90 _copy_to_user+0x23/0x70 filldir+0xa5/0x120 dcache_readdir+0xf9/0x170 iterate_dir+0x69/0x1a0 SyS_getdents+0xa5/0x140 entry_SYSCALL_64_fastpath+0x1c/0xb1 -> #4 (&sb->s_type->i_mutex_key#5){++++}: down_write+0x3b/0x70 handle_create+0xcb/0x1e0 devtmpfsd+0x139/0x180 kthread+0x152/0x190 ret_from_fork+0x27/0x40 -> #3 ((complete)&req.done){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 wait_for_common+0x58/0x210 wait_for_completion+0x1d/0x20 devtmpfs_create_node+0x13d/0x160 device_add+0x5eb/0x620 device_create_groups_vargs+0xe0/0xf0 device_create+0x3a/0x40 msr_device_create+0x2b/0x40 cpuhp_invoke_callback+0xa3/0x840 cpuhp_thread_fun+0x7a/0x150 smpboot_thread_fn+0x18a/0x280 kthread+0x152/0x190 ret_from_fork+0x27/0x40 -> #2 (cpuhp_state){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 cpuhp_issue_call+0x10b/0x170 __cpuhp_setup_state_cpuslocked+0x134/0x2a0 __cpuhp_setup_state+0x46/0x60 page_writeback_init+0x43/0x67 pagecache_init+0x3d/0x42 start_kernel+0x3a8/0x3fc x86_64_start_reservations+0x2a/0x2c x86_64_start_kernel+0x6d/0x70 verify_cpu+0x0/0xfb -> #1 (cpuhp_state_mutex){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 __mutex_lock+0x86/0x9b0 mutex_lock_nested+0x1b/0x20 __cpuhp_setup_state_cpuslocked+0x52/0x2a0 __cpuhp_setup_state+0x46/0x60 page_alloc_init+0x28/0x30 start_kernel+0x145/0x3fc x86_64_start_reservations+0x2a/0x2c x86_64_start_kernel+0x6d/0x70 verify_cpu+0x0/0xfb -> #0 (cpu_hotplug_lock.rw_sem){++++}: check_prev_add+0x430/0x840 __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 cpus_read_lock+0x3d/0xb0 apply_workqueue_attrs+0x17/0x50 __alloc_workqueue_key+0x1d8/0x4d9 i915_gem_userptr_init__mmu_notifier+0x1fb/0x270 [i915] i915_gem_userptr_ioctl+0x222/0x2c0 [i915] drm_ioctl_kernel+0x69/0xb0 drm_ioctl+0x2f9/0x3d0 do_vfs_ioctl+0x94/0x670 SyS_ioctl+0x41/0x70 entry_SYSCALL_64_fastpath+0x1c/0xb1 other info that might help us debug this: Chain exists of: cpu_hotplug_lock.rw_sem --> &mm->mmap_sem --> &dev_priv->mm_lock Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&dev_priv->mm_lock); lock(&mm->mmap_sem); lock(&dev_priv->mm_lock); lock(cpu_hotplug_lock.rw_sem); *** DEADLOCK *** 2 locks held by prime_mmap/1551: #0: (&mm->mmap_sem){++++}, at: [] i915_gem_userptr_init__mmu_notifier+0x138/0x270 [i915] #1: (&dev_priv->mm_lock){+.+.}, at: [] i915_gem_userptr_init__mmu_notifier+0x14a/0x270 [i915] stack backtrace: CPU: 4 PID: 1551 Comm: prime_mmap Tainted: G U 4.14.0-rc1-CI-CI_DRM_3118+ #1 Hardware name: Dell Inc. XPS 8300 /0Y2MRG, BIOS A06 10/17/2011 Call Trace: dump_stack+0x68/0x9f print_circular_bug+0x235/0x3c0 ? lockdep_init_map_crosslock+0x20/0x20 check_prev_add+0x430/0x840 __lock_acquire+0x1420/0x15e0 ? __lock_acquire+0x1420/0x15e0 ? lockdep_init_map_crosslock+0x20/0x20 lock_acquire+0xb0/0x200 ? apply_workqueue_attrs+0x17/0x50 cpus_read_lock+0x3d/0xb0 ? apply_workqueue_attrs+0x17/0x50 apply_workqueue_attrs+0x17/0x50 __alloc_workqueue_key+0x1d8/0x4d9 ? __lockdep_init_map+0x57/0x1c0 i915_gem_userptr_init__mmu_notifier+0x1fb/0x270 [i915] i915_gem_userptr_ioctl+0x222/0x2c0 [i915] ? i915_gem_userptr_release+0x140/0x140 [i915] drm_ioctl_kernel+0x69/0xb0 drm_ioctl+0x2f9/0x3d0 ? i915_gem_userptr_release+0x140/0x140 [i915] ? __do_page_fault+0x2a4/0x570 do_vfs_ioctl+0x94/0x670 ? entry_SYSCALL_64_fastpath+0x5/0xb1 ? __this_cpu_preempt_check+0x13/0x20 ? trace_hardirqs_on_caller+0xe3/0x1b0 SyS_ioctl+0x41/0x70 entry_SYSCALL_64_fastpath+0x1c/0xb1 RIP: 0033:0x7fbb83c39587 RSP: 002b:00007fff188dc228 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: ffffffff81492963 RCX: 00007fbb83c39587 RDX: 00007fff188dc260 RSI: 00000000c0186473 RDI: 0000000000000003 RBP: ffffc90001487f88 R08: 0000000000000000 R09: 00007fff188dc2ac R10: 00007fbb83efcb58 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000003 R14: 00000000c0186473 R15: 00007fff188dc2ac ? __this_cpu_preempt_check+0x13/0x20 Note that this also has the minor benefit of slightly reducing the critical section where we hold mmap_sem. v2: Set ret correctly when we raced with another thread. v3: Use Chris' diff. Attach the right lockdep splat. v4: Repaint in Tvrtko's colors (aka don't report ENOMEM if we race and some other thread managed to not also get an ENOMEM and successfully install the mmu notifier. Note that the kernel guarantees that small allocations succeed, so this never actually happens). Cc: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Sasha Levin Cc: Marta Lofstedt Cc: Tejun Heo References: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_3180/shard-hsw3/igt@prime_mmap@test_userptr.html Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102939 Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171009164401.16035-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/i915_gem_userptr.c | 38 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index c36a84b070b6..4d712a4db63b 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -164,7 +164,6 @@ static struct i915_mmu_notifier * i915_mmu_notifier_create(struct mm_struct *mm) { struct i915_mmu_notifier *mn; - int ret; mn = kmalloc(sizeof(*mn), GFP_KERNEL); if (mn == NULL) @@ -179,14 +178,6 @@ i915_mmu_notifier_create(struct mm_struct *mm) return ERR_PTR(-ENOMEM); } - /* Protected by mmap_sem (write-lock) */ - ret = __mmu_notifier_register(&mn->mn, mm); - if (ret) { - destroy_workqueue(mn->wq); - kfree(mn); - return ERR_PTR(ret); - } - return mn; } @@ -210,23 +201,40 @@ i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) static struct i915_mmu_notifier * i915_mmu_notifier_find(struct i915_mm_struct *mm) { - struct i915_mmu_notifier *mn = mm->mn; + struct i915_mmu_notifier *mn; + int err = 0; mn = mm->mn; if (mn) return mn; + mn = i915_mmu_notifier_create(mm->mm); + if (IS_ERR(mn)) + err = PTR_ERR(mn); + down_write(&mm->mm->mmap_sem); mutex_lock(&mm->i915->mm_lock); - if ((mn = mm->mn) == NULL) { - mn = i915_mmu_notifier_create(mm->mm); - if (!IS_ERR(mn)) - mm->mn = mn; + if (mm->mn == NULL && !err) { + /* Protected by mmap_sem (write-lock) */ + err = __mmu_notifier_register(&mn->mn, mm->mm); + if (!err) { + /* Protected by mm_lock */ + mm->mn = fetch_and_zero(&mn); + } + } else { + /* someone else raced and successfully installed the mmu + * notifier, we can cancel our own errors */ + err = 0; } mutex_unlock(&mm->i915->mm_lock); up_write(&mm->mm->mmap_sem); - return mn; + if (mn) { + destroy_workqueue(mn->wq); + kfree(mn); + } + + return err ? ERR_PTR(err) : mm->mn; } static int -- cgit v1.2.3 From dc2279e169f0676b969014c02689c4bbb069ad01 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 10 Oct 2017 14:48:57 +0300 Subject: drm/i915: Use execlists_num_ports instead of size of array There is function to tell how many ports we have, so use it. We still have direct relationship with array size and port count, so no harm was done. Fixes: 76e70087d360 ("drm/i915: Make execlist port count variable") Cc: Mika Kuoppala Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171010114857.13108-1-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_guc_submission.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 31381a327347..f15de4dcefde 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -500,7 +500,7 @@ static void i915_guc_submit(struct intel_engine_cs *engine) const unsigned int engine_id = engine->id; unsigned int n; - for (n = 0; n < ARRAY_SIZE(execlists->port); n++) { + for (n = 0; n < execlists_num_ports(execlists); n++) { struct drm_i915_gem_request *rq; unsigned int count; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 721432ddf403..fbfcf88d7fe3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -691,7 +691,7 @@ static void execlist_cancel_port_requests(struct intel_engine_execlists *execlists) { struct execlist_port *port = execlists->port; - unsigned int num_ports = ARRAY_SIZE(execlists->port); + unsigned int num_ports = execlists_num_ports(execlists); while (num_ports-- && port_isset(port)) { struct drm_i915_gem_request *rq = port_request(port); -- cgit v1.2.3 From 69208c9e1e938cd115fdafdc502b5a7aa99d8d0b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 10 Oct 2017 11:18:16 +0200 Subject: drm/i915: Increase atomic update vblank evasion time with lockdep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All our mmio writes take forever with lockdep due to the constant lock acquire&dropping we do. Ville has some patches to only acquire the mmio spinlocks once instead for every single mmio, but those aren't ready yet. As an interim solution just extend our budget slightly when lockdep is enabled, to avoid the rare and sporadic noise in CI. v2: I forgot to add the FIXME comment ... Cc: Ville Syrjala Acked-by: Ville Syrjälä References: https://bugs.freedesktop.org/show_bug.cgi?id=103169 References: https://bugs.freedesktop.org/show_bug.cgi?id=103124 References: https://bugs.freedesktop.org/show_bug.cgi?id=102403 References: https://bugs.freedesktop.org/show_bug.cgi?id=103020 References: https://bugs.freedesktop.org/show_bug.cgi?id=103019 References: https://bugs.freedesktop.org/show_bug.cgi?id=102723 References: https://bugs.freedesktop.org/show_bug.cgi?id=102544 References: https://bugs.freedesktop.org/show_bug.cgi?id=103180 Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171010091816.26898-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/intel_sprite.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index b0d6e3e28d07..f29369622d2c 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -66,7 +66,13 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 1000 * adjusted_mode->crtc_htotal); } +/* FIXME: We should instead only take spinlocks once for the entire update + * instead of once per mmio. */ +#if IS_ENABLED(CONFIG_PROVE_LOCKING) +#define VBLANK_EVASION_TIME_US 250 +#else #define VBLANK_EVASION_TIME_US 100 +#endif /** * intel_pipe_update_start() - start update of a set of display registers -- cgit v1.2.3 From ecf837d98e375d18f4fd8df6f744ca9ca9b5957d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:55:56 +0300 Subject: drm/i915: Use enum pipe for PCH transcoders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One more place where we've failed to switch to enum pipe when talking about PCH transcoders. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010125556.25086-1-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 45d6e57fbe89..57d886cece16 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14758,10 +14758,10 @@ static struct intel_connector *intel_encoder_find_connector(struct intel_encoder } static bool has_pch_trancoder(struct drm_i915_private *dev_priv, - enum transcoder pch_transcoder) + enum pipe pch_transcoder) { return HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) || - (HAS_PCH_LPT_H(dev_priv) && pch_transcoder == TRANSCODER_A); + (HAS_PCH_LPT_H(dev_priv) && pch_transcoder == PIPE_A); } static void intel_sanitize_crtc(struct intel_crtc *crtc, @@ -14844,7 +14844,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc, * PCH transcoders B and C would prevent enabling the south * error interrupt (see cpt_can_enable_serr_int()). */ - if (has_pch_trancoder(dev_priv, (enum transcoder)crtc->pipe)) + if (has_pch_trancoder(dev_priv, crtc->pipe)) crtc->pch_fifo_underrun_disabled = true; } } -- cgit v1.2.3 From dfa311f0d8e2bbd4ba97344ac4a2eb6e810fc0e6 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 13 Sep 2017 17:08:54 +0300 Subject: drm/i915: Parametrize CBR_DPLLBMD_PIPE defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply a bit of polish by parametrizing the CBR_DPLLBMD_PIPE defines. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170913140900.6972-3-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 3 +-- drivers/gpu/drm/i915/intel_display.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 50e65c98ca6c..1ebbbc9ad9e7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5684,8 +5684,7 @@ enum { #define CBR_PWM_CLOCK_MUX_SELECT (1<<30) #define CBR4_VLV _MMIO(VLV_DISPLAY_BASE + 0x70450) -#define CBR_DPLLBMD_PIPE_C (1<<29) -#define CBR_DPLLBMD_PIPE_B (1<<18) +#define CBR_DPLLBMD_PIPE(pipe) (1<<(7+(pipe)*11)) /* pipes B and C */ /* FIFO watermark sizes etc */ #define G4X_FIFO_LINE_SIZE 64 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 57d886cece16..c96d02ce1f2f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1539,7 +1539,7 @@ static void chv_enable_pll(struct intel_crtc *crtc, * DPLLCMD is AWOL. Use chicken bits to propagate * the value from DPLLBMD to either pipe B or C. */ - I915_WRITE(CBR4_VLV, pipe == PIPE_B ? CBR_DPLLBMD_PIPE_B : CBR_DPLLBMD_PIPE_C); + I915_WRITE(CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); I915_WRITE(DPLL_MD(PIPE_B), pipe_config->dpll_hw_state.dpll_md); I915_WRITE(CBR4_VLV, 0); dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md; -- cgit v1.2.3 From 939994da2f63cb130ddeb131736254ad203662cd Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 13 Sep 2017 17:08:56 +0300 Subject: drm/i915: Pass crtc state to i9xx_enable_pll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the crtc state to i9xx_enable_pll() and use it rather than crtc->config. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170913140900.6972-5-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c96d02ce1f2f..99a2052864a1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1568,11 +1568,12 @@ static int intel_num_dvo_pipes(struct drm_i915_private *dev_priv) return count; } -static void i9xx_enable_pll(struct intel_crtc *crtc) +static void i9xx_enable_pll(struct intel_crtc *crtc, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); i915_reg_t reg = DPLL(crtc->pipe); - u32 dpll = crtc->config->dpll_hw_state.dpll; + u32 dpll = crtc_state->dpll_hw_state.dpll; int i; assert_pipe_disabled(dev_priv, crtc->pipe); @@ -1609,7 +1610,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) if (INTEL_GEN(dev_priv) >= 4) { I915_WRITE(DPLL_MD(crtc->pipe), - crtc->config->dpll_hw_state.dpll_md); + crtc_state->dpll_hw_state.dpll_md); } else { /* The pixel multiplier can only be updated once the * DPLL is enabled and the clocks are stable. @@ -5895,7 +5896,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config, intel_encoders_pre_enable(crtc, pipe_config, old_state); - i9xx_enable_pll(intel_crtc); + i9xx_enable_pll(intel_crtc, pipe_config); i9xx_pfit_enable(intel_crtc); -- cgit v1.2.3 From db37d8f39c1ea5a7efb410fda94e3bb9d5844b1d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 13 Sep 2017 17:08:57 +0300 Subject: drm/i915: Nuke the bogus kernel doc for i9xx_disable_pll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20170913140900.6972-6-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 99a2052864a1..cf13fba80d53 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1628,15 +1628,6 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, } } -/** - * i9xx_disable_pll - disable a PLL - * @dev_priv: i915 private structure - * @pipe: pipe PLL to disable - * - * Disable the PLL for @pipe, making sure the pipe is off first. - * - * Note! This is for pre-ILK only. - */ static void i9xx_disable_pll(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); -- cgit v1.2.3 From e836e3211229d7307660239cc957f2ab60e6aa00 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Wed, 6 Sep 2017 10:11:38 +0200 Subject: i40e: Fix comment about locking for __i40e_read_nvm_word() Caller needs to acquire the lock. Called functions will not. Fixes: 09f79fd49d94 ("i40e: avoid NVM acquire deadlock during NVM update") Signed-off-by: Stefano Brivio Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c index 57505b1df98d..d591b3e6bd7c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c @@ -298,7 +298,7 @@ static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, } /** - * __i40e_read_nvm_word - Reads nvm word, assumes called does the locking + * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) * @data: word read from the Shadow RAM -- cgit v1.2.3 From 2b9478ffc550f17c6cd8c69057234e91150f5972 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 4 Oct 2017 08:44:43 -0700 Subject: i40e: Fix memory leak related filter programming status It looks like we weren't correctly placing the pages from buffers that had been used to return a filter programming status back on the ring. As a result they were being overwritten and tracking of the pages was lost. This change works to correct that by incorporating part of i40e_put_rx_buffer into the programming status handler code. As a result we should now be correctly placing the pages for those buffers on the re-allocation list instead of letting them stay in place. Fixes: 0e626ff7ccbf ("i40e: Fix support for flow director programming status") Reported-by: Anders K. Pedersen Signed-off-by: Alexander Duyck Tested-by: Anders K Pedersen Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 63 ++++++++++++++++------------- 1 file changed, 36 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 1519dfb851d0..2756131495f0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1037,6 +1037,32 @@ reset_latency: return false; } +/** + * i40e_reuse_rx_page - page flip buffer and store it back on the ring + * @rx_ring: rx descriptor ring to store buffers on + * @old_buff: donor buffer to have page reused + * + * Synchronizes page for reuse by the adapter + **/ +static void i40e_reuse_rx_page(struct i40e_ring *rx_ring, + struct i40e_rx_buffer *old_buff) +{ + struct i40e_rx_buffer *new_buff; + u16 nta = rx_ring->next_to_alloc; + + new_buff = &rx_ring->rx_bi[nta]; + + /* update, and store next to alloc */ + nta++; + rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; + + /* transfer page from old buffer to new buffer */ + new_buff->dma = old_buff->dma; + new_buff->page = old_buff->page; + new_buff->page_offset = old_buff->page_offset; + new_buff->pagecnt_bias = old_buff->pagecnt_bias; +} + /** * i40e_rx_is_programming_status - check for programming status descriptor * @qw: qword representing status_error_len in CPU ordering @@ -1071,15 +1097,24 @@ static void i40e_clean_programming_status(struct i40e_ring *rx_ring, union i40e_rx_desc *rx_desc, u64 qw) { - u32 ntc = rx_ring->next_to_clean + 1; + struct i40e_rx_buffer *rx_buffer; + u32 ntc = rx_ring->next_to_clean; u8 id; /* fetch, update, and store next to clean */ + rx_buffer = &rx_ring->rx_bi[ntc++]; ntc = (ntc < rx_ring->count) ? ntc : 0; rx_ring->next_to_clean = ntc; prefetch(I40E_RX_DESC(rx_ring, ntc)); + /* place unused page back on the ring */ + i40e_reuse_rx_page(rx_ring, rx_buffer); + rx_ring->rx_stats.page_reuse_count++; + + /* clear contents of buffer_info */ + rx_buffer->page = NULL; + id = (qw & I40E_RX_PROG_STATUS_DESC_QW1_PROGID_MASK) >> I40E_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT; @@ -1638,32 +1673,6 @@ static bool i40e_cleanup_headers(struct i40e_ring *rx_ring, struct sk_buff *skb, return false; } -/** - * i40e_reuse_rx_page - page flip buffer and store it back on the ring - * @rx_ring: rx descriptor ring to store buffers on - * @old_buff: donor buffer to have page reused - * - * Synchronizes page for reuse by the adapter - **/ -static void i40e_reuse_rx_page(struct i40e_ring *rx_ring, - struct i40e_rx_buffer *old_buff) -{ - struct i40e_rx_buffer *new_buff; - u16 nta = rx_ring->next_to_alloc; - - new_buff = &rx_ring->rx_bi[nta]; - - /* update, and store next to alloc */ - nta++; - rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; - - /* transfer page from old buffer to new buffer */ - new_buff->dma = old_buff->dma; - new_buff->page = old_buff->page; - new_buff->page_offset = old_buff->page_offset; - new_buff->pagecnt_bias = old_buff->pagecnt_bias; -} - /** * i40e_page_is_reusable - check if any reuse is possible * @page: page struct to check -- cgit v1.2.3 From 0d5f662575e542ed22b5054c2b0887f42271be5e Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Tue, 10 Oct 2017 13:17:02 +0300 Subject: drm/i915: Don't relay on I915_MAX_PIPES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's remove the dependency on I915_MAX_PIPES. Instead, get the number of pipes from platform information. Reviewed-by: Ville Syrjälä Signed-off-by: Ramalingam C Signed-off-by: Mika Kahola Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1507630626-23806-2-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_audio.c | 2 +- drivers/gpu/drm/i915/intel_pipe_crc.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 27743be5b768..0ddba16fde1b 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -754,7 +754,7 @@ static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv, { struct intel_encoder *encoder; - if (WARN_ON(pipe >= I915_MAX_PIPES)) + if (WARN_ON(pipe >= INTEL_INFO(dev_priv)->num_pipes)) return NULL; /* MST */ diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c index 96043a51c1bf..24d781f97761 100644 --- a/drivers/gpu/drm/i915/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c @@ -775,11 +775,12 @@ display_crc_ctl_parse_object(const char *buf, enum intel_pipe_crc_object *o) return -EINVAL; } -static int display_crc_ctl_parse_pipe(const char *buf, enum pipe *pipe) +static int display_crc_ctl_parse_pipe(struct drm_i915_private *dev_priv, + const char *buf, enum pipe *pipe) { const char name = buf[0]; - if (name < 'A' || name >= pipe_name(I915_MAX_PIPES)) + if (name < 'A' || name >= pipe_name(INTEL_INFO(dev_priv)->num_pipes)) return -EINVAL; *pipe = name - 'A'; @@ -828,7 +829,7 @@ static int display_crc_ctl_parse(struct drm_i915_private *dev_priv, return -EINVAL; } - if (display_crc_ctl_parse_pipe(words[1], &pipe) < 0) { + if (display_crc_ctl_parse_pipe(dev_priv, words[1], &pipe) < 0) { DRM_DEBUG_DRIVER("unknown pipe %s\n", words[1]); return -EINVAL; } -- cgit v1.2.3 From 2b68504be6b47fabd4d14c89bbea37a6fd0fd28c Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Tue, 10 Oct 2017 13:17:03 +0300 Subject: drm/i915: Remove I915_MAX_PIPES dependency for DDB allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove dependency for I915_MAX_PIPES by replacing it with for_each_pipe() macro. v2: use 'enum pipe pipe' instead of 'i' Reviewed-by: Ville Syrjälä Signed-off-by: Ramalingam C Signed-off-by: Mika Kahola Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1507630626-23806-3-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_display.c | 5 ++++- drivers/gpu/drm/i915/intel_drv.h | 3 ++- drivers/gpu/drm/i915/intel_pm.c | 12 +++++++----- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cf13fba80d53..e03b0c3d6f9f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12215,7 +12215,10 @@ static void skl_update_crtcs(struct drm_atomic_state *state) if (updated & cmask || !cstate->base.active) continue; - if (skl_ddb_allocation_overlaps(entries, &cstate->wm.skl.ddb, i)) + if (skl_ddb_allocation_overlaps(dev_priv, + entries, + &cstate->wm.skl.ddb, + i)) continue; updated |= cmask; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0cab667fff57..ceb3b8284c86 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1893,7 +1893,8 @@ int intel_enable_sagv(struct drm_i915_private *dev_priv); int intel_disable_sagv(struct drm_i915_private *dev_priv); bool skl_wm_level_equals(const struct skl_wm_level *l1, const struct skl_wm_level *l2); -bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry **entries, +bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv, + const struct skl_ddb_entry **entries, const struct skl_ddb_entry *ddb, int ignore); bool ilk_disable_lp_wm(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9d0ca2656a23..39acfadb5a21 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4820,16 +4820,18 @@ static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, return a->start < b->end && b->start < a->end; } -bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry **entries, +bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv, + const struct skl_ddb_entry **entries, const struct skl_ddb_entry *ddb, int ignore) { - int i; + enum pipe pipe; - for (i = 0; i < I915_MAX_PIPES; i++) - if (i != ignore && entries[i] && - skl_ddb_entries_overlap(ddb, entries[i])) + for_each_pipe(dev_priv, pipe) { + if (pipe != ignore && entries[pipe] && + skl_ddb_entries_overlap(ddb, entries[pipe])) return true; + } return false; } -- cgit v1.2.3 From 0a195c02942236c977703023c024b75f5bb6b254 Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Tue, 10 Oct 2017 13:17:04 +0300 Subject: drm/i915: Fold IRQ pipe masks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold IRQ pipe masks into one loop instead of hardcoding per pipe. Reviewed-by: Ville Syrjälä Signed-off-by: Mika Kahola Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1507630626-23806-4-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index de777139f6a1..a38ad6043ae5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3610,16 +3610,15 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) else if (IS_BROADWELL(dev_priv)) de_port_enables |= GEN8_PORT_DP_A_HOTPLUG; - dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; - dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; - dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked; + for_each_pipe(dev_priv, pipe) { + dev_priv->de_irq_mask[pipe] = ~de_pipe_masked; - for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, dev_priv->de_irq_mask[pipe], de_pipe_enables); + } GEN3_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables); GEN3_IRQ_INIT(GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); -- cgit v1.2.3 From 78619e32e57f9f9acd8653b569e48f2d52fa3304 Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Tue, 10 Oct 2017 13:17:05 +0300 Subject: drm/i915: Favor for_each_pipe() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Favor for_each_pipe() macro when looping through pipes. v2: use 'enum pipe pipe' instead of 'i' Reviewed-by: Ville Syrjälä Signed-off-by: Mika Kahola Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1507630626-23806-5-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_pipe_crc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c index 24d781f97761..899839f2f7c6 100644 --- a/drivers/gpu/drm/i915/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c @@ -206,11 +206,11 @@ static const char *pipe_crc_source_name(enum intel_pipe_crc_source source) static int display_crc_ctl_show(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = m->private; - int i; + enum pipe pipe; - for (i = 0; i < I915_MAX_PIPES; i++) - seq_printf(m, "%c %s\n", pipe_name(i), - pipe_crc_source_name(dev_priv->pipe_crc[i].source)); + for_each_pipe(dev_priv, pipe) + seq_printf(m, "%c %s\n", pipe_name(pipe), + pipe_crc_source_name(dev_priv->pipe_crc[pipe].source)); return 0; } -- cgit v1.2.3 From 45c1cd8754064076f6090128958cbde9db45d41b Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Tue, 10 Oct 2017 13:17:06 +0300 Subject: drm/i915: Cleanup South Error Interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup and parametrize the handling of South Error Interrupts (SERR_INT). Reviewed-by: Ville Syrjälä Signed-off-by: Mika Kahola Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1507630626-23806-6-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 12 ++++-------- drivers/gpu/drm/i915/i915_reg.h | 3 --- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a38ad6043ae5..3736290f2d0c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2252,18 +2252,14 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) { u32 serr_int = I915_READ(SERR_INT); + enum pipe pipe; if (serr_int & SERR_INT_POISON) DRM_ERROR("PCH poison interrupt\n"); - if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN) - intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_A); - - if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN) - intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B); - - if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN) - intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_C); + for_each_pipe(dev_priv, pipe) + if (serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pipe)) + intel_pch_fifo_underrun_irq_handler(dev_priv, pipe); I915_WRITE(SERR_INT, serr_int); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1ebbbc9ad9e7..d2d0a83c09b6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7182,9 +7182,6 @@ enum { #define SERR_INT _MMIO(0xc4040) #define SERR_INT_POISON (1<<31) -#define SERR_INT_TRANS_C_FIFO_UNDERRUN (1<<6) -#define SERR_INT_TRANS_B_FIFO_UNDERRUN (1<<3) -#define SERR_INT_TRANS_A_FIFO_UNDERRUN (1<<0) #define SERR_INT_TRANS_FIFO_UNDERRUN(pipe) (1<<((pipe)*3)) /* digital port hotplug */ -- cgit v1.2.3 From 06ea8c537ab8d14454d41599a64d46364fe1a75a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 10 Oct 2017 12:10:05 +0100 Subject: drm/i915: Silently fallback to 4k scratch If we fail to allocate a 64k hugepage for scratch, we try again with a normal 4k page (with some loss of efficiency at runtime). As we handle this gracefully, we do not need a noisy allocation failure warning. Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171010111005.13625-1-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 4c605785e2b3..ca7fd34fbe8b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -538,7 +538,7 @@ setup_scratch_page(struct i915_address_space *vm, gfp_t gfp) if (i915_vm_is_48bit(vm) && HAS_PAGE_SIZES(vm->i915, I915_GTT_PAGE_SIZE_64K)) { order = get_order(I915_GTT_PAGE_SIZE_64K); - page = alloc_pages(gfp | __GFP_ZERO, order); + page = alloc_pages(gfp | __GFP_ZERO | __GFP_NOWARN, order); if (page) { addr = dma_map_page(vm->dma, page, 0, I915_GTT_PAGE_SIZE_64K, -- cgit v1.2.3 From aba2d9a6385a5cc4f7a7e8eb5788e1ddbc213fc0 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Fri, 6 Oct 2017 16:35:40 -0500 Subject: iommu/amd: Do not disable SWIOTLB if SME is active When SME memory encryption is active it will rely on SWIOTLB to handle DMA for devices that cannot support the addressing requirements of having the encryption mask set in the physical address. The IOMMU currently disables SWIOTLB if it is not running in passthrough mode. This is not desired as non-PCI devices attempting DMA may fail. Update the code to check if SME is active and not disable SWIOTLB. Fixes: 2543a786aa25 ("iommu/amd: Allow the AMD IOMMU to work with memory encryption") Signed-off-by: Tom Lendacky Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 51f8215877f5..822679ac90a1 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2773,14 +2773,16 @@ int __init amd_iommu_init_api(void) int __init amd_iommu_init_dma_ops(void) { - swiotlb = iommu_pass_through ? 1 : 0; + swiotlb = (iommu_pass_through || sme_me_mask) ? 1 : 0; iommu_detected = 1; /* * In case we don't initialize SWIOTLB (actually the common case - * when AMD IOMMU is enabled), make sure there are global - * dma_ops set as a fall-back for devices not handled by this - * driver (for example non-PCI devices). + * when AMD IOMMU is enabled and SME is not active), make sure there + * are global dma_ops set as a fall-back for devices not handled by + * this driver (for example non-PCI devices). When SME is active, + * make sure that swiotlb variable remains set so the global dma_ops + * continue to be SWIOTLB. */ if (!swiotlb) dma_ops = &nommu_dma_ops; -- cgit v1.2.3 From 0a7480bd327afcccd7263be5b485f85943e1e903 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Sep 2017 13:33:45 +0300 Subject: rpmsg: glink: Unlock on error in qcom_glink_request_intent() If qcom_glink_tx() fails, then we need to unlock before returning the error code. Fixes: 27b9c5b66b23 ("rpmsg: glink: Request for intents when unavailable") Acked-by: Sricharan R Signed-off-by: Dan Carpenter Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_glink_native.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 5a5e927ea50f..fecb1dafa8f3 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1197,7 +1197,7 @@ static int qcom_glink_request_intent(struct qcom_glink *glink, ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); if (ret) - return ret; + goto unlock; ret = wait_for_completion_timeout(&channel->intent_req_comp, 10 * HZ); if (!ret) { @@ -1207,6 +1207,7 @@ static int qcom_glink_request_intent(struct qcom_glink *glink, ret = channel->intent_req_result ? 0 : -ECANCELED; } +unlock: mutex_unlock(&channel->intent_req_lock); return ret; } -- cgit v1.2.3 From b775d158530285c9657a1a0628c139b0dfd0d2e5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Sep 2017 13:34:42 +0300 Subject: rpmsg: glink: Fix memory leak in qcom_glink_alloc_intent() We need to free "intent" and "intent->data" on a couple error paths. Fixes: 933b45da5d1d ("rpmsg: glink: Add support for TX intents") Acked-by: Sricharan R Signed-off-by: Dan Carpenter Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_glink_native.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index fecb1dafa8f3..5dcc9bf1c5bc 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -635,19 +635,18 @@ qcom_glink_alloc_intent(struct qcom_glink *glink, unsigned long flags; intent = kzalloc(sizeof(*intent), GFP_KERNEL); - if (!intent) return NULL; intent->data = kzalloc(size, GFP_KERNEL); if (!intent->data) - return NULL; + goto free_intent; spin_lock_irqsave(&channel->intent_lock, flags); ret = idr_alloc_cyclic(&channel->liids, intent, 1, -1, GFP_ATOMIC); if (ret < 0) { spin_unlock_irqrestore(&channel->intent_lock, flags); - return NULL; + goto free_data; } spin_unlock_irqrestore(&channel->intent_lock, flags); @@ -656,6 +655,12 @@ qcom_glink_alloc_intent(struct qcom_glink *glink, intent->reuse = reuseable; return intent; + +free_data: + kfree(intent->data); +free_intent: + kfree(intent); + return NULL; } static void qcom_glink_handle_rx_done(struct qcom_glink *glink, -- cgit v1.2.3 From 68c2d645ebbd4a636cf93ed56f15912bcf9376bc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Oct 2017 15:58:27 +0300 Subject: remoteproc: imx_rproc: fix a couple off by one bugs The priv->mem[] array has IMX7D_RPROC_MEM_MAX elements so the > should be >= to avoid writing one element beyond the end of the array. Fixes: a0ff4aa6f010 ("remoteproc: imx_rproc: add a NXP/Freescale imx_rproc driver") Signed-off-by: Dan Carpenter Signed-off-by: Bjorn Andersson --- drivers/remoteproc/imx_rproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 612d91403341..81ba44510b75 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -264,7 +264,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv, if (!(att->flags & ATT_OWN)) continue; - if (b > IMX7D_RPROC_MEM_MAX) + if (b >= IMX7D_RPROC_MEM_MAX) break; priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, @@ -296,7 +296,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv, return err; } - if (b > IMX7D_RPROC_MEM_MAX) + if (b >= IMX7D_RPROC_MEM_MAX) break; priv->mem[b].cpu_addr = devm_ioremap_resource(&pdev->dev, &res); -- cgit v1.2.3 From ab759b9732fd8a4ae0252bb2087e90d776f74b9f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 11 Sep 2017 21:54:17 +0200 Subject: remoteproc: qcom: fix RPMSG_QCOM_GLINK_SMEM dependencies When RPMSG_QCOM_GLINK_SMEM=m and one driver causes the qcom_common.c file to be compiled as built-in, we get a link error: drivers/remoteproc/qcom_common.o: In function `glink_subdev_remove': qcom_common.c:(.text+0x130): undefined reference to `qcom_glink_smem_unregister' qcom_common.c:(.text+0x130): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `qcom_glink_smem_unregister' drivers/remoteproc/qcom_common.o: In function `glink_subdev_probe': qcom_common.c:(.text+0x160): undefined reference to `qcom_glink_smem_register' qcom_common.c:(.text+0x160): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `qcom_glink_smem_register' Out of the three PIL driver instances, QCOM_ADSP_PIL already has a Kconfig dependency to prevent this from happening, but the other two do not. This adds the same dependency there. Fixes: eea07023e6d9 ("remoteproc: qcom: adsp: Allow defining GLINK edge") Signed-off-by: Arnd Bergmann Signed-off-by: Bjorn Andersson --- drivers/remoteproc/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index df63e44526ac..bf04479456a0 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -109,6 +109,7 @@ config QCOM_Q6V5_PIL depends on OF && ARCH_QCOM depends on QCOM_SMEM depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n) + depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n select MFD_SYSCON select QCOM_RPROC_COMMON select QCOM_SCM @@ -120,6 +121,7 @@ config QCOM_WCNSS_PIL tristate "Qualcomm WCNSS Peripheral Image Loader" depends on OF && ARCH_QCOM depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n) + depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n depends on QCOM_SMEM select QCOM_MDT_LOADER select QCOM_RPROC_COMMON -- cgit v1.2.3 From 365ff9df562889501964ab5ee9fb4ce700d1a8c0 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Mon, 9 Oct 2017 12:41:53 -0700 Subject: wimax/i2400m: Remove VLAIS Convert Variable Length Array in Struct (VLAIS) to valid C by converting local struct definition to use a flexible array. The structure is only used to define a cast of a buffer so the size of the struct is not used to allocate storage. Signed-off-by: Behan Webster Signed-off-by: Mark Charebois Suggested-by: Arnd Bergmann Signed-off-by: Matthias Kaehlcke Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index c9c711dcd0e6..a89b5685e68b 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -652,7 +652,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk, struct device *dev = i2400m_dev(i2400m); struct { struct i2400m_bootrom_header cmd; - u8 cmd_payload[chunk_len]; + u8 cmd_payload[]; } __packed *buf; struct i2400m_bootrom_header ack; -- cgit v1.2.3 From c3d64ad4fea66d07e878b248b803ccd12c45e18c Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 10 Oct 2017 09:16:22 -0700 Subject: nfp: fix ethtool stats gather retry The while loop fetching 64 bit ethtool statistics may have to retry multiple times, it shouldn't modify the outside state. Fixes: 4c3523623dc0 ("net: add driver for Netronome NFP4000/NFP6000 NIC VFs") Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index 07969f06df10..dc016dfec64d 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -464,7 +464,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) do { start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); - *data++ = nn->r_vecs[i].rx_pkts; + data[0] = nn->r_vecs[i].rx_pkts; tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; tmp[2] = nn->r_vecs[i].hw_csum_rx_error; @@ -472,14 +472,16 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) do { start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); - *data++ = nn->r_vecs[i].tx_pkts; - *data++ = nn->r_vecs[i].tx_busy; + data[1] = nn->r_vecs[i].tx_pkts; + data[2] = nn->r_vecs[i].tx_busy; tmp[3] = nn->r_vecs[i].hw_csum_tx; tmp[4] = nn->r_vecs[i].hw_csum_tx_inner; tmp[5] = nn->r_vecs[i].tx_gather; tmp[6] = nn->r_vecs[i].tx_lso; } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); + data += 3; + for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++) gathered_stats[j] += tmp[j]; } -- cgit v1.2.3 From 5f0ca2fb71e28df146f590eebfe32b41171b737f Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 10 Oct 2017 09:16:23 -0700 Subject: nfp: handle page allocation failures page_address() does not handle NULL argument gracefully, make sure we NULL-check the page pointer before passing it to page_address(). Fixes: ecd63a0217d5 ("nfp: add XDP support in the driver") Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 1c0187f0af51..e118b5f23996 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -1180,10 +1180,14 @@ static void *nfp_net_rx_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr) { void *frag; - if (!dp->xdp_prog) + if (!dp->xdp_prog) { frag = netdev_alloc_frag(dp->fl_bufsz); - else - frag = page_address(alloc_page(GFP_KERNEL | __GFP_COLD)); + } else { + struct page *page; + + page = alloc_page(GFP_KERNEL | __GFP_COLD); + frag = page ? page_address(page) : NULL; + } if (!frag) { nn_dp_warn(dp, "Failed to alloc receive page frag\n"); return NULL; @@ -1203,10 +1207,14 @@ static void *nfp_net_napi_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr) { void *frag; - if (!dp->xdp_prog) + if (!dp->xdp_prog) { frag = napi_alloc_frag(dp->fl_bufsz); - else - frag = page_address(alloc_page(GFP_ATOMIC | __GFP_COLD)); + } else { + struct page *page; + + page = alloc_page(GFP_ATOMIC | __GFP_COLD); + frag = page ? page_address(page) : NULL; + } if (!frag) { nn_dp_warn(dp, "Failed to alloc receive page frag\n"); return NULL; -- cgit v1.2.3 From 617dc7610d9f5f64ec79cfdbdd4fb42cfcd93ee9 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Tue, 10 Oct 2017 14:30:30 +0100 Subject: drm/i915/selftests: ditch the kernel context There's really no good reason to be using the kernel context for the huge-page livetests. Also with the introduction of commit bef27bdb6cfb ("drm/i915: Assert we do not try to expand VMA for hugepage inside GGTT") we start hitting the bug on in the selftests, since the kernel context will always return true for i915_vma_is_ggtt(), so now seems like the opportune time to instead create our own context. Fixes: 4049866f0913 ("drm/i915/selftests: huge page tests") Fixes: bef27bdb6cfb ("drm/i915: Assert we do not try to expand VMA for hugepage inside GGTT") Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010133030.12112-1-matthew.auld@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/selftests/huge_pages.c | 57 +++++++++++++++++++---------- 1 file changed, 38 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c index b8b9d0822199..c53f8474113a 100644 --- a/drivers/gpu/drm/i915/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c @@ -1047,10 +1047,10 @@ static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val) return err; } -static int igt_write_huge(struct drm_i915_gem_object *obj) +static int igt_write_huge(struct i915_gem_context *ctx, + struct drm_i915_gem_object *obj) { struct drm_i915_private *i915 = to_i915(obj->base.dev); - struct i915_gem_context *ctx = i915->kernel_context; struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base; struct intel_engine_cs *engine; struct i915_vma *vma; @@ -1149,7 +1149,8 @@ out_vma_close: static int igt_ppgtt_exhaust_huge(void *arg) { - struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx = arg; + struct drm_i915_private *i915 = ctx->i915; unsigned long supported = INTEL_INFO(i915)->page_sizes; static unsigned int pages[ARRAY_SIZE(page_sizes)]; struct drm_i915_gem_object *obj; @@ -1220,7 +1221,7 @@ static int igt_ppgtt_exhaust_huge(void *arg) /* Force the page-size for the gtt insertion */ obj->mm.page_sizes.sg = page_sizes; - err = igt_write_huge(obj); + err = igt_write_huge(ctx, obj); if (err) { pr_err("exhaust write-huge failed with size=%u\n", size); @@ -1245,7 +1246,8 @@ out_device: static int igt_ppgtt_internal_huge(void *arg) { - struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx = arg; + struct drm_i915_private *i915 = ctx->i915; struct drm_i915_gem_object *obj; static const unsigned int sizes[] = { SZ_64K, @@ -1280,7 +1282,7 @@ static int igt_ppgtt_internal_huge(void *arg) goto out_unpin; } - err = igt_write_huge(obj); + err = igt_write_huge(ctx, obj); if (err) { pr_err("internal write-huge failed with size=%u\n", size); @@ -1308,7 +1310,8 @@ static inline bool igt_can_allocate_thp(struct drm_i915_private *i915) static int igt_ppgtt_gemfs_huge(void *arg) { - struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx = arg; + struct drm_i915_private *i915 = ctx->i915; struct drm_i915_gem_object *obj; static const unsigned int sizes[] = { SZ_2M, @@ -1347,7 +1350,7 @@ static int igt_ppgtt_gemfs_huge(void *arg) goto out_unpin; } - err = igt_write_huge(obj); + err = igt_write_huge(ctx, obj); if (err) { pr_err("gemfs write-huge failed with size=%u\n", size); @@ -1370,9 +1373,10 @@ out_put: static int igt_ppgtt_pin_update(void *arg) { - struct drm_i915_private *dev_priv = arg; + struct i915_gem_context *ctx = arg; + struct drm_i915_private *dev_priv = ctx->i915; unsigned long supported = INTEL_INFO(dev_priv)->page_sizes; - struct i915_hw_ppgtt *ppgtt = dev_priv->kernel_context->ppgtt; + struct i915_hw_ppgtt *ppgtt = ctx->ppgtt; struct drm_i915_gem_object *obj; struct i915_vma *vma; unsigned int flags = PIN_USER | PIN_OFFSET_FIXED; @@ -1473,8 +1477,7 @@ static int igt_ppgtt_pin_update(void *arg) * land in the now stale 2M page. */ - err = gpu_write(vma, dev_priv->kernel_context, dev_priv->engine[RCS], - 0, 0xdeadbeaf); + err = gpu_write(vma, ctx, dev_priv->engine[RCS], 0, 0xdeadbeaf); if (err) goto out_unpin; @@ -1492,9 +1495,9 @@ out_put: static int igt_tmpfs_fallback(void *arg) { - struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx = arg; + struct drm_i915_private *i915 = ctx->i915; struct vfsmount *gemfs = i915->mm.gemfs; - struct i915_gem_context *ctx = i915->kernel_context; struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base; struct drm_i915_gem_object *obj; struct i915_vma *vma; @@ -1549,8 +1552,8 @@ out_restore: static int igt_shrink_thp(void *arg) { - struct drm_i915_private *i915 = arg; - struct i915_gem_context *ctx = i915->kernel_context; + struct i915_gem_context *ctx = arg; + struct drm_i915_private *i915 = ctx->i915; struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base; struct drm_i915_gem_object *obj; struct i915_vma *vma; @@ -1590,8 +1593,7 @@ static int igt_shrink_thp(void *arg) if (err) goto out_unpin; - err = gpu_write(vma, i915->kernel_context, i915->engine[RCS], 0, - 0xdeadbeaf); + err = gpu_write(vma, ctx, i915->engine[RCS], 0, 0xdeadbeaf); if (err) goto out_unpin; @@ -1700,6 +1702,8 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv) SUBTEST(igt_ppgtt_gemfs_huge), SUBTEST(igt_ppgtt_internal_huge), }; + struct drm_file *file; + struct i915_gem_context *ctx; int err; if (!USES_PPGTT(dev_priv)) { @@ -1707,9 +1711,24 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv) return 0; } + file = mock_file(dev_priv); + if (IS_ERR(file)) + return PTR_ERR(file); + mutex_lock(&dev_priv->drm.struct_mutex); - err = i915_subtests(tests, dev_priv); + + ctx = live_context(dev_priv, file); + if (IS_ERR(ctx)) { + err = PTR_ERR(ctx); + goto out_unlock; + } + + err = i915_subtests(tests, ctx); + +out_unlock: mutex_unlock(&dev_priv->drm.struct_mutex); + mock_file_free(dev_priv, file); + return err; } -- cgit v1.2.3 From 8c2b4e3c3725801b57d7b858d216d38f83bdb35d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 9 Oct 2017 12:29:35 +0200 Subject: Revert "PCI: tegra: Do not allocate MSI target memory" This reverts commit d7bd554f27c942e6b8b54100b4044f9be1038edf. It turns out that Tegra20 has a bug in the implementation of the MSI target address register (which is worked around by the existence of the struct tegra_pcie_soc.msi_base_shift parameter) that restricts the MSI target memory to the lower 32 bits of physical memory on that particular generation. The offending patch causes a regression on TrimSlice, which is a Tegra20-based device and has a PCI network interface card. An initial, simpler fix was to change the MSI target address for Tegra20 only, but it was pointed out that the offending commit also prevents the use of 32-bit only MSI capable devices, even on later chips. Technically this was never guaranteed to work with the prior code in the first place because the allocated page could have resided beyond the 4 GiB boundary, but it is still possible that this could've introduced a regression. The proper fix that was settled on is to select a fixed address within the lowest 32 bits of physical address space that is otherwise unused, but testing of that patch has provided mixed results that are not fully understood yet. Given all of the above and the relative urgency to get this fixed in v4.13, revert the offending commit until a universal fix is found. Fixes: d7bd554f27c9 ("PCI: tegra: Do not allocate MSI target memory") Reported-by: Tomasz Maciej Nowak Reported-by: Erik Faye-Lund Signed-off-by: Thierry Reding Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # 4.13.x --- drivers/pci/host/pci-tegra.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 9c40da54f88a..1987fec1f126 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -233,6 +233,7 @@ struct tegra_msi { struct msi_controller chip; DECLARE_BITMAP(used, INT_PCI_MSI_NR); struct irq_domain *domain; + unsigned long pages; struct mutex lock; u64 phys; int irq; @@ -1529,22 +1530,9 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) goto err; } - /* - * The PCI host bridge on Tegra contains some logic that intercepts - * MSI writes, which means that the MSI target address doesn't have - * to point to actual physical memory. Rather than allocating one 4 - * KiB page of system memory that's never used, we can simply pick - * an arbitrary address within an area reserved for system memory - * in the FPCI address map. - * - * However, in order to avoid confusion, we pick an address that - * doesn't map to physical memory. The FPCI address map reserves a - * 1012 GiB region for system memory and memory-mapped I/O. Since - * none of the Tegra SoCs that contain this PCI host bridge can - * address more than 16 GiB of system memory, the last 4 KiB of - * these 1012 GiB is a good candidate. - */ - msi->phys = 0xfcfffff000; + /* setup AFI/FPCI range */ + msi->pages = __get_free_pages(GFP_KERNEL, 0); + msi->phys = virt_to_phys((void *)msi->pages); afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST); @@ -1596,6 +1584,8 @@ static int tegra_pcie_disable_msi(struct tegra_pcie *pcie) afi_writel(pcie, 0, AFI_MSI_EN_VEC6); afi_writel(pcie, 0, AFI_MSI_EN_VEC7); + free_pages(msi->pages, 0); + if (msi->irq > 0) free_irq(msi->irq, pcie); -- cgit v1.2.3 From 407dae1e4415acde2d9f48bb76361893c4653756 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 9 Oct 2017 09:00:49 +0200 Subject: PCI: aardvark: Move to struct pci_host_bridge IRQ mapping functions struct pci_host_bridge gained hooks to map/swizzle IRQs, so that the IRQ mapping can be done automatically by PCI core code through the pci_assign_irq() function instead of resorting to arch-specific implementation callbacks to carry out the same task which force PCI host bridge drivers implementation to implement per-arch kludges to carry out a task that is inherently architecture agnostic. Commit 769b461fc0c0 ("arm64: PCI: Drop DT IRQ allocation from pcibios_alloc_irq()") was assuming all PCI host controller drivers had been converted to use ->map_irq(), but that wasn't the case: pci-aardvark had not been converted. Due to this, it broke the support for legacy PCI interrupts when using the pci-aardvark driver (used on Marvell Armada 3720 platforms). In order to fix this, we make sure the ->map_irq and ->swizzle_irq fields of pci_host_bridge are properly filled in. Fixes: 769b461fc0c0 ("arm64: PCI: Drop DT IRQ allocation from pcibios_alloc_irq()") Signed-off-by: Thomas Petazzoni Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v4.13+ --- drivers/pci/host/pci-aardvark.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index 89f4e3d072d7..26ed0c08f209 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -935,6 +935,8 @@ static int advk_pcie_probe(struct platform_device *pdev) bridge->sysdata = pcie; bridge->busnr = 0; bridge->ops = &advk_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle; ret = pci_scan_root_bus_bridge(bridge); if (ret < 0) { -- cgit v1.2.3 From 960e54652ceed1c0f49969c5d951688eab1d49cb Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:29:59 +0100 Subject: drm/i915: Separate RPS and RC6 handling for gen6+ This patch separates enable/disable of RC6 and RPS for gen6+ platforms prior to VLV. v2: Fixed checkpatch issue. (Sagar) Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Radoslaw Szwichtenberg #1 Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-2-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 17 +++++++-------- drivers/gpu/drm/i915/intel_pm.c | 43 +++++++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5b58d2b897c7..a904f4e69c66 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1190,6 +1190,13 @@ static int i915_frequency_info(struct seq_file *m, void *unused) pm_iir = I915_READ(GEN8_GT_IIR(2)); pm_mask = I915_READ(GEN6_PMINTRMSK); } + seq_printf(m, "Video Turbo Mode: %s\n", + yesno(rpmodectl & GEN6_RP_MEDIA_TURBO)); + seq_printf(m, "HW control enabled: %s\n", + yesno(rpmodectl & GEN6_RP_ENABLE)); + seq_printf(m, "SW control enabled: %s\n", + yesno((rpmodectl & GEN6_RP_MEDIA_MODE_MASK) == + GEN6_RP_MEDIA_SW_MODE)); seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n", pm_ier, pm_imr, pm_isr, pm_iir, pm_mask); seq_printf(m, "pm_intrmsk_mbz: 0x%08x\n", @@ -1533,7 +1540,7 @@ static int vlv_drpc_info(struct seq_file *m) static int gen6_drpc_info(struct seq_file *m) { struct drm_i915_private *dev_priv = node_to_i915(m->private); - u32 rpmodectl1, gt_core_status, rcctl1, rc6vids = 0; + u32 gt_core_status, rcctl1, rc6vids = 0; u32 gen9_powergate_enable = 0, gen9_powergate_status = 0; unsigned forcewake_count; int count = 0; @@ -1552,7 +1559,6 @@ static int gen6_drpc_info(struct seq_file *m) gt_core_status = I915_READ_FW(GEN6_GT_CORE_STATUS); trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4, true); - rpmodectl1 = I915_READ(GEN6_RP_CONTROL); rcctl1 = I915_READ(GEN6_RC_CONTROL); if (INTEL_GEN(dev_priv) >= 9) { gen9_powergate_enable = I915_READ(GEN9_PG_ENABLE); @@ -1563,13 +1569,6 @@ static int gen6_drpc_info(struct seq_file *m) sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); mutex_unlock(&dev_priv->rps.hw_lock); - seq_printf(m, "Video Turbo Mode: %s\n", - yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO)); - seq_printf(m, "HW control enabled: %s\n", - yesno(rpmodectl1 & GEN6_RP_ENABLE)); - seq_printf(m, "SW control enabled: %s\n", - yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == - GEN6_RP_MEDIA_SW_MODE)); seq_printf(m, "RC1e Enabled: %s\n", yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); seq_printf(m, "RC6 Enabled: %s\n", diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 39acfadb5a21..dfa9afe9cb61 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6334,9 +6334,13 @@ static void gen9_disable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RP_CONTROL, 0); } -static void gen6_disable_rps(struct drm_i915_private *dev_priv) +static void gen6_disable_rc6(struct drm_i915_private *dev_priv) { I915_WRITE(GEN6_RC_CONTROL, 0); +} + +static void gen6_disable_rps(struct drm_i915_private *dev_priv) +{ I915_WRITE(GEN6_RPNSWREQ, 1 << 31); I915_WRITE(GEN6_RP_CONTROL, 0); } @@ -6694,7 +6698,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); } -static void gen6_enable_rps(struct drm_i915_private *dev_priv) +static void gen6_enable_rc6(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; enum intel_engine_id id; @@ -6705,12 +6709,6 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv) WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); - /* Here begins a magic sequence of register writes to enable - * auto-downclocking. - * - * Perhaps there might be some value in exposing these to - * userspace... - */ I915_WRITE(GEN6_RC_STATE, 0); /* Clear the DBG now so we don't confuse earlier errors */ @@ -6764,12 +6762,6 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv) GEN6_RC_CTL_EI_MODE(1) | GEN6_RC_CTL_HW_ENABLE); - /* Power down if completely idle for over 50ms */ - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000); - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - - reset_rps(dev_priv, gen6_set_rps); - rc6vids = 0; ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); if (IS_GEN6(dev_priv) && ret) { @@ -6787,6 +6779,27 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); } +static void gen6_enable_rps(struct drm_i915_private *dev_priv) +{ + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + /* Here begins a magic sequence of register writes to enable + * auto-downclocking. + * + * Perhaps there might be some value in exposing these to + * userspace... + */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + /* Power down if completely idle for over 50ms */ + I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000); + I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); + + reset_rps(dev_priv, gen6_set_rps); + + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); +} + static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) { int min_freq = 15; @@ -7936,6 +7949,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) } else if (IS_VALLEYVIEW(dev_priv)) { valleyview_disable_rps(dev_priv); } else if (INTEL_GEN(dev_priv) >= 6) { + gen6_disable_rc6(dev_priv); gen6_disable_rps(dev_priv); } else if (IS_IRONLAKE_M(dev_priv)) { ironlake_disable_drps(dev_priv); @@ -7972,6 +7986,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) gen8_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } else if (INTEL_GEN(dev_priv) >= 6) { + gen6_enable_rc6(dev_priv); gen6_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } else if (IS_IRONLAKE_M(dev_priv)) { -- cgit v1.2.3 From 415544d5a89fb2be3b12dc7c4682806323aabdbf Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:00 +0100 Subject: drm/i915: Remove superfluous IS_BDW checks and non-BDW changes from gen8_enable_rps This patch removes all IS_BROADWELL checks and non-BDW changes from gen8_enable_rps as it is called only for BROADWELL. Suggested-by: Chris Wilson Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-3-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index dfa9afe9cb61..21a72f660e0f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6644,23 +6644,16 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv) for_each_engine(engine, dev_priv, id) I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); I915_WRITE(GEN6_RC_SLEEP, 0); - if (IS_BROADWELL(dev_priv)) - I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */ - else - I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */ + I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */ /* 3: Enable RC6 */ if (intel_enable_rc6() & INTEL_RC6_ENABLE) rc6_mask = GEN6_RC_CTL_RC6_ENABLE; intel_print_rc6_info(dev_priv, rc6_mask); - if (IS_BROADWELL(dev_priv)) - I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | - GEN7_RC_CTL_TO_MODE | - rc6_mask); - else - I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | - GEN6_RC_CTL_EI_MODE(1) | - rc6_mask); + + I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | + GEN7_RC_CTL_TO_MODE | + rc6_mask); /* 4 Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RPNSWREQ, -- cgit v1.2.3 From 3a85392c0ea0689d8d3ba1f9c9df5d3e32bfa517 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:01 +0100 Subject: drm/i915: Separate RPS and RC6 handling for BDW This patch separates RC6 and RPS enabling for BDW. RC6/RPS Disabling are handled through gen6 functions. PM Programming guide recommends a sequence within forcewakes to configure RC6, RPS and ring frequencies in sequence. With this patch the order is still maintained. v2: Update sequence numbers in RC6 programming and comment about intent of reset_rps during gen8_enable_rps. (Radoslaw) v3: Rebase. Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-4-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 21a72f660e0f..540e23ab51df 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6621,7 +6621,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); } -static void gen8_enable_rps(struct drm_i915_private *dev_priv) +static void gen8_enable_rc6(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; enum intel_engine_id id; @@ -6630,7 +6630,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv) /* 1a: Software RC state - RC0 */ I915_WRITE(GEN6_RC_STATE, 0); - /* 1c & 1d: Get forcewake during program sequence. Although the driver + /* 1b: Get forcewake during program sequence. Although the driver * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); @@ -6655,7 +6655,14 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv) GEN7_RC_CTL_TO_MODE | rc6_mask); - /* 4 Program defaults and thresholds for RPS*/ + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); +} + +static void gen8_enable_rps(struct drm_i915_private *dev_priv) +{ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + /* 1 Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RPNSWREQ, HSW_FREQUENCY(dev_priv->rps.rp1_freq)); I915_WRITE(GEN6_RC_VIDEO_FREQ, @@ -6675,7 +6682,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - /* 5: Enable RPS */ + /* 2: Enable RPS */ I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_TURBO | GEN6_RP_MEDIA_HW_NORMAL_MODE | @@ -6684,8 +6691,6 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv) GEN6_RP_UP_BUSY_AVG | GEN6_RP_DOWN_IDLE_AVG); - /* 6: Ring frequency + overclocking (our driver does this later */ - reset_rps(dev_priv, gen6_set_rps); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); @@ -7976,6 +7981,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) gen6_update_ring_freq(dev_priv); } else if (IS_BROADWELL(dev_priv)) { + gen8_enable_rc6(dev_priv); gen8_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } else if (INTEL_GEN(dev_priv) >= 6) { -- cgit v1.2.3 From 0d6fc92a73e0c4dd8635268ef0ffb852986bba89 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:02 +0100 Subject: drm/i915: Separate RPS and RC6 handling for VLV This patch separates enable/disable of RC6 and RPS for VLV. v2: Removed unnecessary comments about forcewakes while enabling RC6/RPS. Added changes to output turbo control status for VLV in i915_frequency_info. Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-5-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 24 +++++++-------- drivers/gpu/drm/i915/intel_pm.c | 61 ++++++++++++++++++++++++------------- 2 files changed, 51 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a904f4e69c66..31ab92eda45d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1095,9 +1095,19 @@ static int i915_frequency_info(struct seq_file *m, void *unused) seq_printf(m, "Current P-state: %d\n", (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - u32 freq_sts; + u32 rpmodectl, freq_sts; mutex_lock(&dev_priv->rps.hw_lock); + + rpmodectl = I915_READ(GEN6_RP_CONTROL); + seq_printf(m, "Video Turbo Mode: %s\n", + yesno(rpmodectl & GEN6_RP_MEDIA_TURBO)); + seq_printf(m, "HW control enabled: %s\n", + yesno(rpmodectl & GEN6_RP_ENABLE)); + seq_printf(m, "SW control enabled: %s\n", + yesno((rpmodectl & GEN6_RP_MEDIA_MODE_MASK) == + GEN6_RP_MEDIA_SW_MODE)); + freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts); seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq); @@ -1508,21 +1518,11 @@ static void print_rc6_res(struct seq_file *m, static int vlv_drpc_info(struct seq_file *m) { struct drm_i915_private *dev_priv = node_to_i915(m->private); - u32 rpmodectl1, rcctl1, pw_status; + u32 rcctl1, pw_status; pw_status = I915_READ(VLV_GTLC_PW_STATUS); - rpmodectl1 = I915_READ(GEN6_RP_CONTROL); rcctl1 = I915_READ(GEN6_RC_CONTROL); - seq_printf(m, "Video Turbo Mode: %s\n", - yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO)); - seq_printf(m, "Turbo enabled: %s\n", - yesno(rpmodectl1 & GEN6_RP_ENABLE)); - seq_printf(m, "HW control enabled: %s\n", - yesno(rpmodectl1 & GEN6_RP_ENABLE)); - seq_printf(m, "SW control enabled: %s\n", - yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == - GEN6_RP_MEDIA_SW_MODE)); seq_printf(m, "RC6 Enabled: %s\n", yesno(rcctl1 & (GEN7_RC_CTL_TO_MODE | GEN6_RC_CTL_EI_MODE(1)))); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 540e23ab51df..5fb08271b91c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6350,9 +6350,9 @@ static void cherryview_disable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC_CONTROL, 0); } -static void valleyview_disable_rps(struct drm_i915_private *dev_priv) +static void valleyview_disable_rc6(struct drm_i915_private *dev_priv) { - /* we're doing forcewake before Disabling RC6, + /* We're doing forcewake before Disabling RC6, * This what the BIOS expects when going into suspend */ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); @@ -6361,6 +6361,11 @@ static void valleyview_disable_rps(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); } +static void valleyview_disable_rps(struct drm_i915_private *dev_priv) +{ + I915_WRITE(GEN6_RP_CONTROL, 0); +} + static void intel_print_rc6_info(struct drm_i915_private *dev_priv, u32 mode) { if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { @@ -7283,11 +7288,11 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); } -static void valleyview_enable_rps(struct drm_i915_private *dev_priv) +static void valleyview_enable_rc6(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; enum intel_engine_id id; - u32 gtfifodbg, val, rc6_mode = 0; + u32 gtfifodbg, rc6_mode = 0; WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); @@ -7300,28 +7305,11 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GTFIFODBG, gtfifodbg); } - /* If VLV, Forcewake all wells, else re-direct to regular path */ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); /* Disable RC states. */ I915_WRITE(GEN6_RC_CONTROL, 0); - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); - I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); - I915_WRITE(GEN6_RP_UP_EI, 66000); - I915_WRITE(GEN6_RP_DOWN_EI, 350000); - - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - - I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_ENABLE | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_CONT); - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); @@ -7331,7 +7319,7 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC6_THRESHOLD, 0x557); - /* allows RC6 residency counter to work */ + /* Allows RC6 residency counter to work */ I915_WRITE(VLV_COUNTER_CONTROL, _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH | VLV_MEDIA_RC0_COUNT_EN | @@ -7346,6 +7334,33 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC_CONTROL, rc6_mode); + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); +} + +static void valleyview_enable_rps(struct drm_i915_private *dev_priv) +{ + u32 val; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); + I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); + I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); + I915_WRITE(GEN6_RP_UP_EI, 66000); + I915_WRITE(GEN6_RP_DOWN_EI, 350000); + + I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); + + I915_WRITE(GEN6_RP_CONTROL, + GEN6_RP_MEDIA_TURBO | + GEN6_RP_MEDIA_HW_NORMAL_MODE | + GEN6_RP_MEDIA_IS_GFX | + GEN6_RP_ENABLE | + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_CONT); + /* Setting Fixed Bias */ val = VLV_OVERRIDE_EN | VLV_SOC_TDP_EN | @@ -7945,6 +7960,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) } else if (IS_CHERRYVIEW(dev_priv)) { cherryview_disable_rps(dev_priv); } else if (IS_VALLEYVIEW(dev_priv)) { + valleyview_disable_rc6(dev_priv); valleyview_disable_rps(dev_priv); } else if (INTEL_GEN(dev_priv) >= 6) { gen6_disable_rc6(dev_priv); @@ -7974,6 +7990,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) if (IS_CHERRYVIEW(dev_priv)) { cherryview_enable_rps(dev_priv); } else if (IS_VALLEYVIEW(dev_priv)) { + valleyview_enable_rc6(dev_priv); valleyview_enable_rps(dev_priv); } else if (INTEL_GEN(dev_priv) >= 9) { gen9_enable_rc6(dev_priv); -- cgit v1.2.3 From d46b00dc38c8aea80357a0dd04f57c097dbfa5b9 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:03 +0100 Subject: drm/i915: Separate RPS and RC6 handling for CHV This patch separates enable/disable of RC6 and RPS for CHV. v2: Fixed comment. Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-6-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-5-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5fb08271b91c..4843e88a7f35 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6345,11 +6345,16 @@ static void gen6_disable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RP_CONTROL, 0); } -static void cherryview_disable_rps(struct drm_i915_private *dev_priv) +static void cherryview_disable_rc6(struct drm_i915_private *dev_priv) { I915_WRITE(GEN6_RC_CONTROL, 0); } +static void cherryview_disable_rps(struct drm_i915_private *dev_priv) +{ + I915_WRITE(GEN6_RP_CONTROL, 0); +} + static void valleyview_disable_rc6(struct drm_i915_private *dev_priv) { /* We're doing forcewake before Disabling RC6, @@ -7199,11 +7204,11 @@ static void valleyview_cleanup_gt_powersave(struct drm_i915_private *dev_priv) valleyview_cleanup_pctx(dev_priv); } -static void cherryview_enable_rps(struct drm_i915_private *dev_priv) +static void cherryview_enable_rc6(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; enum intel_engine_id id; - u32 gtfifodbg, val, rc6_mode = 0, pcbr; + u32 gtfifodbg, rc6_mode = 0, pcbr; WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); @@ -7236,7 +7241,7 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv) /* TO threshold set to 500 us ( 0x186 * 1.28 us) */ I915_WRITE(GEN6_RC6_THRESHOLD, 0x186); - /* allows RC6 residency counter to work */ + /* Allows RC6 residency counter to work */ I915_WRITE(VLV_COUNTER_CONTROL, _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH | VLV_MEDIA_RC6_COUNT_EN | @@ -7252,7 +7257,18 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC_CONTROL, rc6_mode); - /* 4 Program defaults and thresholds for RPS*/ + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); +} + +static void cherryview_enable_rps(struct drm_i915_private *dev_priv) +{ + u32 val; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + /* 1: Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); @@ -7261,7 +7277,7 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - /* 5: Enable RPS */ + /* 2: Enable RPS */ I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_HW_NORMAL_MODE | GEN6_RP_MEDIA_IS_GFX | @@ -7958,6 +7974,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) gen9_disable_rc6(dev_priv); gen9_disable_rps(dev_priv); } else if (IS_CHERRYVIEW(dev_priv)) { + cherryview_disable_rc6(dev_priv); cherryview_disable_rps(dev_priv); } else if (IS_VALLEYVIEW(dev_priv)) { valleyview_disable_rc6(dev_priv); @@ -7988,6 +8005,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) mutex_lock(&dev_priv->rps.hw_lock); if (IS_CHERRYVIEW(dev_priv)) { + cherryview_enable_rc6(dev_priv); cherryview_enable_rps(dev_priv); } else if (IS_VALLEYVIEW(dev_priv)) { valleyview_enable_rc6(dev_priv); -- cgit v1.2.3 From ad1443f0f3dd1b2434af897af8b8f942e47cf8c3 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:04 +0100 Subject: drm/i915: Name i915_runtime_pm structure in dev_priv as "runtime_pm" We were using dev_priv->pm for runtime power management related state. This patch renames it to "runtime_pm" which looks more apt. v2: s/rpm/runtime_pm (Chris) Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Radoslaw Szwichtenberg #1 Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-7-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-6-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 8 ++++---- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gpu_error.c | 4 ++-- drivers/gpu/drm/i915/i915_irq.c | 8 ++++---- drivers/gpu/drm/i915/intel_drv.h | 10 +++++----- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- drivers/gpu/drm/i915/intel_runtime_pm.c | 10 +++++----- 7 files changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 66fc156b294a..9ebbb08dcf2d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2544,12 +2544,12 @@ static int intel_runtime_suspend(struct device *kdev) intel_uncore_suspend(dev_priv); enable_rpm_wakeref_asserts(dev_priv); - WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count)); + WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count)); if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv)) DRM_ERROR("Unclaimed access detected prior to suspending\n"); - dev_priv->pm.suspended = true; + dev_priv->runtime_pm.suspended = true; /* * FIXME: We really should find a document that references the arguments @@ -2595,11 +2595,11 @@ static int intel_runtime_resume(struct device *kdev) DRM_DEBUG_KMS("Resuming device\n"); - WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count)); + WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count)); disable_rpm_wakeref_asserts(dev_priv); intel_opregion_notify_adapter(dev_priv, PCI_D0); - dev_priv->pm.suspended = false; + dev_priv->runtime_pm.suspended = false; if (intel_uncore_unclaimed_mmio(dev_priv)) DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n"); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 770305bdeabb..f44027f6e5e1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2533,7 +2533,7 @@ struct drm_i915_private { bool distrust_bios_wm; } wm; - struct i915_runtime_pm pm; + struct i915_runtime_pm runtime_pm; struct { bool initialized; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index dc91b32d699e..653fb69e7ecb 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1674,8 +1674,8 @@ static void i915_capture_gen_state(struct drm_i915_private *dev_priv, struct i915_gpu_state *error) { error->awake = dev_priv->gt.awake; - error->wakelock = atomic_read(&dev_priv->pm.wakeref_count); - error->suspended = dev_priv->pm.suspended; + error->wakelock = atomic_read(&dev_priv->runtime_pm.wakeref_count); + error->suspended = dev_priv->runtime_pm.suspended; error->iommu = -1; #ifdef CONFIG_INTEL_IOMMU diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3736290f2d0c..915c5b9dc547 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4173,7 +4173,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv) * interrupts as enabled _before_ actually enabling them to avoid * special cases in our ordering checks. */ - dev_priv->pm.irqs_enabled = true; + dev_priv->runtime_pm.irqs_enabled = true; return drm_irq_install(&dev_priv->drm, dev_priv->drm.pdev->irq); } @@ -4189,7 +4189,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) { drm_irq_uninstall(&dev_priv->drm); intel_hpd_cancel_work(dev_priv); - dev_priv->pm.irqs_enabled = false; + dev_priv->runtime_pm.irqs_enabled = false; } /** @@ -4202,7 +4202,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) { dev_priv->drm.driver->irq_uninstall(&dev_priv->drm); - dev_priv->pm.irqs_enabled = false; + dev_priv->runtime_pm.irqs_enabled = false; synchronize_irq(dev_priv->drm.irq); } @@ -4215,7 +4215,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) */ void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv) { - dev_priv->pm.irqs_enabled = true; + dev_priv->runtime_pm.irqs_enabled = true; dev_priv->drm.driver->irq_preinstall(&dev_priv->drm); dev_priv->drm.driver->irq_postinstall(&dev_priv->drm); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ceb3b8284c86..3fd428b99c37 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1254,7 +1254,7 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) * We only use drm_irq_uninstall() at unload and VT switch, so * this is the only thing we need to check. */ - return dev_priv->pm.irqs_enabled; + return dev_priv->runtime_pm.irqs_enabled; } int intel_get_crtc_scanline(struct intel_crtc *crtc); @@ -1790,7 +1790,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, static inline void assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv) { - WARN_ONCE(dev_priv->pm.suspended, + WARN_ONCE(dev_priv->runtime_pm.suspended, "Device suspended during HW access\n"); } @@ -1798,7 +1798,7 @@ static inline void assert_rpm_wakelock_held(struct drm_i915_private *dev_priv) { assert_rpm_device_not_suspended(dev_priv); - WARN_ONCE(!atomic_read(&dev_priv->pm.wakeref_count), + WARN_ONCE(!atomic_read(&dev_priv->runtime_pm.wakeref_count), "RPM wakelock ref not held during HW access"); } @@ -1823,7 +1823,7 @@ assert_rpm_wakelock_held(struct drm_i915_private *dev_priv) static inline void disable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv) { - atomic_inc(&dev_priv->pm.wakeref_count); + atomic_inc(&dev_priv->runtime_pm.wakeref_count); } /** @@ -1840,7 +1840,7 @@ disable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv) static inline void enable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv) { - atomic_dec(&dev_priv->pm.wakeref_count); + atomic_dec(&dev_priv->runtime_pm.wakeref_count); } void intel_runtime_pm_get(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4843e88a7f35..831054084fb7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -9350,8 +9350,8 @@ void intel_pm_setup(struct drm_i915_private *dev_priv) __intel_autoenable_gt_powersave); atomic_set(&dev_priv->rps.num_waiters, 0); - dev_priv->pm.suspended = false; - atomic_set(&dev_priv->pm.wakeref_count, 0); + dev_priv->runtime_pm.suspended = false; + atomic_set(&dev_priv->runtime_pm.wakeref_count, 0); } static u64 vlv_residency_raw(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index c4e1aba83c3e..7348c16c4a96 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -187,7 +187,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, struct i915_power_well *power_well; bool is_enabled; - if (dev_priv->pm.suspended) + if (dev_priv->runtime_pm.suspended) return false; is_enabled = true; @@ -3128,7 +3128,7 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv) ret = pm_runtime_get_sync(kdev); WARN_ONCE(ret < 0, "pm_runtime_get_sync() failed: %d\n", ret); - atomic_inc(&dev_priv->pm.wakeref_count); + atomic_inc(&dev_priv->runtime_pm.wakeref_count); assert_rpm_wakelock_held(dev_priv); } @@ -3162,7 +3162,7 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv) return false; } - atomic_inc(&dev_priv->pm.wakeref_count); + atomic_inc(&dev_priv->runtime_pm.wakeref_count); assert_rpm_wakelock_held(dev_priv); return true; @@ -3193,7 +3193,7 @@ void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) assert_rpm_wakelock_held(dev_priv); pm_runtime_get_noresume(kdev); - atomic_inc(&dev_priv->pm.wakeref_count); + atomic_inc(&dev_priv->runtime_pm.wakeref_count); } /** @@ -3210,7 +3210,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) struct device *kdev = &pdev->dev; assert_rpm_wakelock_held(dev_priv); - atomic_dec(&dev_priv->pm.wakeref_count); + atomic_dec(&dev_priv->runtime_pm.wakeref_count); pm_runtime_mark_last_busy(kdev); pm_runtime_put_autosuspend(kdev); -- cgit v1.2.3 From 9f817501bd7facfe2bffacd637f4332e5991e57a Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:05 +0100 Subject: drm/i915: Move rps.hw_lock to dev_priv and s/hw_lock/pcu_lock In order to separate GT PM related functionality into new structure we are updating rps structure. hw_lock in it is used for display related PCU communication too hence move it to dev_priv. Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-8-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-7-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 24 +++++------ drivers/gpu/drm/i915/i915_drv.h | 16 ++++---- drivers/gpu/drm/i915/i915_irq.c | 4 +- drivers/gpu/drm/i915/i915_sysfs.c | 20 ++++----- drivers/gpu/drm/i915/intel_cdclk.c | 40 +++++++++--------- drivers/gpu/drm/i915/intel_display.c | 12 +++--- drivers/gpu/drm/i915/intel_pm.c | 72 ++++++++++++++++----------------- drivers/gpu/drm/i915/intel_runtime_pm.c | 16 ++++---- drivers/gpu/drm/i915/intel_sideband.c | 6 +-- 9 files changed, 105 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 31ab92eda45d..e733097fa647 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1097,7 +1097,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { u32 rpmodectl, freq_sts; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); rpmodectl = I915_READ(GEN6_RP_CONTROL); seq_printf(m, "Video Turbo Mode: %s\n", @@ -1130,7 +1130,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) seq_printf(m, "efficient (RPe) frequency: %d MHz\n", intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq)); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } else if (INTEL_GEN(dev_priv) >= 6) { u32 rp_state_limits; u32 gt_perf_status; @@ -1565,9 +1565,9 @@ static int gen6_drpc_info(struct seq_file *m) gen9_powergate_status = I915_READ(GEN9_PWRGT_DOMAIN_STATUS); } - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); seq_printf(m, "RC1e Enabled: %s\n", yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); @@ -1842,7 +1842,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); - ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); + ret = mutex_lock_interruptible(&dev_priv->pcu_lock); if (ret) goto out; @@ -1873,7 +1873,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) ((ia_freq >> 8) & 0xff) * 100); } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); out: intel_runtime_pm_put(dev_priv); @@ -4320,7 +4320,7 @@ i915_max_freq_set(void *data, u64 val) DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val); - ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); + ret = mutex_lock_interruptible(&dev_priv->pcu_lock); if (ret) return ret; @@ -4333,7 +4333,7 @@ i915_max_freq_set(void *data, u64 val) hw_min = dev_priv->rps.min_freq; if (val < hw_min || val > hw_max || val < dev_priv->rps.min_freq_softlimit) { - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); return -EINVAL; } @@ -4342,7 +4342,7 @@ i915_max_freq_set(void *data, u64 val) if (intel_set_rps(dev_priv, val)) DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n"); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); return 0; } @@ -4375,7 +4375,7 @@ i915_min_freq_set(void *data, u64 val) DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val); - ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); + ret = mutex_lock_interruptible(&dev_priv->pcu_lock); if (ret) return ret; @@ -4389,7 +4389,7 @@ i915_min_freq_set(void *data, u64 val) if (val < hw_min || val > hw_max || val > dev_priv->rps.max_freq_softlimit) { - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); return -EINVAL; } @@ -4398,7 +4398,7 @@ i915_min_freq_set(void *data, u64 val) if (intel_set_rps(dev_priv, val)) DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n"); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f44027f6e5e1..fca7b939495f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1364,14 +1364,6 @@ struct intel_gen6_power_mgmt { /* manual wa residency calculations */ struct intel_rps_ei ei; - - /* - * Protects RPS/RC6 register access and PCU communication. - * Must be taken after struct_mutex if nested. Note that - * this lock may be held for long periods of time when - * talking to hw - so only take it when talking to hw! - */ - struct mutex hw_lock; }; /* defined intel_pm.c */ @@ -2421,6 +2413,14 @@ struct drm_i915_private { /* Cannot be determined by PCIID. You must always read a register. */ u32 edram_cap; + /* + * Protects RPS/RC6 register access and PCU communication. + * Must be taken after struct_mutex if nested. Note that + * this lock may be held for long periods of time when + * talking to hw - so only take it when talking to hw! + */ + struct mutex pcu_lock; + /* gen6+ rps state */ struct intel_gen6_power_mgmt rps; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 915c5b9dc547..1844d3fe8f1f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1181,7 +1181,7 @@ static void gen6_pm_rps_work(struct work_struct *work) if ((pm_iir & dev_priv->pm_rps_events) == 0 && !client_boost) goto out; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir); @@ -1235,7 +1235,7 @@ static void gen6_pm_rps_work(struct work_struct *work) dev_priv->rps.last_adj = 0; } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); out: /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index d61c8727f756..79fbab49d1d0 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -246,7 +246,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev, intel_runtime_pm_get(dev_priv); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { u32 freq; freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); @@ -261,7 +261,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev, ret = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT; ret = intel_gpu_freq(dev_priv, ret); } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_runtime_pm_put(dev_priv); @@ -304,9 +304,9 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev, if (val < dev_priv->rps.min_freq || val > dev_priv->rps.max_freq) return -EINVAL; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); dev_priv->rps.boost_freq = val; - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); return count; } @@ -344,14 +344,14 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, intel_runtime_pm_get(dev_priv); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); val = intel_freq_opcode(dev_priv, val); if (val < dev_priv->rps.min_freq || val > dev_priv->rps.max_freq || val < dev_priv->rps.min_freq_softlimit) { - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_runtime_pm_put(dev_priv); return -EINVAL; } @@ -371,7 +371,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, * frequency request may be unchanged. */ ret = intel_set_rps(dev_priv, val); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_runtime_pm_put(dev_priv); @@ -401,14 +401,14 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, intel_runtime_pm_get(dev_priv); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); val = intel_freq_opcode(dev_priv, val); if (val < dev_priv->rps.min_freq || val > dev_priv->rps.max_freq || val > dev_priv->rps.max_freq_softlimit) { - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_runtime_pm_put(dev_priv); return -EINVAL; } @@ -424,7 +424,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, * frequency request may be unchanged. */ ret = intel_set_rps(dev_priv, val); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_runtime_pm_put(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 87fc42b19336..b2a6d62b71c0 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -503,7 +503,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, else cmd = 0; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); val &= ~DSPFREQGUAR_MASK; val |= (cmd << DSPFREQGUAR_SHIFT); @@ -513,7 +513,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, 50)) { DRM_ERROR("timed out waiting for CDclk change\n"); } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); mutex_lock(&dev_priv->sb_lock); @@ -590,7 +590,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, */ cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); val &= ~DSPFREQGUAR_MASK_CHV; val |= (cmd << DSPFREQGUAR_SHIFT_CHV); @@ -600,7 +600,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, 50)) { DRM_ERROR("timed out waiting for CDclk change\n"); } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_update_cdclk(dev_priv); @@ -656,10 +656,10 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, "trying to change cdclk frequency with cdclk not enabled\n")) return; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = sandybridge_pcode_write(dev_priv, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); if (ret) { DRM_ERROR("failed to inform pcode about cdclk change\n"); return; @@ -712,9 +712,9 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) DRM_ERROR("Switching back to LCPLL failed\n"); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); @@ -928,12 +928,12 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, WARN_ON((cdclk == 24000) != (vco == 0)); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL, SKL_CDCLK_PREPARE_FOR_CHANGE, SKL_CDCLK_READY_FOR_CHANGE, SKL_CDCLK_READY_FOR_CHANGE, 3); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); if (ret) { DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n", ret); @@ -975,9 +975,9 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, POSTING_READ(CDCLK_CTL); /* inform PCU of the change */ - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_update_cdclk(dev_priv); } @@ -1268,10 +1268,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, } /* Inform power controller of upcoming frequency change */ - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, 0x80000000); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); if (ret) { DRM_ERROR("PCode CDCLK freq change notify failed (err %d, freq %d)\n", @@ -1300,10 +1300,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; I915_WRITE(CDCLK_CTL, val); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, DIV_ROUND_UP(cdclk, 25000)); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); if (ret) { DRM_ERROR("PCode CDCLK freq set failed, (err %d, freq %d)\n", @@ -1518,12 +1518,12 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, u32 val, divider, pcu_ack; int ret; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL, SKL_CDCLK_PREPARE_FOR_CHANGE, SKL_CDCLK_READY_FOR_CHANGE, SKL_CDCLK_READY_FOR_CHANGE, 3); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); if (ret) { DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n", ret); @@ -1575,9 +1575,9 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, I915_WRITE(CDCLK_CTL, val); /* inform PCU of the change */ - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); intel_update_cdclk(dev_priv); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e03b0c3d6f9f..b2c5fba102e1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4946,10 +4946,10 @@ void hsw_enable_ips(struct intel_crtc *crtc) assert_plane_enabled(dev_priv, crtc->plane); if (IS_BROADWELL(dev_priv)) { - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, IPS_ENABLE | IPS_PCODE_CONTROL)); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); /* Quoting Art Runyan: "its not safe to expect any particular * value in IPS_CTL bit 31 after enabling IPS through the * mailbox." Moreover, the mailbox may return a bogus state, @@ -4979,9 +4979,9 @@ void hsw_disable_ips(struct intel_crtc *crtc) assert_plane_enabled(dev_priv, crtc->plane); if (IS_BROADWELL(dev_priv)) { - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); /* wait for pcode to finish disabling IPS, which may take up to 42ms */ if (intel_wait_for_register(dev_priv, IPS_CTL, IPS_ENABLE, 0, @@ -8839,11 +8839,11 @@ static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv) static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val) { if (IS_HASWELL(dev_priv)) { - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val)) DRM_DEBUG_KMS("Failed to write to D_COMP\n"); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } else { I915_WRITE(D_COMP_BDW, val); POSTING_READ(D_COMP_BDW); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 831054084fb7..512f2b0513e0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -322,7 +322,7 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable) { u32 val; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); if (enable) @@ -337,14 +337,14 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable) FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) DRM_ERROR("timed out waiting for Punit DDR DVFS request\n"); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) { u32 val; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); if (enable) @@ -353,7 +353,7 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) val &= ~DSP_MAXFIFO_PM5_ENABLE; vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } #define FW_WM(value, plane) \ @@ -2790,11 +2790,11 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv, /* read the first set of memory latencies[0:3] */ val = 0; /* data0 to be programmed to 0 for first set */ - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = sandybridge_pcode_read(dev_priv, GEN9_PCODE_READ_MEM_LATENCY, &val); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); if (ret) { DRM_ERROR("SKL Mailbox read error = %d\n", ret); @@ -2811,11 +2811,11 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv, /* read the second set of memory latencies[4:7] */ val = 1; /* data0 to be programmed to 1 for second set */ - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = sandybridge_pcode_read(dev_priv, GEN9_PCODE_READ_MEM_LATENCY, &val); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); if (ret) { DRM_ERROR("SKL Mailbox read error = %d\n", ret); return; @@ -3608,13 +3608,13 @@ intel_enable_sagv(struct drm_i915_private *dev_priv) return 0; DRM_DEBUG_KMS("Enabling the SAGV\n"); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); ret = sandybridge_pcode_write(dev_priv, GEN9_PCODE_SAGV_CONTROL, GEN9_SAGV_ENABLE); /* We don't need to wait for the SAGV when enabling */ - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); /* * Some skl systems, pre-release machines in particular, @@ -3645,14 +3645,14 @@ intel_disable_sagv(struct drm_i915_private *dev_priv) return 0; DRM_DEBUG_KMS("Disabling the SAGV\n"); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); /* bspec says to keep retrying for at least 1 ms */ ret = skl_pcode_request(dev_priv, GEN9_PCODE_SAGV_CONTROL, GEN9_SAGV_DISABLE, GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED, 1); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); /* * Some skl systems, pre-release machines in particular, @@ -5621,7 +5621,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev) wm->level = VLV_WM_LEVEL_PM2; if (IS_CHERRYVIEW(dev_priv)) { - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); if (val & DSP_MAXFIFO_PM5_ENABLE) @@ -5651,7 +5651,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev) wm->level = VLV_WM_LEVEL_DDR_DVFS; } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } for_each_intel_crtc(dev, crtc) { @@ -6224,7 +6224,7 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) void gen6_rps_busy(struct drm_i915_private *dev_priv) { - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); if (dev_priv->rps.enabled) { u8 freq; @@ -6247,7 +6247,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) dev_priv->rps.max_freq_softlimit))) DRM_DEBUG_DRIVER("Failed to set idle frequency\n"); } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } void gen6_rps_idle(struct drm_i915_private *dev_priv) @@ -6259,7 +6259,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) */ gen6_disable_rps_interrupts(dev_priv); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); if (dev_priv->rps.enabled) { if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) vlv_set_rps_idle(dev_priv); @@ -6269,7 +6269,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0)); } - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } void gen6_rps_boost(struct drm_i915_gem_request *rq, @@ -6306,7 +6306,7 @@ int intel_set_rps(struct drm_i915_private *dev_priv, u8 val) { int err; - lockdep_assert_held(&dev_priv->rps.hw_lock); + lockdep_assert_held(&dev_priv->pcu_lock); GEM_BUG_ON(val > dev_priv->rps.max_freq); GEM_BUG_ON(val < dev_priv->rps.min_freq); @@ -6715,7 +6715,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) int rc6_mode; int ret; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); I915_WRITE(GEN6_RC_STATE, 0); @@ -6789,7 +6789,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) static void gen6_enable_rps(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); /* Here begins a magic sequence of register writes to enable * auto-downclocking. @@ -6817,7 +6817,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) int scaling_factor = 180; struct cpufreq_policy *policy; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); policy = cpufreq_cpu_get(0); if (policy) { @@ -7210,7 +7210,7 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv) enum intel_engine_id id; u32 gtfifodbg, rc6_mode = 0, pcbr; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV | GT_FIFO_FREE_ENTRIES_CHV); @@ -7264,7 +7264,7 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv) { u32 val; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); @@ -7310,7 +7310,7 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv) enum intel_engine_id id; u32 gtfifodbg, rc6_mode = 0; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); valleyview_check_pctx(dev_priv); @@ -7357,7 +7357,7 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv) { u32 val; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); @@ -7881,7 +7881,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) } mutex_lock(&dev_priv->drm.struct_mutex); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); /* Initialize RPS limits (for userspace) */ if (IS_CHERRYVIEW(dev_priv)) @@ -7921,7 +7921,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) /* Finally allow us to boost to max by default */ dev_priv->rps.boost_freq = dev_priv->rps.max_freq; - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->drm.struct_mutex); intel_autoenable_gt_powersave(dev_priv); @@ -7968,7 +7968,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) if (!READ_ONCE(dev_priv->rps.enabled)) return; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); if (INTEL_GEN(dev_priv) >= 9) { gen9_disable_rc6(dev_priv); @@ -7987,7 +7987,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) } dev_priv->rps.enabled = false; - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) @@ -8002,7 +8002,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) if (intel_vgpu_active(dev_priv)) return; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); if (IS_CHERRYVIEW(dev_priv)) { cherryview_enable_rc6(dev_priv); @@ -8035,7 +8035,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq); dev_priv->rps.enabled = true; - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } static void __intel_autoenable_gt_powersave(struct work_struct *work) @@ -9123,7 +9123,7 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val { int status; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); /* GEN6_PCODE_* are outside of the forcewake domain, we can * use te fw I915_READ variants to reduce the amount of work @@ -9170,7 +9170,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, { int status; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); /* GEN6_PCODE_* are outside of the forcewake domain, we can * use te fw I915_READ variants to reduce the amount of work @@ -9247,7 +9247,7 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request, u32 status; int ret; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); #define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \ &status) @@ -9344,7 +9344,7 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val) void intel_pm_setup(struct drm_i915_private *dev_priv) { - mutex_init(&dev_priv->rps.hw_lock); + mutex_init(&dev_priv->pcu_lock); INIT_DELAYED_WORK(&dev_priv->rps.autoenable_work, __intel_autoenable_gt_powersave); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 7348c16c4a96..8af286c63d3b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -785,7 +785,7 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv, state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) : PUNIT_PWRGT_PWR_GATE(power_well_id); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); #define COND \ ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state) @@ -806,7 +806,7 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv, #undef COND out: - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } static void vlv_power_well_enable(struct drm_i915_private *dev_priv, @@ -833,7 +833,7 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, mask = PUNIT_PWRGT_MASK(power_well_id); ctrl = PUNIT_PWRGT_PWR_ON(power_well_id); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask; /* @@ -852,7 +852,7 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask; WARN_ON(ctrl != state); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); return enabled; } @@ -1364,7 +1364,7 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv, bool enabled; u32 state, ctrl; - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe); /* @@ -1381,7 +1381,7 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv, ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSC_MASK(pipe); WARN_ON(ctrl << 16 != state); - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); return enabled; } @@ -1396,7 +1396,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv, state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe); - mutex_lock(&dev_priv->rps.hw_lock); + mutex_lock(&dev_priv->pcu_lock); #define COND \ ((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe)) == state) @@ -1417,7 +1417,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv, #undef COND out: - mutex_unlock(&dev_priv->rps.hw_lock); + mutex_unlock(&dev_priv->pcu_lock); } static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 7d971cb56116..75c872bb8cc9 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -81,7 +81,7 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr) { u32 val = 0; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); mutex_lock(&dev_priv->sb_lock); vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT, @@ -95,7 +95,7 @@ int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val) { int err; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); mutex_lock(&dev_priv->sb_lock); err = vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT, @@ -125,7 +125,7 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr) { u32 val = 0; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); mutex_lock(&dev_priv->sb_lock); vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC, -- cgit v1.2.3 From 562d9bae08a10335368bf54ea5cc7e4f6185bccc Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:06 +0100 Subject: drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "gt_pm" Prepared substructure rps for RPS related state. autoenable_work is used for RC6 too hence it is defined outside rps structure. As we do this lot many functions are refactored to use intel_rps *rps to access rps related members. Hence renamed intel_rps_client pointer variables to rps_client in various functions. v2: Rebase. v3: s/pm/gt_pm (Chris) Refactored access to rps structure by declaring struct intel_rps * in many functions. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Imre Deak Cc: Joonas Lahtinen Reviewed-by: Radoslaw Szwichtenberg #1 Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-9-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-8-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 99 ++++----- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 14 +- drivers/gpu/drm/i915/i915_gem.c | 21 +- drivers/gpu/drm/i915/i915_gem_request.c | 2 +- drivers/gpu/drm/i915/i915_guc_submission.c | 10 +- drivers/gpu/drm/i915/i915_irq.c | 87 ++++---- drivers/gpu/drm/i915/i915_sysfs.c | 54 ++--- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_pm.c | 315 ++++++++++++++++------------- 10 files changed, 330 insertions(+), 276 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e733097fa647..0bb6e01121fc 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1080,6 +1080,7 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops, static int i915_frequency_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_rps *rps = &dev_priv->gt_pm.rps; int ret = 0; intel_runtime_pm_get(dev_priv); @@ -1116,20 +1117,20 @@ static int i915_frequency_info(struct seq_file *m, void *unused) intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff)); seq_printf(m, "current GPU freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); + intel_gpu_freq(dev_priv, rps->cur_freq)); seq_printf(m, "max GPU freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); + intel_gpu_freq(dev_priv, rps->max_freq)); seq_printf(m, "min GPU freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.min_freq)); + intel_gpu_freq(dev_priv, rps->min_freq)); seq_printf(m, "idle GPU freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq)); + intel_gpu_freq(dev_priv, rps->idle_freq)); seq_printf(m, "efficient (RPe) frequency: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq)); + intel_gpu_freq(dev_priv, rps->efficient_freq)); mutex_unlock(&dev_priv->pcu_lock); } else if (INTEL_GEN(dev_priv) >= 6) { u32 rp_state_limits; @@ -1210,7 +1211,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n", pm_ier, pm_imr, pm_isr, pm_iir, pm_mask); seq_printf(m, "pm_intrmsk_mbz: 0x%08x\n", - dev_priv->rps.pm_intrmsk_mbz); + rps->pm_intrmsk_mbz); seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "Render p-state ratio: %d\n", (gt_perf_status & (INTEL_GEN(dev_priv) >= 9 ? 0x1ff00 : 0xff00)) >> 8); @@ -1230,8 +1231,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup)); seq_printf(m, "RP PREV UP: %d (%dus)\n", rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup)); - seq_printf(m, "Up threshold: %d%%\n", - dev_priv->rps.up_threshold); + seq_printf(m, "Up threshold: %d%%\n", rps->up_threshold); seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n", rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei)); @@ -1239,8 +1239,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown)); seq_printf(m, "RP PREV DOWN: %d (%dus)\n", rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown)); - seq_printf(m, "Down threshold: %d%%\n", - dev_priv->rps.down_threshold); + seq_printf(m, "Down threshold: %d%%\n", rps->down_threshold); max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 : rp_state_cap >> 16) & 0xff; @@ -1262,22 +1261,22 @@ static int i915_frequency_info(struct seq_file *m, void *unused) seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", intel_gpu_freq(dev_priv, max_freq)); seq_printf(m, "Max overclocked frequency: %dMHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); + intel_gpu_freq(dev_priv, rps->max_freq)); seq_printf(m, "Current freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); + intel_gpu_freq(dev_priv, rps->cur_freq)); seq_printf(m, "Actual freq: %d MHz\n", cagf); seq_printf(m, "Idle freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq)); + intel_gpu_freq(dev_priv, rps->idle_freq)); seq_printf(m, "Min freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.min_freq)); + intel_gpu_freq(dev_priv, rps->min_freq)); seq_printf(m, "Boost freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq)); + intel_gpu_freq(dev_priv, rps->boost_freq)); seq_printf(m, "Max freq: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); + intel_gpu_freq(dev_priv, rps->max_freq)); seq_printf(m, "efficient (RPe) frequency: %d MHz\n", - intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq)); + intel_gpu_freq(dev_priv, rps->efficient_freq)); } else { seq_puts(m, "no P-state info available\n"); } @@ -1831,6 +1830,7 @@ static int i915_emon_status(struct seq_file *m, void *unused) static int i915_ring_freq_table(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_rps *rps = &dev_priv->gt_pm.rps; int ret = 0; int gpu_freq, ia_freq; unsigned int max_gpu_freq, min_gpu_freq; @@ -1848,13 +1848,11 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { /* Convert GT frequency to 50 HZ units */ - min_gpu_freq = - dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER; - max_gpu_freq = - dev_priv->rps.max_freq_softlimit / GEN9_FREQ_SCALER; + min_gpu_freq = rps->min_freq_softlimit / GEN9_FREQ_SCALER; + max_gpu_freq = rps->max_freq_softlimit / GEN9_FREQ_SCALER; } else { - min_gpu_freq = dev_priv->rps.min_freq_softlimit; - max_gpu_freq = dev_priv->rps.max_freq_softlimit; + min_gpu_freq = rps->min_freq_softlimit; + max_gpu_freq = rps->max_freq_softlimit; } seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); @@ -2307,25 +2305,26 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = node_to_i915(m->private); struct drm_device *dev = &dev_priv->drm; + struct intel_rps *rps = &dev_priv->gt_pm.rps; struct drm_file *file; - seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled); + seq_printf(m, "RPS enabled? %d\n", rps->enabled); seq_printf(m, "GPU busy? %s [%d requests]\n", yesno(dev_priv->gt.awake), dev_priv->gt.active_requests); seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv)); seq_printf(m, "Boosts outstanding? %d\n", - atomic_read(&dev_priv->rps.num_waiters)); + atomic_read(&rps->num_waiters)); seq_printf(m, "Frequency requested %d\n", - intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); + intel_gpu_freq(dev_priv, rps->cur_freq)); seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n", - intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), - intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit), - intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit), - intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); + intel_gpu_freq(dev_priv, rps->min_freq), + intel_gpu_freq(dev_priv, rps->min_freq_softlimit), + intel_gpu_freq(dev_priv, rps->max_freq_softlimit), + intel_gpu_freq(dev_priv, rps->max_freq)); seq_printf(m, " idle:%d, efficient:%d, boost:%d\n", - intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq), - intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), - intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq)); + intel_gpu_freq(dev_priv, rps->idle_freq), + intel_gpu_freq(dev_priv, rps->efficient_freq), + intel_gpu_freq(dev_priv, rps->boost_freq)); mutex_lock(&dev->filelist_mutex); list_for_each_entry_reverse(file, &dev->filelist, lhead) { @@ -2337,15 +2336,15 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) seq_printf(m, "%s [%d]: %d boosts\n", task ? task->comm : "", task ? task->pid : -1, - atomic_read(&file_priv->rps.boosts)); + atomic_read(&file_priv->rps_client.boosts)); rcu_read_unlock(); } seq_printf(m, "Kernel (anonymous) boosts: %d\n", - atomic_read(&dev_priv->rps.boosts)); + atomic_read(&rps->boosts)); mutex_unlock(&dev->filelist_mutex); if (INTEL_GEN(dev_priv) >= 6 && - dev_priv->rps.enabled && + rps->enabled && dev_priv->gt.active_requests) { u32 rpup, rpupei; u32 rpdown, rpdownei; @@ -2358,13 +2357,13 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n", - rps_power_to_str(dev_priv->rps.power)); + rps_power_to_str(rps->power)); seq_printf(m, " Avg. up: %d%% [above threshold? %d%%]\n", rpup && rpupei ? 100 * rpup / rpupei : 0, - dev_priv->rps.up_threshold); + rps->up_threshold); seq_printf(m, " Avg. down: %d%% [below threshold? %d%%]\n", rpdown && rpdownei ? 100 * rpdown / rpdownei : 0, - dev_priv->rps.down_threshold); + rps->down_threshold); } else { seq_puts(m, "\nRPS Autotuning inactive\n"); } @@ -4304,7 +4303,7 @@ i915_max_freq_get(void *data, u64 *val) if (INTEL_GEN(dev_priv) < 6) return -ENODEV; - *val = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit); + *val = intel_gpu_freq(dev_priv, dev_priv->gt_pm.rps.max_freq_softlimit); return 0; } @@ -4312,6 +4311,7 @@ static int i915_max_freq_set(void *data, u64 val) { struct drm_i915_private *dev_priv = data; + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 hw_max, hw_min; int ret; @@ -4329,15 +4329,15 @@ i915_max_freq_set(void *data, u64 val) */ val = intel_freq_opcode(dev_priv, val); - hw_max = dev_priv->rps.max_freq; - hw_min = dev_priv->rps.min_freq; + hw_max = rps->max_freq; + hw_min = rps->min_freq; - if (val < hw_min || val > hw_max || val < dev_priv->rps.min_freq_softlimit) { + if (val < hw_min || val > hw_max || val < rps->min_freq_softlimit) { mutex_unlock(&dev_priv->pcu_lock); return -EINVAL; } - dev_priv->rps.max_freq_softlimit = val; + rps->max_freq_softlimit = val; if (intel_set_rps(dev_priv, val)) DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n"); @@ -4359,7 +4359,7 @@ i915_min_freq_get(void *data, u64 *val) if (INTEL_GEN(dev_priv) < 6) return -ENODEV; - *val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit); + *val = intel_gpu_freq(dev_priv, dev_priv->gt_pm.rps.min_freq_softlimit); return 0; } @@ -4367,6 +4367,7 @@ static int i915_min_freq_set(void *data, u64 val) { struct drm_i915_private *dev_priv = data; + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 hw_max, hw_min; int ret; @@ -4384,16 +4385,16 @@ i915_min_freq_set(void *data, u64 val) */ val = intel_freq_opcode(dev_priv, val); - hw_max = dev_priv->rps.max_freq; - hw_min = dev_priv->rps.min_freq; + hw_max = rps->max_freq; + hw_min = rps->min_freq; if (val < hw_min || - val > hw_max || val > dev_priv->rps.max_freq_softlimit) { + val > hw_max || val > rps->max_freq_softlimit) { mutex_unlock(&dev_priv->pcu_lock); return -EINVAL; } - dev_priv->rps.min_freq_softlimit = val; + rps->min_freq_softlimit = val; if (intel_set_rps(dev_priv, val)) DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n"); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9ebbb08dcf2d..9b8a19149154 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2502,7 +2502,7 @@ static int intel_runtime_suspend(struct device *kdev) struct drm_i915_private *dev_priv = to_i915(dev); int ret; - if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6()))) + if (WARN_ON_ONCE(!(dev_priv->gt_pm.rps.enabled && intel_enable_rc6()))) return -ENODEV; if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fca7b939495f..521348ee7242 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -609,7 +609,7 @@ struct drm_i915_file_private { struct intel_rps_client { atomic_t boosts; - } rps; + } rps_client; unsigned int bsd_engine; @@ -1317,7 +1317,7 @@ struct intel_rps_ei { u32 media_c0; }; -struct intel_gen6_power_mgmt { +struct intel_rps { /* * work, interrupts_enabled and pm_iir are protected by * dev_priv->irq_lock @@ -1358,7 +1358,6 @@ struct intel_gen6_power_mgmt { enum { LOW_POWER, BETWEEN, HIGH_POWER } power; bool enabled; - struct delayed_work autoenable_work; atomic_t num_waiters; atomic_t boosts; @@ -1366,6 +1365,11 @@ struct intel_gen6_power_mgmt { struct intel_rps_ei ei; }; +struct intel_gen6_power_mgmt { + struct intel_rps rps; + struct delayed_work autoenable_work; +}; + /* defined intel_pm.c */ extern spinlock_t mchdev_lock; @@ -2421,8 +2425,8 @@ struct drm_i915_private { */ struct mutex pcu_lock; - /* gen6+ rps state */ - struct intel_gen6_power_mgmt rps; + /* gen6+ GT PM state */ + struct intel_gen6_power_mgmt gt_pm; /* ilk-only ips/rps state. Everything in here is protected by the global * mchdev_lock in intel_pm.c */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e829e8c900e8..f76890b74d00 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -358,7 +358,7 @@ static long i915_gem_object_wait_fence(struct dma_fence *fence, unsigned int flags, long timeout, - struct intel_rps_client *rps) + struct intel_rps_client *rps_client) { struct drm_i915_gem_request *rq; @@ -391,11 +391,11 @@ i915_gem_object_wait_fence(struct dma_fence *fence, * forcing the clocks too high for the whole system, we only allow * each client to waitboost once in a busy period. */ - if (rps) { + if (rps_client) { if (INTEL_GEN(rq->i915) >= 6) - gen6_rps_boost(rq, rps); + gen6_rps_boost(rq, rps_client); else - rps = NULL; + rps_client = NULL; } timeout = i915_wait_request(rq, flags, timeout); @@ -411,7 +411,7 @@ static long i915_gem_object_wait_reservation(struct reservation_object *resv, unsigned int flags, long timeout, - struct intel_rps_client *rps) + struct intel_rps_client *rps_client) { unsigned int seq = __read_seqcount_begin(&resv->seq); struct dma_fence *excl; @@ -430,7 +430,7 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, for (i = 0; i < count; i++) { timeout = i915_gem_object_wait_fence(shared[i], flags, timeout, - rps); + rps_client); if (timeout < 0) break; @@ -447,7 +447,8 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, } if (excl && timeout >= 0) { - timeout = i915_gem_object_wait_fence(excl, flags, timeout, rps); + timeout = i915_gem_object_wait_fence(excl, flags, timeout, + rps_client); prune_fences = timeout >= 0; } @@ -543,7 +544,7 @@ int i915_gem_object_wait(struct drm_i915_gem_object *obj, unsigned int flags, long timeout, - struct intel_rps_client *rps) + struct intel_rps_client *rps_client) { might_sleep(); #if IS_ENABLED(CONFIG_LOCKDEP) @@ -555,7 +556,7 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj, timeout = i915_gem_object_wait_reservation(obj->resv, flags, timeout, - rps); + rps_client); return timeout < 0 ? timeout : 0; } @@ -563,7 +564,7 @@ static struct intel_rps_client *to_rps_client(struct drm_file *file) { struct drm_i915_file_private *fpriv = file->driver_priv; - return &fpriv->rps; + return &fpriv->rps_client; } static int diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index b100b38f1dd2..d5f4023e5d63 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -416,7 +416,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request) spin_lock_irq(&request->lock); if (request->waitboost) - atomic_dec(&request->i915->rps.num_waiters); + atomic_dec(&request->i915->gt_pm.rps.num_waiters); dma_fence_signal_locked(&request->fence); spin_unlock_irq(&request->lock); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index f15de4dcefde..a2e8114b739d 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -1028,6 +1028,7 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv) static void guc_interrupts_capture(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; struct intel_engine_cs *engine; enum intel_engine_id id; int irqs; @@ -1064,12 +1065,13 @@ static void guc_interrupts_capture(struct drm_i915_private *dev_priv) * Here we CLEAR REDIRECT_TO_GUC bit in pm_intrmsk_mbz, which will * result in the register bit being left SET! */ - dev_priv->rps.pm_intrmsk_mbz |= ARAT_EXPIRED_INTRMSK; - dev_priv->rps.pm_intrmsk_mbz &= ~GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; + rps->pm_intrmsk_mbz |= ARAT_EXPIRED_INTRMSK; + rps->pm_intrmsk_mbz &= ~GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; } static void guc_interrupts_release(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; struct intel_engine_cs *engine; enum intel_engine_id id; int irqs; @@ -1088,8 +1090,8 @@ static void guc_interrupts_release(struct drm_i915_private *dev_priv) I915_WRITE(GUC_VCS2_VCS1_IER, 0); I915_WRITE(GUC_WD_VECS_IER, 0); - dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; - dev_priv->rps.pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK; + rps->pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; + rps->pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK; } int i915_guc_submission_enable(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1844d3fe8f1f..b1296a55c1e4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -404,19 +404,21 @@ void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) { spin_lock_irq(&dev_priv->irq_lock); gen6_reset_pm_iir(dev_priv, dev_priv->pm_rps_events); - dev_priv->rps.pm_iir = 0; + dev_priv->gt_pm.rps.pm_iir = 0; spin_unlock_irq(&dev_priv->irq_lock); } void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) { - if (READ_ONCE(dev_priv->rps.interrupts_enabled)) + struct intel_rps *rps = &dev_priv->gt_pm.rps; + + if (READ_ONCE(rps->interrupts_enabled)) return; spin_lock_irq(&dev_priv->irq_lock); - WARN_ON_ONCE(dev_priv->rps.pm_iir); + WARN_ON_ONCE(rps->pm_iir); WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); - dev_priv->rps.interrupts_enabled = true; + rps->interrupts_enabled = true; gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); @@ -424,11 +426,13 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) { - if (!READ_ONCE(dev_priv->rps.interrupts_enabled)) + struct intel_rps *rps = &dev_priv->gt_pm.rps; + + if (!READ_ONCE(rps->interrupts_enabled)) return; spin_lock_irq(&dev_priv->irq_lock); - dev_priv->rps.interrupts_enabled = false; + rps->interrupts_enabled = false; I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u)); @@ -442,7 +446,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) * we will reset the GPU to minimum frequencies, so the current * state of the worker can be discarded. */ - cancel_work_sync(&dev_priv->rps.work); + cancel_work_sync(&rps->work); gen6_reset_rps_interrupts(dev_priv); } @@ -1119,12 +1123,13 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv, void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) { - memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei)); + memset(&dev_priv->gt_pm.rps.ei, 0, sizeof(dev_priv->gt_pm.rps.ei)); } static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) { - const struct intel_rps_ei *prev = &dev_priv->rps.ei; + struct intel_rps *rps = &dev_priv->gt_pm.rps; + const struct intel_rps_ei *prev = &rps->ei; struct intel_rps_ei now; u32 events = 0; @@ -1151,28 +1156,29 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) c0 = max(render, media); c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */ - if (c0 > time * dev_priv->rps.up_threshold) + if (c0 > time * rps->up_threshold) events = GEN6_PM_RP_UP_THRESHOLD; - else if (c0 < time * dev_priv->rps.down_threshold) + else if (c0 < time * rps->down_threshold) events = GEN6_PM_RP_DOWN_THRESHOLD; } - dev_priv->rps.ei = now; + rps->ei = now; return events; } static void gen6_pm_rps_work(struct work_struct *work) { struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, rps.work); + container_of(work, struct drm_i915_private, gt_pm.rps.work); + struct intel_rps *rps = &dev_priv->gt_pm.rps; bool client_boost = false; int new_delay, adj, min, max; u32 pm_iir = 0; spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->rps.interrupts_enabled) { - pm_iir = fetch_and_zero(&dev_priv->rps.pm_iir); - client_boost = atomic_read(&dev_priv->rps.num_waiters); + if (rps->interrupts_enabled) { + pm_iir = fetch_and_zero(&rps->pm_iir); + client_boost = atomic_read(&rps->num_waiters); } spin_unlock_irq(&dev_priv->irq_lock); @@ -1185,14 +1191,14 @@ static void gen6_pm_rps_work(struct work_struct *work) pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir); - adj = dev_priv->rps.last_adj; - new_delay = dev_priv->rps.cur_freq; - min = dev_priv->rps.min_freq_softlimit; - max = dev_priv->rps.max_freq_softlimit; + adj = rps->last_adj; + new_delay = rps->cur_freq; + min = rps->min_freq_softlimit; + max = rps->max_freq_softlimit; if (client_boost) - max = dev_priv->rps.max_freq; - if (client_boost && new_delay < dev_priv->rps.boost_freq) { - new_delay = dev_priv->rps.boost_freq; + max = rps->max_freq; + if (client_boost && new_delay < rps->boost_freq) { + new_delay = rps->boost_freq; adj = 0; } else if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { if (adj > 0) @@ -1200,15 +1206,15 @@ static void gen6_pm_rps_work(struct work_struct *work) else /* CHV needs even encode values */ adj = IS_CHERRYVIEW(dev_priv) ? 2 : 1; - if (new_delay >= dev_priv->rps.max_freq_softlimit) + if (new_delay >= rps->max_freq_softlimit) adj = 0; } else if (client_boost) { adj = 0; } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) { - if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq) - new_delay = dev_priv->rps.efficient_freq; - else if (dev_priv->rps.cur_freq > dev_priv->rps.min_freq_softlimit) - new_delay = dev_priv->rps.min_freq_softlimit; + if (rps->cur_freq > rps->efficient_freq) + new_delay = rps->efficient_freq; + else if (rps->cur_freq > rps->min_freq_softlimit) + new_delay = rps->min_freq_softlimit; adj = 0; } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) { if (adj < 0) @@ -1216,13 +1222,13 @@ static void gen6_pm_rps_work(struct work_struct *work) else /* CHV needs even encode values */ adj = IS_CHERRYVIEW(dev_priv) ? -2 : -1; - if (new_delay <= dev_priv->rps.min_freq_softlimit) + if (new_delay <= rps->min_freq_softlimit) adj = 0; } else { /* unknown event */ adj = 0; } - dev_priv->rps.last_adj = adj; + rps->last_adj = adj; /* sysfs frequency interfaces may have snuck in while servicing the * interrupt @@ -1232,7 +1238,7 @@ static void gen6_pm_rps_work(struct work_struct *work) if (intel_set_rps(dev_priv, new_delay)) { DRM_DEBUG_DRIVER("Failed to set new GPU frequency\n"); - dev_priv->rps.last_adj = 0; + rps->last_adj = 0; } mutex_unlock(&dev_priv->pcu_lock); @@ -1240,7 +1246,7 @@ static void gen6_pm_rps_work(struct work_struct *work) out: /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->rps.interrupts_enabled) + if (rps->interrupts_enabled) gen6_unmask_pm_irq(dev_priv, dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); } @@ -1721,12 +1727,14 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, * the work queue. */ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + if (pm_iir & dev_priv->pm_rps_events) { spin_lock(&dev_priv->irq_lock); gen6_mask_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); - if (dev_priv->rps.interrupts_enabled) { - dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; - schedule_work(&dev_priv->rps.work); + if (rps->interrupts_enabled) { + rps->pm_iir |= pm_iir & dev_priv->pm_rps_events; + schedule_work(&rps->work); } spin_unlock(&dev_priv->irq_lock); } @@ -4007,11 +4015,12 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) void intel_irq_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = &dev_priv->drm; + struct intel_rps *rps = &dev_priv->gt_pm.rps; int i; intel_hpd_init_work(dev_priv); - INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); + INIT_WORK(&rps->work, gen6_pm_rps_work); INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); for (i = 0; i < MAX_L3_SLICES; ++i) @@ -4027,7 +4036,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) else dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; - dev_priv->rps.pm_intrmsk_mbz = 0; + rps->pm_intrmsk_mbz = 0; /* * SNB,IVB,HSW can while VLV,CHV may hard hang on looping batchbuffer @@ -4036,10 +4045,10 @@ void intel_irq_init(struct drm_i915_private *dev_priv) * TODO: verify if this can be reproduced on VLV,CHV. */ if (INTEL_GEN(dev_priv) <= 7) - dev_priv->rps.pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED; + rps->pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED; if (INTEL_GEN(dev_priv) >= 8) - dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; + rps->pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; if (IS_GEN2(dev_priv)) { /* Gen2 doesn't have a hardware frame counter */ diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 79fbab49d1d0..0a57f9867f7f 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -275,7 +275,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, - dev_priv->rps.cur_freq)); + dev_priv->gt_pm.rps.cur_freq)); } static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) @@ -284,7 +284,7 @@ static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribu return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, - dev_priv->rps.boost_freq)); + dev_priv->gt_pm.rps.boost_freq)); } static ssize_t gt_boost_freq_mhz_store(struct device *kdev, @@ -292,6 +292,7 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev, const char *buf, size_t count) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 val; ssize_t ret; @@ -301,11 +302,11 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev, /* Validate against (static) hardware limits */ val = intel_freq_opcode(dev_priv, val); - if (val < dev_priv->rps.min_freq || val > dev_priv->rps.max_freq) + if (val < rps->min_freq || val > rps->max_freq) return -EINVAL; mutex_lock(&dev_priv->pcu_lock); - dev_priv->rps.boost_freq = val; + rps->boost_freq = val; mutex_unlock(&dev_priv->pcu_lock); return count; @@ -318,7 +319,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, - dev_priv->rps.efficient_freq)); + dev_priv->gt_pm.rps.efficient_freq)); } static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) @@ -327,7 +328,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, - dev_priv->rps.max_freq_softlimit)); + dev_priv->gt_pm.rps.max_freq_softlimit)); } static ssize_t gt_max_freq_mhz_store(struct device *kdev, @@ -335,6 +336,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, const char *buf, size_t count) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 val; ssize_t ret; @@ -348,23 +350,23 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, val = intel_freq_opcode(dev_priv, val); - if (val < dev_priv->rps.min_freq || - val > dev_priv->rps.max_freq || - val < dev_priv->rps.min_freq_softlimit) { + if (val < rps->min_freq || + val > rps->max_freq || + val < rps->min_freq_softlimit) { mutex_unlock(&dev_priv->pcu_lock); intel_runtime_pm_put(dev_priv); return -EINVAL; } - if (val > dev_priv->rps.rp0_freq) + if (val > rps->rp0_freq) DRM_DEBUG("User requested overclocking to %d\n", intel_gpu_freq(dev_priv, val)); - dev_priv->rps.max_freq_softlimit = val; + rps->max_freq_softlimit = val; - val = clamp_t(int, dev_priv->rps.cur_freq, - dev_priv->rps.min_freq_softlimit, - dev_priv->rps.max_freq_softlimit); + val = clamp_t(int, rps->cur_freq, + rps->min_freq_softlimit, + rps->max_freq_softlimit); /* We still need *_set_rps to process the new max_delay and * update the interrupt limits and PMINTRMSK even though @@ -384,7 +386,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, - dev_priv->rps.min_freq_softlimit)); + dev_priv->gt_pm.rps.min_freq_softlimit)); } static ssize_t gt_min_freq_mhz_store(struct device *kdev, @@ -392,6 +394,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, const char *buf, size_t count) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 val; ssize_t ret; @@ -405,19 +408,19 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, val = intel_freq_opcode(dev_priv, val); - if (val < dev_priv->rps.min_freq || - val > dev_priv->rps.max_freq || - val > dev_priv->rps.max_freq_softlimit) { + if (val < rps->min_freq || + val > rps->max_freq || + val > rps->max_freq_softlimit) { mutex_unlock(&dev_priv->pcu_lock); intel_runtime_pm_put(dev_priv); return -EINVAL; } - dev_priv->rps.min_freq_softlimit = val; + rps->min_freq_softlimit = val; - val = clamp_t(int, dev_priv->rps.cur_freq, - dev_priv->rps.min_freq_softlimit, - dev_priv->rps.max_freq_softlimit); + val = clamp_t(int, rps->cur_freq, + rps->min_freq_softlimit, + rps->max_freq_softlimit); /* We still need *_set_rps to process the new min_delay and * update the interrupt limits and PMINTRMSK even though @@ -448,14 +451,15 @@ static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL); static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 val; if (attr == &dev_attr_gt_RP0_freq_mhz) - val = intel_gpu_freq(dev_priv, dev_priv->rps.rp0_freq); + val = intel_gpu_freq(dev_priv, rps->rp0_freq); else if (attr == &dev_attr_gt_RP1_freq_mhz) - val = intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq); + val = intel_gpu_freq(dev_priv, rps->rp1_freq); else if (attr == &dev_attr_gt_RPn_freq_mhz) - val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq); + val = intel_gpu_freq(dev_priv, rps->min_freq); else BUG(); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3fd428b99c37..53acfc475e35 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1243,7 +1243,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv); static inline u32 gen6_sanitize_rps_pm_mask(const struct drm_i915_private *i915, u32 mask) { - return mask & ~i915->rps.pm_intrmsk_mbz; + return mask & ~i915->gt_pm.rps.pm_intrmsk_mbz; } void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 512f2b0513e0..9097489e1993 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5988,6 +5988,7 @@ static void ironlake_disable_drps(struct drm_i915_private *dev_priv) */ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 limits; /* Only set the down limit when we've reached the lowest level to avoid @@ -5997,13 +5998,13 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) * frequency, if the down threshold expires in that window we will not * receive a down interrupt. */ if (INTEL_GEN(dev_priv) >= 9) { - limits = (dev_priv->rps.max_freq_softlimit) << 23; - if (val <= dev_priv->rps.min_freq_softlimit) - limits |= (dev_priv->rps.min_freq_softlimit) << 14; + limits = (rps->max_freq_softlimit) << 23; + if (val <= rps->min_freq_softlimit) + limits |= (rps->min_freq_softlimit) << 14; } else { - limits = dev_priv->rps.max_freq_softlimit << 24; - if (val <= dev_priv->rps.min_freq_softlimit) - limits |= dev_priv->rps.min_freq_softlimit << 16; + limits = rps->max_freq_softlimit << 24; + if (val <= rps->min_freq_softlimit) + limits |= rps->min_freq_softlimit << 16; } return limits; @@ -6011,39 +6012,40 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; int new_power; u32 threshold_up = 0, threshold_down = 0; /* in % */ u32 ei_up = 0, ei_down = 0; - new_power = dev_priv->rps.power; - switch (dev_priv->rps.power) { + new_power = rps->power; + switch (rps->power) { case LOW_POWER: - if (val > dev_priv->rps.efficient_freq + 1 && - val > dev_priv->rps.cur_freq) + if (val > rps->efficient_freq + 1 && + val > rps->cur_freq) new_power = BETWEEN; break; case BETWEEN: - if (val <= dev_priv->rps.efficient_freq && - val < dev_priv->rps.cur_freq) + if (val <= rps->efficient_freq && + val < rps->cur_freq) new_power = LOW_POWER; - else if (val >= dev_priv->rps.rp0_freq && - val > dev_priv->rps.cur_freq) + else if (val >= rps->rp0_freq && + val > rps->cur_freq) new_power = HIGH_POWER; break; case HIGH_POWER: - if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 && - val < dev_priv->rps.cur_freq) + if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 && + val < rps->cur_freq) new_power = BETWEEN; break; } /* Max/min bins are special */ - if (val <= dev_priv->rps.min_freq_softlimit) + if (val <= rps->min_freq_softlimit) new_power = LOW_POWER; - if (val >= dev_priv->rps.max_freq_softlimit) + if (val >= rps->max_freq_softlimit) new_power = HIGH_POWER; - if (new_power == dev_priv->rps.power) + if (new_power == rps->power) return; /* Note the units here are not exactly 1us, but 1280ns. */ @@ -6106,20 +6108,21 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) GEN6_RP_DOWN_IDLE_AVG); skip_hw_write: - dev_priv->rps.power = new_power; - dev_priv->rps.up_threshold = threshold_up; - dev_priv->rps.down_threshold = threshold_down; - dev_priv->rps.last_adj = 0; + rps->power = new_power; + rps->up_threshold = threshold_up; + rps->down_threshold = threshold_down; + rps->last_adj = 0; } static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 mask = 0; /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ - if (val > dev_priv->rps.min_freq_softlimit) + if (val > rps->min_freq_softlimit) mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; - if (val < dev_priv->rps.max_freq_softlimit) + if (val < rps->max_freq_softlimit) mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; mask &= dev_priv->pm_rps_events; @@ -6132,10 +6135,12 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* min/max delay may still have been modified so be sure to * write the limits value. */ - if (val != dev_priv->rps.cur_freq) { + if (val != rps->cur_freq) { gen6_set_rps_thresholds(dev_priv, val); if (INTEL_GEN(dev_priv) >= 9) @@ -6157,7 +6162,7 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val) I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val)); I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); - dev_priv->rps.cur_freq = val; + rps->cur_freq = val; trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); return 0; @@ -6173,7 +6178,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val) I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); - if (val != dev_priv->rps.cur_freq) { + if (val != dev_priv->gt_pm.rps.cur_freq) { err = vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); if (err) return err; @@ -6181,7 +6186,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val) gen6_set_rps_thresholds(dev_priv, val); } - dev_priv->rps.cur_freq = val; + dev_priv->gt_pm.rps.cur_freq = val; trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); return 0; @@ -6196,10 +6201,11 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val) */ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) { - u32 val = dev_priv->rps.idle_freq; + struct intel_rps *rps = &dev_priv->gt_pm.rps; + u32 val = rps->idle_freq; int err; - if (dev_priv->rps.cur_freq <= val) + if (rps->cur_freq <= val) return; /* The punit delays the write of the frequency and voltage until it @@ -6224,27 +6230,29 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) void gen6_rps_busy(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + mutex_lock(&dev_priv->pcu_lock); - if (dev_priv->rps.enabled) { + if (rps->enabled) { u8 freq; if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) gen6_rps_reset_ei(dev_priv); I915_WRITE(GEN6_PMINTRMSK, - gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); + gen6_rps_pm_mask(dev_priv, rps->cur_freq)); gen6_enable_rps_interrupts(dev_priv); /* Use the user's desired frequency as a guide, but for better * performance, jump directly to RPe as our starting frequency. */ - freq = max(dev_priv->rps.cur_freq, - dev_priv->rps.efficient_freq); + freq = max(rps->cur_freq, + rps->efficient_freq); if (intel_set_rps(dev_priv, clamp(freq, - dev_priv->rps.min_freq_softlimit, - dev_priv->rps.max_freq_softlimit))) + rps->min_freq_softlimit, + rps->max_freq_softlimit))) DRM_DEBUG_DRIVER("Failed to set idle frequency\n"); } mutex_unlock(&dev_priv->pcu_lock); @@ -6252,6 +6260,8 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) void gen6_rps_idle(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* Flush our bottom-half so that it does not race with us * setting the idle frequency and so that it is bounded by * our rpm wakeref. And then disable the interrupts to stop any @@ -6260,12 +6270,12 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) gen6_disable_rps_interrupts(dev_priv); mutex_lock(&dev_priv->pcu_lock); - if (dev_priv->rps.enabled) { + if (rps->enabled) { if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) vlv_set_rps_idle(dev_priv); else - gen6_set_rps(dev_priv, dev_priv->rps.idle_freq); - dev_priv->rps.last_adj = 0; + gen6_set_rps(dev_priv, rps->idle_freq); + rps->last_adj = 0; I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0)); } @@ -6273,22 +6283,22 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) } void gen6_rps_boost(struct drm_i915_gem_request *rq, - struct intel_rps_client *rps) + struct intel_rps_client *rps_client) { - struct drm_i915_private *i915 = rq->i915; + struct intel_rps *rps = &rq->i915->gt_pm.rps; unsigned long flags; bool boost; /* This is intentionally racy! We peek at the state here, then * validate inside the RPS worker. */ - if (!i915->rps.enabled) + if (!rps->enabled) return; boost = false; spin_lock_irqsave(&rq->lock, flags); if (!rq->waitboost && !i915_gem_request_completed(rq)) { - atomic_inc(&i915->rps.num_waiters); + atomic_inc(&rps->num_waiters); rq->waitboost = true; boost = true; } @@ -6296,22 +6306,23 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq, if (!boost) return; - if (READ_ONCE(i915->rps.cur_freq) < i915->rps.boost_freq) - schedule_work(&i915->rps.work); + if (READ_ONCE(rps->cur_freq) < rps->boost_freq) + schedule_work(&rps->work); - atomic_inc(rps ? &rps->boosts : &i915->rps.boosts); + atomic_inc(rps_client ? &rps_client->boosts : &rps->boosts); } int intel_set_rps(struct drm_i915_private *dev_priv, u8 val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; int err; lockdep_assert_held(&dev_priv->pcu_lock); - GEM_BUG_ON(val > dev_priv->rps.max_freq); - GEM_BUG_ON(val < dev_priv->rps.min_freq); + GEM_BUG_ON(val > rps->max_freq); + GEM_BUG_ON(val < rps->min_freq); - if (!dev_priv->rps.enabled) { - dev_priv->rps.cur_freq = val; + if (!rps->enabled) { + rps->cur_freq = val; return 0; } @@ -6493,24 +6504,26 @@ int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6) static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* All of these values are in units of 50MHz */ /* static values from HW: RP0 > RP1 > RPn (min_freq) */ if (IS_GEN9_LP(dev_priv)) { u32 rp_state_cap = I915_READ(BXT_RP_STATE_CAP); - dev_priv->rps.rp0_freq = (rp_state_cap >> 16) & 0xff; - dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; - dev_priv->rps.min_freq = (rp_state_cap >> 0) & 0xff; + rps->rp0_freq = (rp_state_cap >> 16) & 0xff; + rps->rp1_freq = (rp_state_cap >> 8) & 0xff; + rps->min_freq = (rp_state_cap >> 0) & 0xff; } else { u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); - dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff; - dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; - dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff; + rps->rp0_freq = (rp_state_cap >> 0) & 0xff; + rps->rp1_freq = (rp_state_cap >> 8) & 0xff; + rps->min_freq = (rp_state_cap >> 16) & 0xff; } /* hw_max = RP0 until we check for overclocking */ - dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; + rps->max_freq = rps->rp0_freq; - dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; + rps->efficient_freq = rps->rp1_freq; if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) || IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { u32 ddcc_status = 0; @@ -6518,33 +6531,34 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv) if (sandybridge_pcode_read(dev_priv, HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, &ddcc_status) == 0) - dev_priv->rps.efficient_freq = + rps->efficient_freq = clamp_t(u8, ((ddcc_status >> 8) & 0xff), - dev_priv->rps.min_freq, - dev_priv->rps.max_freq); + rps->min_freq, + rps->max_freq); } if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { /* Store the frequency values in 16.66 MHZ units, which is * the natural hardware unit for SKL */ - dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER; - dev_priv->rps.rp1_freq *= GEN9_FREQ_SCALER; - dev_priv->rps.min_freq *= GEN9_FREQ_SCALER; - dev_priv->rps.max_freq *= GEN9_FREQ_SCALER; - dev_priv->rps.efficient_freq *= GEN9_FREQ_SCALER; + rps->rp0_freq *= GEN9_FREQ_SCALER; + rps->rp1_freq *= GEN9_FREQ_SCALER; + rps->min_freq *= GEN9_FREQ_SCALER; + rps->max_freq *= GEN9_FREQ_SCALER; + rps->efficient_freq *= GEN9_FREQ_SCALER; } } static void reset_rps(struct drm_i915_private *dev_priv, int (*set)(struct drm_i915_private *, u8)) { - u8 freq = dev_priv->rps.cur_freq; + struct intel_rps *rps = &dev_priv->gt_pm.rps; + u8 freq = rps->cur_freq; /* force a reset */ - dev_priv->rps.power = -1; - dev_priv->rps.cur_freq = -1; + rps->power = -1; + rps->cur_freq = -1; if (set(dev_priv, freq)) DRM_ERROR("Failed to reset RPS to initial values\n"); @@ -6557,7 +6571,7 @@ static void gen9_enable_rps(struct drm_i915_private *dev_priv) /* Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RC_VIDEO_FREQ, - GEN9_FREQUENCY(dev_priv->rps.rp1_freq)); + GEN9_FREQUENCY(dev_priv->gt_pm.rps.rp1_freq)); /* 1 second timeout*/ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, @@ -6670,20 +6684,22 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv) static void gen8_enable_rps(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); /* 1 Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RPNSWREQ, - HSW_FREQUENCY(dev_priv->rps.rp1_freq)); + HSW_FREQUENCY(rps->rp1_freq)); I915_WRITE(GEN6_RC_VIDEO_FREQ, - HSW_FREQUENCY(dev_priv->rps.rp1_freq)); + HSW_FREQUENCY(rps->rp1_freq)); /* NB: Docs say 1s, and 1000000 - which aren't equivalent */ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */ /* Docs recommend 900MHz, and 300 MHz respectively */ I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, - dev_priv->rps.max_freq_softlimit << 24 | - dev_priv->rps.min_freq_softlimit << 16); + rps->max_freq_softlimit << 24 | + rps->min_freq_softlimit << 16); I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/ @@ -6810,6 +6826,7 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv) static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; int min_freq = 15; unsigned int gpu_freq; unsigned int max_ia_freq, min_ring_freq; @@ -6840,11 +6857,11 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { /* Convert GT frequency to 50 HZ units */ - min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER; - max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER; + min_gpu_freq = rps->min_freq / GEN9_FREQ_SCALER; + max_gpu_freq = rps->max_freq / GEN9_FREQ_SCALER; } else { - min_gpu_freq = dev_priv->rps.min_freq; - max_gpu_freq = dev_priv->rps.max_freq; + min_gpu_freq = rps->min_freq; + max_gpu_freq = rps->max_freq; } /* @@ -7095,17 +7112,18 @@ static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv) static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv) { - dev_priv->rps.gpll_ref_freq = + dev_priv->gt_pm.rps.gpll_ref_freq = vlv_get_cck_clock(dev_priv, "GPLL ref", CCK_GPLL_CLOCK_CONTROL, dev_priv->czclk_freq); DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n", - dev_priv->rps.gpll_ref_freq); + dev_priv->gt_pm.rps.gpll_ref_freq); } static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 val; valleyview_setup_pctx(dev_priv); @@ -7127,30 +7145,31 @@ static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv) } DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); - dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv); - dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; + rps->max_freq = valleyview_rps_max_freq(dev_priv); + rps->rp0_freq = rps->max_freq; DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.max_freq), - dev_priv->rps.max_freq); + intel_gpu_freq(dev_priv, rps->max_freq), + rps->max_freq); - dev_priv->rps.efficient_freq = valleyview_rps_rpe_freq(dev_priv); + rps->efficient_freq = valleyview_rps_rpe_freq(dev_priv); DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), - dev_priv->rps.efficient_freq); + intel_gpu_freq(dev_priv, rps->efficient_freq), + rps->efficient_freq); - dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv); + rps->rp1_freq = valleyview_rps_guar_freq(dev_priv); DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), - dev_priv->rps.rp1_freq); + intel_gpu_freq(dev_priv, rps->rp1_freq), + rps->rp1_freq); - dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv); + rps->min_freq = valleyview_rps_min_freq(dev_priv); DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), - dev_priv->rps.min_freq); + intel_gpu_freq(dev_priv, rps->min_freq), + rps->min_freq); } static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; u32 val; cherryview_setup_pctx(dev_priv); @@ -7171,31 +7190,29 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv) } DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); - dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv); - dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; + rps->max_freq = cherryview_rps_max_freq(dev_priv); + rps->rp0_freq = rps->max_freq; DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.max_freq), - dev_priv->rps.max_freq); + intel_gpu_freq(dev_priv, rps->max_freq), + rps->max_freq); - dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv); + rps->efficient_freq = cherryview_rps_rpe_freq(dev_priv); DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), - dev_priv->rps.efficient_freq); + intel_gpu_freq(dev_priv, rps->efficient_freq), + rps->efficient_freq); - dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv); + rps->rp1_freq = cherryview_rps_guar_freq(dev_priv); DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), - dev_priv->rps.rp1_freq); + intel_gpu_freq(dev_priv, rps->rp1_freq), + rps->rp1_freq); - dev_priv->rps.min_freq = cherryview_rps_min_freq(dev_priv); + rps->min_freq = cherryview_rps_min_freq(dev_priv); DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", - intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), - dev_priv->rps.min_freq); + intel_gpu_freq(dev_priv, rps->min_freq), + rps->min_freq); - WARN_ONCE((dev_priv->rps.max_freq | - dev_priv->rps.efficient_freq | - dev_priv->rps.rp1_freq | - dev_priv->rps.min_freq) & 1, + WARN_ONCE((rps->max_freq | rps->efficient_freq | rps->rp1_freq | + rps->min_freq) & 1, "Odd GPU freq values\n"); } @@ -7584,7 +7601,7 @@ static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv) lockdep_assert_held(&mchdev_lock); - pxvid = I915_READ(PXVFREQ(dev_priv->rps.cur_freq)); + pxvid = I915_READ(PXVFREQ(dev_priv->gt_pm.rps.cur_freq)); pxvid = (pxvid >> 24) & 0x7f; ext_v = pvid_to_extvid(dev_priv, pxvid); @@ -7871,6 +7888,8 @@ static void intel_init_emon(struct drm_i915_private *dev_priv) void intel_init_gt_powersave(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* * RPM depends on RC6 to save restore the GT HW context, so make RC6 a * requirement. @@ -7892,16 +7911,16 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) gen6_init_rps_frequencies(dev_priv); /* Derive initial user preferences/limits from the hardware limits */ - dev_priv->rps.idle_freq = dev_priv->rps.min_freq; - dev_priv->rps.cur_freq = dev_priv->rps.idle_freq; + rps->idle_freq = rps->min_freq; + rps->cur_freq = rps->idle_freq; - dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; - dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; + rps->max_freq_softlimit = rps->max_freq; + rps->min_freq_softlimit = rps->min_freq; if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - dev_priv->rps.min_freq_softlimit = + rps->min_freq_softlimit = max_t(int, - dev_priv->rps.efficient_freq, + rps->efficient_freq, intel_freq_opcode(dev_priv, 450)); /* After setting max-softlimit, find the overclock max freq */ @@ -7912,14 +7931,14 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, ¶ms); if (params & BIT(31)) { /* OC supported */ DRM_DEBUG_DRIVER("Overclocking supported, max: %dMHz, overclock: %dMHz\n", - (dev_priv->rps.max_freq & 0xff) * 50, + (rps->max_freq & 0xff) * 50, (params & 0xff) * 50); - dev_priv->rps.max_freq = params & 0xff; + rps->max_freq = params & 0xff; } } /* Finally allow us to boost to max by default */ - dev_priv->rps.boost_freq = dev_priv->rps.max_freq; + rps->boost_freq = rps->max_freq; mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->drm.struct_mutex); @@ -7949,7 +7968,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) if (INTEL_GEN(dev_priv) < 6) return; - if (cancel_delayed_work_sync(&dev_priv->rps.autoenable_work)) + if (cancel_delayed_work_sync(&dev_priv->gt_pm.autoenable_work)) intel_runtime_pm_put(dev_priv); /* gen6_rps_idle() will be called later to disable interrupts */ @@ -7957,7 +7976,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) { - dev_priv->rps.enabled = true; /* force disabling */ + dev_priv->gt_pm.rps.enabled = true; /* force disabling */ intel_disable_gt_powersave(dev_priv); gen6_reset_rps_interrupts(dev_priv); @@ -7965,7 +7984,9 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) { - if (!READ_ONCE(dev_priv->rps.enabled)) + struct intel_rps *rps = &dev_priv->gt_pm.rps; + + if (!READ_ONCE(rps->enabled)) return; mutex_lock(&dev_priv->pcu_lock); @@ -7986,16 +8007,18 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) ironlake_disable_drps(dev_priv); } - dev_priv->rps.enabled = false; + rps->enabled = false; mutex_unlock(&dev_priv->pcu_lock); } void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* We shouldn't be disabling as we submit, so this should be less * racy than it appears! */ - if (READ_ONCE(dev_priv->rps.enabled)) + if (READ_ONCE(rps->enabled)) return; /* Powersaving is controlled by the host when inside a VM */ @@ -8028,24 +8051,26 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) intel_init_emon(dev_priv); } - WARN_ON(dev_priv->rps.max_freq < dev_priv->rps.min_freq); - WARN_ON(dev_priv->rps.idle_freq > dev_priv->rps.max_freq); + WARN_ON(rps->max_freq < rps->min_freq); + WARN_ON(rps->idle_freq > rps->max_freq); - WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq); - WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq); + WARN_ON(rps->efficient_freq < rps->min_freq); + WARN_ON(rps->efficient_freq > rps->max_freq); - dev_priv->rps.enabled = true; + rps->enabled = true; mutex_unlock(&dev_priv->pcu_lock); } static void __intel_autoenable_gt_powersave(struct work_struct *work) { struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), rps.autoenable_work.work); + container_of(work, + typeof(*dev_priv), + gt_pm.autoenable_work.work); struct intel_engine_cs *rcs; struct drm_i915_gem_request *req; - if (READ_ONCE(dev_priv->rps.enabled)) + if (READ_ONCE(dev_priv->gt_pm.rps.enabled)) goto out; rcs = dev_priv->engine[RCS]; @@ -8075,7 +8100,7 @@ out: void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) { - if (READ_ONCE(dev_priv->rps.enabled)) + if (READ_ONCE(dev_priv->gt_pm.rps.enabled)) return; if (IS_IRONLAKE_M(dev_priv)) { @@ -8095,7 +8120,7 @@ void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) * runtime resume it's necessary). */ if (queue_delayed_work(dev_priv->wq, - &dev_priv->rps.autoenable_work, + &dev_priv->gt_pm.autoenable_work, round_jiffies_up_relative(HZ))) intel_runtime_pm_get_noresume(dev_priv); } @@ -9289,31 +9314,39 @@ out: static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* * N = val - 0xb7 * Slow = Fast = GPLL ref * N */ - return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * (val - 0xb7), 1000); + return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * (val - 0xb7), 1000); } static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) { - return DIV_ROUND_CLOSEST(1000 * val, dev_priv->rps.gpll_ref_freq) + 0xb7; + struct intel_rps *rps = &dev_priv->gt_pm.rps; + + return DIV_ROUND_CLOSEST(1000 * val, rps->gpll_ref_freq) + 0xb7; } static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* * N = val / 2 * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2 */ - return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * val, 2 * 2 * 1000); + return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * val, 2 * 2 * 1000); } static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) { + struct intel_rps *rps = &dev_priv->gt_pm.rps; + /* CHV needs even values */ - return DIV_ROUND_CLOSEST(2 * 1000 * val, dev_priv->rps.gpll_ref_freq) * 2; + return DIV_ROUND_CLOSEST(2 * 1000 * val, rps->gpll_ref_freq) * 2; } int intel_gpu_freq(struct drm_i915_private *dev_priv, int val) @@ -9346,9 +9379,9 @@ void intel_pm_setup(struct drm_i915_private *dev_priv) { mutex_init(&dev_priv->pcu_lock); - INIT_DELAYED_WORK(&dev_priv->rps.autoenable_work, + INIT_DELAYED_WORK(&dev_priv->gt_pm.autoenable_work, __intel_autoenable_gt_powersave); - atomic_set(&dev_priv->rps.num_waiters, 0); + atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0); dev_priv->runtime_pm.suspended = false; atomic_set(&dev_priv->runtime_pm.wakeref_count, 0); -- cgit v1.2.3 From 771decb0b4d75b5cc1d7ddfbdf512bd8768d2793 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:07 +0100 Subject: drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled This function gives the status of RC6, whether disabled or if enabled then which state. intel_enable_rc6 will be used for enabling RC6 in the next patch. v2: Rebase. v3: Rebase. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Imre Deak Cc: Joonas Lahtinen Reviewed-by: Radoslaw Szwichtenberg #1 Reviewed-by: Ewelina Musial #1 Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-10-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-9-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_guc.c | 3 ++- drivers/gpu/drm/i915/intel_pm.c | 12 ++++++------ 5 files changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9b8a19149154..f3ac1f45e154 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2502,7 +2502,7 @@ static int intel_runtime_suspend(struct device *kdev) struct drm_i915_private *dev_priv = to_i915(dev); int ret; - if (WARN_ON_ONCE(!(dev_priv->gt_pm.rps.enabled && intel_enable_rc6()))) + if (WARN_ON_ONCE(!(dev_priv->gt_pm.rps.enabled && intel_rc6_enabled()))) return -ENODEV; if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 0a57f9867f7f..791759f632e1 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -49,7 +49,7 @@ static u32 calc_residency(struct drm_i915_private *dev_priv, static ssize_t show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6()); + return snprintf(buf, PAGE_SIZE, "%x\n", intel_rc6_enabled()); } static ssize_t diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 53acfc475e35..cdda0a84babe 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1903,7 +1903,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, struct intel_crtc_state *cstate); void intel_init_ipc(struct drm_i915_private *dev_priv); void intel_enable_ipc(struct drm_i915_private *dev_priv); -static inline int intel_enable_rc6(void) +static inline int intel_rc6_enabled(void) { return i915_modparams.enable_rc6; } diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c index bbe4c328e9fd..9e18c4fb9909 100644 --- a/drivers/gpu/drm/i915/intel_guc.c +++ b/drivers/gpu/drm/i915/intel_guc.c @@ -137,7 +137,8 @@ int intel_guc_sample_forcewake(struct intel_guc *guc) action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE; /* WaRsDisableCoarsePowerGating:skl,bxt */ - if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv)) + if (!intel_rc6_enabled() || + NEEDS_WaRsDisableCoarsePowerGating(dev_priv)) action[1] = 0; else /* bit 0 and 1 are for Render and Media domain separately */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9097489e1993..16f8afbbc5db 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6625,7 +6625,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25); /* 3a: Enable RC6 */ - if (intel_enable_rc6() & INTEL_RC6_ENABLE) + if (intel_rc6_enabled() & INTEL_RC6_ENABLE) rc6_mask = GEN6_RC_CTL_RC6_ENABLE; DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE)); I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ @@ -6671,7 +6671,7 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */ /* 3: Enable RC6 */ - if (intel_enable_rc6() & INTEL_RC6_ENABLE) + if (intel_rc6_enabled() & INTEL_RC6_ENABLE) rc6_mask = GEN6_RC_CTL_RC6_ENABLE; intel_print_rc6_info(dev_priv, rc6_mask); @@ -6766,7 +6766,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ /* Check if we are enabling RC6 */ - rc6_mode = intel_enable_rc6(); + rc6_mode = intel_rc6_enabled(); if (rc6_mode & INTEL_RC6_ENABLE) rc6_mask |= GEN6_RC_CTL_RC6_ENABLE; @@ -7268,7 +7268,7 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv) pcbr = I915_READ(VLV_PCBR); /* 3: Enable RC6 */ - if ((intel_enable_rc6() & INTEL_RC6_ENABLE) && + if ((intel_rc6_enabled() & INTEL_RC6_ENABLE) && (pcbr >> VLV_PCBR_ADDR_SHIFT)) rc6_mode = GEN7_RC_CTL_TO_MODE; @@ -7360,7 +7360,7 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv) VLV_MEDIA_RC6_COUNT_EN | VLV_RENDER_RC6_COUNT_EN)); - if (intel_enable_rc6() & INTEL_RC6_ENABLE) + if (intel_rc6_enabled() & INTEL_RC6_ENABLE) rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL; intel_print_rc6_info(dev_priv, rc6_mode); @@ -9437,7 +9437,7 @@ u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv, { u64 time_hw, units, div; - if (!intel_enable_rc6()) + if (!intel_rc6_enabled()) return 0; intel_runtime_pm_get(dev_priv); -- cgit v1.2.3 From 0870a2a4a3d0aab568ce5729bd99f43f96825f85 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:08 +0100 Subject: drm/i915: Create generic function to setup LLC ring frequency table Prepared intel_update_ring_freq function to setup ring frequency for applicable platforms determined by macro HAS_LLC. v2: Replaced NEEDS_RING_FREQ_UPDATE with HAS_LLC macro. (Chris) Added check while calling from intel_enable_gt_powersave. v3: s/intel_update_ring_freq/intel_enable_llc_pstate and created new placeholder function intel_disable_llc_pstate. (Chris) Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-11-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-10-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 16f8afbbc5db..238d405e2fb2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7982,6 +7982,13 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) gen6_reset_rps_interrupts(dev_priv); } +static inline void intel_disable_llc_pstate(struct drm_i915_private *i915) +{ + lockdep_assert_held(&i915->pcu_lock); + + /* Currently there is no HW configuration to be done to disable. */ +} + void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) { struct intel_rps *rps = &dev_priv->gt_pm.rps; @@ -8007,10 +8014,20 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) ironlake_disable_drps(dev_priv); } + if (HAS_LLC(dev_priv)) + intel_disable_llc_pstate(dev_priv); + rps->enabled = false; mutex_unlock(&dev_priv->pcu_lock); } +static inline void intel_enable_llc_pstate(struct drm_i915_private *i915) +{ + lockdep_assert_held(&i915->pcu_lock); + + gen6_update_ring_freq(i915); +} + void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) { struct intel_rps *rps = &dev_priv->gt_pm.rps; @@ -8036,21 +8053,20 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) } else if (INTEL_GEN(dev_priv) >= 9) { gen9_enable_rc6(dev_priv); gen9_enable_rps(dev_priv); - if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) - gen6_update_ring_freq(dev_priv); } else if (IS_BROADWELL(dev_priv)) { gen8_enable_rc6(dev_priv); gen8_enable_rps(dev_priv); - gen6_update_ring_freq(dev_priv); } else if (INTEL_GEN(dev_priv) >= 6) { gen6_enable_rc6(dev_priv); gen6_enable_rps(dev_priv); - gen6_update_ring_freq(dev_priv); } else if (IS_IRONLAKE_M(dev_priv)) { ironlake_enable_drps(dev_priv); intel_init_emon(dev_priv); } + if (HAS_LLC(dev_priv)) + intel_enable_llc_pstate(dev_priv); + WARN_ON(rps->max_freq < rps->min_freq); WARN_ON(rps->idle_freq > rps->max_freq); -- cgit v1.2.3 From fc77426a8d69d6a706378a53b18c882578af44e5 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:09 +0100 Subject: drm/i915: Create generic functions to control RC6, RPS Prepared generic functions intel_enable_rc6, intel_disable_rc6, intel_enable_rps and intel_disable_rps functions to setup RC6/RPS based on platforms. v2: Make intel_enable/disable_rc6/rps static. (Chris) v3: Added lockdep_assert_held(dev_priv->pcu_lock) in new generic functions. (Chris) Removed WARN_ON(&dev_priv->pcu_lock) from lower level functions as generic function now has lockdep_assert. Rebase. Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-12-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-11-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 116 ++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 238d405e2fb2..a4d431d3980a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6731,8 +6731,6 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) int rc6_mode; int ret; - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); - I915_WRITE(GEN6_RC_STATE, 0); /* Clear the DBG now so we don't confuse earlier errors */ @@ -6805,8 +6803,6 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) static void gen6_enable_rps(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); - /* Here begins a magic sequence of register writes to enable * auto-downclocking. * @@ -7227,8 +7223,6 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv) enum intel_engine_id id; u32 gtfifodbg, rc6_mode = 0, pcbr; - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); - gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV | GT_FIFO_FREE_ENTRIES_CHV); if (gtfifodbg) { @@ -7281,8 +7275,6 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv) { u32 val; - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); /* 1: Program defaults and thresholds for RPS*/ @@ -7327,8 +7319,6 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv) enum intel_engine_id id; u32 gtfifodbg, rc6_mode = 0; - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); - valleyview_check_pctx(dev_priv); gtfifodbg = I915_READ(GTFIFODBG); @@ -7374,8 +7364,6 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv) { u32 val; - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); @@ -7989,31 +7977,47 @@ static inline void intel_disable_llc_pstate(struct drm_i915_private *i915) /* Currently there is no HW configuration to be done to disable. */ } -void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) +static void intel_disable_rc6(struct drm_i915_private *dev_priv) { - struct intel_rps *rps = &dev_priv->gt_pm.rps; + lockdep_assert_held(&dev_priv->pcu_lock); - if (!READ_ONCE(rps->enabled)) - return; + if (INTEL_GEN(dev_priv) >= 9) + gen9_disable_rc6(dev_priv); + else if (IS_CHERRYVIEW(dev_priv)) + cherryview_disable_rc6(dev_priv); + else if (IS_VALLEYVIEW(dev_priv)) + valleyview_disable_rc6(dev_priv); + else if (INTEL_GEN(dev_priv) >= 6) + gen6_disable_rc6(dev_priv); +} - mutex_lock(&dev_priv->pcu_lock); +static void intel_disable_rps(struct drm_i915_private *dev_priv) +{ + lockdep_assert_held(&dev_priv->pcu_lock); - if (INTEL_GEN(dev_priv) >= 9) { - gen9_disable_rc6(dev_priv); + if (INTEL_GEN(dev_priv) >= 9) gen9_disable_rps(dev_priv); - } else if (IS_CHERRYVIEW(dev_priv)) { - cherryview_disable_rc6(dev_priv); + else if (IS_CHERRYVIEW(dev_priv)) cherryview_disable_rps(dev_priv); - } else if (IS_VALLEYVIEW(dev_priv)) { - valleyview_disable_rc6(dev_priv); + else if (IS_VALLEYVIEW(dev_priv)) valleyview_disable_rps(dev_priv); - } else if (INTEL_GEN(dev_priv) >= 6) { - gen6_disable_rc6(dev_priv); + else if (INTEL_GEN(dev_priv) >= 6) gen6_disable_rps(dev_priv); - } else if (IS_IRONLAKE_M(dev_priv)) { + else if (IS_IRONLAKE_M(dev_priv)) ironlake_disable_drps(dev_priv); - } +} + +void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) +{ + struct intel_rps *rps = &dev_priv->gt_pm.rps; + if (!READ_ONCE(rps->enabled)) + return; + + mutex_lock(&dev_priv->pcu_lock); + + intel_disable_rc6(dev_priv); + intel_disable_rps(dev_priv); if (HAS_LLC(dev_priv)) intel_disable_llc_pstate(dev_priv); @@ -8028,50 +8032,70 @@ static inline void intel_enable_llc_pstate(struct drm_i915_private *i915) gen6_update_ring_freq(i915); } -void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) +static void intel_enable_rc6(struct drm_i915_private *dev_priv) { - struct intel_rps *rps = &dev_priv->gt_pm.rps; + lockdep_assert_held(&dev_priv->pcu_lock); - /* We shouldn't be disabling as we submit, so this should be less - * racy than it appears! - */ - if (READ_ONCE(rps->enabled)) - return; + if (IS_CHERRYVIEW(dev_priv)) + cherryview_enable_rc6(dev_priv); + else if (IS_VALLEYVIEW(dev_priv)) + valleyview_enable_rc6(dev_priv); + else if (INTEL_GEN(dev_priv) >= 9) + gen9_enable_rc6(dev_priv); + else if (IS_BROADWELL(dev_priv)) + gen8_enable_rc6(dev_priv); + else if (INTEL_GEN(dev_priv) >= 6) + gen6_enable_rc6(dev_priv); +} - /* Powersaving is controlled by the host when inside a VM */ - if (intel_vgpu_active(dev_priv)) - return; +static void intel_enable_rps(struct drm_i915_private *dev_priv) +{ + struct intel_rps *rps = &dev_priv->gt_pm.rps; - mutex_lock(&dev_priv->pcu_lock); + lockdep_assert_held(&dev_priv->pcu_lock); if (IS_CHERRYVIEW(dev_priv)) { - cherryview_enable_rc6(dev_priv); cherryview_enable_rps(dev_priv); } else if (IS_VALLEYVIEW(dev_priv)) { - valleyview_enable_rc6(dev_priv); valleyview_enable_rps(dev_priv); } else if (INTEL_GEN(dev_priv) >= 9) { - gen9_enable_rc6(dev_priv); gen9_enable_rps(dev_priv); } else if (IS_BROADWELL(dev_priv)) { - gen8_enable_rc6(dev_priv); gen8_enable_rps(dev_priv); } else if (INTEL_GEN(dev_priv) >= 6) { - gen6_enable_rc6(dev_priv); gen6_enable_rps(dev_priv); } else if (IS_IRONLAKE_M(dev_priv)) { ironlake_enable_drps(dev_priv); intel_init_emon(dev_priv); } - if (HAS_LLC(dev_priv)) - intel_enable_llc_pstate(dev_priv); - WARN_ON(rps->max_freq < rps->min_freq); WARN_ON(rps->idle_freq > rps->max_freq); WARN_ON(rps->efficient_freq < rps->min_freq); WARN_ON(rps->efficient_freq > rps->max_freq); +} + +void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) +{ + struct intel_rps *rps = &dev_priv->gt_pm.rps; + + /* We shouldn't be disabling as we submit, so this should be less + * racy than it appears! + */ + if (READ_ONCE(rps->enabled)) + return; + + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev_priv)) + return; + + mutex_lock(&dev_priv->pcu_lock); + + intel_enable_rc6(dev_priv); + intel_enable_rps(dev_priv); + if (HAS_LLC(dev_priv)) + intel_enable_llc_pstate(dev_priv); rps->enabled = true; mutex_unlock(&dev_priv->pcu_lock); -- cgit v1.2.3 From 37d933fc1728e998d929d0ff5113dcb14ce31293 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Tue, 10 Oct 2017 22:30:10 +0100 Subject: drm/i915: Introduce separate status variable for RC6 and LLC ring frequency setup Defined new struct intel_rc6 to hold RC6 specific state and intel_ring_pstate to hold ring specific state. v2: s/intel_ring_pstate/intel_llc_pstate. Removed checks from autoenable_* functions. (Chris) Signed-off-by: Sagar Arun Kamble Cc: Imre Deak Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-13-git-send-email-sagar.a.kamble@intel.com Acked-by: Imre Deak Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-12-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 10 ++++++++ drivers/gpu/drm/i915/intel_pm.c | 54 ++++++++++++++++++++++++----------------- 3 files changed, 43 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f3ac1f45e154..f1e651703764 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2502,7 +2502,7 @@ static int intel_runtime_suspend(struct device *kdev) struct drm_i915_private *dev_priv = to_i915(dev); int ret; - if (WARN_ON_ONCE(!(dev_priv->gt_pm.rps.enabled && intel_rc6_enabled()))) + if (WARN_ON_ONCE(!(dev_priv->gt_pm.rc6.enabled && intel_rc6_enabled()))) return -ENODEV; if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 521348ee7242..6bbc4b83aa0a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1365,8 +1365,18 @@ struct intel_rps { struct intel_rps_ei ei; }; +struct intel_rc6 { + bool enabled; +}; + +struct intel_llc_pstate { + bool enabled; +}; + struct intel_gen6_power_mgmt { struct intel_rps rps; + struct intel_rc6 rc6; + struct intel_llc_pstate llc_pstate; struct delayed_work autoenable_work; }; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a4d431d3980a..2fcff9788b6f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7964,7 +7964,8 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) { - dev_priv->gt_pm.rps.enabled = true; /* force disabling */ + dev_priv->gt_pm.rps.enabled = true; /* force RPS disabling */ + dev_priv->gt_pm.rc6.enabled = true; /* force RC6 disabling */ intel_disable_gt_powersave(dev_priv); gen6_reset_rps_interrupts(dev_priv); @@ -7974,13 +7975,21 @@ static inline void intel_disable_llc_pstate(struct drm_i915_private *i915) { lockdep_assert_held(&i915->pcu_lock); + if (!i915->gt_pm.llc_pstate.enabled) + return; + /* Currently there is no HW configuration to be done to disable. */ + + i915->gt_pm.llc_pstate.enabled = false; } static void intel_disable_rc6(struct drm_i915_private *dev_priv) { lockdep_assert_held(&dev_priv->pcu_lock); + if (!dev_priv->gt_pm.rc6.enabled) + return; + if (INTEL_GEN(dev_priv) >= 9) gen9_disable_rc6(dev_priv); else if (IS_CHERRYVIEW(dev_priv)) @@ -7989,12 +7998,17 @@ static void intel_disable_rc6(struct drm_i915_private *dev_priv) valleyview_disable_rc6(dev_priv); else if (INTEL_GEN(dev_priv) >= 6) gen6_disable_rc6(dev_priv); + + dev_priv->gt_pm.rc6.enabled = false; } static void intel_disable_rps(struct drm_i915_private *dev_priv) { lockdep_assert_held(&dev_priv->pcu_lock); + if (!dev_priv->gt_pm.rps.enabled) + return; + if (INTEL_GEN(dev_priv) >= 9) gen9_disable_rps(dev_priv); else if (IS_CHERRYVIEW(dev_priv)) @@ -8005,15 +8019,12 @@ static void intel_disable_rps(struct drm_i915_private *dev_priv) gen6_disable_rps(dev_priv); else if (IS_IRONLAKE_M(dev_priv)) ironlake_disable_drps(dev_priv); + + dev_priv->gt_pm.rps.enabled = false; } void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) { - struct intel_rps *rps = &dev_priv->gt_pm.rps; - - if (!READ_ONCE(rps->enabled)) - return; - mutex_lock(&dev_priv->pcu_lock); intel_disable_rc6(dev_priv); @@ -8021,7 +8032,6 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) if (HAS_LLC(dev_priv)) intel_disable_llc_pstate(dev_priv); - rps->enabled = false; mutex_unlock(&dev_priv->pcu_lock); } @@ -8029,13 +8039,21 @@ static inline void intel_enable_llc_pstate(struct drm_i915_private *i915) { lockdep_assert_held(&i915->pcu_lock); + if (i915->gt_pm.llc_pstate.enabled) + return; + gen6_update_ring_freq(i915); + + i915->gt_pm.llc_pstate.enabled = true; } static void intel_enable_rc6(struct drm_i915_private *dev_priv) { lockdep_assert_held(&dev_priv->pcu_lock); + if (dev_priv->gt_pm.rc6.enabled) + return; + if (IS_CHERRYVIEW(dev_priv)) cherryview_enable_rc6(dev_priv); else if (IS_VALLEYVIEW(dev_priv)) @@ -8046,6 +8064,8 @@ static void intel_enable_rc6(struct drm_i915_private *dev_priv) gen8_enable_rc6(dev_priv); else if (INTEL_GEN(dev_priv) >= 6) gen6_enable_rc6(dev_priv); + + dev_priv->gt_pm.rc6.enabled = true; } static void intel_enable_rps(struct drm_i915_private *dev_priv) @@ -8054,6 +8074,9 @@ static void intel_enable_rps(struct drm_i915_private *dev_priv) lockdep_assert_held(&dev_priv->pcu_lock); + if (rps->enabled) + return; + if (IS_CHERRYVIEW(dev_priv)) { cherryview_enable_rps(dev_priv); } else if (IS_VALLEYVIEW(dev_priv)) { @@ -8074,18 +8097,12 @@ static void intel_enable_rps(struct drm_i915_private *dev_priv) WARN_ON(rps->efficient_freq < rps->min_freq); WARN_ON(rps->efficient_freq > rps->max_freq); + + rps->enabled = true; } void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) { - struct intel_rps *rps = &dev_priv->gt_pm.rps; - - /* We shouldn't be disabling as we submit, so this should be less - * racy than it appears! - */ - if (READ_ONCE(rps->enabled)) - return; - /* Powersaving is controlled by the host when inside a VM */ if (intel_vgpu_active(dev_priv)) return; @@ -8097,7 +8114,6 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) if (HAS_LLC(dev_priv)) intel_enable_llc_pstate(dev_priv); - rps->enabled = true; mutex_unlock(&dev_priv->pcu_lock); } @@ -8110,9 +8126,6 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work) struct intel_engine_cs *rcs; struct drm_i915_gem_request *req; - if (READ_ONCE(dev_priv->gt_pm.rps.enabled)) - goto out; - rcs = dev_priv->engine[RCS]; if (rcs->last_retired_context) goto out; @@ -8140,9 +8153,6 @@ out: void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) { - if (READ_ONCE(dev_priv->gt_pm.rps.enabled)) - return; - if (IS_IRONLAKE_M(dev_priv)) { ironlake_enable_drps(dev_priv); intel_init_emon(dev_priv); -- cgit v1.2.3 From cda77556447c782b3c9c068f81ef58136cb487c3 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 10 Oct 2017 15:13:55 +0200 Subject: gpu: ipu-v3: Allow channel burst locking on i.MX6 only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IDMAC_LOCK_EN registers on i.MX51 have a different layout, and on i.MX53 enabling the lock feature causes bursts to get lost. Restrict enabling the burst lock feature to i.MX6. Reported-by: Patrick Brünn Fixes: 790cb4c7c954 ("drm/imx: lock scanout transfers for consecutive bursts") Tested-by: Patrick Brünn Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-common.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 6a573d21d3cc..658fa2d3e40c 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -405,6 +405,14 @@ int ipu_idmac_lock_enable(struct ipuv3_channel *channel, int num_bursts) return -EINVAL; } + /* + * IPUv3EX / i.MX51 has a different register layout, and on IPUv3M / + * i.MX53 channel arbitration locking doesn't seem to work properly. + * Allow enabling the lock feature on IPUv3H / i.MX6 only. + */ + if (bursts && ipu->ipu_type != IPUV3H) + return -EINVAL; + for (i = 0; i < ARRAY_SIZE(idmac_lock_en_info); i++) { if (channel->num == idmac_lock_en_info[i].chnum) break; -- cgit v1.2.3 From 263c3b8044f9c9356a34fdb2640b52d27e378f9c Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 24 Mar 2017 18:01:53 +0100 Subject: gpu: ipu-v3: prg: wait for double buffers to be filled on channel startup Wait for both double buffer to be filled when first starting a channel. This makes channel startup a lot more reliable, probably because it allows the internal state machine to settle before the requests from the IPU are coming in. Signed-off-by: Lucas Stach [p.zabel@pengutronix.de: rebased before switch to runtime PM] Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-prg.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c index ecc9ea44dc50..0013ca9f72c8 100644 --- a/drivers/gpu/ipu-v3/ipu-prg.c +++ b/drivers/gpu/ipu-v3/ipu-prg.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -329,6 +330,12 @@ int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan, val = IPU_PRG_REG_UPDATE_REG_UPDATE; writel(val, prg->regs + IPU_PRG_REG_UPDATE); + /* wait for both double buffers to be filled */ + readl_poll_timeout(prg->regs + IPU_PRG_STATUS, val, + (val & IPU_PRG_STATUS_BUFFER0_READY(prg_chan)) && + (val & IPU_PRG_STATUS_BUFFER1_READY(prg_chan)), + 5, 1000); + clk_disable_unprepare(prg->clk_ipg); chan->enabled = true; -- cgit v1.2.3 From 11aff4b4c7c4b7257660ef890920f2ac72911ed0 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 18 Sep 2017 17:45:07 +0200 Subject: gpu: ipu-v3: pre: implement workaround for ERR009624 The PRE has a bug where a software write to the CTRL register can block the setting of the ENABLE bit by the hardware in auto repeat mode. When this happens the PRE will fail to handle new jobs. To work around this software must not write to CTRL register when the PRE store engine is inside the unsafe window, where a hardware update to the ENABLE bit may happen. Signed-off-by: Lucas Stach [p.zabel@pengutronix.de: rebased before PRE tiled prefetch support] Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-pre.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c index c35f74c83065..c860a7997cb5 100644 --- a/drivers/gpu/ipu-v3/ipu-pre.c +++ b/drivers/gpu/ipu-v3/ipu-pre.c @@ -73,6 +73,14 @@ #define IPU_PRE_STORE_ENG_CTRL_WR_NUM_BYTES(v) ((v & 0x7) << 1) #define IPU_PRE_STORE_ENG_CTRL_OUTPUT_ACTIVE_BPP(v) ((v & 0x3) << 4) +#define IPU_PRE_STORE_ENG_STATUS 0x120 +#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_X_MASK 0xffff +#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_X_SHIFT 0 +#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_MASK 0x3fff +#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_SHIFT 16 +#define IPU_PRE_STORE_ENG_STATUS_STORE_FIFO_FULL (1 << 30) +#define IPU_PRE_STORE_ENG_STATUS_STORE_FIELD (1 << 31) + #define IPU_PRE_STORE_ENG_SIZE 0x130 #define IPU_PRE_STORE_ENG_SIZE_INPUT_WIDTH(v) ((v & 0xffff) << 0) #define IPU_PRE_STORE_ENG_SIZE_INPUT_HEIGHT(v) ((v & 0xffff) << 16) @@ -93,6 +101,7 @@ struct ipu_pre { dma_addr_t buffer_paddr; void *buffer_virt; bool in_use; + unsigned int safe_window_end; }; static DEFINE_MUTEX(ipu_pre_list_mutex); @@ -160,6 +169,9 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width, u32 active_bpp = info->cpp[0] >> 1; u32 val; + /* calculate safe window for ctrl register updates */ + pre->safe_window_end = height - 2; + writel(bufaddr, pre->regs + IPU_PRE_CUR_BUF); writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); @@ -199,7 +211,24 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width, void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr) { + unsigned long timeout = jiffies + msecs_to_jiffies(5); + unsigned short current_yblock; + u32 val; + writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); + + do { + if (time_after(jiffies, timeout)) { + dev_warn(pre->dev, "timeout waiting for PRE safe window\n"); + return; + } + + val = readl(pre->regs + IPU_PRE_STORE_ENG_STATUS); + current_yblock = + (val >> IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_SHIFT) & + IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_MASK; + } while (current_yblock == 0 || current_yblock >= pre->safe_window_end); + writel(IPU_PRE_CTRL_SDW_UPDATE, pre->regs + IPU_PRE_CTRL_SET); } -- cgit v1.2.3 From 203f44c475a1a8ace6d30c4c14ab41295081a23f Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Mon, 2 Oct 2017 12:22:53 +0100 Subject: usb: phy: tegra: Fix phy suspend for UDC Commit dfebb5f43a78 ("usb: chipidea: Add support for Tegra20/30/114/124") added UDC support for Tegra but with UDC support enabled, is was found that Tegra30, Tegra114 and Tegra124 would hang on entry to suspend. The hang occurred during the suspend of the USB PHY when the Tegra PHY driver attempted to disable the PHY clock. The problem is that before the Tegra PHY driver is suspended, the chipidea driver already disabled the PHY clock and when the Tegra PHY driver suspended, it could not read DEVLC register and caused the device to hang. The Tegra USB PHY driver is used by both the Tegra EHCI driver and now the chipidea UDC driver and so simply removing the disabling of the PHY clock from the USB PHY driver would not work for the Tegra EHCI driver. Fortunately, the status of the USB PHY clock can be read from the USB_SUSP_CTRL register and therefore, to workaround this issue, simply poll the register prior to disabling the clock in USB PHY driver to see if clock gating has already been initiated. Please note that it can take a few uS for the clock to disable and so simply reading this status register once on entry is not sufficient. Similarly when turning on the PHY clock, it is possible that the clock is already enabled or in the process of being enabled, and so check for this when enabling the PHY. Please note that no issues are seen with Tegra20 because it has a slightly different PHY to Tegra30/114/124. Fixes: dfebb5f43a78 ("usb: chipidea: Add support for Tegra20/30/114/124") Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Acked-by: Thierry Reding Signed-off-by: Jon Hunter Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-tegra-usb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 5fe4a5704bde..ccc2bf5274b4 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) unsigned long val; void __iomem *base = phy->regs; + /* + * The USB driver may have already initiated the phy clock + * disable so wait to see if the clock turns off and if not + * then proceed with gating the clock. + */ + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) == 0) + return; + if (phy->is_legacy_phy) { val = readl(base + USB_SUSP_CTRL); val |= USB_SUSP_SET; @@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) unsigned long val; void __iomem *base = phy->regs; + /* + * The USB driver may have already initiated the phy clock + * enable so wait to see if the clock turns on and if not + * then proceed with ungating the clock. + */ + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID) == 0) + return; + if (phy->is_legacy_phy) { val = readl(base + USB_SUSP_CTRL); val |= USB_SUSP_CLR; -- cgit v1.2.3 From ab219221a5064abfff9f78c323c4a257b16cdb81 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 6 Oct 2017 10:27:44 -0400 Subject: USB: dummy-hcd: Fix deadlock caused by disconnect detection The dummy-hcd driver calls the gadget driver's disconnect callback under the wrong conditions. It should invoke the callback when Vbus power is turned off, but instead it does so when the D+ pullup is turned off. This can cause a deadlock in the composite core when a gadget driver is unregistered: [ 88.361471] ============================================ [ 88.362014] WARNING: possible recursive locking detected [ 88.362580] 4.14.0-rc2+ #9 Not tainted [ 88.363010] -------------------------------------------- [ 88.363561] v4l_id/526 is trying to acquire lock: [ 88.364062] (&(&cdev->lock)->rlock){....}, at: [] composite_disconnect+0x43/0x100 [libcomposite] [ 88.365051] [ 88.365051] but task is already holding lock: [ 88.365826] (&(&cdev->lock)->rlock){....}, at: [] usb_function_deactivate+0x29/0x80 [libcomposite] [ 88.366858] [ 88.366858] other info that might help us debug this: [ 88.368301] Possible unsafe locking scenario: [ 88.368301] [ 88.369304] CPU0 [ 88.369701] ---- [ 88.370101] lock(&(&cdev->lock)->rlock); [ 88.370623] lock(&(&cdev->lock)->rlock); [ 88.371145] [ 88.371145] *** DEADLOCK *** [ 88.371145] [ 88.372211] May be due to missing lock nesting notation [ 88.372211] [ 88.373191] 2 locks held by v4l_id/526: [ 88.373715] #0: (&(&cdev->lock)->rlock){....}, at: [] usb_function_deactivate+0x29/0x80 [libcomposite] [ 88.374814] #1: (&(&dum_hcd->dum->lock)->rlock){....}, at: [] dummy_pullup+0x7d/0xf0 [dummy_hcd] [ 88.376289] [ 88.376289] stack backtrace: [ 88.377726] CPU: 0 PID: 526 Comm: v4l_id Not tainted 4.14.0-rc2+ #9 [ 88.378557] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 [ 88.379504] Call Trace: [ 88.380019] dump_stack+0x86/0xc7 [ 88.380605] __lock_acquire+0x841/0x1120 [ 88.381252] lock_acquire+0xd5/0x1c0 [ 88.381865] ? composite_disconnect+0x43/0x100 [libcomposite] [ 88.382668] _raw_spin_lock_irqsave+0x40/0x54 [ 88.383357] ? composite_disconnect+0x43/0x100 [libcomposite] [ 88.384290] composite_disconnect+0x43/0x100 [libcomposite] [ 88.385490] set_link_state+0x2d4/0x3c0 [dummy_hcd] [ 88.386436] dummy_pullup+0xa7/0xf0 [dummy_hcd] [ 88.387195] usb_gadget_disconnect+0xd8/0x160 [udc_core] [ 88.387990] usb_gadget_deactivate+0xd3/0x160 [udc_core] [ 88.388793] usb_function_deactivate+0x64/0x80 [libcomposite] [ 88.389628] uvc_function_disconnect+0x1e/0x40 [usb_f_uvc] This patch changes the code to test the port-power status bit rather than the port-connect status bit when deciding whether to isue the callback. Signed-off-by: Alan Stern Reported-by: David Tulloh CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index b17618a55f1b..f04e91ef9e7c 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -419,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) static void set_link_state(struct dummy_hcd *dum_hcd) { struct dummy *dum = dum_hcd->dum; + unsigned int power_bit; dum_hcd->active = 0; if (dum->pullup) @@ -429,17 +430,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd) return; set_link_state_by_speed(dum_hcd); + power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ? + USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER); if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || dum_hcd->active) dum_hcd->resuming = 0; /* Currently !connected or in reset */ - if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || + if ((dum_hcd->port_status & power_bit) == 0 || (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { - unsigned disconnect = USB_PORT_STAT_CONNECTION & + unsigned int disconnect = power_bit & dum_hcd->old_status & (~dum_hcd->port_status); - unsigned reset = USB_PORT_STAT_RESET & + unsigned int reset = USB_PORT_STAT_RESET & (~dum_hcd->old_status) & dum_hcd->port_status; /* Report reset and disconnect events to the driver */ -- cgit v1.2.3 From 29c7f3e68eec4ae94d85ad7b5dfdafdb8089f513 Mon Sep 17 00:00:00 2001 From: Kazuya Mizuguchi Date: Mon, 2 Oct 2017 14:01:41 +0900 Subject: usb: renesas_usbhs: Fix DMAC sequence for receiving zero-length packet The DREQE bit of the DnFIFOSEL should be set to 1 after the DE bit of USB-DMAC on R-Car SoCs is set to 1 after the USB-DMAC received a zero-length packet. Otherwise, a transfer completion interruption of USB-DMAC doesn't happen. Even if the driver changes the sequence, normal operations (transmit/receive without zero-length packet) will not cause any side-effects. So, this patch fixes the sequence anyway. Signed-off-by: Kazuya Mizuguchi [shimoda: revise the commit log] Fixes: e73a9891b3a1 ("usb: renesas_usbhs: add DMAEngine support") Cc: # v3.1+ Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 68f26904c316..50285b01da92 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -857,9 +857,9 @@ static void xfer_work(struct work_struct *work) fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); usbhs_pipe_running(pipe, 1); - usbhsf_dma_start(pipe, fifo); usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); dma_async_issue_pending(chan); + usbhsf_dma_start(pipe, fifo); usbhs_pipe_enable(pipe); xfer_work_end: -- cgit v1.2.3 From cb84f56861eb333af0a5bab475d741b13067c05c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 30 Sep 2017 11:15:29 +0300 Subject: usb: misc: usbtest: Fix overflow in usbtest_do_ioctl() There used to be a test against "if (param->sglen > MAX_SGLEN)" but it was removed during a refactor. It leads to an integer overflow and a stack overflow in test_queue() if we try to create a too large urbs[] array on the stack. There is a second integer overflow in test_queue() as well if "param->iterations" is too high. I don't immediately see that it's harmful but I've added a check to prevent it and silence the static checker warning. Fixes: 18fc4ebdc705 ("usb: misc: usbtest: Remove timeval usage") Acked-by: Deepa Dinamani Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index eee82ca55b7b..113e38bfe0ef 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1964,6 +1964,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param, int status = 0; struct urb *urbs[param->sglen]; + if (!param->sglen || param->iterations > UINT_MAX / param->sglen) + return -EINVAL; + memset(&context, 0, sizeof(context)); context.count = param->iterations * param->sglen; context.dev = dev; @@ -2087,6 +2090,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param) if (param->iterations <= 0) return -EINVAL; + if (param->sglen > MAX_SGLEN) + return -EINVAL; /* * Just a bunch of test cases that every HCD is expected to handle. * -- cgit v1.2.3 From aec17e1e249567e82b26dafbb86de7d07fde8729 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Sat, 30 Sep 2017 08:55:55 -0700 Subject: usb: gadget: composite: Fix use-after-free in usb_composite_overwrite_options KASAN enabled configuration reports an error BUG: KASAN: use-after-free in usb_composite_overwrite_options+... [libcomposite] at addr ... Read of size 1 by task ... when some driver is un-bound and then bound again. For example, this happens with FunctionFS driver when "ffs-test" test application is run several times in a row. If the driver has empty manufacturer ID string in initial static data, it is then replaced with generated string. After driver unbinding the generated string is freed, but the driver data still keep that pointer. And if the driver is then bound again, that pointer is re-used for string emptiness check. The fix is to clean up the driver string data upon its unbinding to drop the pointer to freed memory. Fixes: cc2683c318a5 ("usb: gadget: Provide a default implementation of default manufacturer string") Cc: stable@vger.kernel.org Signed-off-by: Andrew Gabbasov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index dd74c99d6ce1..5d061b3d8224 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended); static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) { struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_gadget_strings *gstr = cdev->driver->strings[0]; + struct usb_string *dev_str = gstr->strings; /* composite_disconnect() must already have been called * by the underlying peripheral controller driver! @@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) composite_dev_cleanup(cdev); + if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) + dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; + kfree(cdev->def_manufacturer); kfree(cdev); set_gadget_data(gadget, NULL); -- cgit v1.2.3 From ff74745e6d3d97a865eda8c1f3fd29c13b79f0cc Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Sat, 30 Sep 2017 08:54:52 -0700 Subject: usb: gadget: configfs: Fix memory leak of interface directory data Kmemleak checking configuration reports a memory leak in usb_os_desc_prepare_interf_dir function when rndis function instance is freed and then allocated again. For example, this happens with FunctionFS driver with RNDIS function enabled when "ffs-test" test application is run several times in a row. The data for intermediate "os_desc" group for interface directories is allocated as a single VLA chunk and (after a change of default groups handling) is not ever freed and actually not stored anywhere besides inside a list of default groups of a parent group. The fix is to make usb_os_desc_prepare_interf_dir function return a pointer to allocated data (as a pointer to the first VLA item) instead of (an unused) integer and to make the caller component (currently the only one is RNDIS function) responsible for storing the pointer and freeing the memory when appropriate. Fixes: 1ae1602de028 ("configfs: switch ->default groups to a linked list") Cc: stable@vger.kernel.org Signed-off-by: Andrew Gabbasov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 15 ++++++++------- drivers/usb/gadget/configfs.h | 11 ++++++----- drivers/usb/gadget/function/f_rndis.c | 12 ++++++++++-- drivers/usb/gadget/function/u_rndis.h | 1 + 4 files changed, 25 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index a22a892de7b7..aeb9f3c40521 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1143,11 +1143,12 @@ static struct configfs_attribute *interf_grp_attrs[] = { NULL }; -int usb_os_desc_prepare_interf_dir(struct config_group *parent, - int n_interf, - struct usb_os_desc **desc, - char **names, - struct module *owner) +struct config_group *usb_os_desc_prepare_interf_dir( + struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + char **names, + struct module *owner) { struct config_group *os_desc_group; struct config_item_type *os_desc_type, *interface_type; @@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); if (!vlabuf) - return -ENOMEM; + return ERR_PTR(-ENOMEM); os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); @@ -1184,7 +1185,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, configfs_add_default_group(&d->group, os_desc_group); } - return 0; + return os_desc_group; } EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h index 36c468c4f5e9..540d5e92ed22 100644 --- a/drivers/usb/gadget/configfs.h +++ b/drivers/usb/gadget/configfs.h @@ -5,11 +5,12 @@ void unregister_gadget_item(struct config_item *item); -int usb_os_desc_prepare_interf_dir(struct config_group *parent, - int n_interf, - struct usb_os_desc **desc, - char **names, - struct module *owner); +struct config_group *usb_os_desc_prepare_interf_dir( + struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + char **names, + struct module *owner); static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) { diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index e1d5853ef1e4..c7c5b3ce1d98 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f) free_netdev(opts->net); } + kfree(opts->rndis_interf_group); /* single VLA chunk */ kfree(opts); } @@ -916,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) struct f_rndis_opts *opts; struct usb_os_desc *descs[1]; char *names[1]; + struct config_group *rndis_interf_group; opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) @@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void) names[0] = "rndis"; config_group_init_type_name(&opts->func_inst.group, "", &rndis_func_type); - usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, - names, THIS_MODULE); + rndis_interf_group = + usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, + names, THIS_MODULE); + if (IS_ERR(rndis_interf_group)) { + rndis_free_inst(&opts->func_inst); + return ERR_CAST(rndis_interf_group); + } + opts->rndis_interf_group = rndis_interf_group; return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h index a35ee3c2545d..efdb7ac381d9 100644 --- a/drivers/usb/gadget/function/u_rndis.h +++ b/drivers/usb/gadget/function/u_rndis.h @@ -26,6 +26,7 @@ struct f_rndis_opts { bool bound; bool borrowed_net; + struct config_group *rndis_interf_group; struct usb_os_desc rndis_os_desc; char rndis_ext_compat_id[16]; -- cgit v1.2.3 From 7c80f9e4a588f1925b07134bb2e3689335f6c6d8 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 29 Sep 2017 10:54:24 -0400 Subject: usb: usbtest: fix NULL pointer dereference If the usbtest driver encounters a device with an IN bulk endpoint but no OUT bulk endpoint, it will try to dereference a NULL pointer (out->desc.bEndpointAddress). The problem can be solved by adding a missing test. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 113e38bfe0ef..b3fc602b2e24 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -202,12 +202,13 @@ found: return tmp; } - if (in) { + if (in) dev->in_pipe = usb_rcvbulkpipe(udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + if (out) dev->out_pipe = usb_sndbulkpipe(udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - } + if (iso_in) { dev->iso_in = &iso_in->desc; dev->in_iso_pipe = usb_rcvisocpipe(udev, -- cgit v1.2.3 From f043bfc98c193c284e2cd768fefabe18ac2fed9b Mon Sep 17 00:00:00 2001 From: Jaejoong Kim Date: Thu, 28 Sep 2017 19:16:30 +0900 Subject: HID: usbhid: fix out-of-bounds bug The hid descriptor identifies the length and type of subordinate descriptors for a device. If the received hid descriptor is smaller than the size of the struct hid_descriptor, it is possible to cause out-of-bounds. In addition, if bNumDescriptors of the hid descriptor have an incorrect value, this can also cause out-of-bounds while approaching hdesc->desc[n]. So check the size of hid descriptor and bNumDescriptors. BUG: KASAN: slab-out-of-bounds in usbhid_parse+0x9b1/0xa20 Read of size 1 at addr ffff88006c5f8edf by task kworker/1:2/1261 CPU: 1 PID: 1261 Comm: kworker/1:2 Not tainted 4.14.0-rc1-42251-gebb2c2437d80 #169 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Workqueue: usb_hub_wq hub_event Call Trace: __dump_stack lib/dump_stack.c:16 dump_stack+0x292/0x395 lib/dump_stack.c:52 print_address_description+0x78/0x280 mm/kasan/report.c:252 kasan_report_error mm/kasan/report.c:351 kasan_report+0x22f/0x340 mm/kasan/report.c:409 __asan_report_load1_noabort+0x19/0x20 mm/kasan/report.c:427 usbhid_parse+0x9b1/0xa20 drivers/hid/usbhid/hid-core.c:1004 hid_add_device+0x16b/0xb30 drivers/hid/hid-core.c:2944 usbhid_probe+0xc28/0x1100 drivers/hid/usbhid/hid-core.c:1369 usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361 really_probe drivers/base/dd.c:413 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523 device_add+0xd0b/0x1660 drivers/base/core.c:1835 usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266 really_probe drivers/base/dd.c:413 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523 device_add+0xd0b/0x1660 drivers/base/core.c:1835 usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457 hub_port_connect drivers/usb/core/hub.c:4903 hub_port_connect_change drivers/usb/core/hub.c:5009 port_event drivers/usb/core/hub.c:5115 hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119 worker_thread+0x221/0x1850 kernel/workqueue.c:2253 kthread+0x3a1/0x470 kernel/kthread.c:231 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 Cc: stable@vger.kernel.org Reported-by: Andrey Konovalov Signed-off-by: Jaejoong Kim Tested-by: Andrey Konovalov Acked-by: Alan Stern Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 089bad8a9a21..045b5da9b992 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -975,6 +975,8 @@ static int usbhid_parse(struct hid_device *hid) unsigned int rsize = 0; char *rdesc; int ret, n; + int num_descriptors; + size_t offset = offsetof(struct hid_descriptor, desc); quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); @@ -997,10 +999,18 @@ static int usbhid_parse(struct hid_device *hid) return -ENODEV; } + if (hdesc->bLength < sizeof(struct hid_descriptor)) { + dbg_hid("hid descriptor is too short\n"); + return -EINVAL; + } + hid->version = le16_to_cpu(hdesc->bcdHID); hid->country = hdesc->bCountryCode; - for (n = 0; n < hdesc->bNumDescriptors; n++) + num_descriptors = min_t(int, hdesc->bNumDescriptors, + (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor)); + + for (n = 0; n < num_descriptors; n++) if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); -- cgit v1.2.3 From a0933a456ff83a3b5ffa3a1903e0b8de4a56adf5 Mon Sep 17 00:00:00 2001 From: Alex Manoussakis Date: Thu, 5 Oct 2017 13:41:20 -0400 Subject: HID: hid-elecom: extend to fix descriptor for HUGE trackball In addition to DEFT, Elecom introduced a larger trackball called HUGE, in both wired (M-HT1URBK) and wireless (M-HT1DRBK) versions. It has the same buttons and behavior as the DEFT. This patch adds the two relevant USB IDs to enable operation of the three Fn buttons on the top of the device. Cc: Diego Elio Petteno Signed-off-by: Alex Manoussakis Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + drivers/hid/hid-core.c | 2 ++ drivers/hid/hid-elecom.c | 13 +++++++++---- drivers/hid/hid-ids.h | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 0a3117cc29e7..374301fcbc86 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -281,6 +281,7 @@ config HID_ELECOM Support for ELECOM devices: - BM084 Bluetooth Mouse - DEFT Trackball (Wired and wireless) + - HUGE Trackball (Wired and wireless) config HID_ELO tristate "ELO USB 4000/4500 touchscreen" diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9bc91160819b..330ca983828b 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2032,6 +2032,8 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) }, #endif #if IS_ENABLED(CONFIG_HID_ELO) { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c index e2c7465df69f..54aeea57d209 100644 --- a/drivers/hid/hid-elecom.c +++ b/drivers/hid/hid-elecom.c @@ -3,6 +3,7 @@ * Copyright (c) 2010 Richard Nauber * Copyright (c) 2016 Yuxuan Shui * Copyright (c) 2017 Diego Elio Pettenò + * Copyright (c) 2017 Alex Manoussakis */ /* @@ -32,9 +33,11 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, break; case USB_DEVICE_ID_ELECOM_DEFT_WIRED: case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS: - /* The DEFT trackball has eight buttons, but its descriptor only - * reports five, disabling the three Fn buttons on the top of - * the mouse. + case USB_DEVICE_ID_ELECOM_HUGE_WIRED: + case USB_DEVICE_ID_ELECOM_HUGE_WIRELESS: + /* The DEFT/HUGE trackball has eight buttons, but its descriptor + * only reports five, disabling the three Fn buttons on the top + * of the mouse. * * Apply the following diff to the descriptor: * @@ -62,7 +65,7 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, * End Collection, End Collection, */ if (*rsize == 213 && rdesc[13] == 5 && rdesc[21] == 5) { - hid_info(hdev, "Fixing up Elecom DEFT Fn buttons\n"); + hid_info(hdev, "Fixing up Elecom DEFT/HUGE Fn buttons\n"); rdesc[13] = 8; /* Button/Variable Report Count */ rdesc[21] = 8; /* Button/Variable Usage Maximum */ rdesc[29] = 0; /* Button/Constant Report Count */ @@ -76,6 +79,8 @@ static const struct hid_device_id elecom_devices[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) }, { } }; MODULE_DEVICE_TABLE(hid, elecom_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index a98919199858..be2e005c3c51 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -368,6 +368,8 @@ #define USB_DEVICE_ID_ELECOM_BM084 0x0061 #define USB_DEVICE_ID_ELECOM_DEFT_WIRED 0x00fe #define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS 0x00ff +#define USB_DEVICE_ID_ELECOM_HUGE_WIRED 0x010c +#define USB_DEVICE_ID_ELECOM_HUGE_WIRELESS 0x010d #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 #define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004 -- cgit v1.2.3 From af7a8ffad9c58deac791333a65c62d7fc72f9e9c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 11 Oct 2017 11:10:19 +0200 Subject: drm/i915: Use rcu instead of stop_machine in set_wedged stop_machine is not really a locking primitive we should use, except when the hw folks tell us the hw is broken and that's the only way to work around it. This patch tries to address the locking abuse of stop_machine() from commit 20e4933c478a1ca694b38fa4ac44d99e659941f5 Author: Chris Wilson Date: Tue Nov 22 14:41:21 2016 +0000 drm/i915: Stop the machine as we install the wedged submit_request handler Chris said parts of the reasons for going with stop_machine() was that it's no overhead for the fast-path. But these callbacks use irqsave spinlocks and do a bunch of MMIO, and rcu_read_lock is _real_ fast. To stay as close as possible to the stop_machine semantics we first update all the submit function pointers to the nop handler, then call synchronize_rcu() to make sure no new requests can be submitted. This should give us exactly the huge barrier we want. I pondered whether we should annotate engine->submit_request as __rcu and use rcu_assign_pointer and rcu_dereference on it. But the reason behind those is to make sure the compiler/cpu barriers are there for when you have an actual data structure you point at, to make sure all the writes are seen correctly on the read side. But we just have a function pointer, and .text isn't changed, so no need for these barriers and hence no need for annotations. Unfortunately there's a complication with the call to intel_engine_init_global_seqno: - Without stop_machine we must hold the corresponding spinlock. - Without stop_machine we must ensure that all requests are marked as having failed with dma_fence_set_error() before we call it. That means we need to split the nop request submission into two phases, both synchronized with rcu: 1. Only stop submitting the requests to hw and mark them as failed. 2. After all pending requests in the scheduler/ring are suitably marked up as failed and we can force complete them all, also force complete by calling intel_engine_init_global_seqno(). This should fix the followwing lockdep splat: ====================================================== WARNING: possible circular locking dependency detected 4.14.0-rc3-CI-CI_DRM_3179+ #1 Tainted: G U ------------------------------------------------------ kworker/3:4/562 is trying to acquire lock: (cpu_hotplug_lock.rw_sem){++++}, at: [] stop_machine+0x1c/0x40 but task is already holding lock: (&dev->struct_mutex){+.+.}, at: [] i915_reset_device+0x1e8/0x260 [i915] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #6 (&dev->struct_mutex){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 __mutex_lock+0x86/0x9b0 mutex_lock_interruptible_nested+0x1b/0x20 i915_mutex_lock_interruptible+0x51/0x130 [i915] i915_gem_fault+0x209/0x650 [i915] __do_fault+0x1e/0x80 __handle_mm_fault+0xa08/0xed0 handle_mm_fault+0x156/0x300 __do_page_fault+0x2c5/0x570 do_page_fault+0x28/0x250 page_fault+0x22/0x30 -> #5 (&mm->mmap_sem){++++}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 __might_fault+0x68/0x90 _copy_to_user+0x23/0x70 filldir+0xa5/0x120 dcache_readdir+0xf9/0x170 iterate_dir+0x69/0x1a0 SyS_getdents+0xa5/0x140 entry_SYSCALL_64_fastpath+0x1c/0xb1 -> #4 (&sb->s_type->i_mutex_key#5){++++}: down_write+0x3b/0x70 handle_create+0xcb/0x1e0 devtmpfsd+0x139/0x180 kthread+0x152/0x190 ret_from_fork+0x27/0x40 -> #3 ((complete)&req.done){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 wait_for_common+0x58/0x210 wait_for_completion+0x1d/0x20 devtmpfs_create_node+0x13d/0x160 device_add+0x5eb/0x620 device_create_groups_vargs+0xe0/0xf0 device_create+0x3a/0x40 msr_device_create+0x2b/0x40 cpuhp_invoke_callback+0xc9/0xbf0 cpuhp_thread_fun+0x17b/0x240 smpboot_thread_fn+0x18a/0x280 kthread+0x152/0x190 ret_from_fork+0x27/0x40 -> #2 (cpuhp_state-up){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 cpuhp_issue_call+0x133/0x1c0 __cpuhp_setup_state_cpuslocked+0x139/0x2a0 __cpuhp_setup_state+0x46/0x60 page_writeback_init+0x43/0x67 pagecache_init+0x3d/0x42 start_kernel+0x3a8/0x3fc x86_64_start_reservations+0x2a/0x2c x86_64_start_kernel+0x6d/0x70 verify_cpu+0x0/0xfb -> #1 (cpuhp_state_mutex){+.+.}: __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 __mutex_lock+0x86/0x9b0 mutex_lock_nested+0x1b/0x20 __cpuhp_setup_state_cpuslocked+0x53/0x2a0 __cpuhp_setup_state+0x46/0x60 page_alloc_init+0x28/0x30 start_kernel+0x145/0x3fc x86_64_start_reservations+0x2a/0x2c x86_64_start_kernel+0x6d/0x70 verify_cpu+0x0/0xfb -> #0 (cpu_hotplug_lock.rw_sem){++++}: check_prev_add+0x430/0x840 __lock_acquire+0x1420/0x15e0 lock_acquire+0xb0/0x200 cpus_read_lock+0x3d/0xb0 stop_machine+0x1c/0x40 i915_gem_set_wedged+0x1a/0x20 [i915] i915_reset+0xb9/0x230 [i915] i915_reset_device+0x1f6/0x260 [i915] i915_handle_error+0x2d8/0x430 [i915] hangcheck_declare_hang+0xd3/0xf0 [i915] i915_hangcheck_elapsed+0x262/0x2d0 [i915] process_one_work+0x233/0x660 worker_thread+0x4e/0x3b0 kthread+0x152/0x190 ret_from_fork+0x27/0x40 other info that might help us debug this: Chain exists of: cpu_hotplug_lock.rw_sem --> &mm->mmap_sem --> &dev->struct_mutex Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&dev->struct_mutex); lock(&mm->mmap_sem); lock(&dev->struct_mutex); lock(cpu_hotplug_lock.rw_sem); *** DEADLOCK *** 3 locks held by kworker/3:4/562: #0: ("events_long"){+.+.}, at: [] process_one_work+0x1aa/0x660 #1: ((&(&i915->gpu_error.hangcheck_work)->work)){+.+.}, at: [] process_one_work+0x1aa/0x660 #2: (&dev->struct_mutex){+.+.}, at: [] i915_reset_device+0x1e8/0x260 [i915] stack backtrace: CPU: 3 PID: 562 Comm: kworker/3:4 Tainted: G U 4.14.0-rc3-CI-CI_DRM_3179+ #1 Hardware name: /NUC7i5BNB, BIOS BNKBL357.86A.0048.2017.0704.1415 07/04/2017 Workqueue: events_long i915_hangcheck_elapsed [i915] Call Trace: dump_stack+0x68/0x9f print_circular_bug+0x235/0x3c0 ? lockdep_init_map_crosslock+0x20/0x20 check_prev_add+0x430/0x840 ? irq_work_queue+0x86/0xe0 ? wake_up_klogd+0x53/0x70 __lock_acquire+0x1420/0x15e0 ? __lock_acquire+0x1420/0x15e0 ? lockdep_init_map_crosslock+0x20/0x20 lock_acquire+0xb0/0x200 ? stop_machine+0x1c/0x40 ? i915_gem_object_truncate+0x50/0x50 [i915] cpus_read_lock+0x3d/0xb0 ? stop_machine+0x1c/0x40 stop_machine+0x1c/0x40 i915_gem_set_wedged+0x1a/0x20 [i915] i915_reset+0xb9/0x230 [i915] i915_reset_device+0x1f6/0x260 [i915] ? gen8_gt_irq_ack+0x170/0x170 [i915] ? work_on_cpu_safe+0x60/0x60 i915_handle_error+0x2d8/0x430 [i915] ? vsnprintf+0xd1/0x4b0 ? scnprintf+0x3a/0x70 hangcheck_declare_hang+0xd3/0xf0 [i915] ? intel_runtime_pm_put+0x56/0xa0 [i915] i915_hangcheck_elapsed+0x262/0x2d0 [i915] process_one_work+0x233/0x660 worker_thread+0x4e/0x3b0 kthread+0x152/0x190 ? process_one_work+0x660/0x660 ? kthread_create_on_node+0x40/0x40 ret_from_fork+0x27/0x40 Setting dangerous option reset - tainting kernel i915 0000:00:02.0: Resetting chip after gpu hang Setting dangerous option reset - tainting kernel i915 0000:00:02.0: Resetting chip after gpu hang v2: Have 1 global synchronize_rcu() barrier across all engines, and improve commit message. v3: We need to protect the seqno update with the timeline spinlock (in set_wedged) to avoid racing with other updates of the seqno, like we already do in nop_submit_request (Chris). v4: Use two-phase sequence to plug the race Chris spotted where we can complete requests before they're marked up with -EIO. v5: Review from Chris: - simplify nop_submit_request. - Add comment to rcu_read_lock section. - Align comments with the new style. v6: Remove unused variable to appease CI. Reviewed-by: Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102886 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103096 Cc: Chris Wilson Cc: Mika Kuoppala Cc: Thomas Gleixner Cc: Marta Lofstedt Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171011091019.1425-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c | 80 +++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_request.c | 9 +++ drivers/gpu/drm/i915/selftests/i915_gem_request.c | 2 + 3 files changed, 62 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f76890b74d00..20fcac37c85a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3086,6 +3086,14 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv) } static void nop_submit_request(struct drm_i915_gem_request *request) +{ + GEM_BUG_ON(!i915_terminally_wedged(&request->i915->gpu_error)); + dma_fence_set_error(&request->fence, -EIO); + + i915_gem_request_submit(request); +} + +static void nop_complete_submit_request(struct drm_i915_gem_request *request) { unsigned long flags; @@ -3098,45 +3106,59 @@ static void nop_submit_request(struct drm_i915_gem_request *request) spin_unlock_irqrestore(&request->engine->timeline->lock, flags); } -static void engine_set_wedged(struct intel_engine_cs *engine) +void i915_gem_set_wedged(struct drm_i915_private *i915) { - /* We need to be sure that no thread is running the old callback as - * we install the nop handler (otherwise we would submit a request - * to hardware that will never complete). In order to prevent this - * race, we wait until the machine is idle before making the swap - * (using stop_machine()). + struct intel_engine_cs *engine; + enum intel_engine_id id; + + /* + * First, stop submission to hw, but do not yet complete requests by + * rolling the global seqno forward (since this would complete requests + * for which we haven't set the fence error to EIO yet). + */ + for_each_engine(engine, i915, id) + engine->submit_request = nop_submit_request; + + /* + * Make sure no one is running the old callback before we proceed with + * cancelling requests and resetting the completion tracking. Otherwise + * we might submit a request to the hardware which never completes. */ - engine->submit_request = nop_submit_request; + synchronize_rcu(); + + for_each_engine(engine, i915, id) { + /* Mark all executing requests as skipped */ + engine->cancel_requests(engine); - /* Mark all executing requests as skipped */ - engine->cancel_requests(engine); + /* + * Only once we've force-cancelled all in-flight requests can we + * start to complete all requests. + */ + engine->submit_request = nop_complete_submit_request; + } - /* Mark all pending requests as complete so that any concurrent - * (lockless) lookup doesn't try and wait upon the request as we - * reset it. + /* + * Make sure no request can slip through without getting completed by + * either this call here to intel_engine_init_global_seqno, or the one + * in nop_complete_submit_request. */ - intel_engine_init_global_seqno(engine, - intel_engine_last_submit(engine)); -} + synchronize_rcu(); -static int __i915_gem_set_wedged_BKL(void *data) -{ - struct drm_i915_private *i915 = data; - struct intel_engine_cs *engine; - enum intel_engine_id id; + for_each_engine(engine, i915, id) { + unsigned long flags; - for_each_engine(engine, i915, id) - engine_set_wedged(engine); + /* Mark all pending requests as complete so that any concurrent + * (lockless) lookup doesn't try and wait upon the request as we + * reset it. + */ + spin_lock_irqsave(&engine->timeline->lock, flags); + intel_engine_init_global_seqno(engine, + intel_engine_last_submit(engine)); + spin_unlock_irqrestore(&engine->timeline->lock, flags); + } set_bit(I915_WEDGED, &i915->gpu_error.flags); wake_up_all(&i915->gpu_error.reset_queue); - - return 0; -} - -void i915_gem_set_wedged(struct drm_i915_private *dev_priv) -{ - stop_machine(__i915_gem_set_wedged_BKL, dev_priv, NULL); } bool i915_gem_unset_wedged(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index d5f4023e5d63..d140fcf5c6a3 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -556,7 +556,16 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) switch (state) { case FENCE_COMPLETE: trace_i915_gem_request_submit(request); + /* + * We need to serialize use of the submit_request() callback with its + * hotplugging performed during an emergency i915_gem_set_wedged(). + * We use the RCU mechanism to mark the critical section in order to + * force i915_gem_set_wedged() to wait until the submit_request() is + * completed before proceeding. + */ + rcu_read_lock(); request->engine->submit_request(request); + rcu_read_unlock(); break; case FENCE_FREE: diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c b/drivers/gpu/drm/i915/selftests/i915_gem_request.c index 78b9f811707f..a999161e8db1 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c @@ -215,7 +215,9 @@ static int igt_request_rewind(void *arg) } i915_gem_request_get(vip); i915_add_request(vip); + rcu_read_lock(); request->engine->submit_request(request); + rcu_read_unlock(); mutex_unlock(&i915->drm.struct_mutex); -- cgit v1.2.3 From de330815677d80a7eae7c82e134de1507867291b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 9 Oct 2017 19:19:50 +0300 Subject: drm/i915: Reuse normal state readout for LVDS/DVO fixed mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reuse the normal state readout code to get the fixed mode for LVDS/DVO encoders. This removes some partially duplicated state readout code from LVDS/DVO encoders. The duplicated code wasn't actually even populating the negative h/vsync flags, leading to possible state checker complaints. The normal readout code populates that stuff fully. Cc: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171009161951.22420-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson Tested-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 50 +++++++++++++++++------------------- drivers/gpu/drm/i915/intel_drv.h | 5 ++-- drivers/gpu/drm/i915/intel_dvo.c | 33 ++++++------------------ drivers/gpu/drm/i915/intel_lvds.c | 18 ++++--------- 4 files changed, 39 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b2c5fba102e1..932d846e2456 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10238,48 +10238,44 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc, &pipe_config->fdi_m_n); } -/** Returns the currently programmed mode of the given pipe. */ -struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc) +/* Returns the currently programmed mode of the given encoder. */ +struct drm_display_mode * +intel_encoder_current_mode(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_crtc_state *crtc_state; struct drm_display_mode *mode; - struct intel_crtc_state *pipe_config; - enum pipe pipe = intel_crtc->pipe; + struct intel_crtc *crtc; + enum pipe pipe; + + if (!encoder->get_hw_state(encoder, &pipe)) + return NULL; + + crtc = intel_get_crtc_for_pipe(dev_priv, pipe); mode = kzalloc(sizeof(*mode), GFP_KERNEL); if (!mode) return NULL; - pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); - if (!pipe_config) { + crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL); + if (!crtc_state) { kfree(mode); return NULL; } - /* - * Construct a pipe_config sufficient for getting the clock info - * back out of crtc_clock_get. - * - * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need - * to use a real value here instead. - */ - pipe_config->cpu_transcoder = (enum transcoder) pipe; - pipe_config->pixel_multiplier = 1; - pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(pipe)); - pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(pipe)); - pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe)); - i9xx_crtc_clock_get(intel_crtc, pipe_config); + crtc_state->base.crtc = &crtc->base; - pipe_config->base.adjusted_mode.crtc_clock = - pipe_config->port_clock / pipe_config->pixel_multiplier; + if (!dev_priv->display.get_pipe_config(crtc, crtc_state)) { + kfree(crtc_state); + kfree(mode); + return NULL; + } - intel_get_pipe_timings(intel_crtc, pipe_config); + encoder->get_config(encoder, crtc_state); - intel_mode_from_pipe_config(mode, pipe_config); + intel_mode_from_pipe_config(mode, crtc_state); - kfree(pipe_config); + kfree(crtc_state); return mode; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cdda0a84babe..b87946dcc53f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1363,8 +1363,9 @@ struct intel_connector *intel_connector_alloc(void); bool intel_connector_get_hw_state(struct intel_connector *connector); void intel_connector_attach_encoder(struct intel_connector *connector, struct intel_encoder *encoder); -struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc); +struct drm_display_mode * +intel_encoder_current_mode(struct intel_encoder *encoder); + enum pipe intel_get_pipe_from_connector(struct intel_connector *connector); int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 5c562e1f56ae..53c9b763f4ce 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -379,32 +379,15 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = { * chip being on DVOB/C and having multiple pipes. */ static struct drm_display_mode * -intel_dvo_get_current_mode(struct drm_connector *connector) +intel_dvo_get_current_mode(struct intel_encoder *encoder) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_dvo *intel_dvo = intel_attached_dvo(connector); - uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); - struct drm_display_mode *mode = NULL; + struct drm_display_mode *mode; - /* If the DVO port is active, that'll be the LVDS, so we can pull out - * its timings to get how the BIOS set up the panel. - */ - if (dvo_val & DVO_ENABLE) { - struct intel_crtc *crtc; - int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0; - - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - if (crtc) { - mode = intel_crtc_mode_get(dev, &crtc->base); - if (mode) { - mode->type |= DRM_MODE_TYPE_PREFERRED; - if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) - mode->flags |= DRM_MODE_FLAG_PHSYNC; - if (dvo_val & DVO_VSYNC_ACTIVE_HIGH) - mode->flags |= DRM_MODE_FLAG_PVSYNC; - } - } + mode = intel_encoder_current_mode(encoder); + if (mode) { + DRM_DEBUG_KMS("using current (BIOS) mode: "); + drm_mode_debug_printmodeline(mode); + mode->type |= DRM_MODE_TYPE_PREFERRED; } return mode; @@ -551,7 +534,7 @@ void intel_dvo_init(struct drm_i915_private *dev_priv) * mode being output through DVO. */ intel_panel_init(&intel_connector->panel, - intel_dvo_get_current_mode(connector), + intel_dvo_get_current_mode(intel_encoder), NULL, NULL); intel_dvo->panel_wants_dither = true; } diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a55954a89148..c5072b951b9c 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -939,10 +939,8 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) struct drm_display_mode *fixed_mode = NULL; struct drm_display_mode *downclock_mode = NULL; struct edid *edid; - struct intel_crtc *crtc; i915_reg_t lvds_reg; u32 lvds; - int pipe; u8 pin; u32 allowed_scalers; @@ -1118,17 +1116,11 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) if (HAS_PCH_SPLIT(dev_priv)) goto failed; - pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - - if (crtc && (lvds & LVDS_PORT_EN)) { - fixed_mode = intel_crtc_mode_get(dev, &crtc->base); - if (fixed_mode) { - DRM_DEBUG_KMS("using current (BIOS) mode: "); - drm_mode_debug_printmodeline(fixed_mode); - fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; - goto out; - } + fixed_mode = intel_encoder_current_mode(intel_encoder); + if (fixed_mode) { + DRM_DEBUG_KMS("using current (BIOS) mode: "); + drm_mode_debug_printmodeline(fixed_mode); + fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; } /* If we still don't have a mode after all that, give up. */ -- cgit v1.2.3 From ead666000a5fe34bdc82d61838e4df2d416ea15e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 12 Sep 2017 05:58:26 -0400 Subject: media: dvb_frontend: only use kref after initialized As reported by Laurent, when a DVB frontend need to register two drivers (e. g. a tuner and a demod), if the second driver fails to register (for example because it was not compiled), the error handling logic frees the frontend by calling dvb_frontend_detach(). That used to work fine, but changeset 1f862a68df24 ("[media] dvb_frontend: move kref to struct dvb_frontend") added a kref at struct dvb_frontend. So, now, instead of just freeing the data, the error handling do a kref_put(). That works fine only after dvb_register_frontend() succeeds. While it would be possible to add a helper function that would be initializing earlier the kref, that would require changing every single DVB frontend on non-trivial ways, and would make frontends different than other drivers. So, instead of doing that, let's focus on the real issue: only call kref_put() after kref_init(). That's easy to check, as, when the dvb frontend is successfuly registered, it will allocate its own private struct. So, if such struct is allocated, it means that it is safe to use kref_put(). If not, then nobody is using yet the frontend, and it is safe to just deallocate it. Fixes: 1f862a68df24 ("[media] dvb_frontend: move kref to struct dvb_frontend") Reported-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 2fcba1616168..9139d01ba7ed 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -141,22 +141,39 @@ struct dvb_frontend_private { static void dvb_frontend_invoke_release(struct dvb_frontend *fe, void (*release)(struct dvb_frontend *fe)); -static void dvb_frontend_free(struct kref *ref) +static void __dvb_frontend_free(struct dvb_frontend *fe) { - struct dvb_frontend *fe = - container_of(ref, struct dvb_frontend, refcount); struct dvb_frontend_private *fepriv = fe->frontend_priv; + if (!fepriv) + return; + dvb_free_device(fepriv->dvbdev); dvb_frontend_invoke_release(fe, fe->ops.release); kfree(fepriv); + fe->frontend_priv = NULL; +} + +static void dvb_frontend_free(struct kref *ref) +{ + struct dvb_frontend *fe = + container_of(ref, struct dvb_frontend, refcount); + + __dvb_frontend_free(fe); } static void dvb_frontend_put(struct dvb_frontend *fe) { - kref_put(&fe->refcount, dvb_frontend_free); + /* + * Check if the frontend was registered, as otherwise + * kref was not initialized yet. + */ + if (fe->frontend_priv) + kref_put(&fe->refcount, dvb_frontend_free); + else + __dvb_frontend_free(fe); } static void dvb_frontend_get(struct dvb_frontend *fe) -- cgit v1.2.3 From eef9ffdf9cd39b2986367bc8395e2772bc1284ba Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Mon, 9 Oct 2017 13:33:19 +0200 Subject: scsi: libiscsi: fix shifting of DID_REQUEUE host byte The SCSI host byte should be shifted left by 16 in order to have scsi_decide_disposition() do the right thing (.i.e. requeue the command). Signed-off-by: Johannes Thumshirn Fixes: 661134ad3765 ("[SCSI] libiscsi, bnx2i: make bound ep check common") Cc: Lee Duncan Cc: Hannes Reinecke Cc: Bart Van Assche Cc: Chris Leech Acked-by: Lee Duncan Signed-off-by: Martin K. Petersen --- drivers/scsi/libiscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index c62e8d111fd9..f8dc1601efd5 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1728,7 +1728,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) { reason = FAILURE_SESSION_IN_RECOVERY; - sc->result = DID_REQUEUE; + sc->result = DID_REQUEUE << 16; goto fault; } -- cgit v1.2.3 From ea850f64c2722278f150dc11de2141baeb24211c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 28 Sep 2017 11:21:57 +0300 Subject: drm/i915/bios: parse DDI ports also for CHV for HDMI DDC pin and DP AUX channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While technically CHV isn't DDI, we do look at the VBT based DDI port info for HDMI DDC pin and DP AUX channel. (We call these "alternate", but they're really just something that aren't platform defaults.) In commit e4ab73a13291 ("drm/i915: Respect alternate_ddc_pin for all DDI ports") Ville writes, "IIRC there may be CHV system that might actually need this." I'm not sure why there couldn't be even more platforms that need this, but start conservative, and parse the info for CHV in addition to DDI. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100553 Reported-by: Marek Wilczewski Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d0815082cb98487618429b62414854137049b888.1506586821.git.jani.nikula@intel.com (cherry picked from commit 348e4058ebf53904e817eec7a1b25327143c2ed2) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 00c6aee0a9a1..5d4cd3d00564 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1240,7 +1240,7 @@ static void parse_ddi_ports(struct drm_i915_private *dev_priv, { enum port port; - if (!HAS_DDI(dev_priv)) + if (!HAS_DDI(dev_priv) && !IS_CHERRYVIEW(dev_priv)) return; if (!dev_priv->vbt.child_dev_num) -- cgit v1.2.3 From 68a39a3e9fe1d6f0dfe59e3f4d6bc6765e01c903 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 11 Oct 2017 10:48:44 +0000 Subject: remoteproc: imx_rproc: fix return value check in imx_rproc_addr_init() In case of error, the function devm_ioremap() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test. Reviewed-by: Oleksij Rempel Signed-off-by: Wei Yongjun Signed-off-by: Bjorn Andersson --- drivers/remoteproc/imx_rproc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 81ba44510b75..633268e9d550 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -269,10 +269,9 @@ static int imx_rproc_addr_init(struct imx_rproc *priv, priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, att->sa, att->size); - if (IS_ERR(priv->mem[b].cpu_addr)) { + if (!priv->mem[b].cpu_addr) { dev_err(dev, "devm_ioremap_resource failed\n"); - err = PTR_ERR(priv->mem[b].cpu_addr); - return err; + return -ENOMEM; } priv->mem[b].sys_addr = att->sa; priv->mem[b].size = att->size; -- cgit v1.2.3 From a9e170e28636fd577249f39029d59e4e960a42b8 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Tue, 10 Oct 2017 12:08:22 -0700 Subject: scsi: qla2xxx: Fix uninitialized work element Fixes following stack trace kernel: Call Trace: kernel: dump_stack+0x63/0x84 kernel: __warn+0xd1/0xf0 kernel: warn_slowpath_null+0x1d/0x20 kernel: __queue_work+0x37a/0x420 kernel: queue_work_on+0x27/0x40 kernel: queue_work+0x14/0x20 [qla2xxx] kernel: schedule_work+0x13/0x20 [qla2xxx] kernel: qla2x00_post_work+0xab/0xb0 [qla2xxx] kernel: qla2x00_post_aen_work+0x3b/0x50 [qla2xxx] kernel: qla2x00_async_event+0x20d/0x15d0 [qla2xxx] kernel: ? lock_timer_base+0x7d/0xa0 kernel: qla24xx_intr_handler+0x1da/0x310 [qla2xxx] kernel: qla2x00_poll+0x36/0x60 [qla2xxx] kernel: qla2x00_mailbox_command+0x659/0xec0 [qla2xxx] kernel: ? proc_create_data+0x7a/0xd0 kernel: qla25xx_init_rsp_que+0x15b/0x240 [qla2xxx] kernel: ? request_irq+0x14/0x20 [qla2xxx] kernel: qla25xx_create_rsp_que+0x256/0x3c0 [qla2xxx] kernel: qla2xxx_create_qpair+0x2af/0x5b0 [qla2xxx] kernel: qla2x00_probe_one+0x1107/0x1c30 [qla2xxx] Fixes: ec7193e26055 ("qla2xxx: Fix delayed response to command for loop mode/direct connect.") Cc: # 4.13 Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5b2437a5ea44..937209805baf 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3175,6 +3175,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->can_queue, base_vha->req, base_vha->mgmt_svr_loop_id, host->sg_tablesize); + INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); + if (ha->mqenable) { bool mq = false; bool startit = false; @@ -3223,7 +3225,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) */ qla2xxx_wake_dpc(base_vha); - INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error); if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) { -- cgit v1.2.3 From 8d30371fd7c328e192d7ea3108bd71b903631d6a Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Tue, 10 Oct 2017 17:31:38 +0200 Subject: scsi: fc: check for rport presence in fc_block_scsi_eh Coverity-scan recently found a possible NULL pointer dereference in fc_block_scsi_eh() as starget_to_rport() either returns the rport for the startget or NULL. While it is rather unlikely to have fc_block_scsi_eh() called without an rport associated it's a good idea to catch potential misuses of the API gracefully. Signed-off-by: Johannes Thumshirn Reviewed-by: Bart Van Assche Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_fc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index cbd4495d0ff9..8c46a6d536af 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3320,6 +3320,9 @@ int fc_block_scsi_eh(struct scsi_cmnd *cmnd) { struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); + if (WARN_ON_ONCE(!rport)) + return FAST_IO_FAIL; + return fc_block_rport(rport); } EXPORT_SYMBOL(fc_block_scsi_eh); -- cgit v1.2.3 From 3c7b6b3c4f2a4882d9d82365cc122cc8d29f4811 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 9 Oct 2017 19:19:51 +0300 Subject: drm/i915: Allow PCH platforms fall back to BIOS LVDS mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With intel_encoder_current_mode() using the normal state readout code it actually works on PCH platforms as well. So let's nuke the PCH check from intel_lvds_init(). I suppose there aren't any machines that actually need this, but at least we get to eliminate a few lines of code, and one FIXME. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171009161951.22420-2-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_lvds.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index c5072b951b9c..38572d65e46e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -1111,11 +1111,6 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) * on. If so, assume that whatever is currently programmed is the * correct mode. */ - - /* Ironlake: FIXME if still fail, not try pipe mode now */ - if (HAS_PCH_SPLIT(dev_priv)) - goto failed; - fixed_mode = intel_encoder_current_mode(intel_encoder); if (fixed_mode) { DRM_DEBUG_KMS("using current (BIOS) mode: "); -- cgit v1.2.3 From fc603ca7f81d729bbec7ced294f25a93113c49f7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 9 Oct 2017 12:29:58 +0300 Subject: drm/i915/dp: centralize max source rate conditions more Turn intel_dp_source_supports_hbr2() into a simple helper to query the pre-filled source rates array, and move the conditions about which platforms support which rates to the single point of truth in intel_dp_set_source_rates(). This also reduces the code paths you have to think about in the source rates initialization in intel_dp_set_source_rates(), making it easier to grasp. Cc: Manasi Navare Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171009092959.29021-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ca48bce23a6f..09d75df497c0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -254,15 +254,15 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) } else if (IS_GEN9_BC(dev_priv)) { source_rates = skl_rates; size = ARRAY_SIZE(skl_rates); - } else { + } else if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) || + IS_BROADWELL(dev_priv)) { source_rates = default_rates; size = ARRAY_SIZE(default_rates); + } else { + source_rates = default_rates; + size = ARRAY_SIZE(default_rates) - 1; } - /* This depends on the fact that 5.4 is last value in the array */ - if (!intel_dp_source_supports_hbr2(intel_dp)) - size--; - intel_dp->source_rates = source_rates; intel_dp->num_source_rates = size; } @@ -1482,14 +1482,9 @@ intel_dp_aux_init(struct intel_dp *intel_dp) bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) { - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + int max_rate = intel_dp->source_rates[intel_dp->num_source_rates - 1]; - if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) || - IS_BROADWELL(dev_priv) || (INTEL_GEN(dev_priv) >= 9)) - return true; - else - return false; + return max_rate >= 540000; } static void -- cgit v1.2.3 From a8a08886ef8c6a5a740e50e3897466cfd11724ff Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 9 Oct 2017 12:29:59 +0300 Subject: drm/i915/dp: limit sink rates based on rate Get rid of redundant intel_dp_num_rates(). We can simply look at the rate and limit based on that. Cc: Manasi Navare Reviewed-by: Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171009092959.29021-3-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 09d75df497c0..b0f446b68f42 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -137,32 +137,20 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe); static void intel_dp_unset_edid(struct intel_dp *intel_dp); -static int intel_dp_num_rates(u8 link_bw_code) -{ - switch (link_bw_code) { - default: - WARN(1, "invalid max DP link bw val %x, using 1.62Gbps\n", - link_bw_code); - case DP_LINK_BW_1_62: - return 1; - case DP_LINK_BW_2_7: - return 2; - case DP_LINK_BW_5_4: - return 3; - } -} - /* update sink rates from dpcd */ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) { - int i, num_rates; + int i, max_rate; - num_rates = intel_dp_num_rates(intel_dp->dpcd[DP_MAX_LINK_RATE]); + max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]); - for (i = 0; i < num_rates; i++) + for (i = 0; i < ARRAY_SIZE(default_rates); i++) { + if (default_rates[i] > max_rate) + break; intel_dp->sink_rates[i] = default_rates[i]; + } - intel_dp->num_sink_rates = num_rates; + intel_dp->num_sink_rates = i; } /* Theoretical max between source and sink */ -- cgit v1.2.3 From c343bc2ce2c627b6cef2b09794a4a5b63419a798 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 26 Sep 2017 12:08:27 +0300 Subject: ACPI: properties: Align return codes of __acpi_node_get_property_reference() acpi_fwnode_get_reference_args(), the function implementing ACPI support for fwnode_property_get_reference_args(), returns directly error codes from __acpi_node_get_property_reference(). The latter uses different error codes than the OF implementation. In particular, the OF implementation uses -ENOENT to indicate that the property is not found, a reference entry is empty and there are no more references. Document and align the error codes for property for fwnode_property_get_reference_args() so that they match with of_parse_phandle_with_args(). Fixes: 3e3119d3088f (device property: Introduce fwnode_property_get_reference_args) Signed-off-by: Sakari Ailus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/property.c | 19 +++++++++---------- drivers/base/property.c | 4 ++++ 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 3fb8ff513461..5a8ac5e1081b 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -571,10 +571,9 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data, * } * } * - * Calling this function with index %2 return %-ENOENT and with index %3 - * returns the last entry. If the property does not contain any more values - * %-ENODATA is returned. The NULL entry must be single integer and - * preferably contain value %0. + * Calling this function with index %2 or index %3 return %-ENOENT. If the + * property does not contain any more values %-ENOENT is returned. The NULL + * entry must be single integer and preferably contain value %0. * * Return: %0 on success, negative error code on failure. */ @@ -590,7 +589,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, data = acpi_device_data_of_node(fwnode); if (!data) - return -EINVAL; + return -ENOENT; ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); if (ret) @@ -635,7 +634,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ret = acpi_bus_get_device(element->reference.handle, &device); if (ret) - return -ENODEV; + return -EINVAL; nargs = 0; element++; @@ -649,11 +648,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, else if (type == ACPI_TYPE_LOCAL_REFERENCE) break; else - return -EPROTO; + return -EINVAL; } if (nargs > MAX_ACPI_REFERENCE_ARGS) - return -EPROTO; + return -EINVAL; if (idx == index) { args->adev = device; @@ -670,13 +669,13 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, return -ENOENT; element++; } else { - return -EPROTO; + return -EINVAL; } idx++; } - return -ENODATA; + return -ENOENT; } EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); diff --git a/drivers/base/property.c b/drivers/base/property.c index 21fcc13013a5..7ed99c1b2a8b 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -683,6 +683,10 @@ EXPORT_SYMBOL_GPL(fwnode_property_match_string); * Caller is responsible to call fwnode_handle_put() on the returned * args->fwnode pointer. * + * Returns: %0 on success + * %-ENOENT when the index is out of bounds, the index has an empty + * reference or the property was not found + * %-EINVAL on parse error */ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, const char *prop, const char *nargs_prop, -- cgit v1.2.3 From 51858a2777f025333c5ac3b3484263bba56461b3 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 11 Oct 2017 11:06:13 +0300 Subject: ACPI: properties: Fix __acpi_node_get_property_reference() return codes Fix more return codes for device property: Align return codes of __acpi_node_get_property_reference(). In particular, what was missed previously: -EPROTO could be returned in certain cases, now -EINVAL; -EINVAL was returned if the property was not found, now -ENOENT; -EINVAL was returned also if the index was higher than the number of entries in a package, now -ENOENT. Reported-by: Hyungwoo Yang Fixes: 3e3119d3088f (device property: Introduce fwnode_property_get_reference_args) Signed-off-by: Sakari Ailus Tested-by: Hyungwoo Yang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/property.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 5a8ac5e1081b..e26ea209b63e 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -593,7 +593,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); if (ret) - return ret; + return ret == -EINVAL ? -ENOENT : -EINVAL; /* * The simplest case is when the value is a single reference. Just @@ -605,7 +605,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ret = acpi_bus_get_device(obj->reference.handle, &device); if (ret) - return ret; + return ret == -ENODEV ? -EINVAL : ret; args->adev = device; args->nargs = 0; @@ -621,8 +621,10 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, * The index argument is then used to determine which reference * the caller wants (along with the arguments). */ - if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count) - return -EPROTO; + if (obj->type != ACPI_TYPE_PACKAGE) + return -EINVAL; + if (index >= obj->package.count) + return -ENOENT; element = obj->package.elements; end = element + obj->package.count; -- cgit v1.2.3 From 5aba2ba5030b66a6f8c93049b718556f9aacd7c6 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Tue, 10 Oct 2017 17:07:12 +0200 Subject: macsec: fix memory leaks when skb_to_sgvec fails Fixes: cda7ea690350 ("macsec: check return value of skb_to_sgvec always") Signed-off-by: Sabrina Dubroca Signed-off-by: David S. Miller --- drivers/net/macsec.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 98e4deaa3a6a..5ab1b8849c30 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -742,6 +742,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, sg_init_table(sg, ret); ret = skb_to_sgvec(skb, sg, 0, skb->len); if (unlikely(ret < 0)) { + aead_request_free(req); macsec_txsa_put(tx_sa); kfree_skb(skb); return ERR_PTR(ret); @@ -954,6 +955,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, sg_init_table(sg, ret); ret = skb_to_sgvec(skb, sg, 0, skb->len); if (unlikely(ret < 0)) { + aead_request_free(req); kfree_skb(skb); return ERR_PTR(ret); } -- cgit v1.2.3 From bde135a672bfd1cc41d91c2bbbbd36eb25409b74 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Wed, 11 Oct 2017 12:56:52 +0800 Subject: r8169: only enable PCI wakeups when WOL is active rtl_init_one() currently enables PCI wakeups if the ethernet device is found to be WOL-capable. There is no need to do this when rtl8169_set_wol() will correctly enable or disable the same wakeup flag when WOL is activated/deactivated. This works around an ACPI DSDT bug which prevents the Acer laptop models Aspire ES1-533, Aspire ES1-732, PackardBell ENTE69AP and Gateway NE533 from entering S3 suspend - even when no ethernet cable is connected. On these platforms, the DSDT says that GPE08 is a wakeup source for ethernet, but this GPE fires as soon as the system goes into suspend, waking the system up immediately. Having the wakeup normally disabled avoids this issue in the default case. With this change, WOL will continue to be unusable on these platforms (it will instantly wake up if WOL is later enabled by the user) but we do not expect this to be a commonly used feature on these consumer laptops. We have separately determined that WOL works fine without any ACPI GPEs enabled during sleep, so a DSDT fix or override would be possible to make WOL work. Signed-off-by: Daniel Drake Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e03fcf914690..a3c949ea7d1a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -8491,8 +8491,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl8168_driver_start(tp); } - device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); - if (pci_dev_run_wake(pdev)) pm_runtime_put_noidle(&pdev->dev); -- cgit v1.2.3 From 418da17214aca5ef5f0b6f7588905ee7df92f98f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 Mar 2017 23:25:07 -0700 Subject: drm: Pass struct drm_file * to __drm_mode_object_find [v2] This will allow __drm_mode_object_file to be extended to perform access control checks based on the file in use. v2: Also fix up vboxvideo driver in staging [airlied: merging early as this is an API change] Suggested-by: Daniel Vetter Signed-off-by: Keith Packard Signed-off-by: Dave Airlie --- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 16 ++++++++-------- drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 4 ++-- drivers/gpu/drm/ast/ast_mode.c | 2 +- drivers/gpu/drm/bochs/bochs_kms.c | 2 +- drivers/gpu/drm/cirrus/cirrus_mode.c | 2 +- drivers/gpu/drm/drm_atomic.c | 8 ++++---- drivers/gpu/drm/drm_atomic_helper.c | 2 +- drivers/gpu/drm/drm_color_mgmt.c | 4 ++-- drivers/gpu/drm/drm_connector.c | 2 +- drivers/gpu/drm/drm_crtc.c | 8 ++++---- drivers/gpu/drm/drm_crtc_internal.h | 1 + drivers/gpu/drm/drm_encoder.c | 2 +- drivers/gpu/drm/drm_framebuffer.c | 9 +++++---- drivers/gpu/drm/drm_mode_object.c | 10 ++++++---- drivers/gpu/drm/drm_plane.c | 14 +++++++------- drivers/gpu/drm/drm_probe_helper.c | 2 +- drivers/gpu/drm/drm_property.c | 6 +++--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_overlay.c | 2 +- drivers/gpu/drm/i915/intel_sprite.c | 2 +- drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 4 ++-- drivers/gpu/drm/radeon/r100.c | 2 +- drivers/gpu/drm/radeon/r600_cs.c | 2 +- drivers/gpu/drm/radeon/radeon_connectors.c | 16 ++++++++-------- drivers/gpu/drm/udl/udl_connector.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- drivers/staging/vboxvideo/vbox_mode.c | 2 +- include/drm/drm_connector.h | 3 ++- include/drm/drm_crtc.h | 5 +++-- include/drm/drm_encoder.h | 3 ++- include/drm/drm_framebuffer.h | 1 + include/drm/drm_mode_object.h | 2 ++ include/drm/drm_plane.h | 3 ++- include/drm/drm_property.h | 3 ++- 37 files changed, 85 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index f51b41f094ef..df9cbc78e168 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -231,7 +231,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector, if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -256,7 +256,7 @@ amdgpu_connector_find_encoder(struct drm_connector *connector, for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -372,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector) /* pick the encoder ids */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } @@ -1077,7 +1077,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -1134,7 +1134,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector) if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -1153,7 +1153,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector) /* then check use digitial */ /* pick the first one */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } @@ -1294,7 +1294,7 @@ u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -1323,7 +1323,7 @@ static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector) for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c index b9ee9073cb0d..a8829af120c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c @@ -288,7 +288,7 @@ dce_virtual_encoder(struct drm_connector *connector) if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -298,7 +298,7 @@ dce_virtual_encoder(struct drm_connector *connector) /* pick the first one */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 6f3849ec0c1d..9555a3542022 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -713,7 +713,7 @@ static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connect int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 6a91e62da2f4..a24a18fbd65a 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -213,7 +213,7 @@ bochs_connector_best_encoder(struct drm_connector *connector) int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index a4c4a465b385..cd23b1b28259 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c @@ -457,7 +457,7 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 366c56fe5f58..268969fecee7 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -718,7 +718,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, struct drm_mode_config *config = &dev->mode_config; if (property == config->prop_fb_id) { - struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val); + struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); drm_atomic_set_fb_for_plane(state, fb); if (fb) drm_framebuffer_put(fb); @@ -734,7 +734,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, return -EINVAL; } else if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, val); + struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); return drm_atomic_set_crtc_for_plane(state, crtc); } else if (property == config->prop_crtc_x) { state->crtc_x = U642I64(val); @@ -1149,7 +1149,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, struct drm_mode_config *config = &dev->mode_config; if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, val); + struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); return drm_atomic_set_crtc_for_connector(state, crtc); } else if (property == config->dpms_property) { /* setting DPMS property requires special handling, which @@ -2259,7 +2259,7 @@ retry: goto out; } - obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY); + obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY); if (!obj) { ret = -ENOENT; goto out; diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 01c34bc5b5b0..c49fbc4db3b5 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3206,7 +3206,7 @@ struct drm_encoder * drm_atomic_helper_best_encoder(struct drm_connector *connector) { WARN_ON(connector->encoder_ids[1]); - return drm_encoder_find(connector->dev, connector->encoder_ids[0]); + return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); } EXPORT_SYMBOL(drm_atomic_helper_best_encoder); diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index fe0982708e95..0d002b045bd2 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -230,7 +230,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - crtc = drm_crtc_find(dev, crtc_lut->crtc_id); + crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id); if (!crtc) return -ENOENT; @@ -308,7 +308,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - crtc = drm_crtc_find(dev, crtc_lut->crtc_id); + crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id); if (!crtc) return -ENOENT; diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index d8ca526ca4ee..704fc8934616 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1310,7 +1310,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); - connector = drm_connector_lookup(dev, out_resp->connector_id); + connector = drm_connector_lookup(dev, file_priv, out_resp->connector_id); if (!connector) return -ENOENT; diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 68b4e976d5e0..f0556e654116 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -402,7 +402,7 @@ int drm_mode_getcrtc(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - crtc = drm_crtc_find(dev, crtc_resp->crtc_id); + crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id); if (!crtc) return -ENOENT; @@ -569,7 +569,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000) return -ERANGE; - crtc = drm_crtc_find(dev, crtc_req->crtc_id); + crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id); if (!crtc) { DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); return -ENOENT; @@ -595,7 +595,7 @@ retry: /* Make refcounting symmetric with the lookup path. */ drm_framebuffer_get(fb); } else { - fb = drm_framebuffer_lookup(dev, crtc_req->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id); if (!fb) { DRM_DEBUG_KMS("Unknown FB ID%d\n", crtc_req->fb_id); @@ -680,7 +680,7 @@ retry: goto out; } - connector = drm_connector_lookup(dev, out_id); + connector = drm_connector_lookup(dev, file_priv, out_id); if (!connector) { DRM_DEBUG_KMS("Connector id %d unknown\n", out_id); diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index a43582076b20..9ebb8841778c 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -106,6 +106,7 @@ int drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj, void drm_mode_object_register(struct drm_device *dev, struct drm_mode_object *obj); struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id, uint32_t type); void drm_mode_object_unregister(struct drm_device *dev, struct drm_mode_object *object); diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index 0708779840d2..43f644844b83 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -220,7 +220,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - encoder = drm_encoder_find(dev, enc_resp->encoder_id); + encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id); if (!encoder) return -ENOENT; diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index af279844d7ce..2affe53f3fda 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -381,7 +381,7 @@ int drm_mode_rmfb(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - fb = drm_framebuffer_lookup(dev, *id); + fb = drm_framebuffer_lookup(dev, file_priv, *id); if (!fb) return -ENOENT; @@ -450,7 +450,7 @@ int drm_mode_getfb(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - fb = drm_framebuffer_lookup(dev, r->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id); if (!fb) return -ENOENT; @@ -515,7 +515,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - fb = drm_framebuffer_lookup(dev, r->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id); if (!fb) return -ENOENT; @@ -688,12 +688,13 @@ EXPORT_SYMBOL(drm_framebuffer_init); * again, using drm_framebuffer_put(). */ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id) { struct drm_mode_object *obj; struct drm_framebuffer *fb = NULL; - obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_FB); + obj = __drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_FB); if (obj) fb = obj_to_fb(obj); return fb; diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 7a1ea91d3343..240a05d91a53 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -105,6 +105,7 @@ void drm_mode_object_unregister(struct drm_device *dev, } struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id, uint32_t type) { struct drm_mode_object *obj = NULL; @@ -127,7 +128,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, /** * drm_mode_object_find - look up a drm object with static lifetime - * @dev: drm device + * @file_priv: drm file * @id: id of the mode object * @type: type of the mode object * @@ -136,11 +137,12 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, * by callind drm_mode_object_put(). */ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id, uint32_t type) { struct drm_mode_object *obj = NULL; - obj = __drm_mode_object_find(dev, id, type); + obj = __drm_mode_object_find(dev, file_priv, id, type); return obj; } EXPORT_SYMBOL(drm_mode_object_find); @@ -359,7 +361,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, drm_modeset_lock_all(dev); - obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); + obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type); if (!obj) { ret = -ENOENT; goto out; @@ -481,7 +483,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); + arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type); if (!arg_obj) return -ENOENT; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 72cba9805edc..6af02c7b5da3 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -513,7 +513,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - plane = drm_plane_find(dev, plane_resp->plane_id); + plane = drm_plane_find(dev, file_priv, plane_resp->plane_id); if (!plane) return -ENOENT; @@ -703,7 +703,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, * First, find the plane, crtc, and fb objects. If not available, * we don't bother to call the driver. */ - plane = drm_plane_find(dev, plane_req->plane_id); + plane = drm_plane_find(dev, file_priv, plane_req->plane_id); if (!plane) { DRM_DEBUG_KMS("Unknown plane ID %d\n", plane_req->plane_id); @@ -711,14 +711,14 @@ int drm_mode_setplane(struct drm_device *dev, void *data, } if (plane_req->fb_id) { - fb = drm_framebuffer_lookup(dev, plane_req->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id); if (!fb) { DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", plane_req->fb_id); return -ENOENT; } - crtc = drm_crtc_find(dev, plane_req->crtc_id); + crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id); if (!crtc) { drm_framebuffer_put(fb); DRM_DEBUG_KMS("Unknown crtc ID %d\n", @@ -829,7 +829,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) return -EINVAL; - crtc = drm_crtc_find(dev, req->crtc_id); + crtc = drm_crtc_find(dev, file_priv, req->crtc_id); if (!crtc) { DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); return -ENOENT; @@ -944,7 +944,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip) return -EINVAL; - crtc = drm_crtc_find(dev, page_flip->crtc_id); + crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id); if (!crtc) return -ENOENT; @@ -1005,7 +1005,7 @@ retry: goto out; } - fb = drm_framebuffer_lookup(dev, page_flip->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id); if (!fb) { ret = -ENOENT; goto out; diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 5840aabbf24e..6dc2dde5b672 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -99,7 +99,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode, /* Step 2: Validate against encoders and crtcs */ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]); + struct drm_encoder *encoder = drm_encoder_find(dev, NULL, ids[i]); struct drm_crtc *crtc; if (!encoder) diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c index bc5128203056..bae50e6b819d 100644 --- a/drivers/gpu/drm/drm_property.c +++ b/drivers/gpu/drm/drm_property.c @@ -450,7 +450,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - property = drm_property_find(dev, out_resp->prop_id); + property = drm_property_find(dev, file_priv, out_resp->prop_id); if (!property) return -ENOENT; @@ -634,7 +634,7 @@ struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, struct drm_mode_object *obj; struct drm_property_blob *blob = NULL; - obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB); + obj = __drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_BLOB); if (obj) blob = obj_to_blob(obj); return blob; @@ -897,7 +897,7 @@ bool drm_property_change_valid_get(struct drm_property *property, if (value == 0) return true; - *ref = __drm_mode_object_find(property->dev, value, + *ref = __drm_mode_object_find(property->dev, NULL, value, property->values[0]); return *ref != NULL; } diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index ec4dd9df9150..f4eba87c96f3 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -36,7 +36,7 @@ static int hibmc_connector_mode_valid(struct drm_connector *connector, static struct drm_encoder * hibmc_connector_best_encoder(struct drm_connector *connector) { - return drm_encoder_find(connector->dev, connector->encoder_ids[0]); + return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]); } static const struct drm_connector_helper_funcs diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f780f39e0758..0bec6deaae4f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13511,7 +13511,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_crtc *drmmode_crtc; struct intel_crtc *crtc; - drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id); + drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id); if (!drmmode_crtc) return -ENOENT; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index aace22e7ccac..1b397b41cb4f 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1134,7 +1134,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, if (!params) return -ENOMEM; - drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id); + drmmode_crtc = drm_crtc_find(dev, file_priv, put_image_rec->crtc_id); if (!drmmode_crtc) { ret = -ENOENT; goto out_free; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index b0d6e3e28d07..28a1209d87e2 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -994,7 +994,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, set->flags & I915_SET_COLORKEY_DESTINATION) return -EINVAL; - plane = drm_plane_find(dev, set->plane_id); + plane = drm_plane_find(dev, file_priv, set->plane_id); if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) return -ENOENT; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 5e9cd4c0e8b6..68e5d9c94475 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1670,7 +1670,7 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 70d8e0d69ad5..69d6e61a01ec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -373,7 +373,7 @@ find_encoder(struct drm_connector *connector, int type) if (!id) break; - enc = drm_encoder_find(dev, id); + enc = drm_encoder_find(dev, NULL, id); if (!enc) continue; nv_encoder = nouveau_encoder(enc); @@ -441,7 +441,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector) if (id == 0) break; - encoder = drm_encoder_find(dev, id); + encoder = drm_encoder_find(dev, NULL, id); if (!encoder) continue; nv_encoder = nouveau_encoder(encoder); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index c31e660e35db..7d39ed63e5be 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1456,7 +1456,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) header = radeon_get_ib_value(p, h_idx); crtc_id = radeon_get_ib_value(p, h_idx + 5); reg = R100_CP_PACKET0_GET_REG(header); - crtc = drm_crtc_find(p->rdev->ddev, crtc_id); + crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id); if (!crtc) { DRM_ERROR("cannot find crtc %d\n", crtc_id); return -ENOENT; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 97fd58e97043..c96b31950ca7 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -887,7 +887,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p, crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); reg = R600_CP_PACKET0_GET_REG(header); - crtc = drm_crtc_find(p->rdev->ddev, crtc_id); + crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id); if (!crtc) { DRM_ERROR("cannot find crtc %d\n", crtc_id); return -ENOENT; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2f642cbefd8e..59dcefb2df3b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -263,7 +263,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -290,7 +290,7 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -404,7 +404,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn int enc_id = connector->encoder_ids[0]; /* pick the encoder ids */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } @@ -1368,7 +1368,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -1454,7 +1454,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -1473,7 +1473,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) /* then check use digitial */ /* pick the first one */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } @@ -1620,7 +1620,7 @@ u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; @@ -1649,7 +1649,7 @@ static bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) if (connector->encoder_ids[i] == 0) break; - encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); + encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); if (!encoder) continue; diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index 9f9a49748d17..091ca81658eb 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -105,7 +105,7 @@ static struct drm_encoder* udl_best_single_encoder(struct drm_connector *connector) { int enc_id = connector->encoder_ids[0]; - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); } static int udl_connector_set_property(struct drm_connector *connector, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 5ec24fd801cd..01be355525e4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -286,7 +286,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, drm_modeset_lock_all(dev); - fb = drm_framebuffer_lookup(dev, arg->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); if (!fb) { DRM_ERROR("Invalid framebuffer id.\n"); ret = -ENOENT; @@ -369,7 +369,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, drm_modeset_lock_all(dev); - fb = drm_framebuffer_lookup(dev, arg->fb_id); + fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); if (!fb) { DRM_ERROR("Invalid framebuffer id.\n"); ret = -ENOENT; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b850562fbdd6..0545740b3724 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1726,7 +1726,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data, return 0; } - crtc = drm_crtc_find(dev, arg->crtc_id); + crtc = drm_crtc_find(dev, file_priv, arg->crtc_id); if (!crtc) { ret = -ENOENT; goto out; diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 257a77830410..c745a0402c68 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -377,7 +377,7 @@ static struct drm_encoder *vbox_best_single_encoder(struct drm_connector /* pick the encoder ids */ if (enc_id) - return drm_encoder_find(connector->dev, enc_id); + return drm_encoder_find(connector->dev, NULL, enc_id); return NULL; } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index b34904dc8b9b..b4285c40e1e4 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -939,10 +939,11 @@ static inline unsigned drm_connector_index(struct drm_connector *connector) * add takes a reference to it. */ static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id) { struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR); + mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CONNECTOR); return mo ? obj_to_connector(mo) : NULL; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 80c97210eda5..f7fcceef46d9 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -959,10 +959,11 @@ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx); * userspace interface should be done using &drm_property. */ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, - uint32_t id) + struct drm_file *file_priv, + uint32_t id) { struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CRTC); + mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CRTC); return mo ? obj_to_crtc(mo) : NULL; } diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 8d8245ec0181..86db0da8bdcb 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -214,11 +214,12 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, * drm_mode_object_find(). */ static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id) { struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); + mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_ENCODER); return mo ? obj_to_encoder(mo) : NULL; } diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index b6996ddb19d6..4c5ee4ae54df 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h @@ -205,6 +205,7 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, const struct drm_framebuffer_funcs *funcs); struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id); void drm_framebuffer_remove(struct drm_framebuffer *fb); void drm_framebuffer_cleanup(struct drm_framebuffer *fb); diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index a767b4a30a6d..b2f920b518e3 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -27,6 +27,7 @@ struct drm_object_properties; struct drm_property; struct drm_device; +struct drm_file; /** * struct drm_mode_object - base structure for modeset objects @@ -113,6 +114,7 @@ struct drm_object_properties { } struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id, uint32_t type); void drm_mode_object_get(struct drm_mode_object *obj); void drm_mode_object_put(struct drm_mode_object *obj); diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 82a217bd77f0..069c4c8ce360 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -597,10 +597,11 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane, * drm_mode_object_find(). */ static inline struct drm_plane *drm_plane_find(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id) { struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE); + mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PLANE); return mo ? obj_to_plane(mo) : NULL; } diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h index 37355c623e6c..429d8218f740 100644 --- a/include/drm/drm_property.h +++ b/include/drm/drm_property.h @@ -312,10 +312,11 @@ drm_property_unreference_blob(struct drm_property_blob *blob) * This function looks up the property object specified by id and returns it. */ static inline struct drm_property *drm_property_find(struct drm_device *dev, + struct drm_file *file_priv, uint32_t id) { struct drm_mode_object *mo; - mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY); + mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PROPERTY); return mo ? obj_to_property(mo) : NULL; } -- cgit v1.2.3 From 3b86b9ec21031aeaa8a9c2634299c1aa5c686bfd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:00 +0200 Subject: omapdrm: encoder-tpd12s015: keep ls_oe_gpio high For OMAP4 CEC support the CEC pin should always be on. So keep ls_oe_gpio high all the time in order to support CEC. Background: even if the HPD is low it should still be possible to use CEC. Some displays will set the HPD low when they go into standby or when they switch to another input, but CEC is still available and able to wake up/change input for such a display. This is explicitly allowed by the CEC standard. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index a9e9d667c55e..293b8fd07cfc 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -51,6 +51,8 @@ static int tpd_connect(struct omap_dss_device *dssdev, dssdev->dst = dst; gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1); + gpiod_set_value_cansleep(ddata->ls_oe_gpio, 1); + /* DC-DC converter needs at max 300us to get to 90% of 5V */ udelay(300); @@ -69,6 +71,7 @@ static void tpd_disconnect(struct omap_dss_device *dssdev, return; gpiod_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0); + gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0); dst->src = NULL; dssdev->dst = NULL; @@ -146,18 +149,11 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, { struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *in = ddata->in; - int r; if (!gpiod_get_value_cansleep(ddata->hpd_gpio)) return -ENODEV; - gpiod_set_value_cansleep(ddata->ls_oe_gpio, 1); - - r = in->ops.hdmi->read_edid(in, edid, len); - - gpiod_set_value_cansleep(ddata->ls_oe_gpio, 0); - - return r; + return in->ops.hdmi->read_edid(in, edid, len); } static bool tpd_detect(struct omap_dss_device *dssdev) -- cgit v1.2.3 From eb2f17b4965cdfc7337f1a212378430202e37217 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:01 +0200 Subject: omapdrm: hdmi.h: extend hdmi_core_data with CEC fields Extend the hdmi_core_data struct with the additional fields needed for CEC. Also fix a simple typo in a comment. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h index a820b394af09..c2609c448ddc 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "omapdss.h" #include "dss.h" @@ -264,6 +265,10 @@ struct hdmi_core_data { void __iomem *base; bool cts_swmode; bool audio_use_mclk; + + struct hdmi_wp_data *wp; + unsigned int core_pwr_cnt; + struct cec_adapter *adap; }; static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, @@ -373,7 +378,7 @@ struct omap_hdmi { bool audio_configured; struct omap_dss_audio audio_config; - /* This lock should be taken when booleans bellow are touched. */ + /* This lock should be taken when booleans below are touched. */ spinlock_t audio_playing_lock; bool audio_playing; bool display_enabled; -- cgit v1.2.3 From 5bebbbfecc3d61d3e98913e0a6acbba9a43efd76 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:02 +0200 Subject: omapdrm: hdmi4: make low-level functions available Three low-level functions in hdmi4.c and hdmi4_core.c are made available for use by the OMAP4 CEC support. Renamed the prefix to hdmi4 since these are OMAP4 specific. These function deal with the HDMI core and are needed to power it up for use with CEC, even when the HPD is low. Background: even if the HPD is low it should still be possible to use CEC. Some displays will set the HPD low when they go into standby or when they switch to another input, but CEC is still available and able to wake up/change input for such a display. This is explicitly allowed by the CEC standard. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 12 ++++++------ drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | 6 +++--- drivers/gpu/drm/omapdrm/dss/hdmi4_core.h | 4 ++++ 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index f169348da377..bd0efcc48bff 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -393,11 +393,11 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev) mutex_unlock(&hdmi.lock); } -static int hdmi_core_enable(struct omap_dss_device *dssdev) +int hdmi4_core_enable(struct omap_dss_device *dssdev) { int r = 0; - DSSDBG("ENTER omapdss_hdmi_core_enable\n"); + DSSDBG("ENTER omapdss_hdmi4_core_enable\n"); mutex_lock(&hdmi.lock); @@ -415,9 +415,9 @@ err0: return r; } -static void hdmi_core_disable(struct omap_dss_device *dssdev) +void hdmi4_core_disable(struct omap_dss_device *dssdev) { - DSSDBG("Enter omapdss_hdmi_core_disable\n"); + DSSDBG("Enter omapdss_hdmi4_core_disable\n"); mutex_lock(&hdmi.lock); @@ -475,7 +475,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, need_enable = hdmi.core_enabled == false; if (need_enable) { - r = hdmi_core_enable(dssdev); + r = hdmi4_core_enable(dssdev); if (r) return r; } @@ -483,7 +483,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, r = read_edid(edid, len); if (need_enable) - hdmi_core_disable(dssdev); + hdmi4_core_disable(dssdev); return r; } diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index 365cf07daa01..47a6b7035ead 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c @@ -208,9 +208,9 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; } -static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) +void hdmi4_core_powerdown_disable(struct hdmi_core_data *core) { - DSSDBG("Enter hdmi_core_powerdown_disable\n"); + DSSDBG("Enter hdmi4_core_powerdown_disable\n"); REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0); } @@ -336,7 +336,7 @@ void hdmi4_configure(struct hdmi_core_data *core, hdmi_core_swreset_assert(core); /* power down off */ - hdmi_core_powerdown_disable(core); + hdmi4_core_powerdown_disable(core); v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode; diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.h index a069f96ec6f6..b6ab579e44d2 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.h @@ -266,6 +266,10 @@ void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s); int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core); +int hdmi4_core_enable(struct omap_dss_device *dssdev); +void hdmi4_core_disable(struct omap_dss_device *dssdev); +void hdmi4_core_powerdown_disable(struct hdmi_core_data *core); + int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -- cgit v1.2.3 From f3096a4adacd6b3d8197b18b5ad6fffda00983b2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:03 +0200 Subject: omapdrm: hdmi4: prepare irq handling for HDMI CEC support Pass struct omap_hdmi to the irq handler since it will need access to hdmi.core. Do not clear the IRQ_HDMI_CORE bit: that will be controlled by the HDMI CEC code. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index bd0efcc48bff..b5d78028024f 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -70,7 +70,8 @@ static void hdmi_runtime_put(void) static irqreturn_t hdmi_irq_handler(int irq, void *data) { - struct hdmi_wp_data *wp = data; + struct omap_hdmi *hdmi = data; + struct hdmi_wp_data *wp = &hdmi->wp; u32 irqstatus; irqstatus = hdmi_wp_get_irqstatus(wp); @@ -166,8 +167,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) return r; /* disable and clear irqs */ - hdmi_wp_clear_irqenable(wp, 0xffffffff); - hdmi_wp_set_irqstatus(wp, 0xffffffff); + hdmi_wp_clear_irqenable(wp, ~HDMI_IRQ_CORE); + hdmi_wp_set_irqstatus(wp, ~HDMI_IRQ_CORE); vm = &hdmi.cfg.vm; @@ -242,7 +243,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev) { enum omap_channel channel = dssdev->dispc_channel; - hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); + hdmi_wp_clear_irqenable(&hdmi.wp, ~HDMI_IRQ_CORE); hdmi_wp_video_stop(&hdmi.wp); @@ -724,7 +725,7 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) r = devm_request_threaded_irq(&pdev->dev, irq, NULL, hdmi_irq_handler, - IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); + IRQF_ONESHOT, "OMAP HDMI", &hdmi); if (r) { DSSERR("HDMI IRQ request failed\n"); goto err; -- cgit v1.2.3 From 1d54ecf230029dccc97e26a520ed95b9b95ae0eb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:04 +0200 Subject: omapdrm: hdmi4: move hdmi4_core_powerdown_disable to hdmi_power_on_core() Call hdmi4_core_powerdown_disable() in hdmi_power_on_core() to power up the HDMI core (needed for CEC). The same call can now be dropped in hdmi4_configure(). Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 2 ++ drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index b5d78028024f..91c2a1e8b324 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -132,6 +132,8 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) if (r) goto err_runtime_get; + hdmi4_core_powerdown_disable(&hdmi.core); + /* Make selection of HDMI in DSS */ dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index 47a6b7035ead..62e451162d96 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c @@ -335,9 +335,6 @@ void hdmi4_configure(struct hdmi_core_data *core, */ hdmi_core_swreset_assert(core); - /* power down off */ - hdmi4_core_powerdown_disable(core); - v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode; -- cgit v1.2.3 From a141a29612d7c0ba95a4e36a236d51c2b86e0e2b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:05 +0200 Subject: omapdrm: hdmi4: refcount hdmi_power_on/off_core The hdmi_power_on/off_core functions can be called multiple times: when the HPD changes and when the HDMI CEC support needs to power the HDMI core. So use a counter to know when to really power on or off the HDMI core. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 91c2a1e8b324..fd1b252c6e6d 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -124,9 +124,12 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) { int r; + if (hdmi.core.core_pwr_cnt++) + return 0; + r = regulator_enable(hdmi.vdda_reg); if (r) - return r; + goto err_reg_enable; r = hdmi_runtime_get(); if (r) @@ -143,12 +146,17 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) err_runtime_get: regulator_disable(hdmi.vdda_reg); +err_reg_enable: + hdmi.core.core_pwr_cnt--; return r; } static void hdmi_power_off_core(struct omap_dss_device *dssdev) { + if (--hdmi.core.core_pwr_cnt) + return; + hdmi.core_enabled = false; hdmi_runtime_put(); -- cgit v1.2.3 From 8d7f934df8d87237abd5c5caa318dfbf581854aa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:06 +0200 Subject: omapdrm: hdmi4_cec: add OMAP4 HDMI CEC support Add the source and header for the OMAP4 HDMI CEC support. This code is not yet hooked up, that will happen in the next patch. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 381 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 55 +++++ 2 files changed, 436 insertions(+) create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c new file mode 100644 index 000000000000..d86873f2abe6 --- /dev/null +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -0,0 +1,381 @@ +/* + * HDMI CEC + * + * Based on the CEC code from hdmi_ti_4xxx_ip.c from Android. + * + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * Authors: Yong Zhi + * Mythri pk + * + * Heavily modified to use the linux CEC framework: + * + * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "dss.h" +#include "hdmi.h" +#include "hdmi4_core.h" +#include "hdmi4_cec.h" + +/* HDMI CEC */ +#define HDMI_CEC_DEV_ID 0x900 +#define HDMI_CEC_SPEC 0x904 + +/* Not really a debug register, more a low-level control register */ +#define HDMI_CEC_DBG_3 0x91C +#define HDMI_CEC_TX_INIT 0x920 +#define HDMI_CEC_TX_DEST 0x924 +#define HDMI_CEC_SETUP 0x938 +#define HDMI_CEC_TX_COMMAND 0x93C +#define HDMI_CEC_TX_OPERAND 0x940 +#define HDMI_CEC_TRANSMIT_DATA 0x97C +#define HDMI_CEC_CA_7_0 0x988 +#define HDMI_CEC_CA_15_8 0x98C +#define HDMI_CEC_INT_STATUS_0 0x998 +#define HDMI_CEC_INT_STATUS_1 0x99C +#define HDMI_CEC_INT_ENABLE_0 0x990 +#define HDMI_CEC_INT_ENABLE_1 0x994 +#define HDMI_CEC_RX_CONTROL 0x9B0 +#define HDMI_CEC_RX_COUNT 0x9B4 +#define HDMI_CEC_RX_CMD_HEADER 0x9B8 +#define HDMI_CEC_RX_COMMAND 0x9BC +#define HDMI_CEC_RX_OPERAND 0x9C0 + +#define HDMI_CEC_TX_FIFO_INT_MASK 0x64 +#define HDMI_CEC_RETRANSMIT_CNT_INT_MASK 0x2 + +#define HDMI_CORE_CEC_RETRY 200 + +static void hdmi_cec_received_msg(struct hdmi_core_data *core) +{ + u32 cnt = hdmi_read_reg(core->base, HDMI_CEC_RX_COUNT) & 0xff; + + /* While there are CEC frames in the FIFO */ + while (cnt & 0x70) { + /* and the frame doesn't have an error */ + if (!(cnt & 0x80)) { + struct cec_msg msg = {}; + unsigned int i; + + /* then read the message */ + msg.len = cnt & 0xf; + msg.msg[0] = hdmi_read_reg(core->base, + HDMI_CEC_RX_CMD_HEADER); + msg.msg[1] = hdmi_read_reg(core->base, + HDMI_CEC_RX_COMMAND); + for (i = 0; i < msg.len; i++) { + unsigned int reg = HDMI_CEC_RX_OPERAND + i * 4; + + msg.msg[2 + i] = + hdmi_read_reg(core->base, reg); + } + msg.len += 2; + cec_received_msg(core->adap, &msg); + } + /* Clear the current frame from the FIFO */ + hdmi_write_reg(core->base, HDMI_CEC_RX_CONTROL, 1); + /* Wait until the current frame is cleared */ + while (hdmi_read_reg(core->base, HDMI_CEC_RX_CONTROL) & 1) + udelay(1); + /* + * Re-read the count register and loop to see if there are + * more messages in the FIFO. + */ + cnt = hdmi_read_reg(core->base, HDMI_CEC_RX_COUNT) & 0xff; + } +} + +static void hdmi_cec_transmit_fifo_empty(struct hdmi_core_data *core, u32 stat1) +{ + if (stat1 & 2) { + u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); + + cec_transmit_done(core->adap, + CEC_TX_STATUS_NACK | + CEC_TX_STATUS_MAX_RETRIES, + 0, (dbg3 >> 4) & 7, 0, 0); + } else if (stat1 & 1) { + cec_transmit_done(core->adap, + CEC_TX_STATUS_ARB_LOST | + CEC_TX_STATUS_MAX_RETRIES, + 0, 0, 0, 0); + } else if (stat1 == 0) { + cec_transmit_done(core->adap, CEC_TX_STATUS_OK, + 0, 0, 0, 0); + } +} + +void hdmi4_cec_irq(struct hdmi_core_data *core) +{ + u32 stat0 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0); + u32 stat1 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_1); + + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, stat0); + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, stat1); + + if (stat0 & 0x40) + REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); + else if (stat0 & 0x24) + hdmi_cec_transmit_fifo_empty(core, stat1); + if (stat1 & 2) { + u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); + + cec_transmit_done(core->adap, + CEC_TX_STATUS_NACK | + CEC_TX_STATUS_MAX_RETRIES, + 0, (dbg3 >> 4) & 7, 0, 0); + } else if (stat1 & 1) { + cec_transmit_done(core->adap, + CEC_TX_STATUS_ARB_LOST | + CEC_TX_STATUS_MAX_RETRIES, + 0, 0, 0, 0); + } + if (stat0 & 0x02) + hdmi_cec_received_msg(core); + if (stat1 & 0x3) + REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); +} + +static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap) +{ + struct hdmi_core_data *core = cec_get_drvdata(adap); + int retry = HDMI_CORE_CEC_RETRY; + int temp; + + REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); + while (retry) { + temp = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); + if (FLD_GET(temp, 7, 7) == 0) + break; + retry--; + } + return retry != 0; +} + +static bool hdmi_cec_clear_rx_fifo(struct cec_adapter *adap) +{ + struct hdmi_core_data *core = cec_get_drvdata(adap); + int retry = HDMI_CORE_CEC_RETRY; + int temp; + + hdmi_write_reg(core->base, HDMI_CEC_RX_CONTROL, 0x3); + retry = HDMI_CORE_CEC_RETRY; + while (retry) { + temp = hdmi_read_reg(core->base, HDMI_CEC_RX_CONTROL); + if (FLD_GET(temp, 1, 0) == 0) + break; + retry--; + } + return retry != 0; +} + +static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ + struct hdmi_core_data *core = cec_get_drvdata(adap); + int temp, err; + + if (!enable) { + hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0); + hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0); + REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0, 3, 3); + hdmi_wp_clear_irqenable(core->wp, HDMI_IRQ_CORE); + hdmi_wp_set_irqstatus(core->wp, HDMI_IRQ_CORE); + hdmi4_core_disable(NULL); + return 0; + } + err = hdmi4_core_enable(NULL); + if (err) + return err; + + /* Clear TX FIFO */ + if (!hdmi_cec_clear_tx_fifo(adap)) { + pr_err("cec-%s: could not clear TX FIFO\n", adap->name); + return -EIO; + } + + /* Clear RX FIFO */ + if (!hdmi_cec_clear_rx_fifo(adap)) { + pr_err("cec-%s: could not clear RX FIFO\n", adap->name); + return -EIO; + } + + /* Clear CEC interrupts */ + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, + hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_1)); + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, + hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0)); + + /* Enable HDMI core interrupts */ + hdmi_wp_set_irqenable(core->wp, HDMI_IRQ_CORE); + /* Unmask CEC interrupt */ + REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0x1, 3, 3); + /* + * Enable CEC interrupts: + * Transmit Buffer Full/Empty Change event + * Transmitter FIFO Empty event + * Receiver FIFO Not Empty event + */ + hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x26); + /* + * Enable CEC interrupts: + * RX FIFO Overrun Error event + * Short Pulse Detected event + * Frame Retransmit Count Exceeded event + * Start Bit Irregularity event + */ + hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x0f); + + /* cec calibration enable (self clearing) */ + hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x03); + msleep(20); + hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x04); + + temp = hdmi_read_reg(core->base, HDMI_CEC_SETUP); + if (FLD_GET(temp, 4, 4) != 0) { + temp = FLD_MOD(temp, 0, 4, 4); + hdmi_write_reg(core->base, HDMI_CEC_SETUP, temp); + + /* + * If we enabled CEC in middle of a CEC message on the bus, + * we could have start bit irregularity and/or short + * pulse event. Clear them now. + */ + temp = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_1); + temp = FLD_MOD(0x0, 0x5, 2, 0); + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, temp); + } + return 0; +} + +static int hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) +{ + struct hdmi_core_data *core = cec_get_drvdata(adap); + u32 v; + + if (log_addr == CEC_LOG_ADDR_INVALID) { + hdmi_write_reg(core->base, HDMI_CEC_CA_7_0, 0); + hdmi_write_reg(core->base, HDMI_CEC_CA_15_8, 0); + return 0; + } + if (log_addr <= 7) { + v = hdmi_read_reg(core->base, HDMI_CEC_CA_7_0); + v |= 1 << log_addr; + hdmi_write_reg(core->base, HDMI_CEC_CA_7_0, v); + } else { + v = hdmi_read_reg(core->base, HDMI_CEC_CA_15_8); + v |= 1 << (log_addr - 8); + hdmi_write_reg(core->base, HDMI_CEC_CA_15_8, v); + } + return 0; +} + +static int hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct hdmi_core_data *core = cec_get_drvdata(adap); + int temp; + u32 i; + + /* Clear TX FIFO */ + if (!hdmi_cec_clear_tx_fifo(adap)) { + pr_err("cec-%s: could not clear TX FIFO for transmit\n", + adap->name); + return -EIO; + } + + /* Clear TX interrupts */ + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, + HDMI_CEC_TX_FIFO_INT_MASK); + + hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, + HDMI_CEC_RETRANSMIT_CNT_INT_MASK); + + /* Set the retry count */ + REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, attempts - 1, 6, 4); + + /* Set the initiator addresses */ + hdmi_write_reg(core->base, HDMI_CEC_TX_INIT, cec_msg_initiator(msg)); + + /* Set destination id */ + temp = cec_msg_destination(msg); + if (msg->len == 1) + temp |= 0x80; + hdmi_write_reg(core->base, HDMI_CEC_TX_DEST, temp); + if (msg->len == 1) + return 0; + + /* Setup command and arguments for the command */ + hdmi_write_reg(core->base, HDMI_CEC_TX_COMMAND, msg->msg[1]); + + for (i = 0; i < msg->len - 2; i++) + hdmi_write_reg(core->base, HDMI_CEC_TX_OPERAND + i * 4, + msg->msg[2 + i]); + + /* Operand count */ + hdmi_write_reg(core->base, HDMI_CEC_TRANSMIT_DATA, + (msg->len - 2) | 0x10); + return 0; +} + +static const struct cec_adap_ops hdmi_cec_adap_ops = { + .adap_enable = hdmi_cec_adap_enable, + .adap_log_addr = hdmi_cec_adap_log_addr, + .adap_transmit = hdmi_cec_adap_transmit, +}; + +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +{ + cec_s_phys_addr(core->adap, pa, false); +} + +int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, + struct hdmi_wp_data *wp) +{ + const u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | + CEC_CAP_PASSTHROUGH | CEC_CAP_RC; + unsigned int ret; + + core->adap = cec_allocate_adapter(&hdmi_cec_adap_ops, core, + "omap4", caps, CEC_MAX_LOG_ADDRS); + ret = PTR_ERR_OR_ZERO(core->adap); + if (ret < 0) + return ret; + core->wp = wp; + + /* + * Initialize CEC clock divider: CEC needs 2MHz clock hence + * set the devider to 24 to get 48/24=2MHz clock + */ + REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0); + + ret = cec_register_adapter(core->adap, &pdev->dev); + if (ret < 0) { + cec_delete_adapter(core->adap); + return ret; + } + return 0; +} + +void hdmi4_cec_uninit(struct hdmi_core_data *core) +{ + cec_unregister_adapter(core->adap); +} diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h new file mode 100644 index 000000000000..0292337c97cc --- /dev/null +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h @@ -0,0 +1,55 @@ +/* + * HDMI header definition for OMAP4 HDMI CEC IP + * + * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * 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. + */ + +#ifndef _HDMI4_CEC_H_ +#define _HDMI4_CEC_H_ + +struct hdmi_core_data; +struct hdmi_wp_data; +struct platform_device; + +/* HDMI CEC funcs */ +#ifdef CONFIG_OMAP4_DSS_HDMI_CEC +void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa); +void hdmi4_cec_irq(struct hdmi_core_data *core); +int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, + struct hdmi_wp_data *wp); +void hdmi4_cec_uninit(struct hdmi_core_data *core); +#else +static inline void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa) +{ +} + +static inline void hdmi4_cec_irq(struct hdmi_core_data *core) +{ +} + +static inline int hdmi4_cec_init(struct platform_device *pdev, + struct hdmi_core_data *core, + struct hdmi_wp_data *wp) +{ + return 0; +} + +static inline void hdmi4_cec_uninit(struct hdmi_core_data *core) +{ +} +#endif + +#endif -- cgit v1.2.3 From 1897e1a394c3a54a86dd46656e96d58e135033db Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Aug 2017 10:54:07 +0200 Subject: omapdrm: hdmi4: hook up the HDMI CEC support Hook up the HDMI CEC support in the hdmi4 driver. It add the CEC irq handler, the CEC (un)init calls and tells the CEC implementation when the physical address changes. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/dss/Kconfig | 8 ++++++++ drivers/gpu/drm/omapdrm/dss/Makefile | 1 + drivers/gpu/drm/omapdrm/dss/hdmi4.c | 23 ++++++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig index 8b87d5cf45fc..f24ebf7f61dd 100644 --- a/drivers/gpu/drm/omapdrm/dss/Kconfig +++ b/drivers/gpu/drm/omapdrm/dss/Kconfig @@ -65,6 +65,14 @@ config OMAP4_DSS_HDMI help HDMI support for OMAP4 based SoCs. +config OMAP4_DSS_HDMI_CEC + bool "Enable HDMI CEC support for OMAP4" + depends on OMAP4_DSS_HDMI + select CEC_CORE + default y + ---help--- + When selected the HDMI transmitter will support the CEC feature. + config OMAP5_DSS_HDMI bool "HDMI support for OMAP5" default n diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile index 142ce5a02542..3c5644c3fc38 100644 --- a/drivers/gpu/drm/omapdrm/dss/Makefile +++ b/drivers/gpu/drm/omapdrm/dss/Makefile @@ -14,5 +14,6 @@ omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_common.o hdmi_wp.o hdmi_pll.o \ hdmi_phy.o omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o +omapdss-$(CONFIG_OMAP4_DSS_HDMI_CEC) += hdmi4_cec.o omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi5_core.o ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index fd1b252c6e6d..2bfbd6745850 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -36,9 +36,11 @@ #include #include #include +#include #include "omapdss.h" #include "hdmi4_core.h" +#include "hdmi4_cec.h" #include "dss.h" #include "hdmi.h" @@ -96,6 +98,13 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); } + if (irqstatus & HDMI_IRQ_CORE) { + u32 intr4 = hdmi_read_reg(hdmi->core.base, HDMI_CORE_SYS_INTR4); + + hdmi_write_reg(hdmi->core.base, HDMI_CORE_SYS_INTR4, intr4); + if (intr4 & 8) + hdmi4_cec_irq(&hdmi->core); + } return IRQ_HANDLED; } @@ -392,6 +401,8 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev) DSSDBG("Enter hdmi_display_disable\n"); + hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID); + mutex_lock(&hdmi.lock); spin_lock_irqsave(&hdmi.audio_playing_lock, flags); @@ -492,7 +503,11 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, } r = read_edid(edid, len); - + if (r >= 256) + hdmi4_cec_set_phys_addr(&hdmi.core, + cec_get_edid_phys_addr(edid, r, NULL)); + else + hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID); if (need_enable) hdmi4_core_disable(dssdev); @@ -726,6 +741,10 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data) if (r) goto err; + r = hdmi4_cec_init(pdev, &hdmi.core, &hdmi.wp); + if (r) + goto err; + irq = platform_get_irq(pdev, 0); if (irq < 0) { DSSERR("platform_get_irq failed\n"); @@ -770,6 +789,8 @@ static void hdmi4_unbind(struct device *dev, struct device *master, void *data) hdmi_uninit_output(pdev); + hdmi4_cec_uninit(&hdmi.core); + hdmi_pll_uninit(&hdmi.pll); pm_runtime_disable(&pdev->dev); -- cgit v1.2.3 From 019114efd9bb21594c36a5fbdab34a004dfb0a79 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Aug 2017 15:19:57 +0200 Subject: omapdrm: omapdss_hdmi_ops: add lost_hotplug op The CEC framework needs to know when the hotplug detect signal disappears, since that means the CEC physical address has to be invalidated (i.e. set to f.f.f.f). Add a lost_hotplug op that is called when the HPD signal goes away. Signed-off-by: Hans Verkuil Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 8 ++++++-- drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 6 +++++- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 8 ++++++-- drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index d9d25df6fc1b..4600d3841c25 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -165,11 +165,15 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *in = ddata->in; + bool connected; if (gpio_is_valid(ddata->hpd_gpio)) - return gpio_get_value_cansleep(ddata->hpd_gpio); + connected = gpio_get_value_cansleep(ddata->hpd_gpio); else - return in->ops.hdmi->detect(in); + connected = in->ops.hdmi->detect(in); + if (!connected && in->ops.hdmi->lost_hotplug) + in->ops.hdmi->lost_hotplug(in); + return connected; } static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 293b8fd07cfc..e3d98d78fc40 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -159,8 +159,12 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, static bool tpd_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); + struct omap_dss_device *in = ddata->in; + bool connected = gpiod_get_value_cansleep(ddata->hpd_gpio); - return gpiod_get_value_cansleep(ddata->hpd_gpio); + if (!connected && in->ops.hdmi->lost_hotplug) + in->ops.hdmi->lost_hotplug(in); + return connected; } static int tpd_register_hpd_cb(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 2bfbd6745850..a598dfdeb585 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -401,8 +401,6 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev) DSSDBG("Enter hdmi_display_disable\n"); - hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID); - mutex_lock(&hdmi.lock); spin_lock_irqsave(&hdmi.audio_playing_lock, flags); @@ -514,6 +512,11 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, return r; } +static void hdmi_lost_hotplug(struct omap_dss_device *dssdev) +{ + hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID); +} + static int hdmi_set_infoframe(struct omap_dss_device *dssdev, const struct hdmi_avi_infoframe *avi) { @@ -540,6 +543,7 @@ static const struct omapdss_hdmi_ops hdmi_ops = { .get_timings = hdmi_display_get_timings, .read_edid = hdmi_read_edid, + .lost_hotplug = hdmi_lost_hotplug, .set_infoframe = hdmi_set_infoframe, .set_hdmi_mode = hdmi_set_hdmi_mode, }; diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 47a331670963..990422b35784 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -395,6 +395,7 @@ struct omapdss_hdmi_ops { struct videomode *vm); int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len); + void (*lost_hotplug)(struct omap_dss_device *dssdev); bool (*detect)(struct omap_dss_device *dssdev); int (*register_hpd_cb)(struct omap_dss_device *dssdev, -- cgit v1.2.3 From 7c781423379d8215f2cc4940700bde0b9f93fed0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Oct 2017 15:18:57 +0100 Subject: drm/i915/userptr: Drop struct_mutex before cleanup Purely to silence lockdep, as we know that no bo can exist at this time and so the inversion is impossible. Nevertheless, lockdep currently warns on unload: [ 137.522565] WARNING: possible circular locking dependency detected [ 137.522568] 4.14.0-rc4-CI-CI_DRM_3209+ #1 Tainted: G U [ 137.522570] ------------------------------------------------------ [ 137.522572] drv_module_relo/1532 is trying to acquire lock: [ 137.522574] ("i915-userptr-acquire"){+.+.}, at: [] flush_workqueue+0x91/0x540 [ 137.522581] but task is already holding lock: [ 137.522583] (&dev->struct_mutex){+.+.}, at: [] i915_gem_fini+0x3f/0xc0 [i915] [ 137.522605] which lock already depends on the new lock. [ 137.522608] the existing dependency chain (in reverse order) is: [ 137.522611] -> #3 (&dev->struct_mutex){+.+.}: [ 137.522615] __lock_acquire+0x1420/0x15e0 [ 137.522618] lock_acquire+0xb0/0x200 [ 137.522621] __mutex_lock+0x86/0x9b0 [ 137.522623] mutex_lock_interruptible_nested+0x1b/0x20 [ 137.522640] i915_mutex_lock_interruptible+0x51/0x130 [i915] [ 137.522657] i915_gem_fault+0x20b/0x720 [i915] [ 137.522660] __do_fault+0x1e/0x80 [ 137.522662] __handle_mm_fault+0xa08/0xed0 [ 137.522664] handle_mm_fault+0x156/0x300 [ 137.522666] __do_page_fault+0x2c5/0x570 [ 137.522668] do_page_fault+0x28/0x250 [ 137.522671] page_fault+0x22/0x30 [ 137.522672] -> #2 (&mm->mmap_sem){++++}: [ 137.522677] __lock_acquire+0x1420/0x15e0 [ 137.522679] lock_acquire+0xb0/0x200 [ 137.522682] down_read+0x3e/0x70 [ 137.522699] __i915_gem_userptr_get_pages_worker+0x141/0x240 [i915] [ 137.522701] process_one_work+0x233/0x660 [ 137.522704] worker_thread+0x4e/0x3b0 [ 137.522706] kthread+0x152/0x190 [ 137.522708] ret_from_fork+0x27/0x40 [ 137.522710] -> #1 ((&work->work)){+.+.}: [ 137.522714] __lock_acquire+0x1420/0x15e0 [ 137.522717] lock_acquire+0xb0/0x200 [ 137.522719] process_one_work+0x206/0x660 [ 137.522721] worker_thread+0x4e/0x3b0 [ 137.522723] kthread+0x152/0x190 [ 137.522725] ret_from_fork+0x27/0x40 [ 137.522727] -> #0 ("i915-userptr-acquire"){+.+.}: [ 137.522731] check_prev_add+0x430/0x840 [ 137.522733] __lock_acquire+0x1420/0x15e0 [ 137.522735] lock_acquire+0xb0/0x200 [ 137.522738] flush_workqueue+0xb4/0x540 [ 137.522740] drain_workqueue+0xd4/0x1b0 [ 137.522742] destroy_workqueue+0x1c/0x200 [ 137.522758] i915_gem_cleanup_userptr+0x15/0x20 [i915] [ 137.522770] i915_gem_fini+0x5f/0xc0 [i915] [ 137.522782] i915_driver_unload+0x122/0x180 [i915] [ 137.522794] i915_pci_remove+0x19/0x30 [i915] [ 137.522797] pci_device_remove+0x39/0xb0 [ 137.522800] device_release_driver_internal+0x15d/0x220 [ 137.522803] driver_detach+0x40/0x80 [ 137.522805] bus_remove_driver+0x58/0xd0 [ 137.522807] driver_unregister+0x2c/0x40 [ 137.522809] pci_unregister_driver+0x36/0xb0 [ 137.522828] i915_exit+0x1a/0x8b [i915] [ 137.522831] SyS_delete_module+0x18c/0x1e0 [ 137.522834] entry_SYSCALL_64_fastpath+0x1c/0xb1 [ 137.522835] other info that might help us debug this: [ 137.522838] Chain exists of: "i915-userptr-acquire" --> &mm->mmap_sem --> &dev->struct_mutex [ 137.522844] Possible unsafe locking scenario: [ 137.522846] CPU0 CPU1 [ 137.522848] ---- ---- [ 137.522850] lock(&dev->struct_mutex); [ 137.522852] lock(&mm->mmap_sem); [ 137.522854] lock(&dev->struct_mutex); [ 137.522857] lock("i915-userptr-acquire"); [ 137.522859] *** DEADLOCK *** [ 137.522862] 3 locks held by drv_module_relo/1532: [ 137.522864] #0: (&dev->mutex){....}, at: [] device_release_driver_internal+0x2b/0x220 [ 137.522869] #1: (&dev->mutex){....}, at: [] device_release_driver_internal+0x39/0x220 [ 137.522873] #2: (&dev->struct_mutex){+.+.}, at: [] i915_gem_fini+0x3f/0xc0 [i915] [ 137.522888] stack backtrace: [ 137.522891] CPU: 0 PID: 1532 Comm: drv_module_relo Tainted: G U 4.14.0-rc4-CI-CI_DRM_3209+ #1 [ 137.522894] Hardware name: /NUC7i5BNB, BIOS BNKBL357.86A.0048.2017.0704.1415 07/04/2017 [ 137.522897] Call Trace: [ 137.522900] dump_stack+0x68/0x9f [ 137.522902] print_circular_bug+0x235/0x3c0 [ 137.522905] ? lockdep_init_map_crosslock+0x20/0x20 [ 137.522908] check_prev_add+0x430/0x840 [ 137.522919] ? i915_gem_fini+0x5f/0xc0 [i915] [ 137.522922] ? __kernel_text_address+0x12/0x40 [ 137.522925] ? __save_stack_trace+0x66/0xd0 [ 137.522928] __lock_acquire+0x1420/0x15e0 [ 137.522930] ? __lock_acquire+0x1420/0x15e0 [ 137.522933] ? lockdep_init_map_crosslock+0x20/0x20 [ 137.522936] ? __this_cpu_preempt_check+0x13/0x20 [ 137.522938] lock_acquire+0xb0/0x200 [ 137.522940] ? flush_workqueue+0x91/0x540 [ 137.522943] flush_workqueue+0xb4/0x540 [ 137.522945] ? flush_workqueue+0x91/0x540 [ 137.522948] ? __mutex_unlock_slowpath+0x43/0x2c0 [ 137.522951] ? trace_hardirqs_on_caller+0xe3/0x1b0 [ 137.522954] drain_workqueue+0xd4/0x1b0 [ 137.522956] ? drain_workqueue+0xd4/0x1b0 [ 137.522958] destroy_workqueue+0x1c/0x200 [ 137.522975] i915_gem_cleanup_userptr+0x15/0x20 [i915] [ 137.522987] i915_gem_fini+0x5f/0xc0 [i915] [ 137.523000] i915_driver_unload+0x122/0x180 [i915] [ 137.523015] i915_pci_remove+0x19/0x30 [i915] [ 137.523018] pci_device_remove+0x39/0xb0 [ 137.523021] device_release_driver_internal+0x15d/0x220 [ 137.523023] driver_detach+0x40/0x80 [ 137.523026] bus_remove_driver+0x58/0xd0 [ 137.523028] driver_unregister+0x2c/0x40 [ 137.523030] pci_unregister_driver+0x36/0xb0 [ 137.523049] i915_exit+0x1a/0x8b [i915] [ 137.523052] SyS_delete_module+0x18c/0x1e0 [ 137.523055] entry_SYSCALL_64_fastpath+0x1c/0xb1 [ 137.523057] RIP: 0033:0x7f7bd0609287 [ 137.523059] RSP: 002b:00007ffef694bc18 EFLAGS: 00000246 ORIG_RAX: 00000000000000b0 [ 137.523062] RAX: ffffffffffffffda RBX: ffffffff81493f33 RCX: 00007f7bd0609287 [ 137.523065] RDX: 0000000000000001 RSI: 0000000000000800 RDI: 0000564f999f9fc8 [ 137.523067] RBP: ffffc90005c4ff88 R08: 0000000000000000 R09: 0000000000000080 [ 137.523069] R10: 00007f7bd20ef8c0 R11: 0000000000000246 R12: 0000000000000000 [ 137.523072] R13: 00007ffef694be00 R14: 0000000000000000 R15: 0000000000000000 [ 137.523075] ? __this_cpu_preempt_check+0x13/0x20 Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171011141857.14161-1-chris@chris-wilson.co.uk Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f1e651703764..3db5851756f0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -615,9 +615,10 @@ static void i915_gem_fini(struct drm_i915_private *dev_priv) intel_uc_fini_hw(dev_priv); i915_gem_cleanup_engines(dev_priv); i915_gem_contexts_fini(dev_priv); - i915_gem_cleanup_userptr(dev_priv); mutex_unlock(&dev_priv->drm.struct_mutex); + i915_gem_cleanup_userptr(dev_priv); + i915_gem_drain_freed_objects(dev_priv); WARN_ON(!list_empty(&dev_priv->contexts.list)); -- cgit v1.2.3 From 9d25e3cc83d731ae4eeb017fd07562fde3f80bef Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 9 Oct 2017 13:40:23 +0200 Subject: iommu/exynos: Remove initconst attribute to avoid potential kernel oops Exynos SYSMMU registers standard platform device with sysmmu_of_match table, what means that this table is accessed every time a new platform device is registered in a system. This might happen also after the boot, so the table must not be attributed as initconst to avoid potential kernel oops caused by access to freed memory. Fixes: 6b21a5db3642 ("iommu/exynos: Support for device tree") Signed-off-by: Marek Szyprowski Reviewed-by: Krzysztof Kozlowski Signed-off-by: Joerg Roedel --- drivers/iommu/exynos-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index f596fcc32898..25c2c75f5332 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -709,7 +709,7 @@ static const struct dev_pm_ops sysmmu_pm_ops = { pm_runtime_force_resume) }; -static const struct of_device_id sysmmu_of_match[] __initconst = { +static const struct of_device_id sysmmu_of_match[] = { { .compatible = "samsung,exynos-sysmmu", }, { }, }; -- cgit v1.2.3 From c0368e4db4a3e8a3dce40f3f621c06e14c560d79 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 11 Oct 2017 14:59:22 -0700 Subject: spi: bcm-qspi: Fix use after free in bcm_qspi_probe() in error path There was an inversion in how the error path in bcm_qspi_probe() is done which would make us trip over a KASAN use-after-free report. Turns out that qspi->dev_ids does not get allocated until later in the probe process. Fix this by introducing a new lable: qspi_resource_err which takes care of cleaning up the SPI master instance. Fixes: fa236a7ef240 ("spi: bcm-qspi: Add Broadcom MSPI driver") Signed-off-by: Florian Fainelli Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-bcm-qspi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 6ef6c44f39f5..a172ab299e80 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -1250,7 +1250,7 @@ int bcm_qspi_probe(struct platform_device *pdev, goto qspi_probe_err; } } else { - goto qspi_probe_err; + goto qspi_resource_err; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); @@ -1272,7 +1272,7 @@ int bcm_qspi_probe(struct platform_device *pdev, qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); if (IS_ERR(qspi->base[CHIP_SELECT])) { ret = PTR_ERR(qspi->base[CHIP_SELECT]); - goto qspi_probe_err; + goto qspi_resource_err; } } @@ -1280,7 +1280,7 @@ int bcm_qspi_probe(struct platform_device *pdev, GFP_KERNEL); if (!qspi->dev_ids) { ret = -ENOMEM; - goto qspi_probe_err; + goto qspi_resource_err; } for (val = 0; val < num_irqs; val++) { @@ -1369,8 +1369,9 @@ qspi_reg_err: bcm_qspi_hw_uninit(qspi); clk_disable_unprepare(qspi->clk); qspi_probe_err: - spi_master_put(master); kfree(qspi->dev_ids); +qspi_resource_err: + spi_master_put(master); return ret; } /* probe function to be called by SoC specific platform driver probe */ -- cgit v1.2.3 From 612dde7ec306696d376d88d659f6287391d369a4 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Tue, 10 Oct 2017 17:33:55 +0300 Subject: drm/i915: Simplify intel_sanitize_enable_ppgtt Remove dead code around has_aliasing_ppgtt condition. Suggested-by: Colin Ian King Signed-off-by: Joonas Lahtinen Cc: Colin Ian King Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171010143355.16577-1-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index ca7fd34fbe8b..daba55a4fce2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -135,11 +135,12 @@ static inline void i915_ggtt_invalidate(struct drm_i915_private *i915) int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, int enable_ppgtt) { - bool has_aliasing_ppgtt; bool has_full_ppgtt; bool has_full_48bit_ppgtt; - has_aliasing_ppgtt = dev_priv->info.has_aliasing_ppgtt; + if (!dev_priv->info.has_aliasing_ppgtt) + return 0; + has_full_ppgtt = dev_priv->info.has_full_ppgtt; has_full_48bit_ppgtt = dev_priv->info.has_full_48bit_ppgtt; @@ -149,9 +150,6 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, has_full_48bit_ppgtt = intel_vgpu_has_full_48bit_ppgtt(dev_priv); } - if (!has_aliasing_ppgtt) - return 0; - /* * We don't allow disabling PPGTT for gen9+ as it's a requirement for * execlists, the sole mechanism available to submit work. @@ -188,7 +186,7 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, return 2; } - return has_aliasing_ppgtt ? 1 : 0; + return 1; } static int ppgtt_bind_vma(struct i915_vma *vma, -- cgit v1.2.3 From 2bbbd96357ce76cc45ec722c00f654aa7b189112 Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Mon, 28 Aug 2017 17:25:16 +0200 Subject: bus: mbus: fix window size calculation for 4GB windows At least the Armada XP SoC supports 4GB on a single DRAM window. Because the size register values contain the actual size - 1, the MSB is set in that case. For example, the SDRAM window's control register's value is 0xffffffe1 for 4GB (bits 31 to 24 contain the size). The MBUS driver reads back each window's size from registers and calculates the actual size as (control_reg | ~DDR_SIZE_MASK) + 1, which overflows for 32 bit values, resulting in other miscalculations further on (a bad RAM window for the CESA crypto engine calculated by mvebu_mbus_setup_cpu_target_nooverlap() in my case). This patch changes the type in 'struct mbus_dram_window' from u32 to u64, which allows us to keep using the same register calculation code in most MBUS-using drivers (which calculate ->size - 1 again). Fixes: fddddb52a6c4 ("bus: introduce an Marvell EBU MBus driver") CC: stable@vger.kernel.org Signed-off-by: Jan Luebbe Signed-off-by: Gregory CLEMENT --- drivers/bus/mvebu-mbus.c | 2 +- include/linux/mbus.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index c7f396903184..70db4d5638a6 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) if (mbus->hw_io_coherency) w->mbus_attr |= ATTR_HW_COHERENCY; w->base = base & DDR_BASE_CS_LOW_MASK; - w->size = (size | ~DDR_SIZE_MASK) + 1; + w->size = (u64)(size | ~DDR_SIZE_MASK) + 1; } } mvebu_mbus_dram_info.num_cs = cs; diff --git a/include/linux/mbus.h b/include/linux/mbus.h index 0d3f14fd2621..4773145246ed 100644 --- a/include/linux/mbus.h +++ b/include/linux/mbus.h @@ -31,8 +31,8 @@ struct mbus_dram_target_info struct mbus_dram_window { u8 cs_index; u8 mbus_attr; - u32 base; - u32 size; + u64 base; + u64 size; } cs[4]; }; -- cgit v1.2.3 From 27b94b4f1386c3a8181f5a0277434a32e24e7dd7 Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 1 Sep 2017 09:22:56 +0200 Subject: drm/amdgpu: fix placement flags in amdgpu_ttm_bind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we lose the NO_EVICT flag and can try to evict pinned BOs. Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 7ef6c28a34d9..bc746131987f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -834,7 +834,7 @@ int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem) placement.busy_placement = &placements; placements.fpfn = 0; placements.lpfn = adev->mc.gart_size >> PAGE_SHIFT; - placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; + placements.flags = bo->mem.placement | TTM_PL_FLAG_TT; r = ttm_bo_mem_space(bo, &placement, &tmp, true, false); if (unlikely(r)) -- cgit v1.2.3 From aa3c2ba1c3a7c25d0440a8ac3ddd266c0f43b7b7 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 12 Oct 2017 08:37:45 -0400 Subject: drm/msm/mdp5: add missing max size for 8x74 v1 This should have same max width as v2. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c index c2bdad88447e..824067d2d427 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c @@ -83,6 +83,8 @@ const struct mdp5_cfg_hw msm8x74v1_config = { .caps = MDP_LM_CAP_WB }, }, .nb_stages = 5, + .max_width = 2048, + .max_height = 0xFFFF, }, .dspp = { .count = 3, -- cgit v1.2.3 From f44001e2637138d9d506efe8da67011f8170e860 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 2 Oct 2017 10:28:37 -0400 Subject: drm/msm: use proper memory barriers for updating tail/head Fixes intermittent corruption of cmdstream dump. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_rd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 0366b8092f97..ec56794ad039 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -111,10 +111,14 @@ static void rd_write(struct msm_rd_state *rd, const void *buf, int sz) wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0); + /* Note that smp_load_acquire() is not strictly required + * as CIRC_SPACE_TO_END() does not access the tail more + * than once. + */ n = min(sz, circ_space_to_end(&rd->fifo)); memcpy(fptr, ptr, n); - fifo->head = (fifo->head + n) & (BUF_SZ - 1); + smp_store_release(&fifo->head, (fifo->head + n) & (BUF_SZ - 1)); sz -= n; ptr += n; @@ -145,13 +149,17 @@ static ssize_t rd_read(struct file *file, char __user *buf, if (ret) goto out; + /* Note that smp_load_acquire() is not strictly required + * as CIRC_CNT_TO_END() does not access the head more than + * once. + */ n = min_t(int, sz, circ_count_to_end(&rd->fifo)); if (copy_to_user(buf, fptr, n)) { ret = -EFAULT; goto out; } - fifo->tail = (fifo->tail + n) & (BUF_SZ - 1); + smp_store_release(&fifo->tail, (fifo->tail + n) & (BUF_SZ - 1)); *ppos += n; wake_up_all(&rd->fifo_event); -- cgit v1.2.3 From c9811d0fa55929b182f62e0ee49b71b0bea6a936 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 11 Oct 2017 11:36:56 +0000 Subject: drm/msm: fix return value check in _msm_gem_kernel_new() In case of error, the function msm_gem_get_vaddr() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). Fixes: 8223286d62e2 ("drm/msm: Add a helper function for in-kernel buffer allocations") Signed-off-by: Wei Yongjun Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index f15821a0d900..0b338fbf97ce 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1045,10 +1045,10 @@ static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size, } vaddr = msm_gem_get_vaddr(obj); - if (!vaddr) { + if (IS_ERR(vaddr)) { msm_gem_put_iova(obj, aspace); drm_gem_object_unreference(obj); - return ERR_PTR(-ENOMEM); + return ERR_CAST(vaddr); } if (bo) -- cgit v1.2.3 From a18a0ea0096833ecb52053b183fcf9709f7bafd8 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 6 Oct 2017 16:27:06 +0530 Subject: drm/msm/dsi: Use correct pm_runtime_put variant during host_init The DSI runtime PM suspend/resume callbacks check whether msm_host->cfg_hnd is non-NULL before trying to enable the bus clocks. This is done to accommodate early calls to these functions that may happen before the bus clocks are even initialized. Calling pm_runtime_put_autosuspend() in dsi_host_init() can result in racy behaviour since msm_host->cfg_hnd is set very soon after. If the suspend callback happens too late, we end up trying to disable clocks that were never enabled, resulting in a bunch of WARN_ON splats. Use pm_runtime_put_sync() so that the suspend callback is called immediately. Reported-by: Nicolas Dechesne Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index dbb31a014419..deaf869374ea 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -248,7 +248,7 @@ disable_clks: clk_disable_unprepare(ahb_clk); disable_gdsc: regulator_disable(gdsc_reg); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); put_clk: clk_put(ahb_clk); put_gdsc: -- cgit v1.2.3 From 9e4621531e2af230611c28c67306a31e1a09f76a Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 6 Oct 2017 16:27:07 +0530 Subject: drm/msm/mdp5: Remove extra pm_runtime_put call in mdp5_crtc_cursor_set() While converting mdp5_enable/disable() calls to pm_runtime_get/put() API, an extra call to pm_runtime_put_autosuspend() crept in mdp5_crtc_cursor_set(). This results in calling the suspend handler twice, and therefore clk_disables twice, which isn't a nice thing to do. Fixes: d68fe15b1878 (drm/msm/mdp5: Use runtime PM get/put API instead ...) Reported-by: Stanimir Varbanov Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 6fcb58ab718c..440977677001 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -804,8 +804,6 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); - pm_runtime_put_autosuspend(&pdev->dev); - set_cursor: ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable); if (ret) { -- cgit v1.2.3 From db179e0d0d1003f10b798e072524be6bcdae5053 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 26 Sep 2017 15:25:10 +0900 Subject: of: do not leak console options Do not strdup() console options. It seems that the only reason for it to be strdup()-ed was a compilation warning: printk, UART and console drivers, for some reason, expect char pointer instead of const char pointer. So we can just pass `of_stdout_options', but need to cast it to char pointer. A better fix would be to change printk, console drivers and UART to accept const char `options'; but that will take time - there are lots of drivers to update. The patch also fixes a possible memory leak: add_preferred_console() can fail, but we don't kfree() options. Signed-off-by: Sergey Senozhatsky Reviewed-by: Petr Mladek Signed-off-by: Rob Herring --- drivers/of/base.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index 260d33c0f26c..63897531cd75 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1781,8 +1781,12 @@ bool of_console_check(struct device_node *dn, char *name, int index) { if (!dn || dn != of_stdout || console_set_on_cmdline) return false; - return !add_preferred_console(name, index, - kstrdup(of_stdout_options, GFP_KERNEL)); + + /* + * XXX: cast `options' to char pointer to suppress complication + * warnings: printk, UART and console drivers expect char pointer. + */ + return !add_preferred_console(name, index, (char *)of_stdout_options); } EXPORT_SYMBOL_GPL(of_console_check); -- cgit v1.2.3 From 22f8cc6e33731678e7687a18ffd0f578131edb4c Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Tue, 26 Sep 2017 18:40:00 +1000 Subject: drivers: of: increase MAX_RESERVED_REGIONS to 32 There are two types of memory reservations firmware can ask the kernel to make in the device tree: static and dynamic. See Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt If you have greater than 16 entries in /reserved-memory (as we do on POWER9 systems) you would get this scary looking error message: [ 0.000000] OF: reserved mem: not enough space all defined regions. This is harmless if all your reservations are static (which with OPAL on POWER9, they are). It is not harmless if you have any dynamic reservations after the 16th. In the first pass over the fdt to find reservations, the child nodes of /reserved-memory are added to a static array in of_reserved_mem.c so that memory can be reserved in a 2nd pass. The array has 16 entries. This is why, on my dual socket POWER9 system, I get that error 4 times with 20 static reservations. We don't have a problem on ppc though, as in arch/powerpc/kernel/prom.c we look at the new style /reserved-ranges property to do reservations, and this logic was introduced in 0962e8004e974 (well before any powernv system shipped). A Google search shows up no occurances of that exact error message, so we're probably safe in that no machine that people use has memory not being reserved when it should be. The simple fix is to bump the length of the array to 32 which "should be enough for everyone(TM)". The simple fix of not recording static allocations in the array would cause problems for devices with "memory-region" properties. A more future-proof fix is likely possible, although more invasive and this simple fix is perfectly suitable in the meantime while a more future-proof fix is developed. Signed-off-by: Stewart Smith Tested-by: Mauricio Faria de Oliveira Signed-off-by: Rob Herring --- drivers/of/of_reserved_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index d507c3569a88..32771c2ced7b 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -25,7 +25,7 @@ #include #include -#define MAX_RESERVED_REGIONS 16 +#define MAX_RESERVED_REGIONS 32 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; static int reserved_mem_count; -- cgit v1.2.3 From 3314c6bdd26880e0dfbcb0cb85a1b36d185ce47c Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Tue, 22 Aug 2017 02:19:12 +0200 Subject: device property: preserve usecount for node passed to of_fwnode_graph_get_port_parent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using CONFIG_OF_DYNAMIC=y uncovered an imbalance in the usecount of the node being passed to of_fwnode_graph_get_port_parent(). Preserve the usecount by using of_get_parent() instead of of_get_next_parent() which don't decrement the usecount of the node passed to it. Fixes: 3b27d00e7b6d7c88 ("device property: Move fwnode graph ops to firmware specific locations") Signed-off-by: Niklas Söderlund Acked-by: Sakari Ailus Signed-off-by: Rob Herring --- drivers/of/property.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/property.c b/drivers/of/property.c index fbb72116e9d4..264c355ba1ff 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -954,7 +954,7 @@ of_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode) struct device_node *np; /* Get the parent of the port */ - np = of_get_next_parent(to_of_node(fwnode)); + np = of_get_parent(to_of_node(fwnode)); if (!np) return NULL; -- cgit v1.2.3 From fa9caf0b6e69703ff8a4d4da17897008ec2f2dd3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 Oct 2017 21:05:11 +0300 Subject: drm/i915: Update DRIVER_DATE to 20171012 Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6bbc4b83aa0a..c7b2ca6aff05 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -80,8 +80,8 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20170929" -#define DRIVER_TIMESTAMP 1506682238 +#define DRIVER_DATE "20171012" +#define DRIVER_TIMESTAMP 1507831511 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions -- cgit v1.2.3 From 4d90f2d507ab4634e9e1923de3a6769ac0aa71fa Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 12 Oct 2017 16:02:01 +0300 Subject: drm/i915: Start tracking PSR state in crtc state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the minimal amount of PSR tracking into the crtc state. This allows precomputing the possibility of using PSR correctly, and it means we can safely call the psr enable/disable functions for any DP endcoder. As a nice bonus we get rid of some more crtc->config usage, which we want to kill off eventually. v2: Fix 'goto unlock' fail in intel_psr_enable() (Jani) Check intel_dp_is_edp() in is_edp_psr() (Jani) Cc: Rodrigo Vivi Cc: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171012130201.21318-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula Acked-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_dp.c | 2 + drivers/gpu/drm/i915/intel_drv.h | 5 +++ drivers/gpu/drm/i915/intel_psr.c | 85 +++++++++++++++++++++------------------- 3 files changed, 52 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b0f446b68f42..753404280a19 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1832,6 +1832,8 @@ found: if (!HAS_DDI(dev_priv)) intel_dp_set_clock(encoder, pipe_config); + intel_psr_compute_config(intel_dp, pipe_config); + return true; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b87946dcc53f..d61985f93d40 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -718,6 +718,9 @@ struct intel_crtc_state { struct intel_link_m_n dp_m2_n2; bool has_drrs; + bool has_psr; + bool has_psr2; + /* * Frequence the dpll for the port should run at. Differs from the * adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also @@ -1764,6 +1767,8 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, void intel_psr_init(struct drm_i915_private *dev_priv); void intel_psr_single_frame_update(struct drm_i915_private *dev_priv, unsigned frontbuffer_bits); +void intel_psr_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state); /* intel_runtime_pm.c */ int intel_power_domains_init(struct drm_i915_private *); diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 5419cda83ba8..93b177cc4cbf 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -58,6 +58,9 @@ static bool is_edp_psr(struct intel_dp *intel_dp) { + if (!intel_dp_is_edp(intel_dp)) + return false; + return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; } @@ -376,22 +379,25 @@ static void hsw_psr_activate(struct intel_dp *intel_dp) hsw_activate_psr1(intel_dp); } -static bool intel_psr_match_conditions(struct intel_dp *intel_dp) +void intel_psr_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_crtc *crtc = dig_port->base.base.crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); const struct drm_display_mode *adjusted_mode = - &intel_crtc->config->base.adjusted_mode; + &crtc_state->base.adjusted_mode; int psr_setup_time; - lockdep_assert_held(&dev_priv->psr.lock); - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + if (!HAS_PSR(dev_priv)) + return; - dev_priv->psr.source_ok = false; + if (!is_edp_psr(intel_dp)) + return; + + if (!i915_modparams.enable_psr) { + DRM_DEBUG_KMS("PSR disable by flag\n"); + return; + } /* * HSW spec explicitly says PSR is tied to port A. @@ -402,66 +408,70 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp) */ if (HAS_DDI(dev_priv) && dig_port->port != PORT_A) { DRM_DEBUG_KMS("PSR condition failed: Port not supported\n"); - return false; - } - - if (!i915_modparams.enable_psr) { - DRM_DEBUG_KMS("PSR disable by flag\n"); - return false; + return; } if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && !dev_priv->psr.link_standby) { DRM_ERROR("PSR condition failed: Link off requested but not supported on this platform\n"); - return false; + return; } if (IS_HASWELL(dev_priv) && - I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config->cpu_transcoder)) & + I915_READ(HSW_STEREO_3D_CTL(crtc_state->cpu_transcoder)) & S3D_ENABLE) { DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n"); - return false; + return; } if (IS_HASWELL(dev_priv) && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n"); - return false; + return; } psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd); if (psr_setup_time < 0) { DRM_DEBUG_KMS("PSR condition failed: Invalid PSR setup time (0x%02x)\n", intel_dp->psr_dpcd[1]); - return false; + return; } if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) > adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay - 1) { DRM_DEBUG_KMS("PSR condition failed: PSR setup time (%d us) too long\n", psr_setup_time); - return false; + return; + } + + /* + * FIXME psr2_support is messed up. It's both computed + * dynamically during PSR enable, and extracted from sink + * caps during eDP detection. + */ + if (!dev_priv->psr.psr2_support) { + crtc_state->has_psr = true; + return; } /* PSR2 is restricted to work with panel resolutions upto 3200x2000 */ - if (dev_priv->psr.psr2_support && - (intel_crtc->config->pipe_src_w > 3200 || - intel_crtc->config->pipe_src_h > 2000)) { - dev_priv->psr.psr2_support = false; - return false; + if (adjusted_mode->crtc_hdisplay > 3200 || + adjusted_mode->crtc_vdisplay > 2000) { + DRM_DEBUG_KMS("PSR2 disabled, panel resolution too big\n"); + return; } /* * FIXME:enable psr2 only for y-cordinate psr2 panels * After gtc implementation , remove this restriction. */ - if (!dev_priv->psr.y_cord_support && dev_priv->psr.psr2_support) { + if (!dev_priv->psr.y_cord_support) { DRM_DEBUG_KMS("PSR2 disabled, panel does not support Y coordinate\n"); - return false; + return; } - dev_priv->psr.source_ok = true; - return true; + crtc_state->has_psr = true; + crtc_state->has_psr2 = true; } static void intel_psr_activate(struct intel_dp *intel_dp) @@ -531,13 +541,8 @@ void intel_psr_enable(struct intel_dp *intel_dp, struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - if (!HAS_PSR(dev_priv)) - return; - - if (!is_edp_psr(intel_dp)) { - DRM_DEBUG_KMS("PSR not supported by this panel\n"); + if (!crtc_state->has_psr) return; - } WARN_ON(dev_priv->drrs.dp); mutex_lock(&dev_priv->psr.lock); @@ -546,8 +551,8 @@ void intel_psr_enable(struct intel_dp *intel_dp, goto unlock; } - if (!intel_psr_match_conditions(intel_dp)) - goto unlock; + dev_priv->psr.psr2_support = crtc_state->has_psr2; + dev_priv->psr.source_ok = true; dev_priv->psr.busy_frontbuffer_bits = 0; @@ -668,7 +673,7 @@ void intel_psr_disable(struct intel_dp *intel_dp, struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - if (!HAS_PSR(dev_priv)) + if (!old_crtc_state->has_psr) return; mutex_lock(&dev_priv->psr.lock); -- cgit v1.2.3 From 6bd6ae2dfc7e091059fd8a650579bb1efc9b4b9f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 24 Aug 2017 14:24:29 -0400 Subject: drm/msm: fix error path cleanup If we fail to attach iommu, gpu->aspace could be IS_ERR().. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index ffbff27600e0..6a887032c66a 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -718,7 +718,8 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) msm_gem_put_iova(gpu->rb->bo, gpu->aspace); msm_ringbuffer_destroy(gpu->rb); } - if (gpu->aspace) { + + if (!IS_ERR_OR_NULL(gpu->aspace)) { gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu, NULL, 0); msm_gem_address_space_put(gpu->aspace); -- cgit v1.2.3 From 06451a3d1d777141dedfa947649cbb0c594ac3af Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 12 Sep 2017 14:23:05 -0400 Subject: drm/msm: fix _NO_IMPLICIT fencing case We need to call reservation_object_reserve_shared() in both cases, but this wasn't happening in the _NO_IMPLICIT submit case. Fixes: f0a42bb ("drm/msm: submit support for in-fences") Reported-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 11 ----------- drivers/gpu/drm/msm/msm_gem_submit.c | 24 ++++++++++++++++++------ 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 0b338fbf97ce..ea5bb0e1632c 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -610,17 +610,6 @@ int msm_gem_sync_object(struct drm_gem_object *obj, struct dma_fence *fence; int i, ret; - if (!exclusive) { - /* NOTE: _reserve_shared() must happen before _add_shared_fence(), - * which makes this a slightly strange place to call it. OTOH this - * is a convenient can-fail point to hook it in. (And similar to - * how etnaviv and nouveau handle this.) - */ - ret = reservation_object_reserve_shared(msm_obj->resv); - if (ret) - return ret; - } - fobj = reservation_object_get_list(msm_obj->resv); if (!fobj || (fobj->shared_count == 0)) { fence = reservation_object_get_excl(msm_obj->resv); diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 5d0a75d4b249..93535cac0676 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -221,7 +221,7 @@ fail: return ret; } -static int submit_fence_sync(struct msm_gem_submit *submit) +static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit) { int i, ret = 0; @@ -229,6 +229,20 @@ static int submit_fence_sync(struct msm_gem_submit *submit) struct msm_gem_object *msm_obj = submit->bos[i].obj; bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE; + if (!write) { + /* NOTE: _reserve_shared() must happen before + * _add_shared_fence(), which makes this a slightly + * strange place to call it. OTOH this is a + * convenient can-fail point to hook it in. + */ + ret = reservation_object_reserve_shared(msm_obj->resv); + if (ret) + return ret; + } + + if (no_implicit) + continue; + ret = msm_gem_sync_object(&msm_obj->base, submit->gpu->fctx, write); if (ret) break; @@ -451,11 +465,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (ret) goto out; - if (!(args->flags & MSM_SUBMIT_NO_IMPLICIT)) { - ret = submit_fence_sync(submit); - if (ret) - goto out; - } + ret = submit_fence_sync(submit, !!(args->flags & MSM_SUBMIT_NO_IMPLICIT)); + if (ret) + goto out; ret = submit_pin_objects(submit); if (ret) -- cgit v1.2.3 From 55b4f1ce2f23692c57205b9974fba61baa4b9321 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 12 Oct 2017 13:57:24 +0100 Subject: drm/i915: Fix eviction when the GGTT is idle but full In the full-ppgtt world, we can fill the GGTT full of context objects. These context objects are currently implicitly tracked by the requests that pin them i.e. they are only unpinned when the request is completed and retired, but we do not have the link from the vma to the request (anymore). In order to unpin those contexts, we have to issue another request and wait upon the switch to the kernel context. The bug during eviction was that we assumed that a full GGTT meant we would have requests on the GGTT timeline, and so we missed situations where those requests where merely in flight (and when even they have not yet been submitted to hw yet). The fix employed here is to change the already-is-idle test to no look at the execution timeline, but count the outstanding requests and then check that we have switched to the kernel context. Erring on the side of overkill here just means that we stall a little longer than may be strictly required, but we only expect to hit this path in extreme corner cases where returning an erroneous error is worse than the delay. v2: Logical inversion when swapping over branches. Fixes: 80b204bce8f2 ("drm/i915: Enable multiple timelines") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20171012125726.14736-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_evict.c | 63 ++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index a5a5b7e6daae..ee4811ffb7aa 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -33,21 +33,20 @@ #include "intel_drv.h" #include "i915_trace.h" -static bool ggtt_is_idle(struct drm_i915_private *dev_priv) +static bool ggtt_is_idle(struct drm_i915_private *i915) { - struct i915_ggtt *ggtt = &dev_priv->ggtt; - struct intel_engine_cs *engine; - enum intel_engine_id id; + struct intel_engine_cs *engine; + enum intel_engine_id id; - for_each_engine(engine, dev_priv, id) { - struct intel_timeline *tl; + if (i915->gt.active_requests) + return false; - tl = &ggtt->base.timeline.engine[engine->id]; - if (i915_gem_active_isset(&tl->last_request)) - return false; - } + for_each_engine(engine, i915, id) { + if (engine->last_retired_context != i915->kernel_context) + return false; + } - return true; + return true; } static int ggtt_flush(struct drm_i915_private *i915) @@ -157,7 +156,8 @@ i915_gem_evict_something(struct i915_address_space *vm, min_size, alignment, cache_level, start, end, mode); - /* Retire before we search the active list. Although we have + /* + * Retire before we search the active list. Although we have * reasonable accuracy in our retirement lists, we may have * a stray pin (preventing eviction) that can only be resolved by * retiring. @@ -182,7 +182,8 @@ search_again: BUG_ON(ret); } - /* Can we unpin some objects such as idle hw contents, + /* + * Can we unpin some objects such as idle hw contents, * or pending flips? But since only the GGTT has global entries * such as scanouts, rinbuffers and contexts, we can skip the * purge when inspecting per-process local address spaces. @@ -190,19 +191,33 @@ search_again: if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK) return -ENOSPC; - if (ggtt_is_idle(dev_priv)) { - /* If we still have pending pageflip completions, drop - * back to userspace to give our workqueues time to - * acquire our locks and unpin the old scanouts. - */ - return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC; - } + /* + * Not everything in the GGTT is tracked via VMA using + * i915_vma_move_to_active(), otherwise we could evict as required + * with minimal stalling. Instead we are forced to idle the GPU and + * explicitly retire outstanding requests which will then remove + * the pinning for active objects such as contexts and ring, + * enabling us to evict them on the next iteration. + * + * To ensure that all user contexts are evictable, we perform + * a switch to the perma-pinned kernel context. This all also gives + * us a termination condition, when the last retired context is + * the kernel's there is no more we can evict. + */ + if (!ggtt_is_idle(dev_priv)) { + ret = ggtt_flush(dev_priv); + if (ret) + return ret; - ret = ggtt_flush(dev_priv); - if (ret) - return ret; + goto search_again; + } - goto search_again; + /* + * If we still have pending pageflip completions, drop + * back to userspace to give our workqueues time to + * acquire our locks and unpin the old scanouts. + */ + return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC; found: /* drm_mm doesn't allow any other other operations while -- cgit v1.2.3 From 214707fc2ce08d09982bc4fe4b7a1c1f010e82be Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 12 Oct 2017 13:57:25 +0100 Subject: drm/i915/selftests: Wrap a timer into a i915_sw_fence For some selftests, we want to issue requests but delay them going to hardware. Furthermore, we don't want those requests to block indefinitely (or else we may hang the driver and block testing) so we want to employ a timeout. So naturally we want a fence that is automatically signaled by a timer. v2: Add kselftests. v3: Limit the API available to selftests; there isn't an overwhelming reason to export it universally. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20171012125726.14736-2-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_sw_fence.c | 10 ++++ drivers/gpu/drm/i915/selftests/i915_sw_fence.c | 42 ++++++++++++++ drivers/gpu/drm/i915/selftests/lib_sw_fence.c | 78 ++++++++++++++++++++++++++ drivers/gpu/drm/i915/selftests/lib_sw_fence.h | 42 ++++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 drivers/gpu/drm/i915/selftests/lib_sw_fence.c create mode 100644 drivers/gpu/drm/i915/selftests/lib_sw_fence.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 808ea4d5b962..ca33cc08cb07 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -41,6 +41,11 @@ static inline void debug_fence_init(struct i915_sw_fence *fence) debug_object_init(fence, &i915_sw_fence_debug_descr); } +static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) +{ + debug_object_init_on_stack(fence, &i915_sw_fence_debug_descr); +} + static inline void debug_fence_activate(struct i915_sw_fence *fence) { debug_object_activate(fence, &i915_sw_fence_debug_descr); @@ -79,6 +84,10 @@ static inline void debug_fence_init(struct i915_sw_fence *fence) { } +static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) +{ +} + static inline void debug_fence_activate(struct i915_sw_fence *fence) { } @@ -507,5 +516,6 @@ int i915_sw_fence_await_reservation(struct i915_sw_fence *fence, } #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +#include "selftests/lib_sw_fence.c" #include "selftests/i915_sw_fence.c" #endif diff --git a/drivers/gpu/drm/i915/selftests/i915_sw_fence.c b/drivers/gpu/drm/i915/selftests/i915_sw_fence.c index 19d145d6bf52..ea01d0fe3ace 100644 --- a/drivers/gpu/drm/i915/selftests/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/selftests/i915_sw_fence.c @@ -24,6 +24,7 @@ #include #include +#include #include "../i915_selftest.h" @@ -565,6 +566,46 @@ err_in: return ret; } +static int test_timer(void *arg) +{ + unsigned long target, delay; + struct timed_fence tf; + + timed_fence_init(&tf, target = jiffies); + if (!i915_sw_fence_done(&tf.fence)) { + pr_err("Fence with immediate expiration not signaled\n"); + goto err; + } + timed_fence_fini(&tf); + + for_each_prime_number(delay, i915_selftest.timeout_jiffies/2) { + timed_fence_init(&tf, target = jiffies + delay); + if (i915_sw_fence_done(&tf.fence)) { + pr_err("Fence with future expiration (%lu jiffies) already signaled\n", delay); + goto err; + } + + i915_sw_fence_wait(&tf.fence); + if (!i915_sw_fence_done(&tf.fence)) { + pr_err("Fence not signaled after wait\n"); + goto err; + } + if (time_before(jiffies, target)) { + pr_err("Fence signaled too early, target=%lu, now=%lu\n", + target, jiffies); + goto err; + } + + timed_fence_fini(&tf); + } + + return 0; + +err: + timed_fence_fini(&tf); + return -EINVAL; +} + int i915_sw_fence_mock_selftests(void) { static const struct i915_subtest tests[] = { @@ -576,6 +617,7 @@ int i915_sw_fence_mock_selftests(void) SUBTEST(test_C_AB), SUBTEST(test_chain), SUBTEST(test_ipc), + SUBTEST(test_timer), }; return i915_subtests(tests, NULL); diff --git a/drivers/gpu/drm/i915/selftests/lib_sw_fence.c b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c new file mode 100644 index 000000000000..3790fdf44a1a --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c @@ -0,0 +1,78 @@ +/* + * Copyright © 2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "lib_sw_fence.h" + +/* Small library of different fence types useful for writing tests */ + +static int __i915_sw_fence_call +nop_fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) +{ + return NOTIFY_DONE; +} + +void __onstack_fence_init(struct i915_sw_fence *fence, + const char *name, + struct lock_class_key *key) +{ + debug_fence_init_onstack(fence); + + __init_waitqueue_head(&fence->wait, name, key); + atomic_set(&fence->pending, 1); + fence->flags = (unsigned long)nop_fence_notify; +} + +void onstack_fence_fini(struct i915_sw_fence *fence) +{ + i915_sw_fence_commit(fence); + i915_sw_fence_fini(fence); +} + +static void timed_fence_wake(unsigned long data) +{ + struct timed_fence *tf = (struct timed_fence *)data; + + i915_sw_fence_commit(&tf->fence); +} + +void timed_fence_init(struct timed_fence *tf, unsigned long expires) +{ + onstack_fence_init(&tf->fence); + + setup_timer_on_stack(&tf->timer, timed_fence_wake, (unsigned long)tf); + + if (time_after(expires, jiffies)) + mod_timer(&tf->timer, expires); + else + i915_sw_fence_commit(&tf->fence); +} + +void timed_fence_fini(struct timed_fence *tf) +{ + if (del_timer_sync(&tf->timer)) + i915_sw_fence_commit(&tf->fence); + + destroy_timer_on_stack(&tf->timer); + i915_sw_fence_fini(&tf->fence); +} diff --git a/drivers/gpu/drm/i915/selftests/lib_sw_fence.h b/drivers/gpu/drm/i915/selftests/lib_sw_fence.h new file mode 100644 index 000000000000..474aafb92ae1 --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/lib_sw_fence.h @@ -0,0 +1,42 @@ +/* + * lib_sw_fence.h - library routines for testing N:M synchronisation points + * + * Copyright (C) 2017 Intel Corporation + * + * This file is released under the GPLv2. + * + */ + +#ifndef _LIB_SW_FENCE_H_ +#define _LIB_SW_FENCE_H_ + +#include + +#include "../i915_sw_fence.h" + +#ifdef CONFIG_LOCKDEP +#define onstack_fence_init(fence) \ +do { \ + static struct lock_class_key __key; \ + \ + __onstack_fence_init((fence), #fence, &__key); \ +} while (0) +#else +#define onstack_fence_init(fence) \ + __onstack_fence_init((fence), NULL, NULL) +#endif + +void __onstack_fence_init(struct i915_sw_fence *fence, + const char *name, + struct lock_class_key *key); +void onstack_fence_fini(struct i915_sw_fence *fence); + +struct timed_fence { + struct i915_sw_fence fence; + struct timer_list timer; +}; + +void timed_fence_init(struct timed_fence *tf, unsigned long expires); +void timed_fence_fini(struct timed_fence *tf); + +#endif /* _LIB_SW_FENCE_H_ */ -- cgit v1.2.3 From 9c1477e83e629632758518cde4a039d62a1000e7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 12 Oct 2017 13:57:26 +0100 Subject: drm/i915/selftests: Exercise adding requests to a full GGTT A bug recently encountered involved the issue where are we were submitting requests to different ppGTT, each would pin a segment of the GGTT for its logical context and ring. However, this is invisible to eviction as we do not tie the context/ring VMA to a request and so do not automatically wait upon it them (instead they are marked as pinned, preventing eviction entirely). Instead the eviction code must flush those contexts by switching to the kernel context. This selftest tries to fill the GGTT with contexts to exercise a path where the switch-to-kernel-context failed to make forward progress and we fail with ENOSPC. v2: Make the hole in the filled GGTT explicit. v3: Swap out the arbitrary timeout for a private notification from i915_gem_evict_something() Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20171012125726.14736-3-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem_evict.c | 7 + drivers/gpu/drm/i915/selftests/i915_gem_evict.c | 154 +++++++++++++++++++++ .../gpu/drm/i915/selftests/i915_live_selftests.h | 1 + drivers/gpu/drm/i915/selftests/mock_context.c | 6 +- 4 files changed, 163 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index ee4811ffb7aa..8daa8a78cdc0 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -33,6 +33,10 @@ #include "intel_drv.h" #include "i915_trace.h" +I915_SELFTEST_DECLARE(static struct igt_evict_ctl { + bool fail_if_busy:1; +} igt_evict_ctl;) + static bool ggtt_is_idle(struct drm_i915_private *i915) { struct intel_engine_cs *engine; @@ -205,6 +209,9 @@ search_again: * the kernel's there is no more we can evict. */ if (!ggtt_is_idle(dev_priv)) { + if (I915_SELFTEST_ONLY(igt_evict_ctl.fail_if_busy)) + return -EBUSY; + ret = ggtt_flush(dev_priv); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index 5ea373221f49..473aa9631145 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -24,6 +24,9 @@ #include "../i915_selftest.h" +#include "lib_sw_fence.h" +#include "mock_context.h" +#include "mock_drm.h" #include "mock_gem_device.h" static int populate_ggtt(struct drm_i915_private *i915) @@ -325,6 +328,148 @@ cleanup: return err; } +static int igt_evict_contexts(void *arg) +{ + const u64 PRETEND_GGTT_SIZE = 16ull << 20; + struct drm_i915_private *i915 = arg; + struct intel_engine_cs *engine; + enum intel_engine_id id; + struct reserved { + struct drm_mm_node node; + struct reserved *next; + } *reserved = NULL; + struct drm_mm_node hole; + unsigned long count; + int err; + + /* + * The purpose of this test is to verify that we will trigger an + * eviction in the GGTT when constructing a request that requires + * additional space in the GGTT for pinning the context. This space + * is not directly tied to the request so reclaiming it requires + * extra work. + * + * As such this test is only meaningful for full-ppgtt environments + * where the GTT space of the request is separate from the GGTT + * allocation required to build the request. + */ + if (!USES_FULL_PPGTT(i915)) + return 0; + + mutex_lock(&i915->drm.struct_mutex); + + /* Reserve a block so that we know we have enough to fit a few rq */ + memset(&hole, 0, sizeof(hole)); + err = i915_gem_gtt_insert(&i915->ggtt.base, &hole, + PRETEND_GGTT_SIZE, 0, I915_COLOR_UNEVICTABLE, + 0, i915->ggtt.base.total, + PIN_NOEVICT); + if (err) + goto out_locked; + + /* Make the GGTT appear small by filling it with unevictable nodes */ + count = 0; + do { + struct reserved *r; + + r = kcalloc(1, sizeof(*r), GFP_KERNEL); + if (!r) { + err = -ENOMEM; + goto out_locked; + } + + if (i915_gem_gtt_insert(&i915->ggtt.base, &r->node, + 1ul << 20, 0, I915_COLOR_UNEVICTABLE, + 0, i915->ggtt.base.total, + PIN_NOEVICT)) { + kfree(r); + break; + } + + r->next = reserved; + reserved = r; + + count++; + } while (1); + drm_mm_remove_node(&hole); + mutex_unlock(&i915->drm.struct_mutex); + pr_info("Filled GGTT with %lu 1MiB nodes\n", count); + + /* Overfill the GGTT with context objects and so try to evict one. */ + for_each_engine(engine, i915, id) { + struct i915_sw_fence fence; + struct drm_file *file; + + file = mock_file(i915); + if (IS_ERR(file)) + return PTR_ERR(file); + + count = 0; + mutex_lock(&i915->drm.struct_mutex); + onstack_fence_init(&fence); + do { + struct drm_i915_gem_request *rq; + struct i915_gem_context *ctx; + + ctx = live_context(i915, file); + if (!ctx) + break; + + /* We will need some GGTT space for the rq's context */ + igt_evict_ctl.fail_if_busy = true; + rq = i915_gem_request_alloc(engine, ctx); + igt_evict_ctl.fail_if_busy = false; + + if (IS_ERR(rq)) { + /* When full, fail_if_busy will trigger EBUSY */ + if (PTR_ERR(rq) != -EBUSY) { + pr_err("Unexpected error from request alloc (ctx hw id %u, on %s): %d\n", + ctx->hw_id, engine->name, + (int)PTR_ERR(rq)); + err = PTR_ERR(rq); + } + break; + } + + /* Keep every request/ctx pinned until we are full */ + err = i915_sw_fence_await_sw_fence_gfp(&rq->submit, + &fence, + GFP_KERNEL); + if (err < 0) + break; + + i915_add_request(rq); + count++; + err = 0; + } while(1); + mutex_unlock(&i915->drm.struct_mutex); + + onstack_fence_fini(&fence); + pr_info("Submitted %lu contexts/requests on %s\n", + count, engine->name); + + mock_file_free(i915, file); + if (err) + break; + } + + mutex_lock(&i915->drm.struct_mutex); +out_locked: + while (reserved) { + struct reserved *next = reserved->next; + + drm_mm_remove_node(&reserved->node); + kfree(reserved); + + reserved = next; + } + if (drm_mm_node_allocated(&hole)) + drm_mm_remove_node(&hole); + mutex_unlock(&i915->drm.struct_mutex); + + return err; +} + int i915_gem_evict_mock_selftests(void) { static const struct i915_subtest tests[] = { @@ -348,3 +493,12 @@ int i915_gem_evict_mock_selftests(void) drm_dev_unref(&i915->drm); return err; } + +int i915_gem_evict_live_selftests(struct drm_i915_private *i915) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_evict_contexts), + }; + + return i915_subtests(tests, i915); +} diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h index 64acd7eccc5c..54a73534b37e 100644 --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h @@ -15,6 +15,7 @@ selftest(objects, i915_gem_object_live_selftests) selftest(dmabuf, i915_gem_dmabuf_live_selftests) selftest(coherency, i915_gem_coherency_live_selftests) selftest(gtt, i915_gem_gtt_live_selftests) +selftest(evict, i915_gem_evict_live_selftests) selftest(hugepages, i915_gem_huge_page_live_selftests) selftest(contexts, i915_gem_context_live_selftests) selftest(hangcheck, intel_hangcheck_live_selftests) diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c b/drivers/gpu/drm/i915/selftests/mock_context.c index 098ce643ad07..bbf80d42e793 100644 --- a/drivers/gpu/drm/i915/selftests/mock_context.c +++ b/drivers/gpu/drm/i915/selftests/mock_context.c @@ -73,11 +73,7 @@ err_put: void mock_context_close(struct i915_gem_context *ctx) { - i915_gem_context_set_closed(ctx); - - i915_ppgtt_close(&ctx->ppgtt->base); - - i915_gem_context_put(ctx); + context_close(ctx); } void mock_init_contexts(struct drm_i915_private *i915) -- cgit v1.2.3 From 67680d3c046450b3901aa4e5a9cf2f8fbd7ed9a2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 11 Oct 2017 17:20:12 +0200 Subject: drm: vblank: use ktime_t instead of timeval The drm vblank handling uses 'timeval' to store timestamps in either monotonic or wall-clock time base. In either case, it reads the current time as a ktime_t in get_drm_timestamp() and converts it from there. This is a bit suspicious, as users of 'timeval' often suffer from the time_t overflow in y2038. I have gone through this code and found that it is unlikely to cause problems here: - The user space ABI does not use time_t or timeval, but uses 'u32' and 'long' as the types. This means at least that rebuilding user programs against a new libc with 64-bit time_t does not change the ABI. - As of commit c61eef726a78 ("drm: add support for monotonic vblank timestamps") in linux-3.8, the monotonic timestamp is the default and can only get reverted to wall-clock through a module-parameter. - With the default monotonic timestamps, there is no problem at all. - The drm_wait_vblank_ioctl() interface is alway safe on 64-bit architectures, on 32-bit it might overflow the 'long' timestamps in 2038 with wall-clock timestamps. - The event handling uses 'u32' seconds, which overflow in 2106 on both 32-bit and 64-bit machines, when wall-clock timestamps are used. - The effect of overflowing either of the two is only temporary (during the overflow, and is likely to keep working again afterwards. It is likely the same problem as observing a 'settimeofday()' call, which was the reason for moving to the monotonic timestamps in the first place. Overall, this seems good enough, so my patch removes the use of 'timeval' from the vblank handling altogether and uses ktime_t consistently, except for the part where we copy the data to user space structures in the existing format. Signed-off-by: Arnd Bergmann Reviewed-by: Sean Paul Reviewed-by: Keith Packard Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_vblank.c | 123 +++++++++++++++++++++++-------------------- include/drm/drm_drv.h | 2 +- include/drm/drm_vblank.h | 6 +-- 3 files changed, 71 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 70f2b9593edc..c605c3ad6b6e 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -78,7 +78,7 @@ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, - struct timeval *tvblank, bool in_vblank_irq); + ktime_t *tvblank, bool in_vblank_irq); static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ @@ -99,7 +99,7 @@ MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); static void store_vblank(struct drm_device *dev, unsigned int pipe, u32 vblank_count_inc, - struct timeval *t_vblank, u32 last) + ktime_t t_vblank, u32 last) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; @@ -108,7 +108,7 @@ static void store_vblank(struct drm_device *dev, unsigned int pipe, vblank->last = last; write_seqlock(&vblank->seqlock); - vblank->time = *t_vblank; + vblank->time = t_vblank; vblank->count += vblank_count_inc; write_sequnlock(&vblank->seqlock); } @@ -151,7 +151,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe { u32 cur_vblank; bool rc; - struct timeval t_vblank; + ktime_t t_vblank; int count = DRM_TIMESTAMP_MAXRETRIES; spin_lock(&dev->vblank_time_lock); @@ -171,13 +171,13 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe * interrupt and assign 0 for now, to mark the vblanktimestamp as invalid. */ if (!rc) - t_vblank = (struct timeval) {0, 0}; + t_vblank = 0; /* * +1 to make sure user will never see the same * vblank counter value before and after a modeset */ - store_vblank(dev, pipe, 1, &t_vblank, cur_vblank); + store_vblank(dev, pipe, 1, t_vblank, cur_vblank); spin_unlock(&dev->vblank_time_lock); } @@ -200,7 +200,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 cur_vblank, diff; bool rc; - struct timeval t_vblank; + ktime_t t_vblank; int count = DRM_TIMESTAMP_MAXRETRIES; int framedur_ns = vblank->framedur_ns; @@ -225,11 +225,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, /* trust the hw counter when it's around */ diff = (cur_vblank - vblank->last) & dev->max_vblank_count; } else if (rc && framedur_ns) { - const struct timeval *t_old; - u64 diff_ns; - - t_old = &vblank->time; - diff_ns = timeval_to_ns(&t_vblank) - timeval_to_ns(t_old); + u64 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time)); /* * Figure out how many vblanks we've missed based @@ -278,9 +274,9 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, * for now, to mark the vblanktimestamp as invalid. */ if (!rc && !in_vblank_irq) - t_vblank = (struct timeval) {0, 0}; + t_vblank = 0; - store_vblank(dev, pipe, diff, &t_vblank, cur_vblank); + store_vblank(dev, pipe, diff, t_vblank, cur_vblank); } static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe) @@ -556,7 +552,7 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * @pipe: index of CRTC whose vblank timestamp to retrieve * @max_error: Desired maximum allowable error in timestamps (nanosecs) * On return contains true maximum error of timestamp - * @vblank_time: Pointer to struct timeval which should receive the timestamp + * @vblank_time: Pointer to time which should receive the timestamp * @in_vblank_irq: * True when called from drm_crtc_handle_vblank(). Some drivers * need to apply some workarounds for gpu-specific vblank irq quirks @@ -584,10 +580,10 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, - struct timeval *vblank_time, + ktime_t *vblank_time, bool in_vblank_irq) { - struct timeval tv_etime; + struct timespec64 ts_etime, ts_vblank_time; ktime_t stime, etime; bool vbl_status; struct drm_crtc *crtc; @@ -680,29 +676,27 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, etime = ktime_mono_to_real(etime); /* save this only for debugging purposes */ - tv_etime = ktime_to_timeval(etime); + ts_etime = ktime_to_timespec64(etime); + ts_vblank_time = ktime_to_timespec64(*vblank_time); /* Subtract time delta from raw timestamp to get final * vblank_time timestamp for end of vblank. */ etime = ktime_sub_ns(etime, delta_ns); - *vblank_time = ktime_to_timeval(etime); + *vblank_time = etime; - DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", + DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %lld.%06ld -> %lld.%06ld [e %d us, %d rep]\n", pipe, hpos, vpos, - (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, - (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, - duration_ns/1000, i); + (u64)ts_etime.tv_sec, ts_etime.tv_nsec / 1000, + (u64)ts_vblank_time.tv_sec, ts_vblank_time.tv_nsec / 1000, + duration_ns / 1000, i); return true; } EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); -static struct timeval get_drm_timestamp(void) +static ktime_t get_drm_timestamp(void) { - ktime_t now; - - now = drm_timestamp_monotonic ? ktime_get() : ktime_get_real(); - return ktime_to_timeval(now); + return drm_timestamp_monotonic ? ktime_get() : ktime_get_real(); } /** @@ -710,7 +704,7 @@ static struct timeval get_drm_timestamp(void) * vblank interval * @dev: DRM device * @pipe: index of CRTC whose vblank timestamp to retrieve - * @tvblank: Pointer to target struct timeval which should receive the timestamp + * @tvblank: Pointer to target time which should receive the timestamp * @in_vblank_irq: * True when called from drm_crtc_handle_vblank(). Some drivers * need to apply some workarounds for gpu-specific vblank irq quirks @@ -728,7 +722,7 @@ static struct timeval get_drm_timestamp(void) */ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, - struct timeval *tvblank, bool in_vblank_irq) + ktime_t *tvblank, bool in_vblank_irq) { bool ret = false; @@ -769,14 +763,14 @@ u32 drm_crtc_vblank_count(struct drm_crtc *crtc) EXPORT_SYMBOL(drm_crtc_vblank_count); static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, - struct timeval *vblanktime) + ktime_t *vblanktime) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 vblank_count; unsigned int seq; if (WARN_ON(pipe >= dev->num_crtcs)) { - *vblanktime = (struct timeval) { 0 }; + *vblanktime = 0; return 0; } @@ -793,7 +787,7 @@ static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, * drm_crtc_vblank_count_and_time - retrieve "cooked" vblank counter value * and the system timestamp corresponding to that vblank counter value * @crtc: which counter to retrieve - * @vblanktime: Pointer to struct timeval to receive the vblank timestamp. + * @vblanktime: Pointer to time to receive the vblank timestamp. * * Fetches the "cooked" vblank count value that represents the number of * vblank events since the system was booted, including lost events due to @@ -801,7 +795,7 @@ static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, * of the vblank interval that corresponds to the current vblank counter value. */ u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, - struct timeval *vblanktime) + ktime_t *vblanktime) { return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc), vblanktime); @@ -810,11 +804,18 @@ EXPORT_SYMBOL(drm_crtc_vblank_count_and_time); static void send_vblank_event(struct drm_device *dev, struct drm_pending_vblank_event *e, - unsigned long seq, struct timeval *now) + unsigned long seq, ktime_t now) { + struct timespec64 tv = ktime_to_timespec64(now); + e->event.sequence = seq; - e->event.tv_sec = now->tv_sec; - e->event.tv_usec = now->tv_usec; + /* + * e->event is a user space structure, with hardcoded unsigned + * 32-bit seconds/microseconds. This will overflow in 2106 for + * drm_timestamp_monotonic==0, but not with drm_timestamp_monotonic==1 + */ + e->event.tv_sec = tv.tv_sec; + e->event.tv_usec = tv.tv_nsec / 1000; trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, e->event.sequence); @@ -891,7 +892,7 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; unsigned int seq, pipe = drm_crtc_index(crtc); - struct timeval now; + ktime_t now; if (dev->num_crtcs > 0) { seq = drm_vblank_count_and_time(dev, pipe, &now); @@ -902,7 +903,7 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, } e->pipe = pipe; e->event.crtc_id = crtc->base.id; - send_vblank_event(dev, e, seq, &now); + send_vblank_event(dev, e, seq, now); } EXPORT_SYMBOL(drm_crtc_send_vblank_event); @@ -1100,7 +1101,8 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc) unsigned int pipe = drm_crtc_index(crtc); struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; struct drm_pending_vblank_event *e, *t; - struct timeval now; + + ktime_t now; unsigned long irqflags; unsigned int seq; @@ -1141,7 +1143,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc) e->event.sequence, seq); list_del(&e->base.link); drm_vblank_put(dev, pipe); - send_vblank_event(dev, e, seq, &now); + send_vblank_event(dev, e, seq, now); } spin_unlock_irqrestore(&dev->event_lock, irqflags); @@ -1321,7 +1323,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; struct drm_pending_vblank_event *e; - struct timeval now; + ktime_t now; unsigned long flags; unsigned int seq; int ret; @@ -1367,7 +1369,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, e->event.sequence = vblwait->request.sequence; if (vblank_passed(seq, vblwait->request.sequence)) { drm_vblank_put(dev, pipe); - send_vblank_event(dev, e, seq, &now); + send_vblank_event(dev, e, seq, now); vblwait->reply.sequence = seq; } else { /* drm_handle_vblank_events will call drm_vblank_put */ @@ -1398,6 +1400,24 @@ static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait) _DRM_VBLANK_NEXTONMISS)); } +static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe, + struct drm_wait_vblank_reply *reply) +{ + ktime_t now; + struct timespec64 ts; + + /* + * drm_wait_vblank_reply is a UAPI structure that uses 'long' + * to store the seconds. This will overflow in y2038 on 32-bit + * architectures with drm_timestamp_monotonic==0, but not with + * drm_timestamp_monotonic==1 (the default). + */ + reply->sequence = drm_vblank_count_and_time(dev, pipe, &now); + ts = ktime_to_timespec64(now); + reply->tval_sec = (u32)ts.tv_sec; + reply->tval_usec = ts.tv_nsec / 1000; +} + int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -1439,12 +1459,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, if (dev->vblank_disable_immediate && drm_wait_vblank_is_query(vblwait) && READ_ONCE(vblank->enabled)) { - struct timeval now; - - vblwait->reply.sequence = - drm_vblank_count_and_time(dev, pipe, &now); - vblwait->reply.tval_sec = now.tv_sec; - vblwait->reply.tval_usec = now.tv_usec; + drm_wait_vblank_reply(dev, pipe, &vblwait->reply); return 0; } @@ -1487,11 +1502,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, } if (ret != -EINTR) { - struct timeval now; - - vblwait->reply.sequence = drm_vblank_count_and_time(dev, pipe, &now); - vblwait->reply.tval_sec = now.tv_sec; - vblwait->reply.tval_usec = now.tv_usec; + drm_wait_vblank_reply(dev, pipe, &vblwait->reply); DRM_DEBUG("crtc %d returning %u to client\n", pipe, vblwait->reply.sequence); @@ -1507,7 +1518,7 @@ done: static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) { struct drm_pending_vblank_event *e, *t; - struct timeval now; + ktime_t now; unsigned int seq; assert_spin_locked(&dev->event_lock); @@ -1525,7 +1536,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) list_del(&e->base.link); drm_vblank_put(dev, pipe); - send_vblank_event(dev, e, seq, &now); + send_vblank_event(dev, e, seq, now); } trace_drm_vblank_event(pipe, seq); diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index ee06ecd6c01f..412e83a4d3db 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -324,7 +324,7 @@ struct drm_driver { */ bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, - struct timeval *vblank_time, + ktime_t *vblank_time, bool in_vblank_irq); /** diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index 7fba9efe4951..6a58e2e91a0f 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -92,7 +92,7 @@ struct drm_vblank_crtc { /** * @time: Vblank timestamp corresponding to @count. */ - struct timeval time; + ktime_t time; /** * @refcount: Number of users/waiters of the vblank interrupt. Only when @@ -154,7 +154,7 @@ struct drm_vblank_crtc { int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); u32 drm_crtc_vblank_count(struct drm_crtc *crtc); u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, - struct timeval *vblanktime); + ktime_t *vblanktime); void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e); void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, @@ -172,7 +172,7 @@ u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, - struct timeval *vblank_time, + ktime_t *vblank_time, bool in_vblank_irq); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); -- cgit v1.2.3 From 25e1a79874eb3821d93310c908cc0a81b47af060 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 11 Oct 2017 17:20:13 +0200 Subject: drm: vblank: remove drm_timestamp_monotonic parameter There is a risk of overflowing vblank timestamps in 2038 or 2106 if someone sets the drm_timestamp_monotonic module parameter to zero. I found no indication of anyone ever setting the parameter, or complaining about the default being wrong, after it was introduced as a way to handle backwards-compatibility with linux prior to c61eef726a78 ("drm: add support for monotonic vblank timestamps"), so it's probably safer to just remove the parameter completely and only allowing the default behavior. Signed-off-by: Arnd Bergmann Acked-by: Daniel Stone Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_internal.h | 1 - drivers/gpu/drm/drm_ioctl.c | 2 +- drivers/gpu/drm/drm_vblank.c | 29 ++++++----------------------- 3 files changed, 7 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index fbc3f308fa19..edd921adcf33 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -55,7 +55,6 @@ int drm_clients_info(struct seq_file *m, void* data); int drm_gem_name_info(struct seq_file *m, void *data); /* drm_vblank.c */ -extern unsigned int drm_timestamp_monotonic; void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe); void drm_vblank_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index a9ae6dd2d593..a78f03155466 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -235,7 +235,7 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ /* Only some caps make sense with UMS/render-only drivers. */ switch (req->capability) { case DRM_CAP_TIMESTAMP_MONOTONIC: - req->value = drm_timestamp_monotonic; + req->value = 1; return 0; case DRM_CAP_PRIME: req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0; diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index c605c3ad6b6e..810a93fc558b 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -82,20 +82,12 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ -/* - * Default to use monotonic timestamps for wait-for-vblank and page-flip - * complete events. - */ -unsigned int drm_timestamp_monotonic = 1; - static int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); -module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)"); MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); -MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); static void store_vblank(struct drm_device *dev, unsigned int pipe, u32 vblank_count_inc, @@ -672,9 +664,6 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, delta_ns = div_s64(1000000LL * (vpos * mode->crtc_htotal + hpos), mode->crtc_clock); - if (!drm_timestamp_monotonic) - etime = ktime_mono_to_real(etime); - /* save this only for debugging purposes */ ts_etime = ktime_to_timespec64(etime); ts_vblank_time = ktime_to_timespec64(*vblank_time); @@ -694,11 +683,6 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, } EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); -static ktime_t get_drm_timestamp(void) -{ - return drm_timestamp_monotonic ? ktime_get() : ktime_get_real(); -} - /** * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent * vblank interval @@ -738,7 +722,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, * Return current monotonic/gettimeofday timestamp as best estimate. */ if (!ret) - *tvblank = get_drm_timestamp(); + *tvblank = ktime_get(); return ret; } @@ -811,8 +795,8 @@ static void send_vblank_event(struct drm_device *dev, e->event.sequence = seq; /* * e->event is a user space structure, with hardcoded unsigned - * 32-bit seconds/microseconds. This will overflow in 2106 for - * drm_timestamp_monotonic==0, but not with drm_timestamp_monotonic==1 + * 32-bit seconds/microseconds. This is safe as we always use + * monotonic timestamps since linux-4.15 */ e->event.tv_sec = tv.tv_sec; e->event.tv_usec = tv.tv_nsec / 1000; @@ -899,7 +883,7 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, } else { seq = 0; - now = get_drm_timestamp(); + now = ktime_get(); } e->pipe = pipe; e->event.crtc_id = crtc->base.id; @@ -1408,9 +1392,8 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe, /* * drm_wait_vblank_reply is a UAPI structure that uses 'long' - * to store the seconds. This will overflow in y2038 on 32-bit - * architectures with drm_timestamp_monotonic==0, but not with - * drm_timestamp_monotonic==1 (the default). + * to store the seconds. This is safe as we always use monotonic + * timestamps since linux-4.15. */ reply->sequence = drm_vblank_count_and_time(dev, pipe, &now); ts = ktime_to_timespec64(now); -- cgit v1.2.3 From 6fa228ba96f8c35de2f1ec9eabaa45d3865b1d0c Mon Sep 17 00:00:00 2001 From: James Ausmus Date: Thu, 12 Oct 2017 14:30:36 -0700 Subject: drm/i915: Fix DP_AUX_CH_CTL_TIME_OUT naming Rename DP_AUX_CH_CTL_TIME_OUT_1600us to DP_AUX_CH_CTL_TIME_OUT_MAX, as the meaning of the (3 << 26) value varies per platform, but it's always the maximum timeout for that platform. Pre-CNL it means 1600us, and for CNL it means 3200us. v2: -Split in to two patches (Rodrigo) Cc: Rodrigo Vivi Signed-off-by: James Ausmus Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171012213037.4245-1-james.ausmus@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 2 +- drivers/gpu/drm/i915/intel_dp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d2d0a83c09b6..5f99d4d6291b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5242,7 +5242,7 @@ enum { #define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26) #define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26) #define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_1600us (3 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_MAX (3 << 26) /* Varies per platform */ #define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26) #define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25) #define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 753404280a19..3f0d37fa833f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1032,7 +1032,7 @@ static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp, DP_AUX_CH_CTL_DONE | (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) | DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_TIME_OUT_1600us | + DP_AUX_CH_CTL_TIME_OUT_MAX | DP_AUX_CH_CTL_RECEIVE_ERROR | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) | -- cgit v1.2.3 From 8f5f63d558b979402ae48f3df2f7bc3589531e28 Mon Sep 17 00:00:00 2001 From: James Ausmus Date: Thu, 12 Oct 2017 14:30:37 -0700 Subject: drm/i915/bdw: Fix DP_AUX_CH_CTL_TIME_OUT setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per BSpec, 400us is "BDW+ Do not use this setting." - not just PORT_A. Set BDW to 600us unconditionally. v2: -Split in to two patches (Rodrigo) Cc: Jani Nikula Cc: Ville Syrjälä Signed-off-by: James Ausmus Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171012213037.4245-2-james.ausmus@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3f0d37fa833f..4b65cf137f79 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1007,7 +1007,7 @@ static uint32_t g4x_get_aux_send_ctl(struct intel_dp *intel_dp, else precharge = 5; - if (IS_BROADWELL(dev_priv) && intel_dig_port->port == PORT_A) + if (IS_BROADWELL(dev_priv)) timeout = DP_AUX_CH_CTL_TIME_OUT_600us; else timeout = DP_AUX_CH_CTL_TIME_OUT_400us; -- cgit v1.2.3 From f687e25a7a245952349f1f9f9cc238ac5a3be258 Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Thu, 12 Oct 2017 22:10:08 +0530 Subject: drm: Add retries for lspcon mode detection From the CI builds, its been observed that during a driver reload/insert, dp dual mode read function sometimes fails to read from LSPCON device over i2c-over-aux channel. This patch: - adds some delay and few retries, allowing a scope for these devices to settle down and respond. - changes one error log's level from ERROR->DEBUG as we want to call it an error only after all the retries are exhausted. V2: Addressed review comments from Jani (for loop for retry) V3: Addressed review comments from Imre (break on partial read too) V3: Addressed review comments from Ville/Imre (Add the retries exclusively for LSPCON, not for all dp_dual_mode devices) V4: Added r-b from Imre, sending it to dri-devel (Jani) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102294 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102295 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102359 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103186 Cc: Ville Syrjala Cc: Imre Deak Cc: Jani Nikula Reviewed-by: Imre Deak Acked-by: Dave Airlie Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507826408-19322-1-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/drm_dp_dual_mode_helper.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c index 0ef9011a1856..02a50929af67 100644 --- a/drivers/gpu/drm/drm_dp_dual_mode_helper.c +++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c @@ -410,6 +410,7 @@ int drm_lspcon_get_mode(struct i2c_adapter *adapter, { u8 data; int ret = 0; + int retry; if (!mode) { DRM_ERROR("NULL input\n"); @@ -417,10 +418,19 @@ int drm_lspcon_get_mode(struct i2c_adapter *adapter, } /* Read Status: i2c over aux */ - ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_LSPCON_CURRENT_MODE, - &data, sizeof(data)); + for (retry = 0; retry < 6; retry++) { + if (retry) + usleep_range(500, 1000); + + ret = drm_dp_dual_mode_read(adapter, + DP_DUAL_MODE_LSPCON_CURRENT_MODE, + &data, sizeof(data)); + if (!ret) + break; + } + if (ret < 0) { - DRM_ERROR("LSPCON read(0x80, 0x41) failed\n"); + DRM_DEBUG_KMS("LSPCON read(0x80, 0x41) failed\n"); return -EFAULT; } -- cgit v1.2.3 From d18aef0f75436abb95894a230b504432df26c167 Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Tue, 10 Oct 2017 15:37:43 +0530 Subject: drm/i915: Don't give up waiting on INVALID_MODE Our current logic to read LSPCON's current mode, stops retries and breaks wait-loop, if it gets LSPCON_MODE_INVALID as return from the core function. This doesn't allow us to try reading the mode again. This patch removes this condition and allows retries reading the currnt mode until timeout. This also fixes/prevents some of the noise in form of debug messages while running IGT CI test cases. V2: rebase, added r-b V2: changed some debug message levels from debug->error and error->debug in lspcon_get_current_mode function. V3: Rebase Cc: Imre Deak Cc: Daniel Vetter Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102294 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102295 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102359 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103186 Reviewed-by: Imre Deak Signed-off-by: Shashank Sharma Signed-off-by: Mahesh Kumar Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507630064-17908-3-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_lspcon.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index beb9baaf2f2e..768825472754 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -56,7 +56,7 @@ static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc; if (drm_lspcon_get_mode(adapter, ¤t_mode)) { - DRM_ERROR("Error reading LSPCON mode\n"); + DRM_DEBUG_KMS("Error reading LSPCON mode\n"); return DRM_LSPCON_MODE_INVALID; } return current_mode; @@ -68,16 +68,15 @@ static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon, enum drm_lspcon_mode current_mode; current_mode = lspcon_get_current_mode(lspcon); - if (current_mode == mode || current_mode == DRM_LSPCON_MODE_INVALID) + if (current_mode == mode) goto out; DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n", lspcon_mode_name(mode)); - wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode || - current_mode == DRM_LSPCON_MODE_INVALID, 100); + wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 100); if (current_mode != mode) - DRM_DEBUG_KMS("LSPCON mode hasn't settled\n"); + DRM_ERROR("LSPCON mode hasn't settled\n"); out: DRM_DEBUG_KMS("Current LSPCON mode %s\n", -- cgit v1.2.3 From a2fc4bd61e7ec3bb1f7c8b3d47272be813f88aea Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Tue, 10 Oct 2017 15:37:44 +0530 Subject: drm/i915: Add retries for LSPCON detection We read the dp dual mode Adapter identifier to detect the LSPCON device. It's been observed from the CI testing that in few cases, this read can get delayed or fail. For such scenarios, LSPCON vendors suggest to retry the read operation. This patch adds retry in the probe function, while reading LSPCON identifier. V3: added this patch in the series Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102294 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102295 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102359 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103186 Cc: Ville Syrjala Cc: Imre Deak Signed-off-by: Shashank Sharma Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507630064-17908-4-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_lspcon.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 768825472754..dcbc786479f9 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -132,6 +132,7 @@ static bool lspcon_wake_native_aux_ch(struct intel_lspcon *lspcon) static bool lspcon_probe(struct intel_lspcon *lspcon) { + int retry; enum drm_dp_dual_mode_type adaptor_type; struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc; enum drm_lspcon_mode expected_mode; @@ -140,10 +141,18 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) DRM_LSPCON_MODE_PCON : DRM_LSPCON_MODE_LS; /* Lets probe the adaptor and check its type */ - adaptor_type = drm_dp_dual_mode_detect(adapter); + for (retry = 0; retry < 6; retry++) { + if (retry) + usleep_range(500, 1000); + + adaptor_type = drm_dp_dual_mode_detect(adapter); + if (adaptor_type == DRM_DP_DUAL_MODE_LSPCON) + break; + } + if (adaptor_type != DRM_DP_DUAL_MODE_LSPCON) { DRM_DEBUG_KMS("No LSPCON detected, found %s\n", - drm_dp_get_dual_mode_type_name(adaptor_type)); + drm_dp_get_dual_mode_type_name(adaptor_type)); return false; } -- cgit v1.2.3 From ce99f7206c9105851d97202ed08c058af6f11ac4 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 12 Oct 2017 12:19:46 +0300 Subject: drm/tilcdc: Precalculate total frametime in tilcdc_crtc_set_mode() We need the total frame refresh time to check if we are too close to vertical sync when updating the two framebuffer DMA registers and risk a collision. This new method is more accurate that the previous that based on mode's vrefresh value, which itself is inaccurate or may not even be initialized. Reported-by: Kevin Hao Fixes: 11abbc9f39e0 ("drm/tilcdc: Set framebuffer DMA address to HW only if CRTC is enabled") Cc: # v4.11+ Signed-off-by: Jyri Sarha Reviewed-by: Tomi Valkeinen --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 704db2443b5e..6ef4d1a1e3a9 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "tilcdc_drv.h" #include "tilcdc_regs.h" @@ -48,6 +49,7 @@ struct tilcdc_crtc { unsigned int lcd_fck_rate; ktime_t last_vblank; + unsigned int hvtotal_us; struct drm_framebuffer *curr_fb; struct drm_framebuffer *next_fb; @@ -292,6 +294,12 @@ static void tilcdc_crtc_set_clk(struct drm_crtc *crtc) LCDC_V2_CORE_CLK_EN); } +uint tilcdc_mode_hvtotal(const struct drm_display_mode *mode) +{ + return (uint) div_u64(1000llu * mode->htotal * mode->vtotal, + mode->clock); +} + static void tilcdc_crtc_set_mode(struct drm_crtc *crtc) { struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); @@ -459,6 +467,9 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc) drm_framebuffer_get(fb); crtc->hwmode = crtc->state->adjusted_mode; + + tilcdc_crtc->hvtotal_us = + tilcdc_mode_hvtotal(&crtc->hwmode); } static void tilcdc_crtc_enable(struct drm_crtc *crtc) @@ -642,7 +653,7 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc, spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); next_vblank = ktime_add_us(tilcdc_crtc->last_vblank, - 1000000 / crtc->hwmode.vrefresh); + tilcdc_crtc->hvtotal_us); tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get())); if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US) -- cgit v1.2.3 From 44cd3939c111b78a9fc6e3136fb0f9b6f475f68a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 13 Oct 2017 00:47:55 -0700 Subject: drm/tilcdc: Remove redundant OF_DETACHED flag setting of_fdt_unflatten_tree() already sets the flag on this node to OF_DETACHED, because of_fdt_unflatten_tree() calls __unflatten_device_tree() with the detached bool set to true. Cc: Rob Herring Cc: Frank Rowand Signed-off-by: Stephen Boyd Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c index 623a9140493c..482299a6f3b0 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c @@ -163,7 +163,6 @@ static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft) return NULL; } - of_node_set_flag(overlay, OF_DETACHED); ret = of_resolve_phandles(overlay); if (ret) { pr_err("%s: Failed to resolve phandles: %d\n", __func__, ret); -- cgit v1.2.3 From 4d58443dddf95e7f1de73f60b8490426eb300b10 Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Fri, 13 Oct 2017 13:24:46 +0300 Subject: drm/i915: Get rid of hardcoded pipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Favor for_each_pipe() macro when looping through pipes. Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/1507890286-16214-1-git-send-email-mika.kahola@intel.com Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_dp_mst.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 3c131e2544cf..f7c782576162 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -454,9 +454,10 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_connector *intel_connector; struct drm_connector *connector; - int i; + enum pipe pipe; intel_connector = intel_connector_alloc(); if (!intel_connector) @@ -470,9 +471,9 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo intel_connector->mst_port = intel_dp; intel_connector->port = port; - for (i = PIPE_A; i <= PIPE_C; i++) { + for_each_pipe(dev_priv, pipe) { drm_mode_connector_attach_encoder(&intel_connector->base, - &intel_dp->mst_encoders[i]->base.base); + &intel_dp->mst_encoders[pipe]->base.base); } drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0); @@ -569,11 +570,12 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum static bool intel_dp_create_fake_mst_encoders(struct intel_digital_port *intel_dig_port) { - int i; struct intel_dp *intel_dp = &intel_dig_port->dp; + struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); + enum pipe pipe; - for (i = PIPE_A; i <= PIPE_C; i++) - intel_dp->mst_encoders[i] = intel_dp_create_fake_mst_encoder(intel_dig_port, i); + for_each_pipe(dev_priv, pipe) + intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(intel_dig_port, pipe); return true; } -- cgit v1.2.3 From c3ed110386db97e8213151ddc665adedf6cd11df Mon Sep 17 00:00:00 2001 From: Harsha Sharma Date: Mon, 9 Oct 2017 17:36:43 +0530 Subject: drm/i915: Replace *_reference/unreference() or *_ref/unref with _get/put() Replace instances of drm_framebuffer_reference/unreference() with *_get/put() suffixes and drm_dev_unref with *_put() suffix because get/put is shorter and consistent with the kernel use of *_get/put suffixes. Done with following coccinelle semantic patch @@ expression ex; @@ ( -drm_framebuffer_unreference(ex); +drm_framebuffer_put(ex); | -drm_dev_unref(ex); +drm_dev_put(ex); | -drm_framebuffer_reference(ex); +drm_framebuffer_get(ex); ) Signed-off-by: Harsha Sharma [danvet: Drop the drm_dev_put change for now, to make the patch apply with out a backmerge.] Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171009120643.11953-1-harshasharmaiitr@gmail.com --- drivers/gpu/drm/i915/intel_display.c | 10 +++++----- drivers/gpu/drm/i915/intel_fbdev.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 932d846e2456..98c64e65cd15 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2847,7 +2847,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, if (intel_plane_ggtt_offset(state) == plane_config->base) { fb = c->primary->fb; - drm_framebuffer_reference(fb); + drm_framebuffer_get(fb); goto valid_fb; } } @@ -2878,7 +2878,7 @@ valid_fb: intel_crtc->pipe, PTR_ERR(intel_state->vma)); intel_state->vma = NULL; - drm_framebuffer_unreference(fb); + drm_framebuffer_put(fb); return; } @@ -2899,7 +2899,7 @@ valid_fb: if (i915_gem_object_is_tiled(obj)) dev_priv->preserve_bios_swizzle = true; - drm_framebuffer_reference(fb); + drm_framebuffer_get(fb); primary->fb = primary->state->fb = fb; primary->crtc = primary->state->crtc = &intel_crtc->base; @@ -9846,7 +9846,7 @@ mode_fits_in_fbdev(struct drm_device *dev, if (obj->base.size < mode->vdisplay * fb->pitches[0]) return NULL; - drm_framebuffer_reference(fb); + drm_framebuffer_get(fb); return fb; #else return NULL; @@ -10027,7 +10027,7 @@ found: if (ret) goto fail; - drm_framebuffer_unreference(fb); + drm_framebuffer_put(fb); ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); if (ret) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index f2bb8116227c..b8af35187d22 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -189,7 +189,7 @@ static int intelfb_create(struct drm_fb_helper *helper, " releasing it\n", intel_fb->base.width, intel_fb->base.height, sizes->fb_width, sizes->fb_height); - drm_framebuffer_unreference(&intel_fb->base); + drm_framebuffer_put(&intel_fb->base); intel_fb = ifbdev->fb = NULL; } if (!intel_fb || WARN_ON(!intel_fb->obj)) { @@ -627,7 +627,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8; ifbdev->fb = fb; - drm_framebuffer_reference(&ifbdev->fb->base); + drm_framebuffer_get(&ifbdev->fb->base); /* Final pass to check if any active pipes don't have fbs */ for_each_crtc(dev, crtc) { -- cgit v1.2.3 From c427a475b6bc9d3304cca04acdec53464f71f24c Mon Sep 17 00:00:00 2001 From: Shanker Donthineni Date: Sat, 23 Sep 2017 13:50:19 -0500 Subject: irqchip/gic-v3-its: Fix the incorrect BUG_ON in its_init_vpe_domain() The driver probe path hits 'BUG_ON(entries != vpe_proxy.dev->nr_ites)' on systems where it has VLPI capability, doesn't support direct LPI feature and boot with a single CPU. Relax the BUG_ON() condition to fix the issue. Signed-off-by: Shanker Donthineni Signed-off-by: Marc Zyngier --- drivers/irqchip/irq-gic-v3-its.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e8d89343d613..e3a59f43def8 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -2851,7 +2851,7 @@ static int its_init_vpe_domain(void) return -ENOMEM; } - BUG_ON(entries != vpe_proxy.dev->nr_ites); + BUG_ON(entries > vpe_proxy.dev->nr_ites); raw_spin_lock_init(&vpe_proxy.lock); vpe_proxy.next_victim = 0; -- cgit v1.2.3 From 32bd44dc19de012e22f1fdebd2606b5fb86d54c5 Mon Sep 17 00:00:00 2001 From: Shanker Donthineni Date: Sat, 7 Oct 2017 15:43:48 -0500 Subject: irqchip/gic-v3-its: Fix the incorrect parsing of VCPU table size The VCPU table consists of vPE entries, and its size provides the number of VPEs supported by GICv4 hardware. Unfortunately the maximum size of the VPE table is not discoverable like Device table. All VLPI commands limits the number of bits to 16 to hold VPEID, which is index into VCPU table. Don't apply DEVID bits for VCPU table instead assume maximum bits to 16. ITS log messages on QDF2400 without fix: allocated 524288 Devices (indirect, esz 8, psz 64K, shr 1) allocated 8192 Interrupt Collections (flat, esz 8, psz 64K, shr 1) Virtual CPUs Table too large, reduce ids 32->26 Virtual CPUs too large, reduce ITS pages 8192->256 allocated 2097152 Virtual CPUs (flat, esz 8, psz 64K, shr 1) ITS log messages on QDF2400 with fix: allocated 524288 Devices (indirect, esz 8, psz 64K, shr 1) allocated 8192 Interrupt Collections (flat, esz 8, psz 64K, shr 1) allocated 65536 Virtual CPUs (flat, esz 8, psz 64K, shr 1) Signed-off-by: Shanker Donthineni Signed-off-by: Marc Zyngier --- drivers/irqchip/irq-gic-v3-its.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e3a59f43def8..991cf33750c6 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -107,6 +107,10 @@ struct its_node { #define ITS_ITT_ALIGN SZ_256 +/* The maximum number of VPEID bits supported by VLPI commands */ +#define ITS_MAX_VPEID_BITS (16) +#define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS)) + /* Convert page order to size in bytes */ #define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o)) @@ -1582,13 +1586,12 @@ retry_baser: static bool its_parse_indirect_baser(struct its_node *its, struct its_baser *baser, - u32 psz, u32 *order) + u32 psz, u32 *order, u32 ids) { u64 tmp = its_read_baser(its, baser); u64 type = GITS_BASER_TYPE(tmp); u64 esz = GITS_BASER_ENTRY_SIZE(tmp); u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb; - u32 ids = its->device_ids; u32 new_order = *order; bool indirect = false; @@ -1680,9 +1683,13 @@ static int its_alloc_tables(struct its_node *its) continue; case GITS_BASER_TYPE_DEVICE: + indirect = its_parse_indirect_baser(its, baser, + psz, &order, + its->device_ids); case GITS_BASER_TYPE_VCPU: indirect = its_parse_indirect_baser(its, baser, - psz, &order); + psz, &order, + ITS_MAX_VPEID_BITS); break; } @@ -2551,7 +2558,7 @@ static struct irq_chip its_vpe_irq_chip = { static int its_vpe_id_alloc(void) { - return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL); + return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL); } static void its_vpe_id_free(u16 id) -- cgit v1.2.3 From 30ae9610d275f8f03f5bf7612ce71d8af6fc400b Mon Sep 17 00:00:00 2001 From: Shanker Donthineni Date: Mon, 9 Oct 2017 11:46:55 -0500 Subject: irqchip/gic-v3-its: Add missing changes to support 52bit physical address The current ITS driver works fine as long as normal memory and GICR regions are located within the lower 48bit (>=0 && <2^48) physical address space. Some of the registers GICR_PEND/PROP, GICR_VPEND/VPROP and GITS_CBASER are handled properly but not all when configuring the hardware with 52bit physical address. This patch does the following changes to support 52bit PA. -Handle 52bit PA in GITS_BASERn. -Fix ITT_addr width to 52bits, bits[51:8]. -Fix RDbase width to 52bits, bits[51:16]. -Fix VPT_addr width to 52bits, bits[51:16]. Definition of the GITS_BASERn register when ITS PageSize is 64KB: -Bits[47:16] of the register provide bits[47:16] of the table PA. -Bits[15:12] of the register provide bits[51:48] of the table PA. -Bits[15:00] of the base physical address are 0. Signed-off-by: Shanker Donthineni Signed-off-by: Marc Zyngier --- drivers/irqchip/irq-gic-v3-its.c | 26 +++++++++++++++++++++----- include/linux/irqchip/arm-gic-v3.h | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 991cf33750c6..e88395605e32 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -312,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size) static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) { - its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8); + its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8); } static void its_encode_valid(struct its_cmd_block *cmd, int valid) @@ -322,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid) static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) { - its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16); + its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16); } static void its_encode_collection(struct its_cmd_block *cmd, u16 col) @@ -362,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list) static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) { - its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16); + its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16); } static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) @@ -1482,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, u64 val = its_read_baser(its, baser); u64 esz = GITS_BASER_ENTRY_SIZE(val); u64 type = GITS_BASER_TYPE(val); + u64 baser_phys, tmp; u32 alloc_pages; void *base; - u64 tmp; retry_alloc_baser: alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); @@ -1500,8 +1500,24 @@ retry_alloc_baser: if (!base) return -ENOMEM; + baser_phys = virt_to_phys(base); + + /* Check if the physical address of the memory is above 48bits */ + if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) { + + /* 52bit PA is supported only when PageSize=64K */ + if (psz != SZ_64K) { + pr_err("ITS: no 52bit PA support when psz=%d\n", psz); + free_pages((unsigned long)base, order); + return -ENXIO; + } + + /* Convert 52bit PA to 48bit field */ + baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys); + } + retry_baser: - val = (virt_to_phys(base) | + val = (baser_phys | (type << GITS_BASER_TYPE_SHIFT) | ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) | diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 1ea576c8126f..14b74f22d43c 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -372,6 +372,8 @@ #define GITS_BASER_ENTRY_SIZE_SHIFT (48) #define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) #define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48) +#define GITS_BASER_PHYS_52_to_48(phys) \ + (((phys) & GENMASK_ULL(47, 16)) | (((phys) >> 48) & 0xf) << 12) #define GITS_BASER_SHAREABILITY_SHIFT (10) #define GITS_BASER_InnerShareable \ GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable) -- cgit v1.2.3 From 16150904d8ba7b93b51d97bcfc671951b7f3dc02 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 4 Oct 2017 14:27:20 +0200 Subject: irqchip/tango: Use irq_gc_mask_disable_and_ack_set The only usage of the irq_gc_mask_disable_reg_and_ack() function is by the Tango irqchip driver. This usage is replaced by the irq_gc_mask_disable_and_ack_set() function since it provides the intended functionality. Fixes: 4bba66899ac6 ("irqchip/tango: Add support for Sigma Designs SMP86xx/SMP87xx interrupt controller") Acked-by: Mans Rullgard Acked-by: Marc Gonzalez Signed-off-by: Florian Fainelli Signed-off-by: Doug Berger Signed-off-by: Marc Zyngier --- drivers/irqchip/irq-tango.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-tango.c b/drivers/irqchip/irq-tango.c index bdbb5c0ff7fe..0c085303a583 100644 --- a/drivers/irqchip/irq-tango.c +++ b/drivers/irqchip/irq-tango.c @@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc, for (i = 0; i < 2; i++) { ct[i].chip.irq_ack = irq_gc_ack_set_bit; ct[i].chip.irq_mask = irq_gc_mask_disable_reg; - ct[i].chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack; + ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set; ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg; ct[i].chip.irq_set_type = tangox_irq_set_type; ct[i].chip.name = gc->domain->name; -- cgit v1.2.3 From ce76353f169a6471542d999baf3d29b121dce9c0 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 13 Oct 2017 14:32:37 +0200 Subject: iommu/amd: Finish TLB flush in amd_iommu_unmap() The function only sends the flush command to the IOMMU(s), but does not wait for its completion when it returns. Fix that. Fixes: 601367d76bd1 ('x86/amd-iommu: Remove iommu_flush_domain function') Cc: stable@vger.kernel.org # >= 2.6.33 Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 822679ac90a1..8e8874d23717 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -3048,6 +3048,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, mutex_unlock(&domain->api_lock); domain_flush_tlb_pde(domain); + domain_flush_complete(domain); return unmap_size; } -- cgit v1.2.3 From e7ad97938eaccb5a9ff4534167b1abafb507935c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 12 Oct 2017 11:48:31 +0200 Subject: liquidio: fix timespec64_to_ns typo While experimenting with changes to the timekeeping code, I ran into a build error in the liquidio driver: drivers/net/ethernet/cavium/liquidio/lio_main.c: In function 'liquidio_ptp_settime': drivers/net/ethernet/cavium/liquidio/lio_main.c:1850:22: error: passing argument 1 of 'timespec_to_ns' from incompatible pointer type [-Werror=incompatible-pointer-types] The driver had a type mismatch since it was first merged, but this never caused problems because it is only built on 64-bit architectures that define timespec and timespec64 to the same type. If we ever want to compile-test the driver on 32-bit or change the way that 64-bit timespec64 is defined, we need to fix it, so let's just do it now. Fixes: f21fb3ed364b ("Add support of Cavium Liquidio ethernet adapters") Signed-off-by: Arnd Bergmann Acked-by: Felix Manlunas Signed-off-by: David S. Miller --- drivers/net/ethernet/cavium/liquidio/lio_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index e7f54948173f..5b19826a7e16 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -1847,7 +1847,7 @@ static int liquidio_ptp_settime(struct ptp_clock_info *ptp, struct lio *lio = container_of(ptp, struct lio, ptp_info); struct octeon_device *oct = (struct octeon_device *)lio->oct_dev; - ns = timespec_to_ns(ts); + ns = timespec64_to_ns(ts); spin_lock_irqsave(&lio->ptp_lock, flags); lio_pci_writeq(oct, ns, CN6XXX_MIO_PTP_CLOCK_HI); -- cgit v1.2.3 From b9849860675f925da0380f4ea76c3f5041909737 Mon Sep 17 00:00:00 2001 From: Emiliano Ingrassia Date: Thu, 12 Oct 2017 11:00:47 +0200 Subject: net: stmmac: dwmac_lib: fix interchanged sleep/timeout values in DMA reset function The DMA reset timeout, used in read_poll_timeout, is ten times shorter than the sleep time. This patch fixes these values interchanging them, as it was before the read_poll_timeout introduction. Fixes: 8a70aeca80c2 ("net: stmmac: Use readl_poll_timeout") Signed-off-by: Emiliano Ingrassia Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c index 67af0bdd7f10..7516ca210855 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c @@ -34,7 +34,7 @@ int dwmac_dma_reset(void __iomem *ioaddr) err = readl_poll_timeout(ioaddr + DMA_BUS_MODE, value, !(value & DMA_BUS_MODE_SFT_RESET), - 100000, 10000); + 10000, 100000); if (err) return -EBUSY; -- cgit v1.2.3 From 40b2be419f8abecbdfaef79c6f03124854b589b7 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:11:59 +0300 Subject: drm/i915: Dump 'output_types' in crtc state dump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make it easier to debug things let's dump the output types bitmask in the crtc state dump. And to make life that much better, let's pretty print it as a a human reaadable string as well. v2: Have the caller pass in the buffer (Chris) #undef OUTPUT_TYPE (Jani) Cc: Chris Wilson Cc: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 98c64e65cd15..9c5b489a1f63 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10662,6 +10662,52 @@ intel_dump_m_n_config(struct intel_crtc_state *pipe_config, char *id, m_n->link_m, m_n->link_n, m_n->tu); } +#define OUTPUT_TYPE(x) [INTEL_OUTPUT_ ## x] = #x + +static const char * const output_type_str[] = { + OUTPUT_TYPE(UNUSED), + OUTPUT_TYPE(ANALOG), + OUTPUT_TYPE(DVO), + OUTPUT_TYPE(SDVO), + OUTPUT_TYPE(LVDS), + OUTPUT_TYPE(TVOUT), + OUTPUT_TYPE(HDMI), + OUTPUT_TYPE(DP), + OUTPUT_TYPE(EDP), + OUTPUT_TYPE(DSI), + OUTPUT_TYPE(UNKNOWN), + OUTPUT_TYPE(DP_MST), +}; + +#undef OUTPUT_TYPE + +static void snprintf_output_types(char *buf, size_t len, + unsigned int output_types) +{ + char *str = buf; + int i; + + str[0] = '\0'; + + for (i = 0; i < ARRAY_SIZE(output_type_str); i++) { + int r; + + if ((output_types & BIT(i)) == 0) + continue; + + r = snprintf(str, len, "%s%s", + str != buf ? "," : "", output_type_str[i]); + if (r >= len) + break; + str += r; + len -= r; + + output_types &= ~BIT(i); + } + + WARN_ON_ONCE(output_types != 0); +} + static void intel_dump_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, const char *context) @@ -10672,10 +10718,15 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, struct intel_plane *intel_plane; struct intel_plane_state *state; struct drm_framebuffer *fb; + char buf[64]; DRM_DEBUG_KMS("[CRTC:%d:%s]%s\n", crtc->base.base.id, crtc->base.name, context); + snprintf_output_types(buf, sizeof(buf), pipe_config->output_types); + DRM_DEBUG_KMS("output_types: %s (0x%x)\n", + buf, pipe_config->output_types); + DRM_DEBUG_KMS("cpu_transcoder: %s, pipe bpp: %i, dithering: %i\n", transcoder_name(pipe_config->cpu_transcoder), pipe_config->pipe_bpp, pipe_config->dither); -- cgit v1.2.3 From 6b8506d575e3d7a064a526202007929429c28f9e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:00 +0300 Subject: drm/i915: Extract intel_ddi_clk_disable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the code to disable the port clock into a function. We already have the intel_ddi_clk_select() counterpart. v2: Keep using intel_ddi_get_encoder_port() for now (Chris) Cc: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b307b6fe1ce3..1cc61ba48e3a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2141,6 +2141,21 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, } } +static void intel_ddi_clk_disable(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + + if (IS_CANNONLAKE(dev_priv)) + I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) | + DPCLKA_CFGCR0_DDI_CLK_OFF(port)); + else if (IS_GEN9_BC(dev_priv)) + I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) | + DPLL_CTRL2_DDI_CLK_OFF(port)); + else if (INTEL_GEN(dev_priv) < 9) + I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); +} + static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, int link_rate, uint32_t lane_count, struct intel_shared_dpll *pll, @@ -2301,14 +2316,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, if (dig_port) intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); - if (IS_CANNONLAKE(dev_priv)) - I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) | - DPCLKA_CFGCR0_DDI_CLK_OFF(port)); - else if (IS_GEN9_BC(dev_priv)) - I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) | - DPLL_CTRL2_DDI_CLK_OFF(port))); - else if (INTEL_GEN(dev_priv) < 9) - I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); + intel_ddi_clk_disable(intel_encoder); if (type == INTEL_OUTPUT_HDMI) { struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); -- cgit v1.2.3 From e725f6456f6fd251e8e02685dfe22543a8c73f5a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:01 +0300 Subject: drm/i915: Extract intel_disable_ddi_buf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the code to disable the DDI_BUF_CTL into small helper. This will allows us to detangle the encoder type mess in intel_ddi_post_disable(). v2: Keep using intel_ddi_get_encoder_port() for now Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 41 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1cc61ba48e3a..e4d1d934231b 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2257,17 +2257,37 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder, } } +static void intel_disable_ddi_buf(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + bool wait = false; + u32 val; + + val = I915_READ(DDI_BUF_CTL(port)); + if (val & DDI_BUF_CTL_ENABLE) { + val &= ~DDI_BUF_CTL_ENABLE; + I915_WRITE(DDI_BUF_CTL(port), val); + wait = true; + } + + val = I915_READ(DP_TP_CTL(port)); + val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); + val |= DP_TP_CTL_LINK_TRAIN_PAT1; + I915_WRITE(DP_TP_CTL(port), val); + + if (wait) + intel_wait_ddi_buf_idle(dev_priv, port); +} + static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { struct drm_encoder *encoder = &intel_encoder->base; struct drm_i915_private *dev_priv = to_i915(encoder->dev); - enum port port = intel_ddi_get_encoder_port(intel_encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); int type = intel_encoder->type; - uint32_t val; - bool wait = false; if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { /* @@ -2286,20 +2306,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); } - val = I915_READ(DDI_BUF_CTL(port)); - if (val & DDI_BUF_CTL_ENABLE) { - val &= ~DDI_BUF_CTL_ENABLE; - I915_WRITE(DDI_BUF_CTL(port), val); - wait = true; - } - - val = I915_READ(DP_TP_CTL(port)); - val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); - val |= DP_TP_CTL_LINK_TRAIN_PAT1; - I915_WRITE(DP_TP_CTL(port), val); - - if (wait) - intel_wait_ddi_buf_idle(dev_priv, port); + intel_disable_ddi_buf(intel_encoder); if (type == INTEL_OUTPUT_HDMI) { dig_port->set_infoframes(encoder, false, -- cgit v1.2.3 From fb0bd3bd10bd83319c2ac935f1cd47db85131d1b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:02 +0300 Subject: drm/i915: Inline the required bits of intel_ddi_post_disable() into intel_ddi_fdi_post_disable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To untangle the mess that is intel_ddi_post_disable() move the the bits needed by FDI into intel_ddi_fdi_post_disable(). This way we can stop worrying about FDI in intel_ddi_post_disable(). Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e4d1d934231b..7187aea75697 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2349,7 +2349,8 @@ void intel_ddi_fdi_post_disable(struct intel_encoder *encoder, val &= ~FDI_RX_ENABLE; I915_WRITE(FDI_RX_CTL(PIPE_A), val); - intel_ddi_post_disable(encoder, old_crtc_state, old_conn_state); + intel_disable_ddi_buf(encoder); + intel_ddi_clk_disable(encoder); val = I915_READ(FDI_RX_MISC(PIPE_A)); val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); -- cgit v1.2.3 From f45f3da7c4f6220746944cb5d5851ec5817c1f4f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:03 +0300 Subject: drm/i915: Split intel_ddi_post_disable() into DP vs. HDMI variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To clean up the mess in intel_ddi_post_disable() split it into two clean variants for HDMI and DP. v2: Rebase due to MST DPMS changes Reviewed-by: Jani Nikula #v1 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 95 +++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 7187aea75697..afe56bc6fce3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2280,56 +2280,73 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder) intel_wait_ddi_buf_idle(dev_priv, port); } -static void intel_ddi_post_disable(struct intel_encoder *intel_encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state) +static void intel_ddi_post_disable_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) { - struct drm_encoder *encoder = &intel_encoder->base; - struct drm_i915_private *dev_priv = to_i915(encoder->dev); - struct intel_digital_port *dig_port = enc_to_dig_port(encoder); - int type = intel_encoder->type; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); + struct intel_dp *intel_dp = &dig_port->dp; + /* + * old_crtc_state and old_conn_state are NULL when called from + * DP_MST. The main connector associated with this port is never + * bound to a crtc for MST. + */ + bool is_mst = !old_crtc_state; - if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { - /* - * old_crtc_state and old_conn_state are NULL when called from - * DP_MST. The main connector associated with this port is never - * bound to a crtc for MST. - */ - bool is_mst = !old_crtc_state; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + /* + * Power down sink before disabling the port, otherwise we end + * up getting interrupts from the sink on detecting link loss. + */ + if (!is_mst) + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); - /* - * Power down sink before disabling the port, otherwise we end - * up getting interrupts from the sink on detecting link loss. - */ - if (!is_mst) - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); - } + intel_disable_ddi_buf(encoder); - intel_disable_ddi_buf(intel_encoder); + intel_edp_panel_vdd_on(intel_dp); + intel_edp_panel_off(intel_dp); - if (type == INTEL_OUTPUT_HDMI) { - dig_port->set_infoframes(encoder, false, - old_crtc_state, old_conn_state); - } + intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); - if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + intel_ddi_clk_disable(encoder); +} - intel_edp_panel_vdd_on(intel_dp); - intel_edp_panel_off(intel_dp); - } +static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); + struct intel_hdmi *intel_hdmi = &dig_port->hdmi; - if (dig_port) - intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); + intel_disable_ddi_buf(encoder); - intel_ddi_clk_disable(intel_encoder); + dig_port->set_infoframes(&encoder->base, false, + old_crtc_state, old_conn_state); - if (type == INTEL_OUTPUT_HDMI) { - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); + intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); - intel_dp_dual_mode_set_tmds_output(intel_hdmi, false); - } + intel_ddi_clk_disable(encoder); + + intel_dp_dual_mode_set_tmds_output(intel_hdmi, false); +} + +static void intel_ddi_post_disable(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + /* + * old_crtc_state and old_conn_state are NULL when called from + * DP_MST. The main connector associated with this port is never + * bound to a crtc for MST. + */ + if (old_crtc_state && + intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) + intel_ddi_post_disable_hdmi(encoder, + old_crtc_state, old_conn_state); + else + intel_ddi_post_disable_dp(encoder, + old_crtc_state, old_conn_state); } void intel_ddi_fdi_post_disable(struct intel_encoder *encoder, -- cgit v1.2.3 From 680b71c201fc47859135cf27223b9bceea34beec Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:04 +0300 Subject: drm/i915: Remove useless eDP check from intel_ddi_pre_enable_dp() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_edp_panel_on() will itself do the is_edp() check, so the caller doesn't have to bother. Pre-DDI code doesn't bother, so let's follow the same approach for DDI. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index afe56bc6fce3..945980e71697 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2171,8 +2171,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, intel_dp_set_link_params(intel_dp, link_rate, lane_count, link_mst); - if (encoder->type == INTEL_OUTPUT_EDP) - intel_edp_panel_on(intel_dp); + + intel_edp_panel_on(intel_dp); intel_ddi_clk_select(encoder, pll); -- cgit v1.2.3 From 33f083f002cb24ab73e76f895a99729f1721611a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:05 +0300 Subject: drm/i915: Split intel_disable_ddi() into DP vs. HDMI variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Untangle intel_disable_ddi() by splitting it into DP and HDMI specific variants. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-8-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 45 +++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 945980e71697..c930ef0338c5 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2424,29 +2424,40 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder, intel_audio_codec_enable(intel_encoder, pipe_config, conn_state); } -static void intel_disable_ddi(struct intel_encoder *intel_encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state) +static void intel_disable_ddi_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) { - struct drm_encoder *encoder = &intel_encoder->base; - int type = intel_encoder->type; + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); if (old_crtc_state->has_audio) - intel_audio_codec_disable(intel_encoder); + intel_audio_codec_disable(encoder); - if (type == INTEL_OUTPUT_HDMI) { - intel_hdmi_handle_sink_scrambling(intel_encoder, - old_conn_state->connector, - false, false); - } + intel_edp_drrs_disable(intel_dp, old_crtc_state); + intel_psr_disable(intel_dp, old_crtc_state); + intel_edp_backlight_off(old_conn_state); +} - if (type == INTEL_OUTPUT_EDP) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); +static void intel_disable_ddi_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + if (old_crtc_state->has_audio) + intel_audio_codec_disable(encoder); - intel_edp_drrs_disable(intel_dp, old_crtc_state); - intel_psr_disable(intel_dp, old_crtc_state); - intel_edp_backlight_off(old_conn_state); - } + intel_hdmi_handle_sink_scrambling(encoder, + old_conn_state->connector, + false, false); +} + +static void intel_disable_ddi(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) + intel_disable_ddi_hdmi(encoder, old_crtc_state, old_conn_state); + else + intel_disable_ddi_dp(encoder, old_crtc_state, old_conn_state); } static void bxt_ddi_pre_pll_enable(struct intel_encoder *encoder, -- cgit v1.2.3 From 45e0327e28e57e84f83d3214a35a318eebb19aa5 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:06 +0300 Subject: drm/i915: Plumb crtc_state etc. directly to intel_ddi_pre_enable_{dp,hdmi}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather that plumb the link parameters separately to intel_ddi_pre_enable_dp() let's just pass the entire crtc state. intel_ddi_pre_enable_hdmi() already took the crtc state, but for some reason intel_ddi_pre_enable() still wanted to extract has_infoframe from therein and pass it in separately. Let's not do that since it's pointless. v2: Rebase due to more code getting pulled into the DDI hooks Cc: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-9-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 54 +++++++++++++++------------------------- 1 file changed, 20 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index c930ef0338c5..49cf8d9d2bc1 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2157,24 +2157,24 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder) } static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, - int link_rate, uint32_t lane_count, - struct intel_shared_dpll *pll, - bool link_mst) + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = intel_ddi_get_encoder_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); + bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); uint32_t level = intel_ddi_dp_level(intel_dp); - WARN_ON(link_mst && (port == PORT_A || port == PORT_E)); + WARN_ON(is_mst && (port == PORT_A || port == PORT_E)); - intel_dp_set_link_params(intel_dp, link_rate, lane_count, - link_mst); + intel_dp_set_link_params(intel_dp, crtc_state->port_clock, + crtc_state->lane_count, is_mst); intel_edp_panel_on(intel_dp); - intel_ddi_clk_select(encoder, pll); + intel_ddi_clk_select(encoder, crtc_state->shared_dpll); intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); @@ -2186,7 +2186,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, intel_prepare_dp_ddi_buffers(encoder); intel_ddi_init_dp_buf_reg(encoder); - if (!link_mst) + if (!is_mst) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) @@ -2194,10 +2194,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, } static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, - bool has_infoframe, const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, - const struct intel_shared_dpll *pll) + const struct drm_connector_state *conn_state) { struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; @@ -2207,7 +2205,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); - intel_ddi_clk_select(encoder, pll); + intel_ddi_clk_select(encoder, crtc_state->shared_dpll); intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); @@ -2223,38 +2221,26 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, skl_ddi_set_iboost(encoder, level); intel_dig_port->set_infoframes(&encoder->base, - has_infoframe, + crtc_state->has_infoframe, crtc_state, conn_state); } static void intel_ddi_pre_enable(struct intel_encoder *encoder, - const struct intel_crtc_state *pipe_config, + const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_crtc *crtc = pipe_config->base.crtc; - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int type = encoder->type; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum pipe pipe = crtc->pipe; - WARN_ON(intel_crtc->config->has_pch_encoder); + WARN_ON(crtc_state->has_pch_encoder); intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); - if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { - intel_ddi_pre_enable_dp(encoder, - pipe_config->port_clock, - pipe_config->lane_count, - pipe_config->shared_dpll, - intel_crtc_has_type(pipe_config, - INTEL_OUTPUT_DP_MST)); - } - if (type == INTEL_OUTPUT_HDMI) { - intel_ddi_pre_enable_hdmi(encoder, - pipe_config->has_infoframe, - pipe_config, conn_state, - pipe_config->shared_dpll); - } + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + intel_ddi_pre_enable_hdmi(encoder, crtc_state, conn_state); + else + intel_ddi_pre_enable_dp(encoder, crtc_state, conn_state); } static void intel_disable_ddi_buf(struct intel_encoder *encoder) -- cgit v1.2.3 From 15d05f0e77fb32131ad07b377274eedfaf42479d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 10 Oct 2017 15:12:07 +0300 Subject: drm/i915: Split intel_enable_ddi() into DP and HDMI variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Untangle intel_enable_ddi() by splitting it into DP and HDMI specific variants. v2: Keep using intel_ddi_get_encoder_port() for now Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171010121207.570-10-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 80 +++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 49cf8d9d2bc1..18bf06c7e43f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2369,45 +2369,57 @@ void intel_ddi_fdi_post_disable(struct intel_encoder *encoder, I915_WRITE(FDI_RX_CTL(PIPE_A), val); } -static void intel_enable_ddi(struct intel_encoder *intel_encoder, - const struct intel_crtc_state *pipe_config, - const struct drm_connector_state *conn_state) +static void intel_enable_ddi_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { - struct drm_encoder *encoder = &intel_encoder->base; - struct drm_i915_private *dev_priv = to_i915(encoder->dev); - enum port port = intel_ddi_get_encoder_port(intel_encoder); - int type = intel_encoder->type; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + enum port port = intel_ddi_get_encoder_port(encoder); - if (type == INTEL_OUTPUT_HDMI) { - struct intel_digital_port *intel_dig_port = - enc_to_dig_port(encoder); - bool clock_ratio = pipe_config->hdmi_high_tmds_clock_ratio; - bool scrambling = pipe_config->hdmi_scrambling; - - intel_hdmi_handle_sink_scrambling(intel_encoder, - conn_state->connector, - clock_ratio, scrambling); - - /* In HDMI/DVI mode, the port width, and swing/emphasis values - * are ignored so nothing special needs to be done besides - * enabling the port. - */ - I915_WRITE(DDI_BUF_CTL(port), - intel_dig_port->saved_port_bits | - DDI_BUF_CTL_ENABLE); - } else if (type == INTEL_OUTPUT_EDP) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + if (port == PORT_A && INTEL_GEN(dev_priv) < 9) + intel_dp_stop_link_train(intel_dp); - if (port == PORT_A && INTEL_GEN(dev_priv) < 9) - intel_dp_stop_link_train(intel_dp); + intel_edp_backlight_on(crtc_state, conn_state); + intel_psr_enable(intel_dp, crtc_state); + intel_edp_drrs_enable(intel_dp, crtc_state); - intel_edp_backlight_on(pipe_config, conn_state); - intel_psr_enable(intel_dp, pipe_config); - intel_edp_drrs_enable(intel_dp, pipe_config); - } + if (crtc_state->has_audio) + intel_audio_codec_enable(encoder, crtc_state, conn_state); +} - if (pipe_config->has_audio) - intel_audio_codec_enable(intel_encoder, pipe_config, conn_state); +static void intel_enable_ddi_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); + enum port port = intel_ddi_get_encoder_port(encoder); + + intel_hdmi_handle_sink_scrambling(encoder, + conn_state->connector, + crtc_state->hdmi_high_tmds_clock_ratio, + crtc_state->hdmi_scrambling); + + /* In HDMI/DVI mode, the port width, and swing/emphasis values + * are ignored so nothing special needs to be done besides + * enabling the port. + */ + I915_WRITE(DDI_BUF_CTL(port), + dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE); + + if (crtc_state->has_audio) + intel_audio_codec_enable(encoder, crtc_state, conn_state); +} + +static void intel_enable_ddi(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + intel_enable_ddi_hdmi(encoder, crtc_state, conn_state); + else + intel_enable_ddi_dp(encoder, crtc_state, conn_state); } static void intel_disable_ddi_dp(struct intel_encoder *encoder, -- cgit v1.2.3 From c6ebcedbab7ca78984959386012a17b21183e1a3 Mon Sep 17 00:00:00 2001 From: Pontus Andersson Date: Mon, 2 Oct 2017 14:45:19 +0200 Subject: i2c: ismt: Separate I2C block read from SMBus block read Commit b6c159a9cb69 ("i2c: ismt: Don't duplicate the receive length for block reads") broke I2C block reads. It aimed to fix normal SMBus block read, but changed the correct behavior of I2C block read in the process. According to Documentation/i2c/smbus-protocol, one vital difference between normal SMBus block read and I2C block read is that there is no byte count prefixed in the data sent on the wire: SMBus Block Read: i2c_smbus_read_block_data() S Addr Wr [A] Comm [A] S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P I2C Block Read: i2c_smbus_read_i2c_block_data() S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P Therefore the two transaction types need to be processed differently in the driver by copying of the dma_buffer as done previously for the I2C_SMBUS_I2C_BLOCK_DATA case. Fixes: b6c159a9cb69 ("i2c: ismt: Don't duplicate the receive length for block reads") Signed-off-by: Pontus Andersson Tested-by: Stephen Douthit Cc: stable@vger.kernel.org Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-ismt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index 22ffcb73c185..b51adffa4841 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c @@ -340,12 +340,15 @@ static int ismt_process_desc(const struct ismt_desc *desc, data->word = dma_buffer[0] | (dma_buffer[1] << 8); break; case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_I2C_BLOCK_DATA: if (desc->rxbytes != dma_buffer[0] + 1) return -EMSGSIZE; memcpy(data->block, dma_buffer, desc->rxbytes); break; + case I2C_SMBUS_I2C_BLOCK_DATA: + memcpy(&data->block[1], dma_buffer, desc->rxbytes); + data->block[0] = desc->rxbytes; + break; } return 0; } -- cgit v1.2.3 From df0a2fdab0068f7452bf0a97ea9ba0ad69d49a1f Mon Sep 17 00:00:00 2001 From: Wei Jinhua Date: Wed, 11 Oct 2017 15:57:20 +0800 Subject: i2c: imx: use IRQF_SHARED mode to request IRQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some SoC share one irq number between I2C controllers. For example, on the LS2088 board, I2C 1 and I2C 2 share one irq number. In this case, only one I2C controller can register successfully, and others will fail. Signed-off-by: Wei Jinhua Reviewed-by: Jiang Biao Acked-by: Uwe Kleine-König Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 54a47b40546f..e5c8b3d5df77 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1100,7 +1100,7 @@ static int i2c_imx_probe(struct platform_device *pdev) } /* Request IRQ */ - ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0, + ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED, pdev->name, i2c_imx); if (ret) { dev_err(&pdev->dev, "can't claim irq %d\n", irq); -- cgit v1.2.3 From eba523b468a1e30384b6e8c1a9419163f325086e Mon Sep 17 00:00:00 2001 From: Clemens Gruber Date: Mon, 9 Oct 2017 21:26:14 +0200 Subject: i2c: imx: fix misleading bus recovery debug message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arguments for SDA and SCL were swapped. Fix it. Signed-off-by: Clemens Gruber Acked-by: Uwe Kleine-König Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index e5c8b3d5df77..f96830ffd9f1 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1021,7 +1021,7 @@ static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx, } dev_dbg(&pdev->dev, "using scl-gpio %d and sda-gpio %d for recovery\n", - rinfo->sda_gpio, rinfo->scl_gpio); + rinfo->scl_gpio, rinfo->sda_gpio); rinfo->prepare_recovery = i2c_imx_prepare_recovery; rinfo->unprepare_recovery = i2c_imx_unprepare_recovery; -- cgit v1.2.3 From 0fe16195f89173652cf111d7b384941b00c5aabd Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 15 Jul 2017 16:51:26 -0700 Subject: i2c: piix4: Fix SMBus port selection for AMD Family 17h chips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AMD Family 17h uses the KERNCZ SMBus controller. While its documentation is not publicly available, it is documented in the BIOS and Kernel Developer’s Guide for AMD Family 15h Models 60h-6Fh Processors. On this SMBus controller, the port select register is at PMx register 0x02, bit 4:3 (PMx00 register bit 20:19). Without this patch, the 4 SMBus channels on AMD Family 17h chips are mirrored and report the same chips on all channels. Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang Cc: stable@kernel.org --- drivers/i2c/busses/i2c-piix4.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 0ecdb47a23ab..01f767ee4546 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -94,6 +94,12 @@ #define SB800_PIIX4_PORT_IDX_ALT 0x2e #define SB800_PIIX4_PORT_IDX_SEL 0x2f #define SB800_PIIX4_PORT_IDX_MASK 0x06 +#define SB800_PIIX4_PORT_IDX_SHIFT 1 + +/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */ +#define SB800_PIIX4_PORT_IDX_KERNCZ 0x02 +#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18 +#define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3 /* insmod parameters */ @@ -149,6 +155,8 @@ static const struct dmi_system_id piix4_dmi_ibm[] = { */ static DEFINE_MUTEX(piix4_mutex_sb800); static u8 piix4_port_sel_sb800; +static u8 piix4_port_mask_sb800; +static u8 piix4_port_shift_sb800; static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = { " port 0", " port 2", " port 3", " port 4" }; @@ -347,7 +355,19 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, /* Find which register is used for port selection */ if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD) { - piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT; + switch (PIIX4_dev->device) { + case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS: + piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ; + piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ; + piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ; + break; + case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS: + default: + piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT; + piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; + piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; + break; + } } else { mutex_lock(&piix4_mutex_sb800); outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX); @@ -355,6 +375,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, piix4_port_sel_sb800 = (port_sel & 0x01) ? SB800_PIIX4_PORT_IDX_ALT : SB800_PIIX4_PORT_IDX; + piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; + piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; mutex_unlock(&piix4_mutex_sb800); } @@ -616,8 +638,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); port = adapdata->port; - if ((smba_en_lo & SB800_PIIX4_PORT_IDX_MASK) != port) - outb_p((smba_en_lo & ~SB800_PIIX4_PORT_IDX_MASK) | port, + if ((smba_en_lo & piix4_port_mask_sb800) != port) + outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port, SB800_PIIX4_SMB_IDX + 1); retval = piix4_access(adap, addr, flags, read_write, @@ -706,7 +728,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, adapdata->smba = smba; adapdata->sb800_main = sb800_main; - adapdata->port = port << 1; + adapdata->port = port << piix4_port_shift_sb800; /* set up the sysfs linkage to our parent device */ adap->dev.parent = &dev->dev; -- cgit v1.2.3 From 88fa2dfb075a20c3464e3d303c57dd8ced9e8309 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Tue, 10 Oct 2017 18:11:15 +0200 Subject: i2c: piix4: Disable completely the IMC during SMBUS_BLOCK_DATA SMBUS_BLOCK_DATA transactions might fail due to a race condition with the IMC (Integrated Micro Controller), even when the IMC semaphore is used. This bug has been reported and confirmed by AMD, who suggested as a solution an IMC firmware upgrade (obtained via BIOS update) and disabling the IMC during SMBUS_BLOCK_DATA transactions. Even without the IMC upgrade, the SMBUS is much more stable with this patch. Tested on a Bettong-alike board. Signed-off-by: Ricardo Ribalda Delgado Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-piix4.c | 132 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 126 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 01f767ee4546..174579d32e5f 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -85,6 +85,9 @@ /* SB800 constants */ #define SB800_PIIX4_SMB_IDX 0xcd6 +#define KERNCZ_IMC_IDX 0x3e +#define KERNCZ_IMC_DATA 0x3f + /* * SB800 port is selected by bits 2:1 of the smb_en register (0x2c) * or the smb_sel register (0x2e), depending on bit 0 of register 0x2f. @@ -167,6 +170,7 @@ struct i2c_piix4_adapdata { /* SB800 */ bool sb800_main; + bool notify_imc; u8 port; /* Port number, shifted */ }; @@ -594,6 +598,67 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, return 0; } +static uint8_t piix4_imc_read(uint8_t idx) +{ + outb_p(idx, KERNCZ_IMC_IDX); + return inb_p(KERNCZ_IMC_DATA); +} + +static void piix4_imc_write(uint8_t idx, uint8_t value) +{ + outb_p(idx, KERNCZ_IMC_IDX); + outb_p(value, KERNCZ_IMC_DATA); +} + +static int piix4_imc_sleep(void) +{ + int timeout = MAX_TIMEOUT; + + if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc")) + return -EBUSY; + + /* clear response register */ + piix4_imc_write(0x82, 0x00); + /* request ownership flag */ + piix4_imc_write(0x83, 0xB4); + /* kick off IMC Mailbox command 96 */ + piix4_imc_write(0x80, 0x96); + + while (timeout--) { + if (piix4_imc_read(0x82) == 0xfa) { + release_region(KERNCZ_IMC_IDX, 2); + return 0; + } + usleep_range(1000, 2000); + } + + release_region(KERNCZ_IMC_IDX, 2); + return -ETIMEDOUT; +} + +static void piix4_imc_wakeup(void) +{ + int timeout = MAX_TIMEOUT; + + if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc")) + return; + + /* clear response register */ + piix4_imc_write(0x82, 0x00); + /* release ownership flag */ + piix4_imc_write(0x83, 0xB5); + /* kick off IMC Mailbox command 96 */ + piix4_imc_write(0x80, 0x96); + + while (timeout--) { + if (piix4_imc_read(0x82) == 0xfa) + break; + usleep_range(1000, 2000); + } + + release_region(KERNCZ_IMC_IDX, 2); +} + /* * Handles access to multiple SMBus ports on the SB800. * The port is selected by bits 2:1 of the smb_en register (0x2c). @@ -634,6 +699,41 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, return -EBUSY; } + /* + * Notify the IMC (Integrated Micro Controller) if required. + * Among other responsibilities, the IMC is in charge of monitoring + * the System fans and temperature sensors, and act accordingly. + * All this is done through SMBus and can/will collide + * with our transactions if they are long (BLOCK_DATA). + * Therefore we need to request the ownership flag during those + * transactions. + */ + if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) { + int ret; + + ret = piix4_imc_sleep(); + switch (ret) { + case -EBUSY: + dev_warn(&adap->dev, + "IMC base address index region 0x%x already in use.\n", + KERNCZ_IMC_IDX); + break; + case -ETIMEDOUT: + dev_warn(&adap->dev, + "Failed to communicate with the IMC.\n"); + break; + default: + break; + } + + /* If IMC communication fails do not retry */ + if (ret) { + dev_warn(&adap->dev, + "Continuing without IMC notification.\n"); + adapdata->notify_imc = false; + } + } + outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); @@ -650,6 +750,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, /* Release the semaphore */ outb_p(smbslvcnt | 0x20, SMBSLVCNT); + if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) + piix4_imc_wakeup(); + mutex_unlock(&piix4_mutex_sb800); return retval; @@ -701,7 +804,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS]; static struct i2c_adapter *piix4_aux_adapter; static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, - bool sb800_main, u8 port, + bool sb800_main, u8 port, bool notify_imc, const char *name, struct i2c_adapter **padap) { struct i2c_adapter *adap; @@ -729,6 +832,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, adapdata->smba = smba; adapdata->sb800_main = sb800_main; adapdata->port = port << piix4_port_shift_sb800; + adapdata->notify_imc = notify_imc; /* set up the sysfs linkage to our parent device */ adap->dev.parent = &dev->dev; @@ -750,14 +854,15 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, return 0; } -static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba) +static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba, + bool notify_imc) { struct i2c_piix4_adapdata *adapdata; int port; int retval; for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) { - retval = piix4_add_adapter(dev, smba, true, port, + retval = piix4_add_adapter(dev, smba, true, port, notify_imc, piix4_main_port_names_sb800[port], &piix4_main_adapters[port]); if (retval < 0) @@ -791,6 +896,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && dev->revision >= 0x40) || dev->vendor == PCI_VENDOR_ID_AMD) { + bool notify_imc = false; is_sb800 = true; if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) { @@ -800,6 +906,20 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) return -EBUSY; } + if (dev->vendor == PCI_VENDOR_ID_AMD && + dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) { + u8 imc; + + /* + * Detect if IMC is active or not, this method is + * described on coreboot's AMD IMC notes + */ + pci_bus_read_config_byte(dev->bus, PCI_DEVFN(0x14, 3), + 0x40, &imc); + if (imc & 0x80) + notify_imc = true; + } + /* base address location etc changed in SB800 */ retval = piix4_setup_sb800(dev, id, 0); if (retval < 0) { @@ -811,7 +931,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) * Try to register multiplexed main SMBus adapter, * give up if we can't */ - retval = piix4_add_adapters_sb800(dev, retval); + retval = piix4_add_adapters_sb800(dev, retval, notify_imc); if (retval < 0) { release_region(SB800_PIIX4_SMB_IDX, 2); return retval; @@ -822,7 +942,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) return retval; /* Try to register main SMBus adapter, give up if we can't */ - retval = piix4_add_adapter(dev, retval, false, 0, "", + retval = piix4_add_adapter(dev, retval, false, 0, false, "", &piix4_main_adapters[0]); if (retval < 0) return retval; @@ -849,7 +969,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) if (retval > 0) { /* Try to add the aux adapter if it exists, * piix4_add_adapter will clean up if this fails */ - piix4_add_adapter(dev, retval, false, 0, + piix4_add_adapter(dev, retval, false, 0, false, is_sb800 ? piix4_aux_port_name_sb800 : "", &piix4_aux_adapter); } -- cgit v1.2.3 From 5d031f4e1618b64344713b8e4f864a6ccc1f31cf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 12 Oct 2017 21:40:19 +0100 Subject: drm/i915: Stop asserting on set-wedged vs nop_submit_request ordering Since the removal of the stop_machine(), it is allowed and expected for the nop_submit_request() and nop_complete_submit_request() to run in parallel to the i915_gem_set_wedged() processing. As such we can no longer assert that i915_gem_set_wedged() has completed inside the stop_machine prior to the individual nop_submit_request execution. Fixes: af7a8ffad9c5 ("drm/i915: Use rcu instead of stop_machine in set_wedged") Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171012204019.3557-1-chris@chris-wilson.co.uk Reviewed-by: Daniel Vetter Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gem.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 20fcac37c85a..d9d39b309ce8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3087,7 +3087,6 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv) static void nop_submit_request(struct drm_i915_gem_request *request) { - GEM_BUG_ON(!i915_terminally_wedged(&request->i915->gpu_error)); dma_fence_set_error(&request->fence, -EIO); i915_gem_request_submit(request); @@ -3097,7 +3096,6 @@ static void nop_complete_submit_request(struct drm_i915_gem_request *request) { unsigned long flags; - GEM_BUG_ON(!i915_terminally_wedged(&request->i915->gpu_error)); dma_fence_set_error(&request->fence, -EIO); spin_lock_irqsave(&request->engine->timeline->lock, flags); -- cgit v1.2.3 From 7836cd02f27c03af2fca04b450177c51fc7caf1e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 14:12:17 +0100 Subject: drm/i915: Keep the rings stopped until they have been re-initialized Before modifying the ring register (RING_START, HEAD, TAIL, CTL) we first make sure it is stopped (or else the hw may not resample the registers). However, we do not need to let the hw restart until after we have reprogrammed all the rings. This should help prevent situations where pending operations on the ring may resume (because we are trying to re-initialize following an unsuccessful GPU hang, i.e. from i915_gem_unset_wedged). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103260 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171013131218.18013-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4285f09ff8b8..b2a6cb09c6e7 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -484,11 +484,6 @@ static bool stop_ring(struct intel_engine_cs *engine) I915_WRITE_HEAD(engine, 0); I915_WRITE_TAIL(engine, 0); - if (INTEL_GEN(dev_priv) > 2) { - (void)I915_READ_CTL(engine); - I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); - } - return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; } @@ -570,6 +565,9 @@ static int init_ring_common(struct intel_engine_cs *engine) intel_engine_init_hangcheck(engine); + if (INTEL_GEN(dev_priv) > 2) + I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); + out: intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); -- cgit v1.2.3 From 5896a5c8c9c01b09af05b02cdb2ae275ef143959 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 14:12:18 +0100 Subject: drm/i915: Always stop the rings before a missing GPU reset Always try to stop the rings, even if the GPU reset itself has been disabled (via modparam i915.reset). This should at least stop the hw from spinning in the background consuming resources (e.g. power and memory bandwidth) letting the system rest-in-peace. References: https://bugs.freedesktop.org/show_bug.cgi?id=103260 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171013131218.18013-2-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/intel_uncore.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 983617b5b338..20e3c65c0999 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1403,6 +1403,9 @@ static void i915_stop_engines(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine; enum intel_engine_id id; + if (INTEL_GEN(dev_priv) < 3) + return; + for_each_engine_masked(engine, dev_priv, engine_mask, id) gen3_stop_engine(engine); } @@ -1742,16 +1745,12 @@ static reset_func intel_get_gpu_reset(struct drm_i915_private *dev_priv) int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { - reset_func reset; + reset_func reset = intel_get_gpu_reset(dev_priv); int retry; int ret; might_sleep(); - reset = intel_get_gpu_reset(dev_priv); - if (reset == NULL) - return -ENODEV; - /* If the power well sleeps during the reset, the reset * request may be dropped and never completes (causing -EIO). */ @@ -1771,7 +1770,9 @@ int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) */ i915_stop_engines(dev_priv, engine_mask); - ret = reset(dev_priv, engine_mask); + ret = -ENODEV; + if (reset) + ret = reset(dev_priv, engine_mask); if (ret != -ETIMEDOUT) break; -- cgit v1.2.3 From 1210d3889077653b90b0bfd2cc54e19f4766e4e6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 16:47:35 +0100 Subject: drm/i915: Use bdw_ddi_translations_fdi for Broadwell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compiler warns: drivers/gpu/drm/i915/intel_ddi.c:118:35: warning: ‘bdw_ddi_translations_fdi’ defined but not used Lo and behold, if we look at intel_ddi_get_buf_trans_fdi(), it uses hsw_ddi_translations_fdi[] for both Haswell and *Broadwell* Fixes: 7d1c42e679f9 ("drm/i915: Refactor code to select the DDI buf translation table") Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: David Weinehall Cc: Jani Nikula Cc: # v4.12+ Link: https://patchwork.freedesktop.org/patch/msgid/20171013154735.27163-1-chris@chris-wilson.co.uk Reviewed-by: Jani Nikula Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 18bf06c7e43f..8ef65941b8fd 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -734,8 +734,8 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv, int *n_entries) { if (IS_BROADWELL(dev_priv)) { - *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); - return hsw_ddi_translations_fdi; + *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi); + return bdw_ddi_translations_fdi; } else if (IS_HASWELL(dev_priv)) { *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); return hsw_ddi_translations_fdi; -- cgit v1.2.3 From 064f0e9302af4f4ab5e9dca03a5a77d6bebfd35e Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Fri, 13 Oct 2017 15:57:50 -0700 Subject: mm: only display online cpus of the numa node When I execute numactl -H (which reads /sys/devices/system/node/nodeX/cpumap and displays cpumask_of_node for each node), I get different result on X86 and arm64. For each numa node, the former only displayed online CPUs, and the latter displayed all possible CPUs. Unfortunately, both Linux documentation and numactl manual have not described it clear. I sent a mail to ask for help, and Michal Hocko replied that he preferred to print online cpus because it doesn't really make much sense to bind anything on offline nodes. Will said: "I suspect the vast majority (if not all) code that reads this file was developed for x86, so having the same behaviour for arm64 sounds like something we should do ASAP before people try to special case with things like #ifdef __aarch64__. I'd rather have this in 4.14 if possible." Link: http://lkml.kernel.org/r/1506678805-15392-2-git-send-email-thunder.leizhen@huawei.com Signed-off-by: Zhen Lei Acked-by: Michal Hocko Cc: Catalin Marinas Cc: Will Deacon Cc: Greg Kroah-Hartman Cc: Tianhong Ding Cc: Hanjun Guo Cc: Libin Cc: Kefeng Wang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/node.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/node.c b/drivers/base/node.c index 3855902f2c5b..aae2402f3791 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -27,13 +27,21 @@ static struct bus_type node_subsys = { static ssize_t node_read_cpumap(struct device *dev, bool list, char *buf) { + ssize_t n; + cpumask_var_t mask; struct node *node_dev = to_node(dev); - const struct cpumask *mask = cpumask_of_node(node_dev->dev.id); /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */ BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1)); - return cpumap_print_to_pagebuf(list, buf, mask); + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + return 0; + + cpumask_and(mask, cpumask_of_node(node_dev->dev.id), cpu_online_mask); + n = cpumap_print_to_pagebuf(list, buf, mask); + free_cpumask_var(mask); + + return n; } static inline ssize_t node_read_cpumask(struct device *dev, -- cgit v1.2.3 From e65c62b1375cbff69fa925787bcdae4b27bffb48 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 13 Oct 2017 15:58:08 -0700 Subject: tty: fall back to N_NULL if switching to N_TTY fails during hangup We have seen NULL-pointer dereference crashes in tty->disc_data when the N_TTY fallback driver failed to open during hangup. The immediate cause of this open to fail has been addressed in the preceding patch to vmalloc(), but this code could be more robust. As Alan pointed out in commit 8a8dabf2dd68 ("tty: handle the case where we cannot restore a line discipline"), the N_TTY driver, historically the safe fallback that could never fail, can indeed fail, but the surrounding code is not prepared to handle this. To avoid crashes he added a new N_NULL driver to take N_TTY's place as the last resort. Hook that fallback up to the hangup path. Update tty_ldisc_reinit() to reflect the reality that n_tty_open can indeed fail. Link: http://lkml.kernel.org/r/20171004185959.GC2136@cmpxchg.org Signed-off-by: Johannes Weiner Cc: Alan Cox Cc: Christoph Hellwig Cc: Dmitry Vyukov Cc: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/tty/tty_ldisc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 2fe216b276e2..84a8ac2a779f 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -694,10 +694,8 @@ int tty_ldisc_reinit(struct tty_struct *tty, int disc) tty_set_termios_ldisc(tty, disc); retval = tty_ldisc_open(tty, tty->ldisc); if (retval) { - if (!WARN_ON(disc == N_TTY)) { - tty_ldisc_put(tty->ldisc); - tty->ldisc = NULL; - } + tty_ldisc_put(tty->ldisc); + tty->ldisc = NULL; } return retval; } @@ -752,8 +750,9 @@ void tty_ldisc_hangup(struct tty_struct *tty, bool reinit) if (tty->ldisc) { if (reinit) { - if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0) - tty_ldisc_reinit(tty, N_TTY); + if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0 && + tty_ldisc_reinit(tty, N_TTY) < 0) + WARN_ON(tty_ldisc_reinit(tty, N_NULL) < 0); } else tty_ldisc_kill(tty); } -- cgit v1.2.3 From ca4c302398963c0cae29bc168e44cf91e40ff0d3 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Wed, 11 Oct 2017 14:21:14 +0300 Subject: iio: adc: at91-sama5d2_adc: fix probe error on missing trigger property This fix allows platforms to probe correctly even if the trigger edge property is missing. The hardware trigger will no longer be registered in the sybsystem Preserves backwards compatibility with the support that was in the driver before the hardware trigger. https://storage.kernelci.org/mainline/master/v4.14-rc2-255-g74d83ec2b734/arm/sama5_defconfig/lab-free-electrons/boot-at91-sama5d2_xplained.txt Signed-off-by: Eugen Hristev Fixes: 5e1a1da0f ("iio: adc: at91-sama5d2_adc: add hw trigger and buffer support") Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 45 ++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index bc5b38e3a147..a70ef7fec95f 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -225,6 +225,7 @@ struct at91_adc_trigger { char *name; unsigned int trgmod_value; unsigned int edge_type; + bool hw_trig; }; struct at91_adc_state { @@ -254,16 +255,25 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = { .name = "external_rising", .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE, .edge_type = IRQ_TYPE_EDGE_RISING, + .hw_trig = true, }, { .name = "external_falling", .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL, .edge_type = IRQ_TYPE_EDGE_FALLING, + .hw_trig = true, }, { .name = "external_any", .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY, .edge_type = IRQ_TYPE_EDGE_BOTH, + .hw_trig = true, + }, + { + .name = "software", + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER, + .edge_type = IRQ_TYPE_NONE, + .hw_trig = false, }, }; @@ -597,7 +607,7 @@ static int at91_adc_probe(struct platform_device *pdev) struct at91_adc_state *st; struct resource *res; int ret, i; - u32 edge_type; + u32 edge_type = IRQ_TYPE_NONE; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); if (!indio_dev) @@ -641,14 +651,14 @@ static int at91_adc_probe(struct platform_device *pdev) ret = of_property_read_u32(pdev->dev.of_node, "atmel,trigger-edge-type", &edge_type); if (ret) { - dev_err(&pdev->dev, - "invalid or missing value for atmel,trigger-edge-type\n"); - return ret; + dev_dbg(&pdev->dev, + "atmel,trigger-edge-type not specified, only software trigger available\n"); } st->selected_trig = NULL; - for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++) + /* find the right trigger, or no trigger at all */ + for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++) if (at91_adc_trigger_list[i].edge_type == edge_type) { st->selected_trig = &at91_adc_trigger_list[i]; break; @@ -717,24 +727,27 @@ static int at91_adc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); - ret = at91_adc_buffer_init(indio_dev); - if (ret < 0) { - dev_err(&pdev->dev, "couldn't initialize the buffer.\n"); - goto per_clk_disable_unprepare; - } + if (st->selected_trig->hw_trig) { + ret = at91_adc_buffer_init(indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "couldn't initialize the buffer.\n"); + goto per_clk_disable_unprepare; + } - ret = at91_adc_trigger_init(indio_dev); - if (ret < 0) { - dev_err(&pdev->dev, "couldn't setup the triggers.\n"); - goto per_clk_disable_unprepare; + ret = at91_adc_trigger_init(indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "couldn't setup the triggers.\n"); + goto per_clk_disable_unprepare; + } } ret = iio_device_register(indio_dev); if (ret < 0) goto per_clk_disable_unprepare; - dev_info(&pdev->dev, "setting up trigger as %s\n", - st->selected_trig->name); + if (st->selected_trig->hw_trig) + dev_info(&pdev->dev, "setting up trigger as %s\n", + st->selected_trig->name); dev_info(&pdev->dev, "version: %x\n", readl_relaxed(st->base + AT91_SAMA5D2_VERSION)); -- cgit v1.2.3 From 3efc93c2bc243f940beb3324f67aa14e223abdd1 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 13 Oct 2017 13:39:22 -0400 Subject: net: dsa: mv88e6060: fix switch MAC address The 88E6060 Ethernet switch always transmits the multicast bit of the switch MAC address as a zero. It re-uses the corresponding bit 8 of the register "Switch MAC Address Register Bytes 0 & 1" for "DiffAddr". If the "DiffAddr" bit is 0, then all ports transmit the same source address. If it is set to 1, then bit 2:0 are used for the port number. The mv88e6060 driver is currently wrongly shifting the MAC address byte 0 by 9. To fix this, shift it by 8 as usual and clear its bit 0. Signed-off-by: Vivien Didelot Reviewed-by: Woojung Huh Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6060.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c index dce7fa57eb55..f123ed57630d 100644 --- a/drivers/net/dsa/mv88e6060.c +++ b/drivers/net/dsa/mv88e6060.c @@ -214,8 +214,14 @@ static int mv88e6060_setup(struct dsa_switch *ds) static int mv88e6060_set_addr(struct dsa_switch *ds, u8 *addr) { - /* Use the same MAC Address as FD Pause frames for all ports */ - REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, (addr[0] << 9) | addr[1]); + u16 val = addr[0] << 8 | addr[1]; + + /* The multicast bit is always transmitted as a zero, so the switch uses + * bit 8 for "DiffAddr", where 0 means all ports transmit the same SA. + */ + val &= 0xfeff; + + REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, val); REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]); REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]); -- cgit v1.2.3 From c213eae8d3cd4c026f348ce4fd64f4754b3acf2b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 13 Oct 2017 21:09:29 -0400 Subject: bnxt_en: Improve VF/PF link change logic. Link status query firmware messages originating from the VFs are forwarded to the PF. The driver handles these interactions in a workqueue for the VF and PF. The VF driver waits for the response from the PF in the workqueue. If the PF and VF driver are running on the same host and the work for both PF and VF are queued on the same workqueue, the VF driver may not get the response if the PF work item is queued behind it on the same workqueue. This will lead to the VF link query message timing out. To prevent this, we create a private workqueue for PFs instead of using the common workqueue. The VF query and PF response will never be on the same workqueue. Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 66 +++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index aacec8bc19d5..7906153c5c05 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -214,6 +214,8 @@ static const u16 bnxt_async_events_arr[] = { ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE, }; +static struct workqueue_struct *bnxt_pf_wq; + static bool bnxt_vf_pciid(enum board_idx idx) { return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF); @@ -1024,12 +1026,28 @@ static int bnxt_discard_rx(struct bnxt *bp, struct bnxt_napi *bnapi, return 0; } +static void bnxt_queue_sp_work(struct bnxt *bp) +{ + if (BNXT_PF(bp)) + queue_work(bnxt_pf_wq, &bp->sp_task); + else + schedule_work(&bp->sp_task); +} + +static void bnxt_cancel_sp_work(struct bnxt *bp) +{ + if (BNXT_PF(bp)) + flush_workqueue(bnxt_pf_wq); + else + cancel_work_sync(&bp->sp_task); +} + static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) { if (!rxr->bnapi->in_reset) { rxr->bnapi->in_reset = true; set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); } rxr->rx_next_cons = 0xffff; } @@ -1717,7 +1735,7 @@ static int bnxt_async_event_process(struct bnxt *bp, default: goto async_event_process_exit; } - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); async_event_process_exit: bnxt_ulp_async_events(bp, cmpl); return 0; @@ -1751,7 +1769,7 @@ static int bnxt_hwrm_handler(struct bnxt *bp, struct tx_cmp *txcmp) set_bit(vf_id - bp->pf.first_vf_id, bp->pf.vf_event_bmap); set_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); break; case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT: @@ -6647,7 +6665,7 @@ static void bnxt_set_rx_mode(struct net_device *dev) vnic->rx_mask = mask; set_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); } } @@ -6920,7 +6938,7 @@ static void bnxt_tx_timeout(struct net_device *dev) netdev_err(bp->dev, "TX timeout detected, starting reset task!\n"); set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -6952,7 +6970,7 @@ static void bnxt_timer(unsigned long data) if (bp->link_info.link_up && (bp->flags & BNXT_FLAG_PORT_STATS) && bp->stats_coal_ticks) { set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); } bnxt_restart_timer: mod_timer(&bp->timer, jiffies + bp->current_interval); @@ -7433,7 +7451,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, spin_unlock_bh(&bp->ntp_fltr_lock); set_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); return new_fltr->sw_id; @@ -7516,7 +7534,7 @@ static void bnxt_udp_tunnel_add(struct net_device *dev, if (bp->vxlan_port_cnt == 1) { bp->vxlan_port = ti->port; set_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event); - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); } break; case UDP_TUNNEL_TYPE_GENEVE: @@ -7533,7 +7551,7 @@ static void bnxt_udp_tunnel_add(struct net_device *dev, return; } - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); } static void bnxt_udp_tunnel_del(struct net_device *dev, @@ -7572,7 +7590,7 @@ static void bnxt_udp_tunnel_del(struct net_device *dev, return; } - schedule_work(&bp->sp_task); + bnxt_queue_sp_work(bp); } static int bnxt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, @@ -7720,7 +7738,7 @@ static void bnxt_remove_one(struct pci_dev *pdev) pci_disable_pcie_error_reporting(pdev); unregister_netdev(dev); bnxt_shutdown_tc(bp); - cancel_work_sync(&bp->sp_task); + bnxt_cancel_sp_work(bp); bp->sp_event = 0; bnxt_clear_int_mode(bp); @@ -8138,8 +8156,17 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) else device_set_wakeup_capable(&pdev->dev, false); - if (BNXT_PF(bp)) + if (BNXT_PF(bp)) { + if (!bnxt_pf_wq) { + bnxt_pf_wq = + create_singlethread_workqueue("bnxt_pf_wq"); + if (!bnxt_pf_wq) { + dev_err(&pdev->dev, "Unable to create workqueue.\n"); + goto init_err_pci_clean; + } + } bnxt_init_tc(bp); + } rc = register_netdev(dev); if (rc) @@ -8375,4 +8402,17 @@ static struct pci_driver bnxt_pci_driver = { #endif }; -module_pci_driver(bnxt_pci_driver); +static int __init bnxt_init(void) +{ + return pci_register_driver(&bnxt_pci_driver); +} + +static void __exit bnxt_exit(void) +{ + pci_unregister_driver(&bnxt_pci_driver); + if (bnxt_pf_wq) + destroy_workqueue(bnxt_pf_wq); +} + +module_init(bnxt_init); +module_exit(bnxt_exit); -- cgit v1.2.3 From e2dc9b6e38fa3919e63d6d7905da70ca41cbf908 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 13 Oct 2017 21:09:30 -0400 Subject: bnxt_en: Don't use rtnl lock to protect link change logic in workqueue. As a further improvement to the PF/VF link change logic, use a private mutex instead of the rtnl lock to protect link change logic. With the new mutex, we don't have to take the rtnl lock in the workqueue when we have to handle link related functions. If the VF and PF drivers are running on the same host and both take the rtnl lock and one is waiting for the other, it will cause timeout. This patch fixes these timeouts. Fixes: 90c694bb7181 ("bnxt_en: Fix RTNL lock usage on bnxt_update_link().") Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 25 ++++++++++++----------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 ++++ drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 4 ++++ 3 files changed, 21 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 7906153c5c05..3f596de2abe3 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -6345,7 +6345,9 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) } if (link_re_init) { + mutex_lock(&bp->link_lock); rc = bnxt_update_phy_setting(bp); + mutex_unlock(&bp->link_lock); if (rc) netdev_warn(bp->dev, "failed to update phy settings\n"); } @@ -7043,30 +7045,28 @@ static void bnxt_sp_task(struct work_struct *work) if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) bnxt_hwrm_port_qstats(bp); - /* These functions below will clear BNXT_STATE_IN_SP_TASK. They - * must be the last functions to be called before exiting. - */ if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { - int rc = 0; + int rc; + mutex_lock(&bp->link_lock); if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, &bp->sp_event)) bnxt_hwrm_phy_qcaps(bp); - bnxt_rtnl_lock_sp(bp); - if (test_bit(BNXT_STATE_OPEN, &bp->state)) - rc = bnxt_update_link(bp, true); - bnxt_rtnl_unlock_sp(bp); + rc = bnxt_update_link(bp, true); + mutex_unlock(&bp->link_lock); if (rc) netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", rc); } if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) { - bnxt_rtnl_lock_sp(bp); - if (test_bit(BNXT_STATE_OPEN, &bp->state)) - bnxt_get_port_module_status(bp); - bnxt_rtnl_unlock_sp(bp); + mutex_lock(&bp->link_lock); + bnxt_get_port_module_status(bp); + mutex_unlock(&bp->link_lock); } + /* These functions below will clear BNXT_STATE_IN_SP_TASK. They + * must be the last functions to be called before exiting. + */ if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) bnxt_reset(bp, false); @@ -7766,6 +7766,7 @@ static int bnxt_probe_phy(struct bnxt *bp) rc); return rc; } + mutex_init(&bp->link_lock); rc = bnxt_update_link(bp, false); if (rc) { diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 7b888d4b2b55..d2925c04709a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1290,6 +1290,10 @@ struct bnxt { unsigned long *ntp_fltr_bmap; int ntp_fltr_count; + /* To protect link related settings during link changes and + * ethtool settings changes. + */ + struct mutex link_lock; struct bnxt_link_info link_info; struct ethtool_eee eee; u32 lpi_tmr_lo; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 8eff05a3e0e4..b2cbc970b497 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1052,6 +1052,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev, u32 ethtool_speed; ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported); + mutex_lock(&bp->link_lock); bnxt_fw_to_ethtool_support_spds(link_info, lk_ksettings); ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising); @@ -1099,6 +1100,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev, base->port = PORT_FIBRE; } base->phy_address = link_info->phy_addr; + mutex_unlock(&bp->link_lock); return 0; } @@ -1190,6 +1192,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev, if (!BNXT_SINGLE_PF(bp)) return -EOPNOTSUPP; + mutex_lock(&bp->link_lock); if (base->autoneg == AUTONEG_ENABLE) { BNXT_ETHTOOL_TO_FW_SPDS(fw_advertising, lk_ksettings, advertising); @@ -1234,6 +1237,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev, rc = bnxt_hwrm_set_link_setting(bp, set_pause, false); set_setting_exit: + mutex_unlock(&bp->link_lock); return rc; } -- cgit v1.2.3 From 7ab0760f5178169c4c218852f51646ea90817d7c Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Fri, 13 Oct 2017 21:09:31 -0400 Subject: bnxt_en: Fix VF PCIe link speed and width logic. PCIE PCIE_EP_REG_LINK_STATUS_CONTROL register is only defined in PF config space, so we must read it from the PF. Fixes: 90c4f788f6c0 ("bnxt_en: Report PCIe link speed and width during driver load") Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 3f596de2abe3..4ffa0b1e565a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -7965,7 +7965,7 @@ static void bnxt_parse_log_pcie_link(struct bnxt *bp) enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN; enum pci_bus_speed speed = PCI_SPEED_UNKNOWN; - if (pcie_get_minimum_link(bp->pdev, &speed, &width) || + if (pcie_get_minimum_link(pci_physfn(bp->pdev), &speed, &width) || speed == PCI_SPEED_UNKNOWN || width == PCIE_LNK_WIDTH_UNKNOWN) netdev_info(bp->dev, "Failed to determine PCIe Link Info\n"); else -- cgit v1.2.3 From 021570793d8cd86cb62ac038c535f4450586b454 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 13 Oct 2017 21:09:32 -0400 Subject: bnxt_en: Fix VF resource checking. In bnxt_sriov_enable(), we calculate to see if we have enough hardware resources to enable the requested number of VFs. The logic to check for minimum completion rings and statistics contexts is missing. Add the required checks so that VF configuration won't fail. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index d37925a8a65b..5ee18660bc33 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -502,6 +502,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs) int rc = 0, vfs_supported; int min_rx_rings, min_tx_rings, min_rss_ctxs; int tx_ok = 0, rx_ok = 0, rss_ok = 0; + int avail_cp, avail_stat; /* Check if we can enable requested num of vf's. At a mininum * we require 1 RX 1 TX rings for each VF. In this minimum conf @@ -509,6 +510,10 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs) */ vfs_supported = *num_vfs; + avail_cp = bp->pf.max_cp_rings - bp->cp_nr_rings; + avail_stat = bp->pf.max_stat_ctxs - bp->num_stat_ctxs; + avail_cp = min_t(int, avail_cp, avail_stat); + while (vfs_supported) { min_rx_rings = vfs_supported; min_tx_rings = vfs_supported; @@ -523,10 +528,12 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs) min_rx_rings) rx_ok = 1; } - if (bp->pf.max_vnics - bp->nr_vnics < min_rx_rings) + if (bp->pf.max_vnics - bp->nr_vnics < min_rx_rings || + avail_cp < min_rx_rings) rx_ok = 0; - if (bp->pf.max_tx_rings - bp->tx_nr_rings >= min_tx_rings) + if (bp->pf.max_tx_rings - bp->tx_nr_rings >= min_tx_rings && + avail_cp >= min_tx_rings) tx_ok = 1; if (bp->pf.max_rsscos_ctxs - bp->rsscos_nr_ctxs >= min_rss_ctxs) -- cgit v1.2.3 From cc72f3b1feb4fd38d33ab7a013d5ab95041cb8ba Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 13 Oct 2017 21:09:33 -0400 Subject: bnxt_en: Fix possible corrupted NVRAM parameters from firmware response. In bnxt_find_nvram_item(), it is copying firmware response data after releasing the mutex. This can cause the firmware response data to be corrupted if the next firmware response overwrites the response buffer. The rare problem shows up when running ethtool -i repeatedly. Fix it by calling the new variant _hwrm_send_message_silent() that requires the caller to take the mutex and to release it after the response data has been copied. Fixes: 3ebf6f0a09a2 ("bnxt_en: Add installed-package version reporting via Ethtool GDRVINFO") Reported-by: Sarveswara Rao Mygapula Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 ++++++ drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 4ffa0b1e565a..dc5de275352a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3466,6 +3466,12 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, false); } +int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 msg_len, + int timeout) +{ + return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, true); +} + int hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) { int rc; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index d2925c04709a..c911e69ff25f 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1362,6 +1362,7 @@ void bnxt_set_ring_params(struct bnxt *); int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode); void bnxt_hwrm_cmd_hdr_init(struct bnxt *, void *, u16, u16, u16); int _hwrm_send_message(struct bnxt *, void *, u32, int); +int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 len, int timeout); int hwrm_send_message(struct bnxt *, void *, u32, int); int hwrm_send_message_silent(struct bnxt *, void *, u32, int); int bnxt_hwrm_func_rgtr_async_events(struct bnxt *bp, unsigned long *bmap, diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index b2cbc970b497..3cbe771b3352 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1809,7 +1809,8 @@ static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal, req.dir_ordinal = cpu_to_le16(ordinal); req.dir_ext = cpu_to_le16(ext); req.opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ; - rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + mutex_lock(&bp->hwrm_cmd_lock); + rc = _hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); if (rc == 0) { if (index) *index = le16_to_cpu(output->dir_idx); @@ -1818,6 +1819,7 @@ static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal, if (data_length) *data_length = le32_to_cpu(output->dir_data_length); } + mutex_unlock(&bp->hwrm_cmd_lock); return rc; } -- cgit v1.2.3 From 5b1e1a9ce06fd94b563d6c3dd896589231995d89 Mon Sep 17 00:00:00 2001 From: Sankar Patchineelam Date: Fri, 13 Oct 2017 21:09:34 -0400 Subject: bnxt_en: Fix possible corruption in DCB parameters from firmware. hwrm_send_message() is replaced with _hwrm_send_message(), and hwrm_cmd_lock mutex lock is grabbed for the whole period of firmware call until the firmware DCB parameters have been copied. This will prevent possible corruption of the firmware data. Fixes: 7df4ae9fe855 ("bnxt_en: Implement DCBNL to support host-based DCBX.") Signed-off-by: Sankar Patchineelam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c index aa1f3a2c7a78..fed37cd9ae1d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c @@ -50,7 +50,9 @@ static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets) bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PRI2COS_QCFG, -1, -1); req.flags = cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN); - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + + mutex_lock(&bp->hwrm_cmd_lock); + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); if (!rc) { u8 *pri2cos = &resp->pri0_cos_queue_id; int i, j; @@ -66,6 +68,7 @@ static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets) } } } + mutex_unlock(&bp->hwrm_cmd_lock); return rc; } @@ -119,9 +122,13 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets) int rc, i; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_COS2BW_QCFG, -1, -1); - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); - if (rc) + + mutex_lock(&bp->hwrm_cmd_lock); + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (rc) { + mutex_unlock(&bp->hwrm_cmd_lock); return rc; + } data = &resp->queue_id0 + offsetof(struct bnxt_cos2bw_cfg, queue_id); for (i = 0; i < bp->max_tc; i++, data += sizeof(cos2bw) - 4) { @@ -143,6 +150,7 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets) } } } + mutex_unlock(&bp->hwrm_cmd_lock); return 0; } @@ -240,12 +248,17 @@ static int bnxt_hwrm_queue_pfc_qcfg(struct bnxt *bp, struct ieee_pfc *pfc) int rc; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PFCENABLE_QCFG, -1, -1); - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); - if (rc) + + mutex_lock(&bp->hwrm_cmd_lock); + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (rc) { + mutex_unlock(&bp->hwrm_cmd_lock); return rc; + } pri_mask = le32_to_cpu(resp->flags); pfc->pfc_en = pri_mask; + mutex_unlock(&bp->hwrm_cmd_lock); return 0; } -- cgit v1.2.3 From 0a51897bfac9886d36e986d009df0317582b19a2 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 9 Oct 2017 10:43:53 +0200 Subject: drm/exynos: Fix potential NULL pointer dereference in suspend/resume paths The patch 6e8edf8a7d8d: "drm/exynos: Fix suspend/resume support" introduced a new code in suspend/resume paths. However it unconditionally dereference drm_dev pointer, which might be NULL if suspend/resume happens before Exynos DRM driver components bind. This patch fixes this issue. Reported-by: Dan Carpenter Fixes: 6e8edf8a7d8d "drm/exynos: Fix suspend/resume support" Signed-off-by: Marek Szyprowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index e651a58c18cf..aa770bb0153c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -168,11 +168,13 @@ static struct drm_driver exynos_drm_driver = { static int exynos_drm_suspend(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); - struct exynos_drm_private *private = drm_dev->dev_private; + struct exynos_drm_private *private; if (pm_runtime_suspended(dev) || !drm_dev) return 0; + private = drm_dev->dev_private; + drm_kms_helper_poll_disable(drm_dev); exynos_drm_fbdev_suspend(drm_dev); private->suspend_state = drm_atomic_helper_suspend(drm_dev); @@ -188,11 +190,12 @@ static int exynos_drm_suspend(struct device *dev) static int exynos_drm_resume(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); - struct exynos_drm_private *private = drm_dev->dev_private; + struct exynos_drm_private *private; if (pm_runtime_suspended(dev) || !drm_dev) return 0; + private = drm_dev->dev_private; drm_atomic_helper_resume(drm_dev, private->suspend_state); exynos_drm_fbdev_resume(drm_dev); drm_kms_helper_poll_enable(drm_dev); -- cgit v1.2.3 From 238604ca0b708319e089e22545bcda39afb5faa8 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 9 Oct 2017 10:44:01 +0200 Subject: drm/exynos: Clear drvdata after component unbind When components are unbound, DRM driver is unregistered and freed, so clear drvdata to avoid potential use-after-free issue in suspend/resume paths. Signed-off-by: Marek Szyprowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index aa770bb0153c..82b72425a42f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -430,6 +430,7 @@ static void exynos_drm_unbind(struct device *dev) kfree(drm->dev_private); drm->dev_private = NULL; + dev_set_drvdata(dev, NULL); drm_dev_unref(drm); } -- cgit v1.2.3 From 31dc3f819bac28a0990b36510197560258ab7421 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 12 Oct 2017 14:50:46 +0200 Subject: USB: serial: metro-usb: add MS7820 device id Add device-id entry for (Honeywell) Metrologic MS7820 bar code scanner. The device has two interfaces (in this mode?); a vendor-specific interface with two interrupt endpoints and a second HID interface, which we do not bind to. Reported-by: Ladislav Dobrovsky Tested-by: Ladislav Dobrovsky Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/metro-usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index cc84da8dbb84..14511d6a7d44 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -45,6 +45,7 @@ struct metrousb_private { static const struct usb_device_id id_table[] = { { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, + { USB_DEVICE_INTERFACE_CLASS(0x0c2e, 0x0730, 0xff) }, /* MS7820 */ { }, /* Terminating entry. */ }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v1.2.3 From 1fd51d9d97059cb7dd0bf7a3b6f7cb609d485718 Mon Sep 17 00:00:00 2001 From: Weinan Li Date: Sun, 15 Oct 2017 11:55:25 +0800 Subject: drm/i915: enable to read CSB and CSB write pointer from HWSP in GVT-g VM Let GVT-g VM read the CSB and CSB write pointer from virtual HWSP, not all the host support this feature, need to check the BIT(3) of caps in PVINFO. v3 : Remove unnecessary comments. v4 : Separate VM enable patch with GVT-g implementation patch due to code dependency. v5 : Use inline for GVT virtual HWSP caps check function. v6 : Comments refine. Signed-off-by: Weinan Li Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/1508039725-1066-1-git-send-email-weinan.z.li@intel.com --- drivers/gpu/drm/i915/i915_pvinfo.h | 1 + drivers/gpu/drm/i915/i915_vgpu.h | 6 ++++++ drivers/gpu/drm/i915/intel_engine_cs.c | 9 +++++---- drivers/gpu/drm/i915/intel_lrc.c | 1 - 4 files changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h index 0679a58cdbae..195203f298df 100644 --- a/drivers/gpu/drm/i915/i915_pvinfo.h +++ b/drivers/gpu/drm/i915/i915_pvinfo.h @@ -53,6 +53,7 @@ enum vgt_g2v_type { * VGT capabilities type */ #define VGT_CAPS_FULL_48BIT_PPGTT BIT(2) +#define VGT_CAPS_HWSP_EMULATION BIT(3) struct vgt_if { u64 magic; /* VGT_MAGIC */ diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h index b72bd2956b70..bb8338450dc1 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.h +++ b/drivers/gpu/drm/i915/i915_vgpu.h @@ -30,6 +30,12 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv); bool intel_vgpu_has_full_48bit_ppgtt(struct drm_i915_private *dev_priv); +static inline bool +intel_vgpu_has_hwsp_emulation(struct drm_i915_private *dev_priv) +{ + return dev_priv->vgpu.caps & VGT_CAPS_HWSP_EMULATION; +} + int intel_vgt_balloon(struct drm_i915_private *dev_priv); void intel_vgt_deballoon(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index a59b2a30ff5a..83e696f67d42 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -25,6 +25,7 @@ #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "intel_ringbuffer.h" #include "intel_lrc.h" @@ -386,10 +387,6 @@ static void intel_engine_init_timeline(struct intel_engine_cs *engine) static bool csb_force_mmio(struct drm_i915_private *i915) { - /* GVT emulation depends upon intercepting CSB mmio */ - if (intel_vgpu_active(i915)) - return true; - /* * IOMMU adds unpredictable latency causing the CSB write (from the * GPU into the HWSP) to only be visible some time after the interrupt @@ -398,6 +395,10 @@ static bool csb_force_mmio(struct drm_i915_private *i915) if (intel_vtd_active()) return true; + /* Older GVT emulation depends upon intercepting CSB mmio */ + if (intel_vgpu_active(i915) && !intel_vgpu_has_hwsp_emulation(i915)) + return true; + return false; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index fbfcf88d7fe3..766552f2cfae 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -793,7 +793,6 @@ static void intel_lrc_irq_handler(unsigned long data) &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; unsigned int head, tail; - /* However GVT emulation depends upon intercepting CSB mmio */ if (unlikely(execlists->csb_use_mmio)) { buf = (u32 * __force) (dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); -- cgit v1.2.3 From 46f1e8b3de827057cdbeb9a78e6994b1f0386474 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:10 +0000 Subject: drm/i915: Move intel_guc_wopcm_size to intel_guc.c Function intel_guc_wopcm_size didn't fit well in the old place. With this move upcoming cleanup will be simpler. Suggested-by: Joonas Lahtinen Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc.c | 11 +++++++++++ drivers/gpu/drm/i915/intel_guc_loader.c | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c index 9e18c4fb9909..be1c9a7f4ff3 100644 --- a/drivers/gpu/drm/i915/intel_guc.c +++ b/drivers/gpu/drm/i915/intel_guc.c @@ -263,3 +263,14 @@ err: i915_gem_object_put(obj); return vma; } + +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv) +{ + u32 wopcm_size = GUC_WOPCM_TOP; + + /* On BXT, the top of WOPCM is reserved for RC6 context */ + if (IS_GEN9_LP(dev_priv)) + wopcm_size -= BXT_GUC_WOPCM_RC6_RESERVED; + + return wopcm_size; +} diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index c7a800a3798d..30b70f5158f6 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -250,17 +250,6 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv, return ret; } -u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv) -{ - u32 wopcm_size = GUC_WOPCM_TOP; - - /* On BXT, the top of WOPCM is reserved for RC6 context */ - if (IS_GEN9_LP(dev_priv)) - wopcm_size -= BXT_GUC_WOPCM_RC6_RESERVED; - - return wopcm_size; -} - /* * Load the GuC firmware blob into the MinuteIA. */ -- cgit v1.2.3 From 5d53be45a86f2103a30872e2a06cbf6d38233326 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:11 +0000 Subject: drm/i915/guc: Move GuC boot param initialization out of xfer We want to keep ucode xfer functions separate from other initialization. Once separated, add explicit forcewake. v2: use BLITTER domain only and add comment (Daniele) Suggested-by: Joonas Lahtinen Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Cc: Daniele Ceraolo Spurio Reviewed-by: Chris Wilson #1 Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc.c | 92 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_guc.h | 1 + drivers/gpu/drm/i915/intel_guc_loader.c | 85 ------------------------------ drivers/gpu/drm/i915/intel_uc.c | 1 + 4 files changed, 94 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c index be1c9a7f4ff3..719144ac8fc0 100644 --- a/drivers/gpu/drm/i915/intel_guc.c +++ b/drivers/gpu/drm/i915/intel_guc.c @@ -67,6 +67,98 @@ void intel_guc_init_early(struct intel_guc *guc) guc->notify = gen8_guc_raise_irq; } +static u32 get_gttype(struct drm_i915_private *dev_priv) +{ + /* XXX: GT type based on PCI device ID? field seems unused by fw */ + return 0; +} + +static u32 get_core_family(struct drm_i915_private *dev_priv) +{ + u32 gen = INTEL_GEN(dev_priv); + + switch (gen) { + case 9: + return GUC_CORE_FAMILY_GEN9; + + default: + MISSING_CASE(gen); + return GUC_CORE_FAMILY_UNKNOWN; + } +} + +/* + * Initialise the GuC parameter block before starting the firmware + * transfer. These parameters are read by the firmware on startup + * and cannot be changed thereafter. + */ +void intel_guc_init_params(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + u32 params[GUC_CTL_MAX_DWORDS]; + int i; + + memset(¶ms, 0, sizeof(params)); + + params[GUC_CTL_DEVICE_INFO] |= + (get_gttype(dev_priv) << GUC_CTL_GTTYPE_SHIFT) | + (get_core_family(dev_priv) << GUC_CTL_COREFAMILY_SHIFT); + + /* + * GuC ARAT increment is 10 ns. GuC default scheduler quantum is one + * second. This ARAR is calculated by: + * Scheduler-Quantum-in-ns / ARAT-increment-in-ns = 1000000000 / 10 + */ + params[GUC_CTL_ARAT_HIGH] = 0; + params[GUC_CTL_ARAT_LOW] = 100000000; + + params[GUC_CTL_WA] |= GUC_CTL_WA_UK_BY_DRIVER; + + params[GUC_CTL_FEATURE] |= GUC_CTL_DISABLE_SCHEDULER | + GUC_CTL_VCS2_ENABLED; + + params[GUC_CTL_LOG_PARAMS] = guc->log.flags; + + if (i915_modparams.guc_log_level >= 0) { + params[GUC_CTL_DEBUG] = + i915_modparams.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; + } else + params[GUC_CTL_DEBUG] = GUC_LOG_DISABLED; + + /* If GuC submission is enabled, set up additional parameters here */ + if (i915_modparams.enable_guc_submission) { + u32 ads = guc_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT; + u32 pgs = guc_ggtt_offset(dev_priv->guc.stage_desc_pool); + u32 ctx_in_16 = GUC_MAX_STAGE_DESCRIPTORS / 16; + + params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT; + params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED; + + pgs >>= PAGE_SHIFT; + params[GUC_CTL_CTXINFO] = (pgs << GUC_CTL_BASE_ADDR_SHIFT) | + (ctx_in_16 << GUC_CTL_CTXNUM_IN16_SHIFT); + + params[GUC_CTL_FEATURE] |= GUC_CTL_KERNEL_SUBMISSIONS; + + /* Unmask this bit to enable the GuC's internal scheduler */ + params[GUC_CTL_FEATURE] &= ~GUC_CTL_DISABLE_SCHEDULER; + } + + /* + * All SOFT_SCRATCH registers are in FORCEWAKE_BLITTER domain and + * they are power context saved so it's ok to release forcewake + * when we are done here and take it again at xfer time. + */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_BLITTER); + + I915_WRITE(SOFT_SCRATCH(0), 0); + + for (i = 0; i < GUC_CTL_MAX_DWORDS; i++) + I915_WRITE(SOFT_SCRATCH(1 + i), params[i]); + + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_BLITTER); +} + int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len) { WARN(1, "Unexpected send: action=%#x\n", *action); diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index aa9a7b55be6e..8b441650e64b 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -95,6 +95,7 @@ static inline u32 guc_ggtt_offset(struct i915_vma *vma) void intel_guc_init_early(struct intel_guc *guc); void intel_guc_init_send_regs(struct intel_guc *guc); +void intel_guc_init_params(struct intel_guc *guc); int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len); int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len); int intel_guc_sample_forcewake(struct intel_guc *guc); diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 30b70f5158f6..d9089bccab86 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -79,89 +79,6 @@ MODULE_FIRMWARE(I915_KBL_GUC_UCODE); #define I915_GLK_GUC_UCODE GUC_FW_PATH(glk, GLK_FW_MAJOR, GLK_FW_MINOR) -static u32 get_gttype(struct drm_i915_private *dev_priv) -{ - /* XXX: GT type based on PCI device ID? field seems unused by fw */ - return 0; -} - -static u32 get_core_family(struct drm_i915_private *dev_priv) -{ - u32 gen = INTEL_GEN(dev_priv); - - switch (gen) { - case 9: - return GUC_CORE_FAMILY_GEN9; - - default: - MISSING_CASE(gen); - return GUC_CORE_FAMILY_UNKNOWN; - } -} - -/* - * Initialise the GuC parameter block before starting the firmware - * transfer. These parameters are read by the firmware on startup - * and cannot be changed thereafter. - */ -static void guc_params_init(struct drm_i915_private *dev_priv) -{ - struct intel_guc *guc = &dev_priv->guc; - u32 params[GUC_CTL_MAX_DWORDS]; - int i; - - memset(¶ms, 0, sizeof(params)); - - params[GUC_CTL_DEVICE_INFO] |= - (get_gttype(dev_priv) << GUC_CTL_GTTYPE_SHIFT) | - (get_core_family(dev_priv) << GUC_CTL_COREFAMILY_SHIFT); - - /* - * GuC ARAT increment is 10 ns. GuC default scheduler quantum is one - * second. This ARAR is calculated by: - * Scheduler-Quantum-in-ns / ARAT-increment-in-ns = 1000000000 / 10 - */ - params[GUC_CTL_ARAT_HIGH] = 0; - params[GUC_CTL_ARAT_LOW] = 100000000; - - params[GUC_CTL_WA] |= GUC_CTL_WA_UK_BY_DRIVER; - - params[GUC_CTL_FEATURE] |= GUC_CTL_DISABLE_SCHEDULER | - GUC_CTL_VCS2_ENABLED; - - params[GUC_CTL_LOG_PARAMS] = guc->log.flags; - - if (i915_modparams.guc_log_level >= 0) { - params[GUC_CTL_DEBUG] = - i915_modparams.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; - } else - params[GUC_CTL_DEBUG] = GUC_LOG_DISABLED; - - /* If GuC submission is enabled, set up additional parameters here */ - if (i915_modparams.enable_guc_submission) { - u32 ads = guc_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT; - u32 pgs = guc_ggtt_offset(dev_priv->guc.stage_desc_pool); - u32 ctx_in_16 = GUC_MAX_STAGE_DESCRIPTORS / 16; - - params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT; - params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED; - - pgs >>= PAGE_SHIFT; - params[GUC_CTL_CTXINFO] = (pgs << GUC_CTL_BASE_ADDR_SHIFT) | - (ctx_in_16 << GUC_CTL_CTXNUM_IN16_SHIFT); - - params[GUC_CTL_FEATURE] |= GUC_CTL_KERNEL_SUBMISSIONS; - - /* Unmask this bit to enable the GuC's internal scheduler */ - params[GUC_CTL_FEATURE] &= ~GUC_CTL_DISABLE_SCHEDULER; - } - - I915_WRITE(SOFT_SCRATCH(0), 0); - - for (i = 0; i < GUC_CTL_MAX_DWORDS; i++) - I915_WRITE(SOFT_SCRATCH(1 + i), params[i]); -} - /* * Read the GuC status register (GUC_STATUS) and store it in the * specified location; then return a boolean indicating whether @@ -301,8 +218,6 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv) I915_WRITE(GUC_ARAT_C6DIS, 0x1FF); } - guc_params_init(dev_priv); - ret = guc_ucode_xfer_dma(dev_priv, vma); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 7b938e822fde..53fdd9a76eb0 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -195,6 +195,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) goto err_submission; intel_huc_init_hw(&dev_priv->huc); + intel_guc_init_params(guc); ret = intel_guc_init_hw(&dev_priv->guc); if (ret == 0 || ret != -EAGAIN) break; -- cgit v1.2.3 From fdc6d7319e2b2da9ac108691c2039ee836779222 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:12 +0000 Subject: drm/i915/guc: Small fixups post code move Existing code needs some style fixes. To avoid polluting pure move patch, do it now as separate step. Suggested-by: Chris Wilson Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc.c | 11 ++++++----- drivers/gpu/drm/i915/intel_guc_fwif.h | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c index 719144ac8fc0..10037c0fdf95 100644 --- a/drivers/gpu/drm/i915/intel_guc.c +++ b/drivers/gpu/drm/i915/intel_guc.c @@ -67,7 +67,7 @@ void intel_guc_init_early(struct intel_guc *guc) guc->notify = gen8_guc_raise_irq; } -static u32 get_gttype(struct drm_i915_private *dev_priv) +static u32 get_gt_type(struct drm_i915_private *dev_priv) { /* XXX: GT type based on PCI device ID? field seems unused by fw */ return 0; @@ -98,11 +98,11 @@ void intel_guc_init_params(struct intel_guc *guc) u32 params[GUC_CTL_MAX_DWORDS]; int i; - memset(¶ms, 0, sizeof(params)); + memset(params, 0, sizeof(params)); params[GUC_CTL_DEVICE_INFO] |= - (get_gttype(dev_priv) << GUC_CTL_GTTYPE_SHIFT) | - (get_core_family(dev_priv) << GUC_CTL_COREFAMILY_SHIFT); + (get_gt_type(dev_priv) << GUC_CTL_GT_TYPE_SHIFT) | + (get_core_family(dev_priv) << GUC_CTL_CORE_FAMILY_SHIFT); /* * GuC ARAT increment is 10 ns. GuC default scheduler quantum is one @@ -122,8 +122,9 @@ void intel_guc_init_params(struct intel_guc *guc) if (i915_modparams.guc_log_level >= 0) { params[GUC_CTL_DEBUG] = i915_modparams.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; - } else + } else { params[GUC_CTL_DEBUG] = GUC_LOG_DISABLED; + } /* If GuC submission is enabled, set up additional parameters here */ if (i915_modparams.enable_guc_submission) { diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 1c0a2a3de121..80c507435458 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -82,8 +82,8 @@ #define GUC_CTL_ARAT_LOW 2 #define GUC_CTL_DEVICE_INFO 3 -#define GUC_CTL_GTTYPE_SHIFT 0 -#define GUC_CTL_COREFAMILY_SHIFT 7 +#define GUC_CTL_GT_TYPE_SHIFT 0 +#define GUC_CTL_CORE_FAMILY_SHIFT 7 #define GUC_CTL_LOG_PARAMS 4 #define GUC_LOG_VALID (1 << 0) -- cgit v1.2.3 From d9e2e0143cee8a3c08ce7db4e3adc6aebc84d1ed Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:13 +0000 Subject: drm/i915/guc: Move doc near related definitions After GuC code reorg some documentation was left in wrong place. Move it closer to corresponding definitions. v2: use consistent name for the GuC (Sagar) Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Reviewed-by: Sagar Arun Kamble Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-5-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc.h | 11 +++++++++++ drivers/gpu/drm/i915/intel_guc_loader.c | 23 ----------------------- drivers/gpu/drm/i915/intel_uc_fw.h | 5 +++++ 3 files changed, 16 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 8b441650e64b..9ad59645b7fe 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -33,6 +33,11 @@ #include "i915_guc_reg.h" #include "i915_vma.h" +/* + * Top level structure of GuC. It handles firmware loading and manages client + * pool and doorbells. intel_guc owns a i915_guc_client to replace the legacy + * ExecList submission. + */ struct intel_guc { struct intel_uc_fw fw; struct intel_guc_log log; @@ -83,6 +88,12 @@ static inline void intel_guc_notify(struct intel_guc *guc) guc->notify(guc); } +/* + * GuC does not allow any gfx GGTT address that falls into range [0, WOPCM_TOP), + * which is reserved for Boot ROM, SRAM and WOPCM. Currently this top address is + * 512K. In order to exclude 0-512K address space from GGTT, all gfx objects + * used by GuC is pinned with PIN_OFFSET_BIAS along with size of WOPCM. + */ static inline u32 guc_ggtt_offset(struct i915_vma *vma) { u32 offset = i915_ggtt_offset(vma); diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index d9089bccab86..8508b946c8e9 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -29,29 +29,6 @@ #include "i915_drv.h" #include "intel_uc.h" -/** - * DOC: GuC-specific firmware loader - * - * intel_guc: - * Top level structure of guc. It handles firmware loading and manages client - * pool and doorbells. intel_guc owns a i915_guc_client to replace the legacy - * ExecList submission. - * - * Firmware versioning: - * The firmware build process will generate a version header file with major and - * minor version defined. The versions are built into CSS header of firmware. - * i915 kernel driver set the minimal firmware version required per platform. - * The firmware installation package will install (symbolic link) proper version - * of firmware. - * - * GuC address space: - * GuC does not allow any gfx GGTT address that falls into range [0, WOPCM_TOP), - * which is reserved for Boot ROM, SRAM and WOPCM. Currently this top address is - * 512K. In order to exclude 0-512K address space from GGTT, all gfx objects - * used by GuC is pinned with PIN_OFFSET_BIAS along with size of WOPCM. - * - */ - #define SKL_FW_MAJOR 6 #define SKL_FW_MINOR 1 diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index c3e9af4b9bf0..5c018492ccdc 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -50,6 +50,11 @@ struct intel_uc_fw { enum intel_uc_fw_status fetch_status; enum intel_uc_fw_status load_status; + /* + * The firmware build process will generate a version header file with major and + * minor version defined. The versions are built into CSS header of firmware. + * i915 kernel driver set the minimal firmware version required per platform. + */ u16 major_ver_wanted; u16 minor_ver_wanted; u16 major_ver_found; -- cgit v1.2.3 From e8668bbcb0f91c7baa84be02514dff76b1eba6c8 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:14 +0000 Subject: drm/i915/guc: Rename intel_guc_loader.c to intel_guc_fw.c Remaining functions in intel_guc_loader.c were focused around GuC firmware. Rename them to match object-verb pattern and rename file itself. Suggested-by: Joonas Lahtinen Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-6-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/Makefile | 2 +- drivers/gpu/drm/i915/intel_guc.h | 4 +- drivers/gpu/drm/i915/intel_guc_fw.c | 298 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_guc_fw.h | 33 ++++ drivers/gpu/drm/i915/intel_guc_loader.c | 298 -------------------------------- drivers/gpu/drm/i915/intel_uc.c | 4 +- 6 files changed, 335 insertions(+), 304 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_guc_fw.c create mode 100644 drivers/gpu/drm/i915/intel_guc_fw.h delete mode 100644 drivers/gpu/drm/i915/intel_guc_loader.c (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 66d23b619db1..6c3b0481ef82 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -64,7 +64,7 @@ i915-y += intel_uc.o \ intel_guc.o \ intel_guc_ct.o \ intel_guc_log.o \ - intel_guc_loader.o \ + intel_guc_fw.o \ intel_huc.o \ i915_guc_submission.o diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 9ad59645b7fe..418450b1ae27 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -26,6 +26,7 @@ #define _INTEL_GUC_H_ #include "intel_uncore.h" +#include "intel_guc_fw.h" #include "intel_guc_fwif.h" #include "intel_guc_ct.h" #include "intel_guc_log.h" @@ -114,9 +115,6 @@ int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset); int intel_guc_suspend(struct drm_i915_private *dev_priv); int intel_guc_resume(struct drm_i915_private *dev_priv); struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); - -int intel_guc_select_fw(struct intel_guc *guc); -int intel_guc_init_hw(struct intel_guc *guc); u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv); #endif diff --git a/drivers/gpu/drm/i915/intel_guc_fw.c b/drivers/gpu/drm/i915/intel_guc_fw.c new file mode 100644 index 000000000000..61d6369b10b5 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_fw.c @@ -0,0 +1,298 @@ +/* + * Copyright © 2014 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Vinit Azad + * Ben Widawsky + * Dave Gordon + * Alex Dai + */ + +#include "intel_guc_fw.h" +#include "i915_drv.h" + +#define SKL_FW_MAJOR 6 +#define SKL_FW_MINOR 1 + +#define BXT_FW_MAJOR 8 +#define BXT_FW_MINOR 7 + +#define KBL_FW_MAJOR 9 +#define KBL_FW_MINOR 14 + +#define GLK_FW_MAJOR 10 +#define GLK_FW_MINOR 56 + +#define GUC_FW_PATH(platform, major, minor) \ + "i915/" __stringify(platform) "_guc_ver" __stringify(major) "_" __stringify(minor) ".bin" + +#define I915_SKL_GUC_UCODE GUC_FW_PATH(skl, SKL_FW_MAJOR, SKL_FW_MINOR) +MODULE_FIRMWARE(I915_SKL_GUC_UCODE); + +#define I915_BXT_GUC_UCODE GUC_FW_PATH(bxt, BXT_FW_MAJOR, BXT_FW_MINOR) +MODULE_FIRMWARE(I915_BXT_GUC_UCODE); + +#define I915_KBL_GUC_UCODE GUC_FW_PATH(kbl, KBL_FW_MAJOR, KBL_FW_MINOR) +MODULE_FIRMWARE(I915_KBL_GUC_UCODE); + +#define I915_GLK_GUC_UCODE GUC_FW_PATH(glk, GLK_FW_MAJOR, GLK_FW_MINOR) + +/* + * Read the GuC status register (GUC_STATUS) and store it in the + * specified location; then return a boolean indicating whether + * the value matches either of two values representing completion + * of the GuC boot process. + * + * This is used for polling the GuC status in a wait_for() + * loop below. + */ +static inline bool guc_ucode_response(struct drm_i915_private *dev_priv, + u32 *status) +{ + u32 val = I915_READ(GUC_STATUS); + u32 uk_val = val & GS_UKERNEL_MASK; + *status = val; + return (uk_val == GS_UKERNEL_READY || + ((val & GS_MIA_CORE_STATE) && uk_val == GS_UKERNEL_LAPIC_DONE)); +} + +/* + * Transfer the firmware image to RAM for execution by the microcontroller. + * + * Architecturally, the DMA engine is bidirectional, and can potentially even + * transfer between GTT locations. This functionality is left out of the API + * for now as there is no need for it. + * + * Note that GuC needs the CSS header plus uKernel code to be copied by the + * DMA engine in one operation, whereas the RSA signature is loaded via MMIO. + */ +static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv, + struct i915_vma *vma) +{ + struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; + unsigned long offset; + struct sg_table *sg = vma->pages; + u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT]; + int i, ret = 0; + + /* where RSA signature starts */ + offset = guc_fw->rsa_offset; + + /* Copy RSA signature from the fw image to HW for verification */ + sg_pcopy_to_buffer(sg->sgl, sg->nents, rsa, sizeof(rsa), offset); + for (i = 0; i < UOS_RSA_SCRATCH_MAX_COUNT; i++) + I915_WRITE(UOS_RSA_SCRATCH(i), rsa[i]); + + /* The header plus uCode will be copied to WOPCM via DMA, excluding any + * other components */ + I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size); + + /* Set the source address for the new blob */ + offset = guc_ggtt_offset(vma) + guc_fw->header_offset; + I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset)); + I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF); + + /* + * Set the DMA destination. Current uCode expects the code to be + * loaded at 8k; locations below this are used for the stack. + */ + I915_WRITE(DMA_ADDR_1_LOW, 0x2000); + I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM); + + /* Finally start the DMA */ + I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA)); + + /* + * Wait for the DMA to complete & the GuC to start up. + * NB: Docs recommend not using the interrupt for completion. + * Measurements indicate this should take no more than 20ms, so a + * timeout here indicates that the GuC has failed and is unusable. + * (Higher levels of the driver will attempt to fall back to + * execlist mode if this happens.) + */ + ret = wait_for(guc_ucode_response(dev_priv, &status), 100); + + DRM_DEBUG_DRIVER("DMA status 0x%x, GuC status 0x%x\n", + I915_READ(DMA_CTRL), status); + + if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) { + DRM_ERROR("GuC firmware signature verification failed\n"); + ret = -ENOEXEC; + } + + DRM_DEBUG_DRIVER("returning %d\n", ret); + + return ret; +} + +/* + * Load the GuC firmware blob into the MinuteIA. + */ +static int guc_ucode_xfer(struct drm_i915_private *dev_priv) +{ + struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; + struct i915_vma *vma; + int ret; + + ret = i915_gem_object_set_to_gtt_domain(guc_fw->obj, false); + if (ret) { + DRM_DEBUG_DRIVER("set-domain failed %d\n", ret); + return ret; + } + + vma = i915_gem_object_ggtt_pin(guc_fw->obj, NULL, 0, 0, + PIN_OFFSET_BIAS | GUC_WOPCM_TOP); + if (IS_ERR(vma)) { + DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma)); + return PTR_ERR(vma); + } + + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + /* Enable MIA caching. GuC clock gating is disabled. */ + I915_WRITE(GUC_SHIM_CONTROL, GUC_SHIM_CONTROL_VALUE); + + /* WaDisableMinuteIaClockGating:bxt */ + if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) { + I915_WRITE(GUC_SHIM_CONTROL, (I915_READ(GUC_SHIM_CONTROL) & + ~GUC_ENABLE_MIA_CLOCK_GATING)); + } + + /* WaC6DisallowByGfxPause:bxt */ + if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) + I915_WRITE(GEN6_GFXPAUSE, 0x30FFF); + + if (IS_GEN9_LP(dev_priv)) + I915_WRITE(GEN9LP_GT_PM_CONFIG, GT_DOORBELL_ENABLE); + else + I915_WRITE(GEN9_GT_PM_CONFIG, GT_DOORBELL_ENABLE); + + if (IS_GEN9(dev_priv)) { + /* DOP Clock Gating Enable for GuC clocks */ + I915_WRITE(GEN7_MISCCPCTL, (GEN8_DOP_CLOCK_GATE_GUC_ENABLE | + I915_READ(GEN7_MISCCPCTL))); + + /* allows for 5us (in 10ns units) before GT can go to RC6 */ + I915_WRITE(GUC_ARAT_C6DIS, 0x1FF); + } + + ret = guc_ucode_xfer_dma(dev_priv, vma); + + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); + + /* + * We keep the object pages for reuse during resume. But we can unpin it + * now that DMA has completed, so it doesn't continue to take up space. + */ + i915_vma_unpin(vma); + + return ret; +} + +/** + * intel_guc_fw_upload() - finish preparing the GuC for activity + * @guc: intel_guc structure + * + * Called during driver loading and also after a GPU reset. + * + * The main action required here it to load the GuC uCode into the device. + * The firmware image should have already been fetched into memory by the + * earlier call to intel_guc_init(), so here we need only check that + * worked, and then transfer the image to the h/w. + * + * Return: non-zero code on error + */ +int intel_guc_fw_upload(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + const char *fw_path = guc->fw.path; + int ret; + + DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n", + fw_path, + intel_uc_fw_status_repr(guc->fw.fetch_status), + intel_uc_fw_status_repr(guc->fw.load_status)); + + if (guc->fw.fetch_status != INTEL_UC_FIRMWARE_SUCCESS) + return -EIO; + + guc->fw.load_status = INTEL_UC_FIRMWARE_PENDING; + + DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n", + intel_uc_fw_status_repr(guc->fw.fetch_status), + intel_uc_fw_status_repr(guc->fw.load_status)); + + ret = guc_ucode_xfer(dev_priv); + + if (ret) + return -EAGAIN; + + guc->fw.load_status = INTEL_UC_FIRMWARE_SUCCESS; + + DRM_INFO("GuC %s (firmware %s [version %u.%u])\n", + i915_modparams.enable_guc_submission ? "submission enabled" : + "loaded", + guc->fw.path, + guc->fw.major_ver_found, guc->fw.minor_ver_found); + + return 0; +} + +/** + * intel_guc_fw_select() - selects GuC firmware for loading + * @guc: intel_guc struct + * + * Return: zero when we know firmware, non-zero in other case + */ +int intel_guc_fw_select(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + + intel_uc_fw_init(&guc->fw, INTEL_UC_FW_TYPE_GUC); + + if (i915_modparams.guc_firmware_path) { + guc->fw.path = i915_modparams.guc_firmware_path; + guc->fw.major_ver_wanted = 0; + guc->fw.minor_ver_wanted = 0; + } else if (IS_SKYLAKE(dev_priv)) { + guc->fw.path = I915_SKL_GUC_UCODE; + guc->fw.major_ver_wanted = SKL_FW_MAJOR; + guc->fw.minor_ver_wanted = SKL_FW_MINOR; + } else if (IS_BROXTON(dev_priv)) { + guc->fw.path = I915_BXT_GUC_UCODE; + guc->fw.major_ver_wanted = BXT_FW_MAJOR; + guc->fw.minor_ver_wanted = BXT_FW_MINOR; + } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { + guc->fw.path = I915_KBL_GUC_UCODE; + guc->fw.major_ver_wanted = KBL_FW_MAJOR; + guc->fw.minor_ver_wanted = KBL_FW_MINOR; + } else if (IS_GEMINILAKE(dev_priv)) { + guc->fw.path = I915_GLK_GUC_UCODE; + guc->fw.major_ver_wanted = GLK_FW_MAJOR; + guc->fw.minor_ver_wanted = GLK_FW_MINOR; + } else { + DRM_ERROR("No GuC firmware known for platform with GuC!\n"); + return -ENOENT; + } + + return 0; +} diff --git a/drivers/gpu/drm/i915/intel_guc_fw.h b/drivers/gpu/drm/i915/intel_guc_fw.h new file mode 100644 index 000000000000..023f5baa9dd6 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_fw.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2017 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +#ifndef _INTEL_GUC_FW_H_ +#define _INTEL_GUC_FW_H_ + +struct intel_guc; + +int intel_guc_fw_select(struct intel_guc *guc); +int intel_guc_fw_upload(struct intel_guc *guc); + +#endif diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c deleted file mode 100644 index 8508b946c8e9..000000000000 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright © 2014 Intel Corporation - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Authors: - * Vinit Azad - * Ben Widawsky - * Dave Gordon - * Alex Dai - */ -#include "i915_drv.h" -#include "intel_uc.h" - -#define SKL_FW_MAJOR 6 -#define SKL_FW_MINOR 1 - -#define BXT_FW_MAJOR 8 -#define BXT_FW_MINOR 7 - -#define KBL_FW_MAJOR 9 -#define KBL_FW_MINOR 14 - -#define GLK_FW_MAJOR 10 -#define GLK_FW_MINOR 56 - -#define GUC_FW_PATH(platform, major, minor) \ - "i915/" __stringify(platform) "_guc_ver" __stringify(major) "_" __stringify(minor) ".bin" - -#define I915_SKL_GUC_UCODE GUC_FW_PATH(skl, SKL_FW_MAJOR, SKL_FW_MINOR) -MODULE_FIRMWARE(I915_SKL_GUC_UCODE); - -#define I915_BXT_GUC_UCODE GUC_FW_PATH(bxt, BXT_FW_MAJOR, BXT_FW_MINOR) -MODULE_FIRMWARE(I915_BXT_GUC_UCODE); - -#define I915_KBL_GUC_UCODE GUC_FW_PATH(kbl, KBL_FW_MAJOR, KBL_FW_MINOR) -MODULE_FIRMWARE(I915_KBL_GUC_UCODE); - -#define I915_GLK_GUC_UCODE GUC_FW_PATH(glk, GLK_FW_MAJOR, GLK_FW_MINOR) - - -/* - * Read the GuC status register (GUC_STATUS) and store it in the - * specified location; then return a boolean indicating whether - * the value matches either of two values representing completion - * of the GuC boot process. - * - * This is used for polling the GuC status in a wait_for() - * loop below. - */ -static inline bool guc_ucode_response(struct drm_i915_private *dev_priv, - u32 *status) -{ - u32 val = I915_READ(GUC_STATUS); - u32 uk_val = val & GS_UKERNEL_MASK; - *status = val; - return (uk_val == GS_UKERNEL_READY || - ((val & GS_MIA_CORE_STATE) && uk_val == GS_UKERNEL_LAPIC_DONE)); -} - -/* - * Transfer the firmware image to RAM for execution by the microcontroller. - * - * Architecturally, the DMA engine is bidirectional, and can potentially even - * transfer between GTT locations. This functionality is left out of the API - * for now as there is no need for it. - * - * Note that GuC needs the CSS header plus uKernel code to be copied by the - * DMA engine in one operation, whereas the RSA signature is loaded via MMIO. - */ -static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv, - struct i915_vma *vma) -{ - struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; - unsigned long offset; - struct sg_table *sg = vma->pages; - u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT]; - int i, ret = 0; - - /* where RSA signature starts */ - offset = guc_fw->rsa_offset; - - /* Copy RSA signature from the fw image to HW for verification */ - sg_pcopy_to_buffer(sg->sgl, sg->nents, rsa, sizeof(rsa), offset); - for (i = 0; i < UOS_RSA_SCRATCH_MAX_COUNT; i++) - I915_WRITE(UOS_RSA_SCRATCH(i), rsa[i]); - - /* The header plus uCode will be copied to WOPCM via DMA, excluding any - * other components */ - I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size); - - /* Set the source address for the new blob */ - offset = guc_ggtt_offset(vma) + guc_fw->header_offset; - I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset)); - I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF); - - /* - * Set the DMA destination. Current uCode expects the code to be - * loaded at 8k; locations below this are used for the stack. - */ - I915_WRITE(DMA_ADDR_1_LOW, 0x2000); - I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM); - - /* Finally start the DMA */ - I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA)); - - /* - * Wait for the DMA to complete & the GuC to start up. - * NB: Docs recommend not using the interrupt for completion. - * Measurements indicate this should take no more than 20ms, so a - * timeout here indicates that the GuC has failed and is unusable. - * (Higher levels of the driver will attempt to fall back to - * execlist mode if this happens.) - */ - ret = wait_for(guc_ucode_response(dev_priv, &status), 100); - - DRM_DEBUG_DRIVER("DMA status 0x%x, GuC status 0x%x\n", - I915_READ(DMA_CTRL), status); - - if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) { - DRM_ERROR("GuC firmware signature verification failed\n"); - ret = -ENOEXEC; - } - - DRM_DEBUG_DRIVER("returning %d\n", ret); - - return ret; -} - -/* - * Load the GuC firmware blob into the MinuteIA. - */ -static int guc_ucode_xfer(struct drm_i915_private *dev_priv) -{ - struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; - struct i915_vma *vma; - int ret; - - ret = i915_gem_object_set_to_gtt_domain(guc_fw->obj, false); - if (ret) { - DRM_DEBUG_DRIVER("set-domain failed %d\n", ret); - return ret; - } - - vma = i915_gem_object_ggtt_pin(guc_fw->obj, NULL, 0, 0, - PIN_OFFSET_BIAS | GUC_WOPCM_TOP); - if (IS_ERR(vma)) { - DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma)); - return PTR_ERR(vma); - } - - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); - - /* Enable MIA caching. GuC clock gating is disabled. */ - I915_WRITE(GUC_SHIM_CONTROL, GUC_SHIM_CONTROL_VALUE); - - /* WaDisableMinuteIaClockGating:bxt */ - if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) { - I915_WRITE(GUC_SHIM_CONTROL, (I915_READ(GUC_SHIM_CONTROL) & - ~GUC_ENABLE_MIA_CLOCK_GATING)); - } - - /* WaC6DisallowByGfxPause:bxt */ - if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) - I915_WRITE(GEN6_GFXPAUSE, 0x30FFF); - - if (IS_GEN9_LP(dev_priv)) - I915_WRITE(GEN9LP_GT_PM_CONFIG, GT_DOORBELL_ENABLE); - else - I915_WRITE(GEN9_GT_PM_CONFIG, GT_DOORBELL_ENABLE); - - if (IS_GEN9(dev_priv)) { - /* DOP Clock Gating Enable for GuC clocks */ - I915_WRITE(GEN7_MISCCPCTL, (GEN8_DOP_CLOCK_GATE_GUC_ENABLE | - I915_READ(GEN7_MISCCPCTL))); - - /* allows for 5us (in 10ns units) before GT can go to RC6 */ - I915_WRITE(GUC_ARAT_C6DIS, 0x1FF); - } - - ret = guc_ucode_xfer_dma(dev_priv, vma); - - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); - - /* - * We keep the object pages for reuse during resume. But we can unpin it - * now that DMA has completed, so it doesn't continue to take up space. - */ - i915_vma_unpin(vma); - - return ret; -} - -/** - * intel_guc_init_hw() - finish preparing the GuC for activity - * @guc: intel_guc structure - * - * Called during driver loading and also after a GPU reset. - * - * The main action required here it to load the GuC uCode into the device. - * The firmware image should have already been fetched into memory by the - * earlier call to intel_guc_init(), so here we need only check that - * worked, and then transfer the image to the h/w. - * - * Return: non-zero code on error - */ -int intel_guc_init_hw(struct intel_guc *guc) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - const char *fw_path = guc->fw.path; - int ret; - - DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n", - fw_path, - intel_uc_fw_status_repr(guc->fw.fetch_status), - intel_uc_fw_status_repr(guc->fw.load_status)); - - if (guc->fw.fetch_status != INTEL_UC_FIRMWARE_SUCCESS) - return -EIO; - - guc->fw.load_status = INTEL_UC_FIRMWARE_PENDING; - - DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n", - intel_uc_fw_status_repr(guc->fw.fetch_status), - intel_uc_fw_status_repr(guc->fw.load_status)); - - ret = guc_ucode_xfer(dev_priv); - - if (ret) - return -EAGAIN; - - guc->fw.load_status = INTEL_UC_FIRMWARE_SUCCESS; - - DRM_INFO("GuC %s (firmware %s [version %u.%u])\n", - i915_modparams.enable_guc_submission ? "submission enabled" : - "loaded", - guc->fw.path, - guc->fw.major_ver_found, guc->fw.minor_ver_found); - - return 0; -} - -/** - * intel_guc_select_fw() - selects GuC firmware for loading - * @guc: intel_guc struct - * - * Return: zero when we know firmware, non-zero in other case - */ -int intel_guc_select_fw(struct intel_guc *guc) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - - intel_uc_fw_init(&guc->fw, INTEL_UC_FW_TYPE_GUC); - - if (i915_modparams.guc_firmware_path) { - guc->fw.path = i915_modparams.guc_firmware_path; - guc->fw.major_ver_wanted = 0; - guc->fw.minor_ver_wanted = 0; - } else if (IS_SKYLAKE(dev_priv)) { - guc->fw.path = I915_SKL_GUC_UCODE; - guc->fw.major_ver_wanted = SKL_FW_MAJOR; - guc->fw.minor_ver_wanted = SKL_FW_MINOR; - } else if (IS_BROXTON(dev_priv)) { - guc->fw.path = I915_BXT_GUC_UCODE; - guc->fw.major_ver_wanted = BXT_FW_MAJOR; - guc->fw.minor_ver_wanted = BXT_FW_MINOR; - } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { - guc->fw.path = I915_KBL_GUC_UCODE; - guc->fw.major_ver_wanted = KBL_FW_MAJOR; - guc->fw.minor_ver_wanted = KBL_FW_MINOR; - } else if (IS_GEMINILAKE(dev_priv)) { - guc->fw.path = I915_GLK_GUC_UCODE; - guc->fw.major_ver_wanted = GLK_FW_MAJOR; - guc->fw.minor_ver_wanted = GLK_FW_MINOR; - } else { - DRM_ERROR("No GuC firmware known for platform with GuC!\n"); - return -ENOENT; - } - - return 0; -} diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 53fdd9a76eb0..048f5c42c7b5 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -68,7 +68,7 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv) if (HAS_HUC_UCODE(dev_priv)) intel_huc_select_fw(&dev_priv->huc); - if (intel_guc_select_fw(&dev_priv->guc)) + if (intel_guc_fw_select(&dev_priv->guc)) i915_modparams.enable_guc_loading = 0; } @@ -196,7 +196,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) intel_huc_init_hw(&dev_priv->huc); intel_guc_init_params(guc); - ret = intel_guc_init_hw(&dev_priv->guc); + ret = intel_guc_fw_upload(guc); if (ret == 0 || ret != -EAGAIN) break; -- cgit v1.2.3 From cd5a917e35bc51ebc5fe10cf226ba124b94f2147 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:15 +0000 Subject: drm/i915/guc: Reorder functions in intel_guc_fw.c Functions should be defined in their use order. Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-7-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc_fw.c | 81 +++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc_fw.c b/drivers/gpu/drm/i915/intel_guc_fw.c index 61d6369b10b5..71dacc35a204 100644 --- a/drivers/gpu/drm/i915/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/intel_guc_fw.c @@ -56,6 +56,47 @@ MODULE_FIRMWARE(I915_KBL_GUC_UCODE); #define I915_GLK_GUC_UCODE GUC_FW_PATH(glk, GLK_FW_MAJOR, GLK_FW_MINOR) +/** + * intel_guc_fw_select() - selects GuC firmware for uploading + * + * @guc: intel_guc struct + * + * Return: zero when we know firmware, non-zero in other case + */ +int intel_guc_fw_select(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + + intel_uc_fw_init(&guc->fw, INTEL_UC_FW_TYPE_GUC); + + if (i915_modparams.guc_firmware_path) { + guc->fw.path = i915_modparams.guc_firmware_path; + guc->fw.major_ver_wanted = 0; + guc->fw.minor_ver_wanted = 0; + } else if (IS_SKYLAKE(dev_priv)) { + guc->fw.path = I915_SKL_GUC_UCODE; + guc->fw.major_ver_wanted = SKL_FW_MAJOR; + guc->fw.minor_ver_wanted = SKL_FW_MINOR; + } else if (IS_BROXTON(dev_priv)) { + guc->fw.path = I915_BXT_GUC_UCODE; + guc->fw.major_ver_wanted = BXT_FW_MAJOR; + guc->fw.minor_ver_wanted = BXT_FW_MINOR; + } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { + guc->fw.path = I915_KBL_GUC_UCODE; + guc->fw.major_ver_wanted = KBL_FW_MAJOR; + guc->fw.minor_ver_wanted = KBL_FW_MINOR; + } else if (IS_GEMINILAKE(dev_priv)) { + guc->fw.path = I915_GLK_GUC_UCODE; + guc->fw.major_ver_wanted = GLK_FW_MAJOR; + guc->fw.minor_ver_wanted = GLK_FW_MINOR; + } else { + DRM_ERROR("No GuC firmware known for platform with GuC!\n"); + return -ENOENT; + } + + return 0; +} + /* * Read the GuC status register (GUC_STATUS) and store it in the * specified location; then return a boolean indicating whether @@ -256,43 +297,3 @@ int intel_guc_fw_upload(struct intel_guc *guc) return 0; } - -/** - * intel_guc_fw_select() - selects GuC firmware for loading - * @guc: intel_guc struct - * - * Return: zero when we know firmware, non-zero in other case - */ -int intel_guc_fw_select(struct intel_guc *guc) -{ - struct drm_i915_private *dev_priv = guc_to_i915(guc); - - intel_uc_fw_init(&guc->fw, INTEL_UC_FW_TYPE_GUC); - - if (i915_modparams.guc_firmware_path) { - guc->fw.path = i915_modparams.guc_firmware_path; - guc->fw.major_ver_wanted = 0; - guc->fw.minor_ver_wanted = 0; - } else if (IS_SKYLAKE(dev_priv)) { - guc->fw.path = I915_SKL_GUC_UCODE; - guc->fw.major_ver_wanted = SKL_FW_MAJOR; - guc->fw.minor_ver_wanted = SKL_FW_MINOR; - } else if (IS_BROXTON(dev_priv)) { - guc->fw.path = I915_BXT_GUC_UCODE; - guc->fw.major_ver_wanted = BXT_FW_MAJOR; - guc->fw.minor_ver_wanted = BXT_FW_MINOR; - } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { - guc->fw.path = I915_KBL_GUC_UCODE; - guc->fw.major_ver_wanted = KBL_FW_MAJOR; - guc->fw.minor_ver_wanted = KBL_FW_MINOR; - } else if (IS_GEMINILAKE(dev_priv)) { - guc->fw.path = I915_GLK_GUC_UCODE; - guc->fw.major_ver_wanted = GLK_FW_MAJOR; - guc->fw.minor_ver_wanted = GLK_FW_MINOR; - } else { - DRM_ERROR("No GuC firmware known for platform with GuC!\n"); - return -ENOENT; - } - - return 0; -} -- cgit v1.2.3 From afb3484f925d5e88ac0d4685ffc06b8dc5838bbf Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:16 +0000 Subject: drm/i915/uc: Check all firmwares against WOPCM size Both GuC and HuC firmwares will be moved into WOPCM so we can check ucode size early for both cases. Suggested-by: Joonas Lahtinen Signed-off-by: Michal Wajdeczko Cc: Sagar Arun Kamble Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Joonas Lahtinen Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-8-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uc_fw.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c index 766b1cbdfbd7..40f5ce482792 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/intel_uc_fw.c @@ -85,6 +85,15 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size; uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32); + /* Header and uCode will be loaded to WOPCM */ + size = uc_fw->header_size + uc_fw->ucode_size; + if (size > intel_guc_wopcm_size(dev_priv)) { + DRM_WARN("%s: Firmware is too large to fit in WOPCM\n", + intel_uc_fw_type_repr(uc_fw->type)); + err = -E2BIG; + goto fail; + } + /* now RSA */ if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) { DRM_NOTE("RSA key size is bad\n"); @@ -108,14 +117,6 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, */ switch (uc_fw->type) { case INTEL_UC_FW_TYPE_GUC: - /* Header and uCode will be loaded to WOPCM. Size of the two. */ - size = uc_fw->header_size + uc_fw->ucode_size; - - /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */ - if (size > intel_guc_wopcm_size(dev_priv)) { - DRM_ERROR("Firmware is too large to fit in WOPCM\n"); - goto fail; - } uc_fw->major_ver_found = css->guc.sw_version >> 16; uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF; break; -- cgit v1.2.3 From 86ffc31211cbad56bc4e06441801a37b380b3779 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:17 +0000 Subject: drm/i915/guc: Pick better place for Guc final status message GuC status message printed right after firmware upload may be too optimistic, as we may fail on subsequent steps. Move that message to the end of intel_uc_init_hw where we know the status for sure. v2: use dev_info (Chris) Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-9-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc_fw.c | 6 ------ drivers/gpu/drm/i915/intel_uc.c | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc_fw.c b/drivers/gpu/drm/i915/intel_guc_fw.c index 71dacc35a204..4cb8c1cc6597 100644 --- a/drivers/gpu/drm/i915/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/intel_guc_fw.c @@ -289,11 +289,5 @@ int intel_guc_fw_upload(struct intel_guc *guc) guc->fw.load_status = INTEL_UC_FIRMWARE_SUCCESS; - DRM_INFO("GuC %s (firmware %s [version %u.%u])\n", - i915_modparams.enable_guc_submission ? "submission enabled" : - "loaded", - guc->fw.path, - guc->fw.major_ver_found, guc->fw.minor_ver_found); - return 0; } diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 048f5c42c7b5..9d84fdd08302 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -222,6 +222,12 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) goto err_interrupts; } + dev_info(dev_priv->drm.dev, "GuC %s (firmware %s [version %u.%u])\n", + i915_modparams.enable_guc_submission ? "submission enabled" : + "loaded", + guc->fw.path, + guc->fw.major_ver_found, guc->fw.minor_ver_found); + return 0; /* -- cgit v1.2.3 From 5f99afdbf186733bf1a0fa55534e7e8e25e961db Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:18 +0000 Subject: drm/i915/uc: Improve debug messages in firmware fetch Time to remove less important info and make messages clear and consistent. v2: change some message levels (Chris) v3: restore DRM_WARN (Chris) Signed-off-by: Michal Wajdeczko Cc: Sagar Arun Kamble Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson #2 Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-10-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uc_fw.c | 75 +++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c index 40f5ce482792..8a06781c2496 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/intel_uc_fw.c @@ -45,26 +45,33 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, size_t size; int err; + DRM_DEBUG_DRIVER("%s fw fetch %s\n", + intel_uc_fw_type_repr(uc_fw->type), uc_fw->path); + if (!uc_fw->path) return; uc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING; - - DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n", + DRM_DEBUG_DRIVER("%s fw fetch %s\n", + intel_uc_fw_type_repr(uc_fw->type), intel_uc_fw_status_repr(uc_fw->fetch_status)); err = request_firmware(&fw, uc_fw->path, &pdev->dev); - if (err) - goto fail; - if (!fw) + if (err) { + DRM_DEBUG_DRIVER("%s fw request_firmware err=%d\n", + intel_uc_fw_type_repr(uc_fw->type), err); goto fail; + } - DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n", - uc_fw->path, fw); + DRM_DEBUG_DRIVER("%s fw size %zu ptr %p\n", + intel_uc_fw_type_repr(uc_fw->type), fw->size, fw); /* Check the size of the blob before examining buffer contents */ if (fw->size < sizeof(struct uc_css_header)) { - DRM_NOTE("Firmware header is missing\n"); + DRM_WARN("%s: Unexpected firmware size (%zu, min %zu)\n", + intel_uc_fw_type_repr(uc_fw->type), + fw->size, sizeof(struct uc_css_header)); + err = -ENODATA; goto fail; } @@ -77,7 +84,9 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, sizeof(u32); if (uc_fw->header_size != sizeof(struct uc_css_header)) { - DRM_NOTE("CSS header definition mismatch\n"); + DRM_WARN("%s: Mismatched firmware header definition\n", + intel_uc_fw_type_repr(uc_fw->type)); + err = -ENOEXEC; goto fail; } @@ -96,7 +105,9 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, /* now RSA */ if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) { - DRM_NOTE("RSA key size is bad\n"); + DRM_WARN("%s: Mismatched firmware RSA key size (%u)\n", + intel_uc_fw_type_repr(uc_fw->type), css->key_size_dw); + err = -ENOEXEC; goto fail; } uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size; @@ -105,7 +116,9 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, /* At least, it should have header, uCode and RSA. Size of all three. */ size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size; if (fw->size < size) { - DRM_NOTE("Missing firmware components\n"); + DRM_WARN("%s: Truncated firmware (%zu, expected %zu)\n", + intel_uc_fw_type_repr(uc_fw->type), fw->size, size); + err = -ENOEXEC; goto fail; } @@ -127,17 +140,21 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, break; default: - DRM_ERROR("Unknown firmware type %d\n", uc_fw->type); - err = -ENOEXEC; - goto fail; + MISSING_CASE(uc_fw->type); + break; } + DRM_DEBUG_DRIVER("%s fw version %u.%u (wanted %u.%u)\n", + intel_uc_fw_type_repr(uc_fw->type), + uc_fw->major_ver_found, uc_fw->minor_ver_found, + uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted); + if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0) { - DRM_NOTE("Skipping %s firmware version check\n", + DRM_NOTE("%s: Skipping firmware version check\n", intel_uc_fw_type_repr(uc_fw->type)); } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted || uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) { - DRM_NOTE("%s firmware version %d.%d, required %d.%d\n", + DRM_NOTE("%s: Wrong firmware version (%u.%u, required %u.%u)\n", intel_uc_fw_type_repr(uc_fw->type), uc_fw->major_ver_found, uc_fw->minor_ver_found, uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted); @@ -145,34 +162,34 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, goto fail; } - DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n", - uc_fw->major_ver_found, uc_fw->minor_ver_found, - uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted); - obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size); if (IS_ERR(obj)) { err = PTR_ERR(obj); + DRM_DEBUG_DRIVER("%s fw object_create err=%d\n", + intel_uc_fw_type_repr(uc_fw->type), err); goto fail; } uc_fw->obj = obj; uc_fw->size = fw->size; - - DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n", - uc_fw->obj); + uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS; + DRM_DEBUG_DRIVER("%s fw fetch %s\n", + intel_uc_fw_type_repr(uc_fw->type), + intel_uc_fw_status_repr(uc_fw->fetch_status)); release_firmware(fw); - uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS; return; fail: - DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n", - uc_fw->path, err); - DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n", - err, fw, uc_fw->obj); + uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL; + DRM_DEBUG_DRIVER("%s fw fetch %s\n", + intel_uc_fw_type_repr(uc_fw->type), + intel_uc_fw_status_repr(uc_fw->fetch_status)); + + DRM_WARN("%s: Failed to fetch firmware %s (error %d)\n", + intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err); release_firmware(fw); /* OK even if fw is NULL */ - uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL; } /** -- cgit v1.2.3 From 1e913d27cef4760e247951253bf207333d418268 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:19 +0000 Subject: drm/i915/uc: Add message with firmware url In case of firmware fetch failure we should help user find latest firmware. URL macro duplication from csr.c will be fixed in upcoming patch. Suggested-by: Chris Wilson Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-11-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uc_fw.c | 2 ++ drivers/gpu/drm/i915/intel_uc_fw.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c index 8a06781c2496..1bb031925239 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/intel_uc_fw.c @@ -188,6 +188,8 @@ fail: DRM_WARN("%s: Failed to fetch firmware %s (error %d)\n", intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err); + DRM_INFO("%s: Firmware can be downloaded from %s\n", + intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL); release_firmware(fw); /* OK even if fw is NULL */ } diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index 5c018492ccdc..1d580faedadc 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -27,6 +27,8 @@ struct drm_i915_private; +#define INTEL_UC_FIRMWARE_URL "https://01.org/linuxgraphics/downloads/firmware" + enum intel_uc_fw_status { INTEL_UC_FIRMWARE_FAIL = -1, INTEL_UC_FIRMWARE_NONE = 0, -- cgit v1.2.3 From f1e86cecf1d1ae9b933d3f69cc24632556d5eb8c Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:20 +0000 Subject: drm/i915: Update DMC firmware load error messages Some of the error messages from DMC load were too generic and may be confusing for the user. Lets explicitly add DMC words there. Also as homepage of DMC firmware is same as for the GuC and Huc, lets reuse URL definition. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Imre Deak Cc: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-12-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_csr.c | 31 ++++++++++++++++--------------- drivers/gpu/drm/i915/intel_uc_fw.h | 1 + 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index ea5d5c9645a4..da9de47562b8 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -52,10 +52,6 @@ MODULE_FIRMWARE(I915_CSR_SKL); MODULE_FIRMWARE(I915_CSR_BXT); #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) -#define FIRMWARE_URL "https://01.org/linuxgraphics/downloads/firmware" - - - #define CSR_MAX_FW_SIZE 0x2FFF #define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF @@ -291,7 +287,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, css_header = (struct intel_css_header *)fw->data; if (sizeof(struct intel_css_header) != (css_header->header_len * 4)) { - DRM_ERROR("Firmware has wrong CSS header length %u bytes\n", + DRM_ERROR("DMC firmware has wrong CSS header length " + "(%u bytes)\n", (css_header->header_len * 4)); return NULL; } @@ -315,7 +312,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, if (csr->version != required_version) { DRM_INFO("Refusing to load DMC firmware v%u.%u," - " please use v%u.%u [" FIRMWARE_URL "].\n", + " please use v%u.%u\n", CSR_VERSION_MAJOR(csr->version), CSR_VERSION_MINOR(csr->version), CSR_VERSION_MAJOR(required_version), @@ -330,7 +327,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, &fw->data[readcount]; if (sizeof(struct intel_package_header) != (package_header->header_len * 4)) { - DRM_ERROR("Firmware has wrong package header length %u bytes\n", + DRM_ERROR("DMC firmware has wrong package header length " + "(%u bytes)\n", (package_header->header_len * 4)); return NULL; } @@ -351,7 +349,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, dmc_offset = package_header->fw_info[i].offset; } if (dmc_offset == CSR_DEFAULT_FW_OFFSET) { - DRM_ERROR("Firmware not supported for %c stepping\n", + DRM_ERROR("DMC firmware not supported for %c stepping\n", si->stepping); return NULL; } @@ -360,7 +358,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, /* Extract dmc_header information. */ dmc_header = (struct intel_dmc_header *)&fw->data[readcount]; if (sizeof(struct intel_dmc_header) != (dmc_header->header_len)) { - DRM_ERROR("Firmware has wrong dmc header length %u bytes\n", + DRM_ERROR("DMC firmware has wrong dmc header length " + "(%u bytes)\n", (dmc_header->header_len)); return NULL; } @@ -368,7 +367,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, /* Cache the dmc header info. */ if (dmc_header->mmio_count > ARRAY_SIZE(csr->mmioaddr)) { - DRM_ERROR("Firmware has wrong mmio count %u\n", + DRM_ERROR("DMC firmware has wrong mmio count %u\n", dmc_header->mmio_count); return NULL; } @@ -376,7 +375,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, for (i = 0; i < dmc_header->mmio_count; i++) { if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE || dmc_header->mmioaddr[i] > CSR_MMIO_END_RANGE) { - DRM_ERROR(" Firmware has wrong mmio address 0x%x\n", + DRM_ERROR("DMC firmware has wrong mmio address 0x%x\n", dmc_header->mmioaddr[i]); return NULL; } @@ -387,7 +386,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */ nbytes = dmc_header->fw_size * 4; if (nbytes > CSR_MAX_FW_SIZE) { - DRM_ERROR("CSR firmware too big (%u) bytes\n", nbytes); + DRM_ERROR("DMC firmware too big (%u bytes)\n", nbytes); return NULL; } csr->dmc_fw_size = dmc_header->fw_size; @@ -425,9 +424,11 @@ static void csr_load_work_fn(struct work_struct *work) CSR_VERSION_MINOR(csr->version)); } else { dev_notice(dev_priv->drm.dev, - "Failed to load DMC firmware" - " [" FIRMWARE_URL "]," - " disabling runtime power management.\n"); + "Failed to load DMC firmware %s." + " Disabling runtime power management.\n", + csr->fw_path); + dev_notice(dev_priv->drm.dev, "DMC firmware homepage: %s", + INTEL_UC_FIRMWARE_URL); } release_firmware(fw); diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index 1d580faedadc..849c3c0c007d 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -27,6 +27,7 @@ struct drm_i915_private; +/* Home of GuC, HuC and DMC firmwares */ #define INTEL_UC_FIRMWARE_URL "https://01.org/linuxgraphics/downloads/firmware" enum intel_uc_fw_status { -- cgit v1.2.3 From 4502e9ec820d763750e54c11683d37b992358d6e Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:21 +0000 Subject: drm/i915/uc: Unify firmware loading Firmware loading for GuC and HuC are similar. Move common code into generic function for maximum reuse. v2: change message levels (Chris) Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Cc: Anusha Srivatsa Cc: Sujaritha Sundaresan Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-13-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_guc_fw.c | 52 +++--------------------- drivers/gpu/drm/i915/intel_huc.c | 53 +++---------------------- drivers/gpu/drm/i915/intel_uc_fw.c | 79 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uc_fw.h | 4 ++ 4 files changed, 93 insertions(+), 95 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_guc_fw.c b/drivers/gpu/drm/i915/intel_guc_fw.c index 4cb8c1cc6597..ef67a36354c5 100644 --- a/drivers/gpu/drm/i915/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/intel_guc_fw.c @@ -188,24 +188,13 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv, /* * Load the GuC firmware blob into the MinuteIA. */ -static int guc_ucode_xfer(struct drm_i915_private *dev_priv) +static int guc_ucode_xfer(struct intel_uc_fw *guc_fw, struct i915_vma *vma) { - struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; - struct i915_vma *vma; + struct intel_guc *guc = container_of(guc_fw, struct intel_guc, fw); + struct drm_i915_private *dev_priv = guc_to_i915(guc); int ret; - ret = i915_gem_object_set_to_gtt_domain(guc_fw->obj, false); - if (ret) { - DRM_DEBUG_DRIVER("set-domain failed %d\n", ret); - return ret; - } - - vma = i915_gem_object_ggtt_pin(guc_fw->obj, NULL, 0, 0, - PIN_OFFSET_BIAS | GUC_WOPCM_TOP); - if (IS_ERR(vma)) { - DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma)); - return PTR_ERR(vma); - } + GEM_BUG_ON(guc_fw->type != INTEL_UC_FW_TYPE_GUC); intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); @@ -240,12 +229,6 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); - /* - * We keep the object pages for reuse during resume. But we can unpin it - * now that DMA has completed, so it doesn't continue to take up space. - */ - i915_vma_unpin(vma); - return ret; } @@ -264,30 +247,5 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv) */ int intel_guc_fw_upload(struct intel_guc *guc) { - struct drm_i915_private *dev_priv = guc_to_i915(guc); - const char *fw_path = guc->fw.path; - int ret; - - DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n", - fw_path, - intel_uc_fw_status_repr(guc->fw.fetch_status), - intel_uc_fw_status_repr(guc->fw.load_status)); - - if (guc->fw.fetch_status != INTEL_UC_FIRMWARE_SUCCESS) - return -EIO; - - guc->fw.load_status = INTEL_UC_FIRMWARE_PENDING; - - DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n", - intel_uc_fw_status_repr(guc->fw.fetch_status), - intel_uc_fw_status_repr(guc->fw.load_status)); - - ret = guc_ucode_xfer(dev_priv); - - if (ret) - return -EAGAIN; - - guc->fw.load_status = INTEL_UC_FIRMWARE_SUCCESS; - - return 0; + return intel_uc_fw_upload(&guc->fw, guc_ucode_xfer); } diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index 4b4cf56d29ad..8be3bfeb58dd 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c @@ -85,26 +85,15 @@ MODULE_FIRMWARE(I915_KBL_HUC_UCODE); * * Return: 0 on success, non-zero on failure */ -static int huc_ucode_xfer(struct drm_i915_private *dev_priv) +static int huc_ucode_xfer(struct intel_uc_fw *huc_fw, struct i915_vma *vma) { - struct intel_uc_fw *huc_fw = &dev_priv->huc.fw; - struct i915_vma *vma; + struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw); + struct drm_i915_private *dev_priv = huc_to_i915(huc); unsigned long offset = 0; u32 size; int ret; - ret = i915_gem_object_set_to_gtt_domain(huc_fw->obj, false); - if (ret) { - DRM_DEBUG_DRIVER("set-domain failed %d\n", ret); - return ret; - } - - vma = i915_gem_object_ggtt_pin(huc_fw->obj, NULL, 0, 0, - PIN_OFFSET_BIAS | GUC_WOPCM_TOP); - if (IS_ERR(vma)) { - DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma)); - return PTR_ERR(vma); - } + GEM_BUG_ON(huc_fw->type != INTEL_UC_FW_TYPE_HUC); intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); @@ -135,12 +124,6 @@ static int huc_ucode_xfer(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); - /* - * We keep the object pages for reuse during resume. But we can unpin it - * now that DMA has completed, so it doesn't continue to take up space. - */ - i915_vma_unpin(vma); - return ret; } @@ -194,33 +177,7 @@ void intel_huc_select_fw(struct intel_huc *huc) */ void intel_huc_init_hw(struct intel_huc *huc) { - struct drm_i915_private *dev_priv = huc_to_i915(huc); - int err; - - DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n", - huc->fw.path, - intel_uc_fw_status_repr(huc->fw.fetch_status), - intel_uc_fw_status_repr(huc->fw.load_status)); - - if (huc->fw.fetch_status != INTEL_UC_FIRMWARE_SUCCESS) - return; - - huc->fw.load_status = INTEL_UC_FIRMWARE_PENDING; - - err = huc_ucode_xfer(dev_priv); - - huc->fw.load_status = err ? - INTEL_UC_FIRMWARE_FAIL : INTEL_UC_FIRMWARE_SUCCESS; - - DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n", - huc->fw.path, - intel_uc_fw_status_repr(huc->fw.fetch_status), - intel_uc_fw_status_repr(huc->fw.load_status)); - - if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) - DRM_ERROR("Failed to complete HuC uCode load with ret %d\n", err); - - return; + intel_uc_fw_upload(&huc->fw, huc_ucode_xfer); } /** diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c index 1bb031925239..7bb0109bfbbd 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/intel_uc_fw.c @@ -194,6 +194,85 @@ fail: release_firmware(fw); /* OK even if fw is NULL */ } +/** + * intel_uc_fw_upload - load uC firmware using custom loader + * + * @uc_fw: uC firmware + * @loader: custom uC firmware loader function + * + * Loads uC firmware using custom loader and updates internal flags. + */ +int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, + int (*xfer)(struct intel_uc_fw *uc_fw, + struct i915_vma *vma)) +{ + struct i915_vma *vma; + int err; + + DRM_DEBUG_DRIVER("%s fw load %s\n", + intel_uc_fw_type_repr(uc_fw->type), uc_fw->path); + + if (uc_fw->fetch_status != INTEL_UC_FIRMWARE_SUCCESS) + return -EIO; + + uc_fw->load_status = INTEL_UC_FIRMWARE_PENDING; + DRM_DEBUG_DRIVER("%s fw load %s\n", + intel_uc_fw_type_repr(uc_fw->type), + intel_uc_fw_status_repr(uc_fw->load_status)); + + /* Pin object with firmware */ + err = i915_gem_object_set_to_gtt_domain(uc_fw->obj, false); + if (err) { + DRM_DEBUG_DRIVER("%s fw set-domain err=%d\n", + intel_uc_fw_type_repr(uc_fw->type), err); + goto fail; + } + + vma = i915_gem_object_ggtt_pin(uc_fw->obj, NULL, 0, 0, + PIN_OFFSET_BIAS | GUC_WOPCM_TOP); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + DRM_DEBUG_DRIVER("%s fw ggtt-pin err=%d\n", + intel_uc_fw_type_repr(uc_fw->type), err); + goto fail; + } + + /* Call custom loader */ + err = xfer(uc_fw, vma); + + /* + * We keep the object pages for reuse during resume. But we can unpin it + * now that DMA has completed, so it doesn't continue to take up space. + */ + i915_vma_unpin(vma); + + if (err) + goto fail; + + uc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS; + DRM_DEBUG_DRIVER("%s fw load %s\n", + intel_uc_fw_type_repr(uc_fw->type), + intel_uc_fw_status_repr(uc_fw->load_status)); + + DRM_INFO("%s: Loaded firmware %s (version %u.%u)\n", + intel_uc_fw_type_repr(uc_fw->type), + uc_fw->path, + uc_fw->major_ver_found, uc_fw->minor_ver_found); + + return 0; + +fail: + uc_fw->load_status = INTEL_UC_FIRMWARE_FAIL; + DRM_DEBUG_DRIVER("%s fw load %s\n", + intel_uc_fw_type_repr(uc_fw->type), + intel_uc_fw_status_repr(uc_fw->load_status)); + + DRM_WARN("%s: Failed to load firmware %s (error %d)\n", + intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err); + + return err; +} + /** * intel_uc_fw_fini - cleanup uC firmware * diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index 849c3c0c007d..412fbdc4db93 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -26,6 +26,7 @@ #define _INTEL_UC_FW_H_ struct drm_i915_private; +struct i915_vma; /* Home of GuC, HuC and DMC firmwares */ #define INTEL_UC_FIRMWARE_URL "https://01.org/linuxgraphics/downloads/firmware" @@ -110,6 +111,9 @@ void intel_uc_fw_init(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type) void intel_uc_fw_fetch(struct drm_i915_private *dev_priv, struct intel_uc_fw *uc_fw); +int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, + int (*xfer)(struct intel_uc_fw *uc_fw, + struct i915_vma *vma)); void intel_uc_fw_fini(struct intel_uc_fw *uc_fw); #endif -- cgit v1.2.3 From 9f65208f250422c943ca49e0f45e9f15b8cdcdac Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:22 +0000 Subject: drm/i915/guc: Update Guc messages on load failure In case of GuC firmware loading failure we were reporting DRM_ERROR also for case when GuC loading was not strictly required. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-14-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_uc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 9d84fdd08302..25bd162f38d2 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -250,12 +250,14 @@ err_submission: err_guc: i915_ggtt_disable_guc(dev_priv); - DRM_ERROR("GuC init failed\n"); if (i915_modparams.enable_guc_loading > 1 || - i915_modparams.enable_guc_submission > 1) + i915_modparams.enable_guc_submission > 1) { + DRM_ERROR("GuC init failed. Firmware loading disabled.\n"); ret = -EIO; - else + } else { + DRM_NOTE("GuC init failed. Firmware loading disabled.\n"); ret = 0; + } if (i915_modparams.enable_guc_submission) { i915_modparams.enable_guc_submission = 0; @@ -263,7 +265,6 @@ err_guc: } i915_modparams.enable_guc_loading = 0; - DRM_NOTE("GuC firmware loading disabled\n"); return ret; } -- cgit v1.2.3 From 543d5e0ea181a3f92cbe19832bcf2e0ea26bfc22 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Mon, 16 Oct 2017 14:47:23 +0000 Subject: drm/i915/huc: Move fw select function No functional change. Just place the function closer to related definitions. Signed-off-by: Michal Wajdeczko Cc: Joonas Lahtinen Cc: Sagar Arun Kamble Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-15-michal.wajdeczko@intel.com --- drivers/gpu/drm/i915/intel_huc.c | 72 ++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index 8be3bfeb58dd..c8a48cbc2b7d 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c @@ -77,6 +77,42 @@ MODULE_FIRMWARE(I915_KBL_HUC_UCODE); #define I915_GLK_HUC_UCODE HUC_FW_PATH(glk, GLK_HUC_FW_MAJOR, \ GLK_HUC_FW_MINOR, GLK_BLD_NUM) +/** + * intel_huc_select_fw() - selects HuC firmware for loading + * @huc: intel_huc struct + */ +void intel_huc_select_fw(struct intel_huc *huc) +{ + struct drm_i915_private *dev_priv = huc_to_i915(huc); + + intel_uc_fw_init(&huc->fw, INTEL_UC_FW_TYPE_HUC); + + if (i915_modparams.huc_firmware_path) { + huc->fw.path = i915_modparams.huc_firmware_path; + huc->fw.major_ver_wanted = 0; + huc->fw.minor_ver_wanted = 0; + } else if (IS_SKYLAKE(dev_priv)) { + huc->fw.path = I915_SKL_HUC_UCODE; + huc->fw.major_ver_wanted = SKL_HUC_FW_MAJOR; + huc->fw.minor_ver_wanted = SKL_HUC_FW_MINOR; + } else if (IS_BROXTON(dev_priv)) { + huc->fw.path = I915_BXT_HUC_UCODE; + huc->fw.major_ver_wanted = BXT_HUC_FW_MAJOR; + huc->fw.minor_ver_wanted = BXT_HUC_FW_MINOR; + } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { + huc->fw.path = I915_KBL_HUC_UCODE; + huc->fw.major_ver_wanted = KBL_HUC_FW_MAJOR; + huc->fw.minor_ver_wanted = KBL_HUC_FW_MINOR; + } else if (IS_GEMINILAKE(dev_priv)) { + huc->fw.path = I915_GLK_HUC_UCODE; + huc->fw.major_ver_wanted = GLK_HUC_FW_MAJOR; + huc->fw.minor_ver_wanted = GLK_HUC_FW_MINOR; + } else { + DRM_ERROR("No HuC firmware known for platform with HuC!\n"); + return; + } +} + /** * huc_ucode_xfer() - DMA's the firmware * @dev_priv: the drm_i915_private device @@ -127,42 +163,6 @@ static int huc_ucode_xfer(struct intel_uc_fw *huc_fw, struct i915_vma *vma) return ret; } -/** - * intel_huc_select_fw() - selects HuC firmware for loading - * @huc: intel_huc struct - */ -void intel_huc_select_fw(struct intel_huc *huc) -{ - struct drm_i915_private *dev_priv = huc_to_i915(huc); - - intel_uc_fw_init(&huc->fw, INTEL_UC_FW_TYPE_HUC); - - if (i915_modparams.huc_firmware_path) { - huc->fw.path = i915_modparams.huc_firmware_path; - huc->fw.major_ver_wanted = 0; - huc->fw.minor_ver_wanted = 0; - } else if (IS_SKYLAKE(dev_priv)) { - huc->fw.path = I915_SKL_HUC_UCODE; - huc->fw.major_ver_wanted = SKL_HUC_FW_MAJOR; - huc->fw.minor_ver_wanted = SKL_HUC_FW_MINOR; - } else if (IS_BROXTON(dev_priv)) { - huc->fw.path = I915_BXT_HUC_UCODE; - huc->fw.major_ver_wanted = BXT_HUC_FW_MAJOR; - huc->fw.minor_ver_wanted = BXT_HUC_FW_MINOR; - } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { - huc->fw.path = I915_KBL_HUC_UCODE; - huc->fw.major_ver_wanted = KBL_HUC_FW_MAJOR; - huc->fw.minor_ver_wanted = KBL_HUC_FW_MINOR; - } else if (IS_GEMINILAKE(dev_priv)) { - huc->fw.path = I915_GLK_HUC_UCODE; - huc->fw.major_ver_wanted = GLK_HUC_FW_MAJOR; - huc->fw.minor_ver_wanted = GLK_HUC_FW_MINOR; - } else { - DRM_ERROR("No HuC firmware known for platform with HuC!\n"); - return; - } -} - /** * intel_huc_init_hw() - load HuC uCode to device * @huc: intel_huc structure -- cgit v1.2.3 From ba3ee00683bc2dad4c14fba805c2241ae23acff9 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Fri, 22 Sep 2017 10:00:09 +0800 Subject: drm/i915/gvt: Fix GPU hang after reusing vGPU instance across different guest OS We have implemented delayed ring mmio switch mechanism to reduce unnecessary mmio switch. While the vGPU is being destroyed or detached from VM, we need to force the ring switch to host context. The later deadline is missed. Then it got a chance that word load from VM2 might execute under the ring context of VM1 which was attached to a same vGPU instance. Finally, the GPU is hang. This patch guarantee the two deadline are performed. v2: Remove unused variable 'scheduler' Signed-off-by: Changbin Du Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/sched_policy.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c index 436377da41ba..03532dfc0cd5 100644 --- a/drivers/gpu/drm/i915/gvt/sched_policy.c +++ b/drivers/gpu/drm/i915/gvt/sched_policy.c @@ -308,20 +308,8 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu) static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu) { - struct intel_gvt_workload_scheduler *scheduler = &vgpu->gvt->scheduler; - int ring_id; - kfree(vgpu->sched_data); vgpu->sched_data = NULL; - - spin_lock_bh(&scheduler->mmio_context_lock); - for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) { - if (scheduler->engine_owner[ring_id] == vgpu) { - intel_gvt_switch_mmio(vgpu, NULL, ring_id); - scheduler->engine_owner[ring_id] = NULL; - } - } - spin_unlock_bh(&scheduler->mmio_context_lock); } static void tbs_sched_start_schedule(struct intel_vgpu *vgpu) @@ -388,6 +376,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) { struct intel_gvt_workload_scheduler *scheduler = &vgpu->gvt->scheduler; + int ring_id; gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id); @@ -401,4 +390,13 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) scheduler->need_reschedule = true; scheduler->current_vgpu = NULL; } + + spin_lock_bh(&scheduler->mmio_context_lock); + for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) { + if (scheduler->engine_owner[ring_id] == vgpu) { + intel_gvt_switch_mmio(vgpu, NULL, ring_id); + scheduler->engine_owner[ring_id] = NULL; + } + } + spin_unlock_bh(&scheduler->mmio_context_lock); } -- cgit v1.2.3 From e4ffc83d3fa7e51390a94303e06356d2d1d5b5ee Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 22 Aug 2017 16:58:28 -0700 Subject: drm/i915/cnl: WaRsUseTimeoutMode Apparently RC6 residency is lower than expected with EI mode for most of the cases on CNL A0, B0 and C0. This Wa doesn't solve our lower residency, but I believe it is better to have it since EI is not expected to work by HW engineers anyways. Cc: David Weinehall Cc: Mika Kuoppala Signed-off-by: Rodrigo Vivi Reviewed-by: David Weinehall Link: https://patchwork.freedesktop.org/patch/msgid/20170822235828.18322-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c7b2ca6aff05..d61936106e36 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3077,6 +3077,7 @@ intel_info(const struct drm_i915_private *dev_priv) #define CNL_REVID_A0 0x0 #define CNL_REVID_B0 0x1 +#define CNL_REVID_C0 0x2 #define IS_CNL_REVID(p, since, until) \ (IS_CANNONLAKE(p) && IS_REVID(p, since, until)) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2fcff9788b6f..ac4cf98030f9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6591,7 +6591,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; enum intel_engine_id id; - uint32_t rc6_mask = 0; + u32 rc6_mode, rc6_mask = 0; /* 1a: Software RC state - RC0 */ I915_WRITE(GEN6_RC_STATE, 0); @@ -6629,8 +6629,15 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv) rc6_mask = GEN6_RC_CTL_RC6_ENABLE; DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE)); I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ + + /* WaRsUseTimeoutMode:cnl (pre-prod) */ + if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_C0)) + rc6_mode = GEN7_RC_CTL_TO_MODE; + else + rc6_mode = GEN6_RC_CTL_EI_MODE(1); + I915_WRITE(GEN6_RC_CONTROL, - GEN6_RC_CTL_HW_ENABLE | GEN6_RC_CTL_EI_MODE(1) | rc6_mask); + GEN6_RC_CTL_HW_ENABLE | rc6_mode | rc6_mask); /* * 3b: Enable Coarse Power Gating only when RC6 is enabled. -- cgit v1.2.3 From f1fa4f442c82eb875babb88399a6b69efce7b453 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:13 +0100 Subject: drm/i915: Refactor testing obj->mm.pages Since we occasionally stuff an error pointer into obj->mm.pages for a semi-permanent or even permanent failure, we have to be more careful and not just test against NULL when deciding if the object has a complete set of its concurrent pages. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 10 ++++++++-- drivers/gpu/drm/i915/i915_gem.c | 19 ++++++++++--------- drivers/gpu/drm/i915/i915_gem_clflush.c | 1 + drivers/gpu/drm/i915/i915_gem_render_state.c | 2 +- drivers/gpu/drm/i915/i915_gem_shrinker.c | 10 +++++----- drivers/gpu/drm/i915/i915_gem_tiling.c | 2 +- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 7 files changed, 27 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d61936106e36..a9bc979e0cbd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3566,10 +3566,16 @@ i915_gem_object_pin_pages(struct drm_i915_gem_object *obj) return __i915_gem_object_get_pages(obj); } +static inline bool +i915_gem_object_has_pages(struct drm_i915_gem_object *obj) +{ + return !IS_ERR_OR_NULL(READ_ONCE(obj->mm.pages)); +} + static inline void __i915_gem_object_pin_pages(struct drm_i915_gem_object *obj) { - GEM_BUG_ON(!obj->mm.pages); + GEM_BUG_ON(!i915_gem_object_has_pages(obj)); atomic_inc(&obj->mm.pages_pin_count); } @@ -3583,8 +3589,8 @@ i915_gem_object_has_pinned_pages(struct drm_i915_gem_object *obj) static inline void __i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) { + GEM_BUG_ON(!i915_gem_object_has_pages(obj)); GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); - GEM_BUG_ON(!obj->mm.pages); atomic_dec(&obj->mm.pages_pin_count); } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d9d39b309ce8..059071715053 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2196,7 +2196,7 @@ void __i915_gem_object_invalidate(struct drm_i915_gem_object *obj) struct address_space *mapping; lockdep_assert_held(&obj->mm.lock); - GEM_BUG_ON(obj->mm.pages); + GEM_BUG_ON(i915_gem_object_has_pages(obj)); switch (obj->mm.madv) { case I915_MADV_DONTNEED: @@ -2259,7 +2259,7 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, return; GEM_BUG_ON(obj->bind_count); - if (!READ_ONCE(obj->mm.pages)) + if (!i915_gem_object_has_pages(obj)) return; /* May be called by shrinker from within get_pages() (on another bo) */ @@ -2563,7 +2563,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj) if (err) return err; - if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) { + if (unlikely(!i915_gem_object_has_pages(obj))) { GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj)); err = ____i915_gem_object_get_pages(obj); @@ -2648,7 +2648,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, type &= ~I915_MAP_OVERRIDE; if (!atomic_inc_not_zero(&obj->mm.pages_pin_count)) { - if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) { + if (unlikely(!i915_gem_object_has_pages(obj))) { GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj)); ret = ____i915_gem_object_get_pages(obj); @@ -2660,7 +2660,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, atomic_inc(&obj->mm.pages_pin_count); pinned = false; } - GEM_BUG_ON(!obj->mm.pages); + GEM_BUG_ON(!i915_gem_object_has_pages(obj)); ptr = page_unpack_bits(obj->mm.mapping, &has_type); if (ptr && has_type != type) { @@ -2715,7 +2715,7 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, * allows it to avoid the cost of retrieving a page (either swapin * or clearing-before-use) before it is overwritten. */ - if (READ_ONCE(obj->mm.pages)) + if (i915_gem_object_has_pages(obj)) return -ENODEV; /* Before the pages are instantiated the object is treated as being @@ -4278,7 +4278,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, if (err) goto out; - if (obj->mm.pages && + if (i915_gem_object_has_pages(obj) && i915_gem_object_is_tiled(obj) && dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) { if (obj->mm.madv == I915_MADV_WILLNEED) { @@ -4297,7 +4297,8 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, obj->mm.madv = args->madv; /* if the object is no longer attached, discard its backing storage */ - if (obj->mm.madv == I915_MADV_DONTNEED && !obj->mm.pages) + if (obj->mm.madv == I915_MADV_DONTNEED && + !i915_gem_object_has_pages(obj)) i915_gem_object_truncate(obj); args->retained = obj->mm.madv != __I915_MADV_PURGED; @@ -4514,7 +4515,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, if (WARN_ON(i915_gem_object_has_pinned_pages(obj))) atomic_set(&obj->mm.pages_pin_count, 0); __i915_gem_object_put_pages(obj, I915_MM_NORMAL); - GEM_BUG_ON(obj->mm.pages); + GEM_BUG_ON(i915_gem_object_has_pages(obj)); if (obj->base.import_attach) drm_prime_gem_destroy(&obj->base, NULL); diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.c b/drivers/gpu/drm/i915/i915_gem_clflush.c index 8a04d33055be..f663cd919795 100644 --- a/drivers/gpu/drm/i915/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/i915_gem_clflush.c @@ -70,6 +70,7 @@ static const struct dma_fence_ops i915_clflush_ops = { static void __i915_do_clflush(struct drm_i915_gem_object *obj) { + GEM_BUG_ON(!i915_gem_object_has_pages(obj)); drm_clflush_sg(obj->mm.pages); intel_fb_obj_flush(obj, ORIGIN_CPU); } diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index 4dd4c2159a92..3703dc91eeda 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -229,7 +229,7 @@ int i915_gem_render_state_emit(struct drm_i915_gem_request *req) return 0; /* Recreate the page after shrinking */ - if (!so->vma->obj->mm.pages) + if (!i915_gem_object_has_pages(so->vma->obj)) so->batch_offset = -1; ret = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH); diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 74002b2d1b6f..b5c87d89777b 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -97,7 +97,7 @@ static bool swap_available(void) static bool can_release_pages(struct drm_i915_gem_object *obj) { - if (!obj->mm.pages) + if (!i915_gem_object_has_pages(obj)) return false; /* Consider only shrinkable ojects. */ @@ -129,7 +129,7 @@ static bool unsafe_drop_pages(struct drm_i915_gem_object *obj) { if (i915_gem_object_unbind(obj) == 0) __i915_gem_object_put_pages(obj, I915_MM_SHRINKER); - return !READ_ONCE(obj->mm.pages); + return !i915_gem_object_has_pages(obj); } /** @@ -247,7 +247,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, /* May arrive from get_pages on another bo */ mutex_lock_nested(&obj->mm.lock, I915_MM_SHRINKER); - if (!obj->mm.pages) { + if (!i915_gem_object_has_pages(obj)) { __i915_gem_object_invalidate(obj); list_del_init(&obj->global_link); count += obj->base.size >> PAGE_SHIFT; @@ -413,7 +413,7 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) */ unbound = bound = unevictable = 0; list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { - if (!obj->mm.pages) + if (!i915_gem_object_has_pages(obj)) continue; if (!can_release_pages(obj)) @@ -422,7 +422,7 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) unbound += obj->base.size >> PAGE_SHIFT; } list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { - if (!obj->mm.pages) + if (!i915_gem_object_has_pages(obj)) continue; if (!can_release_pages(obj)) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index fb5231f98c0d..1294cf695df0 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -269,7 +269,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, * due to the change in swizzling. */ mutex_lock(&obj->mm.lock); - if (obj->mm.pages && + if (i915_gem_object_has_pages(obj) && obj->mm.madv == I915_MADV_WILLNEED && i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) { if (tiling == I915_TILING_NONE) { diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 4d712a4db63b..9afeb68e2d44 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -82,7 +82,7 @@ static void cancel_userptr(struct work_struct *work) /* We are inside a kthread context and can't be interrupted */ if (i915_gem_object_unbind(obj) == 0) __i915_gem_object_put_pages(obj, I915_MM_NORMAL); - WARN_ONCE(obj->mm.pages, + WARN_ONCE(i915_gem_object_has_pages(obj), "Failed to release pages: bind_count=%d, pages_pin_count=%d, pin_display=%d\n", obj->bind_count, atomic_read(&obj->mm.pages_pin_count), -- cgit v1.2.3 From bd3d2252f94da51dda96a6e2ad6fdef5f2959811 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:14 +0100 Subject: drm/i915: Rename obj->pin_display to obj->pin_global In the next patch, we want to extend use of the global pin counter for semi-permanent pinning of context/ring objects. Given that we plan to extend the usage to encompass a disparate set of objects, we want a name that reflects both and should entail less confusion. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 12 ++++++------ drivers/gpu/drm/i915/i915_gem.c | 20 ++++++++++---------- drivers/gpu/drm/i915/i915_gem_object.h | 3 ++- drivers/gpu/drm/i915/i915_gem_userptr.c | 4 ++-- 4 files changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0bb6e01121fc..fb9b34302811 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -83,7 +83,7 @@ static char get_active_flag(struct drm_i915_gem_object *obj) static char get_pin_flag(struct drm_i915_gem_object *obj) { - return obj->pin_display ? 'p' : ' '; + return obj->pin_global ? 'p' : ' '; } static char get_tiling_flag(struct drm_i915_gem_object *obj) @@ -180,8 +180,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) pin_count++; } seq_printf(m, " (pinned x %d)", pin_count); - if (obj->pin_display) - seq_printf(m, " (display)"); + if (obj->pin_global) + seq_printf(m, " (global)"); list_for_each_entry(vma, &obj->vma_list, obj_link) { if (!drm_mm_node_allocated(&vma->node)) continue; @@ -481,7 +481,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) size += obj->base.size; ++count; - if (obj->pin_display) { + if (obj->pin_global) { dpy_size += obj->base.size; ++dpy_count; } @@ -512,7 +512,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) huge_count, stringify_page_sizes(page_sizes, buf, sizeof(buf)), huge_size); - seq_printf(m, "%u display objects (pinned), %llu bytes\n", + seq_printf(m, "%u display objects (globally pinned), %llu bytes\n", dpy_count, dpy_size); seq_printf(m, "%llu [%llu] gtt total\n", @@ -579,7 +579,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) total_obj_size = total_gtt_size = count = 0; list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { - if (show_pin_display_only && !obj->pin_display) + if (show_pin_display_only && !obj->pin_global) continue; seq_puts(m, " "); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 059071715053..1f66a6168444 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -56,7 +56,7 @@ static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj) if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE)) return true; - return obj->pin_display; + return obj->pin_global; /* currently in use by HW, keep flushed */ } static int @@ -3493,7 +3493,7 @@ static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj) void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj) { - if (!READ_ONCE(obj->pin_display)) + if (!READ_ONCE(obj->pin_global)) return; mutex_lock(&obj->base.dev->struct_mutex); @@ -3860,10 +3860,10 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, lockdep_assert_held(&obj->base.dev->struct_mutex); - /* Mark the pin_display early so that we account for the + /* Mark the global pin early so that we account for the * display coherency whilst setting up the cache domains. */ - obj->pin_display++; + obj->pin_global++; /* The display engine is not coherent with the LLC cache on gen6. As * a result, we make sure that the pinning that is about to occur is @@ -3879,7 +3879,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, I915_CACHE_WT : I915_CACHE_NONE); if (ret) { vma = ERR_PTR(ret); - goto err_unpin_display; + goto err_unpin_global; } /* As the user may map the buffer once pinned in the display plane @@ -3910,7 +3910,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, flags); } if (IS_ERR(vma)) - goto err_unpin_display; + goto err_unpin_global; vma->display_alignment = max_t(u64, vma->display_alignment, alignment); @@ -3925,8 +3925,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, return vma; -err_unpin_display: - obj->pin_display--; +err_unpin_global: + obj->pin_global--; return vma; } @@ -3935,10 +3935,10 @@ i915_gem_object_unpin_from_display_plane(struct i915_vma *vma) { lockdep_assert_held(&vma->vm->i915->drm.struct_mutex); - if (WARN_ON(vma->obj->pin_display == 0)) + if (WARN_ON(vma->obj->pin_global == 0)) return; - if (--vma->obj->pin_display == 0) + if (--vma->obj->pin_global == 0) vma->display_alignment = I915_GTT_MIN_ALIGNMENT; /* Bump the LRU to try and avoid premature eviction whilst flipping */ diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index d67f1cbe842d..72aa02f3a0f8 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -161,7 +161,8 @@ struct drm_i915_gem_object { /** Count of VMA actually bound by this object */ unsigned int bind_count; unsigned int active_count; - unsigned int pin_display; + /** Count of how many global VMA are currently pinned for use by HW */ + unsigned int pin_global; struct { struct mutex lock; /* protects the pages and their use */ diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 9afeb68e2d44..cdc9be799eee 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -83,10 +83,10 @@ static void cancel_userptr(struct work_struct *work) if (i915_gem_object_unbind(obj) == 0) __i915_gem_object_put_pages(obj, I915_MM_NORMAL); WARN_ONCE(i915_gem_object_has_pages(obj), - "Failed to release pages: bind_count=%d, pages_pin_count=%d, pin_display=%d\n", + "Failed to release pages: bind_count=%d, pages_pin_count=%d, pin_global=%d\n", obj->bind_count, atomic_read(&obj->mm.pages_pin_count), - obj->pin_display); + obj->pin_global); mutex_unlock(&obj->base.dev->struct_mutex); -- cgit v1.2.3 From f46250e4773149ab0fd8262cdc28764bb58a2d62 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:15 +0100 Subject: drm/i915: Drop debugfs/i915_gem_pin_display It has now lost its meaning (it shows more than just pin_display), I do not believe that we are using in preference to the complete listing from i915_gem_gtt, or the listing from i915_gem_framebuffer, or the listing of active display objects in i915_display_info. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index fb9b34302811..7053d71b1ca9 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -568,7 +568,6 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_i915_private *dev_priv = node_to_i915(node); struct drm_device *dev = &dev_priv->drm; - bool show_pin_display_only = !!node->info_ent->data; struct drm_i915_gem_object *obj; u64 total_obj_size, total_gtt_size; int count, ret; @@ -579,9 +578,6 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) total_obj_size = total_gtt_size = count = 0; list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { - if (show_pin_display_only && !obj->pin_global) - continue; - seq_puts(m, " "); describe_obj(m, obj); seq_putc(m, '\n'); @@ -4751,7 +4747,6 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_capabilities", i915_capabilities, 0}, {"i915_gem_objects", i915_gem_object_info, 0}, {"i915_gem_gtt", i915_gem_gtt_info, 0}, - {"i915_gem_pin_display", i915_gem_gtt_info, 0, (void *)1}, {"i915_gem_stolen", i915_gem_stolen_list_info }, {"i915_gem_request", i915_gem_request_info, 0}, {"i915_gem_seqno", i915_gem_seqno_info, 0}, -- cgit v1.2.3 From 3d574a6bbb12a6c3bbeea807a1724b44a0f6ebbb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:16 +0100 Subject: drm/i915: Remove walk over obj->vma_list for the shrinker In the next patch, we want to reduce the lock coverage within the shrinker, and one of the dangerous walks we have is over obj->vma_list. We are only walking the obj->vma_list in order to check whether it has been permanently pinned by HW access, typically via use on the scanout. But we have a couple of other long term pins, the context objects for which we currently have to check the individual vma pin_count. If we instead mark these using obj->pin_display, we can forgo the dangerous and sometimes slow list iteration. v2: Rearrange code to try and avoid confusion from false associations due to arrangement of whitespace along with rebasing on obj->pin_global. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_shrinker.c | 27 +++++++-------------------- drivers/gpu/drm/i915/intel_lrc.c | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 8 +++++++- 3 files changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index b5c87d89777b..575a6b735f39 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -71,25 +71,6 @@ static void shrinker_unlock(struct drm_i915_private *dev_priv, bool unlock) mutex_unlock(&dev_priv->drm.struct_mutex); } -static bool any_vma_pinned(struct drm_i915_gem_object *obj) -{ - struct i915_vma *vma; - - list_for_each_entry(vma, &obj->vma_list, obj_link) { - /* Only GGTT vma may be permanently pinned, and are always - * at the start of the list. We can stop hunting as soon - * as we see a ppGTT vma. - */ - if (!i915_vma_is_ggtt(vma)) - break; - - if (i915_vma_is_pinned(vma)) - return true; - } - - return false; -} - static bool swap_available(void) { return get_nr_swap_pages() > 0; @@ -115,7 +96,13 @@ static bool can_release_pages(struct drm_i915_gem_object *obj) if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count) return false; - if (any_vma_pinned(obj)) + /* If any vma are "permanently" pinned, it will prevent us from + * reclaiming the obj->mm.pages. We only allow scanout objects to claim + * a permanent pin, along with a few others like the context objects. + * To simplify the scan, and to avoid walking the list of vma under the + * object, we just check the count of its permanently pinned. + */ + if (obj->pin_global) return false; /* We can only return physical pages to the system if we can either diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 766552f2cfae..7f45dd7dc3e5 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1093,6 +1093,7 @@ execlists_context_pin(struct intel_engine_cs *engine, i915_ggtt_offset(ce->ring->vma); ce->state->obj->mm.dirty = true; + ce->state->obj->pin_global++; i915_gem_context_get(ctx); out: @@ -1120,6 +1121,7 @@ static void execlists_context_unpin(struct intel_engine_cs *engine, intel_ring_unpin(ce->ring); + ce->state->obj->pin_global--; i915_gem_object_unpin_map(ce->state->obj); i915_vma_unpin(ce->state); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b2a6cb09c6e7..8da1bde442dd 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1244,6 +1244,8 @@ int intel_ring_pin(struct intel_ring *ring, if (IS_ERR(addr)) goto err; + vma->obj->pin_global++; + ring->vaddr = addr; return 0; @@ -1275,6 +1277,7 @@ void intel_ring_unpin(struct intel_ring *ring) i915_gem_object_unpin_map(ring->vma->obj); ring->vaddr = NULL; + ring->vma->obj->pin_global--; i915_vma_unpin(ring->vma); } @@ -1439,6 +1442,7 @@ intel_ring_context_pin(struct intel_engine_cs *engine, goto err; ce->state->obj->mm.dirty = true; + ce->state->obj->pin_global++; } /* The kernel context is only used as a placeholder for flushing the @@ -1473,8 +1477,10 @@ static void intel_ring_context_unpin(struct intel_engine_cs *engine, if (--ce->pin_count) return; - if (ce->state) + if (ce->state) { + ce->state->obj->pin_global--; i915_vma_unpin(ce->state); + } i915_gem_context_put(ctx); } -- cgit v1.2.3 From f2123818ffad0332e03c266ca73fe116e8ea5354 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Oct 2017 12:40:37 +0100 Subject: drm/i915: Move dev_priv->mm.[un]bound_list to its own lock Remove the struct_mutex requirement around dev_priv->mm.bound_list and dev_priv->mm.unbound_list by giving it its own spinlock. This reduces one more requirement for struct_mutex and in the process gives us slightly more accurate unbound_list tracking, which should improve the shrinker - but the drawback is that we drop the retirement before counting so i915_gem_object_is_active() may be stale and lead us to underestimate the number of objects that may be shrunk (see commit bed50aea61df ("drm/i915/shrinker: Flush active on objects before counting")). v2: Crosslink the spinlock to the lists it protects, and btw this changes s/obj->global_link/obj->mm.link/ v3: Fix decoupling of old links in i915_gem_object_attach_phys() v3.1: Fix the fix, only unlink if it was linked v3.2: Use a local for to_i915(obj->base.dev)->mm.obj_lock Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016114037.5556-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 39 +++++++++++--- drivers/gpu/drm/i915/i915_drv.h | 3 ++ drivers/gpu/drm/i915/i915_gem.c | 53 +++++++++++++++---- drivers/gpu/drm/i915/i915_gem_gtt.c | 3 +- drivers/gpu/drm/i915/i915_gem_object.h | 7 ++- drivers/gpu/drm/i915/i915_gem_shrinker.c | 64 +++++++++-------------- drivers/gpu/drm/i915/i915_gem_stolen.c | 5 +- drivers/gpu/drm/i915/i915_vma.c | 16 ++++-- drivers/gpu/drm/i915/selftests/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_evict.c | 8 ++- 10 files changed, 132 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 7053d71b1ca9..997feddb8436 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -271,7 +271,9 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) goto out; total_obj_size = total_gtt_size = count = 0; - list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { + + spin_lock(&dev_priv->mm.obj_lock); + list_for_each_entry(obj, &dev_priv->mm.bound_list, mm.link) { if (count == total) break; @@ -283,7 +285,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) total_gtt_size += i915_gem_obj_total_ggtt_size(obj); } - list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { + list_for_each_entry(obj, &dev_priv->mm.unbound_list, mm.link) { if (count == total) break; @@ -293,6 +295,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) objects[count++] = obj; total_obj_size += obj->base.size; } + spin_unlock(&dev_priv->mm.obj_lock); sort(objects, count, sizeof(*objects), obj_rank_by_stolen, NULL); @@ -454,7 +457,9 @@ static int i915_gem_object_info(struct seq_file *m, void *data) mapped_size = mapped_count = 0; purgeable_size = purgeable_count = 0; huge_size = huge_count = 0; - list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { + + spin_lock(&dev_priv->mm.obj_lock); + list_for_each_entry(obj, &dev_priv->mm.unbound_list, mm.link) { size += obj->base.size; ++count; @@ -477,7 +482,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) seq_printf(m, "%u unbound objects, %llu bytes\n", count, size); size = count = dpy_size = dpy_count = 0; - list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { + list_for_each_entry(obj, &dev_priv->mm.bound_list, mm.link) { size += obj->base.size; ++count; @@ -502,6 +507,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data) page_sizes |= obj->mm.page_sizes.sg; } } + spin_unlock(&dev_priv->mm.obj_lock); + seq_printf(m, "%u bound objects, %llu bytes\n", count, size); seq_printf(m, "%u purgeable objects, %llu bytes\n", @@ -568,28 +575,46 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_i915_private *dev_priv = node_to_i915(node); struct drm_device *dev = &dev_priv->drm; + struct drm_i915_gem_object **objects; struct drm_i915_gem_object *obj; u64 total_obj_size, total_gtt_size; + unsigned long nobject, n; int count, ret; + nobject = READ_ONCE(dev_priv->mm.object_count); + objects = kvmalloc_array(nobject, sizeof(*objects), GFP_KERNEL); + if (!objects) + return -ENOMEM; + ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - total_obj_size = total_gtt_size = count = 0; - list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { + count = 0; + spin_lock(&dev_priv->mm.obj_lock); + list_for_each_entry(obj, &dev_priv->mm.bound_list, mm.link) { + objects[count++] = obj; + if (count == nobject) + break; + } + spin_unlock(&dev_priv->mm.obj_lock); + + total_obj_size = total_gtt_size = 0; + for (n = 0; n < count; n++) { + obj = objects[n]; + seq_puts(m, " "); describe_obj(m, obj); seq_putc(m, '\n'); total_obj_size += obj->base.size; total_gtt_size += i915_gem_obj_total_ggtt_size(obj); - count++; } mutex_unlock(&dev->struct_mutex); seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n", count, total_obj_size, total_gtt_size); + kvfree(objects); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a9bc979e0cbd..4704cfe93279 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1490,6 +1490,9 @@ struct i915_gem_mm { * always the inner lock when overlapping with struct_mutex. */ struct mutex stolen_lock; + /* Protects bound_list/unbound_list and #drm_i915_gem_object.mm.link */ + spinlock_t obj_lock; + /** List of all objects in gtt_space. Used to restore gtt * mappings on resume */ struct list_head bound_list; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1f66a6168444..60e7fec426e2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1537,6 +1537,8 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) struct list_head *list; struct i915_vma *vma; + GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); + list_for_each_entry(vma, &obj->vma_list, obj_link) { if (!i915_vma_is_ggtt(vma)) break; @@ -1551,8 +1553,10 @@ static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) } i915 = to_i915(obj->base.dev); + spin_lock(&i915->mm.obj_lock); list = obj->bind_count ? &i915->mm.bound_list : &i915->mm.unbound_list; - list_move_tail(&obj->global_link, list); + list_move_tail(&obj->mm.link, list); + spin_unlock(&i915->mm.obj_lock); } /** @@ -2253,6 +2257,7 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj) void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, enum i915_mm_subclass subclass) { + struct drm_i915_private *i915 = to_i915(obj->base.dev); struct sg_table *pages; if (i915_gem_object_has_pinned_pages(obj)) @@ -2273,6 +2278,10 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, pages = fetch_and_zero(&obj->mm.pages); GEM_BUG_ON(!pages); + spin_lock(&i915->mm.obj_lock); + list_del(&obj->mm.link); + spin_unlock(&i915->mm.obj_lock); + if (obj->mm.mapping) { void *ptr; @@ -2507,7 +2516,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, obj->mm.pages = pages; if (i915_gem_object_is_tiled(obj) && - to_i915(obj->base.dev)->quirks & QUIRK_PIN_SWIZZLED_PAGES) { + i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) { GEM_BUG_ON(obj->mm.quirked); __i915_gem_object_pin_pages(obj); obj->mm.quirked = true; @@ -2529,8 +2538,11 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, if (obj->mm.page_sizes.phys & ~0u << i) obj->mm.page_sizes.sg |= BIT(i); } - GEM_BUG_ON(!HAS_PAGE_SIZES(i915, obj->mm.page_sizes.sg)); + + spin_lock(&i915->mm.obj_lock); + list_add(&obj->mm.link, &i915->mm.unbound_list); + spin_unlock(&i915->mm.obj_lock); } static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj) @@ -4324,7 +4336,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, { mutex_init(&obj->mm.lock); - INIT_LIST_HEAD(&obj->global_link); INIT_LIST_HEAD(&obj->vma_list); INIT_LIST_HEAD(&obj->lut_list); INIT_LIST_HEAD(&obj->batch_pool_link); @@ -4496,7 +4507,18 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, GEM_BUG_ON(!list_empty(&obj->vma_list)); GEM_BUG_ON(!RB_EMPTY_ROOT(&obj->vma_tree)); - list_del(&obj->global_link); + /* This serializes freeing with the shrinker. Since the free + * is delayed, first by RCU then by the workqueue, we want the + * shrinker to be able to free pages of unreferenced objects, + * or else we may oom whilst there are plenty of deferred + * freed objects. + */ + if (i915_gem_object_has_pages(obj)) { + spin_lock(&i915->mm.obj_lock); + list_del_init(&obj->mm.link); + spin_unlock(&i915->mm.obj_lock); + } + } intel_runtime_pm_put(i915); mutex_unlock(&i915->drm.struct_mutex); @@ -5035,11 +5057,14 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) goto err_priorities; INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work); + + spin_lock_init(&dev_priv->mm.obj_lock); init_llist_head(&dev_priv->mm.free_list); INIT_LIST_HEAD(&dev_priv->mm.unbound_list); INIT_LIST_HEAD(&dev_priv->mm.bound_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); INIT_LIST_HEAD(&dev_priv->mm.userfault_list); + INIT_DELAYED_WORK(&dev_priv->gt.retire_work, i915_gem_retire_work_handler); INIT_DELAYED_WORK(&dev_priv->gt.idle_work, @@ -5133,12 +5158,12 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv) i915_gem_shrink(dev_priv, -1UL, NULL, I915_SHRINK_UNBOUND); i915_gem_drain_freed_objects(dev_priv); - mutex_lock(&dev_priv->drm.struct_mutex); + spin_lock(&dev_priv->mm.obj_lock); for (p = phases; *p; p++) { - list_for_each_entry(obj, *p, global_link) + list_for_each_entry(obj, *p, mm.link) __start_cpu_write(obj); } - mutex_unlock(&dev_priv->drm.struct_mutex); + spin_unlock(&dev_priv->mm.obj_lock); return 0; } @@ -5457,7 +5482,17 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align) goto err_unlock; } - pages = obj->mm.pages; + pages = fetch_and_zero(&obj->mm.pages); + if (pages) { + struct drm_i915_private *i915 = to_i915(obj->base.dev); + + __i915_gem_object_reset_page_iter(obj); + + spin_lock(&i915->mm.obj_lock); + list_del(&obj->mm.link); + spin_unlock(&i915->mm.obj_lock); + } + obj->ops = &i915_gem_phys_ops; err = ____i915_gem_object_get_pages(obj); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index daba55a4fce2..527a2d2d6281 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3594,8 +3594,7 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv) ggtt->base.closed = true; /* skip rewriting PTE on VMA unbind */ /* clflush objects bound into the GGTT and rebind them. */ - list_for_each_entry_safe(obj, on, - &dev_priv->mm.bound_list, global_link) { + list_for_each_entry_safe(obj, on, &dev_priv->mm.bound_list, mm.link) { bool ggtt_bound = false; struct i915_vma *vma; diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 72aa02f3a0f8..63ce38c1cce9 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -114,7 +114,6 @@ struct drm_i915_gem_object { /** Stolen memory for this object, instead of being backed by shmem. */ struct drm_mm_node *stolen; - struct list_head global_link; union { struct rcu_head rcu; struct llist_node freed; @@ -208,6 +207,12 @@ struct drm_i915_gem_object { struct mutex lock; /* protects this cache */ } get_page; + /** + * Element within i915->mm.unbound_list or i915->mm.bound_list, + * locked by i915->mm.obj_lock. + */ + struct list_head link; + /** * Advice: are the backing pages purgeable? */ diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 575a6b735f39..065d026b5092 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -78,9 +78,6 @@ static bool swap_available(void) static bool can_release_pages(struct drm_i915_gem_object *obj) { - if (!i915_gem_object_has_pages(obj)) - return false; - /* Consider only shrinkable ojects. */ if (!i915_gem_object_is_shrinkable(obj)) return false; @@ -102,7 +99,7 @@ static bool can_release_pages(struct drm_i915_gem_object *obj) * To simplify the scan, and to avoid walking the list of vma under the * object, we just check the count of its permanently pinned. */ - if (obj->pin_global) + if (READ_ONCE(obj->pin_global)) return false; /* We can only return physical pages to the system if we can either @@ -204,15 +201,20 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, continue; INIT_LIST_HEAD(&still_in_list); + + /* + * We serialize our access to unreferenced objects through + * the use of the struct_mutex. While the objects are not + * yet freed (due to RCU then a workqueue) we still want + * to be able to shrink their pages, so they remain on + * the unbound/bound list until actually freed. + */ + spin_lock(&dev_priv->mm.obj_lock); while (count < target && (obj = list_first_entry_or_null(phase->list, typeof(*obj), - global_link))) { - list_move_tail(&obj->global_link, &still_in_list); - if (!obj->mm.pages) { - list_del_init(&obj->global_link); - continue; - } + mm.link))) { + list_move_tail(&obj->mm.link, &still_in_list); if (flags & I915_SHRINK_PURGEABLE && obj->mm.madv != I915_MADV_DONTNEED) @@ -230,20 +232,24 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, if (!can_release_pages(obj)) continue; + spin_unlock(&dev_priv->mm.obj_lock); + if (unsafe_drop_pages(obj)) { /* May arrive from get_pages on another bo */ mutex_lock_nested(&obj->mm.lock, I915_MM_SHRINKER); if (!i915_gem_object_has_pages(obj)) { __i915_gem_object_invalidate(obj); - list_del_init(&obj->global_link); count += obj->base.size >> PAGE_SHIFT; } mutex_unlock(&obj->mm.lock); scanned += obj->base.size >> PAGE_SHIFT; } + + spin_lock(&dev_priv->mm.obj_lock); } list_splice_tail(&still_in_list, phase->list); + spin_unlock(&dev_priv->mm.obj_lock); } if (flags & I915_SHRINK_BOUND) @@ -292,25 +298,17 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) struct drm_i915_private *dev_priv = container_of(shrinker, struct drm_i915_private, mm.shrinker); struct drm_i915_gem_object *obj; - unsigned long count; - bool unlock; - - if (!shrinker_lock(dev_priv, &unlock)) - return 0; - - i915_gem_retire_requests(dev_priv); + unsigned long count = 0; - count = 0; - list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) + spin_lock(&dev_priv->mm.obj_lock); + list_for_each_entry(obj, &dev_priv->mm.unbound_list, mm.link) if (can_release_pages(obj)) count += obj->base.size >> PAGE_SHIFT; - list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { + list_for_each_entry(obj, &dev_priv->mm.bound_list, mm.link) if (!i915_gem_object_is_active(obj) && can_release_pages(obj)) count += obj->base.size >> PAGE_SHIFT; - } - - shrinker_unlock(dev_priv, unlock); + spin_unlock(&dev_priv->mm.obj_lock); return count; } @@ -387,10 +385,6 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) container_of(nb, struct drm_i915_private, mm.oom_notifier); struct drm_i915_gem_object *obj; unsigned long unevictable, bound, unbound, freed_pages; - bool unlock; - - if (!shrinker_lock_uninterruptible(dev_priv, &unlock, 5000)) - return NOTIFY_DONE; freed_pages = i915_gem_shrink_all(dev_priv); @@ -399,26 +393,20 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) * being pointed to by hardware. */ unbound = bound = unevictable = 0; - list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { - if (!i915_gem_object_has_pages(obj)) - continue; - + spin_lock(&dev_priv->mm.obj_lock); + list_for_each_entry(obj, &dev_priv->mm.unbound_list, mm.link) { if (!can_release_pages(obj)) unevictable += obj->base.size >> PAGE_SHIFT; else unbound += obj->base.size >> PAGE_SHIFT; } - list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { - if (!i915_gem_object_has_pages(obj)) - continue; - + list_for_each_entry(obj, &dev_priv->mm.bound_list, mm.link) { if (!can_release_pages(obj)) unevictable += obj->base.size >> PAGE_SHIFT; else bound += obj->base.size >> PAGE_SHIFT; } - - shrinker_unlock(dev_priv, unlock); + spin_unlock(&dev_priv->mm.obj_lock); if (freed_pages || unbound || bound) pr_info("Purging GPU memory, %lu pages freed, " diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 54fd4cfa9d07..03e7abc7e043 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -724,8 +724,11 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv vma->flags |= I915_VMA_GLOBAL_BIND; __i915_vma_set_map_and_fenceable(vma); list_move_tail(&vma->vm_link, &ggtt->base.inactive_list); - list_move_tail(&obj->global_link, &dev_priv->mm.bound_list); + + spin_lock(&dev_priv->mm.obj_lock); + list_move_tail(&obj->mm.link, &dev_priv->mm.bound_list); obj->bind_count++; + spin_unlock(&dev_priv->mm.obj_lock); return obj; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 4dce2e0197d9..fc77e8191eb5 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -58,8 +58,10 @@ i915_vma_retire(struct i915_gem_active *active, * so that we don't steal from recently used but inactive objects * (unless we are forced to ofc!) */ + spin_lock(&rq->i915->mm.obj_lock); if (obj->bind_count) - list_move_tail(&obj->global_link, &rq->i915->mm.bound_list); + list_move_tail(&obj->mm.link, &rq->i915->mm.bound_list); + spin_unlock(&rq->i915->mm.obj_lock); obj->mm.dirty = true; /* be paranoid */ @@ -563,9 +565,13 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); GEM_BUG_ON(!i915_gem_valid_gtt_space(vma, obj->cache_level)); - list_move_tail(&obj->global_link, &dev_priv->mm.bound_list); list_move_tail(&vma->vm_link, &vma->vm->inactive_list); + + spin_lock(&dev_priv->mm.obj_lock); + list_move_tail(&obj->mm.link, &dev_priv->mm.bound_list); obj->bind_count++; + spin_unlock(&dev_priv->mm.obj_lock); + GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count); return 0; @@ -580,6 +586,7 @@ err_unpin: static void i915_vma_remove(struct i915_vma *vma) { + struct drm_i915_private *i915 = vma->vm->i915; struct drm_i915_gem_object *obj = vma->obj; GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); @@ -593,9 +600,10 @@ i915_vma_remove(struct i915_vma *vma) /* Since the unbound list is global, only move to that list if * no more VMAs exist. */ + spin_lock(&i915->mm.obj_lock); if (--obj->bind_count == 0) - list_move_tail(&obj->global_link, - &to_i915(obj->base.dev)->mm.unbound_list); + list_move_tail(&obj->mm.link, &i915->mm.unbound_list); + spin_unlock(&i915->mm.obj_lock); /* And finally now the object is completely decoupled from this vma, * we can drop its hold on the backing storage and allow it to be diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c index fb0a58fc8348..def5052862ae 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c @@ -417,7 +417,7 @@ static int fake_aliasing_ppgtt_enable(struct drm_i915_private *i915) if (err) return err; - list_for_each_entry(obj, &i915->mm.bound_list, global_link) { + list_for_each_entry(obj, &i915->mm.bound_list, mm.link) { struct i915_vma *vma; vma = i915_vma_instance(obj, &i915->ggtt.base, NULL); diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index 473aa9631145..f463105ff48d 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -50,7 +50,7 @@ static int populate_ggtt(struct drm_i915_private *i915) if (!list_empty(&i915->mm.unbound_list)) { size = 0; - list_for_each_entry(obj, &i915->mm.unbound_list, global_link) + list_for_each_entry(obj, &i915->mm.unbound_list, mm.link) size++; pr_err("Found %lld objects unbound!\n", size); @@ -77,10 +77,10 @@ static void cleanup_objects(struct drm_i915_private *i915) { struct drm_i915_gem_object *obj, *on; - list_for_each_entry_safe(obj, on, &i915->mm.unbound_list, global_link) + list_for_each_entry_safe(obj, on, &i915->mm.unbound_list, mm.link) i915_gem_object_put(obj); - list_for_each_entry_safe(obj, on, &i915->mm.bound_list, global_link) + list_for_each_entry_safe(obj, on, &i915->mm.bound_list, mm.link) i915_gem_object_put(obj); mutex_unlock(&i915->drm.struct_mutex); @@ -152,8 +152,6 @@ static int igt_overcommit(void *arg) goto cleanup; } - list_move(&obj->global_link, &i915->mm.unbound_list); - vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0); if (!IS_ERR(vma) || PTR_ERR(vma) != -ENOSPC) { pr_err("Failed to evict+insert, i915_gem_object_ggtt_pin returned err=%d\n", (int)PTR_ERR(vma)); -- cgit v1.2.3 From 4e773c3a8a693e5abc248c5be26973b868466dde Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:18 +0100 Subject: drm/i915: Wire up shrinkctl->nr_scanned shrink_slab() allows us to report back the number of objects we successfully scanned (out of the target shrinkctl->nr_to_scan). As report the number of pages owned by each GEM object as a separate item to the shrinker, we cannot precisely control the number of shrinker objects we scan on each pass; and indeed may free more than requested. If we fail to tell the shrinker about the number of objects we process, it will continue to hold a grudge against us as any objects left unscanned are added to the next reclaim -- and so we will keep on "unfairly" shrinking our own slab in comparison to other slabs. v2: fixup the misplaced addition, we want to count everything we scan (to match the number we reported earlier) not just the objects we successfully validated and freed. References: 912d572d63b8 ("drm/i915: wire up shrinkctl->nr_scanned") Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-6-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_shrinker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 065d026b5092..175765111f4e 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -243,8 +243,8 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, count += obj->base.size >> PAGE_SHIFT; } mutex_unlock(&obj->mm.lock); - scanned += obj->base.size >> PAGE_SHIFT; } + scanned += obj->base.size >> PAGE_SHIFT; spin_lock(&dev_priv->mm.obj_lock); } -- cgit v1.2.3 From c5418a8b38a4ff9284e8e59c06a24f443197131c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:19 +0100 Subject: drm/i915: Set our shrinker->batch to 4096 (~16MiB) Prefer to defer activating our GEM shrinker until we have a few megabytes to free; or we have accumulated sufficient mempressure by deferring the reclaim to force a shrink. The intent is that because our objects may typically be large, we are too effective at shrinking and are not rewarded for freeing more pages than the batch. It will also defer the initial shrinking to hopefully put it at a lower priority than say the buffer cache (although it will balance out over a number of reclaims, with GEM being more bursty). v2: Give it a feedback system to try and tune the batch size towards an effective size for the available objects. v3: Start keeping track of shrinker stats in debugfs v4: Protect against finding no shrinkable objects (div-by-zero) Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-7-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 11 +++++++++++ drivers/gpu/drm/i915/i915_gem_shrinker.c | 34 +++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 997feddb8436..6d643642e0ce 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3331,6 +3331,16 @@ static int i915_engine_info(struct seq_file *m, void *unused) return 0; } +static int i915_shrinker_info(struct seq_file *m, void *unused) +{ + struct drm_i915_private *i915 = node_to_i915(m->private); + + seq_printf(m, "seeks = %d\n", i915->mm.shrinker.seeks); + seq_printf(m, "batch = %lu\n", i915->mm.shrinker.batch); + + return 0; +} + static int i915_semaphore_status(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -4811,6 +4821,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_dmc_info", i915_dmc_info, 0}, {"i915_display_info", i915_display_info, 0}, {"i915_engine_info", i915_engine_info, 0}, + {"i915_shrinker_info", i915_shrinker_info, 0}, {"i915_semaphore_status", i915_semaphore_status, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 175765111f4e..eb31f8aa5c21 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -295,20 +295,39 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv) static unsigned long i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) { - struct drm_i915_private *dev_priv = + struct drm_i915_private *i915 = container_of(shrinker, struct drm_i915_private, mm.shrinker); struct drm_i915_gem_object *obj; + unsigned long num_objects = 0; unsigned long count = 0; - spin_lock(&dev_priv->mm.obj_lock); - list_for_each_entry(obj, &dev_priv->mm.unbound_list, mm.link) - if (can_release_pages(obj)) + spin_lock(&i915->mm.obj_lock); + list_for_each_entry(obj, &i915->mm.unbound_list, mm.link) + if (can_release_pages(obj)) { count += obj->base.size >> PAGE_SHIFT; + num_objects++; + } - list_for_each_entry(obj, &dev_priv->mm.bound_list, mm.link) - if (!i915_gem_object_is_active(obj) && can_release_pages(obj)) + list_for_each_entry(obj, &i915->mm.bound_list, mm.link) + if (!i915_gem_object_is_active(obj) && can_release_pages(obj)) { count += obj->base.size >> PAGE_SHIFT; - spin_unlock(&dev_priv->mm.obj_lock); + num_objects++; + } + spin_unlock(&i915->mm.obj_lock); + + /* Update our preferred vmscan batch size for the next pass. + * Our rough guess for an effective batch size is roughly 2 + * available GEM objects worth of pages. That is we don't want + * the shrinker to fire, until it is worth the cost of freeing an + * entire GEM object. + */ + if (num_objects) { + unsigned long avg = 2 * count / num_objects; + + i915->mm.shrinker.batch = + max((i915->mm.shrinker.batch + avg) >> 1, + 128ul /* default SHRINK_BATCH */); + } return count; } @@ -473,6 +492,7 @@ void i915_gem_shrinker_init(struct drm_i915_private *dev_priv) dev_priv->mm.shrinker.scan_objects = i915_gem_shrinker_scan; dev_priv->mm.shrinker.count_objects = i915_gem_shrinker_count; dev_priv->mm.shrinker.seeks = DEFAULT_SEEKS; + dev_priv->mm.shrinker.batch = 4096; WARN_ON(register_shrinker(&dev_priv->mm.shrinker)); dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom; -- cgit v1.2.3 From 87701b4b559377dd6ebc95003bd8e422a1011303 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:20 +0100 Subject: drm/i915: Only free the oldest stale object before a fresh allocation Inspired by Tvrtko's critique of the reaping of the stale contexts before allocating a new one, also limit the freed object reaping to the oldest stale object before allocating a fresh object. Unlike contexts, objects may have radically different sizes of backing storage, but similar to contexts, while we want to prevent starvation due to excessive freed lists, we also do not want to delay fresh allocations for too long. Only freeing the oldest on the freed object list before each allocation is a reasonable compromise. v2: Only a single consumer of llist_del_first() is allowed (although multiple llist_add are still allowed in parallel). Unlike i915_gem_context, i915_gem_flush_free_objects() is itself not serialized and so we need to add our own spinlock. Otherwise KASAN eventually spots a use-after-free for the race on *first->next. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin #v1 Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-8-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4704cfe93279..dd141b250583 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1513,6 +1513,7 @@ struct i915_gem_mm { */ struct llist_head free_list; struct work_struct free_work; + spinlock_t free_lock; /** * Small stash of WC pages diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 60e7fec426e2..f4b5921a9e9b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4555,9 +4555,18 @@ static void i915_gem_flush_free_objects(struct drm_i915_private *i915) { struct llist_node *freed; - freed = llist_del_all(&i915->mm.free_list); - if (unlikely(freed)) + /* Free the oldest, most stale object to keep the free_list short */ + freed = NULL; + if (!llist_empty(&i915->mm.free_list)) { /* quick test for hotpath */ + /* Only one consumer of llist_del_first() allowed */ + spin_lock(&i915->mm.free_lock); + freed = llist_del_first(&i915->mm.free_list); + spin_unlock(&i915->mm.free_lock); + } + if (unlikely(freed)) { + freed->next = NULL; __i915_gem_free_objects(i915, freed); + } } static void __i915_gem_free_work(struct work_struct *work) @@ -5059,6 +5068,7 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work); spin_lock_init(&dev_priv->mm.obj_lock); + spin_lock_init(&dev_priv->mm.free_lock); init_llist_head(&dev_priv->mm.free_list); INIT_LIST_HEAD(&dev_priv->mm.unbound_list); INIT_LIST_HEAD(&dev_priv->mm.bound_list); -- cgit v1.2.3 From cc731f5a3b1f592d8aef04c9de720c6bc09b209a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 21:26:21 +0100 Subject: drm/i915: Trim struct_mutex hold duration for i915_gem_free_objects We free objects in bulk after they wait for their RCU grace period. Currently, we take struct_mutex and unbind all the objects. This can lead to a long lock duration during which time those objects have their pages unfreeable (i.e. the shrinker is prevented from reaping those pages). If we only process a single object under the struct_mutex and then free the pages, the number of objects locked away from the shrinker is minimal and we allow regular clients better access to struct_mutex if they need it. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-9-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f4b5921a9e9b..1304152bd28b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4490,13 +4490,14 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, { struct drm_i915_gem_object *obj, *on; - mutex_lock(&i915->drm.struct_mutex); intel_runtime_pm_get(i915); - llist_for_each_entry(obj, freed, freed) { + llist_for_each_entry_safe(obj, on, freed, freed) { struct i915_vma *vma, *vn; trace_i915_gem_object_destroy(obj); + mutex_lock(&i915->drm.struct_mutex); + GEM_BUG_ON(i915_gem_object_is_active(obj)); list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link) { @@ -4519,13 +4520,8 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, spin_unlock(&i915->mm.obj_lock); } - } - intel_runtime_pm_put(i915); - mutex_unlock(&i915->drm.struct_mutex); - - cond_resched(); + mutex_unlock(&i915->drm.struct_mutex); - llist_for_each_entry_safe(obj, on, freed, freed) { GEM_BUG_ON(obj->bind_count); GEM_BUG_ON(obj->userfault_count); GEM_BUG_ON(atomic_read(&obj->frontbuffer_bits)); @@ -4548,7 +4544,11 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, kfree(obj->bit_17); i915_gem_object_free(obj); + + if (on) + cond_resched(); } + intel_runtime_pm_put(i915); } static void i915_gem_flush_free_objects(struct drm_i915_private *i915) -- cgit v1.2.3 From 6f74b36b92cf9ee6450258fa341cff7c455a138f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 15 Oct 2017 15:37:25 +0100 Subject: drm/i915: Skip HW reinitialisation on resume if still wedged If we fail to recover the HW state upon resume (i.e. our attempt to clear the wedged bit and reset during i915_gem_sanitize() fails), then skip the HW restart inside i915_gem_init_hw(). We will ultimately do the HW restart when successfully unwedging and resetting the HW later, but attempting to restore a wedged device upon resume is risky as the HW is in an unknown state. v2: Suppress the error message when detecting the already wedged HW. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103240 Testcase: igt/gem_eio/in-flight-suspend Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171015143725.27764-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gem.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1304152bd28b..ee2a30422020 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4867,6 +4867,10 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv) init_unused_rings(dev_priv); BUG_ON(!dev_priv->kernel_context); + if (i915_terminally_wedged(&dev_priv->gpu_error)) { + ret = -EIO; + goto out; + } ret = i915_ppgtt_init_hw(dev_priv); if (ret) { @@ -4965,8 +4969,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv) * wedged. But we only want to do this where the GPU is angry, * for all other failure, such as an allocation failure, bail. */ - DRM_ERROR("Failed to initialize GPU, declaring it wedged\n"); - i915_gem_set_wedged(dev_priv); + if (!i915_terminally_wedged(&dev_priv->gpu_error)) { + DRM_ERROR("Failed to initialize GPU, declaring it wedged\n"); + i915_gem_set_wedged(dev_priv); + } ret = 0; } -- cgit v1.2.3 From e1043a4bb9fce6cfc7d55c5767e429a18ac8c4eb Mon Sep 17 00:00:00 2001 From: Mohammed Gamal Date: Mon, 16 Oct 2017 15:20:32 +0200 Subject: xen-netfront, xen-netback: Use correct minimum MTU values RFC791 specifies the minimum MTU to be 68, while xen-net{front|back} drivers use a minimum value of 0. When set MTU to 0~67 with xen_net{front|back} driver, the network will become unreachable immediately, the guest can no longer be pinged. xen_net{front|back} should not allow the user to set this value which causes network problems. Reported-by: Chen Shi Signed-off-by: Mohammed Gamal Acked-by: Wei Liu Reviewed-by: Boris Ostrovsky Signed-off-by: Boris Ostrovsky --- drivers/net/xen-netback/interface.c | 2 +- drivers/net/xen-netfront.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index ee8ed9da00ad..4491ca5aee90 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -486,7 +486,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, dev->tx_queue_len = XENVIF_QUEUE_LENGTH; - dev->min_mtu = 0; + dev->min_mtu = ETH_MIN_MTU; dev->max_mtu = ETH_MAX_MTU - VLAN_ETH_HLEN; /* diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 523387e71a80..8b8689c6d887 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1316,7 +1316,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) netdev->features |= netdev->hw_features; netdev->ethtool_ops = &xennet_ethtool_ops; - netdev->min_mtu = 0; + netdev->min_mtu = ETH_MIN_MTU; netdev->max_mtu = XEN_NETIF_MAX_TX_SIZE; SET_NETDEV_DEV(netdev, &dev->dev); -- cgit v1.2.3 From 0ad646c81b2182f7fa67ec0c8c825e0ee165696d Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 13 Oct 2017 11:58:53 -0700 Subject: tun: call dev_get_valid_name() before register_netdevice() register_netdevice() could fail early when we have an invalid dev name, in which case ->ndo_uninit() is not called. For tun device, this is a problem because a timer etc. are already initialized and it expects ->ndo_uninit() to clean them up. We could move these initializations into a ->ndo_init() so that register_netdevice() knows better, however this is still complicated due to the logic in tun_detach(). Therefore, I choose to just call dev_get_valid_name() before register_netdevice(), which is quicker and much easier to audit. And for this specific case, it is already enough. Fixes: 96442e42429e ("tuntap: choose the txq based on rxq") Reported-by: Dmitry Alexeev Cc: Jason Wang Cc: "Michael S. Tsirkin" Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- drivers/net/tun.c | 3 +++ include/linux/netdevice.h | 3 +++ net/core/dev.c | 6 +++--- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 5ce580f413b9..e21bf90b819f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2027,6 +2027,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (!dev) return -ENOMEM; + err = dev_get_valid_name(net, dev, name); + if (err) + goto err_free_dev; dev_net_set(dev, net); dev->rtnl_link_ops = &tun_link_ops; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f535779d9dc1..2eaac7d75af4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3694,6 +3694,9 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, unsigned char name_assign_type, void (*setup)(struct net_device *), unsigned int txqs, unsigned int rxqs); +int dev_get_valid_name(struct net *net, struct net_device *dev, + const char *name); + #define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \ alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1) diff --git a/net/core/dev.c b/net/core/dev.c index 588b473194a8..11596a302a26 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1147,9 +1147,8 @@ static int dev_alloc_name_ns(struct net *net, return ret; } -static int dev_get_valid_name(struct net *net, - struct net_device *dev, - const char *name) +int dev_get_valid_name(struct net *net, struct net_device *dev, + const char *name) { BUG_ON(!net); @@ -1165,6 +1164,7 @@ static int dev_get_valid_name(struct net *net, return 0; } +EXPORT_SYMBOL(dev_get_valid_name); /** * dev_change_name - change name of a device -- cgit v1.2.3 From 226584aedd94acd61ffa51fb69bcf6b3309a7b8f Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 16 Oct 2017 12:27:58 +0200 Subject: spi: fix IDR collision on systems with both fixed and dynamic SPI bus numbers On systems where some controllers get a dynamic ID assigned and some have a fixed number from DT, the current implemention might run into an IDR collision if the dynamic controllers gets probed first and get an IDR number, which is later requested by the controller with the fixed numbering. When this happens the fixed controller will fail to register with the SPI core. Fix this by skipping all known alias numbers when assigning the dynamic IDs. Fixes: 9b61e302210e (spi: Pick spi bus number from Linux idr or spi alias) Signed-off-by: Lucas Stach Signed-off-by: Mark Brown --- drivers/spi/spi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 6e65524cbfd9..e8b5a5e21b2e 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -45,7 +45,6 @@ #define CREATE_TRACE_POINTS #include -#define SPI_DYN_FIRST_BUS_NUM 0 static DEFINE_IDR(spi_master_idr); @@ -2086,7 +2085,7 @@ int spi_register_controller(struct spi_controller *ctlr) struct device *dev = ctlr->dev.parent; struct boardinfo *bi; int status = -ENODEV; - int id; + int id, first_dynamic; if (!dev) return -ENODEV; @@ -2116,9 +2115,15 @@ int spi_register_controller(struct spi_controller *ctlr) } } if (ctlr->bus_num < 0) { + first_dynamic = of_alias_get_highest_id("spi"); + if (first_dynamic < 0) + first_dynamic = 0; + else + first_dynamic++; + mutex_lock(&board_lock); - id = idr_alloc(&spi_master_idr, ctlr, SPI_DYN_FIRST_BUS_NUM, 0, - GFP_KERNEL); + id = idr_alloc(&spi_master_idr, ctlr, first_dynamic, + 0, GFP_KERNEL); mutex_unlock(&board_lock); if (WARN(id < 0, "couldn't get idr")) return id; -- cgit v1.2.3 From a27d5a44ec87a019d818a82d0475b5d38856691e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 15 Oct 2017 21:43:10 +0100 Subject: drm/i915: Add in-flight request details to intel_engine_dump() In the intel_engine_cs dumper, we were showing the request details for the request queue but not of those requests already passed to the hw (just a summary of the seqno). If we show those details, we can then eliminate the entirely redundant and forgotten debugfs/i915_gem_request Signed-off-by: Chris Wilson Cc: Jeff McGee Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20171015204310.17045-1-chris@chris-wilson.co.uk Reviewed-by: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 49 ---------------------------------- drivers/gpu/drm/i915/intel_engine_cs.c | 35 +++++++++++++----------- 2 files changed, 19 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6d643642e0ce..40287e9f00d7 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -664,54 +664,6 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data) return 0; } -static void print_request(struct seq_file *m, - struct drm_i915_gem_request *rq, - const char *prefix) -{ - seq_printf(m, "%s%x [%x:%x] prio=%d @ %dms: %s\n", prefix, - rq->global_seqno, rq->ctx->hw_id, rq->fence.seqno, - rq->priotree.priority, - jiffies_to_msecs(jiffies - rq->emitted_jiffies), - rq->timeline->common->name); -} - -static int i915_gem_request_info(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct drm_device *dev = &dev_priv->drm; - struct drm_i915_gem_request *req; - struct intel_engine_cs *engine; - enum intel_engine_id id; - int ret, any; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - any = 0; - for_each_engine(engine, dev_priv, id) { - int count; - - count = 0; - list_for_each_entry(req, &engine->timeline->requests, link) - count++; - if (count == 0) - continue; - - seq_printf(m, "%s requests: %d\n", engine->name, count); - list_for_each_entry(req, &engine->timeline->requests, link) - print_request(m, req, " "); - - any++; - } - mutex_unlock(&dev->struct_mutex); - - if (any == 0) - seq_puts(m, "No requests\n"); - - return 0; -} - static void i915_ring_seqno_info(struct seq_file *m, struct intel_engine_cs *engine) { @@ -4783,7 +4735,6 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_gem_objects", i915_gem_object_info, 0}, {"i915_gem_gtt", i915_gem_gtt_info, 0}, {"i915_gem_stolen", i915_gem_stolen_list_info }, - {"i915_gem_request", i915_gem_request_info, 0}, {"i915_gem_seqno", i915_gem_seqno_info, 0}, {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, {"i915_gem_interrupt", i915_interrupt_info, 0}, diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 83e696f67d42..9a4c4abc7450 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1623,8 +1623,10 @@ static void print_request(struct drm_printer *m, struct drm_i915_gem_request *rq, const char *prefix) { - drm_printf(m, "%s%x [%x:%x] prio=%d @ %dms: %s\n", prefix, - rq->global_seqno, rq->ctx->hw_id, rq->fence.seqno, + drm_printf(m, "%s%x%s [%x:%x] prio=%d @ %dms: %s\n", prefix, + rq->global_seqno, + i915_gem_request_completed(rq) ? "!" : "", + rq->ctx->hw_id, rq->fence.seqno, rq->priotree.priority, jiffies_to_msecs(jiffies - rq->emitted_jiffies), rq->timeline->common->name); @@ -1632,8 +1634,9 @@ static void print_request(struct drm_printer *m, void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) { - struct intel_breadcrumbs *b = &engine->breadcrumbs; - struct i915_gpu_error *error = &engine->i915->gpu_error; + struct intel_breadcrumbs * const b = &engine->breadcrumbs; + const struct intel_engine_execlists * const execlists = &engine->execlists; + struct i915_gpu_error * const error = &engine->i915->gpu_error; struct drm_i915_private *dev_priv = engine->i915; struct drm_i915_gem_request *rq; struct rb_node *rb; @@ -1697,7 +1700,6 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) if (i915_modparams.enable_execlists) { const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; - struct intel_engine_execlists * const execlists = &engine->execlists; u32 ptr, read, write; unsigned int idx; @@ -1745,17 +1747,6 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) } } rcu_read_unlock(); - - spin_lock_irq(&engine->timeline->lock); - for (rb = execlists->first; rb; rb = rb_next(rb)) { - struct i915_priolist *p = - rb_entry(rb, typeof(*p), node); - - list_for_each_entry(rq, &p->requests, - priotree.link) - print_request(m, rq, "\t\tQ "); - } - spin_unlock_irq(&engine->timeline->lock); } else if (INTEL_GEN(dev_priv) > 6) { drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(engine))); @@ -1765,6 +1756,18 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) I915_READ(RING_PP_DIR_DCLV(engine))); } + spin_lock_irq(&engine->timeline->lock); + list_for_each_entry(rq, &engine->timeline->requests, link) + print_request(m, rq, "\t\tE "); + for (rb = execlists->first; rb; rb = rb_next(rb)) { + struct i915_priolist *p = + rb_entry(rb, typeof(*p), node); + + list_for_each_entry(rq, &p->requests, priotree.link) + print_request(m, rq, "\t\tQ "); + } + spin_unlock_irq(&engine->timeline->lock); + spin_lock_irq(&b->rb_lock); for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { struct intel_wait *w = rb_entry(rb, typeof(*w), node); -- cgit v1.2.3 From 87145d95c3d8297fb74762bd92e022d7f5cc250c Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 3 Oct 2017 15:08:58 -0700 Subject: drm/i915/cnl: Fix PLL mapping. On PLL Enable sequence we need to "Configure DPCLKA_CFGCR0 to turn on the clock for the DDI and map the DPLL to the DDI" So we first do the map and then we unset DDI_CLK_OFF to turn the clock on. We do this in 2 separated steps. However, on this second step where we should only unset the off bit we are also unmapping the ddi from the pll. So we end up using the pll 0 for almost everything. Consequently breaking cases with more than one display. Fixes: 555e38d27317 ("drm/i915/cnl: DDI - PLL mapping") Cc: Paulo Zanoni Cc: Manasi Navare Cc: Kahola, Mika Signed-off-by: Rodrigo Vivi Reviewed-by: James Ausmus Link: https://patchwork.freedesktop.org/patch/msgid/20171003220859.21352-2-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 8ef65941b8fd..adf51b328844 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2122,8 +2122,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, * register writes. */ val = I915_READ(DPCLKA_CFGCR0); - val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) | - DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port)); + val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port); I915_WRITE(DPCLKA_CFGCR0, val); } else if (IS_GEN9_BC(dev_priv)) { /* DDI -> PLL mapping */ -- cgit v1.2.3 From 614ee07acfbb55f2debfc3223ffae97fee17ed14 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 3 Oct 2017 15:08:59 -0700 Subject: drm/i915/cnl: Fix PLL initialization for HDMI. HDMI Mode selection on CNL is on CFGCR0 for that PLL, not on in a global CTRL1 as it was on SKL. The original patch addressed this difference, but leaving behind this single entry here. So we were checking the wrong bits during the PLL initialization and consequently avoiding the CFGCR1 setup during HDMI initialization. Luckly when only HDMI was in use BIOS had already setup this for us. But the dual display with hot plug were messed up. Fixes: a927c927de34 ("drm/i915/cnl: Initialize PLLs") Cc: Paulo Zanoni Cc: Manasi Navare Cc: Kahola, Mika Signed-off-by: Rodrigo Vivi Reviewed-by: James Ausmus Reviewed-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20171003220859.21352-3-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_dpll_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index a2a3d93d67bd..df808a94c511 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -1996,7 +1996,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, /* 3. Configure DPLL_CFGCR0 */ /* Avoid touch CFGCR1 if HDMI mode is not enabled */ - if (pll->state.hw_state.cfgcr0 & DPLL_CTRL1_HDMI_MODE(pll->id)) { + if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) { val = pll->state.hw_state.cfgcr1; I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val); /* 4. Reab back to ensure writes completed */ -- cgit v1.2.3 From 99b169d3c2052717a9a56b2c8aab0cabd96f0598 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 12 Oct 2017 13:57:24 +0100 Subject: drm/i915: Fix eviction when the GGTT is idle but full In the full-ppgtt world, we can fill the GGTT full of context objects. These context objects are currently implicitly tracked by the requests that pin them i.e. they are only unpinned when the request is completed and retired, but we do not have the link from the vma to the request (anymore). In order to unpin those contexts, we have to issue another request and wait upon the switch to the kernel context. The bug during eviction was that we assumed that a full GGTT meant we would have requests on the GGTT timeline, and so we missed situations where those requests where merely in flight (and when even they have not yet been submitted to hw yet). The fix employed here is to change the already-is-idle test to no look at the execution timeline, but count the outstanding requests and then check that we have switched to the kernel context. Erring on the side of overkill here just means that we stall a little longer than may be strictly required, but we only expect to hit this path in extreme corner cases where returning an erroneous error is worse than the delay. v2: Logical inversion when swapping over branches. Fixes: 80b204bce8f2 ("drm/i915: Enable multiple timelines") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20171012125726.14736-1-chris@chris-wilson.co.uk (cherry picked from commit 55b4f1ce2f23692c57205b9974fba61baa4b9321) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_gem_evict.c | 63 ++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 4df039ef2ce3..e161d383b526 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -33,21 +33,20 @@ #include "intel_drv.h" #include "i915_trace.h" -static bool ggtt_is_idle(struct drm_i915_private *dev_priv) +static bool ggtt_is_idle(struct drm_i915_private *i915) { - struct i915_ggtt *ggtt = &dev_priv->ggtt; - struct intel_engine_cs *engine; - enum intel_engine_id id; + struct intel_engine_cs *engine; + enum intel_engine_id id; - for_each_engine(engine, dev_priv, id) { - struct intel_timeline *tl; + if (i915->gt.active_requests) + return false; - tl = &ggtt->base.timeline.engine[engine->id]; - if (i915_gem_active_isset(&tl->last_request)) - return false; - } + for_each_engine(engine, i915, id) { + if (engine->last_retired_context != i915->kernel_context) + return false; + } - return true; + return true; } static int ggtt_flush(struct drm_i915_private *i915) @@ -157,7 +156,8 @@ i915_gem_evict_something(struct i915_address_space *vm, min_size, alignment, cache_level, start, end, mode); - /* Retire before we search the active list. Although we have + /* + * Retire before we search the active list. Although we have * reasonable accuracy in our retirement lists, we may have * a stray pin (preventing eviction) that can only be resolved by * retiring. @@ -182,7 +182,8 @@ search_again: BUG_ON(ret); } - /* Can we unpin some objects such as idle hw contents, + /* + * Can we unpin some objects such as idle hw contents, * or pending flips? But since only the GGTT has global entries * such as scanouts, rinbuffers and contexts, we can skip the * purge when inspecting per-process local address spaces. @@ -190,19 +191,33 @@ search_again: if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK) return -ENOSPC; - if (ggtt_is_idle(dev_priv)) { - /* If we still have pending pageflip completions, drop - * back to userspace to give our workqueues time to - * acquire our locks and unpin the old scanouts. - */ - return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC; - } + /* + * Not everything in the GGTT is tracked via VMA using + * i915_vma_move_to_active(), otherwise we could evict as required + * with minimal stalling. Instead we are forced to idle the GPU and + * explicitly retire outstanding requests which will then remove + * the pinning for active objects such as contexts and ring, + * enabling us to evict them on the next iteration. + * + * To ensure that all user contexts are evictable, we perform + * a switch to the perma-pinned kernel context. This all also gives + * us a termination condition, when the last retired context is + * the kernel's there is no more we can evict. + */ + if (!ggtt_is_idle(dev_priv)) { + ret = ggtt_flush(dev_priv); + if (ret) + return ret; - ret = ggtt_flush(dev_priv); - if (ret) - return ret; + goto search_again; + } - goto search_again; + /* + * If we still have pending pageflip completions, drop + * back to userspace to give our workqueues time to + * acquire our locks and unpin the old scanouts. + */ + return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC; found: /* drm_mm doesn't allow any other other operations while -- cgit v1.2.3 From fbe776cc3a753618877f7ce87a28ae3480743348 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Oct 2017 16:47:35 +0100 Subject: drm/i915: Use bdw_ddi_translations_fdi for Broadwell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compiler warns: drivers/gpu/drm/i915/intel_ddi.c:118:35: warning: ‘bdw_ddi_translations_fdi’ defined but not used Lo and behold, if we look at intel_ddi_get_buf_trans_fdi(), it uses hsw_ddi_translations_fdi[] for both Haswell and *Broadwell* Fixes: 7d1c42e679f9 ("drm/i915: Refactor code to select the DDI buf translation table") Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: David Weinehall Cc: Jani Nikula Cc: # v4.12+ Link: https://patchwork.freedesktop.org/patch/msgid/20171013154735.27163-1-chris@chris-wilson.co.uk Reviewed-by: Jani Nikula Reviewed-by: Ville Syrjälä (cherry picked from commit 1210d3889077653b90b0bfd2cc54e19f4766e4e6) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 476681d5940c..d4135e0ee723 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -664,8 +664,8 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv, int *n_entries) { if (IS_BROADWELL(dev_priv)) { - *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); - return hsw_ddi_translations_fdi; + *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi); + return bdw_ddi_translations_fdi; } else if (IS_HASWELL(dev_priv)) { *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); return hsw_ddi_translations_fdi; -- cgit v1.2.3 From 41e64c1ac73bbc2380d7b85357a4b693043a5ba8 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 3 Oct 2017 15:08:58 -0700 Subject: drm/i915/cnl: Fix PLL mapping. On PLL Enable sequence we need to "Configure DPCLKA_CFGCR0 to turn on the clock for the DDI and map the DPLL to the DDI" So we first do the map and then we unset DDI_CLK_OFF to turn the clock on. We do this in 2 separated steps. However, on this second step where we should only unset the off bit we are also unmapping the ddi from the pll. So we end up using the pll 0 for almost everything. Consequently breaking cases with more than one display. Fixes: 555e38d27317 ("drm/i915/cnl: DDI - PLL mapping") Cc: Paulo Zanoni Cc: Manasi Navare Cc: Kahola, Mika Signed-off-by: Rodrigo Vivi Reviewed-by: James Ausmus Link: https://patchwork.freedesktop.org/patch/msgid/20171003220859.21352-2-rodrigo.vivi@intel.com (cherry picked from commit 87145d95c3d8297fb74762bd92e022d7f5cc250c) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_ddi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index d4135e0ee723..5e5fe03b638c 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2102,8 +2102,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, * register writes. */ val = I915_READ(DPCLKA_CFGCR0); - val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) | - DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port)); + val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port); I915_WRITE(DPCLKA_CFGCR0, val); } else if (IS_GEN9_BC(dev_priv)) { /* DDI -> PLL mapping */ -- cgit v1.2.3 From 038daf5556a486cefc7a239ca4528003a5a4ef00 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 3 Oct 2017 15:08:59 -0700 Subject: drm/i915/cnl: Fix PLL initialization for HDMI. HDMI Mode selection on CNL is on CFGCR0 for that PLL, not on in a global CTRL1 as it was on SKL. The original patch addressed this difference, but leaving behind this single entry here. So we were checking the wrong bits during the PLL initialization and consequently avoiding the CFGCR1 setup during HDMI initialization. Luckly when only HDMI was in use BIOS had already setup this for us. But the dual display with hot plug were messed up. Fixes: a927c927de34 ("drm/i915/cnl: Initialize PLLs") Cc: Paulo Zanoni Cc: Manasi Navare Cc: Kahola, Mika Signed-off-by: Rodrigo Vivi Reviewed-by: James Ausmus Reviewed-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20171003220859.21352-3-rodrigo.vivi@intel.com (cherry picked from commit 614ee07acfbb55f2debfc3223ffae97fee17ed14) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_dpll_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index a2a3d93d67bd..df808a94c511 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -1996,7 +1996,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, /* 3. Configure DPLL_CFGCR0 */ /* Avoid touch CFGCR1 if HDMI mode is not enabled */ - if (pll->state.hw_state.cfgcr0 & DPLL_CTRL1_HDMI_MODE(pll->id)) { + if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) { val = pll->state.hw_state.cfgcr1; I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val); /* 4. Reab back to ensure writes completed */ -- cgit v1.2.3 From 40d86701a625eed9e644281b9af228d6a52d8ed9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 13 Oct 2017 00:52:01 +0100 Subject: drm/plane: drop num_overlay_planes (v3) In order to implement plane leasing we need to count things, just make the code consistent with the counting code currently used for counting crtcs/encoders/connectors and drop the need for num_overlay_planes. v2: don't forget to assign plane_ptr. (keithp) v3: use correct bounds check, found by igt. Reviewed-by: Daniel Vetter Reviewed-by: Sean Paul Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_mode_config.c | 1 - drivers/gpu/drm/drm_plane.c | 46 ++++++++++++++------------------------- include/drm/drm_mode_config.h | 13 ----------- 3 files changed, 16 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 74f6ff5df656..919e78d45ab0 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -385,7 +385,6 @@ void drm_mode_config_init(struct drm_device *dev) dev->mode_config.num_connector = 0; dev->mode_config.num_crtc = 0; dev->mode_config.num_encoder = 0; - dev->mode_config.num_overlay_plane = 0; dev->mode_config.num_total_plane = 0; } EXPORT_SYMBOL(drm_mode_config_init); diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 6af02c7b5da3..8090e50607fa 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -241,8 +241,6 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, list_add_tail(&plane->head, &config->plane_list); plane->index = config->num_total_plane++; - if (plane->type == DRM_PLANE_TYPE_OVERLAY) - config->num_overlay_plane++; drm_object_attach_property(&plane->base, config->plane_type_property, @@ -353,8 +351,6 @@ void drm_plane_cleanup(struct drm_plane *plane) list_del(&plane->head); dev->mode_config.num_total_plane--; - if (plane->type == DRM_PLANE_TYPE_OVERLAY) - dev->mode_config.num_overlay_plane--; WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); if (plane->state && plane->funcs->atomic_destroy_state) @@ -462,43 +458,33 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, struct drm_mode_config *config; struct drm_plane *plane; uint32_t __user *plane_ptr; - int copied = 0; - unsigned num_planes; + int count = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; config = &dev->mode_config; - - if (file_priv->universal_planes) - num_planes = config->num_total_plane; - else - num_planes = config->num_overlay_plane; + plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr); /* * This ioctl is called twice, once to determine how much space is * needed, and the 2nd time to fill it. */ - if (num_planes && - (plane_resp->count_planes >= num_planes)) { - plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; - - /* Plane lists are invariant, no locking needed. */ - drm_for_each_plane(plane, dev) { - /* - * Unless userspace set the 'universal planes' - * capability bit, only advertise overlays. - */ - if (plane->type != DRM_PLANE_TYPE_OVERLAY && - !file_priv->universal_planes) - continue; - - if (put_user(plane->base.id, plane_ptr + copied)) - return -EFAULT; - copied++; - } + drm_for_each_plane(plane, dev) { + /* + * Unless userspace set the 'universal planes' + * capability bit, only advertise overlays. + */ + if (plane->type != DRM_PLANE_TYPE_OVERLAY && + !file_priv->universal_planes) + continue; + + if (count < plane_resp->count_planes && + put_user(plane->base.id, plane_ptr + count)) + return -EFAULT; + count++; } - plane_resp->count_planes = num_planes; + plane_resp->count_planes = count; return 0; } diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 1b37368416c8..0b4ac2ebc610 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -429,19 +429,6 @@ struct drm_mode_config { */ struct list_head encoder_list; - /** - * @num_overlay_plane: - * - * Number of overlay planes on this device, excluding primary and cursor - * planes. - * - * Track number of overlay planes separately from number of total - * planes. By default we only advertise overlay planes to userspace; if - * userspace sets the "universal plane" capability bit, we'll go ahead - * and expose all planes. This is invariant over the lifetime of a - * device and hence doesn't need any locks. - */ - int num_overlay_plane; /** * @num_total_plane: * -- cgit v1.2.3 From ab31fd0ce65ec93828b617123792c1bb7c6dcc42 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Fri, 13 Oct 2017 15:40:07 +0200 Subject: scsi: zfcp: fix erp_action use-before-initialize in REC action trace v4.10 commit 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race with LUN recovery") extended accessing parent pointer fields of struct zfcp_erp_action for tracing. If an erp_action has never been enqueued before, these parent pointer fields are uninitialized and NULL. Examples are zfcp objects freshly added to the parent object's children list, before enqueueing their first recovery subsequently. In zfcp_erp_try_rport_unblock(), we iterate such list. Accessing erp_action fields can cause a NULL pointer dereference. Since the kernel can read from lowcore on s390, it does not immediately cause a kernel page fault. Instead it can cause hangs on trying to acquire the wrong erp_action->adapter->dbf->rec_lock in zfcp_dbf_rec_action_lvl() ^bogus^ while holding already other locks with IRQs disabled. Real life example from attaching lots of LUNs in parallel on many CPUs: crash> bt 17723 PID: 17723 TASK: ... CPU: 25 COMMAND: "zfcperp0.0.1800" LOWCORE INFO: -psw : 0x0404300180000000 0x000000000038e424 -function : _raw_spin_lock_wait_flags at 38e424 ... #0 [fdde8fc90] zfcp_dbf_rec_action_lvl at 3e0004e9862 [zfcp] #1 [fdde8fce8] zfcp_erp_try_rport_unblock at 3e0004dfddc [zfcp] #2 [fdde8fd38] zfcp_erp_strategy at 3e0004e0234 [zfcp] #3 [fdde8fda8] zfcp_erp_thread at 3e0004e0a12 [zfcp] #4 [fdde8fe60] kthread at 173550 #5 [fdde8feb8] kernel_thread_starter at 10add2 zfcp_adapter zfcp_port zfcp_unit
, 0x404040d600000000 scsi_device NULL, returning early! zfcp_scsi_dev.status = 0x40000000 0x40000000 ZFCP_STATUS_COMMON_RUNNING crash> zfcp_unit
struct zfcp_unit { erp_action = { adapter = 0x0, port = 0x0, unit = 0x0, }, } zfcp_erp_action is always fully embedded into its container object. Such container object is never moved in its object tree (only add or delete). Hence, erp_action parent pointers can never change. To fix the issue, initialize the erp_action parent pointers before adding the erp_action container to any list and thus before it becomes accessible from outside of its initializing function. In order to also close the time window between zfcp_erp_setup_act() memsetting the entire erp_action to zero and setting the parent pointers again, drop the memset and instead explicitly initialize individually all erp_action fields except for parent pointers. To be extra careful not to introduce any other unintended side effect, even keep zeroing the erp_action fields for list and timer. Also double-check with WARN_ON_ONCE that erp_action parent pointers never change, so we get to know when we would deviate from previous behavior. Signed-off-by: Steffen Maier Fixes: 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race with LUN recovery") Cc: #2.6.32+ Reviewed-by: Benjamin Block Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_aux.c | 5 +++++ drivers/s390/scsi/zfcp_erp.c | 18 +++++++++++------- drivers/s390/scsi/zfcp_scsi.c | 5 +++++ 3 files changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 82ac331d9125..84752152d41f 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -357,6 +357,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) adapter->next_port_scan = jiffies; + adapter->erp_action.adapter = adapter; + if (zfcp_qdio_setup(adapter)) goto failed; @@ -513,6 +515,9 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, port->dev.groups = zfcp_port_attr_groups; port->dev.release = zfcp_port_release; + port->erp_action.adapter = adapter; + port->erp_action.port = port; + if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { kfree(port); goto err_out; diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 37408f5f81ce..ec2532ee1822 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -193,9 +193,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, &zfcp_sdev->status); erp_action = &zfcp_sdev->erp_action; - memset(erp_action, 0, sizeof(struct zfcp_erp_action)); - erp_action->port = port; - erp_action->sdev = sdev; + WARN_ON_ONCE(erp_action->port != port); + WARN_ON_ONCE(erp_action->sdev != sdev); if (!(atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; @@ -208,8 +207,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, zfcp_erp_action_dismiss_port(port); atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); erp_action = &port->erp_action; - memset(erp_action, 0, sizeof(struct zfcp_erp_action)); - erp_action->port = port; + WARN_ON_ONCE(erp_action->port != port); + WARN_ON_ONCE(erp_action->sdev != NULL); if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; @@ -219,7 +218,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, zfcp_erp_action_dismiss_adapter(adapter); atomic_or(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); erp_action = &adapter->erp_action; - memset(erp_action, 0, sizeof(struct zfcp_erp_action)); + WARN_ON_ONCE(erp_action->port != NULL); + WARN_ON_ONCE(erp_action->sdev != NULL); if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; @@ -229,7 +229,11 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, return NULL; } - erp_action->adapter = adapter; + WARN_ON_ONCE(erp_action->adapter != adapter); + memset(&erp_action->list, 0, sizeof(erp_action->list)); + memset(&erp_action->timer, 0, sizeof(erp_action->timer)); + erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED; + erp_action->fsf_req_id = 0; erp_action->action = need; erp_action->status = act_status; diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index ec3ddd1d31d5..6cf8732627e0 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -115,10 +115,15 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) struct zfcp_unit *unit; int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE; + zfcp_sdev->erp_action.adapter = adapter; + zfcp_sdev->erp_action.sdev = sdev; + port = zfcp_get_port_by_wwpn(adapter, rport->port_name); if (!port) return -ENXIO; + zfcp_sdev->erp_action.port = port; + unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); if (unit) put_device(&unit->dev); -- cgit v1.2.3 From 1010f21ecf8ac43be676d498742de18fa6c20987 Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Mon, 16 Oct 2017 11:26:05 -0700 Subject: scsi: qla2xxx: Initialize Work element before requesting IRQs commit a9e170e28636 ("scsi: qla2xxx: Fix uninitialized work element") moved initializiation of work element earlier in the probe to fix call stack. However, it still leaves a window where interrupt can be generated before work element is initialized. Fix that window by initializing work element before we are requesting IRQs. [mkp: fixed typos] Fixes: a9e170e28636 ("scsi: qla2xxx: Fix uninitialized work element") Cc: # 4.13 Signed-off-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 937209805baf..3bd956d3bc5d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3061,6 +3061,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->max_cmd_len, host->max_channel, host->max_lun, host->transportt, sht->vendor_id); + INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); + /* Set up the irqs */ ret = qla2x00_request_irqs(ha, rsp); if (ret) @@ -3175,8 +3177,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->can_queue, base_vha->req, base_vha->mgmt_svr_loop_id, host->sg_tablesize); - INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); - if (ha->mqenable) { bool mq = false; bool startit = false; -- cgit v1.2.3 From c99dfd20f295b2b8c46da5185c0889493ba1f291 Mon Sep 17 00:00:00 2001 From: Christos Gkekas Date: Mon, 16 Oct 2017 20:28:02 +0100 Subject: scsi: hpsa: Fix configured_logical_drive_count·check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check whether configured_logical_drive_count is less than 255. Previous check was always evaluating to true as this variable is defined as u8. Signed-off-by: Christos Gkekas Acked-by: Don Brace --- drivers/scsi/hpsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 9abe81021484..4ed3d26ffdde 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -4091,7 +4091,7 @@ static int hpsa_set_local_logical_count(struct ctlr_info *h, memset(id_ctlr, 0, sizeof(*id_ctlr)); rc = hpsa_bmic_id_controller(h, id_ctlr, sizeof(*id_ctlr)); if (!rc) - if (id_ctlr->configured_logical_drive_count < 256) + if (id_ctlr->configured_logical_drive_count < 255) *nlocals = id_ctlr->configured_logical_drive_count; else *nlocals = le16_to_cpu( -- cgit v1.2.3 From 45348de2c8a7a1e64c5be27b22c9786b4152dd41 Mon Sep 17 00:00:00 2001 From: Raghava Aditya Renukunta Date: Mon, 16 Oct 2017 17:22:31 -0700 Subject: scsi: aacraid: Fix controller initialization failure This is a fix to an issue where the driver sends its periodic WELLNESS command to the controller after the driver shut it down.This causes the controller to crash. The window where this can happen is small, but it can be hit at around 4 hours of constant resets. Cc: Fixes: fbd185986eba (aacraid: Fix AIF triggered IOP_RESET) Signed-off-by: Raghava Aditya Renukunta Reviewed-by: Dave Carroll Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/comminit.c | 8 +++++--- drivers/scsi/aacraid/linit.c | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 97d269f16888..1bc623ad3faf 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -302,9 +302,11 @@ int aac_send_shutdown(struct aac_dev * dev) return -ENOMEM; aac_fib_init(fibctx); - mutex_lock(&dev->ioctl_mutex); - dev->adapter_shutdown = 1; - mutex_unlock(&dev->ioctl_mutex); + if (!dev->adapter_shutdown) { + mutex_lock(&dev->ioctl_mutex); + dev->adapter_shutdown = 1; + mutex_unlock(&dev->ioctl_mutex); + } cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 62beb2596466..c9252b138c1f 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1551,8 +1551,9 @@ static void __aac_shutdown(struct aac_dev * aac) { int i; + mutex_lock(&aac->ioctl_mutex); aac->adapter_shutdown = 1; - aac_send_shutdown(aac); + mutex_unlock(&aac->ioctl_mutex); if (aac->aif_thread) { int i; @@ -1565,7 +1566,11 @@ static void __aac_shutdown(struct aac_dev * aac) } kthread_stop(aac->thread); } + + aac_send_shutdown(aac); + aac_adapter_disable_int(aac); + if (aac_is_src(aac)) { if (aac->max_msix > 1) { for (i = 0; i < aac->max_msix; i++) { -- cgit v1.2.3 From ea7d0d69426cab6747ed311c53f4142eb48b9454 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 6 Oct 2017 17:45:27 +0300 Subject: xhci: Identify USB 3.1 capable hosts by their port protocol capability Many USB 3.1 capable hosts never updated the Serial Bus Release Number (SBRN) register to USB 3.1 from USB 3.0 xhci driver identified USB 3.1 capable hosts based on this SBRN register, which according to specs "contains the release of the Universal Serial Bus Specification with which this Universal Serial Bus Host Controller module is compliant." but still in october 2017 gives USB 3.0 as the only possible option. Make an additional check for USB 3.1 support and enable it if the xHCI supported protocol capablity lists USB 3.1 capable ports. Cc: # v4.6+ Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ee198ea47f49..51535ba2bcd4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4805,7 +4805,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) */ hcd->has_tt = 1; } else { - if (xhci->sbrn == 0x31) { + /* Some 3.1 hosts return sbrn 0x30, can't rely on sbrn alone */ + if (xhci->sbrn == 0x31 || xhci->usb3_rhub.min_rev >= 1) { xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n"); hcd->speed = HCD_USB31; hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; -- cgit v1.2.3 From d1aad52cf8b3f95dfe9b5b64da66343306ddf73b Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Fri, 6 Oct 2017 17:45:28 +0300 Subject: xhci: Cleanup current_cmd in xhci_cleanup_command_queue() KASAN reported use-after-free bug when xhci host controller died: [ 176.952537] BUG: KASAN: use-after-free in xhci_handle_command_timeout+0x68/0x224 [ 176.960846] Write of size 4 at addr ffffffc0cbb01608 by task kworker/3:3/1680 ... [ 177.180644] Freed by task 0: [ 177.183882] kasan_slab_free+0x90/0x15c [ 177.188194] kfree+0x114/0x28c [ 177.191630] xhci_cleanup_command_queue+0xc8/0xf8 [ 177.196916] xhci_hc_died+0x84/0x358 Problem here is that when the cmd_timer fired, it would try to access current_cmd while the command queue is already freed by xhci_hc_died(). Cleanup current_cmd in xhci_cleanup_command_queue() to avoid that. Fixes: d9f11ba9f107 ("xhci: Rework how we handle unresponsive or hoptlug removed hosts") Cc: # v4.12+ Signed-off-by: Jeffy Chen Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index a9443651ce0f..48ae15afa59e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1309,6 +1309,7 @@ static void xhci_complete_del_and_free_cmd(struct xhci_command *cmd, u32 status) void xhci_cleanup_command_queue(struct xhci_hcd *xhci) { struct xhci_command *cur_cmd, *tmp_cmd; + xhci->current_cmd = NULL; list_for_each_entry_safe(cur_cmd, tmp_cmd, &xhci->cmd_list, cmd_list) xhci_complete_del_and_free_cmd(cur_cmd, COMP_COMMAND_ABORTED); } -- cgit v1.2.3 From 810a624bd1b64b13ddcc2eb5c1880526a750a870 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Fri, 6 Oct 2017 17:45:29 +0300 Subject: usb: xhci: Reset halted endpoint if trb is noop When a URB is cancled, xhci driver turns the untransferred trbs into no-ops. If an endpoint stalls on a no-op trb that belongs to the cancelled URB, the event handler won't reset the endpoint. Hence, it will stay halted. Link: http://marc.info/?l=linux-usb&m=149582598330127&w=2 Cc: Signed-off-by: Lu Baolu Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 48ae15afa59e..82c746e2d85c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2580,15 +2580,21 @@ static int handle_tx_event(struct xhci_hcd *xhci, (struct xhci_generic_trb *) ep_trb); /* - * No-op TRB should not trigger interrupts. - * If ep_trb is a no-op TRB, it means the - * corresponding TD has been cancelled. Just ignore - * the TD. + * No-op TRB could trigger interrupts in a case where + * a URB was killed and a STALL_ERROR happens right + * after the endpoint ring stopped. Reset the halted + * endpoint. Otherwise, the endpoint remains stalled + * indefinitely. */ if (trb_is_noop(ep_trb)) { - xhci_dbg(xhci, - "ep_trb is a no-op TRB. Skip it for slot %u ep %u\n", - slot_id, ep_index); + if (trb_comp_code == COMP_STALL_ERROR || + xhci_requires_manual_halt_cleanup(xhci, ep_ctx, + trb_comp_code)) + xhci_cleanup_halted_endpoint(xhci, slot_id, + ep_index, + ep_ring->stream_id, + td, ep_trb, + EP_HARD_RESET); goto cleanup; } -- cgit v1.2.3 From b3207c65dfafae27e7c492cb9188c0dc0eeaf3fd Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Fri, 6 Oct 2017 17:45:30 +0300 Subject: usb: xhci: Handle error condition in xhci_stop_device() xhci_stop_device() calls xhci_queue_stop_endpoint() multiple times without checking the return value. xhci_queue_stop_endpoint() can return error if the HC is already halted or unable to queue commands. This can cause a deadlock condition as xhci_stop_device() would end up waiting indefinitely for a completion for the command that didn't get queued. Fix this by checking the return value and bailing out of xhci_stop_device() in case of error. This patch happens to fix potential memory leaks of the allocated command structures as well. Fixes: c311e391a7ef ("xhci: rework command timeout and cancellation,") Cc: Signed-off-by: Mayank Rana Signed-off-by: Jack Pham Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index da9158f171cb..a2336deb5e36 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -420,14 +420,25 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) GFP_NOWAIT); if (!command) { spin_unlock_irqrestore(&xhci->lock, flags); - xhci_free_command(xhci, cmd); - return -ENOMEM; + ret = -ENOMEM; + goto cmd_cleanup; + } + + ret = xhci_queue_stop_endpoint(xhci, command, slot_id, + i, suspend); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_free_command(xhci, command); + goto cmd_cleanup; } - xhci_queue_stop_endpoint(xhci, command, slot_id, i, - suspend); } } - xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); + ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + goto cmd_cleanup; + } + xhci_ring_cmd_db(xhci); spin_unlock_irqrestore(&xhci->lock, flags); @@ -439,6 +450,8 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n"); ret = -ETIME; } + +cmd_cleanup: xhci_free_command(xhci, cmd); return ret; } -- cgit v1.2.3 From 845d584f41eac3475c21e4a7d5e88d0f6e410cf7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 16 Oct 2017 16:21:19 +0200 Subject: USB: devio: Revert "USB: devio: Don't corrupt user memory" Taking the uurb->buffer_length userspace passes in as a maximum for the actual urbs transfer_buffer_length causes 2 serious issues: 1) It breaks isochronous support for all userspace apps using libusb, as existing libusb versions pass in 0 for uurb->buffer_length, relying on the kernel using the lenghts of the usbdevfs_iso_packet_desc descriptors passed in added together as buffer length. This for example causes redirection of USB audio and Webcam's into virtual machines using qemu-kvm to no longer work. This is a userspace ABI break and as such must be reverted. Note that the original commit does not protect other users / the kernels memory, it only stops the userspace process making the call from shooting itself in the foot. 2) It may cause the kernel to program host controllers to DMA over random memory. Just as the devio code used to only look at the iso_packet_desc lenghts, the host drivers do the same, relying on the submitter of the urbs to make sure the entire buffer is large enough and not checking transfer_buffer_length. But the "USB: devio: Don't corrupt user memory" commit now takes the userspace provided uurb->buffer_length for the buffer-size while copying over the user-provided iso_packet_desc lengths 1:1, allowing the user to specify a small buffer size while programming the host controller to dma a lot more data. (Atleast the ohci, uhci, xhci and fhci drivers do not check transfer_buffer_length for isoc transfers.) This reverts commit fa1ed74eb1c2 ("USB: devio: Don't corrupt user memory") fixing both these issues. Cc: Dan Carpenter Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4664e543cf2f..e9326f31db8d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1576,11 +1576,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb totlen += isopkt[u].length; } u *= sizeof(struct usb_iso_packet_descriptor); - if (totlen <= uurb->buffer_length) - uurb->buffer_length = totlen; - else - WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d", - totlen, uurb->buffer_length); + uurb->buffer_length = totlen; break; default: -- cgit v1.2.3 From 765fb2f181cad669f2beb87842a05d8071f2be85 Mon Sep 17 00:00:00 2001 From: Maksim Salau Date: Wed, 11 Oct 2017 11:10:52 +0300 Subject: usb: cdc_acm: Add quirk for Elatec TWN3 Elatec TWN3 has the union descriptor on data interface. This results in failure to bind the device to the driver with the following log: usb 1-1.2: new full speed USB device using streamplug-ehci and address 4 usb 1-1.2: New USB device found, idVendor=09d8, idProduct=0320 usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 1-1.2: Product: RFID Device (COM) usb 1-1.2: Manufacturer: OEM cdc_acm 1-1.2:1.0: Zero length descriptor references cdc_acm: probe of 1-1.2:1.0 failed with error -22 Adding the NO_UNION_NORMAL quirk for the device fixes the issue. `lsusb -v` of the device: Bus 001 Device 003: ID 09d8:0320 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 2 Communications bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x09d8 idProduct 0x0320 bcdDevice 3.00 iManufacturer 1 OEM iProduct 2 RFID Device (COM) iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 67 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 250mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 2 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 Unused bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 0 CDC Header: bcdCDC 1.10 CDC Call Management: bmCapabilities 0x03 call management use DataInterface bDataInterface 1 CDC ACM: bmCapabilities 0x06 sends break line coding and serial state CDC Union: bMasterInterface 0 bSlaveInterface 1 Device Status: 0x0000 (Bus Powered) Signed-off-by: Maksim Salau Acked-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 5e056064259c..18c923a4c16e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1832,6 +1832,9 @@ static const struct usb_device_id acm_ids[] = { { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ }, + { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ + .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ + }, { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ .driver_info = CLEAR_HALT_CONDITIONS, -- cgit v1.2.3 From 1d7765380f66648d979e33da92bbb49c64c12e61 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 13 Oct 2017 22:40:51 +0300 Subject: drm/i915: Remove mostly duplicated video DIP handling from PSR code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the infoframe hooks are part of the intel_dig_port, we can use the normal .write_infoframe() hook to update the VSC SDP. We do need to deal with the size difference between the VSC DIP and the others though. Another minor snag is that the compiler will complain to use if we keep using enum hdmi_infoframe_type type and passing in the DP define instead, so et's just change to unsigned int all over for the inforframe type. v2: Rebase due to other PSR changes Reviewed-by: Rodrigo Vivi Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171013194051.19286-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_hdmi.c | 26 ++++++++++++++++---------- drivers/gpu/drm/i915/intel_psr.c | 34 ++-------------------------------- 3 files changed, 19 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d61985f93d40..86eed3c7828b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1069,7 +1069,7 @@ struct intel_digital_port { void (*write_infoframe)(struct drm_encoder *encoder, const struct intel_crtc_state *crtc_state, - enum hdmi_infoframe_type type, + unsigned int type, const void *frame, ssize_t len); void (*set_infoframes)(struct drm_encoder *encoder, bool enable, diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index e6f8f30ce7bd..5132dc814788 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -70,7 +70,7 @@ static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector) return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base); } -static u32 g4x_infoframe_index(enum hdmi_infoframe_type type) +static u32 g4x_infoframe_index(unsigned int type) { switch (type) { case HDMI_INFOFRAME_TYPE_AVI: @@ -85,7 +85,7 @@ static u32 g4x_infoframe_index(enum hdmi_infoframe_type type) } } -static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type) +static u32 g4x_infoframe_enable(unsigned int type) { switch (type) { case HDMI_INFOFRAME_TYPE_AVI: @@ -100,9 +100,11 @@ static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type) } } -static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type) +static u32 hsw_infoframe_enable(unsigned int type) { switch (type) { + case DP_SDP_VSC: + return VIDEO_DIP_ENABLE_VSC_HSW; case HDMI_INFOFRAME_TYPE_AVI: return VIDEO_DIP_ENABLE_AVI_HSW; case HDMI_INFOFRAME_TYPE_SPD: @@ -118,10 +120,12 @@ static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type) static i915_reg_t hsw_dip_data_reg(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder, - enum hdmi_infoframe_type type, + unsigned int type, int i) { switch (type) { + case DP_SDP_VSC: + return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i); case HDMI_INFOFRAME_TYPE_AVI: return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i); case HDMI_INFOFRAME_TYPE_SPD: @@ -136,7 +140,7 @@ hsw_dip_data_reg(struct drm_i915_private *dev_priv, static void g4x_write_infoframe(struct drm_encoder *encoder, const struct intel_crtc_state *crtc_state, - enum hdmi_infoframe_type type, + unsigned int type, const void *frame, ssize_t len) { const uint32_t *data = frame; @@ -191,7 +195,7 @@ static bool g4x_infoframe_enabled(struct drm_encoder *encoder, static void ibx_write_infoframe(struct drm_encoder *encoder, const struct intel_crtc_state *crtc_state, - enum hdmi_infoframe_type type, + unsigned int type, const void *frame, ssize_t len) { const uint32_t *data = frame; @@ -251,7 +255,7 @@ static bool ibx_infoframe_enabled(struct drm_encoder *encoder, static void cpt_write_infoframe(struct drm_encoder *encoder, const struct intel_crtc_state *crtc_state, - enum hdmi_infoframe_type type, + unsigned int type, const void *frame, ssize_t len) { const uint32_t *data = frame; @@ -309,7 +313,7 @@ static bool cpt_infoframe_enabled(struct drm_encoder *encoder, static void vlv_write_infoframe(struct drm_encoder *encoder, const struct intel_crtc_state *crtc_state, - enum hdmi_infoframe_type type, + unsigned int type, const void *frame, ssize_t len) { const uint32_t *data = frame; @@ -368,7 +372,7 @@ static bool vlv_infoframe_enabled(struct drm_encoder *encoder, static void hsw_write_infoframe(struct drm_encoder *encoder, const struct intel_crtc_state *crtc_state, - enum hdmi_infoframe_type type, + unsigned int type, const void *frame, ssize_t len) { const uint32_t *data = frame; @@ -377,6 +381,8 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder); i915_reg_t data_reg; + int data_size = type == DP_SDP_VSC ? + VIDEO_DIP_VSC_DATA_SIZE : VIDEO_DIP_DATA_SIZE; int i; u32 val = I915_READ(ctl_reg); @@ -392,7 +398,7 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, data++; } /* Write every possible data byte to force correct ECC calculation. */ - for (; i < VIDEO_DIP_DATA_SIZE; i += 4) + for (; i < data_size; i += 4) I915_WRITE(hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2), 0); mmiowb(); diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 93b177cc4cbf..6e3b430fccdc 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -75,37 +75,6 @@ static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe) (val == VLV_EDP_PSR_ACTIVE_SF_UPDATE); } -static void intel_psr_write_vsc(struct intel_dp *intel_dp, - const struct edp_vsc_psr *vsc_psr) -{ - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); - enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; - i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder); - uint32_t *data = (uint32_t *) vsc_psr; - unsigned int i; - - /* As per BSPec (Pipe Video Data Island Packet), we need to disable - the video DIP being updated before program video DIP data buffer - registers for DIP being updated. */ - I915_WRITE(ctl_reg, 0); - POSTING_READ(ctl_reg); - - for (i = 0; i < sizeof(*vsc_psr); i += 4) { - I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, - i >> 2), *data); - data++; - } - for (; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) - I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, - i >> 2), 0); - - I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW); - POSTING_READ(ctl_reg); -} - static void vlv_psr_setup_vsc(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -152,7 +121,8 @@ static void hsw_psr_setup_vsc(struct intel_dp *intel_dp, psr_vsc.sdp_header.HB3 = 0x8; } - intel_psr_write_vsc(intel_dp, &psr_vsc); + intel_dig_port->write_infoframe(&intel_dig_port->base.base, crtc_state, + DP_SDP_VSC, &psr_vsc, sizeof(psr_vsc)); } static void vlv_psr_enable_sink(struct intel_dp *intel_dp) -- cgit v1.2.3 From 4f190e0b9de89c4c917c3ffb3799e9d00fc534ac Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 9 Oct 2017 22:46:07 -0500 Subject: USB: musb: fix session-bit runtime-PM quirk The current session-bit quirk implementation does not prevent the retry counter from underflowing, something which could break runtime PM and keep the device active for a very long time (about 2^32 seconds) after a disconnect. This notably breaks the B-device timeout case, but could potentially cause problems also when the controller is operating as an A-device. Fixes: 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect") Cc: stable # 4.9 Cc: Tony Lindgren Signed-off-by: Johan Hovold Tested-by: Tony Lindgren Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 029692053dd3..07b8c7152e3d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1861,22 +1861,22 @@ static void musb_pm_runtime_check_session(struct musb *musb) MUSB_DEVCTL_HR; switch (devctl & ~s) { case MUSB_QUIRK_B_INVALID_VBUS_91: - if (musb->quirk_retries--) { + if (musb->quirk_retries) { musb_dbg(musb, "Poll devctl on invalid vbus, assume no session"); schedule_delayed_work(&musb->irq_work, msecs_to_jiffies(1000)); - + musb->quirk_retries--; return; } /* fall through */ case MUSB_QUIRK_A_DISCONNECT_19: - if (musb->quirk_retries--) { + if (musb->quirk_retries) { musb_dbg(musb, "Poll devctl on possible host mode disconnect"); schedule_delayed_work(&musb->irq_work, msecs_to_jiffies(1000)); - + musb->quirk_retries--; return; } if (!musb->session) -- cgit v1.2.3 From 0c3aae9bd59978fb8c3557d7883380bef0f2cfa1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 9 Oct 2017 22:46:08 -0500 Subject: USB: musb: fix late external abort on suspend The musb delayed irq work was never flushed on suspend, something which since 4.9 can lead to an external abort if the work is scheduled after the grandparent's clock has been disabled: PM: Suspending system (mem) PM: suspend of devices complete after 125.224 msecs PM: suspend devices took 0.132 seconds PM: late suspend of devices complete after 7.423 msecs PM: noirq suspend of devices complete after 7.083 msecs suspend debug: Waiting for 5 second(s). Unhandled fault: external abort on non-linefetch (0x1008) at 0xd0262c60 ... [] (musb_default_readb) from [] (musb_irq_work+0x48/0x220) [] (musb_irq_work) from [] (process_one_work+0x1f4/0x758) [] (process_one_work) from [] (worker_thread+0x54/0x514) [] (worker_thread) from [] (kthread+0x128/0x158) [] (kthread) from [] (ret_from_fork+0x14/0x24) Commit 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect") started scheduling musb_irq_work with a delay of up to a second and with retries thereby making this easy to trigger, for example, by suspending shortly after a disconnect. Note that we set a flag to prevent the irq work from rescheduling itself during suspend and instead process a disconnect immediately. This takes care of the case where we are disconnected shortly before suspending. However, when in host mode, a disconnect while suspended will still go unnoticed and thus prevent the controller from runtime suspending upon resume as the session bit is always set. This will need to be addressed separately. Fixes: 550a7375fe72 ("USB: Add MUSB and TUSB support") Fixes: 467d5c980709 ("usb: musb: Implement session bit based runtime PM for musb-core") Fixes: 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect") Cc: stable # 4.9 Cc: Felipe Balbi Cc: Tony Lindgren Signed-off-by: Johan Hovold Tested-by: Tony Lindgren Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 11 +++++++++-- drivers/usb/musb/musb_core.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 07b8c7152e3d..1ced3af75b05 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1861,7 +1861,7 @@ static void musb_pm_runtime_check_session(struct musb *musb) MUSB_DEVCTL_HR; switch (devctl & ~s) { case MUSB_QUIRK_B_INVALID_VBUS_91: - if (musb->quirk_retries) { + if (musb->quirk_retries && !musb->flush_irq_work) { musb_dbg(musb, "Poll devctl on invalid vbus, assume no session"); schedule_delayed_work(&musb->irq_work, @@ -1871,7 +1871,7 @@ static void musb_pm_runtime_check_session(struct musb *musb) } /* fall through */ case MUSB_QUIRK_A_DISCONNECT_19: - if (musb->quirk_retries) { + if (musb->quirk_retries && !musb->flush_irq_work) { musb_dbg(musb, "Poll devctl on possible host mode disconnect"); schedule_delayed_work(&musb->irq_work, @@ -2681,8 +2681,15 @@ static int musb_suspend(struct device *dev) musb_platform_disable(musb); musb_disable_interrupts(musb); + + musb->flush_irq_work = true; + while (flush_delayed_work(&musb->irq_work)) + ; + musb->flush_irq_work = false; + if (!(musb->io.quirks & MUSB_PRESERVE_SESSION)) musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + WARN_ON(!list_empty(&musb->pending_list)); spin_lock_irqsave(&musb->lock, flags); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index c748f4ac1154..20f4614178d9 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -428,6 +428,8 @@ struct musb { unsigned test_mode:1; unsigned softconnect:1; + unsigned flush_irq_work:1; + u8 address; u8 test_mode_nr; u16 ackpend; /* ep0 */ -- cgit v1.2.3 From bfa53e0e366b98185fadb03f7916d1538cb90ebd Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Mon, 9 Oct 2017 22:46:09 -0500 Subject: usb: musb: musb_cppi41: Fix the address of teardown and autoreq registers The DA8xx and DSPS platforms don't use the same address for few registers. On Da8xx, this is causing some issues (e.g. teardown that doesn't work). Configure the address of the register during the init and use them instead of constants. Cc: stable@vger.kernel.org # v4.12+ Reported-by: nsekhar@ti.com Signed-off-by: Alexandre Bailon Tested-by: Sekhar Nori Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_cppi41.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index ba255280a624..d66416a27146 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -26,6 +26,9 @@ #define MUSB_DMA_NUM_CHANNELS 15 +#define DA8XX_USB_AUTOREQ 0x14 +#define DA8XX_USB_TEARDOWN 0x1c + struct cppi41_dma_controller { struct dma_controller controller; struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; @@ -35,6 +38,9 @@ struct cppi41_dma_controller { u32 rx_mode; u32 tx_mode; u32 auto_req; + + u32 tdown_reg; + u32 autoreq_reg; }; static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) @@ -364,8 +370,8 @@ static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel, if (new_mode == old_mode) return; controller->auto_req = new_mode; - musb_writel(controller->controller.musb->ctrl_base, USB_CTRL_AUTOREQ, - new_mode); + musb_writel(controller->controller.musb->ctrl_base, + controller->autoreq_reg, new_mode); } static bool cppi41_configure_channel(struct dma_channel *channel, @@ -581,12 +587,13 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) do { if (is_tx) - musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); + musb_writel(musb->ctrl_base, controller->tdown_reg, + tdbit); ret = dmaengine_terminate_all(cppi41_channel->dc); } while (ret == -EAGAIN); if (is_tx) { - musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); + musb_writel(musb->ctrl_base, controller->tdown_reg, tdbit); csr = musb_readw(epio, MUSB_TXCSR); if (csr & MUSB_TXCSR_TXPKTRDY) { @@ -727,6 +734,14 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base) controller->controller.is_compatible = cppi41_is_compatible; controller->controller.musb = musb; + if (musb->io.quirks & MUSB_DA8XX) { + controller->tdown_reg = DA8XX_USB_TEARDOWN; + controller->autoreq_reg = DA8XX_USB_AUTOREQ; + } else { + controller->tdown_reg = USB_TDOWN; + controller->autoreq_reg = USB_CTRL_AUTOREQ; + } + ret = cppi41_dma_controller_start(controller); if (ret) goto plat_get_fail; -- cgit v1.2.3 From e10c5b0c773efb8643ee89d387d310584ca30830 Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Mon, 9 Oct 2017 22:46:10 -0500 Subject: usb: musb: musb_cppi41: Fix cppi41_set_dma_mode() for DA8xx The way to configure the DMA mode on DA8xx is different from DSPS. Add a new function to configure DMA mode on DA8xx and use a callback to call the right function based on the platform. Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Alexandre Bailon Tested-by: Sekhar Nori Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_cppi41.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index d66416a27146..b2b1306c01cf 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -26,6 +26,7 @@ #define MUSB_DMA_NUM_CHANNELS 15 +#define DA8XX_USB_MODE 0x10 #define DA8XX_USB_AUTOREQ 0x14 #define DA8XX_USB_TEARDOWN 0x1c @@ -41,6 +42,9 @@ struct cppi41_dma_controller { u32 tdown_reg; u32 autoreq_reg; + + void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel, + unsigned int mode); }; static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) @@ -355,6 +359,32 @@ static void cppi41_set_dma_mode(struct cppi41_dma_channel *cppi41_channel, } } +static void da8xx_set_dma_mode(struct cppi41_dma_channel *cppi41_channel, + unsigned int mode) +{ + struct cppi41_dma_controller *controller = cppi41_channel->controller; + struct musb *musb = controller->controller.musb; + unsigned int shift; + u32 port; + u32 new_mode; + u32 old_mode; + + old_mode = controller->tx_mode; + port = cppi41_channel->port_num; + + shift = (port - 1) * 4; + if (!cppi41_channel->is_tx) + shift += 16; + new_mode = old_mode & ~(3 << shift); + new_mode |= mode << shift; + + if (new_mode == old_mode) + return; + controller->tx_mode = new_mode; + musb_writel(musb->ctrl_base, DA8XX_USB_MODE, new_mode); +} + + static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel, unsigned mode) { @@ -379,6 +409,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, dma_addr_t dma_addr, u32 len) { struct cppi41_dma_channel *cppi41_channel = channel->private_data; + struct cppi41_dma_controller *controller = cppi41_channel->controller; struct dma_chan *dc = cppi41_channel->dc; struct dma_async_tx_descriptor *dma_desc; enum dma_transfer_direction direction; @@ -404,7 +435,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, musb_writel(musb->ctrl_base, RNDIS_REG(cppi41_channel->port_num), len); /* gen rndis */ - cppi41_set_dma_mode(cppi41_channel, + controller->set_dma_mode(cppi41_channel, EP_MODE_DMA_GEN_RNDIS); /* auto req */ @@ -413,14 +444,15 @@ static bool cppi41_configure_channel(struct dma_channel *channel, } else { musb_writel(musb->ctrl_base, RNDIS_REG(cppi41_channel->port_num), 0); - cppi41_set_dma_mode(cppi41_channel, + controller->set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); } } else { /* fallback mode */ - cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); + controller->set_dma_mode(cppi41_channel, + EP_MODE_DMA_TRANSPARENT); cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); len = min_t(u32, packet_sz, len); } @@ -737,9 +769,11 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base) if (musb->io.quirks & MUSB_DA8XX) { controller->tdown_reg = DA8XX_USB_TEARDOWN; controller->autoreq_reg = DA8XX_USB_AUTOREQ; + controller->set_dma_mode = da8xx_set_dma_mode; } else { controller->tdown_reg = USB_TDOWN; controller->autoreq_reg = USB_CTRL_AUTOREQ; + controller->set_dma_mode = cppi41_set_dma_mode; } ret = cppi41_dma_controller_start(controller); -- cgit v1.2.3 From 297d7fe9e439473800ab1f2f853b4b5f8c888500 Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Mon, 9 Oct 2017 22:46:11 -0500 Subject: usb: musb: musb_cppi41: Configure the number of channels for DA8xx Currently, the number of channels is set to 15 but in the case of DA8xx, the number of channels is 4. Update the driver to configure the number of channels at runtime. Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Alexandre Bailon Tested-by: Sekhar Nori Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_cppi41.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index b2b1306c01cf..1ec0a4947b6b 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -30,10 +30,12 @@ #define DA8XX_USB_AUTOREQ 0x14 #define DA8XX_USB_TEARDOWN 0x1c +#define DA8XX_DMA_NUM_CHANNELS 4 + struct cppi41_dma_controller { struct dma_controller controller; - struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; - struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS]; + struct cppi41_dma_channel *rx_channel; + struct cppi41_dma_channel *tx_channel; struct hrtimer early_tx; struct list_head early_tx_list; u32 rx_mode; @@ -45,6 +47,7 @@ struct cppi41_dma_controller { void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel, unsigned int mode); + u8 num_channels; }; static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) @@ -483,7 +486,7 @@ static struct dma_channel *cppi41_dma_channel_allocate(struct dma_controller *c, struct cppi41_dma_channel *cppi41_channel = NULL; u8 ch_num = hw_ep->epnum - 1; - if (ch_num >= MUSB_DMA_NUM_CHANNELS) + if (ch_num >= controller->num_channels) return NULL; if (is_tx) @@ -643,7 +646,7 @@ static void cppi41_release_all_dma_chans(struct cppi41_dma_controller *ctrl) struct dma_chan *dc; int i; - for (i = 0; i < MUSB_DMA_NUM_CHANNELS; i++) { + for (i = 0; i < ctrl->num_channels; i++) { dc = ctrl->tx_channel[i].dc; if (dc) dma_release_channel(dc); @@ -695,7 +698,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) goto err; ret = -EINVAL; - if (port > MUSB_DMA_NUM_CHANNELS || !port) + if (port > controller->num_channels || !port) goto err; if (is_tx) cppi41_channel = &controller->tx_channel[port - 1]; @@ -736,6 +739,8 @@ void cppi41_dma_controller_destroy(struct dma_controller *c) hrtimer_cancel(&controller->early_tx); cppi41_dma_controller_stop(controller); + kfree(controller->rx_channel); + kfree(controller->tx_channel); kfree(controller); } EXPORT_SYMBOL_GPL(cppi41_dma_controller_destroy); @@ -744,6 +749,7 @@ struct dma_controller * cppi41_dma_controller_create(struct musb *musb, void __iomem *base) { struct cppi41_dma_controller *controller; + int channel_size; int ret = 0; if (!musb->controller->parent->of_node) { @@ -770,18 +776,33 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base) controller->tdown_reg = DA8XX_USB_TEARDOWN; controller->autoreq_reg = DA8XX_USB_AUTOREQ; controller->set_dma_mode = da8xx_set_dma_mode; + controller->num_channels = DA8XX_DMA_NUM_CHANNELS; } else { controller->tdown_reg = USB_TDOWN; controller->autoreq_reg = USB_CTRL_AUTOREQ; controller->set_dma_mode = cppi41_set_dma_mode; + controller->num_channels = MUSB_DMA_NUM_CHANNELS; } + channel_size = controller->num_channels * + sizeof(struct cppi41_dma_channel); + controller->rx_channel = kzalloc(channel_size, GFP_KERNEL); + if (!controller->rx_channel) + goto rx_channel_alloc_fail; + controller->tx_channel = kzalloc(channel_size, GFP_KERNEL); + if (!controller->tx_channel) + goto tx_channel_alloc_fail; + ret = cppi41_dma_controller_start(controller); if (ret) goto plat_get_fail; return &controller->controller; plat_get_fail: + kfree(controller->tx_channel); +tx_channel_alloc_fail: + kfree(controller->rx_channel); +rx_channel_alloc_fail: kfree(controller); kzalloc_fail: if (ret == -EPROBE_DEFER) -- cgit v1.2.3 From 445ef61543da3db5b699f87fb0aa4f227165f6ed Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Mon, 9 Oct 2017 22:46:12 -0500 Subject: usb: musb: Check for host-mode using is_host_active() on reset interrupt The sunxi musb has a bug where sometimes it will generate a babble error on device disconnect instead of a disconnect IRQ. When this happens the musb controller switches from host mode to device mode (it clears MUSB_DEVCTL_HM/MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and gets stuck in this state. The babble error is misdetected as a bus reset because MUSB_DEVCTL_HM was cleared. To fix this, use is_host_active() rather than (devctl & MUSB_DEVCTL_HM) to detect babble error so that sunxi musb babble recovery can handle it by restoring the mode. This information is provided by the driver logic and does not rely on register contents. Cc: stable@vger.kernel.org # v4.1+ Signed-off-by: Jonathan Liu Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 1ced3af75b05..ff5a1a8989d5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -906,7 +906,7 @@ b_host: */ if (int_usb & MUSB_INTR_RESET) { handled = IRQ_HANDLED; - if (devctl & MUSB_DEVCTL_HM) { + if (is_host_active(musb)) { /* * When BABBLE happens what we can depends on which * platform MUSB is running, because some platforms @@ -916,9 +916,7 @@ b_host: * drop the session. */ dev_err(musb->controller, "Babble\n"); - - if (is_host_active(musb)) - musb_recover_from_babble(musb); + musb_recover_from_babble(musb); } else { musb_dbg(musb, "BUS RESET as %s", usb_otg_state_string(musb->xceiv->otg->state)); -- cgit v1.2.3 From 6ed05c68cbcae42cd52b8e53b66952bfa9c002ce Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Mon, 9 Oct 2017 22:46:13 -0500 Subject: usb: musb: sunxi: Explicitly release USB PHY on exit This fixes a kernel oops when unloading the driver due to usb_put_phy being called after usb_phy_generic_unregister when the device is detached. Calling usb_phy_generic_unregister causes x->dev->driver to be NULL in usb_put_phy and results in a NULL pointer dereference. Cc: stable@vger.kernel.org # v4.3+ Signed-off-by: Jonathan Liu Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/sunxi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index c9a09b5bb6e5..dc353e24d53c 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -297,6 +297,8 @@ static int sunxi_musb_exit(struct musb *musb) if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags)) sunxi_sram_release(musb->controller->parent); + devm_usb_put_phy(glue->dev, glue->xceiv); + return 0; } -- cgit v1.2.3 From 2811501e6d8f5747d08f8e25b9ecf472d0dc4c7d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 3 Oct 2017 11:16:43 +0300 Subject: usb: quirks: add quirk for WORLDE MINI MIDI keyboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This keyboard doesn't implement Get String descriptors properly even though string indexes are valid. What happens is that when requesting for the String descriptor, the device disconnects and reconnects. Without this quirk, this loop will continue forever. Cc: Alan Stern Reported-by: Владимир Мартьянов Cc: stable Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 82806e311202..a6aaf2f193a4 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -221,6 +221,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* Corsair Strafe RGB */ { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, + /* MIDI keyboard WORLDE MINI */ + { USB_DEVICE(0x1c75, 0x0204), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Acer C120 LED Projector */ { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM }, -- cgit v1.2.3 From a6d65e451cc4e7127698384868a4447ee7be7d16 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Oct 2017 21:27:32 +0100 Subject: drm/i915: Report -EFAULT before pwrite fast path into shmemfs When pwriting into shmemfs, the fast path pagecache_write does not notice when it is writing to beyond the end of the truncated shmemfs inode. Report -EFAULT directly when we try to use pwrite into the !I915_MADV_WILLNEED object. Fixes: 7c55e2c5772d ("drm/i915: Use pagecache write to prepopulate shmemfs from pwrite-ioctl") Testcase: igt/gem_madvise/dontneed-before-pwrite Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Joonas Lahtinen Cc: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016202732.25459-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ee2a30422020..d699ea3ab80b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2730,6 +2730,9 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, if (i915_gem_object_has_pages(obj)) return -ENODEV; + if (obj->mm.madv != I915_MADV_WILLNEED) + return -EFAULT; + /* Before the pages are instantiated the object is treated as being * in the CPU domain. The pages will be clflushed as required before * use, and we can freely write into the pages directly. If userspace -- cgit v1.2.3 From 134649ff3545f3b7b862c589e9accb400ace2474 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Oct 2017 11:37:23 +0100 Subject: drm/i915/selftests: Silence the compiler for impossible errors It should be impossible for these tests not to run due to an empty ppgtt, but if it should happen, let's report ENODEV (our typical internal error for impossible events). In file included from drivers/gpu/drm/i915/i915_gem.c:5415: drivers/gpu/drm/i915/selftests/huge_pages.c: In function 'igt_mock_ppgtt_huge_fill': >> drivers/gpu/drm/i915/selftests/huge_pages.c:612: error: 'err' may be used uninitialized in this function drivers/gpu/drm/i915/selftests/huge_pages.c: In function 'igt_ppgtt_exhaust_huge': drivers/gpu/drm/i915/selftests/huge_pages.c:1159: error: 'err' may be used uninitialized in this function Reported-by: kbuild-all@01.org Signed-off-by: Chris Wilson Cc: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20171017103723.6933-1-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/selftests/huge_pages.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c index c53f8474113a..5cc8101bb2b1 100644 --- a/drivers/gpu/drm/i915/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c @@ -609,7 +609,7 @@ static int igt_mock_ppgtt_huge_fill(void *arg) bool single = false; LIST_HEAD(objects); IGT_TIMEOUT(end_time); - int err; + int err = -ENODEV; for_each_prime_number_from(page_num, 1, max_pages) { struct drm_i915_gem_object *obj; @@ -1157,7 +1157,7 @@ static int igt_ppgtt_exhaust_huge(void *arg) unsigned int size_mask; unsigned int page_mask; int n, i; - int err; + int err = -ENODEV; /* * Sanity check creating objects with a varying mix of page sizes -- -- cgit v1.2.3 From 091a4f91942a4396c67e5747f5cb38c6396d1fc5 Mon Sep 17 00:00:00 2001 From: James Ausmus Date: Fri, 13 Oct 2017 11:01:44 -0700 Subject: drm/i915: Handle drm-layer errors in intel_dp_add_mst_connector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make intel_dp_add_mst_connector handle error returns from the drm_ calls. Add intel_connector_free to support cleanup on the error path. v2: Rename new function to avoid confusion, and simplify error paths (Ville) v3: Indentation fixup, style fixes (Ville) v4: Clarify usage of intel_connector_free, and fix usage of intel_connector_free v5: Rebase Cc: Ville Syrjälä Signed-off-by: James Ausmus Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171013180144.15865-1-james.ausmus@intel.com --- drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++ drivers/gpu/drm/i915/intel_dp_mst.c | 27 +++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_drv.h | 1 + 3 files changed, 37 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9c5b489a1f63..3f38be07ee9c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6139,6 +6139,19 @@ struct intel_connector *intel_connector_alloc(void) return connector; } +/* + * Free the bits allocated by intel_connector_alloc. + * This should only be used after intel_connector_alloc has returned + * successfully, and before drm_connector_init returns successfully. + * Otherwise the destroy callbacks for the connector and the state should + * take care of proper cleanup/free + */ +void intel_connector_free(struct intel_connector *connector) +{ + kfree(to_intel_digital_connector_state(connector->base.state)); + kfree(connector); +} + /* Simple connector->get_hw_state implementation for encoders that support only * one connector and no cloning and hence the encoder state determines the state * of the connector. */ diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index f7c782576162..772521440a9f 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -458,13 +458,20 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo struct intel_connector *intel_connector; struct drm_connector *connector; enum pipe pipe; + int ret; intel_connector = intel_connector_alloc(); if (!intel_connector) return NULL; connector = &intel_connector->base; - drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); + ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort); + if (ret) { + intel_connector_free(intel_connector); + return NULL; + } + drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs); intel_connector->get_hw_state = intel_dp_mst_get_hw_state; @@ -472,15 +479,27 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo intel_connector->port = port; for_each_pipe(dev_priv, pipe) { - drm_mode_connector_attach_encoder(&intel_connector->base, - &intel_dp->mst_encoders[pipe]->base.base); + struct drm_encoder *enc = + &intel_dp->mst_encoders[pipe]->base.base; + + ret = drm_mode_connector_attach_encoder(&intel_connector->base, + enc); + if (ret) + goto err; } drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0); drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0); - drm_mode_connector_set_path_property(connector, pathprop); + ret = drm_mode_connector_set_path_property(connector, pathprop); + if (ret) + goto err; + return connector; + +err: + drm_connector_cleanup(connector); + return NULL; } static void intel_dp_register_mst_connector(struct drm_connector *connector) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 86eed3c7828b..8296df51408d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1363,6 +1363,7 @@ void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv); void intel_encoder_destroy(struct drm_encoder *encoder); int intel_connector_init(struct intel_connector *); struct intel_connector *intel_connector_alloc(void); +void intel_connector_free(struct intel_connector *connector); bool intel_connector_get_hw_state(struct intel_connector *connector); void intel_connector_attach_encoder(struct intel_connector *connector, struct intel_encoder *encoder); -- cgit v1.2.3 From 56ffc7427c2b0b27d732a15e062f0c7cdf62c173 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Tue, 17 Oct 2017 09:44:49 +0000 Subject: drm/i915/uc: Add pretty printer for uc firmware Debugfs for GuC and HuC load info have similar common part. Move and update dump of uc_fw to separate helper for reuse. Signed-off-by: Michal Wajdeczko Cc: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171017094449.22584-1-michal.wajdeczko@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 41 ++++++------------------------------- drivers/gpu/drm/i915/intel_uc_fw.c | 26 +++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uc_fw.h | 2 ++ 3 files changed, 34 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 40287e9f00d7..5dcc702942ec 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2359,27 +2359,13 @@ static int i915_llc(struct seq_file *m, void *data) static int i915_huc_load_status_info(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct intel_uc_fw *huc_fw = &dev_priv->huc.fw; + struct drm_printer p; if (!HAS_HUC_UCODE(dev_priv)) return 0; - seq_puts(m, "HuC firmware status:\n"); - seq_printf(m, "\tpath: %s\n", huc_fw->path); - seq_printf(m, "\tfetch: %s\n", - intel_uc_fw_status_repr(huc_fw->fetch_status)); - seq_printf(m, "\tload: %s\n", - intel_uc_fw_status_repr(huc_fw->load_status)); - seq_printf(m, "\tversion wanted: %d.%d\n", - huc_fw->major_ver_wanted, huc_fw->minor_ver_wanted); - seq_printf(m, "\tversion found: %d.%d\n", - huc_fw->major_ver_found, huc_fw->minor_ver_found); - seq_printf(m, "\theader: offset is %d; size = %d\n", - huc_fw->header_offset, huc_fw->header_size); - seq_printf(m, "\tuCode: offset is %d; size = %d\n", - huc_fw->ucode_offset, huc_fw->ucode_size); - seq_printf(m, "\tRSA: offset is %d; size = %d\n", - huc_fw->rsa_offset, huc_fw->rsa_size); + p = drm_seq_file_printer(m); + intel_uc_fw_dump(&dev_priv->huc.fw, &p); intel_runtime_pm_get(dev_priv); seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2)); @@ -2391,29 +2377,14 @@ static int i915_huc_load_status_info(struct seq_file *m, void *data) static int i915_guc_load_status_info(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; + struct drm_printer p; u32 tmp, i; if (!HAS_GUC_UCODE(dev_priv)) return 0; - seq_printf(m, "GuC firmware status:\n"); - seq_printf(m, "\tpath: %s\n", - guc_fw->path); - seq_printf(m, "\tfetch: %s\n", - intel_uc_fw_status_repr(guc_fw->fetch_status)); - seq_printf(m, "\tload: %s\n", - intel_uc_fw_status_repr(guc_fw->load_status)); - seq_printf(m, "\tversion wanted: %d.%d\n", - guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted); - seq_printf(m, "\tversion found: %d.%d\n", - guc_fw->major_ver_found, guc_fw->minor_ver_found); - seq_printf(m, "\theader: offset is %d; size = %d\n", - guc_fw->header_offset, guc_fw->header_size); - seq_printf(m, "\tuCode: offset is %d; size = %d\n", - guc_fw->ucode_offset, guc_fw->ucode_size); - seq_printf(m, "\tRSA: offset is %d; size = %d\n", - guc_fw->rsa_offset, guc_fw->rsa_size); + p = drm_seq_file_printer(m); + intel_uc_fw_dump(&dev_priv->guc.fw, &p); intel_runtime_pm_get(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c index 7bb0109bfbbd..973888e94cba 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/intel_uc_fw.c @@ -23,6 +23,7 @@ */ #include +#include #include "intel_uc_fw.h" #include "i915_drv.h" @@ -290,3 +291,28 @@ void intel_uc_fw_fini(struct intel_uc_fw *uc_fw) uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE; } + +/** + * intel_uc_fw_dump - dump information about uC firmware + * @uc_fw: uC firmware + * @p: the &drm_printer + * + * Pretty printer for uC firmware. + */ +void intel_uc_fw_dump(struct intel_uc_fw *uc_fw, struct drm_printer *p) +{ + drm_printf(p, "%s firmware: %s\n", + intel_uc_fw_type_repr(uc_fw->type), uc_fw->path); + drm_printf(p, "\tstatus: fetch %s, load %s\n", + intel_uc_fw_status_repr(uc_fw->fetch_status), + intel_uc_fw_status_repr(uc_fw->load_status)); + drm_printf(p, "\tversion: wanted %u.%u, found %u.%u\n", + uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted, + uc_fw->major_ver_found, uc_fw->minor_ver_found); + drm_printf(p, "\theader: offset %u, size %u\n", + uc_fw->header_offset, uc_fw->header_size); + drm_printf(p, "\tuCode: offset %u, size %u\n", + uc_fw->ucode_offset, uc_fw->ucode_size); + drm_printf(p, "\tRSA: offset %u, size %u\n", + uc_fw->rsa_offset, uc_fw->rsa_size); +} diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index 412fbdc4db93..132903669391 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h @@ -25,6 +25,7 @@ #ifndef _INTEL_UC_FW_H_ #define _INTEL_UC_FW_H_ +struct drm_printer; struct drm_i915_private; struct i915_vma; @@ -115,5 +116,6 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, int (*xfer)(struct intel_uc_fw *uc_fw, struct i915_vma *vma)); void intel_uc_fw_fini(struct intel_uc_fw *uc_fw); +void intel_uc_fw_dump(struct intel_uc_fw *uc_fw, struct drm_printer *p); #endif -- cgit v1.2.3 From 883b3b6567bfc8b5da7b3f0cec80513af111d2f5 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 16 Oct 2017 14:06:14 -0700 Subject: i2c: omap: Fix error handling for clk_get() Otherwise we can get the following if the fck alias is missing: Unable to handle kernel paging request at virtual address fffffffe ... PC is at clk_get_rate+0x8/0x10 LR is at omap_i2c_probe+0x278/0x6ec ... [] (clk_get_rate) from [] (omap_i2c_probe+0x278/0x6ec) [] (omap_i2c_probe) from [] (platform_drv_probe+0x50/0xb0) [] (platform_drv_probe) from [] (driver_probe_device+0x264/0x2ec) [] (driver_probe_device) from [] (bus_for_each_drv+0x70/0xb8) [] (bus_for_each_drv) from [] (__device_attach+0xcc/0x13c) [] (__device_attach) from [] (bus_probe_device+0x88/0x90) [] (bus_probe_device) from [] (deferred_probe_work_func+0x4c/0x14c) Signed-off-by: Tony Lindgren Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 1ebb5e947e0b..23c2ea2baedc 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -360,6 +360,7 @@ static int omap_i2c_init(struct omap_i2c_dev *omap) unsigned long fclk_rate = 12000000; unsigned long internal_clk = 0; struct clk *fclk; + int error; if (omap->rev >= OMAP_I2C_REV_ON_3430_3530) { /* @@ -378,6 +379,13 @@ static int omap_i2c_init(struct omap_i2c_dev *omap) * do this bit unconditionally. */ fclk = clk_get(omap->dev, "fck"); + if (IS_ERR(fclk)) { + error = PTR_ERR(fclk); + dev_err(omap->dev, "could not get fck: %i\n", error); + + return error; + } + fclk_rate = clk_get_rate(fclk); clk_put(fclk); @@ -410,6 +418,12 @@ static int omap_i2c_init(struct omap_i2c_dev *omap) else internal_clk = 4000; fclk = clk_get(omap->dev, "fck"); + if (IS_ERR(fclk)) { + error = PTR_ERR(fclk); + dev_err(omap->dev, "could not get fck: %i\n", error); + + return error; + } fclk_rate = clk_get_rate(fclk) / 1000; clk_put(fclk); -- cgit v1.2.3 From d6242aeb48d741eb7c1559cdb95d368de04466bd Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Tue, 17 Oct 2017 13:27:51 -0700 Subject: drm/i915: No need for RING_MAX_NONPRIV_SLOTS space Now that we write RING_FORCE_TO_NONPRIV registers directly to hardware, [commit 32ced39 ("drm/i915: Transform whitelisting WAs into a simple reg write")] there is no need to save space for them in the list of context workarounds. v2: Refer to previous commit in commit message (Michel) Signed-off-by: Oscar Mateo Cc: Chris Wilson Reviewed-by: Michel Thierry Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/1508272071-15125-1-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index dd141b250583..d31addb540ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1964,13 +1964,7 @@ struct i915_wa_reg { u32 mask; }; -/* - * RING_MAX_NONPRIV_SLOTS is per-engine but at this point we are only - * allowing it for RCS as we don't foresee any requirement of having - * a whitelist for other engines. When it is really required for - * other engines then the limit need to be increased. - */ -#define I915_MAX_WA_REGS (16 + RING_MAX_NONPRIV_SLOTS) +#define I915_MAX_WA_REGS 16 struct i915_workarounds { struct i915_wa_reg reg[I915_MAX_WA_REGS]; -- cgit v1.2.3 From 930a784d02339be437fec07b3bb7213bde0ed53b Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Tue, 17 Oct 2017 13:25:45 -0700 Subject: drm/i915: Use a mask when applying WaProgramL3SqcReg1Default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we are blasting other bits in GEN8_L3SQCREG1 that might be important (although we probably aren't at the moment because 0 seems to be the default for all the other bits). v2: Extra parentheses (Michel) Fixes: 050fc46 ("drm/i915:bxt: implement WaProgramL3SqcReg1DefaultForPerf") Fixes: 450174f ("drm/i915/chv: Tune L3 SQC credits based on actual latencies") Signed-off-by: Oscar Mateo Cc: Chris Wilson Cc: Mika Kuoppala Cc: Ville Syrjälä Cc: Imre Deak Reviewed-by: Michel Thierry Link: https://patchwork.freedesktop.org/patch/msgid/1508271945-14961-1-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_engine_cs.c | 9 ++++++--- drivers/gpu/drm/i915/intel_pm.c | 9 ++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5f99d4d6291b..68a58cce6ab1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7041,6 +7041,7 @@ enum { */ #define L3_GENERAL_PRIO_CREDITS(x) (((x) >> 1) << 19) #define L3_HIGH_PRIO_CREDITS(x) (((x) >> 1) << 14) +#define L3_PRIO_CREDITS_MASK ((0x1f << 19) | (0x1f << 14)) #define GEN7_L3CNTLREG1 _MMIO(0xB01C) #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 9a4c4abc7450..a47a9c6bea52 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1253,9 +1253,12 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine) } /* WaProgramL3SqcReg1DefaultForPerf:bxt */ - if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) - I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) | - L3_HIGH_PRIO_CREDITS(2)); + if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) { + u32 val = I915_READ(GEN8_L3SQCREG1); + val &= ~L3_PRIO_CREDITS_MASK; + val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2); + I915_WRITE(GEN8_L3SQCREG1, val); + } /* WaToEnableHwFixForPushConstHWBug:bxt */ if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER)) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ac4cf98030f9..c42a65a93b3a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -8484,14 +8484,17 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, int high_prio_credits) { u32 misccpctl; + u32 val; /* WaTempDisableDOPClkGating:bdw */ misccpctl = I915_READ(GEN7_MISCCPCTL); I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); - I915_WRITE(GEN8_L3SQCREG1, - L3_GENERAL_PRIO_CREDITS(general_prio_credits) | - L3_HIGH_PRIO_CREDITS(high_prio_credits)); + val = I915_READ(GEN8_L3SQCREG1); + val &= ~L3_PRIO_CREDITS_MASK; + val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits); + val |= L3_HIGH_PRIO_CREDITS(high_prio_credits); + I915_WRITE(GEN8_L3SQCREG1, val); /* * Wait at least 100 clocks before re-enabling clock gating. -- cgit v1.2.3 From 587c3c9f286cee5c9cac38d28c8ae1875f4ec85b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 15 Oct 2017 18:16:33 +0100 Subject: scsi: sg: Re-fix off by one in sg_fill_request_table() Commit 109bade9c625 ("scsi: sg: use standard lists for sg_requests") introduced an off-by-one error in sg_ioctl(), which was fixed by commit bd46fc406b30 ("scsi: sg: off by one in sg_ioctl()"). Unfortunately commit 4759df905a47 ("scsi: sg: factor out sg_fill_request_table()") moved that code, and reintroduced the bug (perhaps due to a botched rebase). Fix it again. Fixes: 4759df905a47 ("scsi: sg: factor out sg_fill_request_table()") Cc: stable@vger.kernel.org Signed-off-by: Ben Hutchings Acked-by: Douglas Gilbert Signed-off-by: Martin K. Petersen --- drivers/scsi/sg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 0419c2298eab..aa28874e8fb9 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -837,7 +837,7 @@ sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo) val = 0; list_for_each_entry(srp, &sfp->rq_list, entry) { - if (val > SG_MAX_QUEUE) + if (val >= SG_MAX_QUEUE) break; rinfo[val].req_state = srp->done + 1; rinfo[val].problem = -- cgit v1.2.3 From cb8d50dfb341e9615c8d203a3e6513dae9ff901d Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 17 Oct 2017 16:09:08 +0100 Subject: drm/i915: Fixup userptr mmu notifier registration error handling Avoid dereferencing the error pointer and also avoid returning NULL from i915_mmu_notifier_find since the callers do not expect that. Signed-off-by: Tvrtko Ursulin Reported-by: Dan Carpenter Fixes: 7741b547b6e0 ("drm/i915: Preallocate our mmu notifier workequeu to unbreak cpu hotplug deadlock") Cc: Dan Carpenter Cc: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171017150908.12840-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_userptr.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index cdc9be799eee..e26b23171b56 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -221,15 +221,17 @@ i915_mmu_notifier_find(struct i915_mm_struct *mm) /* Protected by mm_lock */ mm->mn = fetch_and_zero(&mn); } - } else { - /* someone else raced and successfully installed the mmu - * notifier, we can cancel our own errors */ + } else if (mm->mn) { + /* + * Someone else raced and successfully installed the mmu + * notifier, we can cancel our own errors. + */ err = 0; } mutex_unlock(&mm->i915->mm_lock); up_write(&mm->mm->mmap_sem); - if (mn) { + if (mn && !IS_ERR(mn)) { destroy_workqueue(mn->wq); kfree(mn); } -- cgit v1.2.3 From 8e9f8ab47588241ae5f85f24e82f75832de866bd Mon Sep 17 00:00:00 2001 From: Harsha Sharma Date: Sun, 15 Oct 2017 00:06:44 +0530 Subject: drm/i915: Replace *_reference/unreference() or *_ref/unref with _get/put() Replace instances of drm_framebuffer_reference/unreference() with *_get/put() suffixes and drm_dev_unref with *_put() suffix because get/put is shorter and consistent with the kernel use of *_get/put suffixes. Done with following coccinelle semantic patch @@ expression ex; @@ ( -drm_framebuffer_unreference(ex); +drm_framebuffer_put(ex); | -drm_dev_unref(ex); +drm_dev_put(ex); | -drm_framebuffer_reference(ex); +drm_framebuffer_get(ex); ) Signed-off-by: Harsha Sharma Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171014183644.21990-1-harshasharmaiitr@gmail.com --- drivers/gpu/drm/i915/i915_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index bf467f30c99b..1223961c3700 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -645,7 +645,7 @@ static void i915_pci_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev); i915_driver_unload(dev); - drm_dev_unref(dev); + drm_dev_put(dev); } static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.3 From d824c7a8e88a7162d14782e73a6a6c867a266500 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Fri, 13 Oct 2017 19:37:31 +0300 Subject: regulator: rn5t618: Do not index regulator_desc arrays by id The regulator_desc arrays in this driver are indexed by RN5T618_* constants and some elements can be missing. This causes probe failures on older models: rn5t618-regulator rn5t618-regulator: failed to register (null) regulator rn5t618-regulator: probe of rn5t618-regulator failed with error -22 Fix this by making the arrays flat. This also saves a little memory because the regulator_desc arrays become smaller. Signed-off-by: Leonard Crestez Fixes: 83b2a3c2ab24 ("regulator: rn5t618: add RC5T619 PMIC support") Signed-off-by: Mark Brown --- drivers/regulator/rn5t618-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c index ef2be56460fe..790a4a73ea2c 100644 --- a/drivers/regulator/rn5t618-regulator.c +++ b/drivers/regulator/rn5t618-regulator.c @@ -29,7 +29,7 @@ static const struct regulator_ops rn5t618_reg_ops = { }; #define REG(rid, ereg, emask, vreg, vmask, min, max, step) \ - [RN5T618_##rid] = { \ + { \ .name = #rid, \ .of_match = of_match_ptr(#rid), \ .regulators_node = of_match_ptr("regulators"), \ -- cgit v1.2.3 From d965465b60bad79d0b067f1009ba80ae76a6561a Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Mon, 16 Oct 2017 16:28:28 +0200 Subject: mlxsw: core: Fix possible deadlock When an EMAD is transmitted, a timeout work item is scheduled with a delay of 200ms, so that another EMAD will be retried until a maximum of five retries. In certain situations, it's possible for the function waiting on the EMAD to be associated with a work item that is queued on the same workqueue (`mlxsw_core`) as the timeout work item. This results in flushing a work item on the same workqueue. According to commit e159489baa71 ("workqueue: relax lockdep annotation on flush_work()") the above may lead to a deadlock in case the workqueue has only one worker active or if the system in under memory pressure and the rescue worker is in use. The latter explains the very rare and random nature of the lockdep splats we have been seeing: [ 52.730240] ============================================ [ 52.736179] WARNING: possible recursive locking detected [ 52.742119] 4.14.0-rc3jiri+ #4 Not tainted [ 52.746697] -------------------------------------------- [ 52.752635] kworker/1:3/599 is trying to acquire lock: [ 52.758378] (mlxsw_core_driver_name){+.+.}, at: [] flush_work+0x3a4/0x5e0 [ 52.767837] but task is already holding lock: [ 52.774360] (mlxsw_core_driver_name){+.+.}, at: [] process_one_work+0x7d4/0x12f0 [ 52.784495] other info that might help us debug this: [ 52.791794] Possible unsafe locking scenario: [ 52.798413] CPU0 [ 52.801144] ---- [ 52.803875] lock(mlxsw_core_driver_name); [ 52.808556] lock(mlxsw_core_driver_name); [ 52.813236] *** DEADLOCK *** [ 52.819857] May be due to missing lock nesting notation [ 52.827450] 3 locks held by kworker/1:3/599: [ 52.832221] #0: (mlxsw_core_driver_name){+.+.}, at: [] process_one_work+0x7d4/0x12f0 [ 52.842846] #1: ((&(&bridge->fdb_notify.dw)->work)){+.+.}, at: [] process_one_work+0x7d4/0x12f0 [ 52.854537] #2: (rtnl_mutex){+.+.}, at: [] rtnl_lock+0x17/0x20 [ 52.863021] stack backtrace: [ 52.867890] CPU: 1 PID: 599 Comm: kworker/1:3 Not tainted 4.14.0-rc3jiri+ #4 [ 52.875773] Hardware name: Mellanox Technologies Ltd. "MSN2100-CB2F"/"SA001017", BIOS 5.6.5 06/07/2016 [ 52.886267] Workqueue: mlxsw_core mlxsw_sp_fdb_notify_work [mlxsw_spectrum] [ 52.894060] Call Trace: [ 52.909122] __lock_acquire+0xf6f/0x2a10 [ 53.025412] lock_acquire+0x158/0x440 [ 53.047557] flush_work+0x3c4/0x5e0 [ 53.087571] __cancel_work_timer+0x3ca/0x5e0 [ 53.177051] cancel_delayed_work_sync+0x13/0x20 [ 53.182142] mlxsw_reg_trans_bulk_wait+0x12d/0x7a0 [mlxsw_core] [ 53.194571] mlxsw_core_reg_access+0x586/0x990 [mlxsw_core] [ 53.225365] mlxsw_reg_query+0x10/0x20 [mlxsw_core] [ 53.230882] mlxsw_sp_fdb_notify_work+0x2a3/0x9d0 [mlxsw_spectrum] [ 53.237801] process_one_work+0x8f1/0x12f0 [ 53.321804] worker_thread+0x1fd/0x10c0 [ 53.435158] kthread+0x28e/0x370 [ 53.448703] ret_from_fork+0x2a/0x40 [ 53.453017] mlxsw_spectrum 0000:01:00.0: EMAD retries (2/5) (tid=bf4549b100000774) [ 53.453119] mlxsw_spectrum 0000:01:00.0: EMAD retries (5/5) (tid=bf4549b100000770) [ 53.453132] mlxsw_spectrum 0000:01:00.0: EMAD reg access failed (tid=bf4549b100000770,reg_id=200b(sfn),type=query,status=0(operation performed)) [ 53.453143] mlxsw_spectrum 0000:01:00.0: Failed to get FDB notifications Fix this by creating another workqueue for EMAD timeouts, thereby preventing the situation of a work item trying to flush a work item queued on the same workqueue. Fixes: caf7297e7ab5f ("mlxsw: core: Introduce support for asynchronous EMAD register access") Signed-off-by: Ido Schimmel Reported-by: Jiri Pirko Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/core.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 9d5e7cf288be..f3315bc874ad 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -96,6 +96,7 @@ struct mlxsw_core { const struct mlxsw_bus *bus; void *bus_priv; const struct mlxsw_bus_info *bus_info; + struct workqueue_struct *emad_wq; struct list_head rx_listener_list; struct list_head event_listener_list; struct { @@ -465,7 +466,7 @@ static void mlxsw_emad_trans_timeout_schedule(struct mlxsw_reg_trans *trans) { unsigned long timeout = msecs_to_jiffies(MLXSW_EMAD_TIMEOUT_MS); - mlxsw_core_schedule_dw(&trans->timeout_dw, timeout); + queue_delayed_work(trans->core->emad_wq, &trans->timeout_dw, timeout); } static int mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core, @@ -587,12 +588,18 @@ static const struct mlxsw_listener mlxsw_emad_rx_listener = static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) { + struct workqueue_struct *emad_wq; u64 tid; int err; if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) return 0; + emad_wq = alloc_workqueue("mlxsw_core_emad", WQ_MEM_RECLAIM, 0); + if (!emad_wq) + return -ENOMEM; + mlxsw_core->emad_wq = emad_wq; + /* Set the upper 32 bits of the transaction ID field to a random * number. This allows us to discard EMADs addressed to other * devices. @@ -619,6 +626,7 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) err_emad_trap_set: mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, mlxsw_core); + destroy_workqueue(mlxsw_core->emad_wq); return err; } @@ -631,6 +639,7 @@ static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core) mlxsw_core->emad.use_emad = false; mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, mlxsw_core); + destroy_workqueue(mlxsw_core->emad_wq); } static struct sk_buff *mlxsw_emad_alloc(const struct mlxsw_core *mlxsw_core, -- cgit v1.2.3 From 2de09681e4ce8b1caa79d2e4482b72d8ef41c550 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Mon, 16 Oct 2017 10:02:11 -0500 Subject: ibmvnic: Fix calculation of number of TX header descriptors This patch correctly sets the number of additional header descriptors that will be sent in an indirect SCRQ entry. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index cb8182f4fdfa..c66abd476023 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1093,11 +1093,12 @@ static int build_hdr_data(u8 hdr_field, struct sk_buff *skb, * places them in a descriptor array, scrq_arr */ -static void create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len, - union sub_crq *scrq_arr) +static int create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len, + union sub_crq *scrq_arr) { union sub_crq hdr_desc; int tmp_len = len; + int num_descs = 0; u8 *data, *cur; int tmp; @@ -1126,7 +1127,10 @@ static void create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len, tmp_len -= tmp; *scrq_arr = hdr_desc; scrq_arr++; + num_descs++; } + + return num_descs; } /** @@ -1144,16 +1148,12 @@ static void build_hdr_descs_arr(struct ibmvnic_tx_buff *txbuff, int *num_entries, u8 hdr_field) { int hdr_len[3] = {0, 0, 0}; - int tot_len, len; + int tot_len; u8 *hdr_data = txbuff->hdr_data; tot_len = build_hdr_data(hdr_field, txbuff->skb, hdr_len, txbuff->hdr_data); - len = tot_len; - len -= 24; - if (len > 0) - num_entries += len % 29 ? len / 29 + 1 : len / 29; - create_hdr_descs(hdr_field, hdr_data, tot_len, hdr_len, + *num_entries += create_hdr_descs(hdr_field, hdr_data, tot_len, hdr_len, txbuff->indir_arr + 1); } -- cgit v1.2.3 From 39cbf2aa41b6d6e8d94b5506bf0e0e896ccf635a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 17 Oct 2017 09:53:04 +0300 Subject: drm/i915: Convert timers to use timer_setup() In preparation for unconditionally passing the struct timer_list pointer to all timer callbacks, switch to using the new timer_setup() and from_timer() to pass the timer pointer explicitly. Cc: Daniel Vetter Cc: Jani Nikula Cc: David Airlie Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Cc: Oscar Mateo Cc: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Kees Cook Reviewed-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171017065304.3358-1-joonas.lahtinen@linux.intel.com --- drivers/gpu/drm/i915/i915_sw_fence.c | 8 +++----- drivers/gpu/drm/i915/intel_breadcrumbs.c | 18 ++++++++---------- drivers/gpu/drm/i915/selftests/mock_engine.c | 8 +++----- 3 files changed, 14 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index ca33cc08cb07..e8ca67a129d2 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -369,9 +369,9 @@ struct i915_sw_dma_fence_cb { struct irq_work work; }; -static void timer_i915_sw_fence_wake(unsigned long data) +static void timer_i915_sw_fence_wake(struct timer_list *t) { - struct i915_sw_dma_fence_cb *cb = (struct i915_sw_dma_fence_cb *)data; + struct i915_sw_dma_fence_cb *cb = from_timer(cb, t, timer); struct i915_sw_fence *fence; fence = xchg(&cb->fence, NULL); @@ -434,9 +434,7 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, i915_sw_fence_await(fence); cb->dma = NULL; - __setup_timer(&cb->timer, - timer_i915_sw_fence_wake, (unsigned long)cb, - TIMER_IRQSAFE); + timer_setup(&cb->timer, timer_i915_sw_fence_wake, TIMER_IRQSAFE); init_irq_work(&cb->work, irq_i915_sw_fence_work); if (timeout) { cb->dma = dma_fence_get(dma); diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 29c62d481cef..48e1ba01ccf8 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -74,9 +74,10 @@ static noinline void missed_breadcrumb(struct intel_engine_cs *engine) set_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings); } -static void intel_breadcrumbs_hangcheck(unsigned long data) +static void intel_breadcrumbs_hangcheck(struct timer_list *t) { - struct intel_engine_cs *engine = (struct intel_engine_cs *)data; + struct intel_engine_cs *engine = from_timer(engine, t, + breadcrumbs.hangcheck); struct intel_breadcrumbs *b = &engine->breadcrumbs; if (!b->irq_armed) @@ -108,9 +109,10 @@ static void intel_breadcrumbs_hangcheck(unsigned long data) } } -static void intel_breadcrumbs_fake_irq(unsigned long data) +static void intel_breadcrumbs_fake_irq(struct timer_list *t) { - struct intel_engine_cs *engine = (struct intel_engine_cs *)data; + struct intel_engine_cs *engine = from_timer(engine, t, + breadcrumbs.fake_irq); struct intel_breadcrumbs *b = &engine->breadcrumbs; /* The timer persists in case we cannot enable interrupts, @@ -787,12 +789,8 @@ int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine) spin_lock_init(&b->rb_lock); spin_lock_init(&b->irq_lock); - setup_timer(&b->fake_irq, - intel_breadcrumbs_fake_irq, - (unsigned long)engine); - setup_timer(&b->hangcheck, - intel_breadcrumbs_hangcheck, - (unsigned long)engine); + timer_setup(&b->fake_irq, intel_breadcrumbs_fake_irq, 0); + timer_setup(&b->hangcheck, intel_breadcrumbs_hangcheck, 0); /* Spawn a thread to provide a common bottom-half for all signals. * As this is an asynchronous interface we cannot steal the current diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c index fc0fd7498689..331c2b09869e 100644 --- a/drivers/gpu/drm/i915/selftests/mock_engine.c +++ b/drivers/gpu/drm/i915/selftests/mock_engine.c @@ -32,9 +32,9 @@ static struct mock_request *first_request(struct mock_engine *engine) link); } -static void hw_delay_complete(unsigned long data) +static void hw_delay_complete(struct timer_list *t) { - struct mock_engine *engine = (typeof(engine))data; + struct mock_engine *engine = from_timer(engine, t, hw_delay); struct mock_request *request; spin_lock(&engine->hw_lock); @@ -161,9 +161,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, /* fake hw queue */ spin_lock_init(&engine->hw_lock); - setup_timer(&engine->hw_delay, - hw_delay_complete, - (unsigned long)engine); + timer_setup(&engine->hw_delay, hw_delay_complete, 0); INIT_LIST_HEAD(&engine->hw_queue); return &engine->base; -- cgit v1.2.3 From c97d96b4e612c7dc1b37d7afc61b598a9a25994d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Sun, 24 Sep 2017 15:20:49 +0100 Subject: staging: bcm2835-audio: Fix memory corruption The previous commit (0adbfd46) fixed a memory leak but also freed a block in the success case, causing a stale pointer to be used with potentially fatal results. Only free the vchi_instance block in the case that vchi_connect fails; once connected, the instance is retained for subsequent connections. Simplifying the code by removing a bunch of gotos and returning errors directly. Signed-off-by: Phil Elwell Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in bcm2835_audio_open_connection()") Cc: stable # 4.12+ Tested-by: Stefan Wahren Signed-off-by: Greg Kroah-Hartman --- .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 5f3d8f2339e3..4be864dbd41c 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream __func__, instance); instance->alsa_stream = alsa_stream; alsa_stream->instance = instance; - ret = 0; // xxx todo -1; - goto err_free_mem; + return 0; } /* Initialize and create a VCHI connection */ @@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", __func__, ret); - ret = -EIO; - goto err_free_mem; + return -EIO; } ret = vchi_connect(NULL, 0, vchi_instance); if (ret) { LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", __func__, ret); - ret = -EIO; - goto err_free_mem; + kfree(vchi_instance); + return -EIO; } initted = 1; } @@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream if (IS_ERR(instance)) { LOG_ERR("%s: failed to initialize audio service\n", __func__); - ret = PTR_ERR(instance); - goto err_free_mem; + /* vchi_instance is retained for use the next time. */ + return PTR_ERR(instance); } instance->alsa_stream = alsa_stream; alsa_stream->instance = instance; LOG_DBG(" success !\n"); - ret = 0; -err_free_mem: - kfree(vchi_instance); - return ret; + return 0; } int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) -- cgit v1.2.3 From bf0a5d4b223dfe523eb5191d0cb428f63cf04e2e Mon Sep 17 00:00:00 2001 From: Juha-Pekka Heikkila Date: Tue, 17 Oct 2017 23:08:07 +0300 Subject: drm/i915: move adjusted_x/y from crtc to cache. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move adjusted_x/y from crtc to fbc cache. Signed-off-by: Juha-Pekka Heikkila Link: https://patchwork.freedesktop.org/patch/msgid/1508270891-22186-2-git-send-email-juhapekka.heikkila@gmail.com [vsyrjala: Add rudimentary commit message] Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++ drivers/gpu/drm/i915/intel_display.c | 6 ------ drivers/gpu/drm/i915/intel_drv.h | 2 -- drivers/gpu/drm/i915/intel_fbc.c | 11 ++++++++--- 4 files changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d31addb540ad..835e2d27581e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1108,6 +1108,14 @@ struct intel_fbc { int src_w; int src_h; bool visible; + /* + * Display surface base address adjustement for + * pageflips. Note that on gen4+ this only adjusts up + * to a tile, offsets within a tile are handled in + * the hw itself (with the TILEOFF register). + */ + int adjusted_x; + int adjusted_y; } plane; struct { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 17a9a57cec58..ccbc7ff0577d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3306,9 +3306,6 @@ static void i9xx_update_primary_plane(struct intel_plane *primary, else crtc->dspaddr_offset = linear_offset; - crtc->adjusted_x = x; - crtc->adjusted_y = y; - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); if (INTEL_GEN(dev_priv) < 4) { @@ -3577,9 +3574,6 @@ static void skylake_update_primary_plane(struct intel_plane *plane, crtc->dspaddr_offset = surf_addr; - crtc->adjusted_x = src_x; - crtc->adjusted_y = src_y; - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8296df51408d..298986ff9634 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -812,8 +812,6 @@ struct intel_crtc { * gen4+ this only adjusts up to a tile, offsets within a tile are * handled in the hw itself (with the TILEOFF register). */ u32 dspaddr_offset; - int adjusted_x; - int adjusted_y; struct intel_crtc_state *config; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 8e3a05505f49..0ee65be50f18 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -71,7 +71,10 @@ static inline bool no_fbc_on_multiple_pipes(struct drm_i915_private *dev_priv) */ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc) { - return crtc->base.y - crtc->adjusted_y; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_fbc *fbc = &dev_priv->fbc; + + return crtc->base.y - fbc->state_cache.plane.adjusted_y; } /* @@ -727,8 +730,8 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) intel_fbc_get_plane_source_size(&fbc->state_cache, &effective_w, &effective_h); - effective_w += crtc->adjusted_x; - effective_h += crtc->adjusted_y; + effective_w += fbc->state_cache.plane.adjusted_x; + effective_h += fbc->state_cache.plane.adjusted_y; return effective_w <= max_w && effective_h <= max_h; } @@ -757,6 +760,8 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, cache->plane.src_w = drm_rect_width(&plane_state->base.src) >> 16; cache->plane.src_h = drm_rect_height(&plane_state->base.src) >> 16; cache->plane.visible = plane_state->base.visible; + cache->plane.adjusted_x = plane_state->main.x; + cache->plane.adjusted_y = plane_state->main.y; if (!cache->plane.visible) return; -- cgit v1.2.3 From e288881b08dc2627dda6f93ce1d406ba4dc0f143 Mon Sep 17 00:00:00 2001 From: Juha-Pekka Heikkila Date: Tue, 17 Oct 2017 23:08:08 +0300 Subject: drm/i915: dspaddr_offset doesn't need to be more than local variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move u32 dspaddr_offset from struct intel_crtc member into local variable in i9xx_update_primary_plane() Signed-off-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1508270891-22186-3-git-send-email-juhapekka.heikkila@gmail.com --- drivers/gpu/drm/i915/intel_display.c | 15 ++++++--------- drivers/gpu/drm/i915/intel_drv.h | 5 ----- 2 files changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ccbc7ff0577d..d468adb9cf82 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3289,7 +3289,6 @@ static void i9xx_update_primary_plane(struct intel_plane *primary, const struct intel_plane_state *plane_state) { struct drm_i915_private *dev_priv = to_i915(primary->base.dev); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); const struct drm_framebuffer *fb = plane_state->base.fb; enum plane plane = primary->plane; u32 linear_offset; @@ -3298,13 +3297,14 @@ static void i9xx_update_primary_plane(struct intel_plane *primary, int x = plane_state->main.x; int y = plane_state->main.y; unsigned long irqflags; + u32 dspaddr_offset; linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); if (INTEL_GEN(dev_priv) >= 4) - crtc->dspaddr_offset = plane_state->main.offset; + dspaddr_offset = plane_state->main.offset; else - crtc->dspaddr_offset = linear_offset; + dspaddr_offset = linear_offset; spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); @@ -3330,18 +3330,18 @@ static void i9xx_update_primary_plane(struct intel_plane *primary, if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { I915_WRITE_FW(DSPSURF(plane), intel_plane_ggtt_offset(plane_state) + - crtc->dspaddr_offset); + dspaddr_offset); I915_WRITE_FW(DSPOFFSET(plane), (y << 16) | x); } else if (INTEL_GEN(dev_priv) >= 4) { I915_WRITE_FW(DSPSURF(plane), intel_plane_ggtt_offset(plane_state) + - crtc->dspaddr_offset); + dspaddr_offset); I915_WRITE_FW(DSPTILEOFF(plane), (y << 16) | x); I915_WRITE_FW(DSPLINOFF(plane), linear_offset); } else { I915_WRITE_FW(DSPADDR(plane), intel_plane_ggtt_offset(plane_state) + - crtc->dspaddr_offset); + dspaddr_offset); } POSTING_READ_FW(reg); @@ -3546,7 +3546,6 @@ static void skylake_update_primary_plane(struct intel_plane *plane, const struct intel_plane_state *plane_state) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); const struct drm_framebuffer *fb = plane_state->base.fb; enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; @@ -3572,8 +3571,6 @@ static void skylake_update_primary_plane(struct intel_plane *plane, dst_w--; dst_h--; - crtc->dspaddr_offset = surf_addr; - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 298986ff9634..36133e4d2099 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -808,11 +808,6 @@ struct intel_crtc { unsigned long long enabled_power_domains; struct intel_overlay *overlay; - /* Display surface base address adjustement for pageflips. Note that on - * gen4+ this only adjusts up to a tile, offsets within a tile are - * handled in the hw itself (with the TILEOFF register). */ - u32 dspaddr_offset; - struct intel_crtc_state *config; /* global reset count when the last flip was submitted */ -- cgit v1.2.3 From 9a8cc576002aa4ad18edac6a6d4c46ea6eab416b Mon Sep 17 00:00:00 2001 From: Juha-Pekka Heikkila Date: Tue, 17 Oct 2017 23:08:09 +0300 Subject: drm/i915: Unify skylake plane update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't handle skylake primary plane separately as it is similar plane as the others. Signed-off-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1508270891-22186-4-git-send-email-juhapekka.heikkila@gmail.com --- drivers/gpu/drm/i915/intel_display.c | 75 +----------------------------------- drivers/gpu/drm/i915/intel_drv.h | 3 ++ drivers/gpu/drm/i915/intel_sprite.c | 2 +- 3 files changed, 6 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d468adb9cf82..42d0fdf2f70f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3541,77 +3541,6 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, return plane_ctl; } -static void skylake_update_primary_plane(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state) -{ - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - const struct drm_framebuffer *fb = plane_state->base.fb; - enum plane_id plane_id = plane->id; - enum pipe pipe = plane->pipe; - u32 plane_ctl = plane_state->ctl; - unsigned int rotation = plane_state->base.rotation; - u32 stride = skl_plane_stride(fb, 0, rotation); - u32 aux_stride = skl_plane_stride(fb, 1, rotation); - u32 surf_addr = plane_state->main.offset; - int scaler_id = plane_state->scaler_id; - int src_x = plane_state->main.x; - int src_y = plane_state->main.y; - int src_w = drm_rect_width(&plane_state->base.src) >> 16; - int src_h = drm_rect_height(&plane_state->base.src) >> 16; - int dst_x = plane_state->base.dst.x1; - int dst_y = plane_state->base.dst.y1; - int dst_w = drm_rect_width(&plane_state->base.dst); - int dst_h = drm_rect_height(&plane_state->base.dst); - unsigned long irqflags; - - /* Sizes are 0 based */ - src_w--; - src_h--; - dst_w--; - dst_h--; - - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); - - if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) { - I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), - PLANE_COLOR_PIPE_GAMMA_ENABLE | - PLANE_COLOR_PIPE_CSC_ENABLE | - PLANE_COLOR_PLANE_GAMMA_DISABLE); - } - - I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); - I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (src_y << 16) | src_x); - I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); - I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); - I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), - (plane_state->aux.offset - surf_addr) | aux_stride); - I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id), - (plane_state->aux.y << 16) | plane_state->aux.x); - - if (scaler_id >= 0) { - uint32_t ps_ctrl = 0; - - WARN_ON(!dst_w || !dst_h); - ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane_id) | - crtc_state->scaler_state.scalers[scaler_id].mode; - I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); - I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0); - I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y); - I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h); - I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0); - } else { - I915_WRITE_FW(PLANE_POS(pipe, plane_id), (dst_y << 16) | dst_x); - } - - I915_WRITE_FW(PLANE_SURF(pipe, plane_id), - intel_plane_ggtt_offset(plane_state) + surf_addr); - - POSTING_READ_FW(PLANE_SURF(pipe, plane_id)); - - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); -} - static void skylake_disable_primary_plane(struct intel_plane *primary, struct intel_crtc *crtc) { @@ -13284,7 +13213,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) num_formats = ARRAY_SIZE(skl_primary_formats); modifiers = skl_format_modifiers_ccs; - primary->update_plane = skylake_update_primary_plane; + primary->update_plane = skl_update_plane; primary->disable_plane = skylake_disable_primary_plane; } else if (INTEL_GEN(dev_priv) >= 9) { intel_primary_formats = skl_primary_formats; @@ -13294,7 +13223,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) else modifiers = skl_format_modifiers_noccs; - primary->update_plane = skylake_update_primary_plane; + primary->update_plane = skl_update_plane; primary->disable_plane = skylake_disable_primary_plane; } else if (INTEL_GEN(dev_priv) >= 4) { intel_primary_formats = i965_primary_formats; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 36133e4d2099..4d267c4edbea 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1922,6 +1922,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state); void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state); +void skl_update_plane(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state); /* intel_tv.c */ void intel_tv_init(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 86fc9b529f2d..c3583dc85d45 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -230,7 +230,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) #endif } -static void +void skl_update_plane(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) -- cgit v1.2.3 From 779d4d8f083e46364cc9b2c784cf8ad6ab3d3aa5 Mon Sep 17 00:00:00 2001 From: Juha-Pekka Heikkila Date: Tue, 17 Oct 2017 23:08:10 +0300 Subject: drm/i915: Unify skylake plane disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't handle skylake primary plane separately as it is similar plane as the others. Signed-off-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1508270891-22186-5-git-send-email-juhapekka.heikkila@gmail.com --- drivers/gpu/drm/i915/intel_display.c | 21 ++------------------- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_sprite.c | 2 +- 3 files changed, 4 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 42d0fdf2f70f..bd62c0a65bcd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3541,23 +3541,6 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, return plane_ctl; } -static void skylake_disable_primary_plane(struct intel_plane *primary, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(primary->base.dev); - enum plane_id plane_id = primary->id; - enum pipe pipe = primary->pipe; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); - - I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0); - I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0); - POSTING_READ_FW(PLANE_SURF(pipe, plane_id)); - - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); -} - static int __intel_display_resume(struct drm_device *dev, struct drm_atomic_state *state, @@ -13214,7 +13197,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) modifiers = skl_format_modifiers_ccs; primary->update_plane = skl_update_plane; - primary->disable_plane = skylake_disable_primary_plane; + primary->disable_plane = skl_disable_plane; } else if (INTEL_GEN(dev_priv) >= 9) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); @@ -13224,7 +13207,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) modifiers = skl_format_modifiers_noccs; primary->update_plane = skl_update_plane; - primary->disable_plane = skylake_disable_primary_plane; + primary->disable_plane = skl_disable_plane; } else if (INTEL_GEN(dev_priv) >= 4) { intel_primary_formats = i965_primary_formats; num_formats = ARRAY_SIZE(i965_primary_formats); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4d267c4edbea..a05ab3a1ab27 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1925,6 +1925,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state); void skl_update_plane(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); +void skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc); /* intel_tv.c */ void intel_tv_init(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index c3583dc85d45..4fcf80ca91dd 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -311,7 +311,7 @@ skl_update_plane(struct intel_plane *plane, spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); } -static void +void skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); -- cgit v1.2.3 From 31d1d3c8862e88c8db1b0c9a560f2a76b1a4972b Mon Sep 17 00:00:00 2001 From: Juha-Pekka Heikkila Date: Tue, 17 Oct 2017 23:08:11 +0300 Subject: drm/i915: adjust get_crtc_fence_y_offset() to use base.y instead of crtc.y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to use clipped y coordinate here. I left get_crtc_fence_y_offset() function itself in place as oneliner to maintain comment above it why this is done. Signed-off-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1508270891-22186-6-git-send-email-juhapekka.heikkila@gmail.com --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_fbc.c | 10 ++++------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 835e2d27581e..f01c80076c59 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1116,6 +1116,8 @@ struct intel_fbc { */ int adjusted_x; int adjusted_y; + + int y; } plane; struct { diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 0ee65be50f18..1a0f5e0c8d10 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -69,12 +69,9 @@ static inline bool no_fbc_on_multiple_pipes(struct drm_i915_private *dev_priv) * address we program because it starts at the real start of the buffer, so we * have to take this into consideration here. */ -static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc) +static unsigned int get_crtc_fence_y_offset(struct intel_fbc *fbc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_fbc *fbc = &dev_priv->fbc; - - return crtc->base.y - fbc->state_cache.plane.adjusted_y; + return fbc->state_cache.plane.y - fbc->state_cache.plane.adjusted_y; } /* @@ -762,6 +759,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, cache->plane.visible = plane_state->base.visible; cache->plane.adjusted_x = plane_state->main.x; cache->plane.adjusted_y = plane_state->main.y; + cache->plane.y = plane_state->base.src.y1 >> 16; if (!cache->plane.visible) return; @@ -893,7 +891,7 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, params->crtc.pipe = crtc->pipe; params->crtc.plane = crtc->plane; - params->crtc.fence_y_offset = get_crtc_fence_y_offset(crtc); + params->crtc.fence_y_offset = get_crtc_fence_y_offset(fbc); params->fb.format = cache->fb.format; params->fb.stride = cache->fb.stride; -- cgit v1.2.3 From b4a0b32d7a6024d9349fd464b3ae7a45048acd36 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 18 Oct 2017 13:16:21 +0100 Subject: drm/i915: Flush the idle-worker for debugfs/i915_drop_caches After being requested to idle the GPU, flush the idle worker to drop the residual active state, and any internal object caches. v2: By popular demand, introduce DROP_IDLE for fine-grained control from userspace, though it should be used as part of a DROP_ACTIVE | DROP_RETIRE | DROP_IDLE | DROP_FREED sequence. v3: Convert to BIT() to sell it to Joonas. References: https://bugs.freedesktop.org/show_bug.cgi?id=102655 Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171018121621.10824-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_debugfs.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5dcc702942ec..c65e381b85f3 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4179,18 +4179,20 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_ring_test_irq_fops, i915_ring_test_irq_get, i915_ring_test_irq_set, "0x%08llx\n"); -#define DROP_UNBOUND 0x1 -#define DROP_BOUND 0x2 -#define DROP_RETIRE 0x4 -#define DROP_ACTIVE 0x8 -#define DROP_FREED 0x10 -#define DROP_SHRINK_ALL 0x20 +#define DROP_UNBOUND BIT(0) +#define DROP_BOUND BIT(1) +#define DROP_RETIRE BIT(2) +#define DROP_ACTIVE BIT(3) +#define DROP_FREED BIT(4) +#define DROP_SHRINK_ALL BIT(5) +#define DROP_IDLE BIT(6) #define DROP_ALL (DROP_UNBOUND | \ DROP_BOUND | \ DROP_RETIRE | \ DROP_ACTIVE | \ DROP_FREED | \ - DROP_SHRINK_ALL) + DROP_SHRINK_ALL |\ + DROP_IDLE) static int i915_drop_caches_get(void *data, u64 *val) { @@ -4206,7 +4208,8 @@ i915_drop_caches_set(void *data, u64 val) struct drm_device *dev = &dev_priv->drm; int ret = 0; - DRM_DEBUG("Dropping caches: 0x%08llx\n", val); + DRM_DEBUG("Dropping caches: 0x%08llx [0x%08llx]\n", + val, val & DROP_ALL); /* No need to check and wait for gpu resets, only libdrm auto-restarts * on ioctls on -EAGAIN. */ @@ -4237,6 +4240,9 @@ i915_drop_caches_set(void *data, u64 val) i915_gem_shrink_all(dev_priv); fs_reclaim_release(GFP_KERNEL); + if (val & DROP_IDLE) + drain_delayed_work(&dev_priv->gt.idle_work); + if (val & DROP_FREED) { synchronize_rcu(); i915_gem_drain_freed_objects(dev_priv); -- cgit v1.2.3 From 1fd16f36be687ce32e875f59363c16d7cf050988 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Mon, 9 Oct 2017 16:35:12 -0400 Subject: drm/amd/amdgpu: Added asic_type as ACP DMA driver platform data asic_type information is passed to ACP DMA Driver as platform data. Reviewed-by: Alex Deucher Signed-off-by: Vijendar Mukunda Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index a52795d9b458..ebca22302ebb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -371,6 +371,8 @@ static int acp_hw_init(void *handle) adev->acp.acp_cell[0].name = "acp_audio_dma"; adev->acp.acp_cell[0].num_resources = 4; adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; + adev->acp.acp_cell[0].platform_data = &adev->asic_type; + adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); adev->acp.acp_cell[1].name = "designware-i2s"; adev->acp.acp_cell[1].num_resources = 1; -- cgit v1.2.3 From f674bd281460451e8784f3bc917a650e8937a8ed Mon Sep 17 00:00:00 2001 From: Akshu Agrawal Date: Wed, 28 Jun 2017 14:08:09 +0530 Subject: drm/amdgpu Moving amdgpu asic types to a separate file Amdgpu asic types will be required for other drivers too. Hence, its better to keep it in a separate include file. Reviewed-by: Alex Deucher Signed-off-by: Akshu Agrawal Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/amd_shared.h | 29 ++---------------- include/drm/amd_asic_type.h | 52 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 27 deletions(-) create mode 100644 include/drm/amd_asic_type.h (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 70e8c20acb2f..3a49fbd8baf8 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -23,34 +23,9 @@ #ifndef __AMD_SHARED_H__ #define __AMD_SHARED_H__ -#define AMD_MAX_USEC_TIMEOUT 200000 /* 200 ms */ +#include -/* - * Supported ASIC types - */ -enum amd_asic_type { - CHIP_TAHITI = 0, - CHIP_PITCAIRN, - CHIP_VERDE, - CHIP_OLAND, - CHIP_HAINAN, - CHIP_BONAIRE, - CHIP_KAVERI, - CHIP_KABINI, - CHIP_HAWAII, - CHIP_MULLINS, - CHIP_TOPAZ, - CHIP_TONGA, - CHIP_FIJI, - CHIP_CARRIZO, - CHIP_STONEY, - CHIP_POLARIS10, - CHIP_POLARIS11, - CHIP_POLARIS12, - CHIP_VEGA10, - CHIP_RAVEN, - CHIP_LAST, -}; +#define AMD_MAX_USEC_TIMEOUT 200000 /* 200 ms */ /* * Chip flags diff --git a/include/drm/amd_asic_type.h b/include/drm/amd_asic_type.h new file mode 100644 index 000000000000..599028f66585 --- /dev/null +++ b/include/drm/amd_asic_type.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + */ + +#ifndef __AMD_ASIC_TYPE_H__ +#define __AMD_ASIC_TYPE_H__ +/* + * Supported ASIC types + */ +enum amd_asic_type { + CHIP_TAHITI = 0, + CHIP_PITCAIRN, + CHIP_VERDE, + CHIP_OLAND, + CHIP_HAINAN, + CHIP_BONAIRE, + CHIP_KAVERI, + CHIP_KABINI, + CHIP_HAWAII, + CHIP_MULLINS, + CHIP_TOPAZ, + CHIP_TONGA, + CHIP_FIJI, + CHIP_CARRIZO, + CHIP_STONEY, + CHIP_POLARIS10, + CHIP_POLARIS11, + CHIP_POLARIS12, + CHIP_VEGA10, + CHIP_RAVEN, + CHIP_LAST, +}; + +#endif /*__AMD_ASIC_TYPE_H__ */ -- cgit v1.2.3 From ca8d7822054287352c41ff38f656e68fef959732 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Oct 2017 21:27:32 +0100 Subject: drm/i915: Report -EFAULT before pwrite fast path into shmemfs When pwriting into shmemfs, the fast path pagecache_write does not notice when it is writing to beyond the end of the truncated shmemfs inode. Report -EFAULT directly when we try to use pwrite into the !I915_MADV_WILLNEED object. Fixes: 7c55e2c5772d ("drm/i915: Use pagecache write to prepopulate shmemfs from pwrite-ioctl") Testcase: igt/gem_madvise/dontneed-before-pwrite Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Joonas Lahtinen Cc: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171016202732.25459-1-chris@chris-wilson.co.uk (cherry picked from commit a6d65e451cc4e7127698384868a4447ee7be7d16) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_gem.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index af289d35b77a..32e857dc507c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2657,6 +2657,9 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, if (READ_ONCE(obj->mm.pages)) return -ENODEV; + if (obj->mm.madv != I915_MADV_WILLNEED) + return -EFAULT; + /* Before the pages are instantiated the object is treated as being * in the CPU domain. The pages will be clflushed as required before * use, and we can freely write into the pages directly. If userspace -- cgit v1.2.3 From dd00ed9eff1e1819922f91da965f0e57e6a94216 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Tue, 17 Oct 2017 13:25:45 -0700 Subject: drm/i915: Use a mask when applying WaProgramL3SqcReg1Default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we are blasting other bits in GEN8_L3SQCREG1 that might be important (although we probably aren't at the moment because 0 seems to be the default for all the other bits). v2: Extra parentheses (Michel) Fixes: 050fc46 ("drm/i915:bxt: implement WaProgramL3SqcReg1DefaultForPerf") Fixes: 450174f ("drm/i915/chv: Tune L3 SQC credits based on actual latencies") Signed-off-by: Oscar Mateo Cc: Chris Wilson Cc: Mika Kuoppala Cc: Ville Syrjälä Cc: Imre Deak Reviewed-by: Michel Thierry Link: https://patchwork.freedesktop.org/patch/msgid/1508271945-14961-1-git-send-email-oscar.mateo@intel.com Signed-off-by: Chris Wilson (cherry picked from commit 930a784d02339be437fec07b3bb7213bde0ed53b) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_engine_cs.c | 9 ++++++--- drivers/gpu/drm/i915/intel_pm.c | 9 ++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ed7cd9ee2c2a..c9bcc6c45012 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6998,6 +6998,7 @@ enum { */ #define L3_GENERAL_PRIO_CREDITS(x) (((x) >> 1) << 19) #define L3_HIGH_PRIO_CREDITS(x) (((x) >> 1) << 14) +#define L3_PRIO_CREDITS_MASK ((0x1f << 19) | (0x1f << 14)) #define GEN7_L3CNTLREG1 _MMIO(0xB01C) #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 9ab596941372..3c2d9cf22ed5 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1048,9 +1048,12 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine) } /* WaProgramL3SqcReg1DefaultForPerf:bxt */ - if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) - I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) | - L3_HIGH_PRIO_CREDITS(2)); + if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) { + u32 val = I915_READ(GEN8_L3SQCREG1); + val &= ~L3_PRIO_CREDITS_MASK; + val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2); + I915_WRITE(GEN8_L3SQCREG1, val); + } /* WaToEnableHwFixForPushConstHWBug:bxt */ if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER)) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ed662937ec3c..0a09f8ff6aff 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -8245,14 +8245,17 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, int high_prio_credits) { u32 misccpctl; + u32 val; /* WaTempDisableDOPClkGating:bdw */ misccpctl = I915_READ(GEN7_MISCCPCTL); I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); - I915_WRITE(GEN8_L3SQCREG1, - L3_GENERAL_PRIO_CREDITS(general_prio_credits) | - L3_HIGH_PRIO_CREDITS(high_prio_credits)); + val = I915_READ(GEN8_L3SQCREG1); + val &= ~L3_PRIO_CREDITS_MASK; + val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits); + val |= L3_HIGH_PRIO_CREDITS(high_prio_credits); + I915_WRITE(GEN8_L3SQCREG1, val); /* * Wait at least 100 clocks before re-enabling clock gating. -- cgit v1.2.3 From c94501279bb191ccf204f496e9576ce036f81bcd Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 12 Oct 2017 13:08:48 -0400 Subject: Revert "drm/amdgpu: discard commands of killed processes" This causes instability in piglit. It's fixed in drm-next with: 515c6faf85970af529953ec137b4b6fcb3272e25 1650c14b459ff9c85767746f1ef795a780653128 214a91e6bfabaa6cbfa692df8732000aab050795 29d253553559dba919315be847f4f2cce29edd42 79867462634836ee5c39a2cdf624719feeb189bd This reverts commit 6af0883ed9770cf9b0a4f224c91481484cd1b025. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 97c94f9683fa..38cea6fb25a8 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -205,32 +205,17 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, struct amd_sched_entity *entity) { struct amd_sched_rq *rq = entity->rq; - int r; if (!amd_sched_entity_is_initialized(sched, entity)) return; + /** * The client will not queue more IBs during this fini, consume existing - * queued IBs or discard them on SIGKILL + * queued IBs */ - if ((current->flags & PF_SIGNALED) && current->exit_code == SIGKILL) - r = -ERESTARTSYS; - else - r = wait_event_killable(sched->job_scheduled, - amd_sched_entity_is_idle(entity)); - amd_sched_rq_remove_entity(rq, entity); - if (r) { - struct amd_sched_job *job; + wait_event(sched->job_scheduled, amd_sched_entity_is_idle(entity)); - /* Park the kernel for a moment to make sure it isn't processing - * our enity. - */ - kthread_park(sched->thread); - kthread_unpark(sched->thread); - while (kfifo_out(&entity->job_queue, &job, sizeof(job))) - sched->ops->free_job(job); - - } + amd_sched_rq_remove_entity(rq, entity); kfifo_free(&entity->job_queue); } -- cgit v1.2.3 From 1c0edc3633b56000e18d82fc241e3995ca18a69e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 18 Oct 2017 12:49:38 -0400 Subject: USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor() Andrey used the syzkaller fuzzer to find an out-of-bounds memory access in usb_get_bos_descriptor(). The code wasn't checking that the next usb_dev_cap_header structure could fit into the remaining buffer space. This patch fixes the error and also reduces the bNumDeviceCaps field in the header to match the actual number of capabilities found, in cases where there are fewer than expected. Reported-by: Andrey Konovalov Signed-off-by: Alan Stern Tested-by: Andrey Konovalov CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 68b54bd88d1e..883549ee946c 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -960,10 +960,12 @@ int usb_get_bos_descriptor(struct usb_device *dev) for (i = 0; i < num; i++) { buffer += length; cap = (struct usb_dev_cap_header *)buffer; - length = cap->bLength; - if (total_len < length) + if (total_len < sizeof(*cap) || total_len < cap->bLength) { + dev->bos->desc->bNumDeviceCaps = i; break; + } + length = cap->bLength; total_len -= length; if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { -- cgit v1.2.3 From 8a82dbf19129dde9e6fc9ab25a00dbc7569abe6a Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 9 Oct 2017 13:39:44 -0700 Subject: nvme-fc: fix iowait hang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing iowait head initialization. Fix irqsave vs irq: wait_event_lock_irq() doesn't do irq save/restore Fixes: 36715cf4b366 ("nvme_fc: replace ioabort msleep loop with completion”) Cc: # 4.13 Signed-off-by: James Smart Reviewed-by: Sagi Grimberg Reviewed-by: Himanshu Madhani Tested-by: Himanshu Madhani Signed-off-by: Christoph Hellwig --- drivers/nvme/host/fc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index af075e998944..8182b1999f49 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2545,10 +2545,10 @@ nvme_fc_delete_association(struct nvme_fc_ctrl *ctrl) nvme_fc_abort_aen_ops(ctrl); /* wait for all io that had to be aborted */ - spin_lock_irqsave(&ctrl->lock, flags); + spin_lock_irq(&ctrl->lock); wait_event_lock_irq(ctrl->ioabort_wait, ctrl->iocnt == 0, ctrl->lock); ctrl->flags &= ~FCCTRL_TERMIO; - spin_unlock_irqrestore(&ctrl->lock, flags); + spin_unlock_irq(&ctrl->lock); nvme_fc_term_aen_ops(ctrl); @@ -2760,6 +2760,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, ctrl->rport = rport; ctrl->dev = lport->dev; ctrl->cnum = idx; + init_waitqueue_head(&ctrl->ioabort_wait); get_device(ctrl->dev); kref_init(&ctrl->ref); -- cgit v1.2.3 From 17c4dc6eb7e1b2fb1ce6a52467e3be635224606e Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 9 Oct 2017 16:39:22 -0700 Subject: nvme-fc: retry initial controller connections 3 times Currently, if a frame is lost of command fails as part of initial association create for a new controller, the new controller connection request will immediately fail. Add in an immediate 3 retry loop before giving up. Signed-off-by: James Smart Signed-off-by: Christoph Hellwig --- drivers/nvme/host/fc.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 8182b1999f49..be49d0f79381 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2734,7 +2734,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, { struct nvme_fc_ctrl *ctrl; unsigned long flags; - int ret, idx; + int ret, idx, retry; if (!(rport->remoteport.port_role & (FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) { @@ -2826,9 +2826,37 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, list_add_tail(&ctrl->ctrl_list, &rport->ctrl_list); spin_unlock_irqrestore(&rport->lock, flags); - ret = nvme_fc_create_association(ctrl); + /* + * It's possible that transactions used to create the association + * may fail. Examples: CreateAssociation LS or CreateIOConnection + * LS gets dropped/corrupted/fails; or a frame gets dropped or a + * command times out for one of the actions to init the controller + * (Connect, Get/Set_Property, Set_Features, etc). Many of these + * transport errors (frame drop, LS failure) inherently must kill + * the association. The transport is coded so that any command used + * to create the association (prior to a LIVE state transition + * while NEW or RECONNECTING) will fail if it completes in error or + * times out. + * + * As such: as the connect request was mostly likely due to a + * udev event that discovered the remote port, meaning there is + * not an admin or script there to restart if the connect + * request fails, retry the initial connection creation up to + * three times before giving up and declaring failure. + */ + for (retry = 0; retry < 3; retry++) { + ret = nvme_fc_create_association(ctrl); + if (!ret) + break; + } + if (ret) { + /* couldn't schedule retry - fail out */ + dev_err(ctrl->ctrl.device, + "NVME-FC{%d}: Connect retry failed\n", ctrl->cnum); + ctrl->ctrl.opts = NULL; + /* initiate nvme ctrl ref counting teardown */ nvme_uninit_ctrl(&ctrl->ctrl); nvme_put_ctrl(&ctrl->ctrl); -- cgit v1.2.3 From 4813766325374af6ed0b66879ba6a0bbb05c83b6 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sat, 23 Sep 2017 13:10:33 -0700 Subject: drm/nouveau/fbcon: fix oops without fbdev emulation This is similar to an earlier commit 52dfcc5ccfbb ("drm/nouveau: fix for disabled fbdev emulation"), but protects all occurrences of helper.fbdev in the source. I see oops in nouveau_fbcon_accel_save_disable() called from nouveau_fbcon_set_suspend_work() on Linux 3.13 when CONFIG_DRM_FBDEV_EMULATION option is disabled. Signed-off-by: Pavel Roskin Reviewed-by: Daniel Vetter Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index f7707849bb53..2b12d82aac15 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -223,7 +223,7 @@ void nouveau_fbcon_accel_save_disable(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { + if (drm->fbcon && drm->fbcon->helper.fbdev) { drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags; drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; } @@ -233,7 +233,7 @@ void nouveau_fbcon_accel_restore(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { + if (drm->fbcon && drm->fbcon->helper.fbdev) { drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags; } } @@ -245,7 +245,8 @@ nouveau_fbcon_accel_fini(struct drm_device *dev) struct nouveau_fbdev *fbcon = drm->fbcon; if (fbcon && drm->channel) { console_lock(); - fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; + if (fbcon->helper.fbdev) + fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; console_unlock(); nouveau_channel_idle(drm->channel); nvif_object_fini(&fbcon->twod); -- cgit v1.2.3 From cf5dd48907bebaefdb43a8ca079be77e8da2cb20 Mon Sep 17 00:00:00 2001 From: Jeff Lance Date: Wed, 18 Oct 2017 17:25:52 -0700 Subject: Input: ti_am335x_tsc - fix incorrect step config for 5 wire touchscreen Step config setting for 5 wire touchscreen is incorrect for Y coordinates. It was broken while we moved to DT. If you look close at the offending commit bb76dc09ddfc ("input: ti_am33x_tsc: Order of TSC wires, made configurable"), the change was: - STEPCONFIG_XNP | STEPCONFIG_YPN; + ts_dev->bit_xn | ts_dev->bit_yp; while bit_xn = STEPCONFIG_XNN and bit_yp = STEPCONFIG_YNN. Not quite the same. Fixes: bb76dc09ddfc ("input: ti_am33x_tsc: Order of TSC wires, made configurable") Signed-off-by: Jeff Lance [vigneshr@ti.com: Rebase to v4.14-rc1] Signed-off-by: Vignesh R Reviewed-by: Michael Nazzareno Trimarchi Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ti_am335x_tsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 7953381d939a..f1043ae71dcc 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -161,7 +161,7 @@ static void titsc_step_config(struct titsc *ts_dev) break; case 5: config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | - ts_dev->bit_xn | ts_dev->bit_yp; + STEPCONFIG_XNP | STEPCONFIG_YPN; break; case 8: config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); -- cgit v1.2.3 From c9bfb2f0031a2de664147ebbfb90f95bb12fdf79 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 18 Oct 2017 17:28:36 -0700 Subject: Input: stmfts - fix setting ABS_MT_POSITION_* maximum size The commit 78bcac7b2ae1e ("Input: add support for the STMicroelectronics FingerTip touchscreen) used the 'touchscreen_parse_properties()' helper function in order to get the value of common properties. But, commit 78bcac7b2ae1e didn't set the capability of ABS_MT_POSITION_* before calling touchscreen_parse_properties(). In result, the max_x and max_y of 'struct touchscreen_properties' were not set. Fixes: 78bcac7b2ae1e ("Input: add support for the STMicroelectronics FingerTip touchscreen") Cc: stable@vger.kernel.org Signed-off-by: Chanwoo Choi Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/stmfts.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index 157fdb4bb2e8..8c6c6178ec12 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c @@ -663,12 +663,10 @@ static int stmfts_probe(struct i2c_client *client, sdata->input->open = stmfts_input_open; sdata->input->close = stmfts_input_close; + input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X); + input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y); touchscreen_parse_properties(sdata->input, true, &sdata->prop); - input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0, - sdata->prop.max_x, 0, 0); - input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0, - sdata->prop.max_y, 0, 0); input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0); -- cgit v1.2.3 From f9cf2a64912d67c9cf49c316a0a0ada0ea7ed1da Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 18 Oct 2017 14:33:59 -0700 Subject: nvmet: synchronize sqhd update In testing target io in read write mix, we did indeed get into cases where sqhd didn't update properly and slowly missed enough updates to shutdown the queue. Protect the updating sqhd by using cmpxchg, and for that turn the sqhd field into a u32 so that cmpxchg works on it for all architectures. Signed-off-by: James Smart Signed-off-by: Christoph Hellwig --- drivers/nvme/target/core.c | 15 ++++++++++++--- drivers/nvme/target/nvmet.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 1b208beeef50..645ba7eee35d 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -387,12 +387,21 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid) static void __nvmet_req_complete(struct nvmet_req *req, u16 status) { + u32 old_sqhd, new_sqhd; + u16 sqhd; + if (status) nvmet_set_status(req, status); - if (req->sq->size) - req->sq->sqhd = (req->sq->sqhd + 1) % req->sq->size; - req->rsp->sq_head = cpu_to_le16(req->sq->sqhd); + if (req->sq->size) { + do { + old_sqhd = req->sq->sqhd; + new_sqhd = (old_sqhd + 1) % req->sq->size; + } while (cmpxchg(&req->sq->sqhd, old_sqhd, new_sqhd) != + old_sqhd); + } + sqhd = req->sq->sqhd & 0x0000FFFF; + req->rsp->sq_head = cpu_to_le16(sqhd); req->rsp->sq_id = cpu_to_le16(req->sq->qid); req->rsp->command_id = req->cmd->common.command_id; diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 7b8e20adf760..87e429bfcd8a 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -74,7 +74,7 @@ struct nvmet_sq { struct percpu_ref ref; u16 qid; u16 size; - u16 sqhd; + u32 sqhd; struct completion free_done; struct completion confirm_done; }; -- cgit v1.2.3 From 1ac7db63333db1eeff901bfd6bbcd502b4634fa4 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 17 Oct 2017 16:07:33 +0300 Subject: usb: hub: Allow reset retry for USB2 devices on connect bounce If the connect status change is set during reset signaling, but the status remains connected just retry port reset. This solves an issue with connecting a 90W HP Thunderbolt 3 dock with a Lenovo Carbon x1 (5th generation) which causes a 30min loop of a high speed device being re-discovererd before usb ports starts working. [...] [ 389.023845] usb 3-1: new high-speed USB device number 55 using xhci_hcd [ 389.491841] usb 3-1: new high-speed USB device number 56 using xhci_hcd [ 389.959928] usb 3-1: new high-speed USB device number 57 using xhci_hcd [...] This is caused by a high speed device that doesn't successfully go to the enabled state after the second port reset. Instead the connection bounces (connected, with connect status change), bailing out completely from enumeration just to restart from scratch. Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1716332 Cc: Stable Signed-off-by: Mathias Nyman Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b5c733613823..e9ce6bb0b22d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2710,13 +2710,16 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, if (!(portstatus & USB_PORT_STAT_CONNECTION)) return -ENOTCONN; - /* bomb out completely if the connection bounced. A USB 3.0 - * connection may bounce if multiple warm resets were issued, + /* Retry if connect change is set but status is still connected. + * A USB 3.0 connection may bounce if multiple warm resets were issued, * but the device may have successfully re-connected. Ignore it. */ if (!hub_is_superspeed(hub->hdev) && - (portchange & USB_PORT_STAT_C_CONNECTION)) - return -ENOTCONN; + (portchange & USB_PORT_STAT_C_CONNECTION)) { + usb_clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_CONNECTION); + return -EAGAIN; + } if (!(portstatus & USB_PORT_STAT_ENABLE)) return -EBUSY; -- cgit v1.2.3 From 6afb10267c1692ada3a2903e31ea339917ad3ac0 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 2 Oct 2017 12:00:54 +0800 Subject: pinctrl/amd: fix masking of GPIO interrupts On Asus laptop models X505BA, X505BP, X542BA and X542BP, the i2c-hid touchpad (using a GPIO for interrupts) becomes unresponsive after a few minutes of usage, or after placing two fingers on the touchpad, which seems to have the effect of queuing up a large amount of input data to be transferred. When the touchpad is in unresponsive state, we observed that the GPIO level-triggered interrupt is still at it's active level, however the pinctrl-amd driver is not receiving/dispatching more interrupts at this point. After the initial interrupt arrives, amd_gpio_irq_mask() is called however we then see amd_gpio_irq_handler() being called repeatedly for the same irq; the interrupt mask is not taking effect because of the following sequence of events: - amd_gpio_irq_handler fires, reads and caches pin reg - amd_gpio_irq_handler calls generic_handle_irq() - During IRQ handling, amd_gpio_irq_mask() is called and modifies pin reg - amd_gpio_irq_handler clears interrupt by writing cached value The stale cached value written at the final stage undoes the masking. Fix this by re-reading the register before clearing the interrupt. I also spotted that the interrupt-clearing code can race against amd_gpio_irq_mask() / amd_gpio_irq_unmask(), so add locking there. Presumably this race was leading to the loss of interrupts. After these changes, the touchpad appears to be working fine. Signed-off-by: Daniel Drake Acked-by: Shah, Nehal-bakulchandra Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 3f6b34febbf1..433af328d981 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -534,8 +534,16 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) continue; irq = irq_find_mapping(gc->irqdomain, irqnr + i); generic_handle_irq(irq); - /* Clear interrupt */ + + /* Clear interrupt. + * We must read the pin register again, in case the + * value was changed while executing + * generic_handle_irq() above. + */ + raw_spin_lock_irqsave(&gpio_dev->lock, flags); + regval = readl(regs + i); writel(regval, regs + i); + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); ret = IRQ_HANDLED; } } -- cgit v1.2.3 From 59861701076b0cfac0b5eaa67a380fff6ab85b9e Mon Sep 17 00:00:00 2001 From: Dmitry Mastykin Date: Wed, 18 Oct 2017 17:21:02 +0300 Subject: pinctrl: mcp23s08: fix interrupt handling regression interrupt handling was broken with conversion to using regmap caching. cached_gpio value was updated by boolean status instead of gpio reading. Fixes: 8f38910ba4f6 ("pinctrl: mcp23s08: switch to regmap caching") Tested-by: Phil Reid Signed-off-by: Dmitry Mastykin Reviewed-by: Sebastian Reichel Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mcp23s08.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 3e40d4245512..9c950bbf07ba 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -407,10 +407,10 @@ static int mcp23s08_get(struct gpio_chip *chip, unsigned offset) ret = mcp_read(mcp, MCP_GPIO, &status); if (ret < 0) status = 0; - else + else { + mcp->cached_gpio = status; status = !!(status & (1 << offset)); - - mcp->cached_gpio = status; + } mutex_unlock(&mcp->lock); return status; -- cgit v1.2.3 From ad2302345d59d29232cb668baaae9e840925d153 Mon Sep 17 00:00:00 2001 From: "ZHU Yi (ST-FIR/ENG1-Zhu)" Date: Fri, 15 Sep 2017 06:59:15 +0000 Subject: can: flexcan: fix state transition regression Update state upon any interrupt to report correct state transitions in case the flexcan core enabled the broken error state quirk fix. Signed-off-by: Zhu Yi Signed-off-by: Mark Jonas Acked-by: Wolfgang Grandegger Cc: linux-stable # >= v4.11 Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 13f0f219d8aa..df4bfb83024c 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -765,8 +765,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); } - /* state change interrupt */ - if (reg_esr & FLEXCAN_ESR_ERR_STATE) + /* state change interrupt or broken error state quirk fix is enabled */ + if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || + (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE)) flexcan_irq_state(dev, reg_esr); /* bus error IRQ - handle if bus error reporting is activated */ -- cgit v1.2.3 From 2f8639b24b4f4f9dd6cf7c1f2aea90e2fcbcc451 Mon Sep 17 00:00:00 2001 From: "ZHU Yi (ST-FIR/ENG1-Zhu)" Date: Fri, 15 Sep 2017 07:01:23 +0000 Subject: can: flexcan: rename legacy error state quirk Rename FLEXCAN_QUIRK_BROKEN_ERR_STATE to FLEXCAN_QUIRK_BROKEN_WERR_STATE for better description of the missing [TR]WRN_INT quirk. Signed-off-by: Zhu Yi Signed-off-by: Mark Jonas Acked-by: Wolfgang Grandegger Cc: linux-stable # >= v4.11 Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index df4bfb83024c..e163c55e737b 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -193,7 +193,7 @@ * * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. */ -#define FLEXCAN_QUIRK_BROKEN_ERR_STATE BIT(1) /* [TR]WRN_INT not connected */ +#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT not connected */ #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */ #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */ #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ @@ -281,7 +281,7 @@ struct flexcan_priv { }; static const struct flexcan_devtype_data fsl_p1010_devtype_data = { - .quirks = FLEXCAN_QUIRK_BROKEN_ERR_STATE, + .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE, }; static const struct flexcan_devtype_data fsl_imx28_devtype_data; @@ -767,7 +767,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) /* state change interrupt or broken error state quirk fix is enabled */ if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || - (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE)) + (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE)) flexcan_irq_state(dev, reg_esr); /* bus error IRQ - handle if bus error reporting is activated */ @@ -888,7 +888,7 @@ static int flexcan_chip_start(struct net_device *dev) * on most Flexcan cores, too. Otherwise we don't get * any error warning or passive interrupts. */ - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE || + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE || priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; else -- cgit v1.2.3 From da49a8075c00b4d98ef069a0ee201177a8b79ead Mon Sep 17 00:00:00 2001 From: "ZHU Yi (ST-FIR/ENG1-Zhu)" Date: Fri, 15 Sep 2017 07:03:58 +0000 Subject: can: flexcan: implement error passive state quirk Add FLEXCAN_QUIRK_BROKEN_PERR_STATE for better description of the missing error passive interrupt quirk. Error interrupt flooding may happen if the broken error state quirk fix is enabled. For example, in case there is singled out node on the bus and the node sends a frame, then error interrupt flooding happens and will not stop because the node cannot go to bus off. The flooding will stop after another node connected to the bus again. If high bitrate configured on the low end system, then the flooding may causes performance issue, hence, this patch mitigates this by: 1. disable error interrupt upon error passive state transition 2. re-enable error interrupt upon error warning state transition 3. disable/enable error interrupt upon error active state transition depends on FLEXCAN_QUIRK_BROKEN_WERR_STATE In this way, the driver is still able to report correct state transitions without additional latency. When there are bus problems, flooding of error interrupts is limited to the number of frames required to change state from error warning to error passive if the core has [TR]WRN_INT connected (FLEXCAN_QUIRK_BROKEN_WERR_STATE is not enabled), otherwise, the flooding is limited to the number of frames required to change state from error active to error passive. Signed-off-by: Zhu Yi Signed-off-by: Mark Jonas Acked-by: Wolfgang Grandegger Cc: linux-stable # >= v4.11 Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 75 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index e163c55e737b..c83a09fa4166 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -182,14 +182,14 @@ /* FLEXCAN hardware feature flags * * Below is some version info we got: - * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err RTR re- - * Filter? connected? detection ception in MB - * MX25 FlexCAN2 03.00.00.00 no no no no - * MX28 FlexCAN2 03.00.04.00 yes yes no no - * MX35 FlexCAN2 03.00.00.00 no no no no - * MX53 FlexCAN2 03.00.00.00 yes no no no - * MX6s FlexCAN3 10.00.12.00 yes yes no yes - * VF610 FlexCAN3 ? no yes yes yes? + * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re- + * Filter? connected? Passive detection ception in MB + * MX25 FlexCAN2 03.00.00.00 no no ? no no + * MX28 FlexCAN2 03.00.04.00 yes yes no no no + * MX35 FlexCAN2 03.00.00.00 no no ? no no + * MX53 FlexCAN2 03.00.00.00 yes no no no no + * MX6s FlexCAN3 10.00.12.00 yes yes no no yes + * VF610 FlexCAN3 ? no yes ? yes yes? * * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. */ @@ -198,6 +198,7 @@ #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */ #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ +#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ /* Structure of the message buffer */ struct flexcan_mb { @@ -335,6 +336,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr) } #endif +static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) +{ + struct flexcan_regs __iomem *regs = priv->regs; + u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK); + + flexcan_write(reg_ctrl, ®s->ctrl); +} + +static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) +{ + struct flexcan_regs __iomem *regs = priv->regs; + u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); + + flexcan_write(reg_ctrl, ®s->ctrl); +} + static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) { if (!priv->reg_xceiver) @@ -713,6 +730,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) struct flexcan_regs __iomem *regs = priv->regs; irqreturn_t handled = IRQ_NONE; u32 reg_iflag1, reg_esr; + enum can_state last_state = priv->can.state; reg_iflag1 = flexcan_read(®s->iflag1); @@ -767,7 +785,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) /* state change interrupt or broken error state quirk fix is enabled */ if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || - (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE)) + (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | + FLEXCAN_QUIRK_BROKEN_PERR_STATE))) flexcan_irq_state(dev, reg_esr); /* bus error IRQ - handle if bus error reporting is activated */ @@ -775,6 +794,44 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) flexcan_irq_bus_err(dev, reg_esr); + /* availability of error interrupt among state transitions in case + * bus error reporting is de-activated and + * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled: + * +--------------------------------------------------------------+ + * | +----------------------------------------------+ [stopped / | + * | | | sleeping] -+ + * +-+-> active <-> warning <-> passive -> bus off -+ + * ___________^^^^^^^^^^^^_______________________________ + * disabled(1) enabled disabled + * + * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled + */ + if ((last_state != priv->can.state) && + (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) && + !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { + switch (priv->can.state) { + case CAN_STATE_ERROR_ACTIVE: + if (priv->devtype_data->quirks & + FLEXCAN_QUIRK_BROKEN_WERR_STATE) + flexcan_error_irq_enable(priv); + else + flexcan_error_irq_disable(priv); + break; + + case CAN_STATE_ERROR_WARNING: + flexcan_error_irq_enable(priv); + break; + + case CAN_STATE_ERROR_PASSIVE: + case CAN_STATE_BUS_OFF: + flexcan_error_irq_disable(priv); + break; + + default: + break; + } + } + return handled; } -- cgit v1.2.3 From cf9c04677f2bf599b44511963039ec6e25583feb Mon Sep 17 00:00:00 2001 From: "ZHU Yi (ST-FIR/ENG1-Zhu)" Date: Fri, 15 Sep 2017 07:05:50 +0000 Subject: can: flexcan: fix i.MX6 state transition issue Enable FLEXCAN_QUIRK_BROKEN_PERR_STATE for i.MX6 to report correct state transitions. Signed-off-by: Zhu Yi Signed-off-by: Mark Jonas Acked-by: Wolfgang Grandegger Cc: linux-stable # >= v4.11 Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index c83a09fa4166..d6ad12744ff1 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -289,7 +289,7 @@ static const struct flexcan_devtype_data fsl_imx28_devtype_data; static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | - FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, + FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE, }; static const struct flexcan_devtype_data fsl_vf610_devtype_data = { -- cgit v1.2.3 From 083c5571290a2d4308b75f1a59cf376b6e907808 Mon Sep 17 00:00:00 2001 From: "ZHU Yi (ST-FIR/ENG1-Zhu)" Date: Fri, 15 Sep 2017 07:08:23 +0000 Subject: can: flexcan: fix i.MX28 state transition issue Enable FLEXCAN_QUIRK_BROKEN_PERR_STATE for i.MX28 to report correct state transitions, especially to error passive. Signed-off-by: Wolfgang Grandegger Signed-off-by: Zhu Yi Signed-off-by: Mark Jonas Cc: linux-stable # >= v4.11 Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index d6ad12744ff1..ed544c44848f 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -285,7 +285,9 @@ static const struct flexcan_devtype_data fsl_p1010_devtype_data = { .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE, }; -static const struct flexcan_devtype_data fsl_imx28_devtype_data; +static const struct flexcan_devtype_data fsl_imx28_devtype_data = { + .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE, +}; static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | -- cgit v1.2.3 From fb5b91d61bebc24686ffc379138fd67808b1a1e6 Mon Sep 17 00:00:00 2001 From: "ZHU Yi (ST-FIR/ENG1-Zhu)" Date: Fri, 15 Sep 2017 07:09:37 +0000 Subject: can: flexcan: fix p1010 state transition issue Enable FLEXCAN_QUIRK_BROKEN_WERR_STATE and FLEXCAN_QUIRK_BROKEN_PERR_STATE for p1010 to report correct state transitions. Signed-off-by: Zhu Yi Signed-off-by: Mark Jonas Acked-by: Wolfgang Grandegger Cc: linux-stable # >= v4.11 Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index ed544c44848f..a13a4896a8bd 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -282,7 +282,8 @@ struct flexcan_priv { }; static const struct flexcan_devtype_data fsl_p1010_devtype_data = { - .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE, + .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | + FLEXCAN_QUIRK_BROKEN_PERR_STATE, }; static const struct flexcan_devtype_data fsl_imx28_devtype_data = { -- cgit v1.2.3 From 72d92e865d1560723e1957ee3f393688c49ca5bf Mon Sep 17 00:00:00 2001 From: Stefan Mätje Date: Wed, 18 Oct 2017 13:25:17 +0200 Subject: can: esd_usb2: Fix can_dlc value for received RTR, frames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dlc member of the struct rx_msg contains also the ESD_RTR flag to mark received RTR frames. Without the fix the can_dlc value for received RTR frames would always be set to 8 by get_can_dlc() instead of the received value. Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device") Signed-off-by: Stefan Mätje Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/esd_usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index be928ce62d32..9fdb0f0bfa06 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -333,7 +333,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, } cf->can_id = id & ESD_IDMASK; - cf->can_dlc = get_can_dlc(msg->msg.rx.dlc); + cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR); if (id & ESD_EXTID) cf->can_id |= CAN_EFF_FLAG; -- cgit v1.2.3 From 97819f943063b622eca44d3644067c190dc75039 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Thu, 14 Sep 2017 18:37:14 +0200 Subject: can: gs_usb: fix busy loop if no more TX context is available If sending messages with no cable connected, it quickly happens that there is no more TX context available. Then "gs_can_start_xmit()" returns with "NETDEV_TX_BUSY" and the upper layer does retry immediately keeping the CPU busy. To fix that issue, I moved "atomic_dec(&dev->active_tx_urbs)" from "gs_usb_xmit_callback()" to the TX done handling in "gs_usb_receive_bulk_callback()". Renaming "active_tx_urbs" to "active_tx_contexts" and moving it into "gs_[alloc|free]_tx_context()" would also make sense. Signed-off-by: Wolfgang Grandegger Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index afcc1312dbaf..68ac3e88a8ce 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -375,6 +375,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) gs_free_tx_context(txc); + atomic_dec(&dev->active_tx_urbs); + netif_wake_queue(netdev); } @@ -463,14 +465,6 @@ static void gs_usb_xmit_callback(struct urb *urb) urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); - - atomic_dec(&dev->active_tx_urbs); - - if (!netif_device_present(netdev)) - return; - - if (netif_queue_stopped(netdev)) - netif_wake_queue(netdev); } static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, -- cgit v1.2.3 From cd7aea1875c54c69a54a333b75e9d8732503f273 Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Tue, 17 Oct 2017 07:33:03 +0000 Subject: net: ena: reduce the severity of some printouts Decrease log level of checksum errors as these messages can be triggered remotely by bad packets. Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller --- drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index f7dc22f65d9f..7040b9052747 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -966,7 +966,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring, u64_stats_update_begin(&rx_ring->syncp); rx_ring->rx_stats.bad_csum++; u64_stats_update_end(&rx_ring->syncp); - netif_err(rx_ring->adapter, rx_err, rx_ring->netdev, + netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev, "RX IPv4 header checksum error\n"); return; } @@ -979,7 +979,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring, u64_stats_update_begin(&rx_ring->syncp); rx_ring->rx_stats.bad_csum++; u64_stats_update_end(&rx_ring->syncp); - netif_err(rx_ring->adapter, rx_err, rx_ring->netdev, + netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev, "RX L4 checksum error\n"); skb->ip_summed = CHECKSUM_NONE; return; -- cgit v1.2.3 From 411838e7b41c52cf4afa51929cec54c2162472ff Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Tue, 17 Oct 2017 07:33:04 +0000 Subject: net: ena: fix rare kernel crash when bar memory remap fails This failure is rare and only found on testing where deliberately fail devm_ioremap() [ 451.170464] ena 0000:04:00.0: failed to remap regs bar 451.170549] Workqueue: pciehp-1 pciehp_power_thread [ 451.170551] task: ffff88085a5f2d00 task.stack: ffffc9000756c000 [ 451.170552] RIP: 0010:devm_iounmap+0x2d/0x40 [ 451.170553] RSP: 0018:ffffc9000756fac0 EFLAGS: 00010282 [ 451.170554] RAX: 00000000fffffffe RBX: 0000000000000000 RCX: 0000000000000000 [ 451.170555] RDX: ffffffff813a7e00 RSI: 0000000000000282 RDI: 0000000000000282 [ 451.170556] RBP: ffffc9000756fac8 R08: 00000000fffffffe R09: 00000000000009b7 [ 451.170557] R10: 0000000000000005 R11: 00000000000009b6 R12: ffff880856c9d0a0 [ 451.170558] R13: ffffc9000f5c90c0 R14: ffff880856c9d0a0 R15: 0000000000000028 [ 451.170559] FS: 0000000000000000(0000) GS:ffff88085f400000(0000) knlGS:0000000000000000 [ 451.170560] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 451.170561] CR2: 00007f169038b000 CR3: 0000000001c09000 CR4: 00000000003406f0 [ 451.170562] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 451.170562] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 451.170563] Call Trace: [ 451.170572] ena_release_bars.isra.48+0x34/0x60 [ena] [ 451.170574] ena_probe+0x144/0xd90 [ena] [ 451.170579] ? ida_simple_get+0x98/0x100 [ 451.170585] ? kernfs_next_descendant_post+0x40/0x50 [ 451.170591] local_pci_probe+0x45/0xa0 [ 451.170592] pci_device_probe+0x157/0x180 [ 451.170599] driver_probe_device+0x2a8/0x460 [ 451.170600] __device_attach_driver+0x7e/0xe0 [ 451.170602] ? driver_allows_async_probing+0x30/0x30 [ 451.170603] bus_for_each_drv+0x68/0xb0 [ 451.170605] __device_attach+0xdd/0x160 [ 451.170607] device_attach+0x10/0x20 [ 451.170610] pci_bus_add_device+0x4f/0xa0 [ 451.170611] pci_bus_add_devices+0x39/0x70 [ 451.170613] pciehp_configure_device+0x96/0x120 [ 451.170614] pciehp_enable_slot+0x1b3/0x290 [ 451.170616] pciehp_power_thread+0x3b/0xb0 [ 451.170622] process_one_work+0x149/0x360 [ 451.170623] worker_thread+0x4d/0x3c0 [ 451.170626] kthread+0x109/0x140 [ 451.170627] ? rescuer_thread+0x380/0x380 [ 451.170628] ? kthread_park+0x60/0x60 [ 451.170632] ret_from_fork+0x25/0x30 Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller --- drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 7040b9052747..c6bd5e24005d 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -3064,7 +3064,8 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev) if (ena_dev->mem_bar) devm_iounmap(&pdev->dev, ena_dev->mem_bar); - devm_iounmap(&pdev->dev, ena_dev->reg_bar); + if (ena_dev->reg_bar) + devm_iounmap(&pdev->dev, ena_dev->reg_bar); release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK; pci_release_selected_regions(pdev, release_bars); -- cgit v1.2.3 From a59df396768a7e37c6ddafeb9666a30c8ac07854 Mon Sep 17 00:00:00 2001 From: Netanel Belgazal Date: Tue, 17 Oct 2017 07:33:05 +0000 Subject: net: ena: fix wrong max Tx/Rx queues on ethtool ethtool ena_get_channels() expose the max number of queues as the max number of queues ENA supports (128 queues) and not the actual number of created queues. Signed-off-by: Netanel Belgazal Signed-off-by: David S. Miller --- drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c index b1212debc2e1..967020fb26ee 100644 --- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c +++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c @@ -742,8 +742,8 @@ static void ena_get_channels(struct net_device *netdev, { struct ena_adapter *adapter = netdev_priv(netdev); - channels->max_rx = ENA_MAX_NUM_IO_QUEUES; - channels->max_tx = ENA_MAX_NUM_IO_QUEUES; + channels->max_rx = adapter->num_queues; + channels->max_tx = adapter->num_queues; channels->max_other = 0; channels->max_combined = 0; channels->rx_count = adapter->num_queues; -- cgit v1.2.3 From d8fe2c7f3365f5b0e517f210957cc813b9102c96 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:56:56 +0300 Subject: drm/i915: Relocate intel_ddi_get_buf_trans_*() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We'll want to use the intel_ddi_get_buf_trans_*() functions a bit earlier in the file, so move them up. While at it start using them in the iboost setup to get rid of the platform checks there. v2: Rebase due to BDW FDI buf trans fix Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-2-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 115 +++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index adf51b328844..a6169ed312c6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -588,6 +588,59 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) } } +static const struct ddi_buf_trans * +intel_ddi_get_buf_trans_dp(struct drm_i915_private *dev_priv, + int *n_entries) +{ + if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { + return kbl_get_buf_trans_dp(dev_priv, n_entries); + } else if (IS_SKYLAKE(dev_priv)) { + return skl_get_buf_trans_dp(dev_priv, n_entries); + } else if (IS_BROADWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(bdw_ddi_translations_dp); + return bdw_ddi_translations_dp; + } else if (IS_HASWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp); + return hsw_ddi_translations_dp; + } + + *n_entries = 0; + return NULL; +} + +static const struct ddi_buf_trans * +intel_ddi_get_buf_trans_edp(struct drm_i915_private *dev_priv, + int *n_entries) +{ + if (IS_GEN9_BC(dev_priv)) { + return skl_get_buf_trans_edp(dev_priv, n_entries); + } else if (IS_BROADWELL(dev_priv)) { + return bdw_get_buf_trans_edp(dev_priv, n_entries); + } else if (IS_HASWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp); + return hsw_ddi_translations_dp; + } + + *n_entries = 0; + return NULL; +} + +static const struct ddi_buf_trans * +intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv, + int *n_entries) +{ + if (IS_BROADWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi); + return bdw_ddi_translations_fdi; + } else if (IS_HASWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); + return hsw_ddi_translations_fdi; + } + + *n_entries = 0; + return NULL; +} + static const struct cnl_ddi_buf_trans * cnl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) { @@ -692,59 +745,6 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por return hdmi_level; } -static const struct ddi_buf_trans * -intel_ddi_get_buf_trans_dp(struct drm_i915_private *dev_priv, - int *n_entries) -{ - if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { - return kbl_get_buf_trans_dp(dev_priv, n_entries); - } else if (IS_SKYLAKE(dev_priv)) { - return skl_get_buf_trans_dp(dev_priv, n_entries); - } else if (IS_BROADWELL(dev_priv)) { - *n_entries = ARRAY_SIZE(bdw_ddi_translations_dp); - return bdw_ddi_translations_dp; - } else if (IS_HASWELL(dev_priv)) { - *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp); - return hsw_ddi_translations_dp; - } - - *n_entries = 0; - return NULL; -} - -static const struct ddi_buf_trans * -intel_ddi_get_buf_trans_edp(struct drm_i915_private *dev_priv, - int *n_entries) -{ - if (IS_GEN9_BC(dev_priv)) { - return skl_get_buf_trans_edp(dev_priv, n_entries); - } else if (IS_BROADWELL(dev_priv)) { - return bdw_get_buf_trans_edp(dev_priv, n_entries); - } else if (IS_HASWELL(dev_priv)) { - *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp); - return hsw_ddi_translations_dp; - } - - *n_entries = 0; - return NULL; -} - -static const struct ddi_buf_trans * -intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv, - int *n_entries) -{ - if (IS_BROADWELL(dev_priv)) { - *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi); - return bdw_ddi_translations_fdi; - } else if (IS_HASWELL(dev_priv)) { - *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi); - return hsw_ddi_translations_fdi; - } - - *n_entries = 0; - return NULL; -} - /* * Starting with Haswell, DDI port buffers must be programmed with correct * values in advance. This function programs the correct values for @@ -1801,19 +1801,14 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, u32 level) if (dp_iboost) { iboost = dp_iboost; } else { - if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) - ddi_translations = kbl_get_buf_trans_dp(dev_priv, - &n_entries); - else - ddi_translations = skl_get_buf_trans_dp(dev_priv, - &n_entries); + ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, &n_entries); iboost = ddi_translations[level].i_boost; } } else if (type == INTEL_OUTPUT_EDP) { if (dp_iboost) { iboost = dp_iboost; } else { - ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries); + ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, &n_entries); if (WARN_ON(port != PORT_A && port != PORT_E && n_entries > 9)) -- cgit v1.2.3 From 975786ee0e25253c4bcd3e6b133a2cd5f0a2c115 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:56:57 +0300 Subject: drm/i915: Extract intel_ddi_get_buf_trans_hdmi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce intel_ddi_get_buf_trans_hdmi() and start using it where we can. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-3-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/intel_ddi.c | 50 ++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index a6169ed312c6..f0fcabfe4050 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -641,6 +641,24 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv, return NULL; } +static const struct ddi_buf_trans * +intel_ddi_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, + int *n_entries) +{ + if (IS_GEN9_BC(dev_priv)) { + return skl_get_buf_trans_hdmi(dev_priv, n_entries); + } else if (IS_BROADWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); + return bdw_ddi_translations_hdmi; + } else if (IS_HASWELL(dev_priv)) { + *n_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); + return hsw_ddi_translations_hdmi; + } + + *n_entries = 0; + return NULL; +} + static const struct cnl_ddi_buf_trans * cnl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) { @@ -723,18 +741,17 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por cnl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); hdmi_default_entry = n_hdmi_entries - 1; } else if (IS_GEN9_BC(dev_priv)) { - skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); + intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); hdmi_default_entry = 8; } else if (IS_BROADWELL(dev_priv)) { - n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); + intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); hdmi_default_entry = 7; } else if (IS_HASWELL(dev_priv)) { - n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); + intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); hdmi_default_entry = 6; } else { WARN(1, "ddi translation table missing\n"); - n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); - hdmi_default_entry = 7; + return 0; } /* Choose a good default if VBT is badly populated */ @@ -810,23 +827,12 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder) hdmi_level = intel_ddi_hdmi_level(dev_priv, port); - if (IS_GEN9_BC(dev_priv)) { - ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); + ddi_translations_hdmi = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); - /* If we're boosting the current, set bit 31 of trans1 */ - if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level) - iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; - } else if (IS_BROADWELL(dev_priv)) { - ddi_translations_hdmi = bdw_ddi_translations_hdmi; - n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); - } else if (IS_HASWELL(dev_priv)) { - ddi_translations_hdmi = hsw_ddi_translations_hdmi; - n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); - } else { - WARN(1, "ddi translation table missing\n"); - ddi_translations_hdmi = bdw_ddi_translations_hdmi; - n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); - } + /* If we're boosting the current, set bit 31 of trans1 */ + if (IS_GEN9_BC(dev_priv) && + dev_priv->vbt.ddi_port_info[port].hdmi_boost_level) + iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; /* Entry 9 is for HDMI: */ I915_WRITE(DDI_BUF_TRANS_LO(port, 9), @@ -1820,7 +1826,7 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, u32 level) if (hdmi_iboost) { iboost = hdmi_iboost; } else { - ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries); + ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); iboost = ddi_translations[level].i_boost; } } else { -- cgit v1.2.3 From 081dfcfafcbb524b2916b0243c976228accaa4df Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:56:58 +0300 Subject: drm/i915: Pass the encoder type explicitly to skl_set_iboost() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit encoder->type isn't reliable for DP/HDMI encoders, so pass the type explicity to skl_set_iboost(). Also take the opportunity to streamline the code. v2: Clean up the argument types to skl_ddi_set_iboost() while at it Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-4-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 57 ++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f0fcabfe4050..a021ebc72123 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1788,49 +1788,36 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv, I915_WRITE(DISPIO_CR_TX_BMU_CR0, tmp); } -static void skl_ddi_set_iboost(struct intel_encoder *encoder, u32 level) +static void skl_ddi_set_iboost(struct intel_encoder *encoder, + int level, enum intel_output_type type) { struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); enum port port = intel_dig_port->port; - int type = encoder->type; - const struct ddi_buf_trans *ddi_translations; uint8_t iboost; - uint8_t dp_iboost, hdmi_iboost; - int n_entries; - /* VBT may override standard boost values */ - dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level; - hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level; + if (type == INTEL_OUTPUT_HDMI) + iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level; + else + iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level; - if (type == INTEL_OUTPUT_DP) { - if (dp_iboost) { - iboost = dp_iboost; - } else { - ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, &n_entries); - iboost = ddi_translations[level].i_boost; - } - } else if (type == INTEL_OUTPUT_EDP) { - if (dp_iboost) { - iboost = dp_iboost; - } else { + if (iboost == 0) { + const struct ddi_buf_trans *ddi_translations; + int n_entries; + + if (type == INTEL_OUTPUT_HDMI) + ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); + else if (type == INTEL_OUTPUT_EDP) ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, &n_entries); + else + ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, &n_entries); - if (WARN_ON(port != PORT_A && - port != PORT_E && n_entries > 9)) - n_entries = 9; + if (WARN_ON(type != INTEL_OUTPUT_HDMI && + port != PORT_A && + port != PORT_E && n_entries > 9)) + n_entries = 9; - iboost = ddi_translations[level].i_boost; - } - } else if (type == INTEL_OUTPUT_HDMI) { - if (hdmi_iboost) { - iboost = hdmi_iboost; - } else { - ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); - iboost = ddi_translations[level].i_boost; - } - } else { - return; + iboost = ddi_translations[level].i_boost; } /* Make sure that the requested I_boost is valid */ @@ -2096,7 +2083,7 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) uint32_t level = intel_ddi_dp_level(intel_dp); if (IS_GEN9_BC(dev_priv)) - skl_ddi_set_iboost(encoder, level); + skl_ddi_set_iboost(encoder, level, encoder->type); return DDI_BUF_TRANS_SELECT(level); } @@ -2218,7 +2205,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, intel_prepare_hdmi_ddi_buffers(encoder); if (IS_GEN9_BC(dev_priv)) - skl_ddi_set_iboost(encoder, level); + skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI); intel_dig_port->set_infoframes(&encoder->base, crtc_state->has_infoframe, -- cgit v1.2.3 From 7ea79333a728740bc83e6102fd4fb992664ee915 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:56:59 +0300 Subject: drm/i915: Pass the level to intel_prepare_hdmi_ddi_buffers() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The caller of intel_prepare_hdmi_ddi_buffers() alreday figured out the level, so let's just pass it in instead if figuring it out again. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-5-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index a021ebc72123..fe0db435fa47 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -817,16 +817,15 @@ static void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder) * values in advance. This function programs the correct values for * HDMI/DVI use cases. */ -static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder) +static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, + int hdmi_level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 iboost_bit = 0; - int n_hdmi_entries, hdmi_level; + int n_hdmi_entries; enum port port = intel_ddi_get_encoder_port(encoder); const struct ddi_buf_trans *ddi_translations_hdmi; - hdmi_level = intel_ddi_hdmi_level(dev_priv, port); - ddi_translations_hdmi = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); /* If we're boosting the current, set bit 31 of trans1 */ @@ -2202,7 +2201,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, bxt_ddi_vswing_sequence(dev_priv, level, port, INTEL_OUTPUT_HDMI); else - intel_prepare_hdmi_ddi_buffers(encoder); + intel_prepare_hdmi_ddi_buffers(encoder, level); if (IS_GEN9_BC(dev_priv)) skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI); -- cgit v1.2.3 From 7d4f37b5db57bb383872ed40793ffb74f201c6ac Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:57:00 +0300 Subject: drm/i915: Integrate BXT into intel_ddi_dp_voltage_max() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make BXT less special by following the CNL approach and handling it in intel_ddi_dp_voltage_max() alognside every other DDI platform. v2: Clean up the argument types to bxt_ddi_vswing_sequence() while at it Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-6-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 69 ++++++++++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_dp.c | 4 +-- 2 files changed, 46 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index fe0db435fa47..524e732fed41 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -659,6 +659,31 @@ intel_ddi_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, return NULL; } +static const struct bxt_ddi_buf_trans * +bxt_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries) +{ + *n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); + return bxt_ddi_translations_dp; +} + +static const struct bxt_ddi_buf_trans * +bxt_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) +{ + if (dev_priv->vbt.edp.low_vswing) { + *n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); + return bxt_ddi_translations_edp; + } + + return bxt_get_buf_trans_dp(dev_priv, n_entries); +} + +static const struct bxt_ddi_buf_trans * +bxt_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) +{ + *n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi); + return bxt_ddi_translations_hdmi; +} + static const struct cnl_ddi_buf_trans * cnl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) { @@ -1831,27 +1856,20 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, _skl_ddi_set_iboost(dev_priv, PORT_E, iboost); } -static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, - u32 level, enum port port, int type) +static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, + int level, enum intel_output_type type) { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct bxt_ddi_buf_trans *ddi_translations; - u32 n_entries, i; - - if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) { - n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); - ddi_translations = bxt_ddi_translations_edp; - } else if (type == INTEL_OUTPUT_DP - || type == INTEL_OUTPUT_EDP) { - n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); - ddi_translations = bxt_ddi_translations_dp; - } else if (type == INTEL_OUTPUT_HDMI) { - n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi); - ddi_translations = bxt_ddi_translations_hdmi; - } else { - DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n", - type); - return; - } + enum port port = encoder->port; + int n_entries, i; + + if (type == INTEL_OUTPUT_HDMI) + ddi_translations = bxt_get_buf_trans_hdmi(dev_priv, &n_entries); + else if (type == INTEL_OUTPUT_EDP) + ddi_translations = bxt_get_buf_trans_edp(dev_priv, &n_entries); + else + ddi_translations = bxt_get_buf_trans_dp(dev_priv, &n_entries); /* Check if default value has to be used */ if (level >= n_entries || @@ -1881,6 +1899,11 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder) cnl_get_buf_trans_edp(dev_priv, &n_entries); else cnl_get_buf_trans_dp(dev_priv, &n_entries); + } else if (IS_GEN9_LP(dev_priv)) { + if (encoder->type == INTEL_OUTPUT_EDP) + bxt_get_buf_trans_edp(dev_priv, &n_entries); + else + bxt_get_buf_trans_dp(dev_priv, &n_entries); } else { if (encoder->type == INTEL_OUTPUT_EDP) intel_ddi_get_buf_trans_edp(dev_priv, &n_entries); @@ -2063,13 +2086,12 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp) struct intel_digital_port *dport = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); struct intel_encoder *encoder = &dport->base; - enum port port = dport->port; u32 level = intel_ddi_dp_level(intel_dp); if (IS_CANNONLAKE(dev_priv)) cnl_ddi_vswing_sequence(encoder, level); else - bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type); + bxt_ddi_vswing_sequence(encoder, level, encoder->type); return 0; } @@ -2167,7 +2189,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, if (IS_CANNONLAKE(dev_priv)) cnl_ddi_vswing_sequence(encoder, level); else if (IS_GEN9_LP(dev_priv)) - bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type); + bxt_ddi_vswing_sequence(encoder, level, encoder->type); else intel_prepare_dp_ddi_buffers(encoder); @@ -2198,8 +2220,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, if (IS_CANNONLAKE(dev_priv)) cnl_ddi_vswing_sequence(encoder, level); else if (IS_GEN9_LP(dev_priv)) - bxt_ddi_vswing_sequence(dev_priv, level, port, - INTEL_OUTPUT_HDMI); + bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); else intel_prepare_hdmi_ddi_buffers(encoder, level); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4b65cf137f79..aa75f55eeb61 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3155,9 +3155,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); enum port port = dp_to_dig_port(intel_dp)->port; - if (IS_GEN9_LP(dev_priv)) - return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; - else if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 9) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; return intel_ddi_dp_voltage_max(encoder); } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) -- cgit v1.2.3 From f3cf4ba45e13bef6287b03b72ba43db1dab60e29 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:57:01 +0300 Subject: drm/i915: Pass encoder type to cnl_ddi_vswing_sequence() explicitly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit encoder->type is unreliable for DP/HDMI, so pass it in explicity into cnl_ddi_vswing_sequence(). This matches what we do for BXT. v2: Pass intel_encoder down to cnl_ddi_vswing_program(), and clean up the argument types while at it Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-7-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 53 +++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 524e732fed41..3607837b1aaf 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1920,20 +1920,21 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder) DP_TRAIN_VOLTAGE_SWING_MASK; } -static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv, - u32 level, enum port port, int type) +static void cnl_ddi_vswing_program(struct intel_encoder *encoder, + int level, enum intel_output_type type) { - const struct cnl_ddi_buf_trans *ddi_translations = NULL; - u32 n_entries, val; - int ln; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + const struct cnl_ddi_buf_trans *ddi_translations; + int n_entries, ln; + u32 val; - if (type == INTEL_OUTPUT_HDMI) { + if (type == INTEL_OUTPUT_HDMI) ddi_translations = cnl_get_buf_trans_hdmi(dev_priv, &n_entries); - } else if (type == INTEL_OUTPUT_DP) { - ddi_translations = cnl_get_buf_trans_dp(dev_priv, &n_entries); - } else if (type == INTEL_OUTPUT_EDP) { + else if (type == INTEL_OUTPUT_EDP) ddi_translations = cnl_get_buf_trans_edp(dev_priv, &n_entries); - } + else + ddi_translations = cnl_get_buf_trans_dp(dev_priv, &n_entries); if (WARN_ON(ddi_translations == NULL)) return; @@ -1986,26 +1987,22 @@ static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv, I915_WRITE(CNL_PORT_TX_DW7_GRP(port), val); } -static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level) +static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, + int level, enum intel_output_type type) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); enum port port = intel_ddi_get_encoder_port(encoder); - int type = encoder->type; - int width = 0; - int rate = 0; + int width, rate, ln; u32 val; - int ln = 0; - if ((intel_dp) && (type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP)) { - width = intel_dp->lane_count; - rate = intel_dp->link_rate; - } else if (type == INTEL_OUTPUT_HDMI) { + if (type == INTEL_OUTPUT_HDMI) { width = 4; - /* Rate is always < than 6GHz for HDMI */ + rate = 0; /* Rate is always < than 6GHz for HDMI */ } else { - MISSING_CASE(type); - return; + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + + width = intel_dp->lane_count; + rate = intel_dp->link_rate; } /* @@ -2014,7 +2011,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level) * else clear to 0b. */ val = I915_READ(CNL_PORT_PCS_DW1_LN0(port)); - if (type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP) + if (type != INTEL_OUTPUT_HDMI) val |= COMMON_KEEPER_EN; else val &= ~COMMON_KEEPER_EN; @@ -2049,7 +2046,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level) I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val); /* 5. Program swing and de-emphasis */ - cnl_ddi_vswing_program(dev_priv, level, port, type); + cnl_ddi_vswing_program(encoder, level, type); /* 6. Set training enable to trigger update */ val = I915_READ(CNL_PORT_TX_DW5_LN0(port)); @@ -2089,7 +2086,7 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp) u32 level = intel_ddi_dp_level(intel_dp); if (IS_CANNONLAKE(dev_priv)) - cnl_ddi_vswing_sequence(encoder, level); + cnl_ddi_vswing_sequence(encoder, level, encoder->type); else bxt_ddi_vswing_sequence(encoder, level, encoder->type); @@ -2187,7 +2184,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); if (IS_CANNONLAKE(dev_priv)) - cnl_ddi_vswing_sequence(encoder, level); + cnl_ddi_vswing_sequence(encoder, level, encoder->type); else if (IS_GEN9_LP(dev_priv)) bxt_ddi_vswing_sequence(encoder, level, encoder->type); else @@ -2218,7 +2215,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); if (IS_CANNONLAKE(dev_priv)) - cnl_ddi_vswing_sequence(encoder, level); + cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); else if (IS_GEN9_LP(dev_priv)) bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); else -- cgit v1.2.3 From 043eaf3685c8edccf5400a0260027b864b931797 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:57:02 +0300 Subject: drm/i915: Kill off the BXT buf_trans default_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit default_index contained in the BXT buf_trans tables is actually useless. For DP we should always have a valid level selected (otherwise the link training logic would be buggy), and for HDMI we can just do what the other platforms do and pick the correct entry in intel_ddi_hdmi_level(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-8-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 80 +++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3607837b1aaf..96ceb7a6887c 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -305,35 +305,34 @@ struct bxt_ddi_buf_trans { u8 scale; /* scale value */ u8 enable; /* scale enable */ u8 deemphasis; - bool default_index; /* true if the entry represents default value */ }; static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { /* Idx NT mV diff db */ - { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */ - { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */ - { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */ - { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */ - { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */ - { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */ - { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */ - { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */ - { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */ - { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */ + { 52, 0x9A, 0, 128, }, /* 0: 400 0 */ + { 78, 0x9A, 0, 85, }, /* 1: 400 3.5 */ + { 104, 0x9A, 0, 64, }, /* 2: 400 6 */ + { 154, 0x9A, 0, 43, }, /* 3: 400 9.5 */ + { 77, 0x9A, 0, 128, }, /* 4: 600 0 */ + { 116, 0x9A, 0, 85, }, /* 5: 600 3.5 */ + { 154, 0x9A, 0, 64, }, /* 6: 600 6 */ + { 102, 0x9A, 0, 128, }, /* 7: 800 0 */ + { 154, 0x9A, 0, 85, }, /* 8: 800 3.5 */ + { 154, 0x9A, 1, 128, }, /* 9: 1200 0 */ }; static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = { /* Idx NT mV diff db */ - { 26, 0, 0, 128, false }, /* 0: 200 0 */ - { 38, 0, 0, 112, false }, /* 1: 200 1.5 */ - { 48, 0, 0, 96, false }, /* 2: 200 4 */ - { 54, 0, 0, 69, false }, /* 3: 200 6 */ - { 32, 0, 0, 128, false }, /* 4: 250 0 */ - { 48, 0, 0, 104, false }, /* 5: 250 1.5 */ - { 54, 0, 0, 85, false }, /* 6: 250 4 */ - { 43, 0, 0, 128, false }, /* 7: 300 0 */ - { 54, 0, 0, 101, false }, /* 8: 300 1.5 */ - { 48, 0, 0, 128, false }, /* 9: 300 0 */ + { 26, 0, 0, 128, }, /* 0: 200 0 */ + { 38, 0, 0, 112, }, /* 1: 200 1.5 */ + { 48, 0, 0, 96, }, /* 2: 200 4 */ + { 54, 0, 0, 69, }, /* 3: 200 6 */ + { 32, 0, 0, 128, }, /* 4: 250 0 */ + { 48, 0, 0, 104, }, /* 5: 250 1.5 */ + { 54, 0, 0, 85, }, /* 6: 250 4 */ + { 43, 0, 0, 128, }, /* 7: 300 0 */ + { 54, 0, 0, 101, }, /* 8: 300 1.5 */ + { 48, 0, 0, 128, }, /* 9: 300 0 */ }; /* BSpec has 2 recommended values - entries 0 and 8. @@ -341,16 +340,16 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = { */ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = { /* Idx NT mV diff db */ - { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */ - { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */ - { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */ - { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */ - { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */ - { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */ - { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */ - { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */ - { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */ - { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */ + { 52, 0x9A, 0, 128, }, /* 0: 400 0 */ + { 52, 0x9A, 0, 85, }, /* 1: 400 3.5 */ + { 52, 0x9A, 0, 64, }, /* 2: 400 6 */ + { 42, 0x9A, 0, 43, }, /* 3: 400 9.5 */ + { 77, 0x9A, 0, 128, }, /* 4: 600 0 */ + { 77, 0x9A, 0, 85, }, /* 5: 600 3.5 */ + { 77, 0x9A, 0, 64, }, /* 6: 600 6 */ + { 102, 0x9A, 0, 128, }, /* 7: 800 0 */ + { 102, 0x9A, 0, 85, }, /* 8: 800 3.5 */ + { 154, 0x9A, 1, 128, }, /* 9: 1200 0 */ }; struct cnl_ddi_buf_trans { @@ -759,12 +758,12 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; - if (IS_GEN9_LP(dev_priv)) - return hdmi_level; - if (IS_CANNONLAKE(dev_priv)) { cnl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); hdmi_default_entry = n_hdmi_entries - 1; + } else if (IS_GEN9_LP(dev_priv)) { + bxt_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); + hdmi_default_entry = n_hdmi_entries - 1; } else if (IS_GEN9_BC(dev_priv)) { intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); hdmi_default_entry = 8; @@ -1862,7 +1861,7 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct bxt_ddi_buf_trans *ddi_translations; enum port port = encoder->port; - int n_entries, i; + int n_entries; if (type == INTEL_OUTPUT_HDMI) ddi_translations = bxt_get_buf_trans_hdmi(dev_priv, &n_entries); @@ -1871,17 +1870,6 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, else ddi_translations = bxt_get_buf_trans_dp(dev_priv, &n_entries); - /* Check if default value has to be used */ - if (level >= n_entries || - (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) { - for (i = 0; i < n_entries; i++) { - if (ddi_translations[i].default_index) { - level = i; - break; - } - } - } - bxt_ddi_phy_set_signal_level(dev_priv, port, ddi_translations[level].margin, ddi_translations[level].scale, -- cgit v1.2.3 From edba48fdfc4770ee41d71e2c2c0360b15cca6567 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 16 Oct 2017 17:57:03 +0300 Subject: drm/i915: Centralize the SKL DDI A/E vs. B/C/D buf trans handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SKL DDI B/C/D only have 9 usable buf trans registers for DP/eDP. That matches the normal DP buf trans tables, but the low vswing eDP tables have 10 entries. Thus the eDP tables can only be used safely with DDI A and E. We try to catch cases where DDI B/C/D gets used with the wrong number of entires in some parts of the code, but not everywhere. Let's move the code to deal with that deeper into intel_ddi_get_buf_trans_edp(). And for sake of symmetry do the same in intel_ddi_get_buf_trans_dp(). That would also avoid explosions in the rather unlikely case that the DP tables would get revised to 10 entries as well. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171016145705.11780-9-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 60 +++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 96ceb7a6887c..5ee0e33e2c00 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -587,14 +587,29 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) } } +static int skl_buf_trans_num_entries(enum port port, int n_entries) +{ + /* Only DDIA and DDIE can select the 10th register with DP */ + if (port == PORT_A || port == PORT_E) + return min(n_entries, 10); + else + return min(n_entries, 9); +} + static const struct ddi_buf_trans * intel_ddi_get_buf_trans_dp(struct drm_i915_private *dev_priv, - int *n_entries) + enum port port, int *n_entries) { if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { - return kbl_get_buf_trans_dp(dev_priv, n_entries); + const struct ddi_buf_trans *ddi_translations = + kbl_get_buf_trans_dp(dev_priv, n_entries); + *n_entries = skl_buf_trans_num_entries(port, *n_entries); + return ddi_translations; } else if (IS_SKYLAKE(dev_priv)) { - return skl_get_buf_trans_dp(dev_priv, n_entries); + const struct ddi_buf_trans *ddi_translations = + skl_get_buf_trans_dp(dev_priv, n_entries); + *n_entries = skl_buf_trans_num_entries(port, *n_entries); + return ddi_translations; } else if (IS_BROADWELL(dev_priv)) { *n_entries = ARRAY_SIZE(bdw_ddi_translations_dp); return bdw_ddi_translations_dp; @@ -609,10 +624,13 @@ intel_ddi_get_buf_trans_dp(struct drm_i915_private *dev_priv, static const struct ddi_buf_trans * intel_ddi_get_buf_trans_edp(struct drm_i915_private *dev_priv, - int *n_entries) + enum port port, int *n_entries) { if (IS_GEN9_BC(dev_priv)) { - return skl_get_buf_trans_edp(dev_priv, n_entries); + const struct ddi_buf_trans *ddi_translations = + skl_get_buf_trans_edp(dev_priv, n_entries); + *n_entries = skl_buf_trans_num_entries(port, *n_entries); + return ddi_translations; } else if (IS_BROADWELL(dev_priv)) { return bdw_get_buf_trans_edp(dev_priv, n_entries); } else if (IS_HASWELL(dev_priv)) { @@ -801,11 +819,11 @@ static void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder) switch (encoder->type) { case INTEL_OUTPUT_EDP: - ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, + ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries); break; case INTEL_OUTPUT_DP: - ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, + ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries); break; case INTEL_OUTPUT_ANALOG: @@ -817,16 +835,10 @@ static void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder) return; } - if (IS_GEN9_BC(dev_priv)) { - /* If we're boosting the current, set bit 31 of trans1 */ - if (dev_priv->vbt.ddi_port_info[port].dp_boost_level) - iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; - - if (WARN_ON(encoder->type == INTEL_OUTPUT_EDP && - port != PORT_A && port != PORT_E && - n_entries > 9)) - n_entries = 9; - } + /* If we're boosting the current, set bit 31 of trans1 */ + if (IS_GEN9_BC(dev_priv) && + dev_priv->vbt.ddi_port_info[port].dp_boost_level) + iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; for (i = 0; i < n_entries; i++) { I915_WRITE(DDI_BUF_TRANS_LO(port, i), @@ -1831,14 +1843,9 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, if (type == INTEL_OUTPUT_HDMI) ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); else if (type == INTEL_OUTPUT_EDP) - ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, &n_entries); + ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries); else - ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, &n_entries); - - if (WARN_ON(type != INTEL_OUTPUT_HDMI && - port != PORT_A && - port != PORT_E && n_entries > 9)) - n_entries = 9; + ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries); iboost = ddi_translations[level].i_boost; } @@ -1880,6 +1887,7 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = encoder->port; int n_entries; if (IS_CANNONLAKE(dev_priv)) { @@ -1894,9 +1902,9 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder) bxt_get_buf_trans_dp(dev_priv, &n_entries); } else { if (encoder->type == INTEL_OUTPUT_EDP) - intel_ddi_get_buf_trans_edp(dev_priv, &n_entries); + intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries); else - intel_ddi_get_buf_trans_dp(dev_priv, &n_entries); + intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries); } if (WARN_ON(n_entries < 1)) -- cgit v1.2.3 From 21b39d2a3adb798dc8dcbdb4abe23250ecfaf7e4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 18 Oct 2017 21:19:34 +0300 Subject: drm/i915: Unify error handling for missing DDI buf trans tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle missing buf trans tables, or out of bounds buf trans levels the same way everywhere. These should never be hit under normal conditions, but let's play it safe for now. v2: Avoid the hdmi_level=-1 case (James) Cc: James Ausmus Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171018181934.4229-1-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5ee0e33e2c00..cd7a0d979a10 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -801,6 +801,11 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por hdmi_level >= n_hdmi_entries) hdmi_level = hdmi_default_entry; + if (WARN_ON_ONCE(n_hdmi_entries == 0)) + return 0; + if (WARN_ON_ONCE(hdmi_level >= n_hdmi_entries)) + hdmi_level = n_hdmi_entries - 1; + return hdmi_level; } @@ -864,6 +869,11 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, ddi_translations_hdmi = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); + if (WARN_ON_ONCE(!ddi_translations_hdmi)) + return; + if (WARN_ON_ONCE(hdmi_level >= n_hdmi_entries)) + hdmi_level = n_hdmi_entries - 1; + /* If we're boosting the current, set bit 31 of trans1 */ if (IS_GEN9_BC(dev_priv) && dev_priv->vbt.ddi_port_info[port].hdmi_boost_level) @@ -1847,6 +1857,11 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, else ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries); + if (WARN_ON_ONCE(!ddi_translations)) + return; + if (WARN_ON_ONCE(level >= n_entries)) + level = n_entries - 1; + iboost = ddi_translations[level].i_boost; } @@ -1877,6 +1892,11 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, else ddi_translations = bxt_get_buf_trans_dp(dev_priv, &n_entries); + if (WARN_ON_ONCE(!ddi_translations)) + return; + if (WARN_ON_ONCE(level >= n_entries)) + level = n_entries - 1; + bxt_ddi_phy_set_signal_level(dev_priv, port, ddi_translations[level].margin, ddi_translations[level].scale, @@ -1932,13 +1952,10 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder, else ddi_translations = cnl_get_buf_trans_dp(dev_priv, &n_entries); - if (WARN_ON(ddi_translations == NULL)) + if (WARN_ON_ONCE(!ddi_translations)) return; - - if (level >= n_entries) { - DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1); + if (WARN_ON_ONCE(level >= n_entries)) level = n_entries - 1; - } /* Set PORT_TX_DW5 Scaling Mode Sel to 010b. */ val = I915_READ(CNL_PORT_TX_DW5_LN0(port)); -- cgit v1.2.3 From d02ace874937a4dda217d4cb772c7777056febb3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 18 Oct 2017 21:19:58 +0300 Subject: drm/i915: Drop the redundant hdmi prefix/suffix from a lot of variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bunch of functions are now exclusively used for HDMI, so naming the variables with hdmi prefix/suffix is redundant. Also use int rather than u32 for the translation level consistently. v2: Rebase due to hdmi_level=-1 avoidance Cc: James Ausmus Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171018181958.4423-1-ville.syrjala@linux.intel.com Reviewed-by: James Ausmus --- drivers/gpu/drm/i915/intel_ddi.c | 63 +++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cd7a0d979a10..b8925bc82f30 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -770,43 +770,40 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port) { - int n_hdmi_entries; - int hdmi_level; - int hdmi_default_entry; + int n_entries, level, default_entry; - hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; + level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; if (IS_CANNONLAKE(dev_priv)) { - cnl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); - hdmi_default_entry = n_hdmi_entries - 1; + cnl_get_buf_trans_hdmi(dev_priv, &n_entries); + default_entry = n_entries - 1; } else if (IS_GEN9_LP(dev_priv)) { - bxt_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); - hdmi_default_entry = n_hdmi_entries - 1; + bxt_get_buf_trans_hdmi(dev_priv, &n_entries); + default_entry = n_entries - 1; } else if (IS_GEN9_BC(dev_priv)) { - intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); - hdmi_default_entry = 8; + intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); + default_entry = 8; } else if (IS_BROADWELL(dev_priv)) { - intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); - hdmi_default_entry = 7; + intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); + default_entry = 7; } else if (IS_HASWELL(dev_priv)) { - intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); - hdmi_default_entry = 6; + intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); + default_entry = 6; } else { WARN(1, "ddi translation table missing\n"); return 0; } /* Choose a good default if VBT is badly populated */ - if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN || - hdmi_level >= n_hdmi_entries) - hdmi_level = hdmi_default_entry; + if (level == HDMI_LEVEL_SHIFT_UNKNOWN || level >= n_entries) + level = default_entry; - if (WARN_ON_ONCE(n_hdmi_entries == 0)) + if (WARN_ON_ONCE(n_entries == 0)) return 0; - if (WARN_ON_ONCE(hdmi_level >= n_hdmi_entries)) - hdmi_level = n_hdmi_entries - 1; + if (WARN_ON_ONCE(level >= n_entries)) + level = n_entries - 1; - return hdmi_level; + return level; } /* @@ -859,20 +856,20 @@ static void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder) * HDMI/DVI use cases. */ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, - int hdmi_level) + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 iboost_bit = 0; - int n_hdmi_entries; + int n_entries; enum port port = intel_ddi_get_encoder_port(encoder); - const struct ddi_buf_trans *ddi_translations_hdmi; + const struct ddi_buf_trans *ddi_translations; - ddi_translations_hdmi = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); + ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); - if (WARN_ON_ONCE(!ddi_translations_hdmi)) + if (WARN_ON_ONCE(!ddi_translations)) return; - if (WARN_ON_ONCE(hdmi_level >= n_hdmi_entries)) - hdmi_level = n_hdmi_entries - 1; + if (WARN_ON_ONCE(level >= n_entries)) + level = n_entries - 1; /* If we're boosting the current, set bit 31 of trans1 */ if (IS_GEN9_BC(dev_priv) && @@ -881,9 +878,9 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, /* Entry 9 is for HDMI: */ I915_WRITE(DDI_BUF_TRANS_LO(port, 9), - ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); + ddi_translations[level].trans1 | iboost_bit); I915_WRITE(DDI_BUF_TRANS_HI(port, 9), - ddi_translations_hdmi[hdmi_level].trans2); + ddi_translations[level].trans2); } static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, @@ -2096,7 +2093,7 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp) struct intel_digital_port *dport = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); struct intel_encoder *encoder = &dport->base; - u32 level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp); if (IS_CANNONLAKE(dev_priv)) cnl_ddi_vswing_sequence(encoder, level, encoder->type); @@ -2111,7 +2108,7 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) struct intel_digital_port *dport = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); struct intel_encoder *encoder = &dport->base; - uint32_t level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp); if (IS_GEN9_BC(dev_priv)) skl_ddi_set_iboost(encoder, level, encoder->type); @@ -2183,7 +2180,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, enum port port = intel_ddi_get_encoder_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - uint32_t level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp); WARN_ON(is_mst && (port == PORT_A || port == PORT_E)); -- cgit v1.2.3 From 0ae188653b73f5bd18384caa3a4be28a8175d295 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Oct 2017 17:02:34 +0300 Subject: drm/i915: remove g4x lowfreq_avail and has_pipe_cxsr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They're unused and unsupported. Leave the reduced_clock pointers in place still, should they prove useful later on. v2: go from nuking DDI lowfreq_avail to nuking it entirely (Ville) Cc: Daniel Vetter Cc: Ville Syrjälä Suggested-by: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171017140234.20677-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_pci.c | 2 -- drivers/gpu/drm/i915/intel_display.c | 15 --------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 4 files changed, 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f01c80076c59..3c2649c27f88 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -785,7 +785,6 @@ struct intel_csr { func(has_logical_ring_contexts); \ func(has_logical_ring_preemption); \ func(has_overlay); \ - func(has_pipe_cxsr); \ func(has_pooled_eu); \ func(has_psr); \ func(has_rc6); \ @@ -3177,7 +3176,6 @@ intel_info(const struct drm_i915_private *dev_priv) #define I915_HAS_HOTPLUG(dev_priv) ((dev_priv)->info.has_hotplug) #define HAS_FW_BLC(dev_priv) (INTEL_GEN(dev_priv) > 2) -#define HAS_PIPE_CXSR(dev_priv) ((dev_priv)->info.has_pipe_cxsr) #define HAS_FBC(dev_priv) ((dev_priv)->info.has_fbc) #define HAS_CUR_FBC(dev_priv) (!HAS_GMCH_DISPLAY(dev_priv) && INTEL_INFO(dev_priv)->gen >= 7) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 1223961c3700..6458c309c039 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -193,7 +193,6 @@ static const struct intel_device_info intel_i965gm_info __initconst = { static const struct intel_device_info intel_g45_info __initconst = { GEN4_FEATURES, .platform = INTEL_G45, - .has_pipe_cxsr = 1, .ring_mask = RENDER_RING | BSD_RING, }; @@ -201,7 +200,6 @@ static const struct intel_device_info intel_gm45_info __initconst = { GEN4_FEATURES, .platform = INTEL_GM45, .is_mobile = 1, .has_fbc = 1, - .has_pipe_cxsr = 1, .supports_tv = 1, .ring_mask = RENDER_RING | BSD_RING, }; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bd62c0a65bcd..e2ac976844d8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6438,11 +6438,9 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, crtc_state->dpll_hw_state.fp0 = fp; - crtc->lowfreq_avail = false; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && reduced_clock) { crtc_state->dpll_hw_state.fp1 = fp2; - crtc->lowfreq_avail = true; } else { crtc_state->dpll_hw_state.fp1 = fp; } @@ -7137,15 +7135,6 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) } } - if (HAS_PIPE_CXSR(dev_priv)) { - if (intel_crtc->lowfreq_avail) { - DRM_DEBUG_KMS("enabling CxSR downclocking\n"); - pipeconf |= PIPECONF_CXSR_DOWNCLOCK; - } else { - DRM_DEBUG_KMS("disabling CxSR downclocking\n"); - } - } - if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { if (INTEL_GEN(dev_priv) < 4 || intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_SDVO)) @@ -8281,8 +8270,6 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); - crtc->lowfreq_avail = false; - /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ if (!crtc_state->has_pch_encoder) return 0; @@ -8941,8 +8928,6 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc, } } - crtc->lowfreq_avail = false; - return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a05ab3a1ab27..47d022d48718 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -803,7 +803,6 @@ struct intel_crtc { * some outputs connected to this crtc. */ bool active; - bool lowfreq_avail; u8 plane_ids_mask; unsigned long long enabled_power_domains; struct intel_overlay *overlay; -- cgit v1.2.3 From 2f26cdc0e2e64b1af10e0885a251fbd38e4b2336 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Oct 2017 17:03:13 +0300 Subject: drm/i915/crt: split compute_config hook by platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only the DDI hook has some actual content. Cc: Daniel Vetter Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20171017140313.20937-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_crt.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 668e8c3e791d..437339f5d098 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -343,11 +343,26 @@ intel_crt_mode_valid(struct drm_connector *connector, static bool intel_crt_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) +{ + return true; +} + +static bool pch_crt_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state) +{ + pipe_config->has_pch_encoder = true; + + return true; +} + +static bool hsw_crt_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - if (HAS_PCH_SPLIT(dev_priv)) - pipe_config->has_pch_encoder = true; + pipe_config->has_pch_encoder = true; /* LPT FDI RX only supports 8bpc. */ if (HAS_PCH_LPT(dev_priv)) { @@ -360,8 +375,7 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder, } /* FDI must always be 2.7 GHz */ - if (HAS_DDI(dev_priv)) - pipe_config->port_clock = 135000 * 2; + pipe_config->port_clock = 135000 * 2; return true; } @@ -959,11 +973,11 @@ void intel_crt_init(struct drm_i915_private *dev_priv) !dmi_check_system(intel_spurious_crt_detect)) crt->base.hpd_pin = HPD_CRT; - crt->base.compute_config = intel_crt_compute_config; if (HAS_DDI(dev_priv)) { crt->base.port = PORT_E; crt->base.get_config = hsw_crt_get_config; crt->base.get_hw_state = intel_ddi_get_hw_state; + crt->base.compute_config = hsw_crt_compute_config; crt->base.pre_pll_enable = hsw_pre_pll_enable_crt; crt->base.pre_enable = hsw_pre_enable_crt; crt->base.enable = hsw_enable_crt; @@ -971,9 +985,11 @@ void intel_crt_init(struct drm_i915_private *dev_priv) crt->base.post_disable = hsw_post_disable_crt; } else { if (HAS_PCH_SPLIT(dev_priv)) { + crt->base.compute_config = pch_crt_compute_config; crt->base.disable = pch_disable_crt; crt->base.post_disable = pch_post_disable_crt; } else { + crt->base.compute_config = intel_crt_compute_config; crt->base.disable = intel_disable_crt; } crt->base.port = PORT_NONE; -- cgit v1.2.3 From 8bd8181590501bc0bae2b6bd9f38d1371e9413a3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Oct 2017 07:37:33 +0100 Subject: drm/i915: Skip waking the device to service pwrite If the device is in runtime suspend, resuming takes time and reduces our powersaving. If this was for a small write into an object, that resume will take longer than any savings in using the indirect GGTT access to avoid the cpu cache. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20171019063733.31620-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d699ea3ab80b..026cb52ece0b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1240,7 +1240,23 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, if (ret) return ret; - intel_runtime_pm_get(i915); + if (i915_gem_object_has_struct_page(obj)) { + /* + * Avoid waking the device up if we can fallback, as + * waking/resuming is very slow (worst-case 10-100 ms + * depending on PCI sleeps and our own resume time). + * This easily dwarfs any performance advantage from + * using the cache bypass of indirect GGTT access. + */ + if (!intel_runtime_pm_get_if_in_use(i915)) { + ret = -EFAULT; + goto out_unlock; + } + } else { + /* No backing pages, no fallback, we must force GGTT access */ + intel_runtime_pm_get(i915); + } + vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE | PIN_NONFAULT | @@ -1257,7 +1273,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, if (IS_ERR(vma)) { ret = insert_mappable_node(ggtt, &node, PAGE_SIZE); if (ret) - goto out_unlock; + goto out_rpm; GEM_BUG_ON(!node.allocated); } @@ -1320,8 +1336,9 @@ out_unpin: } else { i915_vma_unpin(vma); } -out_unlock: +out_rpm: intel_runtime_pm_put(i915); +out_unlock: mutex_unlock(&i915->drm.struct_mutex); return ret; } -- cgit v1.2.3 From bd9f07590a17f3158b51fb869dca723f1f606bdc Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Thu, 19 Oct 2017 16:00:30 +0300 Subject: nvme-rdma: Fix possible double free in reconnect flow The fact that we free the async event buffer in nvme_rdma_destroy_admin_queue can cause us to free it more than once because this happens in every reconnect attempt since commit 31fdf1840170. we rely on the queue state flags DELETING to avoid this for other resources. A more complete fix is to not destroy the admin/io queues unconditionally on every reconnect attempt, but its a bit more extensive and will go in the next release. Fixes: 31fdf1840170 ("nvme-rdma: reuse configure/destroy_admin_queue") Reported-by: Yi Zhang Reviewed-by: Johannes Thumshirn Signed-off-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/host/rdma.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 92a03ff5fb4d..4dbee893a047 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -571,6 +571,12 @@ static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue) if (test_and_set_bit(NVME_RDMA_Q_DELETING, &queue->flags)) return; + if (nvme_rdma_queue_idx(queue) == 0) { + nvme_rdma_free_qe(queue->device->dev, + &queue->ctrl->async_event_sqe, + sizeof(struct nvme_command), DMA_TO_DEVICE); + } + nvme_rdma_destroy_queue_ib(queue); rdma_destroy_id(queue->cm_id); } @@ -739,8 +745,6 @@ out: static void nvme_rdma_destroy_admin_queue(struct nvme_rdma_ctrl *ctrl, bool remove) { - nvme_rdma_free_qe(ctrl->queues[0].device->dev, &ctrl->async_event_sqe, - sizeof(struct nvme_command), DMA_TO_DEVICE); nvme_rdma_stop_queue(&ctrl->queues[0]); if (remove) { blk_cleanup_queue(ctrl->ctrl.admin_q); -- cgit v1.2.3 From f04b9cc87b5fc466b1b7231ba7b078e885956c5b Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Thu, 19 Oct 2017 18:10:53 +0300 Subject: nvme-rdma: Fix error status return in tagset allocation failure We should make sure to escelate allocation failures to prevent a use-after-free in nvmf_create_ctrl. Fixes: b28a308ee777 ("nvme-rdma: move tagset allocation to a dedicated routine") Signed-off-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/host/rdma.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 4dbee893a047..87bac27ec64b 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -769,8 +769,10 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl, if (new) { ctrl->ctrl.admin_tagset = nvme_rdma_alloc_tagset(&ctrl->ctrl, true); - if (IS_ERR(ctrl->ctrl.admin_tagset)) + if (IS_ERR(ctrl->ctrl.admin_tagset)) { + error = PTR_ERR(ctrl->ctrl.admin_tagset); goto out_free_queue; + } ctrl->ctrl.admin_q = blk_mq_init_queue(&ctrl->admin_tag_set); if (IS_ERR(ctrl->ctrl.admin_q)) { @@ -850,8 +852,10 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new) if (new) { ctrl->ctrl.tagset = nvme_rdma_alloc_tagset(&ctrl->ctrl, false); - if (IS_ERR(ctrl->ctrl.tagset)) + if (IS_ERR(ctrl->ctrl.tagset)) { + ret = PTR_ERR(ctrl->ctrl.tagset); goto out_free_io_queues; + } ctrl->ctrl.connect_q = blk_mq_init_queue(&ctrl->tag_set); if (IS_ERR(ctrl->ctrl.connect_q)) { -- cgit v1.2.3 From 8bc4c256f4995d315eb9cce6e47b4885c79ff661 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 13 Oct 2017 14:58:14 -0400 Subject: drm/amdgpu: rename context priority levels Don't leak implementation details about how each priority behaves to usermode. This allows greater flexibility in the future. Squash into c2636dc53abd8269a0930bccd564f2f195dba729 Signed-off-by: Andres Rodriguez Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 8 ++++---- include/uapi/drm/amdgpu_drm.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index cd123306eda7..290cc3f9c433 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -32,14 +32,14 @@ enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) { switch (amdgpu_priority) { - case AMDGPU_CTX_PRIORITY_HIGH_HW: + case AMDGPU_CTX_PRIORITY_VERY_HIGH: return AMD_SCHED_PRIORITY_HIGH_HW; - case AMDGPU_CTX_PRIORITY_HIGH_SW: + case AMDGPU_CTX_PRIORITY_HIGH: return AMD_SCHED_PRIORITY_HIGH_SW; case AMDGPU_CTX_PRIORITY_NORMAL: return AMD_SCHED_PRIORITY_NORMAL; - case AMDGPU_CTX_PRIORITY_LOW_SW: - case AMDGPU_CTX_PRIORITY_LOW_HW: + case AMDGPU_CTX_PRIORITY_LOW: + case AMDGPU_CTX_PRIORITY_VERY_LOW: return AMD_SCHED_PRIORITY_LOW; case AMDGPU_CTX_PRIORITY_UNSET: return AMD_SCHED_PRIORITY_UNSET; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index a332de1aeb42..d0a3ea69eab6 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -172,12 +172,12 @@ union drm_amdgpu_bo_list { /* Context priority level */ #define AMDGPU_CTX_PRIORITY_UNSET -2048 -#define AMDGPU_CTX_PRIORITY_LOW_HW -1023 -#define AMDGPU_CTX_PRIORITY_LOW_SW -512 +#define AMDGPU_CTX_PRIORITY_VERY_LOW -1023 +#define AMDGPU_CTX_PRIORITY_LOW -512 #define AMDGPU_CTX_PRIORITY_NORMAL 0 /* Selecting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER */ -#define AMDGPU_CTX_PRIORITY_HIGH_SW 512 -#define AMDGPU_CTX_PRIORITY_HIGH_HW 1023 +#define AMDGPU_CTX_PRIORITY_HIGH 512 +#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023 struct drm_amdgpu_ctx_in { /** AMDGPU_CTX_OP_* */ -- cgit v1.2.3 From b285f1db6b3d7bf1c088c3700ffc54b8e676bcea Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 9 Oct 2017 16:28:16 -0400 Subject: drm/amdgpu: bump version for new AMDGPU_SCHED ioctl Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index ad02d3fbb44c..b9a32585f58d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -71,9 +71,10 @@ * - 3.19.0 - Add support for UVD MJPEG decode * - 3.20.0 - Add support for local BOs * - 3.21.0 - Add DRM_AMDGPU_FENCE_TO_HANDLE ioctl + * - 3.22.0 - Add DRM_AMDGPU_SCHED ioctl */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 21 +#define KMS_DRIVER_MINOR 22 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; -- cgit v1.2.3 From f7c5798c6d3de6086293d0bfc6434312d06f714e Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Fri, 6 Oct 2017 06:28:16 +0000 Subject: drm/amd/powerplay: get the temperature on CZ Setting the function pointer to the get the temperature on CZ. Reviewed-by: Alex Deucher Signed-off-by: Satyajit Sahu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 189f3b54a385..bd5b0c132368 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1894,6 +1894,7 @@ static const struct pp_hwmgr_func cz_hwmgr_funcs = { .get_current_shallow_sleep_clocks = cz_get_current_shallow_sleep_clocks, .get_clock_by_type = cz_get_clock_by_type, .get_max_high_clocks = cz_get_max_high_clocks, + .get_temperature = cz_thermal_get_temperature, .read_sensor = cz_read_sensor, .power_off_asic = cz_power_off_asic, .asic_setup = cz_setup_asic_task, -- cgit v1.2.3 From 6ba7cf0d5caeac0dec956d70ce7c14bc0316672a Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 15 Sep 2017 17:14:09 +0800 Subject: drm/amd/pp: export new smu messages for vega10 New messages for smu power logging. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h index cb070ebc7de1..d06ece4ac47d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h +++ b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h @@ -124,6 +124,8 @@ typedef uint16_t PPSMC_Result; #define PPSMC_MSG_NumOfDisplays 0x56 #define PPSMC_MSG_ReadSerialNumTop32 0x58 #define PPSMC_MSG_ReadSerialNumBottom32 0x59 +#define PPSMC_MSG_SetSystemVirtualDramAddrHigh 0x5A +#define PPSMC_MSG_SetSystemVirtualDramAddrLow 0x5B #define PPSMC_MSG_RunAcgBtc 0x5C #define PPSMC_MSG_RunAcgInClosedLoop 0x5D #define PPSMC_MSG_RunAcgInOpenLoop 0x5E -- cgit v1.2.3 From e83dcf1051ea81e93f9486a1d50c193f3f1d344c Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 12:21:30 +0800 Subject: drm/amd/pp: add new function point in hwmgr. used for notify SMU the allocated buffer address. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 126b44d47a99..004a40e88bde 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -363,6 +363,12 @@ struct pp_hwmgr_func { int (*set_active_display_count)(struct pp_hwmgr *hwmgr, uint32_t count); int (*set_deep_sleep_dcefclk)(struct pp_hwmgr *hwmgr, uint32_t clock); int (*start_thermal_controller)(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range); + int (*notify_cac_buffer_info)(struct pp_hwmgr *hwmgr, + uint32_t virtual_addr_low, + uint32_t virtual_addr_hi, + uint32_t mc_addr_low, + uint32_t mc_addr_hi, + uint32_t size); }; struct pp_table_func { -- cgit v1.2.3 From 52afb85e661641f654795376ab25eb51514a2f40 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 15 Sep 2017 19:39:09 +0800 Subject: drm/amd/pp: implement function notify_cac_buffer_info on Vega Used for smu power logging. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 48de45ec0eaf..ebaea5cf72f0 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -4994,6 +4994,33 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) return 0; } +static int vega10_notify_cac_buffer_info(struct pp_hwmgr *hwmgr, + uint32_t virtual_addr_low, + uint32_t virtual_addr_hi, + uint32_t mc_addr_low, + uint32_t mc_addr_hi, + uint32_t size) +{ + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SetSystemVirtualDramAddrHigh, + virtual_addr_hi); + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SetSystemVirtualDramAddrLow, + virtual_addr_low); + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramLogSetDramAddrHigh, + mc_addr_hi); + + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramLogSetDramAddrLow, + mc_addr_low); + + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramLogSetDramSize, + size); + return 0; +} + static int vega10_register_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *info) { @@ -5079,6 +5106,7 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = { .get_mclk_od = vega10_get_mclk_od, .set_mclk_od = vega10_set_mclk_od, .avfs_control = vega10_avfs_enable, + .notify_cac_buffer_info = vega10_notify_cac_buffer_info, .register_internal_thermal_interrupt = vega10_register_thermal_interrupt, }; -- cgit v1.2.3 From 26f527810bd41459341d694af6c97d81be767157 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 15 Sep 2017 19:39:52 +0800 Subject: drm/amd/pp: implement function notify_cac_buffer_info on VI Used for smu power logging. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 28 +++++++++++++++ drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 42 ++++++++++++++++++++++ drivers/gpu/drm/amd/powerplay/inc/smumgr.h | 5 +++ drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c | 10 ++++++ drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c | 10 ++++++ drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c | 10 ++++++ .../gpu/drm/amd/powerplay/smumgr/polaris10_smc.c | 10 ++++++ drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c | 10 ++++++ 8 files changed, 125 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index bd5b0c132368..96da4fc9c998 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1871,6 +1871,33 @@ static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, } } +static int cz_notify_cac_buffer_info(struct pp_hwmgr *hwmgr, + uint32_t virtual_addr_low, + uint32_t virtual_addr_hi, + uint32_t mc_addr_low, + uint32_t mc_addr_hi, + uint32_t size) +{ + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramAddrHiVirtual, + mc_addr_hi); + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramAddrLoVirtual, + mc_addr_low); + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramAddrHiPhysical, + virtual_addr_hi); + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramAddrLoPhysical, + virtual_addr_low); + + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_DramBufferSize, + size); + return 0; +} + + static const struct pp_hwmgr_func cz_hwmgr_funcs = { .backend_init = cz_hwmgr_backend_init, .backend_fini = cz_hwmgr_backend_fini, @@ -1901,6 +1928,7 @@ static const struct pp_hwmgr_func cz_hwmgr_funcs = { .dynamic_state_management_enable = cz_enable_dpm_tasks, .power_state_set = cz_set_power_state_tasks, .dynamic_state_management_disable = cz_disable_dpm_tasks, + .notify_cac_buffer_info = cz_notify_cac_buffer_info, }; int cz_init_function_pointers(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 4826b2991b7e..e32f18a99074 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -4645,6 +4645,47 @@ static int smu7_avfs_control(struct pp_hwmgr *hwmgr, bool enable) return 0; } +static int smu7_notify_cac_buffer_info(struct pp_hwmgr *hwmgr, + uint32_t virtual_addr_low, + uint32_t virtual_addr_hi, + uint32_t mc_addr_low, + uint32_t mc_addr_hi, + uint32_t size) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + data->soft_regs_start + + smum_get_offsetof(hwmgr, + SMU_SoftRegisters, DRAM_LOG_ADDR_H), + mc_addr_hi); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + data->soft_regs_start + + smum_get_offsetof(hwmgr, + SMU_SoftRegisters, DRAM_LOG_ADDR_L), + mc_addr_low); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + data->soft_regs_start + + smum_get_offsetof(hwmgr, + SMU_SoftRegisters, DRAM_LOG_PHY_ADDR_H), + virtual_addr_hi); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + data->soft_regs_start + + smum_get_offsetof(hwmgr, + SMU_SoftRegisters, DRAM_LOG_PHY_ADDR_L), + virtual_addr_low); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + data->soft_regs_start + + smum_get_offsetof(hwmgr, + SMU_SoftRegisters, DRAM_LOG_BUFF_SIZE), + size); + return 0; +} + static const struct pp_hwmgr_func smu7_hwmgr_funcs = { .backend_init = &smu7_hwmgr_backend_init, .backend_fini = &smu7_hwmgr_backend_fini, @@ -4696,6 +4737,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { .avfs_control = smu7_avfs_control, .disable_smc_firmware_ctf = smu7_thermal_disable_alert, .start_thermal_controller = smu7_start_thermal_controller, + .notify_cac_buffer_info = smu7_notify_cac_buffer_info, }; uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock, diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h index 7c9aba81cd6a..b1b27b2128f6 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h @@ -75,6 +75,11 @@ enum SMU_MEMBER { VceBootLevel, SamuBootLevel, LowSclkInterruptThreshold, + DRAM_LOG_ADDR_H, + DRAM_LOG_ADDR_L, + DRAM_LOG_PHY_ADDR_H, + DRAM_LOG_PHY_ADDR_L, + DRAM_LOG_BUFF_SIZE, }; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c index 0017b9e62404..4d672cd15785 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c @@ -2266,6 +2266,16 @@ static uint32_t ci_get_offsetof(uint32_t type, uint32_t member) return offsetof(SMU7_SoftRegisters, PreVBlankGap); case VBlankTimeout: return offsetof(SMU7_SoftRegisters, VBlankTimeout); + case DRAM_LOG_ADDR_H: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_BUFF_SIZE); } case SMU_Discrete_DpmTable: switch (member) { diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c index b1a66b5ada4a..e130b77e35c5 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c @@ -2199,6 +2199,16 @@ uint32_t fiji_get_offsetof(uint32_t type, uint32_t member) return offsetof(SMU73_SoftRegisters, VBlankTimeout); case UcodeLoadStatus: return offsetof(SMU73_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_BUFF_SIZE); } case SMU_Discrete_DpmTable: switch (member) { diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c index efb0fc033274..da0c93b73c49 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c @@ -2125,6 +2125,16 @@ uint32_t iceland_get_offsetof(uint32_t type, uint32_t member) return offsetof(SMU71_SoftRegisters, VBlankTimeout); case UcodeLoadStatus: return offsetof(SMU71_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_BUFF_SIZE); } case SMU_Discrete_DpmTable: switch (member) { diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c index c92ea38d2e15..113cadbb722e 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c @@ -2190,6 +2190,16 @@ uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member) return offsetof(SMU74_SoftRegisters, VBlankTimeout); case UcodeLoadStatus: return offsetof(SMU74_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE); } case SMU_Discrete_DpmTable: switch (member) { diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c index 1f720ccdaf99..6675a85b482b 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c @@ -2668,6 +2668,16 @@ uint32_t tonga_get_offsetof(uint32_t type, uint32_t member) return offsetof(SMU72_SoftRegisters, VBlankTimeout); case UcodeLoadStatus: return offsetof(SMU72_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_BUFF_SIZE); } case SMU_Discrete_DpmTable: switch (member) { -- cgit v1.2.3 From 66f1376269705ab66b343a811594785dfd282cf4 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 13:17:26 +0800 Subject: drm/amd/pp: move common function to smu7_smumgr.c fiji and polaris can share same setup_pwr_virus function. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h | 2007 -------------------- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 43 +- .../drm/amd/powerplay/smumgr/polaris10_smumgr.c | 43 +- drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 46 +- drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h | 4 +- 5 files changed, 49 insertions(+), 2094 deletions(-) delete mode 100644 drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h b/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h deleted file mode 100644 index 9d391f0eca94..000000000000 --- a/drivers/gpu/drm/amd/powerplay/inc/fiji_pwrvirus.h +++ /dev/null @@ -1,2007 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - */ -#ifndef _FIJI_PWRVIRUS_H_ -#define _FIJI_PWRVIRUS_H_ - -#define mmCP_HYP_MEC1_UCODE_ADDR 0xf81a -#define mmCP_HYP_MEC1_UCODE_DATA 0xf81b -#define mmCP_HYP_MEC2_UCODE_ADDR 0xf81c -#define mmCP_HYP_MEC2_UCODE_DATA 0xf81d - -struct PWR_Command_Table -{ - uint32_t data; - uint32_t reg; -}; -typedef struct PWR_Command_Table PWR_Command_Table; - -struct PWR_DFY_Section { - uint32_t dfy_cntl; - uint32_t dfy_addr_hi, dfy_addr_lo; - uint32_t dfy_size; - uint32_t dfy_data[]; -}; - -typedef struct PWR_DFY_Section PWR_DFY_Section; - -static const PWR_Command_Table PwrVirusTable_pre[] = -{ - { 0x100100b6, mmPCIE_INDEX }, - { 0x00000000, mmPCIE_DATA }, - { 0x100100b6, mmPCIE_INDEX }, - { 0x0300078c, mmPCIE_DATA }, - { 0x00000000, mmBIF_CLK_CTRL }, - { 0x00000001, mmBIF_CLK_CTRL }, - { 0x00000000, mmBIF_CLK_CTRL }, - { 0x00000003, mmBIF_FB_EN }, - { 0x00000000, mmBIF_FB_EN }, - { 0x00000001, mmBIF_DOORBELL_APER_EN }, - { 0x00000000, mmBIF_DOORBELL_APER_EN }, - { 0x014000c0, mmPCIE_INDEX }, - { 0x00000000, mmPCIE_DATA }, - { 0x014000c0, mmPCIE_INDEX }, - { 0x22000000, mmPCIE_DATA }, - { 0x014000c0, mmPCIE_INDEX }, - { 0x00000000, mmPCIE_DATA }, - /* - { 0x009f0090, mmMC_VM_FB_LOCATION }, - { 0x00000000, mmMC_CITF_CNTL }, - { 0x00000000, mmMC_VM_FB_LOCATION }, - { 0x009f0090, mmMC_VM_FB_LOCATION }, - { 0x00000000, mmMC_VM_FB_LOCATION }, - { 0x009f0090, mmMC_VM_FB_LOCATION }, - { 0x00000000, mmMC_VM_FB_OFFSET },*/ - { 0x00000000, mmRLC_CSIB_ADDR_LO }, - { 0x00000000, mmRLC_CSIB_ADDR_HI }, - { 0x00000000, mmRLC_CSIB_LENGTH }, - /* - { 0x00000000, mmMC_VM_MX_L1_TLB_CNTL }, - { 0x00000001, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR }, - { 0x00000000, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR }, - { 0x00000000, mmMC_VM_FB_LOCATION }, - { 0x009f0090, mmMC_VM_FB_LOCATION },*/ - { 0x00000000, mmVM_CONTEXT0_CNTL }, - { 0x00000000, mmVM_CONTEXT1_CNTL }, - /* - { 0x00000000, mmMC_VM_AGP_BASE }, - { 0x00000002, mmMC_VM_AGP_BOT }, - { 0x00000000, mmMC_VM_AGP_TOP },*/ - { 0x04000000, mmATC_VM_APERTURE0_LOW_ADDR }, - { 0x0400ff20, mmATC_VM_APERTURE0_HIGH_ADDR }, - { 0x00000002, mmATC_VM_APERTURE0_CNTL }, - { 0x0000ffff, mmATC_VM_APERTURE0_CNTL2 }, - { 0x00000001, mmATC_VM_APERTURE1_LOW_ADDR }, - { 0x00000000, mmATC_VM_APERTURE1_HIGH_ADDR }, - { 0x00000000, mmATC_VM_APERTURE1_CNTL }, - { 0x00000000, mmATC_VM_APERTURE1_CNTL2 }, - //{ 0x00000000, mmMC_ARB_RAMCFG }, - { 0x12011003, mmGB_ADDR_CONFIG }, - { 0x00800010, mmGB_TILE_MODE0 }, - { 0x00800810, mmGB_TILE_MODE1 }, - { 0x00801010, mmGB_TILE_MODE2 }, - { 0x00801810, mmGB_TILE_MODE3 }, - { 0x00802810, mmGB_TILE_MODE4 }, - { 0x00802808, mmGB_TILE_MODE5 }, - { 0x00802814, mmGB_TILE_MODE6 }, - { 0x00000000, mmGB_TILE_MODE7 }, - { 0x00000004, mmGB_TILE_MODE8 }, - { 0x02000008, mmGB_TILE_MODE9 }, - { 0x02000010, mmGB_TILE_MODE10 }, - { 0x06000014, mmGB_TILE_MODE11 }, - { 0x00000000, mmGB_TILE_MODE12 }, - { 0x02400008, mmGB_TILE_MODE13 }, - { 0x02400010, mmGB_TILE_MODE14 }, - { 0x02400030, mmGB_TILE_MODE15 }, - { 0x06400014, mmGB_TILE_MODE16 }, - { 0x00000000, mmGB_TILE_MODE17 }, - { 0x0040000c, mmGB_TILE_MODE18 }, - { 0x0100000c, mmGB_TILE_MODE19 }, - { 0x0100001c, mmGB_TILE_MODE20 }, - { 0x01000034, mmGB_TILE_MODE21 }, - { 0x01000024, mmGB_TILE_MODE22 }, - { 0x00000000, mmGB_TILE_MODE23 }, - { 0x0040001c, mmGB_TILE_MODE24 }, - { 0x01000020, mmGB_TILE_MODE25 }, - { 0x01000038, mmGB_TILE_MODE26 }, - { 0x02c00008, mmGB_TILE_MODE27 }, - { 0x02c00010, mmGB_TILE_MODE28 }, - { 0x06c00014, mmGB_TILE_MODE29 }, - { 0x00000000, mmGB_TILE_MODE30 }, - { 0x00000000, mmGB_TILE_MODE31 }, - { 0x000000a8, mmGB_MACROTILE_MODE0 }, - { 0x000000a4, mmGB_MACROTILE_MODE1 }, - { 0x00000090, mmGB_MACROTILE_MODE2 }, - { 0x00000090, mmGB_MACROTILE_MODE3 }, - { 0x00000090, mmGB_MACROTILE_MODE4 }, - { 0x00000090, mmGB_MACROTILE_MODE5 }, - { 0x00000090, mmGB_MACROTILE_MODE6 }, - { 0x00000000, mmGB_MACROTILE_MODE7 }, - { 0x000000ee, mmGB_MACROTILE_MODE8 }, - { 0x000000ea, mmGB_MACROTILE_MODE9 }, - { 0x000000e9, mmGB_MACROTILE_MODE10 }, - { 0x000000e5, mmGB_MACROTILE_MODE11 }, - { 0x000000e4, mmGB_MACROTILE_MODE12 }, - { 0x000000e0, mmGB_MACROTILE_MODE13 }, - { 0x00000090, mmGB_MACROTILE_MODE14 }, - { 0x00000000, mmGB_MACROTILE_MODE15 }, - { 0x00900000, mmHDP_NONSURFACE_BASE }, - { 0x00008000, mmHDP_NONSURFACE_INFO }, - { 0x3fffffff, mmHDP_NONSURFACE_SIZE }, - { 0x00000003, mmBIF_FB_EN }, - //{ 0x00000000, mmMC_VM_FB_OFFSET }, - { 0x00000000, mmSRBM_CNTL }, - { 0x00020000, mmSRBM_CNTL }, - { 0x80000000, mmATC_VMID0_PASID_MAPPING }, - { 0x00000000, mmATC_VMID_PASID_MAPPING_UPDATE_STATUS }, - { 0x00000000, mmRLC_CNTL }, - { 0x00000000, mmRLC_CNTL }, - { 0x00000000, mmRLC_CNTL }, - { 0xe0000000, mmGRBM_GFX_INDEX }, - { 0x00000000, mmCGTS_TCC_DISABLE }, - { 0x00000000, mmTCP_ADDR_CONFIG }, - { 0x000000ff, mmTCP_ADDR_CONFIG }, - { 0x76543210, mmTCP_CHAN_STEER_LO }, - { 0xfedcba98, mmTCP_CHAN_STEER_HI }, - { 0x00000000, mmDB_DEBUG2 }, - { 0x00000000, mmDB_DEBUG }, - { 0x00002b16, mmCP_QUEUE_THRESHOLDS }, - { 0x00006030, mmCP_MEQ_THRESHOLDS }, - { 0x01000104, mmSPI_CONFIG_CNTL_1 }, - { 0x98184020, mmPA_SC_FIFO_SIZE }, - { 0x00000001, mmVGT_NUM_INSTANCES }, - { 0x00000000, mmCP_PERFMON_CNTL }, - { 0x01180000, mmSQ_CONFIG }, - { 0x00000000, mmVGT_CACHE_INVALIDATION }, - { 0x00000000, mmSQ_THREAD_TRACE_BASE }, - { 0x0000df80, mmSQ_THREAD_TRACE_MASK }, - { 0x02249249, mmSQ_THREAD_TRACE_MODE }, - { 0x00000000, mmPA_SC_LINE_STIPPLE_STATE }, - { 0x00000000, mmCB_PERFCOUNTER0_SELECT1 }, - { 0x06000100, mmCGTT_VGT_CLK_CTRL }, - { 0x00000007, mmPA_CL_ENHANCE }, - { 0x00000001, mmPA_SC_ENHANCE }, - { 0x00ffffff, mmPA_SC_FORCE_EOV_MAX_CNTS }, - { 0x00000000, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000010, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000020, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000030, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000040, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000050, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000060, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000070, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000080, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000090, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x000000a0, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x000000b0, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x000000c0, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x000000d0, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x000000e0, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x000000f0, mmSRBM_GFX_CNTL }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000000, mmSRBM_GFX_CNTL }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmRLC_PG_CNTL }, - { 0x00000000, mmGRBM_STATUS2 }, - { 0x15000000, mmCP_ME_CNTL }, - { 0x50000000, mmCP_MEC_CNTL }, - { 0x00000000, mmSRBM_GFX_CNTL }, - { 0x0000000e, mmSH_MEM_APE1_BASE }, - { 0x0000020d, mmSH_MEM_APE1_LIMIT }, - { 0x00000000, mmSRBM_GFX_CNTL }, - { 0x00000000, mmSRBM_GFX_CNTL }, - { 0x00000000, mmSH_MEM_CONFIG }, - { 0x00000320, mmSH_MEM_CONFIG }, - { 0x00000000, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_RB_VMID }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmRLC_CNTL }, - { 0x00000000, mmRLC_CNTL }, - { 0x00000000, mmRLC_SRM_CNTL }, - { 0x00000002, mmRLC_SRM_CNTL }, - { 0x00000000, mmCP_ME_CNTL }, - { 0x15000000, mmCP_ME_CNTL }, - { 0x00000000, mmCP_MEC_CNTL }, - { 0x50000000, mmCP_MEC_CNTL }, - { 0x80000004, mmCP_DFY_CNTL }, - { 0x0840800a, mmCP_RB0_CNTL }, - { 0xf30fff0f, mmTCC_CTRL }, - { 0x00000002, mmTCC_EXE_DISABLE }, - { 0x000000ff, mmTCP_ADDR_CONFIG }, - { 0x540ff000, mmCP_CPC_IC_BASE_LO }, - { 0x000000b4, mmCP_CPC_IC_BASE_HI }, - { 0x00010000, mmCP_HYP_MEC1_UCODE_ADDR }, - { 0x00041b75, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000710e8, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000910dd, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000a1081, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000b016f, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000c0e3c, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000d10ec, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000e0188, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00101b5d, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00150a6c, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00170c5e, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x001d0c8c, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x001e0cfe, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00221408, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00370d7b, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00390dcb, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x003c142f, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x003f0b27, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00400e63, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00500f62, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00460fa7, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00490fa7, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x005811d4, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00680ad6, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00760b00, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00780b0c, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00790af7, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x007d1aba, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x007e1abe, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00591260, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x005a12fb, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00861ac7, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x008c1b01, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x008d1b34, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00a014b9, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00a1152e, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00a216fb, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00a41890, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00a31906, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00a50b14, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00621387, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x005c0b27, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00160a75, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC1_UCODE_DATA }, - { 0x00010000, mmCP_HYP_MEC2_UCODE_ADDR }, - { 0x00041b75, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000710e8, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000910dd, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000a1081, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000b016f, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000c0e3c, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000d10ec, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000e0188, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00101b5d, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00150a6c, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00170c5e, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x001d0c8c, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x001e0cfe, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00221408, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00370d7b, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00390dcb, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x003c142f, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x003f0b27, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00400e63, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00500f62, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00460fa7, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00490fa7, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x005811d4, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00680ad6, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00760b00, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00780b0c, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00790af7, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x007d1aba, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x007e1abe, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00591260, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x005a12fb, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00861ac7, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x008c1b01, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x008d1b34, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00a014b9, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00a1152e, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00a216fb, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00a41890, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00a31906, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00a50b14, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00621387, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x005c0b27, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00160a75, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x000f016a, mmCP_HYP_MEC2_UCODE_DATA }, - { 0x00000000, 0xFFFFFFFF }, -}; - -static const PWR_DFY_Section pwr_virus_section1 = { - .dfy_cntl = 0x80000004, - .dfy_addr_hi = 0x000000b4, - .dfy_addr_lo = 0x540fe800, - .dfy_data = { - 0x7e000200, 0x7e020201, 0x7e040204, 0x7e060205, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0x0a080102, 0x0a0a0701, 0x0a080102, 0x0a0a0701, - 0x0a080500, 0x0a0a0303, 0x0a080500, 0x0a0a0303, 0xbf810000, 0x00000000, 0x00000000, 0x00000000, - 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x54106f00, 0x000400b4, 0x00004000, 0x00804fac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - .dfy_size = 416 -}; - -static const PWR_DFY_Section pwr_virus_section2 = { - .dfy_cntl = 0x80000004, - .dfy_addr_hi = 0x000000b4, - .dfy_addr_lo = 0x540fef00, - .dfy_data = { - 0xc0031502, 0x00001e00, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - .dfy_size = 16 -}; - -static const PWR_DFY_Section pwr_virus_section3 = { - .dfy_cntl = 0x80000004, - .dfy_addr_hi = 0x000000b4, - .dfy_addr_lo = 0x540ff000, - .dfy_data = { - 0xc424000b, 0x80000145, 0x94800001, 0x94c00001, 0x95000001, 0x95400001, 0x95800001, 0xdc810000, - 0xdcc10000, 0xdd010000, 0xdd410000, 0xdd810000, 0xc4080061, 0xd8400013, 0xd8000003, 0xc40c0001, - 0x24ccffff, 0x3cd08000, 0x9500fffd, 0x1cd0ffcf, 0x7d018001, 0xc4140004, 0x050c0019, 0xd8400008, - 0x84c00000, 0x80000023, 0x80000067, 0x8000006a, 0x8000006d, 0x80000079, 0x80000084, 0x8000008f, - 0x80000099, 0x800000a0, 0x800000af, 0xd8400053, 0xc4080007, 0x388c0001, 0x08880002, 0x04100003, - 0x94c00005, 0x98800003, 0x04100004, 0x8000002d, 0x04100005, 0x8c00003f, 0x8c000043, 0x28cc0000, - 0xccc00050, 0x8c000055, 0x28080001, 0xcc000004, 0x7d808001, 0xd8400013, 0xd88130b8, 0xcd400008, - 0xdc180000, 0xdc140000, 0xdc100000, 0xdc0c0000, 0xcc800005, 0xdc080000, 0x80000168, 0xc40c000e, - 0x28cc0008, 0xccc00013, 0x90000000, 0xcd013278, 0xc4113278, 0x95000001, 0x24cc0700, 0xd8400029, - 0xc4113255, 0xcd01324f, 0xc4113254, 0x1d10ffdf, 0xcd013254, 0x10cc0014, 0x1d10c017, 0x7d0d000a, - 0xd8400013, 0xd8400008, 0xcd0130b7, 0x14cc0010, 0x90000000, 0xd9c00036, 0x8000005d, 0xd8400013, - 0xc00c4000, 0xccc130b5, 0xc40c000e, 0x28cc0008, 0xccc00013, 0xc40c0021, 0x14d00011, 0x9500fffe, - 0xdc030000, 0xd800000c, 0xd800000d, 0xc40c005e, 0x94c01b10, 0xd8400013, 0x90000000, 0xc00e0080, - 0xccc130b5, 0x8000013b, 0xc00e0800, 0xccc130b5, 0x8000013b, 0xd8400053, 0x04100006, 0x8c00003f, - 0x8c000043, 0x28cc0000, 0xccc00050, 0x8c000055, 0x280c0008, 0xccc00052, 0xd8000021, 0x28180039, - 0x80000034, 0xd8400053, 0x04100007, 0x8c00003f, 0x8c000043, 0x28cc0001, 0xccc00050, 0x8c000055, - 0x280c0010, 0xccc00052, 0x28180039, 0x80000034, 0xd8400053, 0x04100008, 0x8c00003f, 0x8c000043, - 0x28cc0003, 0xccc00050, 0x8c000055, 0x280c0020, 0xccc00052, 0x28180039, 0x80000034, 0xdc030000, - 0xd8000069, 0x28080001, 0xc428000d, 0x7ca88004, 0xcc800079, 0x04280001, 0xcc00006f, 0x8000013b, - 0x80000034, 0x04100010, 0x8c00003f, 0x8c000043, 0xccc00078, 0x8c000055, 0x28180080, 0x80000034, - 0x04100001, 0xc40c000e, 0x28cc0008, 0xccc00013, 0xcd013278, 0xc4113278, 0x95000001, 0xc00c4000, - 0xc4113254, 0x1d10c017, 0xd8400013, 0xd8400008, 0xccc130b5, 0xcd0130b7, 0x8000013b, 0x95c00001, - 0x96000001, 0x96400001, 0x96800001, 0x96c00001, 0x97000001, 0x97400001, 0x97800001, 0x97c00001, - 0xdc810000, 0xc40c000c, 0xcd4c0380, 0xcdcc0388, 0x55dc0020, 0xcdcc038c, 0xce0c0390, 0x56200020, - 0xce0c0394, 0xce4c0398, 0x56640020, 0xce4c039c, 0xce8c03a0, 0x56a80020, 0xce8c03a4, 0xcecc03a8, - 0x56ec0020, 0xcecc03ac, 0xcf0c03b0, 0x57300020, 0xcf0c03b4, 0xcf4c03b8, 0x57740020, 0xcf4c03bc, - 0xcf8c03c0, 0x57b80020, 0xcf8c03c4, 0xcfcc03c8, 0x57fc0020, 0xcfcc03cc, 0xd9000033, 0xc41c0009, - 0x25dc0010, 0x95c0fffe, 0xd8400013, 0xc41c000c, 0x05dc002f, 0xcdc12009, 0xc41d200a, 0xd8400013, - 0xcc012009, 0xd9000034, 0x25e01c00, 0x12200013, 0x25e40300, 0x12640008, 0x25e800c0, 0x12a80002, - 0x25ec003f, 0x7e25c00a, 0x7eae400a, 0x7de5c00a, 0xddc10000, 0xc02ee000, 0xcec1c200, 0xc40c005f, - 0xccc00037, 0x24d000ff, 0x31100006, 0x9500007b, 0x8c000190, 0xdc1c0000, 0xd8400013, 0xcdc1c200, - 0xc40c000c, 0xc4df0388, 0xc4d7038c, 0x51540020, 0x7d5dc01a, 0xc4e30390, 0xc4d70394, 0x51540020, - 0x7d62001a, 0xc4e70398, 0xc4d7039c, 0x51540020, 0x7d66401a, 0xc4eb03a0, 0xc4d703a4, 0x51540020, - 0x7d6a801a, 0xc4ef03a8, 0xc4d703ac, 0x51540020, 0x7d6ec01a, 0xc4f303b0, 0xc4d703b4, 0x51540020, - 0x7d73001a, 0xc4f703b8, 0xc4d703bc, 0x51540020, 0x7d77401a, 0xc4fb03c0, 0xc4d703c4, 0x51540020, - 0x7d7b801a, 0xc4ff03c8, 0xc4d703cc, 0x51540020, 0x7d7fc01a, 0xdc080000, 0xcc800013, 0xc4d70380, - 0xc4080001, 0x1c88001c, 0xcd400008, 0xc40c0083, 0x94c00010, 0xdc0e0000, 0x94c0000e, 0xc40c0082, - 0x24d00001, 0x9900000b, 0x18cc01e3, 0x3cd00004, 0x95000008, 0xc40c0085, 0x18cc006a, 0x98c00005, - 0xc40c0082, 0x18cc01e3, 0x3cd00004, 0x9900fffa, 0xdc180000, 0xdc140000, 0xdc100000, 0xdc0c0000, - 0xcc800004, 0xdc080000, 0x90000000, 0xc4080001, 0x1c88001c, 0xcd400008, 0xdc180000, 0xdc140000, - 0xdc100000, 0xdc0c0000, 0xcc800004, 0xdc080000, 0x90000000, 0xd8400051, 0xc428000c, 0x04180018, - 0x32640002, 0x9a80001f, 0x9a40001e, 0xcd800013, 0xc4293265, 0x040c0000, 0x1aac0027, 0x2aa80080, - 0xce813265, 0x9ac00017, 0xd80002f1, 0x04080002, 0x08880001, 0xd8080250, 0xd8080258, 0xd8080230, - 0xd8080238, 0xd8080240, 0xd8080248, 0xd8080268, 0xd8080270, 0xd8080278, 0xd8080280, 0xd8080228, - 0xd8000367, 0x9880fff3, 0x04080010, 0x08880001, 0xd80c0309, 0xd80c0319, 0x04cc0001, 0x9880fffc, - 0x7c408001, 0x88000000, 0xc00e0100, 0xd8400013, 0xd8400008, 0xccc130b5, 0x8000016e, 0xc4180032, - 0x29980008, 0xcd800013, 0x95800001, 0x7c40c001, 0x18d0003f, 0x24d4001f, 0x24d80001, 0x155c0001, - 0x05e80180, 0x9900000b, 0x202c003d, 0xcd800010, 0xcec1325b, 0xc42d325b, 0x96c00001, 0x86800000, - 0x80000168, 0x80000aa7, 0x80000bfc, 0x800012e9, 0xc4200007, 0x0a200001, 0xce000010, 0x80001b70, - 0x7c40c001, 0x8c000190, 0xc410001b, 0xd8000032, 0xd8000031, 0x9900091a, 0x7c408001, 0x88000000, - 0x24d000ff, 0x05280196, 0x18d4fe04, 0x29540008, 0xcd400013, 0x86800000, 0x800001b4, 0x8000032b, - 0x80000350, 0x80000352, 0x8000035f, 0x80000701, 0x8000047c, 0x8000019f, 0x80000800, 0xc419325b, - 0x1d98001f, 0xcd81325b, 0x8c00003f, 0xc4140004, 0xd8400008, 0x04100002, 0x8c000043, 0x28cc0002, - 0xccc00050, 0xc43c0044, 0x27fc0003, 0x9bc00002, 0x97c00006, 0xc00c4000, 0xccc130b5, 0x8c000055, - 0xd8400013, 0xd88130b8, 0xcd400008, 0x90000000, 0xd8400008, 0xcd400013, 0x7d40c001, 0xd8400028, - 0xd8400029, 0xd9400036, 0xc4193256, 0xc41d3254, 0x15540008, 0xcd400009, 0xcd40005b, 0xcd40005e, - 0xcd40005d, 0xd840006d, 0xc421325a, 0xc42d3249, 0x11540015, 0x19a4003c, 0x1998003f, 0x1af0007d, - 0x11dc000b, 0x1264001f, 0x15dc000d, 0x7d65400a, 0x13300018, 0x1a38003f, 0x7dd5c00a, 0x7df1c00a, - 0xcd800045, 0xcdc00100, 0xc411326a, 0xc415326b, 0xc419326c, 0xc41d326d, 0xc425326e, 0xc4293279, - 0xce800077, 0xcd000056, 0xcd400057, 0xcd800058, 0xcdc00059, 0xc4193265, 0x259c8000, 0x99c00004, - 0xce40005a, 0x29988000, 0xcd813265, 0xc4113248, 0x2510000f, 0xcd000073, 0xc418000d, 0xc411326f, - 0x17300019, 0x97000009, 0x25140fff, 0x95400007, 0xd800003a, 0x8c001b6d, 0xc4153279, 0xcd400077, - 0xcd00005f, 0xd8000075, 0x26f00001, 0x15100010, 0x7d190004, 0xcd000035, 0x97000035, 0x1af07fe8, - 0xd8800013, 0xd8400010, 0xd8400008, 0xcf00000d, 0xcf00000a, 0x8c001427, 0x04340022, 0x07740001, - 0x04300010, 0xdf430000, 0x7c434001, 0x7c408001, 0xd4412e01, 0x0434001e, 0xdf430000, 0xd4400078, - 0xdf030000, 0xd4412e40, 0xd8400013, 0xcc41c030, 0xcc41c031, 0xc43dc031, 0xccc00013, 0x04343000, - 0xc4113246, 0xc41d3245, 0xcf413267, 0x51100020, 0x7dd1c01a, 0xc4353267, 0x45dc0160, 0xc810001f, - 0x1b4c0057, 0x1b700213, 0x1b740199, 0x7f4f400a, 0x7f73400a, 0x55180020, 0x2198003f, 0xd1c00025, - 0xcf400024, 0xcd000026, 0xcd800026, 0xd8400027, 0x9bc00001, 0x248dfffe, 0xd8800013, 0xccc12e00, - 0x7c434001, 0x7c434001, 0x8c00142b, 0xc43c000e, 0x1af4007d, 0x2bfc0008, 0x33740003, 0x26d80001, - 0xcfc00013, 0x1ae8003e, 0x9680000c, 0xc4253277, 0x26680001, 0x96800009, 0x2a640002, 0xce413277, - 0xd8400013, 0xc4253348, 0xce413348, 0xc4253348, 0x96400001, 0xcfc00013, 0x9b400003, 0x958000d8, - 0x80000315, 0xc4253277, 0x04303000, 0x26680001, 0xcf013267, 0xc4193246, 0xc41d3245, 0xc4313267, - 0x96800041, 0x51980020, 0x1b342010, 0x7d9d801a, 0x1714000c, 0x25540800, 0x1b30c012, 0x459801b0, - 0x7d77400a, 0x7f37000a, 0x2b300000, 0xcf00001c, 0xd180001e, 0xd8400021, 0x04240010, 0x199c01e2, - 0x7e5e4002, 0x3e5c0004, 0x3e540002, 0xc428000f, 0x9a80ffff, 0x95c00006, 0xc80c0011, 0xc8140011, - 0x54d00020, 0x55580020, 0x80000282, 0x95400015, 0xc80c0011, 0x0a640002, 0x041c0001, 0x45980008, - 0x54d00020, 0x96400004, 0xc8140011, 0x45980004, 0x041c0000, 0xcf00001c, 0xd180001e, 0xd8400021, - 0xc428000f, 0x9a80ffff, 0x99c00003, 0xc8180011, 0x80000282, 0xc8140011, 0x55580020, 0x80000282, - 0x45980004, 0xc80c0011, 0xcf00001c, 0xd180001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc8100011, - 0xc8140011, 0x55580020, 0xd8400013, 0xccc1334e, 0xcd01334f, 0xcd413350, 0xcd813351, 0xd881334d, - 0xcfc00013, 0xc4193273, 0xc41d3275, 0xc40d3271, 0xc4113270, 0xc4153274, 0x50cc0020, 0x7cd0c01a, - 0x7cdcc011, 0x05900008, 0xcd00006a, 0xcdc0006b, 0xc41d3272, 0x7d594002, 0x54d00020, 0xd8800013, - 0xccc12e23, 0xcd012e24, 0xcdc12e25, 0xcfc00013, 0xc4193246, 0xc41d3245, 0xc4313267, 0x15540002, - 0x51980020, 0x7d9d801a, 0xc81c001f, 0x1b340057, 0x1b280213, 0x1b300199, 0x45980198, 0x7f37000a, - 0x7f2b000a, 0x55e40020, 0xcf000024, 0xd1800025, 0xcdc00026, 0xce400026, 0xd8400027, 0xcd40000d, - 0xcd40000a, 0xc40d3249, 0x20cc003c, 0xccc13249, 0xc4113274, 0xdd430000, 0xc01e0001, 0x29dc0002, - 0x04280000, 0xd8000036, 0xcc400078, 0xcc400078, 0x2d540002, 0x95400022, 0x078c0000, 0x07d40000, - 0x8c00120d, 0x8c001239, 0x8c001232, 0x04f80000, 0x057c0000, 0xcdc00013, 0xc414000d, 0xc41c0019, - 0x7dd5c005, 0x25dc0001, 0xd840007c, 0xd8400074, 0xd8400069, 0xc40c005e, 0x94c018a6, 0xd4412e22, - 0xd800007c, 0xc40c005e, 0x94c018a2, 0x95c00007, 0xc40c0019, 0x7cd4c005, 0x24cc0001, 0x94c00008, - 0x9680fffc, 0x800002e3, 0xc40c0057, 0x7cd0c002, 0x94c00003, 0x9680fffd, 0x800002e3, 0xd8000069, - 0xcfc00013, 0xcd013273, 0xcd013275, 0xd8000074, 0xc414005e, 0x9540188f, 0xcfc00013, 0xc40d3249, - 0xc013cfff, 0x7cd0c009, 0xccc13249, 0x9680000b, 0xc40c0077, 0x38d00001, 0x99000006, 0x04cc0002, - 0xdcc30000, 0xc40c005e, 0x94c01882, 0xd4400078, 0xd800000d, 0x80000304, 0x7c41c001, 0x7c41c001, - 0xd840002f, 0xc41c0015, 0x95c0ffff, 0xd8400030, 0xc41c0016, 0x95c0ffff, 0xd8000030, 0xc41c0016, - 0x99c0ffff, 0xd800002f, 0xc41c0015, 0x99c0ffff, 0xc81c001f, 0x49980198, 0x55e40020, 0x459801a0, - 0xcf000024, 0xd1800025, 0xcdc00026, 0xce400026, 0xd8400027, 0x04302000, 0xcfc00013, 0xcf013267, - 0xc4313267, 0x96800004, 0x97000001, 0xd8000036, 0x80000329, 0xd8800013, 0xcc812e00, 0x04302000, - 0xcfc00013, 0xcf013267, 0xc4313267, 0x97000001, 0xc4193256, 0xc42d3249, 0x16ec001f, 0xd8000028, - 0xd800002b, 0x1998003e, 0xcec00031, 0xd8000036, 0xd8000010, 0x97800004, 0xd8400010, 0xce00000a, - 0x1a18003e, 0xcd800008, 0x90000000, 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0x04100000, - 0x7d43c001, 0xcd400013, 0xc4093249, 0x1888003e, 0x94800015, 0xd8400074, 0x8c000671, 0xcd400013, - 0x9a400006, 0xc419324c, 0x259c0001, 0x1598001f, 0x95c0000d, 0x9580000c, 0x99000003, 0xd8400036, - 0x04100001, 0xc40c0021, 0x14d80011, 0x24dc00ff, 0x31e00002, 0x31dc0003, 0x9580fff0, 0x9a000003, - 0x99c00002, 0xd9c00036, 0x94800004, 0xd8000074, 0xc418005e, 0x95801827, 0xcf800008, 0x90000000, - 0xd8800036, 0x90000000, 0xd8c00036, 0xc424000b, 0x32640002, 0x9a400004, 0xc4180014, 0x9580ffff, - 0xd840002f, 0xc40c0021, 0x14dc0011, 0x95c0fffe, 0xccc00037, 0x8c000190, 0x90000000, 0xd8400008, - 0xd800006d, 0xc41d3246, 0xc4193245, 0x51dc0020, 0x7d9d801a, 0xd8400028, 0xd8400029, 0xc420000b, - 0x32200002, 0x9a0000ad, 0x04200032, 0xd9000010, 0xde030000, 0xd8400033, 0x04080000, 0xc43c0009, - 0x27fc0002, 0x97c0fffe, 0xc42c0015, 0x96c0ffff, 0xd800002e, 0xc42d3249, 0x1af4003e, 0x9740004d, - 0xc428000d, 0xc4080060, 0x7ca88005, 0x24880001, 0x7f4b4009, 0x97400046, 0xc4313274, 0xc4100057, - 0x7d33400c, 0x97400009, 0x28240100, 0x7e6a4004, 0xce400079, 0x1eecffdd, 0xcec13249, 0xcf013273, - 0xcf013275, 0x800003c3, 0xc429326f, 0x1aa80030, 0x96800006, 0x28240001, 0xc428000d, 0x06a80008, - 0x7e6a8004, 0xce800035, 0xc41d3272, 0x25cc0001, 0x10cc0004, 0x19e80042, 0x25dc0006, 0x11dc0001, - 0x7e8e800a, 0x7de9c00a, 0xc40d3271, 0xc4293270, 0x50cc0020, 0x7ce8c01a, 0x7cd30011, 0x11e80007, - 0x2aa80000, 0xce80001c, 0xd300001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc4300011, 0x1b30003f, - 0x33300000, 0xc4240059, 0x1660001f, 0x7e320009, 0xc0328000, 0x7e72400a, 0x0430000c, 0x9a000002, - 0x04300008, 0xc02ac000, 0x7d310002, 0x17300002, 0x2aa87600, 0x7cd0c011, 0xcdc00024, 0xd0c00025, - 0xce800026, 0x04280222, 0xce800026, 0x96000002, 0xce400026, 0xd8400027, 0xc4280058, 0x22ec003d, - 0xcec13249, 0xcd013273, 0xce813275, 0xd800007b, 0xc8380018, 0x57b00020, 0x04343108, 0xc429325d, - 0x040c3000, 0x13740008, 0x2374007e, 0x32a80003, 0xccc13267, 0xc40d3267, 0x18ec0057, 0x18e40213, - 0x18cc0199, 0x7cecc00a, 0x7ce4c00a, 0x94800003, 0xd4400078, 0x800003e7, 0x04200022, 0xde030000, - 0xccc00024, 0xd1800025, 0xcf400026, 0xd4400026, 0xd8400027, 0x04200010, 0xde030000, 0xccc00024, - 0x45980104, 0xd1800025, 0xd4400026, 0xcf800026, 0xcf000026, 0xd8400027, 0x49980104, 0x9a80000a, - 0xc81c001f, 0x45980168, 0x55e00020, 0xccc00024, 0xd1800025, 0xcdc00026, 0xce000026, 0xd8400027, - 0x800003f2, 0x8c000448, 0xcd400013, 0x040c2000, 0xccc13267, 0xc40d3267, 0x94c00001, 0xc40d3249, - 0x18cc003e, 0xd8400030, 0xc42c0016, 0x96c0ffff, 0xd8000030, 0xc42c0016, 0x9ac0ffff, 0xd800002f, - 0xc42c0015, 0x9ac0ffff, 0xd8400034, 0xc4300025, 0xc4340024, 0xc4380081, 0xcf813279, 0xcf41326e, - 0xcf01326d, 0x94c0000d, 0x254c0700, 0xc424001e, 0x10cc0010, 0x1a641fe8, 0x28cc0726, 0x2a640200, - 0xd8400013, 0xccc1237b, 0x2264003f, 0xcd400013, 0xd8813260, 0xce41325b, 0xc4240033, 0xc4280034, - 0xd9000036, 0xd8000010, 0x8c001427, 0x96400006, 0xde430000, 0xce40000c, 0xc40c005e, 0x94c01755, - 0xd4400078, 0x9680000a, 0xce80000a, 0x06a80002, 0xd8400010, 0xde830000, 0xce80000d, 0xc40c005e, - 0x94c0174c, 0xd4400078, 0xd8000010, 0x8c00142b, 0xc4393265, 0x2bb80040, 0xd8400032, 0xcf813265, - 0xc4200012, 0x9a00ffff, 0xc4100044, 0x19180024, 0xc8100072, 0x551c003f, 0x99c00003, 0x95800010, - 0x8000043d, 0xc00c8000, 0xd840006c, 0x28200000, 0x8000043f, 0xc00c4000, 0x282000f0, 0xcd400013, - 0xd8400008, 0xc4113255, 0xcd01324f, 0xd8400013, 0xd88130b8, 0xccc130b5, 0xce000053, 0x90000000, - 0x195c00e8, 0xc4100004, 0x2555fff0, 0xc0360001, 0x042c0000, 0x29540001, 0xd8400008, 0x04240000, - 0x04280004, 0xc420000b, 0x32200002, 0x9a000009, 0xcd400013, 0xcec1c200, 0xc5e124dc, 0x0aa80001, - 0x7ef6c001, 0x7e624001, 0x96000001, 0x9a80fff9, 0xc02ee000, 0xcd400013, 0x2555fff0, 0xcec1c200, - 0x29540008, 0xc81c001f, 0xcd400013, 0x55e00020, 0xc42d3255, 0xc4353259, 0xd8013260, 0x45980158, - 0xccc00024, 0xd1800025, 0xcdc00026, 0xce000026, 0xd8400027, 0x49980158, 0x45980170, 0xc4200012, - 0x16200010, 0x9a00fffe, 0xccc00024, 0xd1800025, 0xc429324f, 0xce400026, 0xce800026, 0xcec00026, - 0xcf400026, 0xd8400027, 0xcd000008, 0x90000000, 0xc40d325b, 0x7d43c001, 0x195400e8, 0x1154000a, - 0x18dc00e8, 0x05e80488, 0x18d0006c, 0x18f807f0, 0x18e40077, 0x18ec0199, 0x7e6e400a, 0x86800000, - 0x8000048e, 0x80000494, 0x800004de, 0x80000685, 0x80000686, 0x800006ac, 0x1ccc001f, 0xccc1325b, - 0xc411325d, 0x251001ef, 0xcd01325d, 0x90000000, 0xc4293254, 0x1264000a, 0xc4300004, 0x7d79400a, - 0x7e7a400a, 0x52a8001e, 0x15180001, 0x7d69401a, 0x202c007d, 0xcec1325b, 0x95000008, 0x95800028, - 0xc42d3267, 0xc4193246, 0xc41d3245, 0x1aec0028, 0xc40d325c, 0x800004cc, 0xc42d3256, 0xc419324e, - 0x26e8003f, 0x1aec003e, 0x12f4000e, 0xc41d324d, 0xc40d324f, 0x7d75401a, 0x04100002, 0x7d290004, - 0x7f8f4001, 0x7f52800f, 0x51980020, 0x7d9d801a, 0x50e00002, 0x51980008, 0x9a800002, 0x800004d1, - 0x7d0dc002, 0x6665fc00, 0x7e5e401a, 0xcec00008, 0x7da1c011, 0xd140000b, 0xd1c00002, 0x2a644000, - 0xce400002, 0x7f534002, 0x6665fc00, 0x7e76401a, 0xd1800002, 0xce400002, 0x800004d7, 0xc42d325a, - 0xc4193258, 0x1aec003e, 0xc41d3257, 0xc4213259, 0x12f4000e, 0x7d75401a, 0x51980020, 0x52200002, - 0x7d9d801a, 0xcec00008, 0x7da1c011, 0xd140000b, 0xd1c00002, 0x2a644000, 0xce400002, 0x202c003d, - 0xcf000008, 0xcfc00013, 0xcec1325b, 0xc42d325b, 0x96c00001, 0x90000000, 0xc4193260, 0x259c0007, - 0x15980004, 0x05e804e3, 0x86800000, 0x800004e7, 0x800004f0, 0x80000505, 0x8000016a, 0xc4380004, - 0xcfc00013, 0xd8400008, 0xc435325d, 0xd801325b, 0x277401ef, 0xcf41325d, 0xcf800008, 0x90000000, - 0xc4380004, 0xd8400008, 0x8c000671, 0x9640fff4, 0x17e00008, 0xc418000d, 0xce000009, 0xd84131db, - 0xcf800008, 0xcd800009, 0xc430001e, 0xcfc00013, 0xc42d325b, 0x1b301ff8, 0x2b300400, 0x2330003f, - 0x26edf000, 0x7ef2c00a, 0xd8413260, 0xcec1325b, 0x90000000, 0x05a80507, 0x86800000, 0x8000050c, - 0x80000528, 0x8000057d, 0x800005c2, 0x800005f3, 0xc4380004, 0xd8400008, 0x8c000671, 0xcfc00013, - 0x9a400012, 0x1bd400e8, 0xc42c004a, 0xcd40005e, 0xc41c004d, 0xcec0005e, 0x99c0000c, 0xc4100019, - 0x7d150005, 0x25100001, 0x99000008, 0x8c00063b, 0xcfc00013, 0xc4113277, 0x2511fffd, 0xcd013277, - 0xd801326f, 0x80000624, 0x04240012, 0x1be00fe4, 0xce413260, 0xce000066, 0xcf800008, 0x90000000, - 0xd8400068, 0xc4380004, 0xd8400008, 0x8c000671, 0xcfc00013, 0x9a400013, 0x1bd400e8, 0xc42c004a, - 0xcd40005e, 0xc41c004d, 0xcec0005e, 0x99c0000d, 0xc4100019, 0x7d150005, 0x25100001, 0x99000009, - 0xd8400067, 0x8c00063b, 0xcfc00013, 0xc4113277, 0x2511fffd, 0xcd013277, 0xd801326f, 0x80000624, - 0x1bd400e8, 0xc42c0060, 0x7ed6c005, 0x26ec0001, 0xc4113271, 0xc4153270, 0xc4193272, 0xc41d3273, - 0x04280022, 0x51100020, 0x7d51401a, 0xc4113274, 0xc4213275, 0xc4253276, 0xc4313248, 0xd1400061, - 0x2730000f, 0x13300010, 0x7db1800a, 0xcd800060, 0x96c00002, 0x05dc0008, 0xcdc00062, 0x042c3000, - 0xcd000063, 0xce000064, 0xce400065, 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, 0xce813260, - 0x52ec0020, 0x7ef2c01a, 0xc820001f, 0x1b700057, 0x1b680213, 0x1b740199, 0x46ec0188, 0x7f73400a, - 0x7f6b400a, 0x56240020, 0xcf400024, 0xd2c00025, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, - 0xc418000d, 0x17e00008, 0xce000009, 0xcec13267, 0xc42d3267, 0x26e01000, 0x9a00fffe, 0xd8400013, - 0xd9c131fc, 0xcd800009, 0xcf800008, 0x96c00001, 0x90000000, 0xc4380004, 0xd8400008, 0xc4113277, - 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, 0x11dc0008, 0x29dc0001, 0x25140001, 0x191807e4, - 0x192007ec, 0x95400004, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x9580000e, 0x09980001, 0x041c0001, - 0x95800005, 0x09980001, 0x51dc0001, 0x69dc0001, 0x9980fffd, 0x7de20014, 0x561c0020, 0xd8400013, - 0xce013344, 0xcdc13345, 0xcfc00013, 0x95400022, 0x042c3000, 0xcec13267, 0xc42d3246, 0xc4313245, - 0xc4353267, 0xd8400013, 0xc425334d, 0x26640001, 0x9640fffe, 0xc419334e, 0xc41d334f, 0xc4213350, - 0xc4253351, 0x52ec0020, 0x1b680057, 0x7ef2c01a, 0x1b700213, 0x1b740199, 0x46ec01b0, 0x7f6b400a, - 0x7f73400a, 0xcfc00013, 0xcf400024, 0xd2c00025, 0xcd800026, 0xcdc00026, 0xce000026, 0xce400026, - 0x042c2000, 0xd8400027, 0xcec13267, 0xc42d3267, 0x96c00001, 0x04280032, 0xce813260, 0xd8800068, - 0xcf800008, 0x90000000, 0xc4380004, 0xd8400008, 0x2010007d, 0xcd01325b, 0xc411325b, 0x1910003e, - 0x9500fffe, 0x04100040, 0xcd00001b, 0xd8400021, 0xc410000f, 0x9900ffff, 0x04100060, 0xcd00001b, - 0xd8400021, 0xc410000f, 0x9900ffff, 0xcfc00013, 0x2010003d, 0xcd01325b, 0xc4113277, 0x25140001, - 0x191807e4, 0x9540000b, 0x2511fffd, 0xcd013277, 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, - 0x11dc0008, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x95800005, 0xd8400013, 0xd8013344, 0xd8013345, - 0xcfc00013, 0xc4180050, 0xc41c0052, 0x04280042, 0xcd813273, 0xcdc13275, 0xce813260, 0xd9000068, - 0xd8400067, 0xcf800008, 0x90000000, 0x07d40000, 0x8c00120d, 0x8c00124f, 0x8c001232, 0x057c0000, - 0x042c3000, 0xc4380004, 0xcfc00013, 0xd8400008, 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, - 0x52ec0020, 0x7ef2c01a, 0x1b680057, 0x1b700213, 0x1b740199, 0xc820001f, 0x46ec0190, 0x7f6b400a, - 0x7f73400a, 0x56240020, 0xcf400024, 0xd2c00025, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, - 0xcfc00013, 0xcec13267, 0xc4153249, 0x2154003d, 0xc41c0019, 0x1bd800e8, 0x7dd9c005, 0x25dc0001, - 0xc42c004a, 0xcd80005e, 0xc420004d, 0xcec0005e, 0x11dc0010, 0x7e1e000a, 0xcd413249, 0xce01326f, - 0x28340001, 0x05980008, 0x7f598004, 0xcd800035, 0x1be800e8, 0xc42c004a, 0xce80005e, 0xd801327a, - 0xd800005f, 0xd8000075, 0xd800007f, 0xc424004c, 0xce41326e, 0xcec0005e, 0x28240100, 0x7e6a4004, - 0xce400079, 0xc435325d, 0x277401ef, 0x04240020, 0xce41325e, 0xd801325b, 0xd8013260, 0xcf41325d, - 0xda000068, 0xcf800008, 0x90000000, 0xc4113277, 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, - 0x11dc0008, 0x29dc0001, 0x25140001, 0x9540002d, 0xd8400013, 0xcdc1334a, 0xcfc00013, 0x042c3000, - 0xcec13267, 0xc42d3246, 0xc4313245, 0xc4353267, 0xd8400013, 0xc425334d, 0x26640001, 0x9640fffe, - 0xc419334e, 0xc41d334f, 0xc4213350, 0xc4253351, 0x52ec0020, 0x1b680057, 0x7ef2c01a, 0x1b700213, - 0x1b740199, 0x46ec01b0, 0x7f6b400a, 0x7f73400a, 0xcfc00013, 0xcf400024, 0xd2c00025, 0xcd800026, - 0xcdc00026, 0xce000026, 0xce400026, 0x042c2000, 0xd8400027, 0xcec13267, 0xc42d3267, 0x96c00001, - 0xc41c000b, 0xc420000c, 0x11dc0002, 0x7de1c001, 0x11dc0008, 0xd8400013, 0xcdc1334a, 0xcfc00013, - 0x90000000, 0xc430000b, 0x33300002, 0x04240000, 0x9b000010, 0x1be000e8, 0x042c0000, 0xc0360001, - 0x04280004, 0xd8400013, 0xcec1c200, 0xc63124dc, 0x0aa80001, 0x7ef6c001, 0x7e724001, 0x97000001, - 0x9a80fff9, 0xc02ee000, 0xd8400013, 0xcec1c200, 0x90000000, 0x90000000, 0xc4253260, 0x7fc14001, - 0xc40d3249, 0x18cc003e, 0x98c00005, 0x194c1c03, 0xccc0003b, 0xc40c002d, 0x80000697, 0xc420004a, - 0x194c00e8, 0xccc0005e, 0xc40c004c, 0xc431326d, 0x27301fff, 0xce00005e, 0x7cf0c00d, 0x98c00003, - 0x8c0007e0, 0x95c00008, 0xc430001e, 0x1b301ff8, 0x2b300400, 0x2330003f, 0xcd400013, 0xcf01325b, - 0x90000000, 0xcd400013, 0xd801325b, 0xc411325d, 0x251001ef, 0xcd01325d, 0x25100007, 0x31100005, - 0x9900008e, 0xc40c0007, 0xd9000010, 0x8000075e, 0x202c007d, 0xcec1325b, 0xc4293265, 0xc4353254, - 0x26a9feff, 0xc4380004, 0xd8400008, 0x1374000b, 0xc40c000d, 0xd8000009, 0x1774000d, 0xd8400013, - 0xc41d30b8, 0xcfc00013, 0x95c00008, 0xc411325d, 0xd801325b, 0xccc00009, 0xcf800008, 0x251001ef, - 0xcd01325d, 0x90000000, 0xce813265, 0xcf400100, 0xc00ac006, 0xc00e0000, 0x28880700, 0x28cc0014, - 0x8c0006de, 0x14cc0010, 0x30d4000f, 0x04cc0001, 0x10cc0010, 0x28cc0014, 0x99400009, 0xd8400013, - 0xc41530b8, 0xcfc00013, 0xc4193265, 0x19980028, 0x99400003, 0x99800002, 0x800006c8, 0xcfc00013, - 0xc411325d, 0xd801325b, 0xcf800008, 0x251001ef, 0xcd01325d, 0x90000000, 0x15600008, 0xce000009, - 0xc8380023, 0xc4180081, 0x11a00002, 0x7fa38011, 0xc4100026, 0x05980008, 0x7d1a0002, 0x282c2002, - 0x3e280008, 0xcec00013, 0xc4300027, 0x042c0008, 0xd3800025, 0xcf000024, 0x202400d0, 0x7ca48001, - 0xcc800026, 0xccc00026, 0x28240006, 0xcc000026, 0x0a640001, 0x9a40fffe, 0x9a800004, 0x32280000, - 0x9a800002, 0x9a000000, 0xd8400027, 0x24d8003f, 0xd840003c, 0xcec0003a, 0xd8800013, 0xcd81a2a4, - 0x90000000, 0xc41d325d, 0x25dc0007, 0xc40d3249, 0x18cc003e, 0x94c0000a, 0xc420004a, 0x194c00e8, - 0xccc0005e, 0xc40c004c, 0xc431326d, 0x27301fff, 0xce00005e, 0x7cf0c00d, 0x80000712, 0x194c1c03, - 0xccc0003b, 0xc40c002d, 0x05e80714, 0x86800000, 0x8000071c, 0x80000720, 0x80000747, 0x8000071d, - 0x800007c4, 0x80000732, 0x80000745, 0x80000744, 0x90000000, 0x98c00006, 0x8000072e, 0x90000000, - 0x98c00003, 0x8c0007e0, 0x95c0000c, 0xcd400013, 0xc4253265, 0x2a64008c, 0xce413265, 0xc430001e, - 0x1b301fe8, 0x2b300400, 0x2330003f, 0xd8013260, 0xcf01325b, 0x90000000, 0xc40c0007, 0xd9000010, - 0x04240000, 0x8000075e, 0x98c0fff1, 0x8c0007e0, 0x95c00002, 0x80000723, 0xcd400013, 0xc41f02f1, - 0x95c00004, 0xd8013247, 0xd801325d, 0x80000743, 0xd8813247, 0xd801325d, 0xc4100004, 0xd8400008, - 0xd8400013, 0xd88130b8, 0xcd000008, 0x90000000, 0x04100001, 0x98c0ffde, 0x8000072e, 0x98c00003, - 0x8c0007e0, 0x95c00012, 0xc4340004, 0xd8400008, 0x15600008, 0xc418000d, 0xce000009, 0xd8400013, - 0xd84131db, 0xcf400008, 0xcd800009, 0xc430001e, 0x1b301ff8, 0x2b300400, 0x2330003f, 0xcd400013, - 0xd8413260, 0xcf01325b, 0x90000000, 0xc40c0007, 0xd9000010, 0x04240000, 0xcd400013, 0x041c3000, - 0xcdc13267, 0xc41d3267, 0xc41d3265, 0x25dc8000, 0x95c00007, 0xc41c004a, 0x195800e8, 0xcd80005e, - 0xc418004c, 0xcd81326e, 0xcdc0005e, 0xc41d3265, 0x25dd7fff, 0xcdc13265, 0xc41d3246, 0xc4193245, - 0xc42d3267, 0x51e00020, 0x7e1a001a, 0x46200200, 0x04283247, 0x04300033, 0x1af80057, 0x1af40213, - 0x042c000c, 0x7f7b400a, 0x7f6f400a, 0xcf400024, 0xd2000025, 0xcd800026, 0xcdc00026, 0xc6990000, - 0x329c325d, 0x99c00008, 0x329c3269, 0x99c00006, 0x329c3267, 0x95c00005, 0xc01defff, 0x7d9d8009, - 0x8000078a, 0x25980000, 0x0b300001, 0x06a80001, 0xcd800026, 0x9b00fff2, 0xd8400027, 0xc43c0012, - 0x9bc0ffff, 0xcd400013, 0xd801325b, 0xc431325a, 0xc03e7ff0, 0x7f3f0009, 0xcf01325a, 0xc4313249, - 0x1f30001f, 0xcf013249, 0xc03e4000, 0xcfc13254, 0xcd400013, 0xd8013254, 0xc431325d, 0xd801324f, - 0xd8013255, 0xd8013247, 0xd801325d, 0x1b300028, 0x8c00120d, 0x8c001219, 0x8c001232, 0xc4380004, - 0xd8400008, 0xd8400013, 0x9900000d, 0xd88130b8, 0x9700000b, 0xc43d30b5, 0x1bf0003a, 0x9b000b80, - 0x203c003a, 0xc430000e, 0x27300700, 0x13300014, 0x2b300001, 0xcf0130b7, 0xcfc130b5, 0x46200008, - 0xcf400024, 0xd2000025, 0xd8000026, 0xd8400027, 0x043c2000, 0xcd400013, 0xcfc13267, 0xc43d3267, - 0x9bc00001, 0xccc00010, 0xcf800008, 0x90000000, 0xc4080007, 0xd9000010, 0xc4193260, 0x259c0003, - 0x31dc0003, 0x95c00014, 0x040c3000, 0xd8400008, 0xccc13267, 0xc40d3267, 0x18ec0057, 0x18e40213, - 0x18cc0199, 0x7cecc00a, 0x7ce4c00a, 0xc4193246, 0xc41d3245, 0x51980020, 0x7d9d801a, 0x8c000448, - 0xcd400013, 0x040c2000, 0xccc13267, 0xc40d3267, 0x94c00001, 0xcc800010, 0xd801325d, 0x90000000, - 0xc418000b, 0x31980002, 0x041c0000, 0x9980001c, 0x19580066, 0x15600008, 0x040c0000, 0xc0120001, - 0x11980003, 0x04240004, 0x7da18001, 0xc4200007, 0xc4340004, 0xd9000010, 0xd8400008, 0xd8400013, - 0xccc1c200, 0xc41d24db, 0x7cd0c001, 0x0a640001, 0x7dd9c005, 0x25dc0001, 0x99c00002, 0x9a40fff8, - 0xc418005e, 0x9580137b, 0xc00ee000, 0xd8400013, 0xccc1c200, 0xce000010, 0xcf400008, 0x90000000, - 0xd840004f, 0xc4113269, 0x19080070, 0x190c00e8, 0x2510003f, 0x2518000f, 0xcd813268, 0x05a80809, - 0x86800000, 0x8000080e, 0x8000080f, 0x80000898, 0x80000946, 0x800009e1, 0x80000a5a, 0x04a80811, - 0x86800000, 0x80000815, 0x80000834, 0x8000085e, 0x8000085e, 0x04341001, 0xcf400013, 0xc4380004, - 0xd8400008, 0xc42d3045, 0xcec1c091, 0x31300021, 0x9700000b, 0xd84002f1, 0xd8400013, 0xc43130b8, - 0x27300001, 0xc4293059, 0x56a8001f, 0x7f2b000a, 0xcf800008, 0x9b000241, 0x8000084a, 0xcf400013, - 0xd8400008, 0xc43130b6, 0x9b000003, 0xc02f0001, 0xcec130b6, 0xc4252087, 0x5668001a, 0x26a80005, - 0x9a80fffd, 0xcf400013, 0xd80130b6, 0x8000084a, 0xc4380004, 0xd8400008, 0x04341001, 0xcf400013, - 0xc431ecaa, 0x27300080, 0x9b000010, 0xc02e0001, 0xcec130b6, 0xcf400013, 0xd80130b6, 0x31300021, - 0x9700000a, 0xd84002f1, 0xd8400013, 0xc43130b8, 0x27300001, 0xc4293059, 0x56a8001f, 0x7f2b000a, - 0xcf800008, 0x9b00021d, 0xdd410000, 0x040c0005, 0xd84802e9, 0x8c001a41, 0xc43b02f1, 0x9b800006, - 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0xcf800008, 0xcec80278, 0x56f00020, 0xcf080280, - 0x8c001608, 0xdc140000, 0xcd400013, 0xd8813247, 0xd80802e9, 0x8000085e, 0xcd400013, 0x31100011, - 0x950001fa, 0xc02e0001, 0x2aec0008, 0xc01c0020, 0xc0180001, 0xc00c0007, 0x11a40006, 0x7de6000a, - 0x10e40008, 0x7e26000a, 0x7e2e000a, 0xce000013, 0xc4113254, 0x1d10ffdf, 0x2110003e, 0xcd013254, - 0xd801324f, 0xd8013255, 0x1d10ff9e, 0xcd013254, 0xd8013247, 0xd801325d, 0xd801325e, 0xc0245301, - 0xce413249, 0xd801325f, 0xc425326c, 0xc0121fff, 0x29108eff, 0x7e524009, 0xce41326c, 0xc425325a, - 0xc0127ff0, 0x7e524009, 0xce41325a, 0xc425325b, 0xc0131fff, 0x7e524009, 0xce41325b, 0xd801326d, - 0xd801326e, 0xd8013279, 0x94c00003, 0x08cc0001, 0x80000866, 0xc00c0007, 0x95800003, 0x09980001, - 0x80000866, 0xc0100010, 0x7dd2400c, 0x9a400004, 0xc0180003, 0x7dd1c002, 0x80000866, 0x80000a5a, - 0x04a8089a, 0x86800000, 0x8000089e, 0x800008fa, 0x80000945, 0x80000945, 0x31300022, 0x97000007, - 0xc4380004, 0xd8400008, 0xd8400013, 0xc43130b8, 0x27300001, 0xcf800008, 0xcd400013, 0x04183000, - 0xcd813267, 0xc4113246, 0xc4193245, 0x51100020, 0x7d91801a, 0x459801e0, 0xc4313267, 0x2738000f, - 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, - 0xd180001e, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8300011, 0x97000036, 0x45980008, 0xd180001e, - 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8340011, 0x9740002f, 0xc43c0004, 0xd8400008, 0xd8400013, - 0x13b80001, 0xc79d3300, 0xc7a13301, 0x96000001, 0xd8393300, 0xc0260001, 0xce793301, 0xc424005e, - 0x964012a4, 0x7c028009, 0x9740001c, 0x27580001, 0x99800004, 0x57740001, 0x06a80400, 0x800008d2, - 0xc4180006, 0x9980ffff, 0x29640001, 0xce40001a, 0x242c0000, 0x06ec0400, 0x57740001, 0x27580001, - 0x9980fffd, 0xc02620c0, 0xce41c078, 0xce81c080, 0xcc01c081, 0xcf01c082, 0x57240020, 0xce41c083, - 0xc0260400, 0x7e6e400a, 0xce41c084, 0x7eae8001, 0x7f2f0011, 0x800008d2, 0xc4180006, 0x9980ffff, - 0xcdf93300, 0xce393301, 0xcfc00008, 0xcd400013, 0xc43c0004, 0xd8400008, 0x04182000, 0xcd813267, - 0xcfc00008, 0x80000903, 0x31240022, 0x96400008, 0x04100001, 0xc4380004, 0xd8400008, 0xd8400013, - 0xc43130b8, 0x27300001, 0xcf800008, 0xc4af0280, 0xc4b30278, 0x52ec0020, 0x7ef2c01a, 0x7ec30011, - 0x32f80000, 0x9b800011, 0x043c0020, 0x04280000, 0x67180001, 0x0bfc0001, 0x57300001, 0x95800006, - 0x8c001628, 0x9a400003, 0xd981325d, 0x80000915, 0xd9c1325d, 0x06a80001, 0x9bc0fff6, 0x7f818001, - 0x8c001606, 0x7d838001, 0x94800010, 0xcd400013, 0xc41d3259, 0xc421325a, 0x16240014, 0x12640014, - 0x1a2801f0, 0x12a80010, 0x2620ffff, 0x7e2a000a, 0x7de1c001, 0x7e5e400a, 0x9b800002, 0x2264003f, - 0xce41325a, 0xd8013259, 0xc40c0007, 0xd9000010, 0x8c00075e, 0xc4af0228, 0x043c0000, 0x66d80001, - 0x95800010, 0x04300002, 0x1330000d, 0x13f40014, 0x7f73400a, 0xcf400013, 0x04380040, 0xcf80001b, - 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380060, 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, - 0x07fc0001, 0x56ec0001, 0x33e80010, 0x9680ffec, 0x80000a5a, 0x80000a5a, 0x04a80948, 0x86800000, - 0x8000094c, 0x8000099b, 0x800009e0, 0x800009e0, 0xc43c0004, 0xd8400008, 0xcd400013, 0x04183000, - 0xcd813267, 0xc4113246, 0xc4193245, 0x51100020, 0x7d91801a, 0x459801e0, 0xc4313267, 0x2738000f, - 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, - 0xd180001e, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8300011, 0x97000033, 0x45980008, 0xd180001e, - 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc8340011, 0x9740002c, 0xd8400013, 0x13b80001, 0xc79d3300, - 0xc7a13301, 0x96000001, 0xd8393300, 0xc0260001, 0xce793301, 0xc424005e, 0x964011fe, 0x7c028009, - 0x9740001c, 0x27580001, 0x99800004, 0x57740001, 0x06a80400, 0x80000978, 0xc4180006, 0x9980ffff, - 0x29640001, 0xce40001a, 0x242c0000, 0x06ec0400, 0x57740001, 0x27580001, 0x9980fffd, 0xc0260010, - 0xce41c078, 0xcf01c080, 0x57240020, 0xce41c081, 0xce81c082, 0xcc01c083, 0xc0260800, 0x7e6e400a, - 0xce41c084, 0x7eae8001, 0x7f2f0011, 0x80000978, 0xc4180006, 0x9980ffff, 0xcdf93300, 0xce393301, - 0x04182000, 0xcd813267, 0xcfc00008, 0xcd400013, 0xc4193246, 0xc41d3245, 0x51980020, 0x7dda801a, - 0x7d41c001, 0x7e838011, 0xd84802e9, 0x8c001802, 0x469c0390, 0xc4313267, 0x04183000, 0xcd813267, - 0x1b342010, 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, - 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4200011, 0x45dc0004, 0xd1c0001e, - 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4240011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, - 0x9980ffff, 0xc4280011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc42c0011, - 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4300011, 0x45dc0004, 0xd1c0001e, - 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4340011, 0x45dc0004, 0xd1c0001e, 0xd8400021, 0xc418000f, - 0x9980ffff, 0xc4380011, 0xcd400013, 0x04182000, 0xcd813267, 0x043c0001, 0x8c0014df, 0x80000a5a, - 0x80000a5a, 0x31280014, 0xce8802ef, 0x9a800062, 0x31280034, 0x9a800060, 0x04a809e8, 0x86800000, - 0x800009ec, 0x80000a45, 0x80000a59, 0x80000a59, 0xcd400013, 0xc4113246, 0xc4193245, 0x51100020, - 0x7d91801a, 0x45980400, 0xc4b30258, 0xc4a70250, 0x53300020, 0x7e72401a, 0xc4313267, 0x1b342010, - 0x172c000c, 0x26ec0800, 0x1b30c012, 0x7ef7400a, 0x7f37000a, 0x2b300000, 0xcf00001c, 0x042c0020, - 0x66740001, 0x97400041, 0xcd400013, 0x04383000, 0xcf813267, 0xc4393267, 0x9b800001, 0xd180001e, - 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4300011, 0x1b38007e, 0x33b40003, 0x9b400003, 0x4598001c, - 0x9740002f, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc40c0011, 0x45980004, - 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4100011, 0x45980004, 0xd180001e, 0xd8400021, - 0xc438000f, 0x9b80ffff, 0xc4340011, 0xcf4002eb, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, - 0x9b80ffff, 0xc4340011, 0xcf4002ec, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, - 0xc4340011, 0xcf4002ed, 0x45980004, 0xd180001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4340011, - 0xcf4002ee, 0x45980004, 0xcd400013, 0x04382000, 0xcf813267, 0xd84802e9, 0x8c001715, 0xcd400013, - 0x04382000, 0xcf813267, 0x56640001, 0x0aec0001, 0x9ac0ffbc, 0xc4380004, 0xd8400008, 0x04341001, - 0xcf400013, 0x94800005, 0xc431ecaa, 0x27300080, 0x97000002, 0x80000a55, 0xc43130b6, 0x233c0032, - 0xcfc130b6, 0xcf400013, 0xcf0130b6, 0xc49302ef, 0x99000003, 0xcd400013, 0xd8413247, 0xcf800008, - 0x80000a5a, 0x80000a5a, 0xcd400013, 0x04180001, 0x5198001f, 0xcd813268, 0xc4193269, 0x2598000f, - 0x9980fffe, 0xd80002f1, 0xcd400013, 0xd8013268, 0xd800004f, 0x90000000, 0xcd400013, 0x04380001, - 0x53b8001f, 0x7db9801a, 0xcd813268, 0x80000a5e, 0xd8400029, 0xc40c005e, 0x94c01106, 0xd8800013, - 0xcc412e01, 0xcc412e02, 0xcc412e03, 0xcc412e00, 0x80000aa7, 0xd8400029, 0xc40c005e, 0x94c010fd, - 0x7c40c001, 0x50640020, 0x7ce4c01a, 0xd0c00072, 0xc80c0072, 0x58e801fc, 0x12a80009, 0x2aa80000, - 0xd0c0001e, 0xce80001c, 0xd8400021, 0xc424000f, 0x9a40ffff, 0x04240010, 0x18dc01e2, 0x7e5e4002, - 0x3e5c0003, 0x3e540002, 0x95c00006, 0xc8180011, 0xc8100011, 0xc8100011, 0x55140020, 0x80000aa2, - 0x9540000a, 0xc8180011, 0x44cc0008, 0x55900020, 0xd0c0001e, 0xd8400021, 0xc424000f, 0x9a40ffff, - 0xc4140011, 0x80000aa2, 0x44cc0004, 0xc4180011, 0xd0c0001e, 0xd8400021, 0xc424000f, 0x9a40ffff, - 0xc8100011, 0x55140020, 0xd8800013, 0xcd812e01, 0xcd012e02, 0xcd412e03, 0xcc412e00, 0xc428000e, - 0x2aa80008, 0xce800013, 0xc4253249, 0x2264003f, 0xce413249, 0xce800013, 0xc4253249, 0x96400001, - 0xd800002a, 0xc410001a, 0xc40c0021, 0xc4140028, 0x95000005, 0x1e64001f, 0xce800013, 0xce413249, - 0x80001b70, 0x14d00010, 0xc4180030, 0xc41c0007, 0x99000004, 0x99400009, 0x9980000c, 0x80000ab1, - 0xccc00037, 0x8c000190, 0xc420001c, 0xd8000032, 0x9a0010ac, 0x80000aa7, 0xd880003f, 0x95c00002, - 0xd8c0003f, 0x80001082, 0xd8800040, 0x95c00002, 0xd8c00040, 0x800010de, 0xc010ffff, 0x18d403f7, - 0x7d0cc009, 0xc41b0367, 0x7d958004, 0x7d85800a, 0xdc1e0000, 0x90000000, 0xc424000b, 0x32640002, - 0x7c40c001, 0x18d001fc, 0x05280adc, 0x86800000, 0x80000af1, 0x80000adf, 0x80000ae7, 0x8c000ace, - 0xd8c00013, 0x96400002, 0xd8400013, 0xcd8d2000, 0x99c00010, 0x7c408001, 0x88000000, 0x18d803f7, - 0xc010ffff, 0x7d0cc009, 0x04140000, 0x11940014, 0x29544001, 0x9a400002, 0x29544003, 0xcd400013, - 0x80000af4, 0xd8c00013, 0x96400002, 0xd8400013, 0xd44d2000, 0x7c408001, 0x88000000, 0xc424000b, - 0x32640002, 0x7c40c001, 0xd8c00013, 0x96400002, 0xd8400013, 0xd44dc000, 0x7c408001, 0x88000000, - 0x7c40c001, 0x18d0003c, 0x95000006, 0x8c000ace, 0xd8800013, 0xcd8d2c00, 0x99c00003, 0x80000b0a, - 0xd8800013, 0xd44d2c00, 0x7c408001, 0x88000000, 0x7c40c001, 0x28148004, 0x24d800ff, 0xccc00019, - 0xcd400013, 0xd4593240, 0x7c408001, 0x88000000, 0xd8400029, 0xc40c005e, 0x94c0105e, 0x7c410001, - 0x50540020, 0x7c418001, 0x2198003f, 0x199c0034, 0xc40c0007, 0x95c00028, 0xc428000e, 0x2aa80008, - 0xce800013, 0xc42d324f, 0xc4313255, 0x7ef3400c, 0x9b400021, 0xd800002a, 0x80001b70, 0xc40c0007, - 0x14e80001, 0x9a8000af, 0xd9000010, 0x041c0002, 0x042c01c8, 0x8c000d61, 0xccc00010, 0xd8400029, - 0xc40c005e, 0x94c01043, 0x7c410001, 0x50540020, 0x7c418001, 0x18a01fe8, 0x3620005c, 0x9a00000e, - 0x2464003f, 0xd8400013, 0xc6290ce7, 0x16ac001f, 0x96c00004, 0x26ac003f, 0x7ee6c00d, 0x96c00005, - 0x06200001, 0x2620000f, 0x9a00fff8, 0x8000016a, 0xce000367, 0xc424005e, 0x9640102e, 0xc428000e, - 0x199c0037, 0x19a00035, 0x2aa80008, 0xce800013, 0x95c0005d, 0xd800002a, 0xc42d3256, 0xc431325a, - 0x2330003f, 0x16f8001f, 0x9780000d, 0xc4253248, 0xc035f0ff, 0x7e764009, 0x19b401f8, 0x13740008, - 0x7e76400a, 0xce800013, 0xce413248, 0xcf01325a, 0xce800013, 0xc431325a, 0x97000001, 0x7d15001a, - 0xd1000072, 0xc8100072, 0x55140020, 0x199c0034, 0xd8400010, 0xd8400029, 0x9b800004, 0x1ae4003e, - 0xce400008, 0x80000b7c, 0xc4353254, 0x16a80008, 0x1aec003c, 0x19a4003f, 0x12a80015, 0x12ec001f, - 0x1374000b, 0x7eae800a, 0xc02e4000, 0x1774000d, 0x7eae800a, 0xce400008, 0x7f6b400a, 0x95c00005, - 0xc43d3248, 0x1bfc01e8, 0x13fc0018, 0x7dbd800a, 0x1d98ff15, 0x592c00fc, 0xcd80000a, 0x12e00016, - 0x7da1800a, 0x592c007e, 0x12e00015, 0x7da1800a, 0xd1000001, 0xcd800001, 0x11a0000c, 0x1264001e, - 0x1620000c, 0x7e26000a, 0x7e32000a, 0x12e4001b, 0x7e26000a, 0x5924007e, 0x12640017, 0x7e26000a, - 0x19a4003c, 0x12640018, 0x7e26000a, 0xd800002a, 0xce01325a, 0xcd013257, 0xcd413258, 0xc429325a, - 0xc40c005e, 0x94c00fdb, 0x96800001, 0x95c00003, 0x7c40c001, 0x7c410001, 0x9780f5ca, 0xcf400100, - 0xc40c0007, 0xd9000010, 0x8c00120d, 0x8c001219, 0x8c001232, 0xccc00010, 0x8c001b6d, 0x7c408001, - 0x88000000, 0xc42d324e, 0xc431324d, 0x52ec0020, 0x7ef2c01a, 0xc435324f, 0xc4293256, 0x52ec0008, - 0x07740003, 0x04240002, 0x269c003f, 0x7e5e4004, 0x7f67000f, 0x97000003, 0x7f674002, 0x0b740001, - 0x53740002, 0x7ef6c011, 0x1ab42010, 0x1ab8c006, 0x16a8000c, 0x26a80800, 0x2b740000, 0x7f7b400a, - 0x7f6b400a, 0xcf40001c, 0xd2c0001e, 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4180011, 0x9a000003, - 0x8c000bec, 0x80000b47, 0xc42c001d, 0xc4313256, 0x1b34060b, 0x1b300077, 0x7f37000a, 0x13300017, - 0x04340100, 0x26ec00ff, 0xc03a8004, 0x7ef6c00a, 0x7f3b000a, 0x7ef2c00a, 0xcec1325b, 0x80000c16, - 0xc40c0032, 0xc410001d, 0x28cc0008, 0xccc00013, 0xc415325b, 0x7c418001, 0x7c418001, 0x18580037, - 0x251000ff, 0xc421325d, 0x262001ef, 0xce01325d, 0x99800004, 0x7d15400a, 0xcd41325b, 0x80000168, - 0x1d54001f, 0xcd41325b, 0x7c408001, 0x88000000, 0xc428000b, 0xc42c000c, 0x12a80001, 0x26a80004, - 0x7eae800a, 0xc40c0021, 0xc4340028, 0x14f00010, 0xc4380030, 0xc43c0007, 0xcd280200, 0xcd680208, - 0xcda80210, 0x9b00000c, 0x9b400014, 0x9b800017, 0xc428000b, 0xc42c000c, 0x12a80001, 0x26a80004, - 0x7eae800a, 0xc6930200, 0xc6970208, 0xc69b0210, 0x90000000, 0x17300001, 0x9b000005, 0xccc00037, - 0x8c000190, 0xd8000032, 0x90000000, 0xd8000028, 0xd800002b, 0x80000168, 0xd900003f, 0x97c00002, - 0xd940003f, 0x80001082, 0xd9000040, 0x97c00002, 0xd9400040, 0x800010de, 0xc40c0021, 0x14fc0011, - 0x24f800ff, 0x33b80001, 0x97c0fffc, 0x9b800007, 0xccc00037, 0x8c000190, 0xd8000032, 0xd8000028, - 0xd800002b, 0x80001b70, 0xc4380004, 0xd8400008, 0xd8400013, 0xd88130b8, 0x04100000, 0x04140000, - 0xc418000e, 0x29980008, 0x7d83c001, 0xcd800013, 0xc4093249, 0x1888003e, 0x94800020, 0xd8400074, - 0x8c000671, 0x9a400009, 0xc418000e, 0x29980008, 0xcd800013, 0xc419324c, 0x259c0001, 0x1598001f, - 0x95c00016, 0x95800015, 0x99000003, 0xd8400036, 0x04100001, 0xc40c0021, 0x14d80011, 0x24e000ff, - 0x321c0002, 0x32200001, 0x9580ffee, 0x99c00014, 0x96000004, 0xccc00037, 0x04140001, 0x80000c30, - 0x9480000a, 0xd8000074, 0xc418005e, 0x95800f29, 0xcf800008, 0x80000c16, 0x94800004, 0xd8000074, - 0xc418005e, 0x95800f23, 0xd9c00036, 0x99400002, 0xccc00037, 0xcf800008, 0x80000c16, 0x94800004, - 0xd8000074, 0xc418005e, 0x95800f1a, 0xccc00037, 0xd8800036, 0x80001b70, 0x041c0003, 0x042c01c8, - 0x8c000d61, 0xc4200007, 0xc40c0077, 0x94c00001, 0x7c418001, 0xc428000e, 0x9600f502, 0x0a200001, - 0x98c0f500, 0x2aa80008, 0xce000010, 0x9a000f05, 0xce800013, 0xc431325a, 0xc42d3256, 0x1f30001f, - 0x16e4001f, 0xcf01325a, 0xc431325a, 0x97000001, 0x9640f4f4, 0xc434000b, 0x33740002, 0x9b40f4f1, - 0xc4353254, 0x16a80008, 0x1aec003c, 0x12a80015, 0x12ec001f, 0x1374000b, 0x7eae800a, 0xc02e4000, - 0x1774000d, 0x7eae800a, 0x7f6b400a, 0xcf400100, 0x12780001, 0x2bb80001, 0xc00ac005, 0xc00e0002, - 0x28cc8000, 0x28884900, 0x28cc0014, 0x80000ff3, 0xc43c0007, 0x7c40c001, 0x17fc0001, 0xd8400013, - 0x9bc00004, 0xd8400029, 0xc424005e, 0x96400ee1, 0xcc41c40a, 0xcc41c40c, 0xcc41c40d, 0x7c414001, - 0x24d0007f, 0x15580010, 0x255400ff, 0xcd01c411, 0xcd81c40f, 0xcd41c40e, 0xcc41c410, 0x7c414001, - 0x7c418001, 0x04200000, 0x18e80033, 0x18ec0034, 0xcc41c414, 0xcc41c415, 0xcd81c413, 0xcd41c412, - 0x18dc0032, 0x7c030011, 0x7c038011, 0x95c00027, 0x96c00002, 0xc431c417, 0xc435c416, 0x96800004, - 0x96c00002, 0xc439c419, 0xc43dc418, 0xc41c000e, 0x29dc0008, 0xcdc00013, 0xcf413261, 0x96c00002, - 0xcf013262, 0x96800004, 0xcfc13263, 0x96c00002, 0xcf813264, 0x18dc0030, 0xc43c0007, 0x95c00017, - 0x17fc0001, 0x9ac00005, 0x7d77000c, 0x9bc00015, 0x9700000a, 0x80000cd6, 0x51b80020, 0x53300020, - 0x7f97801a, 0x7f37001a, 0x7f3b000c, 0x9bc0000d, 0x97800002, 0x80000cd6, 0x9a000018, 0xd8400013, - 0x28200001, 0x80000ca7, 0x18dc0031, 0x95c00003, 0xc435c40b, 0x9740fffd, 0xd800002a, 0x80001b70, - 0xc4280032, 0x2aa80008, 0xce800013, 0xc40d325b, 0x97000002, 0x800012c2, 0xc438001d, 0x1bb81ff0, - 0x7f8cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, 0xcd01325d, 0x80001b70, 0xc428000e, 0xc43c0007, - 0x2aa80008, 0xc438001d, 0xce800013, 0x13f4000c, 0x9bc00006, 0xc43d3256, 0x1bf0060b, 0x1bfc0077, - 0x7ff3c00a, 0x80000cf4, 0xc43d325a, 0x1bfc0677, 0x13fc0017, 0x04300100, 0x1bb81fe8, 0x7f73400a, - 0xc032800b, 0x7fb7800a, 0x7ff3c00a, 0x7ffbc00a, 0xcfc1325b, 0x80000c16, 0xc43c0007, 0x7c40c001, - 0x18d42011, 0x17fc0001, 0x18d001e8, 0x24cc007f, 0x7cd4c00a, 0x9bc00004, 0xd8400029, 0xc428005e, - 0x96800e6c, 0x7c414001, 0x50580020, 0x7d59401a, 0xd1400072, 0xc8140072, 0x596001fc, 0x12200009, - 0x7ce0c00a, 0x7c418001, 0x505c0020, 0x7d9d801a, 0x7c41c001, 0x50600020, 0x7de1c01a, 0x7c420001, - 0xccc0001b, 0xd140001d, 0xd180001f, 0xd1c00020, 0xd8400021, 0x95000010, 0x04300000, 0xc428000f, - 0x9a80ffff, 0xc8240010, 0x7e5e800c, 0x9bc00015, 0x9a80000c, 0x9b000024, 0x28300001, 0x122c0004, - 0x06ec0001, 0x0aec0001, 0x9ac0ffff, 0xd8400021, 0x80000d1f, 0xc428000f, 0x9a80ffff, 0xc8240010, - 0x566c0020, 0xc428000e, 0x2aa80008, 0xce800013, 0xce413261, 0xcec13262, 0xd800002a, 0x80001b70, - 0xc4340032, 0x2b740008, 0xcf400013, 0xc40d325b, 0x96800005, 0x566c0020, 0xce413261, 0xcec13262, - 0x800012c2, 0xc438001d, 0x1bb81fe8, 0x7f8cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, 0xcd01325d, - 0x80001b70, 0xc43c0007, 0xc438001d, 0xc428000e, 0x2aa80008, 0xce800013, 0x13f4000c, 0x9bc00006, - 0xc43d3256, 0x1bf0060b, 0x1bfc0077, 0x7ff3c00a, 0x80000d57, 0xc43d325a, 0x1bfc0677, 0x13fc0017, - 0x04300100, 0x1bb81fe8, 0x7f73400a, 0xc0328009, 0x7fb7800a, 0x7ff3c00a, 0x7ffbc00a, 0xcfc1325b, - 0x80000c16, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0xc4253246, 0xc4113245, 0x04143000, 0xcd413267, - 0x52640020, 0x7e51001a, 0xc4153267, 0x7d2d0011, 0x19640057, 0x19580213, 0x19600199, 0x7da6400a, - 0x7e26400a, 0xd1000025, 0xce400024, 0xcdc00026, 0xd8400027, 0x04142000, 0xcfc00013, 0xcd413267, - 0xc4153267, 0x99400001, 0x90000000, 0x7c40c001, 0x18d001e8, 0x18d40030, 0x18d80034, 0x05280d83, - 0x7c420001, 0x7c424001, 0x86800000, 0x80000d8a, 0x8000016a, 0x80000d95, 0x80000db1, 0x8000016a, - 0x80000d95, 0x80000dbc, 0x11540010, 0x7e010001, 0x8c00187c, 0x7d75400a, 0xcd400013, 0xd4610000, - 0x9580f3d8, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0xd8000016, 0x526c0020, 0x18e80058, - 0x7e2ec01a, 0xd2c00072, 0xc82c0072, 0x5ae0073a, 0x7ea2800a, 0x9940000a, 0xce800024, 0xd2c00025, - 0xd4400026, 0xd8400027, 0x9580f3c6, 0xc4380012, 0x9b80ffff, 0x7c408001, 0x88000000, 0xdc3a0000, - 0x0bb80001, 0xce800024, 0xd2c00025, 0xcc400026, 0xd8400027, 0x9b80fffb, 0x9980fff5, 0x7c408001, - 0x88000000, 0xc02a0001, 0x2aa80001, 0x16200002, 0xce800013, 0xce01c405, 0xd441c406, 0x9580f3b1, - 0xc439c409, 0x97800001, 0x7c408001, 0x88000000, 0xc424000b, 0x32640002, 0x9a40000b, 0x11540010, - 0x29540002, 0xcd400013, 0xd4610000, 0x9580f3a5, 0xd8400013, 0xc439c040, 0x97800001, 0x7c408001, - 0x88000000, 0xd4400078, 0x80000168, 0xd8400029, 0xc40c005e, 0x94c00da7, 0x7c40c001, 0x50500020, - 0x7cd0c01a, 0xd0c00072, 0xc8280072, 0x5aac007e, 0x12d80017, 0x7c41c001, 0x7d9d800a, 0x56a00020, - 0x2620ffff, 0x7da1800a, 0x51980020, 0x7e82400a, 0x7e58c01a, 0x19d4003d, 0x28182002, 0x99400030, - 0x8c00104f, 0xc430000d, 0xc4340035, 0xd800002a, 0xcd800013, 0xc8140023, 0xc4180081, 0x13300005, - 0xc011000f, 0xc4240004, 0x11a00002, 0x7c908009, 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, - 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x3e280008, 0x20880188, 0x54ec0020, 0x7cb4800a, 0xc4300027, - 0x04380008, 0xd1400025, 0xcf000024, 0x20240090, 0x7ca48001, 0xcc800026, 0xccc00026, 0xcec00026, - 0xcec00026, 0x28240004, 0xcc000026, 0x0a640001, 0x9a40fffe, 0x9a800005, 0x32280000, 0x9a800002, - 0x9a000000, 0x7c018001, 0xd8400027, 0xd8000016, 0xcf80003a, 0xd901a2a4, 0x80001037, 0xc418000e, - 0x29980008, 0xcd800013, 0xc421326c, 0x1624001f, 0x9a40fffe, 0xd841325f, 0xd8800033, 0xc43c0009, - 0x27fc0004, 0x97c0fffe, 0xd8000039, 0xd0c00038, 0xc43c0022, 0x9bc0ffff, 0xd8800034, 0xc429325f, - 0x26ac0001, 0x9ac0fffe, 0x26ac0002, 0x96c00003, 0xd800002a, 0x80001b70, 0xc43c0007, 0xc430001e, - 0xd8800033, 0x13f4000c, 0x1b301ff0, 0x2b300300, 0x2330003f, 0x7f37000a, 0x9680000b, 0xc43c0009, - 0x27fc0004, 0x97c0fffe, 0xd8400039, 0xd0c00038, 0xc43c0022, 0x9bc0ffff, 0xcf01325b, 0xd8800034, - 0x80000c16, 0xd8800034, 0x8c0001a2, 0x80001b70, 0xcc80003b, 0x24b00008, 0xc418000e, 0x1330000a, - 0x18ac0024, 0x2b304000, 0x7c40c001, 0xcec00008, 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, - 0x29980008, 0xcd800013, 0xc4113249, 0x1910003e, 0x99000002, 0xd840003d, 0x7c410001, 0xd4400078, - 0x51100020, 0xcf01326c, 0x7cd0c01a, 0xc421326c, 0x12a80014, 0x2220003f, 0x7e2a000a, 0xcd800013, - 0xce01326c, 0xd8800033, 0xc43c0009, 0x27fc0004, 0x97c0fffe, 0xd8000039, 0xd0c00038, 0xc43c0022, - 0x9bc0ffff, 0xd8800034, 0x80001190, 0x7c40c001, 0x18dc003d, 0x95c00004, 0x041c0001, 0x042c01c8, - 0x8c000d61, 0x18d40030, 0x18d001e8, 0x18fc0034, 0x24e8000f, 0x06a80e71, 0x7c418001, 0x7c41c001, - 0x86800000, 0x80000edd, 0x80000e91, 0x80000e91, 0x80000ea1, 0x80000eaa, 0x80000e7c, 0x80000e7f, - 0x80000e7f, 0x80000e87, 0x80000e8f, 0x8000016a, 0x51dc0020, 0x7d9e001a, 0x80000ee6, 0xc420000e, - 0x2a200008, 0xce000013, 0xc4213262, 0xc4253261, 0x52200020, 0x7e26001a, 0x80000ee6, 0xc420000e, - 0x2a200008, 0xce000013, 0xc4213264, 0xc4253263, 0x52200020, 0x7e26001a, 0x80000ee6, 0xc820001f, - 0x80000ee6, 0x18e82005, 0x51e00020, 0x2aa80000, 0x7da1801a, 0xd1800072, 0xc8180072, 0x59a001fc, - 0x12200009, 0x7ea2800a, 0xce80001c, 0xd180001e, 0xd8400021, 0xc428000f, 0x9a80ffff, 0xc8200011, - 0x80000ee6, 0x15980002, 0xd8400013, 0xcd81c400, 0xc421c401, 0x95400041, 0xc425c401, 0x52640020, - 0x7e26001a, 0x80000ee6, 0x31ac2580, 0x9ac00011, 0x31ac260c, 0x9ac0000f, 0x31ac0800, 0x9ac0000d, - 0x31ac0828, 0x9ac0000b, 0x31ac2440, 0x9ac00009, 0x31ac2390, 0x9ac00007, 0x31ac0093, 0x9ac00005, - 0x31ac31dc, 0x9ac00003, 0x31ac31e6, 0x96c00004, 0xc4340004, 0xd8400008, 0x80000ede, 0x39ac7c06, - 0x3db07c00, 0x9ac00003, 0x97000002, 0x80000ebc, 0x39acc337, 0x3db0c330, 0x9ac00003, 0x97000002, - 0x80000ebc, 0x39acc335, 0x3db0c336, 0x9ac00003, 0x97000002, 0x80000ebc, 0x39ac9002, 0x3db09001, - 0x9ac00003, 0x97000002, 0x80000ebc, 0x39ac9012, 0x3db09011, 0x9ac00003, 0x97000002, 0x80000ebc, - 0x39acec70, 0x3db0ec6f, 0x9ac00003, 0x97000002, 0x80000ebc, 0xc4340004, 0xd8400013, 0xc5a10000, - 0x95400005, 0x05980001, 0xc5a50000, 0x52640020, 0x7e26001a, 0xcf400008, 0x05280eea, 0x7c418001, - 0x7c41c001, 0x86800000, 0x80000ef1, 0x8000016a, 0x80000efe, 0x80000f11, 0x80000f2e, 0x80000efe, - 0x80000f1f, 0xc4340004, 0xd8400013, 0xce190000, 0x95400005, 0x05980001, 0x56200020, 0xce190000, - 0xcf400008, 0x97c0f26f, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0x51ec0020, 0x18e80058, - 0x7daec01a, 0xd2c00072, 0xc82c0072, 0x5af8073a, 0x7eba800a, 0xd2c00025, 0xce800024, 0xce000026, - 0x95400003, 0x56240020, 0xce400026, 0xd8400027, 0x97c0f25c, 0xc4380012, 0x9b80ffff, 0x7c408001, - 0x88000000, 0xc02a0001, 0x2aa80001, 0x15980002, 0xce800013, 0xcd81c405, 0xce01c406, 0x95400003, - 0x56240020, 0xce41c406, 0x97c0f24e, 0xc439c409, 0x97800001, 0x7c408001, 0x88000000, 0xc424000b, - 0x32640002, 0x9a40f247, 0xd8800013, 0xce190000, 0x95400004, 0x05980001, 0x56200020, 0xce190000, - 0x97c0f240, 0xd8400013, 0xc439c040, 0x97800001, 0x7c408001, 0x88000000, 0x31ac2580, 0x9ac00011, - 0x31ac260c, 0x9ac0000f, 0x31ac0800, 0x9ac0000d, 0x31ac0828, 0x9ac0000b, 0x31ac2440, 0x9ac00009, - 0x31ac2390, 0x9ac00007, 0x31ac0093, 0x9ac00005, 0x31ac31dc, 0x9ac00003, 0x31ac31e6, 0x96c00004, - 0xc4340004, 0xd8400008, 0x80000ef2, 0x39ac7c06, 0x3db07c00, 0x9ac00003, 0x97000002, 0x80000f40, - 0x39acc337, 0x3db0c330, 0x9ac00003, 0x97000002, 0x80000f40, 0x39acc335, 0x3db0c336, 0x9ac00003, - 0x97000002, 0x80000f40, 0x39acec70, 0x3db0ec6f, 0x9ac00003, 0x97000002, 0x80000f40, 0x39ac9002, - 0x3db09002, 0x9ac00003, 0x97000002, 0x80000f40, 0x39ac9012, 0x3db09012, 0x9ac00003, 0x97000002, - 0x80000f40, 0x80000ef1, 0xc40c0006, 0x98c0ffff, 0x7c40c001, 0x7c410001, 0x7c414001, 0x7c418001, - 0x7c41c001, 0x7c43c001, 0x95c00001, 0xc434000e, 0x2b740008, 0x2b780001, 0xcf400013, 0xd8c1325e, - 0xcf80001a, 0xd8400013, 0x7c034001, 0x7c038001, 0x18e0007d, 0x32240003, 0x9a400006, 0x32240000, - 0x9a400004, 0xcd01c080, 0xcd41c081, 0x80000f88, 0x51640020, 0x7e52401a, 0xd2400072, 0xc8280072, - 0xce81c080, 0x56ac0020, 0x26f0ffff, 0xcf01c081, 0x1af000fc, 0x1334000a, 0x24e02000, 0x7f63400a, - 0x18e00074, 0x32240003, 0x9a400006, 0x32240000, 0x9a400004, 0xcd81c082, 0xcdc1c083, 0x80000f9d, - 0x51e40020, 0x7e5a401a, 0xd2400072, 0xc8280072, 0xce81c082, 0x56ac0020, 0x26f0ffff, 0xcf01c083, - 0x1af000fc, 0x13380016, 0x18e00039, 0x12200019, 0x7fa3800a, 0x7fb7800a, 0x18e0007d, 0x1220001d, - 0x7fa3800a, 0x18e00074, 0x12200014, 0x7fa3800a, 0xcf81c078, 0xcfc1c084, 0x80000c16, 0x7c40c001, - 0x18dc003d, 0x95c00004, 0x041c0000, 0x042c01c8, 0x8c000d61, 0x18d001e8, 0x31140005, 0x99400003, - 0x31140006, 0x95400002, 0x8c00104f, 0x05280fb7, 0x28140002, 0xcd400013, 0x86800000, 0x80000fbe, - 0x80000fbe, 0x80000fc2, 0x80000fbe, 0x80000fd1, 0x80000ff2, 0x80000ff2, 0x24cc003f, 0xccc1a2a4, - 0x7c408001, 0x88000000, 0x7c414001, 0x18e80039, 0x52a8003b, 0x50580020, 0x24cc003f, 0x7d59401a, - 0xd1400072, 0xc8140072, 0x7d69401a, 0xc41c0017, 0x99c0ffff, 0xd140004b, 0xccc1a2a4, 0x7c408001, - 0x88000000, 0xc414000d, 0x04180001, 0x24cc003f, 0x7d958004, 0xcd800035, 0xccc1a2a4, 0xc43c000e, - 0x2bfc0008, 0xcfc00013, 0xc43d3249, 0x1bfc003e, 0x97c00002, 0xd8400074, 0xc4100019, 0x7d150005, - 0x25100001, 0x9500000b, 0x97c0fffc, 0xc4180021, 0x159c0011, 0x259800ff, 0x31a00003, 0x31a40001, - 0x7e25800a, 0x95c0fff5, 0x9580fff4, 0x80000fef, 0xc411326f, 0x1d100010, 0xcd01326f, 0x97c00002, - 0xd8000074, 0x80001b70, 0x04380000, 0xc430000d, 0xc8140023, 0xc4180081, 0x13300005, 0xc011000f, - 0xc4240004, 0x33b40003, 0x97400003, 0xc0340008, 0x80000ffe, 0xc4340035, 0x11a00002, 0x7c908009, - 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x282c2002, - 0x208801a8, 0x3e280008, 0x7cb4800a, 0xcec00013, 0xc4300027, 0x042c0008, 0xd1400025, 0xcf000024, - 0x20240030, 0x7ca48001, 0xcc800026, 0xccc00026, 0x9b800013, 0xcc400026, 0x7c414001, 0x28340000, - 0xcf400013, 0x507c0020, 0x7d7d401a, 0xd1400072, 0xc8140072, 0x557c0020, 0x28342002, 0xcf400013, - 0xcd400026, 0xcfc00026, 0xd4400026, 0x9a80000e, 0x32280000, 0x9a80000b, 0x8000102f, 0xcc000026, - 0xcc000026, 0xcc000026, 0xcc000026, 0xcc000026, 0x9a800005, 0x32280000, 0x9a800002, 0x9a000000, - 0x7c018001, 0xcc000026, 0xd8400027, 0x1cccfe08, 0xd8800013, 0xcec0003a, 0xccc1a2a4, 0xc43c000e, - 0x2bfc0008, 0xcfc00013, 0xc43d3249, 0x1bfc003e, 0x9bc00007, 0xc428000e, 0x16a80008, 0xce800009, - 0xc42c005e, 0x96c00b33, 0xd840003c, 0xc4200025, 0x7da2400f, 0x7da28002, 0x7e1ac002, 0x0aec0001, - 0x96400002, 0x7d2ac002, 0x3ef40010, 0x9b40f11d, 0x04380030, 0xcf81325e, 0x80000c16, 0xde410000, - 0xdcc10000, 0xdd010000, 0xdd410000, 0xdd810000, 0xddc10000, 0xde010000, 0xc40c000e, 0x7c024001, - 0x28cc0008, 0xccc00013, 0xc8100086, 0x5510003f, 0xc40d3249, 0x18cc003e, 0x98c00003, 0x99000011, - 0x80001075, 0x9900000c, 0xc40c0026, 0xc4100081, 0xc4140025, 0x7d15800f, 0x7d15c002, 0x7d520002, - 0x0a200001, 0x95800002, 0x7cde0002, 0x3e20001a, 0x9a000009, 0x040c0030, 0xccc1325e, 0x80001071, - 0xd9c00036, 0xd8400029, 0xc40c005e, 0x94c00b01, 0x04240001, 0xdc200000, 0xdc1c0000, 0xdc180000, - 0xdc140000, 0xdc100000, 0xdc0c0000, 0x96400004, 0xdc240000, 0xdc0c0000, 0x80000c16, 0xdc240000, - 0x90000000, 0xcc40003f, 0xd8c00010, 0xc4080029, 0xcc80003b, 0xc418000e, 0x18a800e5, 0x1d980008, - 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, 0x18a400e5, 0x12500009, 0x248c0008, 0x94c00006, - 0x200c006d, 0x7cd0c00a, 0xccc1326c, 0xc421326c, 0x96000001, 0xcd800013, 0x200c0228, 0x7cd0c00a, - 0xccc1326c, 0xc421326c, 0x96000001, 0xc40c002a, 0xc410002b, 0x18881fe8, 0x18d4072c, 0x18cc00d1, - 0x7cd4c00a, 0x3094000d, 0x38d80000, 0x311c0003, 0x99400006, 0x30940007, 0x1620001f, 0x9940001d, - 0x9a000023, 0x800010c4, 0x9580001a, 0x99c00019, 0xccc00041, 0x25140001, 0xc418002c, 0x9940000d, - 0x259c007f, 0x95c00013, 0x19a00030, 0xcdc0001b, 0xd8400021, 0xd8400022, 0xc430000f, 0x17300001, - 0x9b00fffe, 0x9a000012, 0xd8400023, 0x800010cb, 0x199c0fe8, 0xcdc0001b, 0xd8400021, 0xd8400023, - 0xc430000f, 0x17300001, 0x9b00fffe, 0x800010cb, 0xd8c00010, 0xd8000022, 0xd8000023, 0xc430005e, - 0x97000aac, 0x7c408001, 0x88000000, 0xc43c000e, 0xc434002e, 0x2bfc0008, 0x2020002c, 0xcfc00013, - 0xce01326c, 0x17780001, 0x27740001, 0x07a810d8, 0xcf400010, 0xc421326c, 0x96000001, 0x86800000, - 0x80000168, 0x80000aa7, 0x80000bfc, 0x800012e9, 0x8000104c, 0xcc400040, 0xd8800010, 0xc4180032, - 0x29980008, 0xcd800013, 0x200c007d, 0xccc1325b, 0xc411325b, 0x95000001, 0x7c408001, 0x88000000, - 0x28240007, 0xde430000, 0xd4400078, 0x80001190, 0xcc80003b, 0x24b00008, 0xc418000e, 0x1330000a, - 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, 0xc40d3249, 0x18cc003e, - 0x98c00002, 0xd840003d, 0x2b304000, 0xcf01326c, 0xc431326c, 0x7c40c001, 0x7c410001, 0x7c414001, - 0x192400fd, 0x50580020, 0x7d59401a, 0x7c41c001, 0x06681110, 0x7c420001, 0xcc400078, 0x18ac0024, - 0x19180070, 0x19100078, 0xcec00008, 0x18f40058, 0x5978073a, 0x7f7b400a, 0x97000001, 0x86800000, - 0x80001117, 0x80001118, 0x80001122, 0x8000112d, 0x80001130, 0x80001133, 0x8000016a, 0x8000117b, - 0x24ec0f00, 0x32ec0600, 0x96c00003, 0xc4300006, 0x9b00ffff, 0xd1400025, 0xcf400024, 0xcdc00026, - 0xd8400027, 0x8000117b, 0x24ec0f00, 0x32ec0600, 0x96c00003, 0xc4300006, 0x9b00ffff, 0xd1400025, - 0xcf400024, 0xcdc00026, 0xce000026, 0xd8400027, 0x8000117b, 0xc81c001f, 0x55e00020, 0x80001122, - 0xc81c0020, 0x55e00020, 0x80001122, 0x8c00116b, 0xd8400013, 0xc02a0200, 0x7e8e8009, 0x22a8003d, - 0x22a80074, 0x2774001c, 0x13740014, 0x7eb6800a, 0x25ecffff, 0x55700020, 0x15f40010, 0x13740002, - 0x275c001f, 0x95c00027, 0x7c018001, 0x7f41c001, 0x15dc0002, 0x39e00008, 0x25dc0007, 0x7dc1c01e, - 0x05dc0001, 0x96000004, 0x05e40008, 0x8c00116e, 0x80001168, 0x7dc2001e, 0x06200001, 0x05e40008, - 0x7e62000e, 0x9a000004, 0x7da58001, 0x8c00116e, 0x80001165, 0x7dc2001e, 0x06200001, 0x7e1a0001, - 0x05cc0008, 0x7e0d000e, 0x95000007, 0x7e02401e, 0x06640001, 0x06640008, 0x05d80008, 0x8c00116e, - 0x80001168, 0x7dc2401e, 0x06640001, 0x7da58001, 0x8c00116e, 0x05e00008, 0x7da2000c, 0x9600ffe6, - 0x17640002, 0x8c00116e, 0x80001190, 0xc4200006, 0x9a00ffff, 0x90000000, 0x8c00116b, 0xc420000e, - 0x2a200001, 0xce00001a, 0xce81c078, 0xcec1c080, 0xcc01c081, 0xcd41c082, 0xcf01c083, 0x12640002, - 0x22640435, 0xce41c084, 0x90000000, 0x0528117e, 0x312c0003, 0x86800000, 0x80001190, 0x80001185, - 0x80001182, 0x80001182, 0xc4300012, 0x9b00ffff, 0x9ac0000c, 0xc03a0400, 0xc4340004, 0xd8400013, - 0xd8400008, 0xc418000e, 0x15980008, 0x1198001c, 0x7d81c00a, 0xcdc130b7, 0xcf8130b5, 0xcf400008, - 0x04240008, 0xc418000e, 0xc41c0049, 0x19a000e8, 0x29a80008, 0x7de2c00c, 0xce800013, 0xc421325e, - 0x26200010, 0xc415326d, 0x9a000006, 0xc420007d, 0x96000004, 0x96c00003, 0xce40003e, 0x800011a3, - 0x7d654001, 0xcd41326d, 0x7c020001, 0x96000005, 0xc4100026, 0xc4240081, 0xc4140025, 0x800011b6, - 0xc4253279, 0xc415326d, 0xc431326c, 0x2730003f, 0x3b380006, 0x97800004, 0x3f38000b, 0x9b800004, - 0x800011b4, 0x04300006, 0x800011b4, 0x0430000b, 0x04380002, 0x7fb10004, 0x7e57000f, 0x7e578002, - 0x7d67c002, 0x0be40001, 0x97000002, 0x7d3a4002, 0x202c002c, 0xc421325e, 0x04280020, 0xcec1326c, - 0x26200010, 0x3e640010, 0x96000003, 0x96400002, 0xce81325e, 0xc4300028, 0xc434002e, 0x17780001, - 0x27740001, 0x07a811cf, 0x9b00feb8, 0xcf400010, 0xc414005e, 0x954009a7, 0x86800000, 0x80000168, - 0x80000aa7, 0x80000bfc, 0x800012e9, 0x80000168, 0x8c00120d, 0x7c40c001, 0xccc1c07c, 0xcc41c07d, - 0xcc41c08c, 0x7c410001, 0xcc41c079, 0xcd01c07e, 0x7c414001, 0x18f0012f, 0x18f40612, 0x18cc00c1, - 0x7f73400a, 0x7cf7400a, 0x39600004, 0x9a000002, 0xc0140004, 0x11600001, 0x18fc003e, 0x9740001c, - 0xcf400041, 0xc425c07f, 0x97c00003, 0x166c001f, 0x800011ee, 0x1a6c003e, 0x96c00006, 0x04200002, - 0x0a200001, 0x9a00ffff, 0xd8400013, 0x800011e8, 0xc428002c, 0x96800010, 0x26ac007f, 0xcec0001b, - 0xd8400021, 0x1ab00030, 0x1aac0fe8, 0xc434000f, 0x9b40ffff, 0x97000008, 0xcec0001b, 0xd8400021, - 0xc434000f, 0x9b40ffff, 0x80001205, 0x0a200001, 0x9a00ffff, 0xd8400013, 0xc425c07f, 0x166c001f, - 0x11600001, 0x9ac0fffa, 0x8c001232, 0x7c408001, 0x88000000, 0xd8000033, 0xc438000b, 0xc43c0009, - 0x27fc0001, 0x97c0fffe, 0xd8400013, 0xd841c07f, 0xc43dc07f, 0x1bfc0078, 0x7ffbc00c, 0x97c0fffd, - 0x90000000, 0xc03a2800, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04380040, - 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380060, 0xcf80001b, 0xd8400021, 0xc438000f, - 0x9b80ffff, 0x04380002, 0x0bb80001, 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, - 0x9bc0fffa, 0x90000000, 0xd8400013, 0xd801c07f, 0xd8400013, 0xc43dc07f, 0xcfc00078, 0xd8000034, - 0x90000000, 0xc03ae000, 0xcf81c200, 0xc03a0800, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, - 0xcc01c07e, 0x04380040, 0xcf80001b, 0xd8400021, 0xc438000f, 0x9b80ffff, 0x04380002, 0x0bb80001, - 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, 0x9bc0fffa, 0x90000000, 0xc03ae000, - 0xcf81c200, 0xc03a4000, 0xcf81c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04380002, - 0x0bb80001, 0x9b80ffff, 0xd8400013, 0xc43dc07f, 0x17fc001f, 0x04380010, 0x9bc0fffa, 0x90000000, - 0xc40c0007, 0x30d00002, 0x99000052, 0xd8400029, 0xc424005e, 0x9640090f, 0x7c410001, 0xc428000e, - 0x1514001f, 0x19180038, 0x2aa80008, 0x99400030, 0x30dc0001, 0xce800013, 0x99c0000a, 0xc42d324e, - 0xc431324d, 0x52ec0020, 0x7ef2c01a, 0xc435324f, 0xc4293256, 0x1ab0c006, 0x52ec0008, 0x8000127f, - 0xc42d3258, 0xc4313257, 0x52ec0020, 0x7ef2c01a, 0xc4353259, 0xc429325a, 0x1ab0c012, 0x07740001, - 0x04240002, 0x26a0003f, 0x7e624004, 0x7f67800f, 0x97800002, 0x04340000, 0x53740002, 0x7ef6c011, - 0x1ab42010, 0x16a8000c, 0x26a80800, 0x2b740000, 0x7f73400a, 0x7f6b400a, 0xcf40001c, 0xd2c0001e, - 0xd8400021, 0xc438000f, 0x9b80ffff, 0xc4100011, 0x1514001f, 0x99400006, 0x9980000a, 0x8c0012e1, - 0xc40c0007, 0x04100000, 0x80001267, 0xd800002a, 0xc424005e, 0x964008d7, 0xd9800036, 0x80000c16, - 0xc42c001d, 0x95c00005, 0xc431325a, 0x1b300677, 0x11dc000c, 0x800012aa, 0xc4313256, 0x1b34060b, - 0x1b300077, 0x7f37000a, 0x13300017, 0x04340100, 0x26ec00ff, 0xc03a8002, 0x7ef6c00a, 0x7edec00a, - 0x7f3b000a, 0x7ef2c00a, 0xcec1325b, 0x80000c16, 0xc4140032, 0xc410001d, 0x29540008, 0xcd400013, - 0xc40d325b, 0x1858003f, 0x251000ff, 0x99800007, 0x7d0cc00a, 0xccc1325b, 0xc411325d, 0x251001ef, - 0xcd01325d, 0x80000168, 0x18d0006c, 0x18d407f0, 0x9900000e, 0x04100002, 0xc4193256, 0xc41d324f, - 0x2598003f, 0x7d190004, 0x7d5d4001, 0x7d52000f, 0x9a000003, 0xcd41324f, 0x800012d8, 0x7d514002, - 0xcd41324f, 0x800012d8, 0xc4193259, 0xc41d325a, 0x7d958001, 0x7dd5c002, 0xcd813259, 0xcdc1325a, - 0xc411325d, 0x251001ef, 0xcd01325d, 0x1ccc001e, 0xccc1325b, 0xc40d325b, 0x94c00001, 0x7c408001, - 0x88000000, 0xc40c0021, 0xc4340028, 0x14f00010, 0xc4380030, 0xc43c0007, 0x9b000004, 0x9b40000c, - 0x9b80000f, 0x90000000, 0x17300001, 0x9b000005, 0xccc00037, 0x8c000190, 0xd8000032, 0x90000000, - 0xd8000028, 0xd800002b, 0x80000168, 0xd980003f, 0x97c00002, 0xd9c0003f, 0x80001082, 0xd9800040, - 0x97c00002, 0xd9c00040, 0x800010de, 0xc43c0007, 0x33f80003, 0x97800051, 0xcc80003b, 0x24b00008, - 0xc418000e, 0x1330000a, 0x18a800e5, 0x1d980008, 0x12a80008, 0x7da9800a, 0x29980008, 0xcd800013, - 0xc4353249, 0x1b74003e, 0x9b400002, 0xd840003d, 0x2b304000, 0xcf01326c, 0xc431326c, 0x97000001, - 0x7c434001, 0x1b4c00f8, 0x7c410001, 0x7c414001, 0x50700020, 0x04e81324, 0x18ac0024, 0x7c41c001, - 0x50600020, 0xcc400078, 0x30e40004, 0x9a400007, 0x7d71401a, 0x596401fc, 0x12640009, 0x1b74008d, - 0x7e76400a, 0x2a640000, 0xcec00008, 0x86800000, 0x8000016a, 0x8000016a, 0x8000016a, 0x8000016a, - 0x8000132c, 0x8000133b, 0x80001344, 0x8000016a, 0xc4340004, 0xd8400013, 0xd8400008, 0xc42530b5, - 0x1a68003a, 0x9a80fffe, 0x2024003a, 0xc418000e, 0x25980700, 0x11980014, 0x7d19000a, 0xcd0130b7, - 0xce4130b5, 0xcf400008, 0x80001190, 0xce40001c, 0xd140001e, 0xd8400021, 0xc428000f, 0x9a80ffff, - 0xc4240011, 0x7de6800f, 0x9a80ffea, 0x80001190, 0xce40001c, 0xd140001e, 0xd8400021, 0xc428000f, - 0x9a80ffff, 0xc8240011, 0x7de1c01a, 0x7de6800f, 0x9a80ffe0, 0x80001190, 0x8c00104f, 0x28182002, - 0xc430000d, 0xc4340035, 0xcd800013, 0xc8140023, 0xc4180081, 0x13300005, 0xc4240004, 0x11a00002, - 0x12640004, 0x7d614011, 0xc4100026, 0x05980008, 0x7ca4800a, 0x7d1a0002, 0x7cb0800a, 0x3e280008, - 0x7cb4800a, 0xc4300027, 0x042c0008, 0xd1400025, 0xcf000024, 0x20240030, 0x7ca48001, 0xcc800026, - 0x7c434001, 0x1b4c00f8, 0xcf400026, 0xcc400026, 0x28340000, 0xcf400013, 0x7c414001, 0x507c0020, - 0x30e40004, 0x9a400005, 0x7d7d401a, 0xd1400072, 0xc8140072, 0x557c0020, 0x28342002, 0xcf400013, - 0xcd400026, 0xcfc00026, 0xd4400026, 0xcc000026, 0x9a800005, 0x32280000, 0x9a800002, 0x9a000000, - 0x7c018001, 0xd8400027, 0xd8800013, 0x04380028, 0xcec0003a, 0xcf81a2a4, 0x80001037, 0xd8400029, - 0xc40c005e, 0x94c007eb, 0x7c40c001, 0x50500020, 0x7d0d001a, 0xd1000072, 0xc8100072, 0x591c01fc, - 0x11dc0009, 0x45140210, 0x595801fc, 0x11980009, 0x29dc0000, 0xcdc0001c, 0xd140001e, 0xd8400021, - 0xc418000f, 0x9980ffff, 0xc4200011, 0x1624001f, 0x96400069, 0xc40c000e, 0x28cc0008, 0xccc00013, - 0xce013249, 0x1a307fe8, 0xcf00000a, 0x23304076, 0xd1000001, 0xcf000001, 0xc41d3254, 0xc4253256, - 0x18cc00e8, 0x10cc0015, 0x4514020c, 0xd140001e, 0xd8400021, 0xc418000f, 0x9980ffff, 0xc4200011, - 0xce013248, 0x1a2001e8, 0x12200014, 0x2a204001, 0xce000013, 0x1a64003c, 0x1264001f, 0x11dc0009, - 0x15dc000b, 0x7dcdc00a, 0x7e5dc00a, 0xcdc00100, 0xd8800013, 0xd8400010, 0xd800002a, 0xd8400008, - 0xcf00000d, 0xcf00000a, 0x8c001427, 0x04340022, 0x07740001, 0x04300010, 0xdf430000, 0x7c434001, - 0x7c408001, 0xd4412e01, 0x0434001e, 0xdf430000, 0xd4400078, 0xdf030000, 0xd4412e40, 0xd8400013, - 0xcc41c030, 0xcc41c031, 0x248dfffe, 0xccc12e00, 0xd8800013, 0xcc812e00, 0x7c434001, 0x7c434001, - 0x8c00142b, 0xd8000010, 0xc40c000e, 0x28cc0008, 0xccc00013, 0x45140248, 0xd140001e, 0xd8400021, - 0xc418000f, 0x9980ffff, 0xc8200011, 0xce013257, 0x56200020, 0xce013258, 0x0434000c, 0xdb000024, - 0xd1400025, 0xd8000026, 0xd8000026, 0xd8400027, 0x45540008, 0xd140001e, 0xd8400021, 0xc418000f, - 0x9980ffff, 0xc8200011, 0xce013259, 0x56200020, 0xc0337fff, 0x7f220009, 0xce01325a, 0x55300020, - 0x7d01c001, 0x042c01d0, 0x8c000d61, 0x06ec0004, 0x7f01c001, 0x8c000d61, 0x041c0002, 0x042c01c8, - 0x8c000d61, 0xc4380012, 0x9b80ffff, 0xd800002a, 0x80000aa7, 0xd800002a, 0x7c408001, 0x88000000, - 0xd8400029, 0x7c40c001, 0x50500020, 0x8c001427, 0x7cd0c01a, 0xc4200007, 0xd0c00072, 0xc8240072, - 0xd240001e, 0x7c414001, 0x19682011, 0x5a6c01fc, 0x12ec0009, 0x7eeac00a, 0x2aec0000, 0xcec0001c, - 0xd8400021, 0xc430000f, 0x9b00ffff, 0xc4180011, 0x7c438001, 0x99800007, 0xdf830000, 0xcfa0000c, - 0x8c00142b, 0xd4400078, 0xd800002a, 0x80001b70, 0x8c00142b, 0xd800002a, 0x80001b70, 0xd8000012, - 0xc43c0008, 0x9bc0ffff, 0x90000000, 0xd8400012, 0xc43c0008, 0x97c0ffff, 0x90000000, 0xc4380007, - 0x7c40c001, 0x17b80001, 0x18d40038, 0x7c410001, 0x9b800004, 0xd8400029, 0xc414005e, 0x9540073d, - 0x18c80066, 0x7c414001, 0x30880001, 0x7c418001, 0x94800008, 0x8c00187c, 0xcf400013, 0xc42c0004, - 0xd8400008, 0xcd910000, 0xcec00008, 0x7d410001, 0x043c0000, 0x7c41c001, 0x7c420001, 0x04240001, - 0x06200001, 0x4220000c, 0x0a640001, 0xcc000078, 0x9a40fffe, 0x24e80007, 0x24ec0010, 0xd8400013, - 0x9ac00006, 0xc42c0004, 0xd8400008, 0xc5310000, 0xcec00008, 0x80001465, 0x51540020, 0x7d15001a, - 0xd1000072, 0xc82c0072, 0xd2c0001e, 0x18f02011, 0x5aec01fc, 0x12ec0009, 0x7ef2c00a, 0x2aec0000, - 0xcec0001c, 0xd8400021, 0xc42c000f, 0x9ac0ffff, 0xc4300011, 0x96800012, 0x12a80001, 0x0aa80001, - 0x06a8146a, 0x7f1f0009, 0x86800000, 0x7f1b400f, 0x80001478, 0x7f1b400e, 0x80001478, 0x7f1b400c, - 0x8000147a, 0x7f1b400d, 0x8000147a, 0x7f1b400f, 0x8000147a, 0x7f1b400e, 0x8000147a, 0x7f334002, - 0x97400014, 0x8000147b, 0x9b400012, 0x9b800005, 0x9bc0001f, 0x7e024001, 0x043c0001, 0x8000144a, - 0xc40c0032, 0xc438001d, 0x28cc0008, 0xccc00013, 0xc43d325b, 0x1bb81ff0, 0x7fbfc00a, 0xcfc1325b, - 0xc411325d, 0x251001ef, 0xcd01325d, 0x80001b70, 0x94800007, 0x8c00187c, 0xcf400013, 0xc42c0004, - 0xd8400008, 0xcd910000, 0xcec00008, 0x9b800003, 0xd800002a, 0x80001b70, 0xc40c0032, 0x28cc0008, - 0xccc00013, 0xc40d325b, 0x800012c2, 0xc40c000e, 0xc43c0007, 0xc438001d, 0x28cc0008, 0xccc00013, - 0x13f4000c, 0x9bc00006, 0xc43d3256, 0x1bf0060b, 0x1bfc0077, 0x7ff3c00a, 0x800014a9, 0xc43d325a, - 0x1bfc0677, 0x04300100, 0x1bb81ff0, 0x7f73400a, 0xc0328007, 0x7fb7800a, 0x13fc0017, 0x7ff3c00a, - 0x7ffbc00a, 0xcfc1325b, 0xc03a0002, 0xc4340004, 0xd8400013, 0xd8400008, 0xcf8130b5, 0xcf400008, - 0x80000c16, 0x043c0000, 0xc414000e, 0x29540008, 0xcd400013, 0xc4193246, 0xc41d3245, 0x51980020, - 0x7dd9c01a, 0x45dc0390, 0xc4313267, 0x04183000, 0xcd813267, 0x1b380057, 0x1b340213, 0x1b300199, - 0x7f7b400a, 0x7f73400a, 0xcf400024, 0xd1c00025, 0xcc800026, 0x7c420001, 0xce000026, 0x7c424001, - 0xce400026, 0x7c428001, 0xce800026, 0x7c42c001, 0xcec00026, 0x7c430001, 0xcf000026, 0x7c434001, - 0xcf400026, 0x7c438001, 0xcf800026, 0xd8400027, 0xcd400013, 0x04182000, 0xcd813267, 0xd840004f, - 0x1a0800fd, 0x109c000a, 0xc4193265, 0x7dd9c00a, 0xcdc13265, 0x2620ffff, 0xce080228, 0x9880000e, - 0xce480250, 0xce880258, 0xd8080230, 0xd8080238, 0xd8080240, 0xd8080248, 0xd8080268, 0xd8080270, - 0xd8080278, 0xd8080280, 0xd800004f, 0x97c0ec75, 0x90000000, 0x040c0000, 0x041c0010, 0x26180001, - 0x09dc0001, 0x16200001, 0x95800002, 0x04cc0001, 0x99c0fffb, 0xccc80230, 0xd8080238, 0xd8080240, - 0xd8080248, 0x040c0000, 0xce480250, 0xce880258, 0x52a80020, 0x7e6a401a, 0x041c0020, 0x66580001, - 0x09dc0001, 0x56640001, 0x95800002, 0x04cc0001, 0x99c0fffb, 0xccc80260, 0xd8080268, 0xd8080270, - 0xd8080278, 0xd8080280, 0x040c0000, 0xcec80288, 0xcf080290, 0xcec80298, 0xcf0802a0, 0x040c0000, - 0x041c0010, 0xcf4802a8, 0x27580001, 0x09dc0001, 0x17740001, 0x95800002, 0x04cc0001, 0x99c0fffb, - 0xccc802b0, 0xd80802b8, 0x178c000b, 0x27b8003f, 0x7cf8c001, 0xcf8802c0, 0xccc802c8, 0xcf8802d0, - 0xcf8802d8, 0xd800004f, 0x97c00002, 0x90000000, 0x7c408001, 0x88000000, 0xc40c000e, 0x28cc0008, - 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c418001, 0x25b8ffff, 0xc4930240, 0xc48f0238, 0x04cc0001, - 0x24cc000f, 0x7cd2800c, 0x9a80000b, 0xc5230309, 0x2620ffff, 0x7e3a400c, 0x9a400004, 0x05100001, - 0x2510000f, 0x80001539, 0xcd08034b, 0xd4400078, 0x80000168, 0xc48f0230, 0xc4930240, 0x98c00004, - 0xcd880353, 0x8c00163f, 0xc49b0353, 0xc4930238, 0xc48f0228, 0x05100001, 0x2510000f, 0x7cd14005, - 0x25540001, 0x99400004, 0x05100001, 0x2510000f, 0x8000154f, 0xc48f0230, 0x7c41c001, 0xcd080238, - 0xcd08034b, 0x08cc0001, 0x2598ffff, 0x3d200008, 0xccc80230, 0xcd900309, 0xd8100319, 0x04340801, - 0x2198003f, 0xcf400013, 0xcd910ce7, 0xc4190ce6, 0x7d918005, 0x25980001, 0x9580fffd, 0x7d918004, - 0xcd810ce6, 0x9a000003, 0xcdd1054f, 0x8000156e, 0x090c0008, 0xcdcd050e, 0x040c0000, 0x110c0014, - 0x28cc4001, 0xccc00013, 0xcc41230a, 0xcc41230b, 0xcc41230c, 0xcc41230d, 0xcc480329, 0xcc48032a, - 0xcc4802e0, 0xd8000055, 0xc48f02e0, 0x24d8003f, 0x09940001, 0x44100001, 0x9580002c, 0x95400005, - 0x09540001, 0x51100001, 0x69100001, 0x8000157f, 0x24cc003f, 0xc4970290, 0xc49b0288, 0x51540020, - 0x7d59401a, 0xc49b02a0, 0xc49f0298, 0x51980020, 0x7d9d801a, 0x041c0040, 0x04200000, 0x7dcdc002, - 0x7d924019, 0x7d26400c, 0x09dc0001, 0x9a400008, 0x51100001, 0x06200001, 0x99c0fffa, 0xc48f0230, - 0xc4930240, 0x8c00163f, 0x80001579, 0x7d010021, 0x7d914019, 0xc4930238, 0x55580020, 0xcd480298, - 0xcd8802a0, 0x10d40010, 0x12180016, 0xc51f0309, 0x7d95800a, 0x7d62000a, 0x7dd9c00a, 0xd8400013, - 0xcdd00309, 0xce113320, 0xc48f02e0, 0xc49b02b0, 0x18dc01e8, 0x7dd9400e, 0xc48f0230, 0xc4930240, - 0x95c0001d, 0x95400003, 0x8c00163f, 0x800015aa, 0xc48f0238, 0xc4a302b8, 0x12240004, 0x7e5e400a, - 0xc4ab02a8, 0x04100000, 0xce4c0319, 0x7d9d8002, 0x7ea14005, 0x25540001, 0x99400004, 0x06200001, - 0x2620000f, 0x800015bc, 0x09dc0001, 0x04240001, 0x7e624004, 0x06200001, 0x7d25000a, 0x2620000f, - 0x99c0fff4, 0xd8400013, 0xcd0d3330, 0xce0802b8, 0xcd8802b0, 0xc4ab02e0, 0x1aa807f0, 0xc48f02d0, - 0xc49702d8, 0xc49b02c8, 0xc49f02c0, 0x96800028, 0x7d4e000f, 0x9600000b, 0x7d964002, 0x7e6a000f, - 0x96000003, 0x7d694001, 0x800015e9, 0x7cde4002, 0x7e6a000f, 0x96000008, 0x7de94001, 0x800015e9, - 0x7cd64002, 0x7e6a000e, 0x96000003, 0x7d694001, 0x800015e9, 0xc48f0230, 0xc4930240, 0x8c00163f, - 0x800015cd, 0xc4930238, 0x7d698002, 0xcd4802d8, 0x129c0008, 0xc50f0319, 0x11a0000e, 0x11140001, - 0xc4340004, 0xd8400008, 0xd8400013, 0x7e1e000a, 0x1198000a, 0xcd953300, 0x7e0e000a, 0x12a8000a, - 0xce953301, 0xce100319, 0xcf400008, 0xc4b70280, 0xc4b30278, 0x7f73800a, 0x536c0020, 0x7ef2c01a, - 0x9780eb68, 0x8c001608, 0xd8080278, 0xd8080280, 0x7c408001, 0x88000000, 0x043c0003, 0x80001609, - 0x043c0001, 0x30b40000, 0x9b400011, 0xc4b70258, 0xc4b30250, 0x53780020, 0x7fb3801a, 0x7faf8019, - 0x04300020, 0x04280000, 0x67b40001, 0x0b300001, 0x57b80001, 0x97400002, 0x06a80001, 0x9b00fffb, - 0xc4bb0260, 0x7fab8001, 0xcf880260, 0x04300020, 0x04280000, 0x66f40001, 0x0b300001, 0x56ec0001, - 0x97400005, 0x8c001628, 0xc4353247, 0x7f7f4009, 0x9b40fffe, 0x06a80001, 0x9b00fff7, 0x90000000, - 0x269c0007, 0x11dc0008, 0x29dc0008, 0x26a00018, 0x12200003, 0x7de1c00a, 0x26a00060, 0x06200020, - 0x16200001, 0x7de1c00a, 0xcdc00013, 0x90000000, 0x269c0018, 0x26a00007, 0x26a40060, 0x11dc0006, - 0x12200006, 0x16640001, 0x29dc0008, 0x7de1c00a, 0x7de5c00a, 0xcdc00013, 0x90000000, 0xc4b70228, - 0x05100001, 0x04cc0001, 0x2510000f, 0xccc80230, 0x7f514005, 0x25540001, 0x99400004, 0x05100001, - 0x2510000f, 0x80001644, 0xc4b30248, 0xcd080240, 0x7f130005, 0x27300001, 0x9b000002, 0x8c001688, - 0x8c00120d, 0x8c001219, 0x8c001232, 0x04300001, 0x04340801, 0x7f130004, 0xcf400013, 0xcf01051e, - 0xc42d051f, 0x7ed2c005, 0x26ec0001, 0x96c0fffd, 0xcf01051f, 0xd8000055, 0xc5170309, 0x195c07f0, - 0x196007f6, 0x04340000, 0x95c00008, 0x09dc0001, 0x04340001, 0x95c00005, 0x09dc0001, 0x53740001, - 0x6b740001, 0x80001665, 0xc4a702a0, 0xc4ab0298, 0x52640020, 0x7e6a401a, 0x7f634014, 0x7e76401a, - 0xc4300004, 0xd8400008, 0xd8400013, 0x56680020, 0xd8113320, 0xce480298, 0xce8802a0, 0xc5170319, - 0xc4b702b0, 0x255c000f, 0x7f5f4001, 0xd8113330, 0xcf4802b0, 0x11340001, 0x195c07e8, 0x196007ee, - 0xd8353300, 0x7e1e4001, 0xd8353301, 0xce4802d0, 0xd8100309, 0xd8100319, 0xcf000008, 0x90000000, - 0xc4970258, 0xc48f0250, 0x51540020, 0x7cd4c01a, 0xc4af0280, 0xc4b30278, 0x52ec0020, 0x7ef2c01a, - 0x04140020, 0x04280000, 0x64d80001, 0x09540001, 0x54cc0001, 0x95800060, 0x8c001628, 0xc4193247, - 0x25980001, 0x9580005c, 0x7dc24001, 0xc41d3248, 0x25dc000f, 0x7dd2000c, 0x96000057, 0xc41d3255, - 0xc435324f, 0x7df5c00c, 0x99c00004, 0xc4193265, 0x25980040, 0x9580fffe, 0xc439325b, 0x1bb0003f, - 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, 0x9700000a, 0xc4393260, 0x1bb000e4, - 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x800016f1, 0xce400013, 0xc033ffff, - 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, 0x27b800ff, 0x9b80fffe, 0xd8c00033, - 0xc4300009, 0x27300008, 0x9700fffe, 0x1a7003e6, 0x27380003, 0x13b80004, 0x27300003, 0x13300003, - 0x7fb38001, 0x1a7000e8, 0x7fb38001, 0x13300001, 0x7fb38001, 0x07b80002, 0xd8400013, 0x1a700064, - 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, - 0x0b300003, 0x800016df, 0x17b00005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, 0x13300005, - 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, 0xd8c00034, 0xce400013, 0xc431325d, - 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffca, 0xd841325d, 0x2030007b, 0xcf01325b, - 0x800016f2, 0xd841325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0x06a80001, 0x9940ff9c, 0x8c001608, - 0xd8080278, 0xd8080280, 0x90000000, 0xd840004f, 0xc414000e, 0x29540008, 0xcd400013, 0xc43d3265, - 0x1bc800ea, 0xd80802e9, 0x7c40c001, 0x18fc0064, 0x9bc00042, 0xc4193246, 0xc41d3245, 0x51980020, - 0x7dd9801a, 0x45980400, 0xc4313267, 0x043c3000, 0xcfc13267, 0xc43d3267, 0x9bc00001, 0x1b380057, - 0x1b340213, 0x1b300199, 0x7f7b400a, 0x7f73400a, 0xcf400024, 0x14f4001d, 0xc4bf02e9, 0x9bc0001c, - 0x7c410001, 0x192807fa, 0xc4bf0258, 0xc4a70250, 0x53fc0020, 0x7e7e401a, 0x042c0000, 0x04300000, - 0x667c0001, 0x56640001, 0x06ec0001, 0x97c0fffd, 0x07300001, 0x0aec0001, 0x7eebc00c, 0x06ec0001, - 0x97c0fff8, 0x0b300001, 0x43300007, 0x53300002, 0x7db30011, 0xd3000025, 0xc03ec005, 0x2bfca200, - 0xcfc00026, 0xccc00026, 0xcd000026, 0x192807fa, 0xc01f007f, 0x7d1d0009, 0x2110007d, 0x8c001628, - 0x203c003f, 0xcfc13256, 0x8c0017f5, 0xcd013254, 0x18fc01e8, 0xcfc13248, 0x8c00185b, 0xd8413247, - 0x0b740001, 0x9b40ffd5, 0xd800004f, 0xc4bf02e9, 0x97c0ea24, 0x90000000, 0x14d4001d, 0xc4930260, - 0x7d52400e, 0xc49f0258, 0xc4a30250, 0x51dc0020, 0x7de1801a, 0x96400017, 0x7d534002, 0xc4af0270, - 0x7dae4005, 0x26640001, 0x32e0001f, 0x9a400006, 0x06ec0001, 0x96000002, 0x042c0000, 0xcec80270, - 0x8000174f, 0x0b740001, 0x8c00178a, 0x05100001, 0x9b40fff3, 0xc4af0280, 0xc4b30278, 0x52ec0020, - 0x7ef2c01a, 0x8c001608, 0xd8080278, 0xd8080280, 0xc4ab0268, 0x7daa4005, 0x26640001, 0x32a0001f, - 0x9a400005, 0x06a80001, 0x96000002, 0x24280000, 0x80001765, 0x7c410001, 0xc01f007f, 0x09540001, - 0x7d1d0009, 0x2110007d, 0x8c001628, 0xd8013256, 0x8c0017f2, 0xcd013254, 0xc4113248, 0x15100004, - 0x11100004, 0xc4b3034b, 0x7f13000a, 0xcf013248, 0xc4930260, 0x8c001855, 0x32a4001f, 0xd8413247, - 0xd800004f, 0x09100001, 0x06a80001, 0x96400002, 0x24280000, 0xcd080260, 0xce880268, 0x9940ffc0, - 0x7c408001, 0x88000000, 0x7ec28001, 0x8c001628, 0x32e0001f, 0xc4253247, 0x26640001, 0x9640005e, - 0xc4293265, 0xc4253255, 0xc431324f, 0x7e72400c, 0x26a80040, 0x9a400002, 0x9680fff7, 0xc429325b, - 0x1aa4003f, 0x96400049, 0x1aa400e8, 0x32680003, 0x9a800046, 0x32640002, 0x9640000a, 0xc4293260, - 0x1aa400e4, 0x32640004, 0x96400040, 0xc425325d, 0x26640010, 0x9a40fffe, 0x800017e2, 0xcdc00013, - 0xc027ffff, 0x2e6400ff, 0xc429325b, 0x7e6a4009, 0xce41325b, 0xc429325b, 0x26a800ff, 0x9a80fffe, - 0xd8c00033, 0xc4240009, 0x26640008, 0x9640fffe, 0x19e403e6, 0x26680003, 0x12a80004, 0x26640003, - 0x12640003, 0x7ea68001, 0x19e400e8, 0x7ea68001, 0x12640001, 0x7ea68001, 0x06a80002, 0xd8400013, - 0x19e40064, 0x32640002, 0x96400009, 0x16a40005, 0x06640003, 0xce412082, 0xcc01203f, 0xd8400013, - 0xcc01203f, 0x0a640003, 0x800017d0, 0x16a40005, 0xce412082, 0xcc01203f, 0xd8400013, 0xcc01203f, - 0x12640005, 0x7ea64002, 0xc4292083, 0x7ea68005, 0x26a80001, 0x9a80ffdf, 0xd8c00034, 0xcdc00013, - 0xc425325d, 0x26640010, 0x9a40fffe, 0xc429325b, 0x26a400ff, 0x9a40ffca, 0xd841325d, 0x2024007b, - 0xce41325b, 0x800017e3, 0xd841325d, 0xc4a70280, 0xc4ab0278, 0x52640020, 0x7e6a401a, 0x04280001, - 0x7eae8014, 0x7e6a401a, 0x56680020, 0xce480278, 0xce880280, 0x06ec0001, 0x96000002, 0x042c0000, - 0xcec80270, 0x90000000, 0x7c438001, 0x7c420001, 0x800017fe, 0xc4bf02e9, 0x9bc00006, 0x7c438001, - 0x7c420001, 0xcf800026, 0xce000026, 0x800017fe, 0xc43b02eb, 0xc42302ec, 0xcf813245, 0xce013246, - 0x52200020, 0x7fa3801a, 0x47b8020c, 0x15e00008, 0x1220000a, 0x2a206032, 0x513c001e, 0x7e3e001a, - 0xc4bf02e9, 0x9bc00005, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0x8000180f, 0xcd400013, 0xc4313267, - 0x1b3c0077, 0x1b300199, 0x7ff3000a, 0x1330000a, 0x2b300032, 0x043c3000, 0xcfc13267, 0xc43d3267, - 0xd200000b, 0xc4200007, 0xd3800002, 0xcf000002, 0xd8000040, 0x96000002, 0xd8400040, 0xd8400018, - 0x043c2000, 0xcfc13267, 0xd8000018, 0xd8800010, 0xcdc00013, 0x7dc30001, 0xdc1e0000, 0x04380032, - 0xcf80000e, 0x8c001427, 0xcc413248, 0xc43d3269, 0x27fc000f, 0x33fc0003, 0x97c00011, 0x043c001f, - 0xdfc30000, 0xd4413249, 0x7c43c001, 0x7c43c001, 0x043c0024, 0x0bfc0021, 0xdfc30000, 0xd441326a, - 0x173c0008, 0x1b300303, 0x7f3f0001, 0x043c0001, 0x7ff3c004, 0xcfc13084, 0x80001842, 0x043c0024, - 0xdfc30000, 0xd4413249, 0x7c43c001, 0x23fc003f, 0xcfc1326d, 0x0bb80026, 0xdf830000, 0xd441326e, - 0x7c438001, 0x7c438001, 0xc4393265, 0x1fb8ffc6, 0xddc30000, 0xcf813265, 0x9a000003, 0xcdc0000c, - 0x80001852, 0xcdc0000d, 0xce000010, 0x8c00142b, 0x90000000, 0x7c41c001, 0x7c420001, 0xcdc13252, - 0xce013253, 0x8c001628, 0x80001878, 0xc49f02e9, 0x99c00018, 0x7c41c001, 0x7c420001, 0xcdc13252, - 0xce013253, 0xc43c000e, 0x2bfc0008, 0xcfc00013, 0x043c3000, 0xcfc13267, 0xc43d3267, 0x97c0ffff, - 0xcdc00026, 0xce000026, 0xd8400027, 0xc41c0012, 0x99c0ffff, 0xc43c000e, 0x2bfc0008, 0xcfc00013, - 0x043c2000, 0xcfc13267, 0x8c001628, 0x80001878, 0xc41f02ed, 0xc42302ee, 0xcdc13252, 0xce013253, - 0x04200001, 0x7e2a0004, 0xce013084, 0x90000000, 0x28340001, 0x313c0bcc, 0x9bc00010, 0x393c051f, - 0x9bc00004, 0x3d3c050e, 0x9bc0000c, 0x97c0000c, 0x393c0560, 0x9bc00004, 0x3d3c054f, 0x9bc00007, - 0x97c00007, 0x393c1538, 0x9bc00005, 0x3d3c1537, 0x9bc00002, 0x97c00002, 0x2b740800, 0x90000000, - 0xc40c000e, 0x28cc0008, 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c40c001, 0x18e8007c, 0x7c42c001, - 0x06a8189a, 0x86800000, 0x8000189e, 0x800018c5, 0x800018f2, 0x8000016a, 0x7c414001, 0x18d0007e, - 0x50580020, 0x09200001, 0x7d59401a, 0xd1400072, 0xc8140072, 0x09240002, 0x7c418001, 0x7c41c001, - 0x99000011, 0xc4340004, 0xd8400013, 0xd8400008, 0xc42130b5, 0x1a24002c, 0x9a40fffe, 0x2020002c, - 0xc418000d, 0x1198001c, 0x10cc0004, 0x14cc0004, 0x7cd8c00a, 0xccc130b7, 0xce0130b5, 0xcf400008, - 0x80000168, 0xd1400025, 0x5978073a, 0x2bb80002, 0xcf800024, 0xcd800026, 0xcdc00026, 0xd8400027, - 0x9600e8a8, 0xc4300012, 0x9b00ffff, 0x9640e8a5, 0x800018a9, 0x04140000, 0xc55b0309, 0x3d5c0010, - 0x05540001, 0x2598ffff, 0x09780001, 0x7dad800c, 0x99c0ffd2, 0x9580fff9, 0xc4970258, 0xc4930250, - 0x51540020, 0x7d15001a, 0x04140020, 0x04280000, 0x442c0000, 0x65180001, 0x09540001, 0x55100001, - 0x9580000b, 0x8c001628, 0xc41d3248, 0x04300001, 0x7f2b0014, 0x25dc000f, 0x7df9c00c, 0x95c00004, - 0x7ef2c01a, 0xd8c13260, 0xd901325d, 0x06a80001, 0x9940fff1, 0x04140020, 0x04280000, 0x66d80001, - 0x09540001, 0x56ec0001, 0x95800005, 0x8c001628, 0xc421325d, 0x26240007, 0x9a40fffe, 0x06a80001, - 0x9940fff7, 0x8000189e, 0x04140020, 0x04280000, 0x09540001, 0x8c001628, 0xc41d3254, 0xc023007f, - 0x19e4003e, 0x7de1c009, 0x7dee000c, 0x96400008, 0x96000007, 0xd8c13260, 0xd901325d, 0xc421325d, - 0x261c0007, 0x99c0fffe, 0x8000189e, 0x06a80001, 0x9940fff0, 0x8000189e, 0xc40c000e, 0x28cc0008, - 0xccc00013, 0xc43d3265, 0x1bc800ea, 0x7c40c001, 0x18e00064, 0x06281911, 0x14f4001d, 0x24cc0003, - 0x86800000, 0x80001915, 0x800019af, 0x80001a2b, 0x8000016a, 0xcc48032b, 0xcc480333, 0xcc48033b, - 0xcc480343, 0x98800011, 0xc4213246, 0xc4253245, 0x52200020, 0x7e26401a, 0x46640400, 0xc4313267, - 0x04203000, 0xce013267, 0xc4213267, 0x9a000001, 0x1b3c0057, 0x1b200213, 0x1b300199, 0x7e3e000a, - 0x7e32000a, 0xce000024, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, 0xc4b30278, - 0x52ec0020, 0x7ef2c01a, 0x04180000, 0x04140020, 0x04280000, 0x7f438001, 0x8c001628, 0xc41d3247, - 0x25dc0001, 0x95c00068, 0xc4213254, 0x1a1c003e, 0x95c00065, 0xc01f007f, 0x7e1e0009, 0x97800062, - 0x0bb80001, 0x43bc0008, 0x7fcbc001, 0xc7df032b, 0x7e1fc00c, 0x97c0fffa, 0x043c0101, 0x94c00002, - 0x043c0102, 0xc439325b, 0x1bb0003f, 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, - 0x97000009, 0xc4393260, 0x1bb000e4, 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, - 0x80001994, 0x8c001628, 0xc033ffff, 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, - 0x27b800ff, 0x9b80fffe, 0xd8c00033, 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27380003, - 0x13b80004, 0x27300003, 0x13300003, 0x7fb38001, 0x19f000e8, 0x7fb38001, 0x13300001, 0x7fb38001, - 0x07b80002, 0xd8400013, 0x19f00064, 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, - 0xcc01203f, 0xd8400013, 0xcc01203f, 0x0b300003, 0x80001982, 0x17b00005, 0xcf012082, 0xcc01203f, - 0xd8400013, 0xcc01203f, 0x13300005, 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, - 0xd8c00034, 0xcdc00013, 0xc431325d, 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffcb, - 0xcfc1325d, 0x2030007b, 0xcf01325b, 0x80001995, 0xcfc1325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, - 0x98800009, 0x41bc0007, 0x53fc0002, 0x7e7fc011, 0xd3c00025, 0xd8000026, 0xd8400027, 0xc43c0012, - 0x9bc0ffff, 0x653c0001, 0x7dbd8001, 0x06a80001, 0x09540001, 0x55100001, 0x9940ff8f, 0xc43c000e, - 0x2bfc0008, 0xcfc00013, 0x043c2000, 0xcfc13267, 0xd8080278, 0xd8080280, 0x80000168, 0x7c410001, - 0x04140000, 0xc55b0309, 0x3d5c0010, 0x2598ffff, 0x05540001, 0x7d91800c, 0x95c00003, 0xd4400078, - 0x80000168, 0x9580fff8, 0x09780001, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, - 0xc4b30278, 0x52ec0020, 0x7ef2c01a, 0x04140020, 0x04280000, 0x65180001, 0x09540001, 0x55100001, - 0x9580005d, 0x8c001628, 0xc4253247, 0x26640001, 0x04200101, 0x96400058, 0x7dc24001, 0xc41d3248, - 0x25dc000f, 0x7df9c00c, 0x95c00053, 0x94c00002, 0x04200102, 0x7e41c001, 0xc425325b, 0x1a70003f, - 0x97000049, 0x1a7000e8, 0x33240003, 0x9a400046, 0x33300002, 0x9700000a, 0xc4253260, 0x1a7000e4, - 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x80001a21, 0xcdc00013, 0xc033ffff, - 0x2f3000ff, 0xc425325b, 0x7f270009, 0xcf01325b, 0xc425325b, 0x266400ff, 0x9a40fffe, 0xd8c00033, - 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27240003, 0x12640004, 0x27300003, 0x13300003, - 0x7e724001, 0x19f000e8, 0x7e724001, 0x13300001, 0x7e724001, 0x06640002, 0xd8400013, 0x19f00064, - 0x33300002, 0x97000009, 0x16700005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, - 0x0b300003, 0x80001a0f, 0x16700005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, 0x13300005, - 0x7e730002, 0xc4252083, 0x7e724005, 0x26640001, 0x9a40ffdf, 0xd8c00034, 0xcdc00013, 0xc431325d, - 0x27300010, 0x9b00fffe, 0xc425325b, 0x267000ff, 0x9b00ffca, 0xce01325d, 0x2030007b, 0xcf01325b, - 0x80001a22, 0xce01325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0x06a80001, 0x9940ff9f, 0xd4400078, - 0xd8080278, 0xd8080280, 0x80000168, 0x8c001a31, 0xd4400078, 0xd8080278, 0xd8080280, 0x7c408001, - 0x88000000, 0xc4213246, 0xc4253245, 0x52200020, 0x7e26401a, 0x46640400, 0xc4313267, 0x04203000, - 0xce013267, 0xc4213267, 0x9a000001, 0x1b180057, 0x1b200213, 0x1b300199, 0x7e1a000a, 0x7e32000a, - 0xce000024, 0xc4970258, 0xc4930250, 0x51540020, 0x7d15001a, 0xc4af0280, 0xc4b30278, 0x52ec0020, - 0x7ef2c01a, 0x04140020, 0x04280000, 0x65180001, 0x95800060, 0x8c001628, 0xc4193247, 0x25980001, - 0x04200101, 0x94c00005, 0x30f00005, 0x04200005, 0x9b000002, 0x04200102, 0x95800056, 0xc439325b, - 0x1bb0003f, 0x97000049, 0x1bb000e8, 0x33380003, 0x9b800046, 0x33300002, 0x9700000a, 0xc4393260, - 0x1bb000e4, 0x33300004, 0x97000040, 0xc431325d, 0x27300010, 0x9b00fffe, 0x80001aa2, 0xcdc00013, - 0xc033ffff, 0x2f3000ff, 0xc439325b, 0x7f3b0009, 0xcf01325b, 0xc439325b, 0x27b800ff, 0x9b80fffe, - 0xd8c00033, 0xc4300009, 0x27300008, 0x9700fffe, 0x19f003e6, 0x27380003, 0x13b80004, 0x27300003, - 0x13300003, 0x7fb38001, 0x19f000e8, 0x7fb38001, 0x13300001, 0x7fb38001, 0x07b80002, 0xd8400013, - 0x19f00064, 0x33300002, 0x97000009, 0x17b00005, 0x07300003, 0xcf012082, 0xcc01203f, 0xd8400013, - 0xcc01203f, 0x0b300003, 0x80001a90, 0x17b00005, 0xcf012082, 0xcc01203f, 0xd8400013, 0xcc01203f, - 0x13300005, 0x7fb30002, 0xc4392083, 0x7fb38005, 0x27b80001, 0x9b80ffdf, 0xd8c00034, 0xcdc00013, - 0xc431325d, 0x27300010, 0x9b00fffe, 0xc439325b, 0x27b000ff, 0x9b00ffca, 0xce01325d, 0x2030007b, - 0xcf00325b, 0x80001aa3, 0xce01325d, 0x04300001, 0x7f2b0014, 0x7ef2c01a, 0xc49b02e9, 0x99800005, - 0xd2400025, 0x4664001c, 0xd8000026, 0xd8400027, 0x06a80001, 0x09540001, 0x55100001, 0x9940ff9c, - 0xc49b02e9, 0x99800008, 0xc430000e, 0x2b300008, 0xcf000013, 0x04302000, 0xcf013267, 0xc4313267, - 0x97000001, 0x90000000, 0x244c00ff, 0xcc4c0200, 0x7c408001, 0x88000000, 0xc44f0200, 0xc410000b, - 0xc414000c, 0x7d158010, 0x059cc000, 0xd8400013, 0xccdd0000, 0x7c408001, 0x88000000, 0xc40c0037, - 0x94c0ffff, 0xcc000049, 0xc40c003a, 0x94c0ffff, 0x7c40c001, 0x24d00001, 0x9500e69a, 0x18d0003b, - 0x18d40021, 0x99400006, 0xd840004a, 0xc40c003c, 0x94c0ffff, 0x14cc0001, 0x94c00028, 0xd8000033, - 0xc438000b, 0xc43c0009, 0x27fc0001, 0x97c0fffe, 0xd8400013, 0xd841c07f, 0xc43dc07f, 0x1bfc0078, - 0x7ffbc00c, 0x97c0fffd, 0x99000004, 0xc0120840, 0x282c0040, 0x80001ae8, 0xc0121841, 0x282c001a, - 0xcd01c07c, 0xcc01c07d, 0xcc01c08c, 0xcc01c079, 0xcc01c07e, 0x04200004, 0xcec0001b, 0xd8400021, - 0x0a200001, 0x9a00ffff, 0xc425c07f, 0x166c001f, 0x04200004, 0x9ac0fffb, 0xc434000f, 0x9b40ffff, - 0xd801c07f, 0xd8400013, 0xc425c07f, 0xce400078, 0xd8000034, 0x9940e66b, 0xd800004a, 0x7c408001, - 0x88000000, 0xc40c0036, 0x24d00001, 0x9900fffe, 0x18cc0021, 0xccc00047, 0xcc000046, 0xc40c0039, - 0x94c0ffff, 0xc40c003d, 0x98c0ffff, 0x7c40c001, 0x24d003ff, 0x18d47fea, 0x18d87ff4, 0xcd00004c, - 0xcd40004e, 0xcd80004d, 0xd8400013, 0xcd41c405, 0xc02a0001, 0x2aa80001, 0xce800013, 0xcd01c406, - 0xcc01c406, 0xcc01c406, 0xc40c0006, 0x98c0ffff, 0xc414000e, 0x29540008, 0x295c0001, 0xcd400013, - 0xd8c1325e, 0xcdc0001a, 0x11980002, 0x4110000c, 0xc0160800, 0x7d15000a, 0xc0164010, 0xd8400013, - 0xcd41c078, 0xcc01c080, 0xcc01c081, 0xcd81c082, 0xcc01c083, 0xcd01c084, 0xc40c0006, 0x98c0ffff, - 0xd8400048, 0xc40c003b, 0x94c0ffff, 0x80000c16, 0xd8400013, 0xd801c40a, 0xd901c40d, 0xd801c410, - 0xd801c40e, 0xd801c40f, 0xc40c0040, 0x04140001, 0x09540001, 0x9940ffff, 0x04140096, 0xd8400013, - 0xccc1c400, 0xc411c401, 0x9500fffa, 0xc424003e, 0x04d00001, 0x11100002, 0xcd01c40c, 0xc0180034, - 0xcd81c411, 0xd841c414, 0x0a540001, 0xcd41c412, 0x2468000f, 0xc419c416, 0x41980003, 0xc41c003f, - 0x7dda0001, 0x12200002, 0x10cc0002, 0xccc1c40c, 0xd901c411, 0xce41c412, 0xd8800013, 0xce292e40, - 0xcc412e01, 0xcc412e02, 0xcc412e03, 0xcc412e00, 0x80000aa7, 0xc43c0007, 0xdc120000, 0x31144000, - 0x95400005, 0xdc030000, 0xd800002a, 0xcc3c000c, 0x80001b70, 0x33f80003, 0xd4400078, 0x9780e601, - 0x188cfff0, 0x04e40002, 0x80001190, 0x7c408001, 0x88000000, 0xc424005e, 0x96400006, 0x90000000, - 0xc424005e, 0x96400003, 0x7c408001, 0x88000000, 0x80001b74, 0x80000168, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0x92100004, 0x92110501, 0x92120206, 0x92130703, 0x92100400, 0x92110105, 0x92120602, 0x92130307, - 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - .dfy_size = 7440 -}; - -static const PWR_DFY_Section pwr_virus_section4 = { - .dfy_cntl = 0x80000004, - .dfy_addr_hi = 0x000000b4, - .dfy_addr_lo = 0x54106500, - .dfy_data = { - 0x7e000200, 0x7e020204, 0xc00a0505, 0x00000000, 0xbf8c007f, 0xb8900904, 0xb8911a04, 0xb8920304, - 0xb8930b44, 0x921c0d0c, 0x921c1c13, 0x921d0c12, 0x811c1d1c, 0x811c111c, 0x921cff1c, 0x00000400, - 0x921dff10, 0x00000100, 0x81181d1c, 0x7e040218, 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050002, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0701000, 0x80050102, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, 0xe0501000, 0x80050302, - 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - .dfy_size = 240 -}; - -static const PWR_DFY_Section pwr_virus_section5 = { - .dfy_cntl = 0x80000004, - .dfy_addr_hi = 0x000000b4, - .dfy_addr_lo = 0x54106900, - .dfy_data = { - 0x7e080200, 0x7e100204, 0xbefc00ff, 0x00010000, 0x24200087, 0x262200ff, 0x000001f0, 0x20222282, - 0x28182111, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, - 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, - 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, - 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, - 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, 0x0000040c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd81a0000, - 0x0000080c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, 0x1100000c, 0xd86c0000, - 0x1100000c, 0xbf810000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - .dfy_size = 384 -}; - -static const PWR_DFY_Section pwr_virus_section6 = { - .dfy_cntl = 0x80000004, - .dfy_addr_hi = 0x000000b4, - .dfy_addr_lo = 0x54116f00, - .dfy_data = { - 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4540fe8, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000041, 0x0000000c, 0x00000000, 0x07808000, 0xffffffff, - 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, - 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x54116f00, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, - 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, - 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb454105e, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x000000c0, 0x00000010, 0x00000000, 0x07808000, 0xffffffff, - 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, - 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x54117300, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, - 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, - 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4541065, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000500, 0x0000001c, 0x00000000, 0x07808000, 0xffffffff, - 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, - 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x54117700, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, - 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, - 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0xc0310800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000040, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0xb4541069, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000444, 0x0000008a, 0x00000000, 0x07808000, 0xffffffff, - 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555, 0x55555555, - 0x55555555, 0x00000000, 0x00000000, 0x540fee40, 0x000000b4, 0x00000010, 0x00000001, 0x00000004, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x54117b00, 0x000000b4, 0x00000000, 0x00000000, 0x00005301, 0x00000000, 0x00000000, 0x00000000, - 0xb4540fef, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x540fee20, 0x000000b4, 0x00000000, - 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - .dfy_size = 1024 -}; - -static const PWR_Command_Table PwrVirusTable_post[] = { - { 0x00000000, mmCP_MEC_CNTL }, - { 0x00000000, mmCP_MEC_CNTL }, - { 0x00000004, mmSRBM_GFX_CNTL }, - { 0x54116f00, mmCP_MQD_BASE_ADDR }, - { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { 0xb4540fef, mmCP_HQD_PQ_BASE }, - { 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { 0x00010000, mmCP_HQD_VMID }, - { 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { 0x00000005, mmSRBM_GFX_CNTL }, - { 0x54117300, mmCP_MQD_BASE_ADDR }, - { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { 0xb4540fef, mmCP_HQD_PQ_BASE }, - { 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { 0x00010000, mmCP_HQD_VMID }, - { 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { 0x00000006, mmSRBM_GFX_CNTL }, - { 0x54117700, mmCP_MQD_BASE_ADDR }, - { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { 0xb4540fef, mmCP_HQD_PQ_BASE }, - { 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { 0x00010000, mmCP_HQD_VMID }, - { 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { 0x00000007, mmSRBM_GFX_CNTL }, - { 0x54117b00, mmCP_MQD_BASE_ADDR }, - { 0x000000b4, mmCP_MQD_BASE_ADDR_HI }, - { 0xb4540fef, mmCP_HQD_PQ_BASE }, - { 0x00000000, mmCP_HQD_PQ_BASE_HI }, - { 0x540fee20, mmCP_HQD_PQ_WPTR_POLL_ADDR }, - { 0x000000b4, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI }, - { 0x00005301, mmCP_HQD_PERSISTENT_STATE }, - { 0x00010000, mmCP_HQD_VMID }, - { 0xc8318509, mmCP_HQD_PQ_CONTROL }, - { 0x00000004, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000104, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000204, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000304, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000404, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000504, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000604, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000704, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000005, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000105, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000205, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000305, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000405, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000505, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000605, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000705, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000006, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000106, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000206, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000306, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000406, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000506, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000606, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000706, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000007, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000107, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000207, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000307, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000407, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000507, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000607, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000707, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000008, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000108, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000208, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000308, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000408, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000508, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000608, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000708, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000009, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000109, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000209, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000309, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000409, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000509, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000609, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000709, mmSRBM_GFX_CNTL }, - { 0x00000000, mmCP_HQD_ACTIVE }, - { 0x00000000, mmCP_HQD_PQ_RPTR }, - { 0x00000000, mmCP_HQD_PQ_WPTR }, - { 0x00000001, mmCP_HQD_ACTIVE }, - { 0x00000004, mmSRBM_GFX_CNTL }, - { 0x01010101, mmCP_PQ_WPTR_POLL_CNTL1 }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, mmGRBM_STATUS }, - { 0x00000000, 0xffffffff }, -}; - -#endif diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 592a89aff12b..ba951c7c2b41 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -37,7 +37,6 @@ #include "gca/gfx_8_0_d.h" #include "bif/bif_5_0_d.h" #include "bif/bif_5_0_sh_mask.h" -#include "fiji_pwrvirus.h" #include "fiji_smc.h" #define AVFS_EN_MSB 1568 @@ -159,46 +158,6 @@ static int fiji_start_smu_in_non_protection_mode(struct pp_hwmgr *hwmgr) return result; } -static void execute_pwr_table(struct pp_hwmgr *hwmgr, const PWR_Command_Table *pvirus, int size) -{ - int i; - uint32_t reg, data; - - for (i = 0; i < size; i++) { - reg = pvirus->reg; - data = pvirus->data; - if (reg != 0xffffffff) - cgs_write_register(hwmgr->device, reg, data); - else - break; - pvirus++; - } -} - -static void execute_pwr_dfy_table(struct pp_hwmgr *hwmgr, const PWR_DFY_Section *section) -{ - int i; - cgs_write_register(hwmgr->device, mmCP_DFY_CNTL, section->dfy_cntl); - cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_HI, section->dfy_addr_hi); - cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_LO, section->dfy_addr_lo); - for (i = 0; i < section->dfy_size; i++) - cgs_write_register(hwmgr->device, mmCP_DFY_DATA_0, section->dfy_data[i]); -} - -static int fiji_setup_pwr_virus(struct pp_hwmgr *hwmgr) -{ - execute_pwr_table(hwmgr, PwrVirusTable_pre, ARRAY_SIZE(PwrVirusTable_pre)); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section1); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section2); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section3); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section4); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section5); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section6); - execute_pwr_table(hwmgr, PwrVirusTable_post, ARRAY_SIZE(PwrVirusTable_post)); - - return 0; -} - static int fiji_start_avfs_btc(struct pp_hwmgr *hwmgr) { int result = 0; @@ -277,7 +236,7 @@ static int fiji_avfs_event_mgr(struct pp_hwmgr *hwmgr, bool smu_started) " table over to SMU", return -EINVAL;); smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL; - PP_ASSERT_WITH_CODE(0 == fiji_setup_pwr_virus(hwmgr), + PP_ASSERT_WITH_CODE(0 == smu7_setup_pwr_virus(hwmgr), "[AVFS][fiji_avfs_event_mgr] Could not setup " "Pwr Virus for AVFS ", return -EINVAL;); diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 61ee6281fbda..454bfc14335d 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -35,7 +35,6 @@ #include "gca/gfx_8_0_d.h" #include "bif/bif_5_0_d.h" #include "bif/bif_5_0_sh_mask.h" -#include "polaris10_pwrvirus.h" #include "ppatomctrl.h" #include "cgs_common.h" #include "polaris10_smc.h" @@ -60,46 +59,6 @@ static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = { static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 = { 0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00}; -static void execute_pwr_table(struct pp_hwmgr *hwmgr, const PWR_Command_Table *pvirus, int size) -{ - int i; - uint32_t reg, data; - - for (i = 0; i < size; i++) { - reg = pvirus->reg; - data = pvirus->data; - if (reg != 0xffffffff) - cgs_write_register(hwmgr->device, reg, data); - else - break; - pvirus++; - } -} - -static void execute_pwr_dfy_table(struct pp_hwmgr *hwmgr, const PWR_DFY_Section *section) -{ - int i; - cgs_write_register(hwmgr->device, mmCP_DFY_CNTL, section->dfy_cntl); - cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_HI, section->dfy_addr_hi); - cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_LO, section->dfy_addr_lo); - for (i = 0; i < section->dfy_size; i++) - cgs_write_register(hwmgr->device, mmCP_DFY_DATA_0, section->dfy_data[i]); -} - -static int polaris10_setup_pwr_virus(struct pp_hwmgr *hwmgr) -{ - execute_pwr_table(hwmgr, pwr_virus_table_pre, ARRAY_SIZE(pwr_virus_table_pre)); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section1); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section2); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section3); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section4); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section5); - execute_pwr_dfy_table(hwmgr, &pwr_virus_section6); - execute_pwr_table(hwmgr, pwr_virus_table_post, ARRAY_SIZE(pwr_virus_table_post)); - - return 0; -} - static int polaris10_perform_btc(struct pp_hwmgr *hwmgr) { int result = 0; @@ -197,7 +156,7 @@ polaris10_avfs_event_mgr(struct pp_hwmgr *hwmgr, bool SMU_VFT_INTACT) if (smu_data->avfs.avfs_btc_param > 1) { pr_info("[AVFS][Polaris10_AVFSEventMgr] AC BTC has not been successfully verified on Fiji. There may be in this setting."); smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL; - PP_ASSERT_WITH_CODE(0 == polaris10_setup_pwr_virus(hwmgr), + PP_ASSERT_WITH_CODE(0 == smu7_setup_pwr_virus(hwmgr), "[AVFS][Polaris10_AVFSEventMgr] Could not setup Pwr Virus for AVFS ", return -EINVAL); } diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c index c997117f2461..7f5359a97ef2 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c @@ -25,12 +25,13 @@ #include "pp_debug.h" #include "smumgr.h" #include "smu_ucode_xfer_vi.h" -#include "smu/smu_7_1_3_d.h" -#include "smu/smu_7_1_3_sh_mask.h" #include "ppatomctrl.h" #include "cgs_common.h" #include "smu7_ppsmc.h" #include "smu7_smumgr.h" +#include "smu7_common.h" + +#include "polaris10_pwrvirus.h" #define SMU7_SMC_SIZE 0x20000 @@ -540,6 +541,47 @@ int smu7_upload_smu_firmware_image(struct pp_hwmgr *hwmgr) return result; } +static void execute_pwr_table(struct pp_hwmgr *hwmgr, const PWR_Command_Table *pvirus, int size) +{ + int i; + uint32_t reg, data; + + for (i = 0; i < size; i++) { + reg = pvirus->reg; + data = pvirus->data; + if (reg != 0xffffffff) + cgs_write_register(hwmgr->device, reg, data); + else + break; + pvirus++; + } +} + +static void execute_pwr_dfy_table(struct pp_hwmgr *hwmgr, const PWR_DFY_Section *section) +{ + int i; + + cgs_write_register(hwmgr->device, mmCP_DFY_CNTL, section->dfy_cntl); + cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_HI, section->dfy_addr_hi); + cgs_write_register(hwmgr->device, mmCP_DFY_ADDR_LO, section->dfy_addr_lo); + for (i = 0; i < section->dfy_size; i++) + cgs_write_register(hwmgr->device, mmCP_DFY_DATA_0, section->dfy_data[i]); +} + +int smu7_setup_pwr_virus(struct pp_hwmgr *hwmgr) +{ + execute_pwr_table(hwmgr, pwr_virus_table_pre, ARRAY_SIZE(pwr_virus_table_pre)); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section1); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section2); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section3); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section4); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section5); + execute_pwr_dfy_table(hwmgr, &pwr_virus_section6); + execute_pwr_table(hwmgr, pwr_virus_table_post, ARRAY_SIZE(pwr_virus_table_post)); + + return 0; +} + int smu7_init(struct pp_hwmgr *hwmgr) { struct smu7_smumgr *smu_data; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h index 0b63c5c1043c..c87263bc0caa 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h @@ -88,4 +88,6 @@ int smu7_upload_smu_firmware_image(struct pp_hwmgr *hwmgr); int smu7_init(struct pp_hwmgr *hwmgr); int smu7_smu_fini(struct pp_hwmgr *hwmgr); -#endif \ No newline at end of file +int smu7_setup_pwr_virus(struct pp_hwmgr *hwmgr); + +#endif -- cgit v1.2.3 From 202f5d6e1a5962e3acb21c50cd9b4e3ab5990dab Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 13:50:31 +0800 Subject: drm/amdgpu: refine code delete duplicated error handling in function amdgpu_ucode_init_bo, when failed, it will set load_type to AMDGPU_FW_LOAD_DIRECT. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 412ad99d8871..1f793eb301ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1711,8 +1711,8 @@ static int amdgpu_init(struct amdgpu_device *adev) } mutex_lock(&adev->firmware.mutex); - if (amdgpu_ucode_init_bo(adev)) - adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT; + if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) + amdgpu_ucode_init_bo(adev); mutex_unlock(&adev->firmware.mutex); for (i = 0; i < adev->num_ip_blocks; i++) { -- cgit v1.2.3 From 9c4cd84f48c179272b93b12007189e6aea509555 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 15:05:21 +0800 Subject: drm/amd/pp: rename ci_smc.c to ci_smumgr.c for consistency. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/Makefile | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c | 2818 ---------------------- drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c | 2818 ++++++++++++++++++++++ 3 files changed, 2819 insertions(+), 2819 deletions(-) delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c create mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile index 4e2988825ff6..d7be7834173f 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile @@ -4,7 +4,7 @@ SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o fiji_smc.o \ polaris10_smumgr.o iceland_smumgr.o polaris10_smc.o tonga_smc.o \ - smu7_smumgr.o iceland_smc.o vega10_smumgr.o rv_smumgr.o ci_smc.o + smu7_smumgr.o iceland_smc.o vega10_smumgr.o rv_smumgr.o ci_smumgr.o AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c deleted file mode 100644 index 4d672cd15785..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smc.c +++ /dev/null @@ -1,2818 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include -#include -#include -#include "linux/delay.h" -#include - -#include "smumgr.h" -#include "pp_debug.h" -#include "ci_smumgr.h" -#include "ppsmc.h" -#include "smu7_hwmgr.h" -#include "hardwaremanager.h" -#include "ppatomctrl.h" -#include "cgs_common.h" -#include "atombios.h" -#include "pppcielanes.h" - -#include "smu/smu_7_0_1_d.h" -#include "smu/smu_7_0_1_sh_mask.h" - -#include "dce/dce_8_0_d.h" -#include "dce/dce_8_0_sh_mask.h" - -#include "bif/bif_4_1_d.h" -#include "bif/bif_4_1_sh_mask.h" - -#include "gca/gfx_7_2_d.h" -#include "gca/gfx_7_2_sh_mask.h" - -#include "gmc/gmc_7_1_d.h" -#include "gmc/gmc_7_1_sh_mask.h" - -#include "processpptables.h" - -#define MC_CG_ARB_FREQ_F0 0x0a -#define MC_CG_ARB_FREQ_F1 0x0b -#define MC_CG_ARB_FREQ_F2 0x0c -#define MC_CG_ARB_FREQ_F3 0x0d - -#define SMC_RAM_END 0x40000 - -#define VOLTAGE_SCALE 4 -#define VOLTAGE_VID_OFFSET_SCALE1 625 -#define VOLTAGE_VID_OFFSET_SCALE2 100 -#define CISLAND_MINIMUM_ENGINE_CLOCK 800 -#define CISLAND_MAX_DEEPSLEEP_DIVIDER_ID 5 - -static const struct ci_pt_defaults defaults_hawaii_xt = { - 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0xB0000, - { 0x2E, 0x00, 0x00, 0x88, 0x00, 0x00, 0x72, 0x60, 0x51, 0xA7, 0x79, 0x6B, 0x90, 0xBD, 0x79 }, - { 0x217, 0x217, 0x217, 0x242, 0x242, 0x242, 0x269, 0x269, 0x269, 0x2A1, 0x2A1, 0x2A1, 0x2C9, 0x2C9, 0x2C9 } -}; - -static const struct ci_pt_defaults defaults_hawaii_pro = { - 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0x65062, - { 0x2E, 0x00, 0x00, 0x88, 0x00, 0x00, 0x72, 0x60, 0x51, 0xA7, 0x79, 0x6B, 0x90, 0xBD, 0x79 }, - { 0x217, 0x217, 0x217, 0x242, 0x242, 0x242, 0x269, 0x269, 0x269, 0x2A1, 0x2A1, 0x2A1, 0x2C9, 0x2C9, 0x2C9 } -}; - -static const struct ci_pt_defaults defaults_bonaire_xt = { - 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, - { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61 }, - { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } -}; - - -static const struct ci_pt_defaults defaults_saturn_xt = { - 1, 0xF, 0xFD, 0x19, 5, 55, 0, 0x70000, - { 0x8C, 0x247, 0x249, 0xA6, 0x80, 0x81, 0x8B, 0x89, 0x86, 0xC9, 0xCA, 0xC9, 0x4D, 0x4D, 0x4D }, - { 0x187, 0x187, 0x187, 0x1C7, 0x1C7, 0x1C7, 0x210, 0x210, 0x210, 0x266, 0x266, 0x266, 0x2C9, 0x2C9, 0x2C9 } -}; - - -static int ci_set_smc_sram_address(struct pp_hwmgr *hwmgr, - uint32_t smc_addr, uint32_t limit) -{ - if ((0 != (3 & smc_addr)) - || ((smc_addr + 3) >= limit)) { - pr_err("smc_addr invalid \n"); - return -EINVAL; - } - - cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_0, smc_addr); - PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); - return 0; -} - -static int ci_copy_bytes_to_smc(struct pp_hwmgr *hwmgr, uint32_t smc_start_address, - const uint8_t *src, uint32_t byte_count, uint32_t limit) -{ - int result; - uint32_t data = 0; - uint32_t original_data; - uint32_t addr = 0; - uint32_t extra_shift; - - if ((3 & smc_start_address) - || ((smc_start_address + byte_count) >= limit)) { - pr_err("smc_start_address invalid \n"); - return -EINVAL; - } - - addr = smc_start_address; - - while (byte_count >= 4) { - /* Bytes are written into the SMC address space with the MSB first. */ - data = src[0] * 0x1000000 + src[1] * 0x10000 + src[2] * 0x100 + src[3]; - - result = ci_set_smc_sram_address(hwmgr, addr, limit); - - if (0 != result) - return result; - - cgs_write_register(hwmgr->device, mmSMC_IND_DATA_0, data); - - src += 4; - byte_count -= 4; - addr += 4; - } - - if (0 != byte_count) { - - data = 0; - - result = ci_set_smc_sram_address(hwmgr, addr, limit); - - if (0 != result) - return result; - - - original_data = cgs_read_register(hwmgr->device, mmSMC_IND_DATA_0); - - extra_shift = 8 * (4 - byte_count); - - while (byte_count > 0) { - /* Bytes are written into the SMC addres space with the MSB first. */ - data = (0x100 * data) + *src++; - byte_count--; - } - - data <<= extra_shift; - - data |= (original_data & ~((~0UL) << extra_shift)); - - result = ci_set_smc_sram_address(hwmgr, addr, limit); - - if (0 != result) - return result; - - cgs_write_register(hwmgr->device, mmSMC_IND_DATA_0, data); - } - - return 0; -} - - -static int ci_program_jump_on_start(struct pp_hwmgr *hwmgr) -{ - static const unsigned char data[4] = { 0xE0, 0x00, 0x80, 0x40 }; - - ci_copy_bytes_to_smc(hwmgr, 0x0, data, 4, sizeof(data)+1); - - return 0; -} - -bool ci_is_smc_ram_running(struct pp_hwmgr *hwmgr) -{ - return ((0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, - CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable)) - && (0x20100 <= cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, ixSMC_PC_C))); -} - -static int ci_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, - uint32_t *value, uint32_t limit) -{ - int result; - - result = ci_set_smc_sram_address(hwmgr, smc_addr, limit); - - if (result) - return result; - - *value = cgs_read_register(hwmgr->device, mmSMC_IND_DATA_0); - return 0; -} - -static int ci_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) -{ - int ret; - - if (!ci_is_smc_ram_running(hwmgr)) - return -EINVAL; - - cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg); - - PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); - - ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP); - - if (ret != 1) - pr_info("\n failed to send message %x ret is %d\n", msg, ret); - - return 0; -} - -static int ci_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, - uint16_t msg, uint32_t parameter) -{ - cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter); - return ci_send_msg_to_smc(hwmgr, msg); -} - -static void ci_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - struct cgs_system_info sys_info = {0}; - uint32_t dev_id; - - sys_info.size = sizeof(struct cgs_system_info); - sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; - cgs_query_system_info(hwmgr->device, &sys_info); - dev_id = (uint32_t)sys_info.value; - - switch (dev_id) { - case 0x67BA: - case 0x66B1: - smu_data->power_tune_defaults = &defaults_hawaii_pro; - break; - case 0x67B8: - case 0x66B0: - smu_data->power_tune_defaults = &defaults_hawaii_xt; - break; - case 0x6640: - case 0x6641: - case 0x6646: - case 0x6647: - smu_data->power_tune_defaults = &defaults_saturn_xt; - break; - case 0x6649: - case 0x6650: - case 0x6651: - case 0x6658: - case 0x665C: - case 0x665D: - case 0x67A0: - case 0x67A1: - case 0x67A2: - case 0x67A8: - case 0x67A9: - case 0x67AA: - case 0x67B9: - case 0x67BE: - default: - smu_data->power_tune_defaults = &defaults_bonaire_xt; - break; - } -} - -static int ci_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, - struct phm_clock_voltage_dependency_table *allowed_clock_voltage_table, - uint32_t clock, uint32_t *vol) -{ - uint32_t i = 0; - - if (allowed_clock_voltage_table->count == 0) - return -EINVAL; - - for (i = 0; i < allowed_clock_voltage_table->count; i++) { - if (allowed_clock_voltage_table->entries[i].clk >= clock) { - *vol = allowed_clock_voltage_table->entries[i].v; - return 0; - } - } - - *vol = allowed_clock_voltage_table->entries[i - 1].v; - return 0; -} - -static int ci_calculate_sclk_params(struct pp_hwmgr *hwmgr, - uint32_t clock, struct SMU7_Discrete_GraphicsLevel *sclk) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct pp_atomctrl_clock_dividers_vi dividers; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - uint32_t ref_clock; - uint32_t ref_divider; - uint32_t fbdiv; - int result; - - /* get the engine clock dividers for this clock value */ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, clock, ÷rs); - - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", - return result); - - /* To get FBDIV we need to multiply this by 16384 and divide it by Fref. */ - ref_clock = atomctrl_get_reference_clock(hwmgr); - ref_divider = 1 + dividers.uc_pll_ref_div; - - /* low 14 bits is fraction and high 12 bits is divider */ - fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; - - /* SPLL_FUNC_CNTL setup */ - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_REF_DIV, dividers.uc_pll_ref_div); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_PDIV_A, dividers.uc_pll_post_div); - - /* SPLL_FUNC_CNTL_3 setup*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, - SPLL_FB_DIV, fbdiv); - - /* set to use fractional accumulation*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, - SPLL_DITHEN, 1); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { - struct pp_atomctrl_internal_ss_info ss_info; - uint32_t vco_freq = clock * dividers.uc_pll_post_div; - - if (!atomctrl_get_engine_clock_spread_spectrum(hwmgr, - vco_freq, &ss_info)) { - uint32_t clk_s = ref_clock * 5 / - (ref_divider * ss_info.speed_spectrum_rate); - uint32_t clk_v = 4 * ss_info.speed_spectrum_percentage * - fbdiv / (clk_s * 10000); - - cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, - CG_SPLL_SPREAD_SPECTRUM, CLKS, clk_s); - cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, - CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); - cg_spll_spread_spectrum_2 = PHM_SET_FIELD(cg_spll_spread_spectrum_2, - CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clk_v); - } - } - - sclk->SclkFrequency = clock; - sclk->CgSpllFuncCntl3 = spll_func_cntl_3; - sclk->CgSpllFuncCntl4 = spll_func_cntl_4; - sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; - sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; - sclk->SclkDid = (uint8_t)dividers.pll_post_divider; - - return 0; -} - -static void ci_populate_phase_value_based_on_sclk(struct pp_hwmgr *hwmgr, - const struct phm_phase_shedding_limits_table *pl, - uint32_t sclk, uint32_t *p_shed) -{ - unsigned int i; - - /* use the minimum phase shedding */ - *p_shed = 1; - - for (i = 0; i < pl->count; i++) { - if (sclk < pl->entries[i].Sclk) { - *p_shed = i; - break; - } - } -} - -static uint8_t ci_get_sleep_divider_id_from_clock(uint32_t clock, - uint32_t clock_insr) -{ - uint8_t i; - uint32_t temp; - uint32_t min = min_t(uint32_t, clock_insr, CISLAND_MINIMUM_ENGINE_CLOCK); - - if (clock < min) { - pr_info("Engine clock can't satisfy stutter requirement!\n"); - return 0; - } - for (i = CISLAND_MAX_DEEPSLEEP_DIVIDER_ID; ; i--) { - temp = clock >> i; - - if (temp >= min || i == 0) - break; - } - return i; -} - -static int ci_populate_single_graphic_level(struct pp_hwmgr *hwmgr, - uint32_t clock, uint16_t sclk_al_threshold, - struct SMU7_Discrete_GraphicsLevel *level) -{ - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - - result = ci_calculate_sclk_params(hwmgr, clock, level); - - /* populate graphics levels */ - result = ci_get_dependency_volt_by_clk(hwmgr, - hwmgr->dyn_state.vddc_dependency_on_sclk, clock, - (uint32_t *)(&level->MinVddc)); - if (result) { - pr_err("vdd_dep_on_sclk table is NULL\n"); - return result; - } - - level->SclkFrequency = clock; - level->MinVddcPhases = 1; - - if (data->vddc_phase_shed_control) - ci_populate_phase_value_based_on_sclk(hwmgr, - hwmgr->dyn_state.vddc_phase_shed_limits_table, - clock, - &level->MinVddcPhases); - - level->ActivityLevel = sclk_al_threshold; - level->CcPwrDynRm = 0; - level->CcPwrDynRm1 = 0; - level->EnabledForActivity = 0; - /* this level can be used for throttling.*/ - level->EnabledForThrottle = 1; - level->UpH = 0; - level->DownH = 0; - level->VoltageDownH = 0; - level->PowerThrottle = 0; - - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkDeepSleep)) - level->DeepSleepDivId = - ci_get_sleep_divider_id_from_clock(clock, - CISLAND_MINIMUM_ENGINE_CLOCK); - - /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ - level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - if (0 == result) { - level->MinVddc = PP_HOST_TO_SMC_UL(level->MinVddc * VOLTAGE_SCALE); - CONVERT_FROM_HOST_TO_SMC_UL(level->MinVddcPhases); - CONVERT_FROM_HOST_TO_SMC_UL(level->SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1); - } - - return result; -} - -static int ci_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - int result = 0; - uint32_t array = smu_data->dpm_table_start + - offsetof(SMU7_Discrete_DpmTable, GraphicsLevel); - uint32_t array_size = sizeof(struct SMU7_Discrete_GraphicsLevel) * - SMU7_MAX_LEVELS_GRAPHICS; - struct SMU7_Discrete_GraphicsLevel *levels = - smu_data->smc_state_table.GraphicsLevel; - uint32_t i; - - for (i = 0; i < dpm_table->sclk_table.count; i++) { - result = ci_populate_single_graphic_level(hwmgr, - dpm_table->sclk_table.dpm_levels[i].value, - (uint16_t)smu_data->activity_target[i], - &levels[i]); - if (result) - return result; - if (i > 1) - smu_data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0; - if (i == (dpm_table->sclk_table.count - 1)) - smu_data->smc_state_table.GraphicsLevel[i].DisplayWatermark = - PPSMC_DISPLAY_WATERMARK_HIGH; - } - - smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; - - smu_data->smc_state_table.GraphicsDpmLevelCount = (u8)dpm_table->sclk_table.count; - data->dpm_level_enable_mask.sclk_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); - - result = ci_copy_bytes_to_smc(hwmgr, array, - (u8 *)levels, array_size, - SMC_RAM_END); - - return result; - -} - -static int ci_populate_svi_load_line(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; - - smu_data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; - smu_data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddc; - smu_data->power_tune_table.SviLoadLineTrimVddC = 3; - smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; - - return 0; -} - -static int ci_populate_tdc_limit(struct pp_hwmgr *hwmgr) -{ - uint16_t tdc_limit; - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; - - tdc_limit = (uint16_t)(hwmgr->dyn_state.cac_dtp_table->usTDC * 256); - smu_data->power_tune_table.TDC_VDDC_PkgLimit = - CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); - smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = - defaults->tdc_vddc_throttle_release_limit_perc; - smu_data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; - - return 0; -} - -static int ci_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; - uint32_t temp; - - if (ci_read_smc_sram_dword(hwmgr, - fuse_table_offset + - offsetof(SMU7_Discrete_PmFuses, TdcWaterfallCtl), - (uint32_t *)&temp, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", - return -EINVAL); - else - smu_data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; - - return 0; -} - -static int ci_populate_fuzzy_fan(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) -{ - uint16_t tmp; - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - - if ((hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity & (1 << 15)) - || 0 == hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity) - tmp = hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity; - else - tmp = hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity; - - smu_data->power_tune_table.FuzzyFan_PwmSetDelta = CONVERT_FROM_HOST_TO_SMC_US(tmp); - - return 0; -} - -static int ci_populate_bapm_vddc_vid_sidd(struct pp_hwmgr *hwmgr) -{ - int i; - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - uint8_t *hi_vid = smu_data->power_tune_table.BapmVddCVidHiSidd; - uint8_t *lo_vid = smu_data->power_tune_table.BapmVddCVidLoSidd; - uint8_t *hi2_vid = smu_data->power_tune_table.BapmVddCVidHiSidd2; - - PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.cac_leakage_table, - "The CAC Leakage table does not exist!", return -EINVAL); - PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count <= 8, - "There should never be more than 8 entries for BapmVddcVid!!!", return -EINVAL); - PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count == hwmgr->dyn_state.vddc_dependency_on_sclk->count, - "CACLeakageTable->count and VddcDependencyOnSCLk->count not equal", return -EINVAL); - - for (i = 0; (uint32_t) i < hwmgr->dyn_state.cac_leakage_table->count; i++) { - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_EVV)) { - lo_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc1); - hi_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc2); - hi2_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc3); - } else { - lo_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc); - hi_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Leakage); - } - } - - return 0; -} - -static int ci_populate_vddc_vid(struct pp_hwmgr *hwmgr) -{ - int i; - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - uint8_t *vid = smu_data->power_tune_table.VddCVid; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - PP_ASSERT_WITH_CODE(data->vddc_voltage_table.count <= 8, - "There should never be more than 8 entries for VddcVid!!!", - return -EINVAL); - - for (i = 0; i < (int)data->vddc_voltage_table.count; i++) - vid[i] = convert_to_vid(data->vddc_voltage_table.entries[i].value); - - return 0; -} - -static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - u8 *hi_vid = smu_data->power_tune_table.BapmVddCVidHiSidd; - u8 *lo_vid = smu_data->power_tune_table.BapmVddCVidLoSidd; - int i, min, max; - - min = max = hi_vid[0]; - for (i = 0; i < 8; i++) { - if (0 != hi_vid[i]) { - if (min > hi_vid[i]) - min = hi_vid[i]; - if (max < hi_vid[i]) - max = hi_vid[i]; - } - - if (0 != lo_vid[i]) { - if (min > lo_vid[i]) - min = lo_vid[i]; - if (max < lo_vid[i]) - max = lo_vid[i]; - } - } - - if ((min == 0) || (max == 0)) - return -EINVAL; - smu_data->power_tune_table.GnbLPMLMaxVid = (u8)max; - smu_data->power_tune_table.GnbLPMLMinVid = (u8)min; - - return 0; -} - -static int ci_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - uint16_t HiSidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; - uint16_t LoSidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; - struct phm_cac_tdp_table *cac_table = hwmgr->dyn_state.cac_dtp_table; - - HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); - LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); - - smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = - CONVERT_FROM_HOST_TO_SMC_US(HiSidd); - smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = - CONVERT_FROM_HOST_TO_SMC_US(LoSidd); - - return 0; -} - -static int ci_populate_pm_fuses(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - uint32_t pm_fuse_table_offset; - int ret = 0; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment)) { - if (ci_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU7_Firmware_Header, PmFuseTable), - &pm_fuse_table_offset, SMC_RAM_END)) { - pr_err("Attempt to get pm_fuse_table_offset Failed!\n"); - return -EINVAL; - } - - /* DW0 - DW3 */ - ret = ci_populate_bapm_vddc_vid_sidd(hwmgr); - /* DW4 - DW5 */ - ret |= ci_populate_vddc_vid(hwmgr); - /* DW6 */ - ret |= ci_populate_svi_load_line(hwmgr); - /* DW7 */ - ret |= ci_populate_tdc_limit(hwmgr); - /* DW8 */ - ret |= ci_populate_dw8(hwmgr, pm_fuse_table_offset); - - ret |= ci_populate_fuzzy_fan(hwmgr, pm_fuse_table_offset); - - ret |= ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(hwmgr); - - ret |= ci_populate_bapm_vddc_base_leakage_sidd(hwmgr); - if (ret) - return ret; - - ret = ci_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, - (uint8_t *)&smu_data->power_tune_table, - sizeof(struct SMU7_Discrete_PmFuses), SMC_RAM_END); - } - return ret; -} - -static int ci_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; - SMU7_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); - struct phm_cac_tdp_table *cac_dtp_table = hwmgr->dyn_state.cac_dtp_table; - struct phm_ppm_table *ppm = hwmgr->dyn_state.ppm_parameter_table; - const uint16_t *def1, *def2; - int i, j, k; - - dpm_table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 256)); - dpm_table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); - - dpm_table->DTETjOffset = 0; - dpm_table->GpuTjMax = (uint8_t)(data->thermal_temp_setting.temperature_high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES); - dpm_table->GpuTjHyst = 8; - - dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; - - if (ppm) { - dpm_table->PPM_PkgPwrLimit = (uint16_t)ppm->dgpu_tdp * 256 / 1000; - dpm_table->PPM_TemperatureLimit = (uint16_t)ppm->tj_max * 256; - } else { - dpm_table->PPM_PkgPwrLimit = 0; - dpm_table->PPM_TemperatureLimit = 0; - } - - CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_PkgPwrLimit); - CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_TemperatureLimit); - - dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bapm_temp_gradient); - def1 = defaults->bapmti_r; - def2 = defaults->bapmti_rc; - - for (i = 0; i < SMU7_DTE_ITERATIONS; i++) { - for (j = 0; j < SMU7_DTE_SOURCES; j++) { - for (k = 0; k < SMU7_DTE_SINKS; k++) { - dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*def1); - dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*def2); - def1++; - def2++; - } - } - } - - return 0; -} - -static int ci_get_std_voltage_value_sidd(struct pp_hwmgr *hwmgr, - pp_atomctrl_voltage_table_entry *tab, uint16_t *hi, - uint16_t *lo) -{ - uint16_t v_index; - bool vol_found = false; - *hi = tab->value * VOLTAGE_SCALE; - *lo = tab->value * VOLTAGE_SCALE; - - PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.vddc_dependency_on_sclk, - "The SCLK/VDDC Dependency Table does not exist.\n", - return -EINVAL); - - if (NULL == hwmgr->dyn_state.cac_leakage_table) { - pr_warn("CAC Leakage Table does not exist, using vddc.\n"); - return 0; - } - - for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { - if (tab->value == hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { - vol_found = true; - if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { - *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage * VOLTAGE_SCALE); - } else { - pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index, using maximum index from CAC table.\n"); - *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); - } - break; - } - } - - if (!vol_found) { - for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { - if (tab->value <= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { - vol_found = true; - if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { - *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage) * VOLTAGE_SCALE; - } else { - pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index in second look up, using maximum index from CAC table."); - *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); - } - break; - } - } - - if (!vol_found) - pr_warn("Unable to get std_vddc from SCLK/VDDC Dependency Table, using vddc.\n"); - } - - return 0; -} - -static int ci_populate_smc_voltage_table(struct pp_hwmgr *hwmgr, - pp_atomctrl_voltage_table_entry *tab, - SMU7_Discrete_VoltageLevel *smc_voltage_tab) -{ - int result; - - result = ci_get_std_voltage_value_sidd(hwmgr, tab, - &smc_voltage_tab->StdVoltageHiSidd, - &smc_voltage_tab->StdVoltageLoSidd); - if (result) { - smc_voltage_tab->StdVoltageHiSidd = tab->value * VOLTAGE_SCALE; - smc_voltage_tab->StdVoltageLoSidd = tab->value * VOLTAGE_SCALE; - } - - smc_voltage_tab->Voltage = PP_HOST_TO_SMC_US(tab->value * VOLTAGE_SCALE); - CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd); - CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageLoSidd); - - return 0; -} - -static int ci_populate_smc_vddc_table(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - unsigned int count; - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - table->VddcLevelCount = data->vddc_voltage_table.count; - for (count = 0; count < table->VddcLevelCount; count++) { - result = ci_populate_smc_voltage_table(hwmgr, - &(data->vddc_voltage_table.entries[count]), - &(table->VddcLevel[count])); - PP_ASSERT_WITH_CODE(0 == result, "do not populate SMC VDDC voltage table", return -EINVAL); - - /* GPIO voltage control */ - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->voltage_control) - table->VddcLevel[count].Smio |= data->vddc_voltage_table.entries[count].smio_low; - else - table->VddcLevel[count].Smio = 0; - } - - CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount); - - return 0; -} - -static int ci_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t count; - int result; - - table->VddciLevelCount = data->vddci_voltage_table.count; - - for (count = 0; count < table->VddciLevelCount; count++) { - result = ci_populate_smc_voltage_table(hwmgr, - &(data->vddci_voltage_table.entries[count]), - &(table->VddciLevel[count])); - PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC VDDCI voltage table", return -EINVAL); - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) - table->VddciLevel[count].Smio |= data->vddci_voltage_table.entries[count].smio_low; - else - table->VddciLevel[count].Smio |= 0; - } - - CONVERT_FROM_HOST_TO_SMC_UL(table->VddciLevelCount); - - return 0; -} - -static int ci_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t count; - int result; - - table->MvddLevelCount = data->mvdd_voltage_table.count; - - for (count = 0; count < table->MvddLevelCount; count++) { - result = ci_populate_smc_voltage_table(hwmgr, - &(data->mvdd_voltage_table.entries[count]), - &table->MvddLevel[count]); - PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC mvdd voltage table", return -EINVAL); - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) - table->MvddLevel[count].Smio |= data->mvdd_voltage_table.entries[count].smio_low; - else - table->MvddLevel[count].Smio |= 0; - } - - CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount); - - return 0; -} - - -static int ci_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - int result; - - result = ci_populate_smc_vddc_table(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "can not populate VDDC voltage table to SMC", return -EINVAL); - - result = ci_populate_smc_vdd_ci_table(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "can not populate VDDCI voltage table to SMC", return -EINVAL); - - result = ci_populate_smc_mvdd_table(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "can not populate MVDD voltage table to SMC", return -EINVAL); - - return 0; -} - -static int ci_populate_ulv_level(struct pp_hwmgr *hwmgr, - struct SMU7_Discrete_Ulv *state) -{ - uint32_t voltage_response_time, ulv_voltage; - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - state->CcPwrDynRm = 0; - state->CcPwrDynRm1 = 0; - - result = pp_tables_get_response_times(hwmgr, &voltage_response_time, &ulv_voltage); - PP_ASSERT_WITH_CODE((0 == result), "can not get ULV voltage value", return result;); - - if (ulv_voltage == 0) { - data->ulv_supported = false; - return 0; - } - - if (data->voltage_control != SMU7_VOLTAGE_CONTROL_BY_SVID2) { - /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ - if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) - state->VddcOffset = 0; - else - /* used in SMIO Mode. not implemented for now. this is backup only for CI. */ - state->VddcOffset = (uint16_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage); - } else { - /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ - if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) - state->VddcOffsetVid = 0; - else /* used in SVI2 Mode */ - state->VddcOffsetVid = (uint8_t)( - (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage) - * VOLTAGE_VID_OFFSET_SCALE2 - / VOLTAGE_VID_OFFSET_SCALE1); - } - state->VddcPhase = 1; - - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); - CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); - - return 0; -} - -static int ci_populate_ulv_state(struct pp_hwmgr *hwmgr, - SMU7_Discrete_Ulv *ulv_level) -{ - return ci_populate_ulv_level(hwmgr, ulv_level); -} - -static int ci_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU7_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - uint32_t i; - -/* Index dpm_table->pcie_speed_table.count is reserved for PCIE boot level.*/ - for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { - table->LinkLevel[i].PcieGenSpeed = - (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; - table->LinkLevel[i].PcieLaneCount = - (uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1); - table->LinkLevel[i].EnabledForActivity = 1; - table->LinkLevel[i].DownT = PP_HOST_TO_SMC_UL(5); - table->LinkLevel[i].UpT = PP_HOST_TO_SMC_UL(30); - } - - smu_data->smc_state_table.LinkLevelCount = - (uint8_t)dpm_table->pcie_speed_table.count; - data->dpm_level_enable_mask.pcie_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); - - return 0; -} - -static int ci_calculate_mclk_params( - struct pp_hwmgr *hwmgr, - uint32_t memory_clock, - SMU7_Discrete_MemoryLevel *mclk, - bool strobe_mode, - bool dllStateOn - ) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; - uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; - uint32_t mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL; - uint32_t mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL; - uint32_t mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL; - uint32_t mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1; - uint32_t mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2; - uint32_t mpll_ss1 = data->clock_registers.vMPLL_SS1; - uint32_t mpll_ss2 = data->clock_registers.vMPLL_SS2; - - pp_atomctrl_memory_clock_param mpll_param; - int result; - - result = atomctrl_get_memory_pll_dividers_si(hwmgr, - memory_clock, &mpll_param, strobe_mode); - PP_ASSERT_WITH_CODE(0 == result, - "Error retrieving Memory Clock Parameters from VBIOS.", return result); - - mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl); - - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, CLKF, mpll_param.mpll_fb_divider.cl_kf); - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, CLKFRAC, mpll_param.mpll_fb_divider.clk_frac); - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, VCO_MODE, mpll_param.vco_mode); - - mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl, - MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); - - if (data->is_memory_gddr5) { - mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, - MPLL_DQ_FUNC_CNTL, YCLK_SEL, mpll_param.yclk_sel); - mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, - MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); - } - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MemorySpreadSpectrumSupport)) { - pp_atomctrl_internal_ss_info ss_info; - uint32_t freq_nom; - uint32_t tmp; - uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr); - - /* for GDDR5 for all modes and DDR3 */ - if (1 == mpll_param.qdr) - freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider); - else - freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider); - - /* tmp = (freq_nom / reference_clock * reference_divider) ^ 2 Note: S.I. reference_divider = 1*/ - tmp = (freq_nom / reference_clock); - tmp = tmp * tmp; - - if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) { - uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate; - uint32_t clkv = - (uint32_t)((((131 * ss_info.speed_spectrum_percentage * - ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom); - - mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv); - mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks); - } - } - - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn); - - - mclk->MclkFrequency = memory_clock; - mclk->MpllFuncCntl = mpll_func_cntl; - mclk->MpllFuncCntl_1 = mpll_func_cntl_1; - mclk->MpllFuncCntl_2 = mpll_func_cntl_2; - mclk->MpllAdFuncCntl = mpll_ad_func_cntl; - mclk->MpllDqFuncCntl = mpll_dq_func_cntl; - mclk->MclkPwrmgtCntl = mclk_pwrmgt_cntl; - mclk->DllCntl = dll_cntl; - mclk->MpllSs1 = mpll_ss1; - mclk->MpllSs2 = mpll_ss2; - - return 0; -} - -static uint8_t ci_get_mclk_frequency_ratio(uint32_t memory_clock, - bool strobe_mode) -{ - uint8_t mc_para_index; - - if (strobe_mode) { - if (memory_clock < 12500) - mc_para_index = 0x00; - else if (memory_clock > 47500) - mc_para_index = 0x0f; - else - mc_para_index = (uint8_t)((memory_clock - 10000) / 2500); - } else { - if (memory_clock < 65000) - mc_para_index = 0x00; - else if (memory_clock > 135000) - mc_para_index = 0x0f; - else - mc_para_index = (uint8_t)((memory_clock - 60000) / 5000); - } - - return mc_para_index; -} - -static uint8_t ci_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock) -{ - uint8_t mc_para_index; - - if (memory_clock < 10000) - mc_para_index = 0; - else if (memory_clock >= 80000) - mc_para_index = 0x0f; - else - mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1); - - return mc_para_index; -} - -static int ci_populate_phase_value_based_on_mclk(struct pp_hwmgr *hwmgr, const struct phm_phase_shedding_limits_table *pl, - uint32_t memory_clock, uint32_t *p_shed) -{ - unsigned int i; - - *p_shed = 1; - - for (i = 0; i < pl->count; i++) { - if (memory_clock < pl->entries[i].Mclk) { - *p_shed = i; - break; - } - } - - return 0; -} - -static int ci_populate_single_memory_level( - struct pp_hwmgr *hwmgr, - uint32_t memory_clock, - SMU7_Discrete_MemoryLevel *memory_level - ) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - int result = 0; - bool dll_state_on; - struct cgs_display_info info = {0}; - uint32_t mclk_edc_wr_enable_threshold = 40000; - uint32_t mclk_edc_enable_threshold = 40000; - uint32_t mclk_strobe_mode_threshold = 40000; - - if (hwmgr->dyn_state.vddc_dependency_on_mclk != NULL) { - result = ci_get_dependency_volt_by_clk(hwmgr, - hwmgr->dyn_state.vddc_dependency_on_mclk, memory_clock, &memory_level->MinVddc); - PP_ASSERT_WITH_CODE((0 == result), - "can not find MinVddc voltage value from memory VDDC voltage dependency table", return result); - } - - if (NULL != hwmgr->dyn_state.vddci_dependency_on_mclk) { - result = ci_get_dependency_volt_by_clk(hwmgr, - hwmgr->dyn_state.vddci_dependency_on_mclk, - memory_clock, - &memory_level->MinVddci); - PP_ASSERT_WITH_CODE((0 == result), - "can not find MinVddci voltage value from memory VDDCI voltage dependency table", return result); - } - - if (NULL != hwmgr->dyn_state.mvdd_dependency_on_mclk) { - result = ci_get_dependency_volt_by_clk(hwmgr, - hwmgr->dyn_state.mvdd_dependency_on_mclk, - memory_clock, - &memory_level->MinMvdd); - PP_ASSERT_WITH_CODE((0 == result), - "can not find MinVddci voltage value from memory MVDD voltage dependency table", return result); - } - - memory_level->MinVddcPhases = 1; - - if (data->vddc_phase_shed_control) { - ci_populate_phase_value_based_on_mclk(hwmgr, hwmgr->dyn_state.vddc_phase_shed_limits_table, - memory_clock, &memory_level->MinVddcPhases); - } - - memory_level->EnabledForThrottle = 1; - memory_level->EnabledForActivity = 1; - memory_level->UpH = 0; - memory_level->DownH = 100; - memory_level->VoltageDownH = 0; - - /* Indicates maximum activity level for this performance level.*/ - memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target; - memory_level->StutterEnable = 0; - memory_level->StrobeEnable = 0; - memory_level->EdcReadEnable = 0; - memory_level->EdcWriteEnable = 0; - memory_level->RttEnable = 0; - - /* default set to low watermark. Highest level will be set to high later.*/ - memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - cgs_get_active_displays_info(hwmgr->device, &info); - data->display_timing.num_existing_displays = info.display_count; - - /* stutter mode not support on ci */ - - /* decide strobe mode*/ - memory_level->StrobeEnable = (mclk_strobe_mode_threshold != 0) && - (memory_clock <= mclk_strobe_mode_threshold); - - /* decide EDC mode and memory clock ratio*/ - if (data->is_memory_gddr5) { - memory_level->StrobeRatio = ci_get_mclk_frequency_ratio(memory_clock, - memory_level->StrobeEnable); - - if ((mclk_edc_enable_threshold != 0) && - (memory_clock > mclk_edc_enable_threshold)) { - memory_level->EdcReadEnable = 1; - } - - if ((mclk_edc_wr_enable_threshold != 0) && - (memory_clock > mclk_edc_wr_enable_threshold)) { - memory_level->EdcWriteEnable = 1; - } - - if (memory_level->StrobeEnable) { - if (ci_get_mclk_frequency_ratio(memory_clock, 1) >= - ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; - else - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0; - } else - dll_state_on = data->dll_default_on; - } else { - memory_level->StrobeRatio = - ci_get_ddr3_mclk_frequency_ratio(memory_clock); - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; - } - - result = ci_calculate_mclk_params(hwmgr, - memory_clock, memory_level, memory_level->StrobeEnable, dll_state_on); - - if (0 == result) { - memory_level->MinVddc = PP_HOST_TO_SMC_UL(memory_level->MinVddc * VOLTAGE_SCALE); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinVddcPhases); - memory_level->MinVddci = PP_HOST_TO_SMC_UL(memory_level->MinVddci * VOLTAGE_SCALE); - memory_level->MinMvdd = PP_HOST_TO_SMC_UL(memory_level->MinMvdd * VOLTAGE_SCALE); - /* MCLK frequency in units of 10KHz*/ - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency); - /* Indicates maximum activity level for this performance level.*/ - CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2); - } - - return result; -} - -static int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - int result; - struct cgs_system_info sys_info = {0}; - uint32_t dev_id; - - uint32_t level_array_address = smu_data->dpm_table_start + offsetof(SMU7_Discrete_DpmTable, MemoryLevel); - uint32_t level_array_size = sizeof(SMU7_Discrete_MemoryLevel) * SMU7_MAX_LEVELS_MEMORY; - SMU7_Discrete_MemoryLevel *levels = smu_data->smc_state_table.MemoryLevel; - uint32_t i; - - memset(levels, 0x00, level_array_size); - - for (i = 0; i < dpm_table->mclk_table.count; i++) { - PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), - "can not populate memory level as memory clock is zero", return -EINVAL); - result = ci_populate_single_memory_level(hwmgr, dpm_table->mclk_table.dpm_levels[i].value, - &(smu_data->smc_state_table.MemoryLevel[i])); - if (0 != result) - return result; - } - - smu_data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1; - - sys_info.size = sizeof(struct cgs_system_info); - sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; - cgs_query_system_info(hwmgr->device, &sys_info); - dev_id = (uint32_t)sys_info.value; - - if ((dpm_table->mclk_table.count >= 2) - && ((dev_id == 0x67B0) || (dev_id == 0x67B1))) { - smu_data->smc_state_table.MemoryLevel[1].MinVddci = - smu_data->smc_state_table.MemoryLevel[0].MinVddci; - smu_data->smc_state_table.MemoryLevel[1].MinMvdd = - smu_data->smc_state_table.MemoryLevel[0].MinMvdd; - } - smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F; - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel); - - smu_data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count; - data->dpm_level_enable_mask.mclk_dpm_enable_mask = phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); - smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; - - result = ci_copy_bytes_to_smc(hwmgr, - level_array_address, (uint8_t *)levels, (uint32_t)level_array_size, - SMC_RAM_END); - - return result; -} - -static int ci_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, - SMU7_Discrete_VoltageLevel *voltage) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - uint32_t i = 0; - - if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { - /* find mvdd value which clock is more than request */ - for (i = 0; i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count; i++) { - if (mclk <= hwmgr->dyn_state.mvdd_dependency_on_mclk->entries[i].clk) { - /* Always round to higher voltage. */ - voltage->Voltage = data->mvdd_voltage_table.entries[i].value; - break; - } - } - - PP_ASSERT_WITH_CODE(i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count, - "MVDD Voltage is outside the supported range.", return -EINVAL); - - } else { - return -EINVAL; - } - - return 0; -} - -static int ci_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - int result = 0; - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct pp_atomctrl_clock_dividers_vi dividers; - - SMU7_Discrete_VoltageLevel voltage_level; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; - uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; - uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; - - - /* The ACPI state should not do DPM on DC (or ever).*/ - table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; - - if (data->acpi_vddc) - table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->acpi_vddc * VOLTAGE_SCALE); - else - table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->min_vddc_in_pptable * VOLTAGE_SCALE); - - table->ACPILevel.MinVddcPhases = data->vddc_phase_shed_control ? 0 : 1; - /* assign zero for now*/ - table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr); - - /* get the engine clock dividers for this clock value*/ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, - table->ACPILevel.SclkFrequency, ÷rs); - - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", return result); - - /* divider ID for required SCLK*/ - table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; - table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - table->ACPILevel.DeepSleepDivId = 0; - - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_PWRON, 0); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_RESET, 1); - spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, - CG_SPLL_FUNC_CNTL_2, SCLK_MUX_SEL, 4); - - table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; - table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; - table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - table->ACPILevel.CcPwrDynRm = 0; - table->ACPILevel.CcPwrDynRm1 = 0; - - /* For various features to be enabled/disabled while this level is active.*/ - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); - /* SCLK frequency in units of 10KHz*/ - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); - - - /* table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;*/ - table->MemoryACPILevel.MinVddc = table->ACPILevel.MinVddc; - table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases; - - if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) - table->MemoryACPILevel.MinVddci = table->MemoryACPILevel.MinVddc; - else { - if (data->acpi_vddci != 0) - table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->acpi_vddci * VOLTAGE_SCALE); - else - table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->min_vddci_in_pptable * VOLTAGE_SCALE); - } - - if (0 == ci_populate_mvdd_value(hwmgr, 0, &voltage_level)) - table->MemoryACPILevel.MinMvdd = - PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE); - else - table->MemoryACPILevel.MinMvdd = 0; - - /* Force reset on DLL*/ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1); - - /* Disable DLL in ACPIState*/ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0); - - /* Enable DLL bypass signal*/ - dll_cntl = PHM_SET_FIELD(dll_cntl, - DLL_CNTL, MRDCK0_BYPASS, 0); - dll_cntl = PHM_SET_FIELD(dll_cntl, - DLL_CNTL, MRDCK1_BYPASS, 0); - - table->MemoryACPILevel.DllCntl = - PP_HOST_TO_SMC_UL(dll_cntl); - table->MemoryACPILevel.MclkPwrmgtCntl = - PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl); - table->MemoryACPILevel.MpllAdFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL); - table->MemoryACPILevel.MpllDqFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL); - table->MemoryACPILevel.MpllFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL); - table->MemoryACPILevel.MpllFuncCntl_1 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1); - table->MemoryACPILevel.MpllFuncCntl_2 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2); - table->MemoryACPILevel.MpllSs1 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1); - table->MemoryACPILevel.MpllSs2 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2); - - table->MemoryACPILevel.EnabledForThrottle = 0; - table->MemoryACPILevel.EnabledForActivity = 0; - table->MemoryACPILevel.UpH = 0; - table->MemoryACPILevel.DownH = 100; - table->MemoryACPILevel.VoltageDownH = 0; - /* Indicates maximum activity level for this performance level.*/ - table->MemoryACPILevel.ActivityLevel = PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); - - table->MemoryACPILevel.StutterEnable = 0; - table->MemoryACPILevel.StrobeEnable = 0; - table->MemoryACPILevel.EdcReadEnable = 0; - table->MemoryACPILevel.EdcWriteEnable = 0; - table->MemoryACPILevel.RttEnable = 0; - - return result; -} - -static int ci_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - int result = 0; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_uvd_clock_voltage_dependency_table *uvd_table = - hwmgr->dyn_state.uvd_clock_voltage_dependency_table; - - table->UvdLevelCount = (uint8_t)(uvd_table->count); - - for (count = 0; count < table->UvdLevelCount; count++) { - table->UvdLevel[count].VclkFrequency = - uvd_table->entries[count].vclk; - table->UvdLevel[count].DclkFrequency = - uvd_table->entries[count].dclk; - table->UvdLevel[count].MinVddc = - uvd_table->entries[count].v * VOLTAGE_SCALE; - table->UvdLevel[count].MinVddcPhases = 1; - - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->UvdLevel[count].VclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for Vclk clock", return result); - - table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; - - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->UvdLevel[count].DclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for Dclk clock", return result); - - table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider; - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(table->UvdLevel[count].MinVddc); - } - - return result; -} - -static int ci_populate_smc_vce_level(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_vce_clock_voltage_dependency_table *vce_table = - hwmgr->dyn_state.vce_clock_voltage_dependency_table; - - table->VceLevelCount = (uint8_t)(vce_table->count); - table->VceBootLevel = 0; - - for (count = 0; count < table->VceLevelCount; count++) { - table->VceLevel[count].Frequency = vce_table->entries[count].evclk; - table->VceLevel[count].MinVoltage = - vce_table->entries[count].v * VOLTAGE_SCALE; - table->VceLevel[count].MinPhases = 1; - - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->VceLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for VCE engine clock", - return result); - - table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_US(table->VceLevel[count].MinVoltage); - } - return result; -} - -static int ci_populate_smc_acp_level(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_acp_clock_voltage_dependency_table *acp_table = - hwmgr->dyn_state.acp_clock_voltage_dependency_table; - - table->AcpLevelCount = (uint8_t)(acp_table->count); - table->AcpBootLevel = 0; - - for (count = 0; count < table->AcpLevelCount; count++) { - table->AcpLevel[count].Frequency = acp_table->entries[count].acpclk; - table->AcpLevel[count].MinVoltage = acp_table->entries[count].v; - table->AcpLevel[count].MinPhases = 1; - - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->AcpLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for engine clock", return result); - - table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_US(table->AcpLevel[count].MinVoltage); - } - return result; -} - -static int ci_populate_smc_samu_level(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_samu_clock_voltage_dependency_table *samu_table = - hwmgr->dyn_state.samu_clock_voltage_dependency_table; - - table->SamuBootLevel = 0; - table->SamuLevelCount = (uint8_t)(samu_table->count); - - for (count = 0; count < table->SamuLevelCount; count++) { - table->SamuLevel[count].Frequency = samu_table->entries[count].samclk; - table->SamuLevel[count].MinVoltage = samu_table->entries[count].v * VOLTAGE_SCALE; - table->SamuLevel[count].MinPhases = 1; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->SamuLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for samu clock", return result); - - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_US(table->SamuLevel[count].MinVoltage); - } - return result; -} - -static int ci_populate_memory_timing_parameters( - struct pp_hwmgr *hwmgr, - uint32_t engine_clock, - uint32_t memory_clock, - struct SMU7_Discrete_MCArbDramTimingTableEntry *arb_regs - ) -{ - uint32_t dramTiming; - uint32_t dramTiming2; - uint32_t burstTime; - int result; - - result = atomctrl_set_engine_dram_timings_rv770(hwmgr, - engine_clock, memory_clock); - - PP_ASSERT_WITH_CODE(result == 0, - "Error calling VBIOS to set DRAM_TIMING.", return result); - - dramTiming = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); - dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); - burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); - - arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dramTiming); - arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2); - arb_regs->McArbBurstTime = (uint8_t)burstTime; - - return 0; -} - -static int ci_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - int result = 0; - SMU7_Discrete_MCArbDramTimingTable arb_regs; - uint32_t i, j; - - memset(&arb_regs, 0x00, sizeof(SMU7_Discrete_MCArbDramTimingTable)); - - for (i = 0; i < data->dpm_table.sclk_table.count; i++) { - for (j = 0; j < data->dpm_table.mclk_table.count; j++) { - result = ci_populate_memory_timing_parameters - (hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value, - data->dpm_table.mclk_table.dpm_levels[j].value, - &arb_regs.entries[i][j]); - - if (0 != result) - break; - } - } - - if (0 == result) { - result = ci_copy_bytes_to_smc( - hwmgr, - smu_data->arb_table_start, - (uint8_t *)&arb_regs, - sizeof(SMU7_Discrete_MCArbDramTimingTable), - SMC_RAM_END - ); - } - - return result; -} - -static int ci_populate_smc_boot_level(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - - table->GraphicsBootLevel = 0; - table->MemoryBootLevel = 0; - - /* find boot level from dpm table*/ - result = phm_find_boot_level(&(data->dpm_table.sclk_table), - data->vbios_boot_state.sclk_bootup_value, - (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); - - if (0 != result) { - smu_data->smc_state_table.GraphicsBootLevel = 0; - pr_err("VBIOS did not find boot engine clock value \ - in dependency table. Using Graphics DPM level 0!"); - result = 0; - } - - result = phm_find_boot_level(&(data->dpm_table.mclk_table), - data->vbios_boot_state.mclk_bootup_value, - (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); - - if (0 != result) { - smu_data->smc_state_table.MemoryBootLevel = 0; - pr_err("VBIOS did not find boot engine clock value \ - in dependency table. Using Memory DPM level 0!"); - result = 0; - } - - table->BootVddc = data->vbios_boot_state.vddc_bootup_value; - table->BootVddci = data->vbios_boot_state.vddci_bootup_value; - table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value; - - return result; -} - -static int ci_populate_mc_reg_address(struct pp_hwmgr *hwmgr, - SMU7_Discrete_MCRegisters *mc_reg_table) -{ - const struct ci_smumgr *smu_data = (struct ci_smumgr *)hwmgr->smu_backend; - - uint32_t i, j; - - for (i = 0, j = 0; j < smu_data->mc_reg_table.last; j++) { - if (smu_data->mc_reg_table.validflag & 1<address[] array out of boundary", return -EINVAL); - mc_reg_table->address[i].s0 = - PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s0); - mc_reg_table->address[i].s1 = - PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s1); - i++; - } - } - - mc_reg_table->last = (uint8_t)i; - - return 0; -} - -static void ci_convert_mc_registers( - const struct ci_mc_reg_entry *entry, - SMU7_Discrete_MCRegisterSet *data, - uint32_t num_entries, uint32_t valid_flag) -{ - uint32_t i, j; - - for (i = 0, j = 0; j < num_entries; j++) { - if (valid_flag & 1<value[i] = PP_HOST_TO_SMC_UL(entry->mc_data[j]); - i++; - } - } -} - -static int ci_convert_mc_reg_table_entry_to_smc( - struct pp_hwmgr *hwmgr, - const uint32_t memory_clock, - SMU7_Discrete_MCRegisterSet *mc_reg_table_data - ) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - uint32_t i = 0; - - for (i = 0; i < smu_data->mc_reg_table.num_entries; i++) { - if (memory_clock <= - smu_data->mc_reg_table.mc_reg_table_entry[i].mclk_max) { - break; - } - } - - if ((i == smu_data->mc_reg_table.num_entries) && (i > 0)) - --i; - - ci_convert_mc_registers(&smu_data->mc_reg_table.mc_reg_table_entry[i], - mc_reg_table_data, smu_data->mc_reg_table.last, - smu_data->mc_reg_table.validflag); - - return 0; -} - -static int ci_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr, - SMU7_Discrete_MCRegisters *mc_regs) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - int res; - uint32_t i; - - for (i = 0; i < data->dpm_table.mclk_table.count; i++) { - res = ci_convert_mc_reg_table_entry_to_smc( - hwmgr, - data->dpm_table.mclk_table.dpm_levels[i].value, - &mc_regs->data[i] - ); - - if (0 != res) - result = res; - } - - return result; -} - -static int ci_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t address; - int32_t result; - - if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) - return 0; - - - memset(&smu_data->mc_regs, 0, sizeof(SMU7_Discrete_MCRegisters)); - - result = ci_convert_mc_reg_table_to_smc(hwmgr, &(smu_data->mc_regs)); - - if (result != 0) - return result; - - address = smu_data->mc_reg_table_start + (uint32_t)offsetof(SMU7_Discrete_MCRegisters, data[0]); - - return ci_copy_bytes_to_smc(hwmgr, address, - (uint8_t *)&smu_data->mc_regs.data[0], - sizeof(SMU7_Discrete_MCRegisterSet) * data->dpm_table.mclk_table.count, - SMC_RAM_END); -} - -static int ci_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - - memset(&smu_data->mc_regs, 0x00, sizeof(SMU7_Discrete_MCRegisters)); - result = ci_populate_mc_reg_address(hwmgr, &(smu_data->mc_regs)); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize MCRegTable for the MC register addresses!", return result;); - - result = ci_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize MCRegTable for driver state!", return result;); - - return ci_copy_bytes_to_smc(hwmgr, smu_data->mc_reg_table_start, - (uint8_t *)&smu_data->mc_regs, sizeof(SMU7_Discrete_MCRegisters), SMC_RAM_END); -} - -static int ci_populate_smc_initial_state(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - uint8_t count, level; - - count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->count); - - for (level = 0; level < count; level++) { - if (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[level].clk - >= data->vbios_boot_state.sclk_bootup_value) { - smu_data->smc_state_table.GraphicsBootLevel = level; - break; - } - } - - count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_mclk->count); - - for (level = 0; level < count; level++) { - if (hwmgr->dyn_state.vddc_dependency_on_mclk->entries[level].clk - >= data->vbios_boot_state.mclk_bootup_value) { - smu_data->smc_state_table.MemoryBootLevel = level; - break; - } - } - - return 0; -} - -static int ci_populate_smc_svi2_config(struct pp_hwmgr *hwmgr, - SMU7_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) - table->SVI2Enable = 1; - else - table->SVI2Enable = 0; - return 0; -} - -static int ci_start_smc(struct pp_hwmgr *hwmgr) -{ - /* set smc instruct start point at 0x0 */ - ci_program_jump_on_start(hwmgr); - - /* enable smc clock */ - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); - - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 0); - - PHM_WAIT_INDIRECT_FIELD(hwmgr, SMC_IND, FIRMWARE_FLAGS, - INTERRUPTS_ENABLED, 1); - - return 0; -} - -static int ci_init_smc_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - SMU7_Discrete_DpmTable *table = &(smu_data->smc_state_table); - struct pp_atomctrl_gpio_pin_assignment gpio_pin; - u32 i; - - ci_initialize_power_tune_defaults(hwmgr); - memset(&(smu_data->smc_state_table), 0x00, sizeof(smu_data->smc_state_table)); - - if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) - ci_populate_smc_voltage_tables(hwmgr, table); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; - - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StepVddc)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; - - if (data->is_memory_gddr5) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; - - if (data->ulv_supported) { - result = ci_populate_ulv_state(hwmgr, &(table->Ulv)); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ULV state!", return result); - - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixCG_ULV_PARAMETER, 0x40035); - } - - result = ci_populate_all_graphic_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Graphics Level!", return result); - - result = ci_populate_all_memory_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Memory Level!", return result); - - result = ci_populate_smc_link_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Link Level!", return result); - - result = ci_populate_smc_acpi_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ACPI Level!", return result); - - result = ci_populate_smc_vce_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize VCE Level!", return result); - - result = ci_populate_smc_acp_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ACP Level!", return result); - - result = ci_populate_smc_samu_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize SAMU Level!", return result); - - /* Since only the initial state is completely set up at this point (the other states are just copies of the boot state) we only */ - /* need to populate the ARB settings for the initial state. */ - result = ci_program_memory_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to Write ARB settings for the initial state.", return result); - - result = ci_populate_smc_uvd_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize UVD Level!", return result); - - table->UvdBootLevel = 0; - table->VceBootLevel = 0; - table->AcpBootLevel = 0; - table->SamuBootLevel = 0; - - table->GraphicsBootLevel = 0; - table->MemoryBootLevel = 0; - - result = ci_populate_smc_boot_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Boot Level!", return result); - - result = ci_populate_smc_initial_state(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, "Failed to initialize Boot State!", return result); - - result = ci_populate_bapm_parameters_in_dpm_table(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, "Failed to populate BAPM Parameters!", return result); - - table->UVDInterval = 1; - table->VCEInterval = 1; - table->ACPInterval = 1; - table->SAMUInterval = 1; - table->GraphicsVoltageChangeEnable = 1; - table->GraphicsThermThrottleEnable = 1; - table->GraphicsInterval = 1; - table->VoltageInterval = 1; - table->ThermalInterval = 1; - - table->TemperatureLimitHigh = - (data->thermal_temp_setting.temperature_high * - SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - table->TemperatureLimitLow = - (data->thermal_temp_setting.temperature_low * - SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - - table->MemoryVoltageChangeEnable = 1; - table->MemoryInterval = 1; - table->VoltageResponseTime = 0; - table->VddcVddciDelta = 4000; - table->PhaseResponseTime = 0; - table->MemoryThermThrottleEnable = 1; - - PP_ASSERT_WITH_CODE((1 <= data->dpm_table.pcie_speed_table.count), - "There must be 1 or more PCIE levels defined in PPTable.", - return -EINVAL); - - table->PCIeBootLinkLevel = (uint8_t)data->dpm_table.pcie_speed_table.count; - table->PCIeGenInterval = 1; - - ci_populate_smc_svi2_config(hwmgr, table); - - for (i = 0; i < SMU7_MAX_ENTRIES_SMIO; i++) - CONVERT_FROM_HOST_TO_SMC_UL(table->Smio[i]); - - table->ThermGpio = 17; - table->SclkStepSize = 0x4000; - if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) { - table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift; - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot); - } else { - table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot); - } - - table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; - - CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcVid); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcPhase); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddciVid); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskMvddVid); - CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); - table->VddcVddciDelta = PP_HOST_TO_SMC_US(table->VddcVddciDelta); - CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); - CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); - - table->BootVddc = PP_HOST_TO_SMC_US(table->BootVddc * VOLTAGE_SCALE); - table->BootVddci = PP_HOST_TO_SMC_US(table->BootVddci * VOLTAGE_SCALE); - table->BootMVdd = PP_HOST_TO_SMC_US(table->BootMVdd * VOLTAGE_SCALE); - - /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ - result = ci_copy_bytes_to_smc(hwmgr, smu_data->dpm_table_start + - offsetof(SMU7_Discrete_DpmTable, SystemFlags), - (uint8_t *)&(table->SystemFlags), - sizeof(SMU7_Discrete_DpmTable)-3 * sizeof(SMU7_PIDController), - SMC_RAM_END); - - PP_ASSERT_WITH_CODE(0 == result, - "Failed to upload dpm data to SMC memory!", return result;); - - result = ci_populate_initial_mc_reg_table(hwmgr); - PP_ASSERT_WITH_CODE((0 == result), - "Failed to populate initialize MC Reg table!", return result); - - result = ci_populate_pm_fuses(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate PM fuses to SMC memory!", return result); - - ci_start_smc(hwmgr); - - return 0; -} - -static int ci_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) -{ - struct ci_smumgr *ci_data = (struct ci_smumgr *)(hwmgr->smu_backend); - SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; - uint32_t duty100; - uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; - uint16_t fdo_min, slope1, slope2; - uint32_t reference_clock; - int res; - uint64_t tmp64; - - if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) - return 0; - - if (hwmgr->thermal_controller.fanInfo.bNoFan) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - if (0 == ci_data->fan_table_start) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100); - - if (0 == duty100) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100; - do_div(tmp64, 10000); - fdo_min = (uint16_t)tmp64; - - t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - hwmgr->thermal_controller.advanceFanControlParameters.usTMin; - t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - hwmgr->thermal_controller.advanceFanControlParameters.usTMed; - - pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; - pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; - - slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); - slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); - - fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100); - fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100); - fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100); - - fan_table.Slope1 = cpu_to_be16(slope1); - fan_table.Slope2 = cpu_to_be16(slope2); - - fan_table.FdoMin = cpu_to_be16(fdo_min); - - fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst); - - fan_table.HystUp = cpu_to_be16(1); - - fan_table.HystSlope = cpu_to_be16(1); - - fan_table.TempRespLim = cpu_to_be16(5); - - reference_clock = smu7_get_xclk(hwmgr); - - fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600); - - fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); - - fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL); - - res = ci_copy_bytes_to_smc(hwmgr, ci_data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), SMC_RAM_END); - - return 0; -} - -static int ci_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (data->need_update_smu7_dpm_table & - (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) - return ci_program_memory_timing_parameters(hwmgr); - - return 0; -} - -static int ci_update_sclk_threshold(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - - int result = 0; - uint32_t low_sclk_interrupt_threshold = 0; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkThrottleLowNotification) - && (hwmgr->gfx_arbiter.sclk_threshold != - data->low_sclk_interrupt_threshold)) { - data->low_sclk_interrupt_threshold = - hwmgr->gfx_arbiter.sclk_threshold; - low_sclk_interrupt_threshold = - data->low_sclk_interrupt_threshold; - - CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); - - result = ci_copy_bytes_to_smc( - hwmgr, - smu_data->dpm_table_start + - offsetof(SMU7_Discrete_DpmTable, - LowSclkInterruptT), - (uint8_t *)&low_sclk_interrupt_threshold, - sizeof(uint32_t), - SMC_RAM_END); - } - - result = ci_update_and_upload_mc_reg_table(hwmgr); - - PP_ASSERT_WITH_CODE((0 == result), "Failed to upload MC reg table!", return result); - - result = ci_program_mem_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE((result == 0), - "Failed to program memory timing parameters!", - ); - - return result; -} - -static uint32_t ci_get_offsetof(uint32_t type, uint32_t member) -{ - switch (type) { - case SMU_SoftRegisters: - switch (member) { - case HandshakeDisables: - return offsetof(SMU7_SoftRegisters, HandshakeDisables); - case VoltageChangeTimeout: - return offsetof(SMU7_SoftRegisters, VoltageChangeTimeout); - case AverageGraphicsActivity: - return offsetof(SMU7_SoftRegisters, AverageGraphicsA); - case PreVBlankGap: - return offsetof(SMU7_SoftRegisters, PreVBlankGap); - case VBlankTimeout: - return offsetof(SMU7_SoftRegisters, VBlankTimeout); - case DRAM_LOG_ADDR_H: - return offsetof(SMU7_SoftRegisters, DRAM_LOG_ADDR_H); - case DRAM_LOG_ADDR_L: - return offsetof(SMU7_SoftRegisters, DRAM_LOG_ADDR_L); - case DRAM_LOG_PHY_ADDR_H: - return offsetof(SMU7_SoftRegisters, DRAM_LOG_PHY_ADDR_H); - case DRAM_LOG_PHY_ADDR_L: - return offsetof(SMU7_SoftRegisters, DRAM_LOG_PHY_ADDR_L); - case DRAM_LOG_BUFF_SIZE: - return offsetof(SMU7_SoftRegisters, DRAM_LOG_BUFF_SIZE); - } - case SMU_Discrete_DpmTable: - switch (member) { - case LowSclkInterruptThreshold: - return offsetof(SMU7_Discrete_DpmTable, LowSclkInterruptT); - } - } - pr_debug("can't get the offset of type %x member %x\n", type, member); - return 0; -} - -static uint32_t ci_get_mac_definition(uint32_t value) -{ - switch (value) { - case SMU_MAX_LEVELS_GRAPHICS: - return SMU7_MAX_LEVELS_GRAPHICS; - case SMU_MAX_LEVELS_MEMORY: - return SMU7_MAX_LEVELS_MEMORY; - case SMU_MAX_LEVELS_LINK: - return SMU7_MAX_LEVELS_LINK; - case SMU_MAX_ENTRIES_SMIO: - return SMU7_MAX_ENTRIES_SMIO; - case SMU_MAX_LEVELS_VDDC: - return SMU7_MAX_LEVELS_VDDC; - case SMU_MAX_LEVELS_VDDCI: - return SMU7_MAX_LEVELS_VDDCI; - case SMU_MAX_LEVELS_MVDD: - return SMU7_MAX_LEVELS_MVDD; - } - - pr_debug("can't get the mac of %x\n", value); - return 0; -} - -static int ci_load_smc_ucode(struct pp_hwmgr *hwmgr) -{ - uint32_t byte_count, start_addr; - uint8_t *src; - uint32_t data; - - struct cgs_firmware_info info = {0}; - - cgs_get_firmware_info(hwmgr->device, CGS_UCODE_ID_SMU, &info); - - hwmgr->is_kicker = info.is_kicker; - byte_count = info.image_size; - src = (uint8_t *)info.kptr; - start_addr = info.ucode_start_address; - - if (byte_count > SMC_RAM_END) { - pr_err("SMC address is beyond the SMC RAM area.\n"); - return -EINVAL; - } - - cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_0, start_addr); - PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1); - - for (; byte_count >= 4; byte_count -= 4) { - data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; - cgs_write_register(hwmgr->device, mmSMC_IND_DATA_0, data); - src += 4; - } - PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); - - if (0 != byte_count) { - pr_err("SMC size must be divisible by 4\n"); - return -EINVAL; - } - - return 0; -} - -static int ci_upload_firmware(struct pp_hwmgr *hwmgr) -{ - if (ci_is_smc_ram_running(hwmgr)) { - pr_info("smc is running, no need to load smc firmware\n"); - return 0; - } - PHM_WAIT_INDIRECT_FIELD(hwmgr, SMC_IND, RCU_UC_EVENTS, - boot_seq_done, 1); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_MISC_CNTL, - pre_fetcher_en, 1); - - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 1); - return ci_load_smc_ucode(hwmgr); -} - -static int ci_process_firmware_header(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct ci_smumgr *ci_data = (struct ci_smumgr *)(hwmgr->smu_backend); - - uint32_t tmp = 0; - int result; - bool error = false; - - if (ci_upload_firmware(hwmgr)) - return -EINVAL; - - result = ci_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU7_Firmware_Header, DpmTable), - &tmp, SMC_RAM_END); - - if (0 == result) - ci_data->dpm_table_start = tmp; - - error |= (0 != result); - - result = ci_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU7_Firmware_Header, SoftRegisters), - &tmp, SMC_RAM_END); - - if (0 == result) { - data->soft_regs_start = tmp; - ci_data->soft_regs_start = tmp; - } - - error |= (0 != result); - - result = ci_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU7_Firmware_Header, mcRegisterTable), - &tmp, SMC_RAM_END); - - if (0 == result) - ci_data->mc_reg_table_start = tmp; - - result = ci_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU7_Firmware_Header, FanTable), - &tmp, SMC_RAM_END); - - if (0 == result) - ci_data->fan_table_start = tmp; - - error |= (0 != result); - - result = ci_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU7_Firmware_Header, mcArbDramTimingTable), - &tmp, SMC_RAM_END); - - if (0 == result) - ci_data->arb_table_start = tmp; - - error |= (0 != result); - - result = ci_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU7_Firmware_Header, Version), - &tmp, SMC_RAM_END); - - if (0 == result) - hwmgr->microcode_version_info.SMC = tmp; - - error |= (0 != result); - - return error ? 1 : 0; -} - -static uint8_t ci_get_memory_modile_index(struct pp_hwmgr *hwmgr) -{ - return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16)); -} - -static bool ci_check_s0_mc_reg_index(uint16_t in_reg, uint16_t *out_reg) -{ - bool result = true; - - switch (in_reg) { - case mmMC_SEQ_RAS_TIMING: - *out_reg = mmMC_SEQ_RAS_TIMING_LP; - break; - - case mmMC_SEQ_DLL_STBY: - *out_reg = mmMC_SEQ_DLL_STBY_LP; - break; - - case mmMC_SEQ_G5PDX_CMD0: - *out_reg = mmMC_SEQ_G5PDX_CMD0_LP; - break; - - case mmMC_SEQ_G5PDX_CMD1: - *out_reg = mmMC_SEQ_G5PDX_CMD1_LP; - break; - - case mmMC_SEQ_G5PDX_CTRL: - *out_reg = mmMC_SEQ_G5PDX_CTRL_LP; - break; - - case mmMC_SEQ_CAS_TIMING: - *out_reg = mmMC_SEQ_CAS_TIMING_LP; - break; - - case mmMC_SEQ_MISC_TIMING: - *out_reg = mmMC_SEQ_MISC_TIMING_LP; - break; - - case mmMC_SEQ_MISC_TIMING2: - *out_reg = mmMC_SEQ_MISC_TIMING2_LP; - break; - - case mmMC_SEQ_PMG_DVS_CMD: - *out_reg = mmMC_SEQ_PMG_DVS_CMD_LP; - break; - - case mmMC_SEQ_PMG_DVS_CTL: - *out_reg = mmMC_SEQ_PMG_DVS_CTL_LP; - break; - - case mmMC_SEQ_RD_CTL_D0: - *out_reg = mmMC_SEQ_RD_CTL_D0_LP; - break; - - case mmMC_SEQ_RD_CTL_D1: - *out_reg = mmMC_SEQ_RD_CTL_D1_LP; - break; - - case mmMC_SEQ_WR_CTL_D0: - *out_reg = mmMC_SEQ_WR_CTL_D0_LP; - break; - - case mmMC_SEQ_WR_CTL_D1: - *out_reg = mmMC_SEQ_WR_CTL_D1_LP; - break; - - case mmMC_PMG_CMD_EMRS: - *out_reg = mmMC_SEQ_PMG_CMD_EMRS_LP; - break; - - case mmMC_PMG_CMD_MRS: - *out_reg = mmMC_SEQ_PMG_CMD_MRS_LP; - break; - - case mmMC_PMG_CMD_MRS1: - *out_reg = mmMC_SEQ_PMG_CMD_MRS1_LP; - break; - - case mmMC_SEQ_PMG_TIMING: - *out_reg = mmMC_SEQ_PMG_TIMING_LP; - break; - - case mmMC_PMG_CMD_MRS2: - *out_reg = mmMC_SEQ_PMG_CMD_MRS2_LP; - break; - - case mmMC_SEQ_WR_CTL_2: - *out_reg = mmMC_SEQ_WR_CTL_2_LP; - break; - - default: - result = false; - break; - } - - return result; -} - -static int ci_set_s0_mc_reg_index(struct ci_mc_reg_table *table) -{ - uint32_t i; - uint16_t address; - - for (i = 0; i < table->last; i++) { - table->mc_reg_address[i].s0 = - ci_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) - ? address : table->mc_reg_address[i].s1; - } - return 0; -} - -static int ci_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, - struct ci_mc_reg_table *ni_table) -{ - uint8_t i, j; - - PP_ASSERT_WITH_CODE((table->last <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES), - "Invalid VramInfo table.", return -EINVAL); - - for (i = 0; i < table->last; i++) - ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1; - - ni_table->last = table->last; - - for (i = 0; i < table->num_entries; i++) { - ni_table->mc_reg_table_entry[i].mclk_max = - table->mc_reg_table_entry[i].mclk_max; - for (j = 0; j < table->last; j++) { - ni_table->mc_reg_table_entry[i].mc_data[j] = - table->mc_reg_table_entry[i].mc_data[j]; - } - } - - ni_table->num_entries = table->num_entries; - - return 0; -} - -static int ci_set_mc_special_registers(struct pp_hwmgr *hwmgr, - struct ci_mc_reg_table *table) -{ - uint8_t i, j, k; - uint32_t temp_reg; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - for (i = 0, j = table->last; i < table->last; i++) { - PP_ASSERT_WITH_CODE((j < SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - switch (table->mc_reg_address[i].s1) { - - case mmMC_SEQ_MISC1: - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - ((temp_reg & 0xffff0000)) | - ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16); - } - j++; - PP_ASSERT_WITH_CODE((j < SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (temp_reg & 0xffff0000) | - (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); - - if (!data->is_memory_gddr5) - table->mc_reg_table_entry[k].mc_data[j] |= 0x100; - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - if (!data->is_memory_gddr5 && j < SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE) { - table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD; - table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16; - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - } - - break; - - case mmMC_SEQ_RESERVE_M: - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (temp_reg & 0xffff0000) | - (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - break; - - default: - break; - } - - } - - table->last = j; - - return 0; -} - -static int ci_set_valid_flag(struct ci_mc_reg_table *table) -{ - uint8_t i, j; - - for (i = 0; i < table->last; i++) { - for (j = 1; j < table->num_entries; j++) { - if (table->mc_reg_table_entry[j-1].mc_data[i] != - table->mc_reg_table_entry[j].mc_data[i]) { - table->validflag |= (1 << i); - break; - } - } - } - - return 0; -} - -static int ci_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); - pp_atomctrl_mc_reg_table *table; - struct ci_mc_reg_table *ni_table = &smu_data->mc_reg_table; - uint8_t module_index = ci_get_memory_modile_index(hwmgr); - - table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); - - if (NULL == table) - return -ENOMEM; - - /* Program additional LP registers that are no longer programmed by VBIOS */ - cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL)); - cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2)); - - memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table)); - - result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); - - if (0 == result) - result = ci_copy_vbios_smc_reg_table(table, ni_table); - - if (0 == result) { - ci_set_s0_mc_reg_index(ni_table); - result = ci_set_mc_special_registers(hwmgr, ni_table); - } - - if (0 == result) - ci_set_valid_flag(ni_table); - - kfree(table); - - return result; -} - -static bool ci_is_dpm_running(struct pp_hwmgr *hwmgr) -{ - return ci_is_smc_ram_running(hwmgr); -} - -static int ci_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request) -{ - struct ci_smumgr *smu_data = (struct ci_smumgr *) - (hwmgr->smu_backend); - struct SMU7_Discrete_GraphicsLevel *levels = - smu_data->smc_state_table.GraphicsLevel; - uint32_t array = smu_data->dpm_table_start + - offsetof(SMU7_Discrete_DpmTable, GraphicsLevel); - uint32_t array_size = sizeof(struct SMU7_Discrete_GraphicsLevel) * - SMU7_MAX_LEVELS_GRAPHICS; - uint32_t i; - - for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { - levels[i].ActivityLevel = - cpu_to_be16(request->activity_threshold); - levels[i].EnabledForActivity = 1; - levels[i].UpH = request->up_hyst; - levels[i].DownH = request->down_hyst; - } - - return ci_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - array_size, SMC_RAM_END); -} - - -static int ci_smu_init(struct pp_hwmgr *hwmgr) -{ - int i; - struct ci_smumgr *ci_priv = NULL; - - ci_priv = kzalloc(sizeof(struct ci_smumgr), GFP_KERNEL); - - if (ci_priv == NULL) - return -ENOMEM; - - for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) - ci_priv->activity_target[i] = 30; - - hwmgr->smu_backend = ci_priv; - - return 0; -} - -static int ci_smu_fini(struct pp_hwmgr *hwmgr) -{ - kfree(hwmgr->smu_backend); - hwmgr->smu_backend = NULL; - cgs_rel_firmware(hwmgr->device, CGS_UCODE_ID_SMU); - return 0; -} - -static int ci_start_smu(struct pp_hwmgr *hwmgr) -{ - return 0; -} - -const struct pp_smumgr_func ci_smu_funcs = { - .smu_init = ci_smu_init, - .smu_fini = ci_smu_fini, - .start_smu = ci_start_smu, - .check_fw_load_finish = NULL, - .request_smu_load_fw = NULL, - .request_smu_load_specific_fw = NULL, - .send_msg_to_smc = ci_send_msg_to_smc, - .send_msg_to_smc_with_parameter = ci_send_msg_to_smc_with_parameter, - .download_pptable_settings = NULL, - .upload_pptable_settings = NULL, - .get_offsetof = ci_get_offsetof, - .process_firmware_header = ci_process_firmware_header, - .init_smc_table = ci_init_smc_table, - .update_sclk_threshold = ci_update_sclk_threshold, - .thermal_setup_fan_table = ci_thermal_setup_fan_table, - .populate_all_graphic_levels = ci_populate_all_graphic_levels, - .populate_all_memory_levels = ci_populate_all_memory_levels, - .get_mac_definition = ci_get_mac_definition, - .initialize_mc_reg_table = ci_initialize_mc_reg_table, - .is_dpm_running = ci_is_dpm_running, - .populate_requested_graphic_levels = ci_populate_requested_graphic_levels, -}; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c new file mode 100644 index 000000000000..4d672cd15785 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c @@ -0,0 +1,2818 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include +#include +#include +#include "linux/delay.h" +#include + +#include "smumgr.h" +#include "pp_debug.h" +#include "ci_smumgr.h" +#include "ppsmc.h" +#include "smu7_hwmgr.h" +#include "hardwaremanager.h" +#include "ppatomctrl.h" +#include "cgs_common.h" +#include "atombios.h" +#include "pppcielanes.h" + +#include "smu/smu_7_0_1_d.h" +#include "smu/smu_7_0_1_sh_mask.h" + +#include "dce/dce_8_0_d.h" +#include "dce/dce_8_0_sh_mask.h" + +#include "bif/bif_4_1_d.h" +#include "bif/bif_4_1_sh_mask.h" + +#include "gca/gfx_7_2_d.h" +#include "gca/gfx_7_2_sh_mask.h" + +#include "gmc/gmc_7_1_d.h" +#include "gmc/gmc_7_1_sh_mask.h" + +#include "processpptables.h" + +#define MC_CG_ARB_FREQ_F0 0x0a +#define MC_CG_ARB_FREQ_F1 0x0b +#define MC_CG_ARB_FREQ_F2 0x0c +#define MC_CG_ARB_FREQ_F3 0x0d + +#define SMC_RAM_END 0x40000 + +#define VOLTAGE_SCALE 4 +#define VOLTAGE_VID_OFFSET_SCALE1 625 +#define VOLTAGE_VID_OFFSET_SCALE2 100 +#define CISLAND_MINIMUM_ENGINE_CLOCK 800 +#define CISLAND_MAX_DEEPSLEEP_DIVIDER_ID 5 + +static const struct ci_pt_defaults defaults_hawaii_xt = { + 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0xB0000, + { 0x2E, 0x00, 0x00, 0x88, 0x00, 0x00, 0x72, 0x60, 0x51, 0xA7, 0x79, 0x6B, 0x90, 0xBD, 0x79 }, + { 0x217, 0x217, 0x217, 0x242, 0x242, 0x242, 0x269, 0x269, 0x269, 0x2A1, 0x2A1, 0x2A1, 0x2C9, 0x2C9, 0x2C9 } +}; + +static const struct ci_pt_defaults defaults_hawaii_pro = { + 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0x65062, + { 0x2E, 0x00, 0x00, 0x88, 0x00, 0x00, 0x72, 0x60, 0x51, 0xA7, 0x79, 0x6B, 0x90, 0xBD, 0x79 }, + { 0x217, 0x217, 0x217, 0x242, 0x242, 0x242, 0x269, 0x269, 0x269, 0x2A1, 0x2A1, 0x2A1, 0x2C9, 0x2C9, 0x2C9 } +}; + +static const struct ci_pt_defaults defaults_bonaire_xt = { + 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, + { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61 }, + { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } +}; + + +static const struct ci_pt_defaults defaults_saturn_xt = { + 1, 0xF, 0xFD, 0x19, 5, 55, 0, 0x70000, + { 0x8C, 0x247, 0x249, 0xA6, 0x80, 0x81, 0x8B, 0x89, 0x86, 0xC9, 0xCA, 0xC9, 0x4D, 0x4D, 0x4D }, + { 0x187, 0x187, 0x187, 0x1C7, 0x1C7, 0x1C7, 0x210, 0x210, 0x210, 0x266, 0x266, 0x266, 0x2C9, 0x2C9, 0x2C9 } +}; + + +static int ci_set_smc_sram_address(struct pp_hwmgr *hwmgr, + uint32_t smc_addr, uint32_t limit) +{ + if ((0 != (3 & smc_addr)) + || ((smc_addr + 3) >= limit)) { + pr_err("smc_addr invalid \n"); + return -EINVAL; + } + + cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_0, smc_addr); + PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); + return 0; +} + +static int ci_copy_bytes_to_smc(struct pp_hwmgr *hwmgr, uint32_t smc_start_address, + const uint8_t *src, uint32_t byte_count, uint32_t limit) +{ + int result; + uint32_t data = 0; + uint32_t original_data; + uint32_t addr = 0; + uint32_t extra_shift; + + if ((3 & smc_start_address) + || ((smc_start_address + byte_count) >= limit)) { + pr_err("smc_start_address invalid \n"); + return -EINVAL; + } + + addr = smc_start_address; + + while (byte_count >= 4) { + /* Bytes are written into the SMC address space with the MSB first. */ + data = src[0] * 0x1000000 + src[1] * 0x10000 + src[2] * 0x100 + src[3]; + + result = ci_set_smc_sram_address(hwmgr, addr, limit); + + if (0 != result) + return result; + + cgs_write_register(hwmgr->device, mmSMC_IND_DATA_0, data); + + src += 4; + byte_count -= 4; + addr += 4; + } + + if (0 != byte_count) { + + data = 0; + + result = ci_set_smc_sram_address(hwmgr, addr, limit); + + if (0 != result) + return result; + + + original_data = cgs_read_register(hwmgr->device, mmSMC_IND_DATA_0); + + extra_shift = 8 * (4 - byte_count); + + while (byte_count > 0) { + /* Bytes are written into the SMC addres space with the MSB first. */ + data = (0x100 * data) + *src++; + byte_count--; + } + + data <<= extra_shift; + + data |= (original_data & ~((~0UL) << extra_shift)); + + result = ci_set_smc_sram_address(hwmgr, addr, limit); + + if (0 != result) + return result; + + cgs_write_register(hwmgr->device, mmSMC_IND_DATA_0, data); + } + + return 0; +} + + +static int ci_program_jump_on_start(struct pp_hwmgr *hwmgr) +{ + static const unsigned char data[4] = { 0xE0, 0x00, 0x80, 0x40 }; + + ci_copy_bytes_to_smc(hwmgr, 0x0, data, 4, sizeof(data)+1); + + return 0; +} + +bool ci_is_smc_ram_running(struct pp_hwmgr *hwmgr) +{ + return ((0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable)) + && (0x20100 <= cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, ixSMC_PC_C))); +} + +static int ci_read_smc_sram_dword(struct pp_hwmgr *hwmgr, uint32_t smc_addr, + uint32_t *value, uint32_t limit) +{ + int result; + + result = ci_set_smc_sram_address(hwmgr, smc_addr, limit); + + if (result) + return result; + + *value = cgs_read_register(hwmgr->device, mmSMC_IND_DATA_0); + return 0; +} + +static int ci_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) +{ + int ret; + + if (!ci_is_smc_ram_running(hwmgr)) + return -EINVAL; + + cgs_write_register(hwmgr->device, mmSMC_MESSAGE_0, msg); + + PHM_WAIT_FIELD_UNEQUAL(hwmgr, SMC_RESP_0, SMC_RESP, 0); + + ret = PHM_READ_FIELD(hwmgr->device, SMC_RESP_0, SMC_RESP); + + if (ret != 1) + pr_info("\n failed to send message %x ret is %d\n", msg, ret); + + return 0; +} + +static int ci_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, + uint16_t msg, uint32_t parameter) +{ + cgs_write_register(hwmgr->device, mmSMC_MSG_ARG_0, parameter); + return ci_send_msg_to_smc(hwmgr, msg); +} + +static void ci_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + struct cgs_system_info sys_info = {0}; + uint32_t dev_id; + + sys_info.size = sizeof(struct cgs_system_info); + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; + cgs_query_system_info(hwmgr->device, &sys_info); + dev_id = (uint32_t)sys_info.value; + + switch (dev_id) { + case 0x67BA: + case 0x66B1: + smu_data->power_tune_defaults = &defaults_hawaii_pro; + break; + case 0x67B8: + case 0x66B0: + smu_data->power_tune_defaults = &defaults_hawaii_xt; + break; + case 0x6640: + case 0x6641: + case 0x6646: + case 0x6647: + smu_data->power_tune_defaults = &defaults_saturn_xt; + break; + case 0x6649: + case 0x6650: + case 0x6651: + case 0x6658: + case 0x665C: + case 0x665D: + case 0x67A0: + case 0x67A1: + case 0x67A2: + case 0x67A8: + case 0x67A9: + case 0x67AA: + case 0x67B9: + case 0x67BE: + default: + smu_data->power_tune_defaults = &defaults_bonaire_xt; + break; + } +} + +static int ci_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, + struct phm_clock_voltage_dependency_table *allowed_clock_voltage_table, + uint32_t clock, uint32_t *vol) +{ + uint32_t i = 0; + + if (allowed_clock_voltage_table->count == 0) + return -EINVAL; + + for (i = 0; i < allowed_clock_voltage_table->count; i++) { + if (allowed_clock_voltage_table->entries[i].clk >= clock) { + *vol = allowed_clock_voltage_table->entries[i].v; + return 0; + } + } + + *vol = allowed_clock_voltage_table->entries[i - 1].v; + return 0; +} + +static int ci_calculate_sclk_params(struct pp_hwmgr *hwmgr, + uint32_t clock, struct SMU7_Discrete_GraphicsLevel *sclk) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct pp_atomctrl_clock_dividers_vi dividers; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + uint32_t ref_clock; + uint32_t ref_divider; + uint32_t fbdiv; + int result; + + /* get the engine clock dividers for this clock value */ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, clock, ÷rs); + + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", + return result); + + /* To get FBDIV we need to multiply this by 16384 and divide it by Fref. */ + ref_clock = atomctrl_get_reference_clock(hwmgr); + ref_divider = 1 + dividers.uc_pll_ref_div; + + /* low 14 bits is fraction and high 12 bits is divider */ + fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; + + /* SPLL_FUNC_CNTL setup */ + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_REF_DIV, dividers.uc_pll_ref_div); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_PDIV_A, dividers.uc_pll_post_div); + + /* SPLL_FUNC_CNTL_3 setup*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, + SPLL_FB_DIV, fbdiv); + + /* set to use fractional accumulation*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, + SPLL_DITHEN, 1); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { + struct pp_atomctrl_internal_ss_info ss_info; + uint32_t vco_freq = clock * dividers.uc_pll_post_div; + + if (!atomctrl_get_engine_clock_spread_spectrum(hwmgr, + vco_freq, &ss_info)) { + uint32_t clk_s = ref_clock * 5 / + (ref_divider * ss_info.speed_spectrum_rate); + uint32_t clk_v = 4 * ss_info.speed_spectrum_percentage * + fbdiv / (clk_s * 10000); + + cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, + CG_SPLL_SPREAD_SPECTRUM, CLKS, clk_s); + cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, + CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); + cg_spll_spread_spectrum_2 = PHM_SET_FIELD(cg_spll_spread_spectrum_2, + CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clk_v); + } + } + + sclk->SclkFrequency = clock; + sclk->CgSpllFuncCntl3 = spll_func_cntl_3; + sclk->CgSpllFuncCntl4 = spll_func_cntl_4; + sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; + sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; + sclk->SclkDid = (uint8_t)dividers.pll_post_divider; + + return 0; +} + +static void ci_populate_phase_value_based_on_sclk(struct pp_hwmgr *hwmgr, + const struct phm_phase_shedding_limits_table *pl, + uint32_t sclk, uint32_t *p_shed) +{ + unsigned int i; + + /* use the minimum phase shedding */ + *p_shed = 1; + + for (i = 0; i < pl->count; i++) { + if (sclk < pl->entries[i].Sclk) { + *p_shed = i; + break; + } + } +} + +static uint8_t ci_get_sleep_divider_id_from_clock(uint32_t clock, + uint32_t clock_insr) +{ + uint8_t i; + uint32_t temp; + uint32_t min = min_t(uint32_t, clock_insr, CISLAND_MINIMUM_ENGINE_CLOCK); + + if (clock < min) { + pr_info("Engine clock can't satisfy stutter requirement!\n"); + return 0; + } + for (i = CISLAND_MAX_DEEPSLEEP_DIVIDER_ID; ; i--) { + temp = clock >> i; + + if (temp >= min || i == 0) + break; + } + return i; +} + +static int ci_populate_single_graphic_level(struct pp_hwmgr *hwmgr, + uint32_t clock, uint16_t sclk_al_threshold, + struct SMU7_Discrete_GraphicsLevel *level) +{ + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + + result = ci_calculate_sclk_params(hwmgr, clock, level); + + /* populate graphics levels */ + result = ci_get_dependency_volt_by_clk(hwmgr, + hwmgr->dyn_state.vddc_dependency_on_sclk, clock, + (uint32_t *)(&level->MinVddc)); + if (result) { + pr_err("vdd_dep_on_sclk table is NULL\n"); + return result; + } + + level->SclkFrequency = clock; + level->MinVddcPhases = 1; + + if (data->vddc_phase_shed_control) + ci_populate_phase_value_based_on_sclk(hwmgr, + hwmgr->dyn_state.vddc_phase_shed_limits_table, + clock, + &level->MinVddcPhases); + + level->ActivityLevel = sclk_al_threshold; + level->CcPwrDynRm = 0; + level->CcPwrDynRm1 = 0; + level->EnabledForActivity = 0; + /* this level can be used for throttling.*/ + level->EnabledForThrottle = 1; + level->UpH = 0; + level->DownH = 0; + level->VoltageDownH = 0; + level->PowerThrottle = 0; + + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkDeepSleep)) + level->DeepSleepDivId = + ci_get_sleep_divider_id_from_clock(clock, + CISLAND_MINIMUM_ENGINE_CLOCK); + + /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ + level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + if (0 == result) { + level->MinVddc = PP_HOST_TO_SMC_UL(level->MinVddc * VOLTAGE_SCALE); + CONVERT_FROM_HOST_TO_SMC_UL(level->MinVddcPhases); + CONVERT_FROM_HOST_TO_SMC_UL(level->SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1); + } + + return result; +} + +static int ci_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + int result = 0; + uint32_t array = smu_data->dpm_table_start + + offsetof(SMU7_Discrete_DpmTable, GraphicsLevel); + uint32_t array_size = sizeof(struct SMU7_Discrete_GraphicsLevel) * + SMU7_MAX_LEVELS_GRAPHICS; + struct SMU7_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t i; + + for (i = 0; i < dpm_table->sclk_table.count; i++) { + result = ci_populate_single_graphic_level(hwmgr, + dpm_table->sclk_table.dpm_levels[i].value, + (uint16_t)smu_data->activity_target[i], + &levels[i]); + if (result) + return result; + if (i > 1) + smu_data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0; + if (i == (dpm_table->sclk_table.count - 1)) + smu_data->smc_state_table.GraphicsLevel[i].DisplayWatermark = + PPSMC_DISPLAY_WATERMARK_HIGH; + } + + smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; + + smu_data->smc_state_table.GraphicsDpmLevelCount = (u8)dpm_table->sclk_table.count; + data->dpm_level_enable_mask.sclk_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); + + result = ci_copy_bytes_to_smc(hwmgr, array, + (u8 *)levels, array_size, + SMC_RAM_END); + + return result; + +} + +static int ci_populate_svi_load_line(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; + + smu_data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; + smu_data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddc; + smu_data->power_tune_table.SviLoadLineTrimVddC = 3; + smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; + + return 0; +} + +static int ci_populate_tdc_limit(struct pp_hwmgr *hwmgr) +{ + uint16_t tdc_limit; + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; + + tdc_limit = (uint16_t)(hwmgr->dyn_state.cac_dtp_table->usTDC * 256); + smu_data->power_tune_table.TDC_VDDC_PkgLimit = + CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); + smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = + defaults->tdc_vddc_throttle_release_limit_perc; + smu_data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; + + return 0; +} + +static int ci_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; + uint32_t temp; + + if (ci_read_smc_sram_dword(hwmgr, + fuse_table_offset + + offsetof(SMU7_Discrete_PmFuses, TdcWaterfallCtl), + (uint32_t *)&temp, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", + return -EINVAL); + else + smu_data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; + + return 0; +} + +static int ci_populate_fuzzy_fan(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) +{ + uint16_t tmp; + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + + if ((hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity & (1 << 15)) + || 0 == hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity) + tmp = hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity; + else + tmp = hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity; + + smu_data->power_tune_table.FuzzyFan_PwmSetDelta = CONVERT_FROM_HOST_TO_SMC_US(tmp); + + return 0; +} + +static int ci_populate_bapm_vddc_vid_sidd(struct pp_hwmgr *hwmgr) +{ + int i; + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + uint8_t *hi_vid = smu_data->power_tune_table.BapmVddCVidHiSidd; + uint8_t *lo_vid = smu_data->power_tune_table.BapmVddCVidLoSidd; + uint8_t *hi2_vid = smu_data->power_tune_table.BapmVddCVidHiSidd2; + + PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.cac_leakage_table, + "The CAC Leakage table does not exist!", return -EINVAL); + PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count <= 8, + "There should never be more than 8 entries for BapmVddcVid!!!", return -EINVAL); + PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count == hwmgr->dyn_state.vddc_dependency_on_sclk->count, + "CACLeakageTable->count and VddcDependencyOnSCLk->count not equal", return -EINVAL); + + for (i = 0; (uint32_t) i < hwmgr->dyn_state.cac_leakage_table->count; i++) { + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_EVV)) { + lo_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc1); + hi_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc2); + hi2_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc3); + } else { + lo_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc); + hi_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Leakage); + } + } + + return 0; +} + +static int ci_populate_vddc_vid(struct pp_hwmgr *hwmgr) +{ + int i; + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + uint8_t *vid = smu_data->power_tune_table.VddCVid; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + PP_ASSERT_WITH_CODE(data->vddc_voltage_table.count <= 8, + "There should never be more than 8 entries for VddcVid!!!", + return -EINVAL); + + for (i = 0; i < (int)data->vddc_voltage_table.count; i++) + vid[i] = convert_to_vid(data->vddc_voltage_table.entries[i].value); + + return 0; +} + +static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + u8 *hi_vid = smu_data->power_tune_table.BapmVddCVidHiSidd; + u8 *lo_vid = smu_data->power_tune_table.BapmVddCVidLoSidd; + int i, min, max; + + min = max = hi_vid[0]; + for (i = 0; i < 8; i++) { + if (0 != hi_vid[i]) { + if (min > hi_vid[i]) + min = hi_vid[i]; + if (max < hi_vid[i]) + max = hi_vid[i]; + } + + if (0 != lo_vid[i]) { + if (min > lo_vid[i]) + min = lo_vid[i]; + if (max < lo_vid[i]) + max = lo_vid[i]; + } + } + + if ((min == 0) || (max == 0)) + return -EINVAL; + smu_data->power_tune_table.GnbLPMLMaxVid = (u8)max; + smu_data->power_tune_table.GnbLPMLMinVid = (u8)min; + + return 0; +} + +static int ci_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + uint16_t HiSidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; + uint16_t LoSidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; + struct phm_cac_tdp_table *cac_table = hwmgr->dyn_state.cac_dtp_table; + + HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); + LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); + + smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = + CONVERT_FROM_HOST_TO_SMC_US(HiSidd); + smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = + CONVERT_FROM_HOST_TO_SMC_US(LoSidd); + + return 0; +} + +static int ci_populate_pm_fuses(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + uint32_t pm_fuse_table_offset; + int ret = 0; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment)) { + if (ci_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU7_Firmware_Header, PmFuseTable), + &pm_fuse_table_offset, SMC_RAM_END)) { + pr_err("Attempt to get pm_fuse_table_offset Failed!\n"); + return -EINVAL; + } + + /* DW0 - DW3 */ + ret = ci_populate_bapm_vddc_vid_sidd(hwmgr); + /* DW4 - DW5 */ + ret |= ci_populate_vddc_vid(hwmgr); + /* DW6 */ + ret |= ci_populate_svi_load_line(hwmgr); + /* DW7 */ + ret |= ci_populate_tdc_limit(hwmgr); + /* DW8 */ + ret |= ci_populate_dw8(hwmgr, pm_fuse_table_offset); + + ret |= ci_populate_fuzzy_fan(hwmgr, pm_fuse_table_offset); + + ret |= ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(hwmgr); + + ret |= ci_populate_bapm_vddc_base_leakage_sidd(hwmgr); + if (ret) + return ret; + + ret = ci_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, + (uint8_t *)&smu_data->power_tune_table, + sizeof(struct SMU7_Discrete_PmFuses), SMC_RAM_END); + } + return ret; +} + +static int ci_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + const struct ci_pt_defaults *defaults = smu_data->power_tune_defaults; + SMU7_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); + struct phm_cac_tdp_table *cac_dtp_table = hwmgr->dyn_state.cac_dtp_table; + struct phm_ppm_table *ppm = hwmgr->dyn_state.ppm_parameter_table; + const uint16_t *def1, *def2; + int i, j, k; + + dpm_table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 256)); + dpm_table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); + + dpm_table->DTETjOffset = 0; + dpm_table->GpuTjMax = (uint8_t)(data->thermal_temp_setting.temperature_high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES); + dpm_table->GpuTjHyst = 8; + + dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; + + if (ppm) { + dpm_table->PPM_PkgPwrLimit = (uint16_t)ppm->dgpu_tdp * 256 / 1000; + dpm_table->PPM_TemperatureLimit = (uint16_t)ppm->tj_max * 256; + } else { + dpm_table->PPM_PkgPwrLimit = 0; + dpm_table->PPM_TemperatureLimit = 0; + } + + CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_PkgPwrLimit); + CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_TemperatureLimit); + + dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bapm_temp_gradient); + def1 = defaults->bapmti_r; + def2 = defaults->bapmti_rc; + + for (i = 0; i < SMU7_DTE_ITERATIONS; i++) { + for (j = 0; j < SMU7_DTE_SOURCES; j++) { + for (k = 0; k < SMU7_DTE_SINKS; k++) { + dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*def1); + dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*def2); + def1++; + def2++; + } + } + } + + return 0; +} + +static int ci_get_std_voltage_value_sidd(struct pp_hwmgr *hwmgr, + pp_atomctrl_voltage_table_entry *tab, uint16_t *hi, + uint16_t *lo) +{ + uint16_t v_index; + bool vol_found = false; + *hi = tab->value * VOLTAGE_SCALE; + *lo = tab->value * VOLTAGE_SCALE; + + PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.vddc_dependency_on_sclk, + "The SCLK/VDDC Dependency Table does not exist.\n", + return -EINVAL); + + if (NULL == hwmgr->dyn_state.cac_leakage_table) { + pr_warn("CAC Leakage Table does not exist, using vddc.\n"); + return 0; + } + + for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { + if (tab->value == hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { + vol_found = true; + if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { + *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage * VOLTAGE_SCALE); + } else { + pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index, using maximum index from CAC table.\n"); + *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); + } + break; + } + } + + if (!vol_found) { + for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { + if (tab->value <= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { + vol_found = true; + if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { + *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage) * VOLTAGE_SCALE; + } else { + pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index in second look up, using maximum index from CAC table."); + *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); + } + break; + } + } + + if (!vol_found) + pr_warn("Unable to get std_vddc from SCLK/VDDC Dependency Table, using vddc.\n"); + } + + return 0; +} + +static int ci_populate_smc_voltage_table(struct pp_hwmgr *hwmgr, + pp_atomctrl_voltage_table_entry *tab, + SMU7_Discrete_VoltageLevel *smc_voltage_tab) +{ + int result; + + result = ci_get_std_voltage_value_sidd(hwmgr, tab, + &smc_voltage_tab->StdVoltageHiSidd, + &smc_voltage_tab->StdVoltageLoSidd); + if (result) { + smc_voltage_tab->StdVoltageHiSidd = tab->value * VOLTAGE_SCALE; + smc_voltage_tab->StdVoltageLoSidd = tab->value * VOLTAGE_SCALE; + } + + smc_voltage_tab->Voltage = PP_HOST_TO_SMC_US(tab->value * VOLTAGE_SCALE); + CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd); + CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageLoSidd); + + return 0; +} + +static int ci_populate_smc_vddc_table(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + unsigned int count; + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + table->VddcLevelCount = data->vddc_voltage_table.count; + for (count = 0; count < table->VddcLevelCount; count++) { + result = ci_populate_smc_voltage_table(hwmgr, + &(data->vddc_voltage_table.entries[count]), + &(table->VddcLevel[count])); + PP_ASSERT_WITH_CODE(0 == result, "do not populate SMC VDDC voltage table", return -EINVAL); + + /* GPIO voltage control */ + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->voltage_control) + table->VddcLevel[count].Smio |= data->vddc_voltage_table.entries[count].smio_low; + else + table->VddcLevel[count].Smio = 0; + } + + CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount); + + return 0; +} + +static int ci_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t count; + int result; + + table->VddciLevelCount = data->vddci_voltage_table.count; + + for (count = 0; count < table->VddciLevelCount; count++) { + result = ci_populate_smc_voltage_table(hwmgr, + &(data->vddci_voltage_table.entries[count]), + &(table->VddciLevel[count])); + PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC VDDCI voltage table", return -EINVAL); + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) + table->VddciLevel[count].Smio |= data->vddci_voltage_table.entries[count].smio_low; + else + table->VddciLevel[count].Smio |= 0; + } + + CONVERT_FROM_HOST_TO_SMC_UL(table->VddciLevelCount); + + return 0; +} + +static int ci_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t count; + int result; + + table->MvddLevelCount = data->mvdd_voltage_table.count; + + for (count = 0; count < table->MvddLevelCount; count++) { + result = ci_populate_smc_voltage_table(hwmgr, + &(data->mvdd_voltage_table.entries[count]), + &table->MvddLevel[count]); + PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC mvdd voltage table", return -EINVAL); + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) + table->MvddLevel[count].Smio |= data->mvdd_voltage_table.entries[count].smio_low; + else + table->MvddLevel[count].Smio |= 0; + } + + CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount); + + return 0; +} + + +static int ci_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + int result; + + result = ci_populate_smc_vddc_table(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "can not populate VDDC voltage table to SMC", return -EINVAL); + + result = ci_populate_smc_vdd_ci_table(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "can not populate VDDCI voltage table to SMC", return -EINVAL); + + result = ci_populate_smc_mvdd_table(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "can not populate MVDD voltage table to SMC", return -EINVAL); + + return 0; +} + +static int ci_populate_ulv_level(struct pp_hwmgr *hwmgr, + struct SMU7_Discrete_Ulv *state) +{ + uint32_t voltage_response_time, ulv_voltage; + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + state->CcPwrDynRm = 0; + state->CcPwrDynRm1 = 0; + + result = pp_tables_get_response_times(hwmgr, &voltage_response_time, &ulv_voltage); + PP_ASSERT_WITH_CODE((0 == result), "can not get ULV voltage value", return result;); + + if (ulv_voltage == 0) { + data->ulv_supported = false; + return 0; + } + + if (data->voltage_control != SMU7_VOLTAGE_CONTROL_BY_SVID2) { + /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ + if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) + state->VddcOffset = 0; + else + /* used in SMIO Mode. not implemented for now. this is backup only for CI. */ + state->VddcOffset = (uint16_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage); + } else { + /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ + if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) + state->VddcOffsetVid = 0; + else /* used in SVI2 Mode */ + state->VddcOffsetVid = (uint8_t)( + (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage) + * VOLTAGE_VID_OFFSET_SCALE2 + / VOLTAGE_VID_OFFSET_SCALE1); + } + state->VddcPhase = 1; + + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); + CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); + + return 0; +} + +static int ci_populate_ulv_state(struct pp_hwmgr *hwmgr, + SMU7_Discrete_Ulv *ulv_level) +{ + return ci_populate_ulv_level(hwmgr, ulv_level); +} + +static int ci_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU7_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + uint32_t i; + +/* Index dpm_table->pcie_speed_table.count is reserved for PCIE boot level.*/ + for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { + table->LinkLevel[i].PcieGenSpeed = + (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; + table->LinkLevel[i].PcieLaneCount = + (uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1); + table->LinkLevel[i].EnabledForActivity = 1; + table->LinkLevel[i].DownT = PP_HOST_TO_SMC_UL(5); + table->LinkLevel[i].UpT = PP_HOST_TO_SMC_UL(30); + } + + smu_data->smc_state_table.LinkLevelCount = + (uint8_t)dpm_table->pcie_speed_table.count; + data->dpm_level_enable_mask.pcie_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); + + return 0; +} + +static int ci_calculate_mclk_params( + struct pp_hwmgr *hwmgr, + uint32_t memory_clock, + SMU7_Discrete_MemoryLevel *mclk, + bool strobe_mode, + bool dllStateOn + ) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; + uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; + uint32_t mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL; + uint32_t mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL; + uint32_t mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL; + uint32_t mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1; + uint32_t mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2; + uint32_t mpll_ss1 = data->clock_registers.vMPLL_SS1; + uint32_t mpll_ss2 = data->clock_registers.vMPLL_SS2; + + pp_atomctrl_memory_clock_param mpll_param; + int result; + + result = atomctrl_get_memory_pll_dividers_si(hwmgr, + memory_clock, &mpll_param, strobe_mode); + PP_ASSERT_WITH_CODE(0 == result, + "Error retrieving Memory Clock Parameters from VBIOS.", return result); + + mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl); + + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, CLKF, mpll_param.mpll_fb_divider.cl_kf); + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, CLKFRAC, mpll_param.mpll_fb_divider.clk_frac); + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, VCO_MODE, mpll_param.vco_mode); + + mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl, + MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); + + if (data->is_memory_gddr5) { + mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, + MPLL_DQ_FUNC_CNTL, YCLK_SEL, mpll_param.yclk_sel); + mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, + MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); + } + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MemorySpreadSpectrumSupport)) { + pp_atomctrl_internal_ss_info ss_info; + uint32_t freq_nom; + uint32_t tmp; + uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr); + + /* for GDDR5 for all modes and DDR3 */ + if (1 == mpll_param.qdr) + freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider); + else + freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider); + + /* tmp = (freq_nom / reference_clock * reference_divider) ^ 2 Note: S.I. reference_divider = 1*/ + tmp = (freq_nom / reference_clock); + tmp = tmp * tmp; + + if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) { + uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate; + uint32_t clkv = + (uint32_t)((((131 * ss_info.speed_spectrum_percentage * + ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom); + + mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv); + mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks); + } + } + + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn); + + + mclk->MclkFrequency = memory_clock; + mclk->MpllFuncCntl = mpll_func_cntl; + mclk->MpllFuncCntl_1 = mpll_func_cntl_1; + mclk->MpllFuncCntl_2 = mpll_func_cntl_2; + mclk->MpllAdFuncCntl = mpll_ad_func_cntl; + mclk->MpllDqFuncCntl = mpll_dq_func_cntl; + mclk->MclkPwrmgtCntl = mclk_pwrmgt_cntl; + mclk->DllCntl = dll_cntl; + mclk->MpllSs1 = mpll_ss1; + mclk->MpllSs2 = mpll_ss2; + + return 0; +} + +static uint8_t ci_get_mclk_frequency_ratio(uint32_t memory_clock, + bool strobe_mode) +{ + uint8_t mc_para_index; + + if (strobe_mode) { + if (memory_clock < 12500) + mc_para_index = 0x00; + else if (memory_clock > 47500) + mc_para_index = 0x0f; + else + mc_para_index = (uint8_t)((memory_clock - 10000) / 2500); + } else { + if (memory_clock < 65000) + mc_para_index = 0x00; + else if (memory_clock > 135000) + mc_para_index = 0x0f; + else + mc_para_index = (uint8_t)((memory_clock - 60000) / 5000); + } + + return mc_para_index; +} + +static uint8_t ci_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock) +{ + uint8_t mc_para_index; + + if (memory_clock < 10000) + mc_para_index = 0; + else if (memory_clock >= 80000) + mc_para_index = 0x0f; + else + mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1); + + return mc_para_index; +} + +static int ci_populate_phase_value_based_on_mclk(struct pp_hwmgr *hwmgr, const struct phm_phase_shedding_limits_table *pl, + uint32_t memory_clock, uint32_t *p_shed) +{ + unsigned int i; + + *p_shed = 1; + + for (i = 0; i < pl->count; i++) { + if (memory_clock < pl->entries[i].Mclk) { + *p_shed = i; + break; + } + } + + return 0; +} + +static int ci_populate_single_memory_level( + struct pp_hwmgr *hwmgr, + uint32_t memory_clock, + SMU7_Discrete_MemoryLevel *memory_level + ) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int result = 0; + bool dll_state_on; + struct cgs_display_info info = {0}; + uint32_t mclk_edc_wr_enable_threshold = 40000; + uint32_t mclk_edc_enable_threshold = 40000; + uint32_t mclk_strobe_mode_threshold = 40000; + + if (hwmgr->dyn_state.vddc_dependency_on_mclk != NULL) { + result = ci_get_dependency_volt_by_clk(hwmgr, + hwmgr->dyn_state.vddc_dependency_on_mclk, memory_clock, &memory_level->MinVddc); + PP_ASSERT_WITH_CODE((0 == result), + "can not find MinVddc voltage value from memory VDDC voltage dependency table", return result); + } + + if (NULL != hwmgr->dyn_state.vddci_dependency_on_mclk) { + result = ci_get_dependency_volt_by_clk(hwmgr, + hwmgr->dyn_state.vddci_dependency_on_mclk, + memory_clock, + &memory_level->MinVddci); + PP_ASSERT_WITH_CODE((0 == result), + "can not find MinVddci voltage value from memory VDDCI voltage dependency table", return result); + } + + if (NULL != hwmgr->dyn_state.mvdd_dependency_on_mclk) { + result = ci_get_dependency_volt_by_clk(hwmgr, + hwmgr->dyn_state.mvdd_dependency_on_mclk, + memory_clock, + &memory_level->MinMvdd); + PP_ASSERT_WITH_CODE((0 == result), + "can not find MinVddci voltage value from memory MVDD voltage dependency table", return result); + } + + memory_level->MinVddcPhases = 1; + + if (data->vddc_phase_shed_control) { + ci_populate_phase_value_based_on_mclk(hwmgr, hwmgr->dyn_state.vddc_phase_shed_limits_table, + memory_clock, &memory_level->MinVddcPhases); + } + + memory_level->EnabledForThrottle = 1; + memory_level->EnabledForActivity = 1; + memory_level->UpH = 0; + memory_level->DownH = 100; + memory_level->VoltageDownH = 0; + + /* Indicates maximum activity level for this performance level.*/ + memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target; + memory_level->StutterEnable = 0; + memory_level->StrobeEnable = 0; + memory_level->EdcReadEnable = 0; + memory_level->EdcWriteEnable = 0; + memory_level->RttEnable = 0; + + /* default set to low watermark. Highest level will be set to high later.*/ + memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + cgs_get_active_displays_info(hwmgr->device, &info); + data->display_timing.num_existing_displays = info.display_count; + + /* stutter mode not support on ci */ + + /* decide strobe mode*/ + memory_level->StrobeEnable = (mclk_strobe_mode_threshold != 0) && + (memory_clock <= mclk_strobe_mode_threshold); + + /* decide EDC mode and memory clock ratio*/ + if (data->is_memory_gddr5) { + memory_level->StrobeRatio = ci_get_mclk_frequency_ratio(memory_clock, + memory_level->StrobeEnable); + + if ((mclk_edc_enable_threshold != 0) && + (memory_clock > mclk_edc_enable_threshold)) { + memory_level->EdcReadEnable = 1; + } + + if ((mclk_edc_wr_enable_threshold != 0) && + (memory_clock > mclk_edc_wr_enable_threshold)) { + memory_level->EdcWriteEnable = 1; + } + + if (memory_level->StrobeEnable) { + if (ci_get_mclk_frequency_ratio(memory_clock, 1) >= + ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; + else + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0; + } else + dll_state_on = data->dll_default_on; + } else { + memory_level->StrobeRatio = + ci_get_ddr3_mclk_frequency_ratio(memory_clock); + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; + } + + result = ci_calculate_mclk_params(hwmgr, + memory_clock, memory_level, memory_level->StrobeEnable, dll_state_on); + + if (0 == result) { + memory_level->MinVddc = PP_HOST_TO_SMC_UL(memory_level->MinVddc * VOLTAGE_SCALE); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinVddcPhases); + memory_level->MinVddci = PP_HOST_TO_SMC_UL(memory_level->MinVddci * VOLTAGE_SCALE); + memory_level->MinMvdd = PP_HOST_TO_SMC_UL(memory_level->MinMvdd * VOLTAGE_SCALE); + /* MCLK frequency in units of 10KHz*/ + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency); + /* Indicates maximum activity level for this performance level.*/ + CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2); + } + + return result; +} + +static int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + int result; + struct cgs_system_info sys_info = {0}; + uint32_t dev_id; + + uint32_t level_array_address = smu_data->dpm_table_start + offsetof(SMU7_Discrete_DpmTable, MemoryLevel); + uint32_t level_array_size = sizeof(SMU7_Discrete_MemoryLevel) * SMU7_MAX_LEVELS_MEMORY; + SMU7_Discrete_MemoryLevel *levels = smu_data->smc_state_table.MemoryLevel; + uint32_t i; + + memset(levels, 0x00, level_array_size); + + for (i = 0; i < dpm_table->mclk_table.count; i++) { + PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), + "can not populate memory level as memory clock is zero", return -EINVAL); + result = ci_populate_single_memory_level(hwmgr, dpm_table->mclk_table.dpm_levels[i].value, + &(smu_data->smc_state_table.MemoryLevel[i])); + if (0 != result) + return result; + } + + smu_data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1; + + sys_info.size = sizeof(struct cgs_system_info); + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; + cgs_query_system_info(hwmgr->device, &sys_info); + dev_id = (uint32_t)sys_info.value; + + if ((dpm_table->mclk_table.count >= 2) + && ((dev_id == 0x67B0) || (dev_id == 0x67B1))) { + smu_data->smc_state_table.MemoryLevel[1].MinVddci = + smu_data->smc_state_table.MemoryLevel[0].MinVddci; + smu_data->smc_state_table.MemoryLevel[1].MinMvdd = + smu_data->smc_state_table.MemoryLevel[0].MinMvdd; + } + smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F; + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel); + + smu_data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count; + data->dpm_level_enable_mask.mclk_dpm_enable_mask = phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); + smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; + + result = ci_copy_bytes_to_smc(hwmgr, + level_array_address, (uint8_t *)levels, (uint32_t)level_array_size, + SMC_RAM_END); + + return result; +} + +static int ci_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, + SMU7_Discrete_VoltageLevel *voltage) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + uint32_t i = 0; + + if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { + /* find mvdd value which clock is more than request */ + for (i = 0; i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count; i++) { + if (mclk <= hwmgr->dyn_state.mvdd_dependency_on_mclk->entries[i].clk) { + /* Always round to higher voltage. */ + voltage->Voltage = data->mvdd_voltage_table.entries[i].value; + break; + } + } + + PP_ASSERT_WITH_CODE(i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count, + "MVDD Voltage is outside the supported range.", return -EINVAL); + + } else { + return -EINVAL; + } + + return 0; +} + +static int ci_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + int result = 0; + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct pp_atomctrl_clock_dividers_vi dividers; + + SMU7_Discrete_VoltageLevel voltage_level; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; + uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; + uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; + + + /* The ACPI state should not do DPM on DC (or ever).*/ + table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; + + if (data->acpi_vddc) + table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->acpi_vddc * VOLTAGE_SCALE); + else + table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->min_vddc_in_pptable * VOLTAGE_SCALE); + + table->ACPILevel.MinVddcPhases = data->vddc_phase_shed_control ? 0 : 1; + /* assign zero for now*/ + table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr); + + /* get the engine clock dividers for this clock value*/ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, + table->ACPILevel.SclkFrequency, ÷rs); + + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", return result); + + /* divider ID for required SCLK*/ + table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; + table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + table->ACPILevel.DeepSleepDivId = 0; + + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_PWRON, 0); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_RESET, 1); + spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, + CG_SPLL_FUNC_CNTL_2, SCLK_MUX_SEL, 4); + + table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; + table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; + table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + table->ACPILevel.CcPwrDynRm = 0; + table->ACPILevel.CcPwrDynRm1 = 0; + + /* For various features to be enabled/disabled while this level is active.*/ + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); + /* SCLK frequency in units of 10KHz*/ + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); + + + /* table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;*/ + table->MemoryACPILevel.MinVddc = table->ACPILevel.MinVddc; + table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases; + + if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) + table->MemoryACPILevel.MinVddci = table->MemoryACPILevel.MinVddc; + else { + if (data->acpi_vddci != 0) + table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->acpi_vddci * VOLTAGE_SCALE); + else + table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->min_vddci_in_pptable * VOLTAGE_SCALE); + } + + if (0 == ci_populate_mvdd_value(hwmgr, 0, &voltage_level)) + table->MemoryACPILevel.MinMvdd = + PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE); + else + table->MemoryACPILevel.MinMvdd = 0; + + /* Force reset on DLL*/ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1); + + /* Disable DLL in ACPIState*/ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0); + + /* Enable DLL bypass signal*/ + dll_cntl = PHM_SET_FIELD(dll_cntl, + DLL_CNTL, MRDCK0_BYPASS, 0); + dll_cntl = PHM_SET_FIELD(dll_cntl, + DLL_CNTL, MRDCK1_BYPASS, 0); + + table->MemoryACPILevel.DllCntl = + PP_HOST_TO_SMC_UL(dll_cntl); + table->MemoryACPILevel.MclkPwrmgtCntl = + PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl); + table->MemoryACPILevel.MpllAdFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL); + table->MemoryACPILevel.MpllDqFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL); + table->MemoryACPILevel.MpllFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL); + table->MemoryACPILevel.MpllFuncCntl_1 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1); + table->MemoryACPILevel.MpllFuncCntl_2 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2); + table->MemoryACPILevel.MpllSs1 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1); + table->MemoryACPILevel.MpllSs2 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2); + + table->MemoryACPILevel.EnabledForThrottle = 0; + table->MemoryACPILevel.EnabledForActivity = 0; + table->MemoryACPILevel.UpH = 0; + table->MemoryACPILevel.DownH = 100; + table->MemoryACPILevel.VoltageDownH = 0; + /* Indicates maximum activity level for this performance level.*/ + table->MemoryACPILevel.ActivityLevel = PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); + + table->MemoryACPILevel.StutterEnable = 0; + table->MemoryACPILevel.StrobeEnable = 0; + table->MemoryACPILevel.EdcReadEnable = 0; + table->MemoryACPILevel.EdcWriteEnable = 0; + table->MemoryACPILevel.RttEnable = 0; + + return result; +} + +static int ci_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + int result = 0; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_uvd_clock_voltage_dependency_table *uvd_table = + hwmgr->dyn_state.uvd_clock_voltage_dependency_table; + + table->UvdLevelCount = (uint8_t)(uvd_table->count); + + for (count = 0; count < table->UvdLevelCount; count++) { + table->UvdLevel[count].VclkFrequency = + uvd_table->entries[count].vclk; + table->UvdLevel[count].DclkFrequency = + uvd_table->entries[count].dclk; + table->UvdLevel[count].MinVddc = + uvd_table->entries[count].v * VOLTAGE_SCALE; + table->UvdLevel[count].MinVddcPhases = 1; + + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->UvdLevel[count].VclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for Vclk clock", return result); + + table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; + + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->UvdLevel[count].DclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for Dclk clock", return result); + + table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider; + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(table->UvdLevel[count].MinVddc); + } + + return result; +} + +static int ci_populate_smc_vce_level(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_vce_clock_voltage_dependency_table *vce_table = + hwmgr->dyn_state.vce_clock_voltage_dependency_table; + + table->VceLevelCount = (uint8_t)(vce_table->count); + table->VceBootLevel = 0; + + for (count = 0; count < table->VceLevelCount; count++) { + table->VceLevel[count].Frequency = vce_table->entries[count].evclk; + table->VceLevel[count].MinVoltage = + vce_table->entries[count].v * VOLTAGE_SCALE; + table->VceLevel[count].MinPhases = 1; + + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->VceLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for VCE engine clock", + return result); + + table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_US(table->VceLevel[count].MinVoltage); + } + return result; +} + +static int ci_populate_smc_acp_level(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_acp_clock_voltage_dependency_table *acp_table = + hwmgr->dyn_state.acp_clock_voltage_dependency_table; + + table->AcpLevelCount = (uint8_t)(acp_table->count); + table->AcpBootLevel = 0; + + for (count = 0; count < table->AcpLevelCount; count++) { + table->AcpLevel[count].Frequency = acp_table->entries[count].acpclk; + table->AcpLevel[count].MinVoltage = acp_table->entries[count].v; + table->AcpLevel[count].MinPhases = 1; + + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->AcpLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for engine clock", return result); + + table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_US(table->AcpLevel[count].MinVoltage); + } + return result; +} + +static int ci_populate_smc_samu_level(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_samu_clock_voltage_dependency_table *samu_table = + hwmgr->dyn_state.samu_clock_voltage_dependency_table; + + table->SamuBootLevel = 0; + table->SamuLevelCount = (uint8_t)(samu_table->count); + + for (count = 0; count < table->SamuLevelCount; count++) { + table->SamuLevel[count].Frequency = samu_table->entries[count].samclk; + table->SamuLevel[count].MinVoltage = samu_table->entries[count].v * VOLTAGE_SCALE; + table->SamuLevel[count].MinPhases = 1; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->SamuLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for samu clock", return result); + + table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_US(table->SamuLevel[count].MinVoltage); + } + return result; +} + +static int ci_populate_memory_timing_parameters( + struct pp_hwmgr *hwmgr, + uint32_t engine_clock, + uint32_t memory_clock, + struct SMU7_Discrete_MCArbDramTimingTableEntry *arb_regs + ) +{ + uint32_t dramTiming; + uint32_t dramTiming2; + uint32_t burstTime; + int result; + + result = atomctrl_set_engine_dram_timings_rv770(hwmgr, + engine_clock, memory_clock); + + PP_ASSERT_WITH_CODE(result == 0, + "Error calling VBIOS to set DRAM_TIMING.", return result); + + dramTiming = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); + dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); + burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); + + arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dramTiming); + arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2); + arb_regs->McArbBurstTime = (uint8_t)burstTime; + + return 0; +} + +static int ci_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + int result = 0; + SMU7_Discrete_MCArbDramTimingTable arb_regs; + uint32_t i, j; + + memset(&arb_regs, 0x00, sizeof(SMU7_Discrete_MCArbDramTimingTable)); + + for (i = 0; i < data->dpm_table.sclk_table.count; i++) { + for (j = 0; j < data->dpm_table.mclk_table.count; j++) { + result = ci_populate_memory_timing_parameters + (hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value, + data->dpm_table.mclk_table.dpm_levels[j].value, + &arb_regs.entries[i][j]); + + if (0 != result) + break; + } + } + + if (0 == result) { + result = ci_copy_bytes_to_smc( + hwmgr, + smu_data->arb_table_start, + (uint8_t *)&arb_regs, + sizeof(SMU7_Discrete_MCArbDramTimingTable), + SMC_RAM_END + ); + } + + return result; +} + +static int ci_populate_smc_boot_level(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + + table->GraphicsBootLevel = 0; + table->MemoryBootLevel = 0; + + /* find boot level from dpm table*/ + result = phm_find_boot_level(&(data->dpm_table.sclk_table), + data->vbios_boot_state.sclk_bootup_value, + (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); + + if (0 != result) { + smu_data->smc_state_table.GraphicsBootLevel = 0; + pr_err("VBIOS did not find boot engine clock value \ + in dependency table. Using Graphics DPM level 0!"); + result = 0; + } + + result = phm_find_boot_level(&(data->dpm_table.mclk_table), + data->vbios_boot_state.mclk_bootup_value, + (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); + + if (0 != result) { + smu_data->smc_state_table.MemoryBootLevel = 0; + pr_err("VBIOS did not find boot engine clock value \ + in dependency table. Using Memory DPM level 0!"); + result = 0; + } + + table->BootVddc = data->vbios_boot_state.vddc_bootup_value; + table->BootVddci = data->vbios_boot_state.vddci_bootup_value; + table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value; + + return result; +} + +static int ci_populate_mc_reg_address(struct pp_hwmgr *hwmgr, + SMU7_Discrete_MCRegisters *mc_reg_table) +{ + const struct ci_smumgr *smu_data = (struct ci_smumgr *)hwmgr->smu_backend; + + uint32_t i, j; + + for (i = 0, j = 0; j < smu_data->mc_reg_table.last; j++) { + if (smu_data->mc_reg_table.validflag & 1<address[] array out of boundary", return -EINVAL); + mc_reg_table->address[i].s0 = + PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s0); + mc_reg_table->address[i].s1 = + PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s1); + i++; + } + } + + mc_reg_table->last = (uint8_t)i; + + return 0; +} + +static void ci_convert_mc_registers( + const struct ci_mc_reg_entry *entry, + SMU7_Discrete_MCRegisterSet *data, + uint32_t num_entries, uint32_t valid_flag) +{ + uint32_t i, j; + + for (i = 0, j = 0; j < num_entries; j++) { + if (valid_flag & 1<value[i] = PP_HOST_TO_SMC_UL(entry->mc_data[j]); + i++; + } + } +} + +static int ci_convert_mc_reg_table_entry_to_smc( + struct pp_hwmgr *hwmgr, + const uint32_t memory_clock, + SMU7_Discrete_MCRegisterSet *mc_reg_table_data + ) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + uint32_t i = 0; + + for (i = 0; i < smu_data->mc_reg_table.num_entries; i++) { + if (memory_clock <= + smu_data->mc_reg_table.mc_reg_table_entry[i].mclk_max) { + break; + } + } + + if ((i == smu_data->mc_reg_table.num_entries) && (i > 0)) + --i; + + ci_convert_mc_registers(&smu_data->mc_reg_table.mc_reg_table_entry[i], + mc_reg_table_data, smu_data->mc_reg_table.last, + smu_data->mc_reg_table.validflag); + + return 0; +} + +static int ci_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr, + SMU7_Discrete_MCRegisters *mc_regs) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int res; + uint32_t i; + + for (i = 0; i < data->dpm_table.mclk_table.count; i++) { + res = ci_convert_mc_reg_table_entry_to_smc( + hwmgr, + data->dpm_table.mclk_table.dpm_levels[i].value, + &mc_regs->data[i] + ); + + if (0 != res) + result = res; + } + + return result; +} + +static int ci_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t address; + int32_t result; + + if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) + return 0; + + + memset(&smu_data->mc_regs, 0, sizeof(SMU7_Discrete_MCRegisters)); + + result = ci_convert_mc_reg_table_to_smc(hwmgr, &(smu_data->mc_regs)); + + if (result != 0) + return result; + + address = smu_data->mc_reg_table_start + (uint32_t)offsetof(SMU7_Discrete_MCRegisters, data[0]); + + return ci_copy_bytes_to_smc(hwmgr, address, + (uint8_t *)&smu_data->mc_regs.data[0], + sizeof(SMU7_Discrete_MCRegisterSet) * data->dpm_table.mclk_table.count, + SMC_RAM_END); +} + +static int ci_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + + memset(&smu_data->mc_regs, 0x00, sizeof(SMU7_Discrete_MCRegisters)); + result = ci_populate_mc_reg_address(hwmgr, &(smu_data->mc_regs)); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize MCRegTable for the MC register addresses!", return result;); + + result = ci_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize MCRegTable for driver state!", return result;); + + return ci_copy_bytes_to_smc(hwmgr, smu_data->mc_reg_table_start, + (uint8_t *)&smu_data->mc_regs, sizeof(SMU7_Discrete_MCRegisters), SMC_RAM_END); +} + +static int ci_populate_smc_initial_state(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + uint8_t count, level; + + count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->count); + + for (level = 0; level < count; level++) { + if (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[level].clk + >= data->vbios_boot_state.sclk_bootup_value) { + smu_data->smc_state_table.GraphicsBootLevel = level; + break; + } + } + + count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_mclk->count); + + for (level = 0; level < count; level++) { + if (hwmgr->dyn_state.vddc_dependency_on_mclk->entries[level].clk + >= data->vbios_boot_state.mclk_bootup_value) { + smu_data->smc_state_table.MemoryBootLevel = level; + break; + } + } + + return 0; +} + +static int ci_populate_smc_svi2_config(struct pp_hwmgr *hwmgr, + SMU7_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) + table->SVI2Enable = 1; + else + table->SVI2Enable = 0; + return 0; +} + +static int ci_start_smc(struct pp_hwmgr *hwmgr) +{ + /* set smc instruct start point at 0x0 */ + ci_program_jump_on_start(hwmgr); + + /* enable smc clock */ + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); + + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 0); + + PHM_WAIT_INDIRECT_FIELD(hwmgr, SMC_IND, FIRMWARE_FLAGS, + INTERRUPTS_ENABLED, 1); + + return 0; +} + +static int ci_init_smc_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + SMU7_Discrete_DpmTable *table = &(smu_data->smc_state_table); + struct pp_atomctrl_gpio_pin_assignment gpio_pin; + u32 i; + + ci_initialize_power_tune_defaults(hwmgr); + memset(&(smu_data->smc_state_table), 0x00, sizeof(smu_data->smc_state_table)); + + if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) + ci_populate_smc_voltage_tables(hwmgr, table); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; + + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StepVddc)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; + + if (data->is_memory_gddr5) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; + + if (data->ulv_supported) { + result = ci_populate_ulv_state(hwmgr, &(table->Ulv)); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ULV state!", return result); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixCG_ULV_PARAMETER, 0x40035); + } + + result = ci_populate_all_graphic_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Graphics Level!", return result); + + result = ci_populate_all_memory_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Memory Level!", return result); + + result = ci_populate_smc_link_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Link Level!", return result); + + result = ci_populate_smc_acpi_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ACPI Level!", return result); + + result = ci_populate_smc_vce_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize VCE Level!", return result); + + result = ci_populate_smc_acp_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ACP Level!", return result); + + result = ci_populate_smc_samu_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize SAMU Level!", return result); + + /* Since only the initial state is completely set up at this point (the other states are just copies of the boot state) we only */ + /* need to populate the ARB settings for the initial state. */ + result = ci_program_memory_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to Write ARB settings for the initial state.", return result); + + result = ci_populate_smc_uvd_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize UVD Level!", return result); + + table->UvdBootLevel = 0; + table->VceBootLevel = 0; + table->AcpBootLevel = 0; + table->SamuBootLevel = 0; + + table->GraphicsBootLevel = 0; + table->MemoryBootLevel = 0; + + result = ci_populate_smc_boot_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Boot Level!", return result); + + result = ci_populate_smc_initial_state(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, "Failed to initialize Boot State!", return result); + + result = ci_populate_bapm_parameters_in_dpm_table(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, "Failed to populate BAPM Parameters!", return result); + + table->UVDInterval = 1; + table->VCEInterval = 1; + table->ACPInterval = 1; + table->SAMUInterval = 1; + table->GraphicsVoltageChangeEnable = 1; + table->GraphicsThermThrottleEnable = 1; + table->GraphicsInterval = 1; + table->VoltageInterval = 1; + table->ThermalInterval = 1; + + table->TemperatureLimitHigh = + (data->thermal_temp_setting.temperature_high * + SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + table->TemperatureLimitLow = + (data->thermal_temp_setting.temperature_low * + SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + + table->MemoryVoltageChangeEnable = 1; + table->MemoryInterval = 1; + table->VoltageResponseTime = 0; + table->VddcVddciDelta = 4000; + table->PhaseResponseTime = 0; + table->MemoryThermThrottleEnable = 1; + + PP_ASSERT_WITH_CODE((1 <= data->dpm_table.pcie_speed_table.count), + "There must be 1 or more PCIE levels defined in PPTable.", + return -EINVAL); + + table->PCIeBootLinkLevel = (uint8_t)data->dpm_table.pcie_speed_table.count; + table->PCIeGenInterval = 1; + + ci_populate_smc_svi2_config(hwmgr, table); + + for (i = 0; i < SMU7_MAX_ENTRIES_SMIO; i++) + CONVERT_FROM_HOST_TO_SMC_UL(table->Smio[i]); + + table->ThermGpio = 17; + table->SclkStepSize = 0x4000; + if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) { + table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift; + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot); + } else { + table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot); + } + + table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; + + CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcVid); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcPhase); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddciVid); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskMvddVid); + CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); + table->VddcVddciDelta = PP_HOST_TO_SMC_US(table->VddcVddciDelta); + CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); + CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); + + table->BootVddc = PP_HOST_TO_SMC_US(table->BootVddc * VOLTAGE_SCALE); + table->BootVddci = PP_HOST_TO_SMC_US(table->BootVddci * VOLTAGE_SCALE); + table->BootMVdd = PP_HOST_TO_SMC_US(table->BootMVdd * VOLTAGE_SCALE); + + /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ + result = ci_copy_bytes_to_smc(hwmgr, smu_data->dpm_table_start + + offsetof(SMU7_Discrete_DpmTable, SystemFlags), + (uint8_t *)&(table->SystemFlags), + sizeof(SMU7_Discrete_DpmTable)-3 * sizeof(SMU7_PIDController), + SMC_RAM_END); + + PP_ASSERT_WITH_CODE(0 == result, + "Failed to upload dpm data to SMC memory!", return result;); + + result = ci_populate_initial_mc_reg_table(hwmgr); + PP_ASSERT_WITH_CODE((0 == result), + "Failed to populate initialize MC Reg table!", return result); + + result = ci_populate_pm_fuses(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate PM fuses to SMC memory!", return result); + + ci_start_smc(hwmgr); + + return 0; +} + +static int ci_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) +{ + struct ci_smumgr *ci_data = (struct ci_smumgr *)(hwmgr->smu_backend); + SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; + uint32_t duty100; + uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; + uint16_t fdo_min, slope1, slope2; + uint32_t reference_clock; + int res; + uint64_t tmp64; + + if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) + return 0; + + if (hwmgr->thermal_controller.fanInfo.bNoFan) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + if (0 == ci_data->fan_table_start) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100); + + if (0 == duty100) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100; + do_div(tmp64, 10000); + fdo_min = (uint16_t)tmp64; + + t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - hwmgr->thermal_controller.advanceFanControlParameters.usTMin; + t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - hwmgr->thermal_controller.advanceFanControlParameters.usTMed; + + pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; + pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; + + slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); + slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + + fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100); + fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100); + fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100); + + fan_table.Slope1 = cpu_to_be16(slope1); + fan_table.Slope2 = cpu_to_be16(slope2); + + fan_table.FdoMin = cpu_to_be16(fdo_min); + + fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst); + + fan_table.HystUp = cpu_to_be16(1); + + fan_table.HystSlope = cpu_to_be16(1); + + fan_table.TempRespLim = cpu_to_be16(5); + + reference_clock = smu7_get_xclk(hwmgr); + + fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600); + + fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); + + fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL); + + res = ci_copy_bytes_to_smc(hwmgr, ci_data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), SMC_RAM_END); + + return 0; +} + +static int ci_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (data->need_update_smu7_dpm_table & + (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) + return ci_program_memory_timing_parameters(hwmgr); + + return 0; +} + +static int ci_update_sclk_threshold(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + + int result = 0; + uint32_t low_sclk_interrupt_threshold = 0; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkThrottleLowNotification) + && (hwmgr->gfx_arbiter.sclk_threshold != + data->low_sclk_interrupt_threshold)) { + data->low_sclk_interrupt_threshold = + hwmgr->gfx_arbiter.sclk_threshold; + low_sclk_interrupt_threshold = + data->low_sclk_interrupt_threshold; + + CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); + + result = ci_copy_bytes_to_smc( + hwmgr, + smu_data->dpm_table_start + + offsetof(SMU7_Discrete_DpmTable, + LowSclkInterruptT), + (uint8_t *)&low_sclk_interrupt_threshold, + sizeof(uint32_t), + SMC_RAM_END); + } + + result = ci_update_and_upload_mc_reg_table(hwmgr); + + PP_ASSERT_WITH_CODE((0 == result), "Failed to upload MC reg table!", return result); + + result = ci_program_mem_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE((result == 0), + "Failed to program memory timing parameters!", + ); + + return result; +} + +static uint32_t ci_get_offsetof(uint32_t type, uint32_t member) +{ + switch (type) { + case SMU_SoftRegisters: + switch (member) { + case HandshakeDisables: + return offsetof(SMU7_SoftRegisters, HandshakeDisables); + case VoltageChangeTimeout: + return offsetof(SMU7_SoftRegisters, VoltageChangeTimeout); + case AverageGraphicsActivity: + return offsetof(SMU7_SoftRegisters, AverageGraphicsA); + case PreVBlankGap: + return offsetof(SMU7_SoftRegisters, PreVBlankGap); + case VBlankTimeout: + return offsetof(SMU7_SoftRegisters, VBlankTimeout); + case DRAM_LOG_ADDR_H: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU7_SoftRegisters, DRAM_LOG_BUFF_SIZE); + } + case SMU_Discrete_DpmTable: + switch (member) { + case LowSclkInterruptThreshold: + return offsetof(SMU7_Discrete_DpmTable, LowSclkInterruptT); + } + } + pr_debug("can't get the offset of type %x member %x\n", type, member); + return 0; +} + +static uint32_t ci_get_mac_definition(uint32_t value) +{ + switch (value) { + case SMU_MAX_LEVELS_GRAPHICS: + return SMU7_MAX_LEVELS_GRAPHICS; + case SMU_MAX_LEVELS_MEMORY: + return SMU7_MAX_LEVELS_MEMORY; + case SMU_MAX_LEVELS_LINK: + return SMU7_MAX_LEVELS_LINK; + case SMU_MAX_ENTRIES_SMIO: + return SMU7_MAX_ENTRIES_SMIO; + case SMU_MAX_LEVELS_VDDC: + return SMU7_MAX_LEVELS_VDDC; + case SMU_MAX_LEVELS_VDDCI: + return SMU7_MAX_LEVELS_VDDCI; + case SMU_MAX_LEVELS_MVDD: + return SMU7_MAX_LEVELS_MVDD; + } + + pr_debug("can't get the mac of %x\n", value); + return 0; +} + +static int ci_load_smc_ucode(struct pp_hwmgr *hwmgr) +{ + uint32_t byte_count, start_addr; + uint8_t *src; + uint32_t data; + + struct cgs_firmware_info info = {0}; + + cgs_get_firmware_info(hwmgr->device, CGS_UCODE_ID_SMU, &info); + + hwmgr->is_kicker = info.is_kicker; + byte_count = info.image_size; + src = (uint8_t *)info.kptr; + start_addr = info.ucode_start_address; + + if (byte_count > SMC_RAM_END) { + pr_err("SMC address is beyond the SMC RAM area.\n"); + return -EINVAL; + } + + cgs_write_register(hwmgr->device, mmSMC_IND_INDEX_0, start_addr); + PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1); + + for (; byte_count >= 4; byte_count -= 4) { + data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; + cgs_write_register(hwmgr->device, mmSMC_IND_DATA_0, data); + src += 4; + } + PHM_WRITE_FIELD(hwmgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); + + if (0 != byte_count) { + pr_err("SMC size must be divisible by 4\n"); + return -EINVAL; + } + + return 0; +} + +static int ci_upload_firmware(struct pp_hwmgr *hwmgr) +{ + if (ci_is_smc_ram_running(hwmgr)) { + pr_info("smc is running, no need to load smc firmware\n"); + return 0; + } + PHM_WAIT_INDIRECT_FIELD(hwmgr, SMC_IND, RCU_UC_EVENTS, + boot_seq_done, 1); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_MISC_CNTL, + pre_fetcher_en, 1); + + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 1); + return ci_load_smc_ucode(hwmgr); +} + +static int ci_process_firmware_header(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct ci_smumgr *ci_data = (struct ci_smumgr *)(hwmgr->smu_backend); + + uint32_t tmp = 0; + int result; + bool error = false; + + if (ci_upload_firmware(hwmgr)) + return -EINVAL; + + result = ci_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU7_Firmware_Header, DpmTable), + &tmp, SMC_RAM_END); + + if (0 == result) + ci_data->dpm_table_start = tmp; + + error |= (0 != result); + + result = ci_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU7_Firmware_Header, SoftRegisters), + &tmp, SMC_RAM_END); + + if (0 == result) { + data->soft_regs_start = tmp; + ci_data->soft_regs_start = tmp; + } + + error |= (0 != result); + + result = ci_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU7_Firmware_Header, mcRegisterTable), + &tmp, SMC_RAM_END); + + if (0 == result) + ci_data->mc_reg_table_start = tmp; + + result = ci_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU7_Firmware_Header, FanTable), + &tmp, SMC_RAM_END); + + if (0 == result) + ci_data->fan_table_start = tmp; + + error |= (0 != result); + + result = ci_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU7_Firmware_Header, mcArbDramTimingTable), + &tmp, SMC_RAM_END); + + if (0 == result) + ci_data->arb_table_start = tmp; + + error |= (0 != result); + + result = ci_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU7_Firmware_Header, Version), + &tmp, SMC_RAM_END); + + if (0 == result) + hwmgr->microcode_version_info.SMC = tmp; + + error |= (0 != result); + + return error ? 1 : 0; +} + +static uint8_t ci_get_memory_modile_index(struct pp_hwmgr *hwmgr) +{ + return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16)); +} + +static bool ci_check_s0_mc_reg_index(uint16_t in_reg, uint16_t *out_reg) +{ + bool result = true; + + switch (in_reg) { + case mmMC_SEQ_RAS_TIMING: + *out_reg = mmMC_SEQ_RAS_TIMING_LP; + break; + + case mmMC_SEQ_DLL_STBY: + *out_reg = mmMC_SEQ_DLL_STBY_LP; + break; + + case mmMC_SEQ_G5PDX_CMD0: + *out_reg = mmMC_SEQ_G5PDX_CMD0_LP; + break; + + case mmMC_SEQ_G5PDX_CMD1: + *out_reg = mmMC_SEQ_G5PDX_CMD1_LP; + break; + + case mmMC_SEQ_G5PDX_CTRL: + *out_reg = mmMC_SEQ_G5PDX_CTRL_LP; + break; + + case mmMC_SEQ_CAS_TIMING: + *out_reg = mmMC_SEQ_CAS_TIMING_LP; + break; + + case mmMC_SEQ_MISC_TIMING: + *out_reg = mmMC_SEQ_MISC_TIMING_LP; + break; + + case mmMC_SEQ_MISC_TIMING2: + *out_reg = mmMC_SEQ_MISC_TIMING2_LP; + break; + + case mmMC_SEQ_PMG_DVS_CMD: + *out_reg = mmMC_SEQ_PMG_DVS_CMD_LP; + break; + + case mmMC_SEQ_PMG_DVS_CTL: + *out_reg = mmMC_SEQ_PMG_DVS_CTL_LP; + break; + + case mmMC_SEQ_RD_CTL_D0: + *out_reg = mmMC_SEQ_RD_CTL_D0_LP; + break; + + case mmMC_SEQ_RD_CTL_D1: + *out_reg = mmMC_SEQ_RD_CTL_D1_LP; + break; + + case mmMC_SEQ_WR_CTL_D0: + *out_reg = mmMC_SEQ_WR_CTL_D0_LP; + break; + + case mmMC_SEQ_WR_CTL_D1: + *out_reg = mmMC_SEQ_WR_CTL_D1_LP; + break; + + case mmMC_PMG_CMD_EMRS: + *out_reg = mmMC_SEQ_PMG_CMD_EMRS_LP; + break; + + case mmMC_PMG_CMD_MRS: + *out_reg = mmMC_SEQ_PMG_CMD_MRS_LP; + break; + + case mmMC_PMG_CMD_MRS1: + *out_reg = mmMC_SEQ_PMG_CMD_MRS1_LP; + break; + + case mmMC_SEQ_PMG_TIMING: + *out_reg = mmMC_SEQ_PMG_TIMING_LP; + break; + + case mmMC_PMG_CMD_MRS2: + *out_reg = mmMC_SEQ_PMG_CMD_MRS2_LP; + break; + + case mmMC_SEQ_WR_CTL_2: + *out_reg = mmMC_SEQ_WR_CTL_2_LP; + break; + + default: + result = false; + break; + } + + return result; +} + +static int ci_set_s0_mc_reg_index(struct ci_mc_reg_table *table) +{ + uint32_t i; + uint16_t address; + + for (i = 0; i < table->last; i++) { + table->mc_reg_address[i].s0 = + ci_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) + ? address : table->mc_reg_address[i].s1; + } + return 0; +} + +static int ci_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, + struct ci_mc_reg_table *ni_table) +{ + uint8_t i, j; + + PP_ASSERT_WITH_CODE((table->last <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES), + "Invalid VramInfo table.", return -EINVAL); + + for (i = 0; i < table->last; i++) + ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1; + + ni_table->last = table->last; + + for (i = 0; i < table->num_entries; i++) { + ni_table->mc_reg_table_entry[i].mclk_max = + table->mc_reg_table_entry[i].mclk_max; + for (j = 0; j < table->last; j++) { + ni_table->mc_reg_table_entry[i].mc_data[j] = + table->mc_reg_table_entry[i].mc_data[j]; + } + } + + ni_table->num_entries = table->num_entries; + + return 0; +} + +static int ci_set_mc_special_registers(struct pp_hwmgr *hwmgr, + struct ci_mc_reg_table *table) +{ + uint8_t i, j, k; + uint32_t temp_reg; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + for (i = 0, j = table->last; i < table->last; i++) { + PP_ASSERT_WITH_CODE((j < SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + switch (table->mc_reg_address[i].s1) { + + case mmMC_SEQ_MISC1: + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + ((temp_reg & 0xffff0000)) | + ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16); + } + j++; + PP_ASSERT_WITH_CODE((j < SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (temp_reg & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + + if (!data->is_memory_gddr5) + table->mc_reg_table_entry[k].mc_data[j] |= 0x100; + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + if (!data->is_memory_gddr5 && j < SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE) { + table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD; + table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16; + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + } + + break; + + case mmMC_SEQ_RESERVE_M: + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (temp_reg & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + break; + + default: + break; + } + + } + + table->last = j; + + return 0; +} + +static int ci_set_valid_flag(struct ci_mc_reg_table *table) +{ + uint8_t i, j; + + for (i = 0; i < table->last; i++) { + for (j = 1; j < table->num_entries; j++) { + if (table->mc_reg_table_entry[j-1].mc_data[i] != + table->mc_reg_table_entry[j].mc_data[i]) { + table->validflag |= (1 << i); + break; + } + } + } + + return 0; +} + +static int ci_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct ci_smumgr *smu_data = (struct ci_smumgr *)(hwmgr->smu_backend); + pp_atomctrl_mc_reg_table *table; + struct ci_mc_reg_table *ni_table = &smu_data->mc_reg_table; + uint8_t module_index = ci_get_memory_modile_index(hwmgr); + + table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); + + if (NULL == table) + return -ENOMEM; + + /* Program additional LP registers that are no longer programmed by VBIOS */ + cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL)); + cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2)); + + memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table)); + + result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); + + if (0 == result) + result = ci_copy_vbios_smc_reg_table(table, ni_table); + + if (0 == result) { + ci_set_s0_mc_reg_index(ni_table); + result = ci_set_mc_special_registers(hwmgr, ni_table); + } + + if (0 == result) + ci_set_valid_flag(ni_table); + + kfree(table); + + return result; +} + +static bool ci_is_dpm_running(struct pp_hwmgr *hwmgr) +{ + return ci_is_smc_ram_running(hwmgr); +} + +static int ci_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, + struct amd_pp_profile *request) +{ + struct ci_smumgr *smu_data = (struct ci_smumgr *) + (hwmgr->smu_backend); + struct SMU7_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t array = smu_data->dpm_table_start + + offsetof(SMU7_Discrete_DpmTable, GraphicsLevel); + uint32_t array_size = sizeof(struct SMU7_Discrete_GraphicsLevel) * + SMU7_MAX_LEVELS_GRAPHICS; + uint32_t i; + + for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { + levels[i].ActivityLevel = + cpu_to_be16(request->activity_threshold); + levels[i].EnabledForActivity = 1; + levels[i].UpH = request->up_hyst; + levels[i].DownH = request->down_hyst; + } + + return ci_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + array_size, SMC_RAM_END); +} + + +static int ci_smu_init(struct pp_hwmgr *hwmgr) +{ + int i; + struct ci_smumgr *ci_priv = NULL; + + ci_priv = kzalloc(sizeof(struct ci_smumgr), GFP_KERNEL); + + if (ci_priv == NULL) + return -ENOMEM; + + for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) + ci_priv->activity_target[i] = 30; + + hwmgr->smu_backend = ci_priv; + + return 0; +} + +static int ci_smu_fini(struct pp_hwmgr *hwmgr) +{ + kfree(hwmgr->smu_backend); + hwmgr->smu_backend = NULL; + cgs_rel_firmware(hwmgr->device, CGS_UCODE_ID_SMU); + return 0; +} + +static int ci_start_smu(struct pp_hwmgr *hwmgr) +{ + return 0; +} + +const struct pp_smumgr_func ci_smu_funcs = { + .smu_init = ci_smu_init, + .smu_fini = ci_smu_fini, + .start_smu = ci_start_smu, + .check_fw_load_finish = NULL, + .request_smu_load_fw = NULL, + .request_smu_load_specific_fw = NULL, + .send_msg_to_smc = ci_send_msg_to_smc, + .send_msg_to_smc_with_parameter = ci_send_msg_to_smc_with_parameter, + .download_pptable_settings = NULL, + .upload_pptable_settings = NULL, + .get_offsetof = ci_get_offsetof, + .process_firmware_header = ci_process_firmware_header, + .init_smc_table = ci_init_smc_table, + .update_sclk_threshold = ci_update_sclk_threshold, + .thermal_setup_fan_table = ci_thermal_setup_fan_table, + .populate_all_graphic_levels = ci_populate_all_graphic_levels, + .populate_all_memory_levels = ci_populate_all_memory_levels, + .get_mac_definition = ci_get_mac_definition, + .initialize_mc_reg_table = ci_initialize_mc_reg_table, + .is_dpm_running = ci_is_dpm_running, + .populate_requested_graphic_levels = ci_populate_requested_graphic_levels, +}; -- cgit v1.2.3 From 2e112b4ae3ba2f40ea3758eb29d9658908b0e2fe Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 15:37:32 +0800 Subject: drm/amd/pp: remove fiji_smc/smumgr split. make all functions in fiji_smumgr.c static and exported by pp_smumgr_func table. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/Makefile | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c | 2496 -------------------- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h | 53 - drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 2379 ++++++++++++++++++- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h | 9 + 5 files changed, 2381 insertions(+), 2558 deletions(-) delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile index d7be7834173f..ec8229e0e9d0 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile @@ -2,7 +2,7 @@ # Makefile for the 'smu manager' sub-component of powerplay. # It provides the smu management services for the driver. -SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o fiji_smc.o \ +SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o \ polaris10_smumgr.o iceland_smumgr.o polaris10_smc.o tonga_smc.o \ smu7_smumgr.o iceland_smc.o vega10_smumgr.o rv_smumgr.o ci_smumgr.o diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c deleted file mode 100644 index e130b77e35c5..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c +++ /dev/null @@ -1,2496 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "pp_debug.h" -#include "fiji_smc.h" -#include "smu7_dyn_defaults.h" - -#include "smu7_hwmgr.h" -#include "hardwaremanager.h" -#include "ppatomctrl.h" -#include "cgs_common.h" -#include "atombios.h" -#include "fiji_smumgr.h" -#include "pppcielanes.h" -#include "smu7_ppsmc.h" -#include "smu73.h" -#include "smu/smu_7_1_3_d.h" -#include "smu/smu_7_1_3_sh_mask.h" -#include "gmc/gmc_8_1_d.h" -#include "gmc/gmc_8_1_sh_mask.h" -#include "bif/bif_5_0_d.h" -#include "bif/bif_5_0_sh_mask.h" -#include "dce/dce_10_0_d.h" -#include "dce/dce_10_0_sh_mask.h" -#include "smu7_smumgr.h" - -#define VOLTAGE_SCALE 4 -#define POWERTUNE_DEFAULT_SET_MAX 1 -#define VOLTAGE_VID_OFFSET_SCALE1 625 -#define VOLTAGE_VID_OFFSET_SCALE2 100 -#define VDDC_VDDCI_DELTA 300 -#define MC_CG_ARB_FREQ_F1 0x0b - -/* [2.5%,~2.5%] Clock stretched is multiple of 2.5% vs - * not and [Fmin, Fmax, LDO_REFSEL, USE_FOR_LOW_FREQ] - */ -static const uint16_t fiji_clock_stretcher_lookup_table[2][4] = { - {600, 1050, 3, 0}, {600, 1050, 6, 1} }; - -/* [FF, SS] type, [] 4 voltage ranges, and - * [Floor Freq, Boundary Freq, VID min , VID max] - */ -static const uint32_t fiji_clock_stretcher_ddt_table[2][4][4] = { - { {265, 529, 120, 128}, {325, 650, 96, 119}, {430, 860, 32, 95}, {0, 0, 0, 31} }, - { {275, 550, 104, 112}, {319, 638, 96, 103}, {360, 720, 64, 95}, {384, 768, 32, 63} } }; - -/* [Use_For_Low_freq] value, [0%, 5%, 10%, 7.14%, 14.28%, 20%] - * (coming from PWR_CKS_CNTL.stretch_amount reg spec) - */ -static const uint8_t fiji_clock_stretch_amount_conversion[2][6] = { - {0, 1, 3, 2, 4, 5}, {0, 2, 4, 5, 6, 5} }; - -static const struct fiji_pt_defaults fiji_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { - /*sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc */ - {1, 0xF, 0xFD, - /* TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase */ - 0x19, 5, 45} -}; - -/* PPGen has the gain setting generated in x * 100 unit - * This function is to convert the unit to x * 4096(0x1000) unit. - * This is the unit expected by SMC firmware - */ -static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, - struct phm_ppt_v1_clock_voltage_dependency_table *dep_table, - uint32_t clock, uint32_t *voltage, uint32_t *mvdd) -{ - uint32_t i; - uint16_t vddci; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - *voltage = *mvdd = 0; - - - /* clock - voltage dependency table is empty table */ - if (dep_table->count == 0) - return -EINVAL; - - for (i = 0; i < dep_table->count; i++) { - /* find first sclk bigger than request */ - if (dep_table->entries[i].clk >= clock) { - *voltage |= (dep_table->entries[i].vddc * - VOLTAGE_SCALE) << VDDC_SHIFT; - if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) - *voltage |= (data->vbios_boot_state.vddci_bootup_value * - VOLTAGE_SCALE) << VDDCI_SHIFT; - else if (dep_table->entries[i].vddci) - *voltage |= (dep_table->entries[i].vddci * - VOLTAGE_SCALE) << VDDCI_SHIFT; - else { - vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), - (dep_table->entries[i].vddc - - VDDC_VDDCI_DELTA)); - *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; - } - - if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) - *mvdd = data->vbios_boot_state.mvdd_bootup_value * - VOLTAGE_SCALE; - else if (dep_table->entries[i].mvdd) - *mvdd = (uint32_t) dep_table->entries[i].mvdd * - VOLTAGE_SCALE; - - *voltage |= 1 << PHASES_SHIFT; - return 0; - } - } - - /* sclk is bigger than max sclk in the dependence table */ - *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; - - if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) - *voltage |= (data->vbios_boot_state.vddci_bootup_value * - VOLTAGE_SCALE) << VDDCI_SHIFT; - else if (dep_table->entries[i-1].vddci) { - vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), - (dep_table->entries[i].vddc - - VDDC_VDDCI_DELTA)); - *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; - } - - if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) - *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE; - else if (dep_table->entries[i].mvdd) - *mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE; - - return 0; -} - - -static uint16_t scale_fan_gain_settings(uint16_t raw_setting) -{ - uint32_t tmp; - tmp = raw_setting * 4096 / 100; - return (uint16_t)tmp; -} - -static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t *sda) -{ - switch (line) { - case SMU7_I2CLineID_DDC1: - *scl = SMU7_I2C_DDC1CLK; - *sda = SMU7_I2C_DDC1DATA; - break; - case SMU7_I2CLineID_DDC2: - *scl = SMU7_I2C_DDC2CLK; - *sda = SMU7_I2C_DDC2DATA; - break; - case SMU7_I2CLineID_DDC3: - *scl = SMU7_I2C_DDC3CLK; - *sda = SMU7_I2C_DDC3DATA; - break; - case SMU7_I2CLineID_DDC4: - *scl = SMU7_I2C_DDC4CLK; - *sda = SMU7_I2C_DDC4DATA; - break; - case SMU7_I2CLineID_DDC5: - *scl = SMU7_I2C_DDC5CLK; - *sda = SMU7_I2C_DDC5DATA; - break; - case SMU7_I2CLineID_DDC6: - *scl = SMU7_I2C_DDC6CLK; - *sda = SMU7_I2C_DDC6DATA; - break; - case SMU7_I2CLineID_SCLSDA: - *scl = SMU7_I2C_SCL; - *sda = SMU7_I2C_SDA; - break; - case SMU7_I2CLineID_DDCVGA: - *scl = SMU7_I2C_DDCVGACLK; - *sda = SMU7_I2C_DDCVGADATA; - break; - default: - *scl = 0; - *sda = 0; - break; - } -} - -static void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - if (table_info && - table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && - table_info->cac_dtp_table->usPowerTuneDataSetID) - smu_data->power_tune_defaults = - &fiji_power_tune_data_set_array - [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; - else - smu_data->power_tune_defaults = &fiji_power_tune_data_set_array[0]; - -} - -static int fiji_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) -{ - - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; - - SMU73_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); - - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; - struct pp_advance_fan_control_parameters *fan_table = - &hwmgr->thermal_controller.advanceFanControlParameters; - uint8_t uc_scl, uc_sda; - - /* TDP number of fraction bits are changed from 8 to 7 for Fiji - * as requested by SMC team - */ - dpm_table->DefaultTdp = PP_HOST_TO_SMC_US( - (uint16_t)(cac_dtp_table->usTDP * 128)); - dpm_table->TargetTdp = PP_HOST_TO_SMC_US( - (uint16_t)(cac_dtp_table->usTDP * 128)); - - PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, - "Target Operating Temp is out of Range!", - ); - - dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp); - dpm_table->GpuTjHyst = 8; - - dpm_table->DTEAmbientTempBase = defaults->DTEAmbientTempBase; - - /* The following are for new Fiji Multi-input fan/thermal control */ - dpm_table->TemperatureLimitEdge = PP_HOST_TO_SMC_US( - cac_dtp_table->usTargetOperatingTemp * 256); - dpm_table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US( - cac_dtp_table->usTemperatureLimitHotspot * 256); - dpm_table->TemperatureLimitLiquid1 = PP_HOST_TO_SMC_US( - cac_dtp_table->usTemperatureLimitLiquid1 * 256); - dpm_table->TemperatureLimitLiquid2 = PP_HOST_TO_SMC_US( - cac_dtp_table->usTemperatureLimitLiquid2 * 256); - dpm_table->TemperatureLimitVrVddc = PP_HOST_TO_SMC_US( - cac_dtp_table->usTemperatureLimitVrVddc * 256); - dpm_table->TemperatureLimitVrMvdd = PP_HOST_TO_SMC_US( - cac_dtp_table->usTemperatureLimitVrMvdd * 256); - dpm_table->TemperatureLimitPlx = PP_HOST_TO_SMC_US( - cac_dtp_table->usTemperatureLimitPlx * 256); - - dpm_table->FanGainEdge = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainEdge)); - dpm_table->FanGainHotspot = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainHotspot)); - dpm_table->FanGainLiquid = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainLiquid)); - dpm_table->FanGainVrVddc = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainVrVddc)); - dpm_table->FanGainVrMvdd = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainVrMvdd)); - dpm_table->FanGainPlx = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainPlx)); - dpm_table->FanGainHbm = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainHbm)); - - dpm_table->Liquid1_I2C_address = cac_dtp_table->ucLiquid1_I2C_address; - dpm_table->Liquid2_I2C_address = cac_dtp_table->ucLiquid2_I2C_address; - dpm_table->Vr_I2C_address = cac_dtp_table->ucVr_I2C_address; - dpm_table->Plx_I2C_address = cac_dtp_table->ucPlx_I2C_address; - - get_scl_sda_value(cac_dtp_table->ucLiquid_I2C_Line, &uc_scl, &uc_sda); - dpm_table->Liquid_I2C_LineSCL = uc_scl; - dpm_table->Liquid_I2C_LineSDA = uc_sda; - - get_scl_sda_value(cac_dtp_table->ucVr_I2C_Line, &uc_scl, &uc_sda); - dpm_table->Vr_I2C_LineSCL = uc_scl; - dpm_table->Vr_I2C_LineSDA = uc_sda; - - get_scl_sda_value(cac_dtp_table->ucPlx_I2C_Line, &uc_scl, &uc_sda); - dpm_table->Plx_I2C_LineSCL = uc_scl; - dpm_table->Plx_I2C_LineSDA = uc_sda; - - return 0; -} - - -static int fiji_populate_svi_load_line(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; - - smu_data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn; - smu_data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC; - smu_data->power_tune_table.SviLoadLineTrimVddC = 3; - smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; - - return 0; -} - - -static int fiji_populate_tdc_limit(struct pp_hwmgr *hwmgr) -{ - uint16_t tdc_limit; - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; - - /* TDC number of fraction bits are changed from 8 to 7 - * for Fiji as requested by SMC team - */ - tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128); - smu_data->power_tune_table.TDC_VDDC_PkgLimit = - CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); - smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = - defaults->TDC_VDDC_ThrottleReleaseLimitPerc; - smu_data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt; - - return 0; -} - -static int fiji_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; - uint32_t temp; - - if (smu7_read_smc_sram_dword(hwmgr, - fuse_table_offset + - offsetof(SMU73_Discrete_PmFuses, TdcWaterfallCtl), - (uint32_t *)&temp, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", - return -EINVAL); - else { - smu_data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl; - smu_data->power_tune_table.LPMLTemperatureMin = - (uint8_t)((temp >> 16) & 0xff); - smu_data->power_tune_table.LPMLTemperatureMax = - (uint8_t)((temp >> 8) & 0xff); - smu_data->power_tune_table.Reserved = (uint8_t)(temp & 0xff); - } - return 0; -} - -static int fiji_populate_temperature_scaler(struct pp_hwmgr *hwmgr) -{ - int i; - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - - /* Currently not used. Set all to zero. */ - for (i = 0; i < 16; i++) - smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0; - - return 0; -} - -static int fiji_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - - if ((hwmgr->thermal_controller.advanceFanControlParameters. - usFanOutputSensitivity & (1 << 15)) || - 0 == hwmgr->thermal_controller.advanceFanControlParameters. - usFanOutputSensitivity) - hwmgr->thermal_controller.advanceFanControlParameters. - usFanOutputSensitivity = hwmgr->thermal_controller. - advanceFanControlParameters.usDefaultFanOutputSensitivity; - - smu_data->power_tune_table.FuzzyFan_PwmSetDelta = - PP_HOST_TO_SMC_US(hwmgr->thermal_controller. - advanceFanControlParameters.usFanOutputSensitivity); - return 0; -} - -static int fiji_populate_gnb_lpml(struct pp_hwmgr *hwmgr) -{ - int i; - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - - /* Currently not used. Set all to zero. */ - for (i = 0; i < 16; i++) - smu_data->power_tune_table.GnbLPML[i] = 0; - - return 0; -} - -static int fiji_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint16_t HiSidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; - uint16_t LoSidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; - struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; - - HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); - LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); - - smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = - CONVERT_FROM_HOST_TO_SMC_US(HiSidd); - smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = - CONVERT_FROM_HOST_TO_SMC_US(LoSidd); - - return 0; -} - -static int fiji_populate_pm_fuses(struct pp_hwmgr *hwmgr) -{ - uint32_t pm_fuse_table_offset; - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment)) { - if (smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU73_Firmware_Header, PmFuseTable), - &pm_fuse_table_offset, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to get pm_fuse_table_offset Failed!", - return -EINVAL); - - /* DW6 */ - if (fiji_populate_svi_load_line(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate SviLoadLine Failed!", - return -EINVAL); - /* DW7 */ - if (fiji_populate_tdc_limit(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TDCLimit Failed!", return -EINVAL); - /* DW8 */ - if (fiji_populate_dw8(hwmgr, pm_fuse_table_offset)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TdcWaterfallCtl, " - "LPMLTemperature Min and Max Failed!", - return -EINVAL); - - /* DW9-DW12 */ - if (0 != fiji_populate_temperature_scaler(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate LPMLTemperatureScaler Failed!", - return -EINVAL); - - /* DW13-DW14 */ - if (fiji_populate_fuzzy_fan(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate Fuzzy Fan Control parameters Failed!", - return -EINVAL); - - /* DW15-DW18 */ - if (fiji_populate_gnb_lpml(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate GnbLPML Failed!", - return -EINVAL); - - /* DW20 */ - if (fiji_populate_bapm_vddc_base_leakage_sidd(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate BapmVddCBaseLeakage Hi and Lo " - "Sidd Failed!", return -EINVAL); - - if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, - (uint8_t *)&smu_data->power_tune_table, - sizeof(struct SMU73_Discrete_PmFuses), SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to download PmFuseTable Failed!", - return -EINVAL); - } - return 0; -} - -/** -* Preparation of vddc and vddgfx CAC tables for SMC. -* -* @param hwmgr the address of the hardware manager -* @param table the SMC DPM table structure to be populated -* @return always 0 -*/ -static int fiji_populate_cac_table(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_DpmTable *table) -{ - uint32_t count; - uint8_t index; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_voltage_lookup_table *lookup_table = - table_info->vddc_lookup_table; - /* tables is already swapped, so in order to use the value from it, - * we need to swap it back. - * We are populating vddc CAC data to BapmVddc table - * in split and merged mode - */ - - for (count = 0; count < lookup_table->count; count++) { - index = phm_get_voltage_index(lookup_table, - data->vddc_voltage_table.entries[count].value); - table->BapmVddcVidLoSidd[count] = - convert_to_vid(lookup_table->entries[index].us_cac_low); - table->BapmVddcVidHiSidd[count] = - convert_to_vid(lookup_table->entries[index].us_cac_high); - } - - return 0; -} - -/** -* Preparation of voltage tables for SMC. -* -* @param hwmgr the address of the hardware manager -* @param table the SMC DPM table structure to be populated -* @return always 0 -*/ - -static int fiji_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_DpmTable *table) -{ - int result; - - result = fiji_populate_cac_table(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "can not populate CAC voltage tables to SMC", - return -EINVAL); - - return 0; -} - -static int fiji_populate_ulv_level(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_Ulv *state) -{ - int result = 0; - - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - state->CcPwrDynRm = 0; - state->CcPwrDynRm1 = 0; - - state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset; - state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset * - VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1); - - state->VddcPhase = 1; - - if (!result) { - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); - CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); - } - return result; -} - -static int fiji_populate_ulv_state(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_DpmTable *table) -{ - return fiji_populate_ulv_level(hwmgr, &table->Ulv); -} - -static int fiji_populate_smc_link_level(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - int i; - - /* Index (dpm_table->pcie_speed_table.count) - * is reserved for PCIE boot level. */ - for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { - table->LinkLevel[i].PcieGenSpeed = - (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; - table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width( - dpm_table->pcie_speed_table.dpm_levels[i].param1); - table->LinkLevel[i].EnabledForActivity = 1; - table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff); - table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5); - table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30); - } - - smu_data->smc_state_table.LinkLevelCount = - (uint8_t)dpm_table->pcie_speed_table.count; - data->dpm_level_enable_mask.pcie_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); - - return 0; -} - - -/** -* Calculates the SCLK dividers using the provided engine clock -* -* @param hwmgr the address of the hardware manager -* @param clock the engine clock to use to populate the structure -* @param sclk the SMC SCLK structure to be populated -*/ -static int fiji_calculate_sclk_params(struct pp_hwmgr *hwmgr, - uint32_t clock, struct SMU73_Discrete_GraphicsLevel *sclk) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct pp_atomctrl_clock_dividers_vi dividers; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - uint32_t ref_clock; - uint32_t ref_divider; - uint32_t fbdiv; - int result; - - /* get the engine clock dividers for this clock value */ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, clock, ÷rs); - - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", - return result); - - /* To get FBDIV we need to multiply this by 16384 and divide it by Fref. */ - ref_clock = atomctrl_get_reference_clock(hwmgr); - ref_divider = 1 + dividers.uc_pll_ref_div; - - /* low 14 bits is fraction and high 12 bits is divider */ - fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; - - /* SPLL_FUNC_CNTL setup */ - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_REF_DIV, dividers.uc_pll_ref_div); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_PDIV_A, dividers.uc_pll_post_div); - - /* SPLL_FUNC_CNTL_3 setup*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, - SPLL_FB_DIV, fbdiv); - - /* set to use fractional accumulation*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, - SPLL_DITHEN, 1); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { - struct pp_atomctrl_internal_ss_info ssInfo; - - uint32_t vco_freq = clock * dividers.uc_pll_post_div; - if (!atomctrl_get_engine_clock_spread_spectrum(hwmgr, - vco_freq, &ssInfo)) { - /* - * ss_info.speed_spectrum_percentage -- in unit of 0.01% - * ss_info.speed_spectrum_rate -- in unit of khz - * - * clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 - */ - uint32_t clk_s = ref_clock * 5 / - (ref_divider * ssInfo.speed_spectrum_rate); - /* clkv = 2 * D * fbdiv / NS */ - uint32_t clk_v = 4 * ssInfo.speed_spectrum_percentage * - fbdiv / (clk_s * 10000); - - cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, - CG_SPLL_SPREAD_SPECTRUM, CLKS, clk_s); - cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, - CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); - cg_spll_spread_spectrum_2 = PHM_SET_FIELD(cg_spll_spread_spectrum_2, - CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clk_v); - } - } - - sclk->SclkFrequency = clock; - sclk->CgSpllFuncCntl3 = spll_func_cntl_3; - sclk->CgSpllFuncCntl4 = spll_func_cntl_4; - sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; - sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; - sclk->SclkDid = (uint8_t)dividers.pll_post_divider; - - return 0; -} - -/** -* Populates single SMC SCLK structure using the provided engine clock -* -* @param hwmgr the address of the hardware manager -* @param clock the engine clock to use to populate the structure -* @param sclk the SMC SCLK structure to be populated -*/ - -static int fiji_populate_single_graphic_level(struct pp_hwmgr *hwmgr, - uint32_t clock, uint16_t sclk_al_threshold, - struct SMU73_Discrete_GraphicsLevel *level) -{ - int result; - /* PP_Clocks minClocks; */ - uint32_t threshold, mvdd; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - result = fiji_calculate_sclk_params(hwmgr, clock, level); - - /* populate graphics levels */ - result = fiji_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_sclk, clock, - (uint32_t *)(&level->MinVoltage), &mvdd); - PP_ASSERT_WITH_CODE((0 == result), - "can not find VDDC voltage value for " - "VDDC engine clock dependency table", - return result); - - level->SclkFrequency = clock; - level->ActivityLevel = sclk_al_threshold; - level->CcPwrDynRm = 0; - level->CcPwrDynRm1 = 0; - level->EnabledForActivity = 0; - level->EnabledForThrottle = 1; - level->UpHyst = 10; - level->DownHyst = 0; - level->VoltageDownHyst = 0; - level->PowerThrottle = 0; - - threshold = clock * data->fast_watermark_threshold / 100; - - data->display_timing.min_clock_in_sr = hwmgr->display_config.min_core_set_clock_in_sr; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) - level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock, - hwmgr->display_config.min_core_set_clock_in_sr); - - - /* Default to slow, highest DPM level will be - * set to PPSMC_DISPLAY_WATERMARK_LOW later. - */ - level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage); - CONVERT_FROM_HOST_TO_SMC_UL(level->SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1); - - return 0; -} -/** -* Populates all SMC SCLK levels' structure based on the trimmed allowed dpm engine clock states -* -* @param hwmgr the address of the hardware manager -*/ -int fiji_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - - struct smu7_dpm_table *dpm_table = &data->dpm_table; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table; - uint8_t pcie_entry_cnt = (uint8_t) data->dpm_table.pcie_speed_table.count; - int result = 0; - uint32_t array = smu_data->smu7_data.dpm_table_start + - offsetof(SMU73_Discrete_DpmTable, GraphicsLevel); - uint32_t array_size = sizeof(struct SMU73_Discrete_GraphicsLevel) * - SMU73_MAX_LEVELS_GRAPHICS; - struct SMU73_Discrete_GraphicsLevel *levels = - smu_data->smc_state_table.GraphicsLevel; - uint32_t i, max_entry; - uint8_t hightest_pcie_level_enabled = 0, - lowest_pcie_level_enabled = 0, - mid_pcie_level_enabled = 0, - count = 0; - - for (i = 0; i < dpm_table->sclk_table.count; i++) { - result = fiji_populate_single_graphic_level(hwmgr, - dpm_table->sclk_table.dpm_levels[i].value, - (uint16_t)smu_data->activity_target[i], - &levels[i]); - if (result) - return result; - - /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ - if (i > 1) - levels[i].DeepSleepDivId = 0; - } - - /* Only enable level 0 for now.*/ - levels[0].EnabledForActivity = 1; - - /* set highest level watermark to high */ - levels[dpm_table->sclk_table.count - 1].DisplayWatermark = - PPSMC_DISPLAY_WATERMARK_HIGH; - - smu_data->smc_state_table.GraphicsDpmLevelCount = - (uint8_t)dpm_table->sclk_table.count; - data->dpm_level_enable_mask.sclk_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); - - if (pcie_table != NULL) { - PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt), - "There must be 1 or more PCIE levels defined in PPTable.", - return -EINVAL); - max_entry = pcie_entry_cnt - 1; - for (i = 0; i < dpm_table->sclk_table.count; i++) - levels[i].pcieDpmLevel = - (uint8_t) ((i < max_entry) ? i : max_entry); - } else { - while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && - ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << (hightest_pcie_level_enabled + 1))) != 0)) - hightest_pcie_level_enabled++; - - while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && - ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << lowest_pcie_level_enabled)) == 0)) - lowest_pcie_level_enabled++; - - while ((count < hightest_pcie_level_enabled) && - ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << (lowest_pcie_level_enabled + 1 + count))) == 0)) - count++; - - mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1 + count) < - hightest_pcie_level_enabled ? - (lowest_pcie_level_enabled + 1 + count) : - hightest_pcie_level_enabled; - - /* set pcieDpmLevel to hightest_pcie_level_enabled */ - for (i = 2; i < dpm_table->sclk_table.count; i++) - levels[i].pcieDpmLevel = hightest_pcie_level_enabled; - - /* set pcieDpmLevel to lowest_pcie_level_enabled */ - levels[0].pcieDpmLevel = lowest_pcie_level_enabled; - - /* set pcieDpmLevel to mid_pcie_level_enabled */ - levels[1].pcieDpmLevel = mid_pcie_level_enabled; - } - /* level count will send to smc once at init smc table and never change */ - result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - (uint32_t)array_size, SMC_RAM_END); - - return result; -} - - -/** - * MCLK Frequency Ratio - * SEQ_CG_RESP Bit[31:24] - 0x0 - * Bit[27:24] \96 DDR3 Frequency ratio - * 0x0 <= 100MHz, 450 < 0x8 <= 500MHz - * 100 < 0x1 <= 150MHz, 500 < 0x9 <= 550MHz - * 150 < 0x2 <= 200MHz, 550 < 0xA <= 600MHz - * 200 < 0x3 <= 250MHz, 600 < 0xB <= 650MHz - * 250 < 0x4 <= 300MHz, 650 < 0xC <= 700MHz - * 300 < 0x5 <= 350MHz, 700 < 0xD <= 750MHz - * 350 < 0x6 <= 400MHz, 750 < 0xE <= 800MHz - * 400 < 0x7 <= 450MHz, 800 < 0xF - */ -static uint8_t fiji_get_mclk_frequency_ratio(uint32_t mem_clock) -{ - if (mem_clock <= 10000) - return 0x0; - if (mem_clock <= 15000) - return 0x1; - if (mem_clock <= 20000) - return 0x2; - if (mem_clock <= 25000) - return 0x3; - if (mem_clock <= 30000) - return 0x4; - if (mem_clock <= 35000) - return 0x5; - if (mem_clock <= 40000) - return 0x6; - if (mem_clock <= 45000) - return 0x7; - if (mem_clock <= 50000) - return 0x8; - if (mem_clock <= 55000) - return 0x9; - if (mem_clock <= 60000) - return 0xa; - if (mem_clock <= 65000) - return 0xb; - if (mem_clock <= 70000) - return 0xc; - if (mem_clock <= 75000) - return 0xd; - if (mem_clock <= 80000) - return 0xe; - /* mem_clock > 800MHz */ - return 0xf; -} - -/** -* Populates the SMC MCLK structure using the provided memory clock -* -* @param hwmgr the address of the hardware manager -* @param clock the memory clock to use to populate the structure -* @param sclk the SMC SCLK structure to be populated -*/ -static int fiji_calculate_mclk_params(struct pp_hwmgr *hwmgr, - uint32_t clock, struct SMU73_Discrete_MemoryLevel *mclk) -{ - struct pp_atomctrl_memory_clock_param mem_param; - int result; - - result = atomctrl_get_memory_pll_dividers_vi(hwmgr, clock, &mem_param); - PP_ASSERT_WITH_CODE((0 == result), - "Failed to get Memory PLL Dividers.", - ); - - /* Save the result data to outpupt memory level structure */ - mclk->MclkFrequency = clock; - mclk->MclkDivider = (uint8_t)mem_param.mpll_post_divider; - mclk->FreqRange = fiji_get_mclk_frequency_ratio(clock); - - return result; -} - -static int fiji_populate_single_memory_level(struct pp_hwmgr *hwmgr, - uint32_t clock, struct SMU73_Discrete_MemoryLevel *mem_level) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - int result = 0; - uint32_t mclk_stutter_mode_threshold = 60000; - - if (table_info->vdd_dep_on_mclk) { - result = fiji_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_mclk, clock, - (uint32_t *)(&mem_level->MinVoltage), &mem_level->MinMvdd); - PP_ASSERT_WITH_CODE((0 == result), - "can not find MinVddc voltage value from memory " - "VDDC voltage dependency table", return result); - } - - mem_level->EnabledForThrottle = 1; - mem_level->EnabledForActivity = 0; - mem_level->UpHyst = 0; - mem_level->DownHyst = 100; - mem_level->VoltageDownHyst = 0; - mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target; - mem_level->StutterEnable = false; - - mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - /* enable stutter mode if all the follow condition applied - * PECI_GetNumberOfActiveDisplays(hwmgr->pPECI, - * &(data->DisplayTiming.numExistingDisplays)); - */ - data->display_timing.num_existing_displays = 1; - - if (mclk_stutter_mode_threshold && - (clock <= mclk_stutter_mode_threshold) && - (!data->is_uvd_enabled) && - (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, - STUTTER_ENABLE) & 0x1)) - mem_level->StutterEnable = true; - - result = fiji_calculate_mclk_params(hwmgr, clock, mem_level); - if (!result) { - CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinMvdd); - CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(mem_level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinVoltage); - } - return result; -} - -/** -* Populates all SMC MCLK levels' structure based on the trimmed allowed dpm memory clock states -* -* @param hwmgr the address of the hardware manager -*/ -int fiji_populate_all_memory_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - int result; - /* populate MCLK dpm table to SMU7 */ - uint32_t array = smu_data->smu7_data.dpm_table_start + - offsetof(SMU73_Discrete_DpmTable, MemoryLevel); - uint32_t array_size = sizeof(SMU73_Discrete_MemoryLevel) * - SMU73_MAX_LEVELS_MEMORY; - struct SMU73_Discrete_MemoryLevel *levels = - smu_data->smc_state_table.MemoryLevel; - uint32_t i; - - for (i = 0; i < dpm_table->mclk_table.count; i++) { - PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), - "can not populate memory level as memory clock is zero", - return -EINVAL); - result = fiji_populate_single_memory_level(hwmgr, - dpm_table->mclk_table.dpm_levels[i].value, - &levels[i]); - if (result) - return result; - } - - /* Only enable level 0 for now. */ - levels[0].EnabledForActivity = 1; - - /* in order to prevent MC activity from stutter mode to push DPM up. - * the UVD change complements this by putting the MCLK in - * a higher state by default such that we are not effected by - * up threshold or and MCLK DPM latency. - */ - levels[0].ActivityLevel = (uint16_t)data->mclk_dpm0_activity_target; - CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel); - - smu_data->smc_state_table.MemoryDpmLevelCount = - (uint8_t)dpm_table->mclk_table.count; - data->dpm_level_enable_mask.mclk_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); - /* set highest level watermark to high */ - levels[dpm_table->mclk_table.count - 1].DisplayWatermark = - PPSMC_DISPLAY_WATERMARK_HIGH; - - /* level count will send to smc once at init smc table and never change */ - result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - (uint32_t)array_size, SMC_RAM_END); - - return result; -} - - -/** -* Populates the SMC MVDD structure using the provided memory clock. -* -* @param hwmgr the address of the hardware manager -* @param mclk the MCLK value to be used in the decision if MVDD should be high or low. -* @param voltage the SMC VOLTAGE structure to be populated -*/ -static int fiji_populate_mvdd_value(struct pp_hwmgr *hwmgr, - uint32_t mclk, SMIO_Pattern *smio_pat) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint32_t i = 0; - - if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { - /* find mvdd value which clock is more than request */ - for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) { - if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) { - smio_pat->Voltage = data->mvdd_voltage_table.entries[i].value; - break; - } - } - PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count, - "MVDD Voltage is outside the supported range.", - return -EINVAL); - } else - return -EINVAL; - - return 0; -} - -static int fiji_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, - SMU73_Discrete_DpmTable *table) -{ - int result = 0; - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct pp_atomctrl_clock_dividers_vi dividers; - SMIO_Pattern vol_level; - uint32_t mvdd; - uint16_t us_mvdd; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; - - table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; - - if (!data->sclk_dpm_key_disabled) { - /* Get MinVoltage and Frequency from DPM0, - * already converted to SMC_UL */ - table->ACPILevel.SclkFrequency = - data->dpm_table.sclk_table.dpm_levels[0].value; - result = fiji_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_sclk, - table->ACPILevel.SclkFrequency, - (uint32_t *)(&table->ACPILevel.MinVoltage), &mvdd); - PP_ASSERT_WITH_CODE((0 == result), - "Cannot find ACPI VDDC voltage value " \ - "in Clock Dependency Table", - ); - } else { - table->ACPILevel.SclkFrequency = - data->vbios_boot_state.sclk_bootup_value; - table->ACPILevel.MinVoltage = - data->vbios_boot_state.vddc_bootup_value * VOLTAGE_SCALE; - } - - /* get the engine clock dividers for this clock value */ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, - table->ACPILevel.SclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", - return result); - - table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; - table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - table->ACPILevel.DeepSleepDivId = 0; - - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_PWRON, 0); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_RESET, 1); - spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, CG_SPLL_FUNC_CNTL_2, - SCLK_MUX_SEL, 4); - - table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; - table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; - table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - table->ACPILevel.CcPwrDynRm = 0; - table->ACPILevel.CcPwrDynRm1 = 0; - - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.MinVoltage); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); - - if (!data->mclk_dpm_key_disabled) { - /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */ - table->MemoryACPILevel.MclkFrequency = - data->dpm_table.mclk_table.dpm_levels[0].value; - result = fiji_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_mclk, - table->MemoryACPILevel.MclkFrequency, - (uint32_t *)(&table->MemoryACPILevel.MinVoltage), &mvdd); - PP_ASSERT_WITH_CODE((0 == result), - "Cannot find ACPI VDDCI voltage value in Clock Dependency Table", - ); - } else { - table->MemoryACPILevel.MclkFrequency = - data->vbios_boot_state.mclk_bootup_value; - table->MemoryACPILevel.MinVoltage = - data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE; - } - - us_mvdd = 0; - if ((SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) || - (data->mclk_dpm_key_disabled)) - us_mvdd = data->vbios_boot_state.mvdd_bootup_value; - else { - if (!fiji_populate_mvdd_value(hwmgr, - data->dpm_table.mclk_table.dpm_levels[0].value, - &vol_level)) - us_mvdd = vol_level.Voltage; - } - - table->MemoryACPILevel.MinMvdd = - PP_HOST_TO_SMC_UL(us_mvdd * VOLTAGE_SCALE); - - table->MemoryACPILevel.EnabledForThrottle = 0; - table->MemoryACPILevel.EnabledForActivity = 0; - table->MemoryACPILevel.UpHyst = 0; - table->MemoryACPILevel.DownHyst = 100; - table->MemoryACPILevel.VoltageDownHyst = 0; - table->MemoryACPILevel.ActivityLevel = - PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); - - table->MemoryACPILevel.StutterEnable = false; - CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage); - - return result; -} - -static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr, - SMU73_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - table_info->mm_dep_table; - - table->VceLevelCount = (uint8_t)(mm_table->count); - table->VceBootLevel = 0; - - for (count = 0; count < table->VceLevelCount; count++) { - table->VceLevel[count].Frequency = mm_table->entries[count].eclk; - table->VceLevel[count].MinVoltage = 0; - table->VceLevel[count].MinVoltage |= - (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; - table->VceLevel[count].MinVoltage |= - ((mm_table->entries[count].vddc - VDDC_VDDCI_DELTA) * - VOLTAGE_SCALE) << VDDCI_SHIFT; - table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT; - - /*retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->VceLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for VCE engine clock", - return result); - - table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage); - } - return result; -} - -static int fiji_populate_smc_acp_level(struct pp_hwmgr *hwmgr, - SMU73_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - table_info->mm_dep_table; - - table->AcpLevelCount = (uint8_t)(mm_table->count); - table->AcpBootLevel = 0; - - for (count = 0; count < table->AcpLevelCount; count++) { - table->AcpLevel[count].Frequency = mm_table->entries[count].aclk; - table->AcpLevel[count].MinVoltage |= (mm_table->entries[count].vddc * - VOLTAGE_SCALE) << VDDC_SHIFT; - table->AcpLevel[count].MinVoltage |= ((mm_table->entries[count].vddc - - VDDC_VDDCI_DELTA) * VOLTAGE_SCALE) << VDDCI_SHIFT; - table->AcpLevel[count].MinVoltage |= 1 << PHASES_SHIFT; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->AcpLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for engine clock", return result); - - table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].MinVoltage); - } - return result; -} - -static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr, - SMU73_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - table_info->mm_dep_table; - - table->SamuBootLevel = 0; - table->SamuLevelCount = (uint8_t)(mm_table->count); - - for (count = 0; count < table->SamuLevelCount; count++) { - /* not sure whether we need evclk or not */ - table->SamuLevel[count].MinVoltage = 0; - table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; - table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * - VOLTAGE_SCALE) << VDDC_SHIFT; - table->SamuLevel[count].MinVoltage |= ((mm_table->entries[count].vddc - - VDDC_VDDCI_DELTA) * VOLTAGE_SCALE) << VDDCI_SHIFT; - table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->SamuLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for samu clock", return result); - - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage); - } - return result; -} - -static int fiji_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr, - int32_t eng_clock, int32_t mem_clock, - struct SMU73_Discrete_MCArbDramTimingTableEntry *arb_regs) -{ - uint32_t dram_timing; - uint32_t dram_timing2; - uint32_t burstTime; - ULONG state, trrds, trrdl; - int result; - - result = atomctrl_set_engine_dram_timings_rv770(hwmgr, - eng_clock, mem_clock); - PP_ASSERT_WITH_CODE(result == 0, - "Error calling VBIOS to set DRAM_TIMING.", return result); - - dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); - dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); - burstTime = cgs_read_register(hwmgr->device, mmMC_ARB_BURST_TIME); - - state = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, STATE0); - trrds = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, TRRDS0); - trrdl = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, TRRDL0); - - arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dram_timing); - arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dram_timing2); - arb_regs->McArbBurstTime = (uint8_t)burstTime; - arb_regs->TRRDS = (uint8_t)trrds; - arb_regs->TRRDL = (uint8_t)trrdl; - - return 0; -} - -static int fiji_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct SMU73_Discrete_MCArbDramTimingTable arb_regs; - uint32_t i, j; - int result = 0; - - for (i = 0; i < data->dpm_table.sclk_table.count; i++) { - for (j = 0; j < data->dpm_table.mclk_table.count; j++) { - result = fiji_populate_memory_timing_parameters(hwmgr, - data->dpm_table.sclk_table.dpm_levels[i].value, - data->dpm_table.mclk_table.dpm_levels[j].value, - &arb_regs.entries[i][j]); - if (result) - break; - } - } - - if (!result) - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.arb_table_start, - (uint8_t *)&arb_regs, - sizeof(SMU73_Discrete_MCArbDramTimingTable), - SMC_RAM_END); - return result; -} - -static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - table_info->mm_dep_table; - - table->UvdLevelCount = (uint8_t)(mm_table->count); - table->UvdBootLevel = 0; - - for (count = 0; count < table->UvdLevelCount; count++) { - table->UvdLevel[count].MinVoltage = 0; - table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; - table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; - table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * - VOLTAGE_SCALE) << VDDC_SHIFT; - table->UvdLevel[count].MinVoltage |= ((mm_table->entries[count].vddc - - VDDC_VDDCI_DELTA) * VOLTAGE_SCALE) << VDDCI_SHIFT; - table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->UvdLevel[count].VclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for Vclk clock", return result); - - table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; - - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->UvdLevel[count].DclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for Dclk clock", return result); - - table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage); - - } - return result; -} - -static int fiji_populate_smc_boot_level(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_DpmTable *table) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - table->GraphicsBootLevel = 0; - table->MemoryBootLevel = 0; - - /* find boot level from dpm table */ - result = phm_find_boot_level(&(data->dpm_table.sclk_table), - data->vbios_boot_state.sclk_bootup_value, - (uint32_t *)&(table->GraphicsBootLevel)); - - result = phm_find_boot_level(&(data->dpm_table.mclk_table), - data->vbios_boot_state.mclk_bootup_value, - (uint32_t *)&(table->MemoryBootLevel)); - - table->BootVddc = data->vbios_boot_state.vddc_bootup_value * - VOLTAGE_SCALE; - table->BootVddci = data->vbios_boot_state.vddci_bootup_value * - VOLTAGE_SCALE; - table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value * - VOLTAGE_SCALE; - - CONVERT_FROM_HOST_TO_SMC_US(table->BootVddc); - CONVERT_FROM_HOST_TO_SMC_US(table->BootVddci); - CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd); - - return 0; -} - -static int fiji_populate_smc_initailial_state(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint8_t count, level; - - count = (uint8_t)(table_info->vdd_dep_on_sclk->count); - for (level = 0; level < count; level++) { - if (table_info->vdd_dep_on_sclk->entries[level].clk >= - data->vbios_boot_state.sclk_bootup_value) { - smu_data->smc_state_table.GraphicsBootLevel = level; - break; - } - } - - count = (uint8_t)(table_info->vdd_dep_on_mclk->count); - for (level = 0; level < count; level++) { - if (table_info->vdd_dep_on_mclk->entries[level].clk >= - data->vbios_boot_state.mclk_bootup_value) { - smu_data->smc_state_table.MemoryBootLevel = level; - break; - } - } - - return 0; -} - -static int fiji_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) -{ - uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks, - volt_with_cks, value; - uint16_t clock_freq_u16; - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2, - volt_offset = 0; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = - table_info->vdd_dep_on_sclk; - - stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount; - - /* Read SMU_Eefuse to read and calculate RO and determine - * if the part is SS or FF. if RO >= 1660MHz, part is FF. - */ - efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixSMU_EFUSE_0 + (146 * 4)); - efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixSMU_EFUSE_0 + (148 * 4)); - efuse &= 0xFF000000; - efuse = efuse >> 24; - efuse2 &= 0xF; - - if (efuse2 == 1) - ro = (2300 - 1350) * efuse / 255 + 1350; - else - ro = (2500 - 1000) * efuse / 255 + 1000; - - if (ro >= 1660) - type = 0; - else - type = 1; - - /* Populate Stretch amount */ - smu_data->smc_state_table.ClockStretcherAmount = stretch_amount; - - /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ - for (i = 0; i < sclk_table->count; i++) { - smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= - sclk_table->entries[i].cks_enable << i; - volt_without_cks = (uint32_t)((14041 * - (sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 / - (4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000))); - volt_with_cks = (uint32_t)((13946 * - (sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 / - (3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000))); - if (volt_without_cks >= volt_with_cks) - volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + - sclk_table->entries[i].cks_voffset) * 100 / 625) + 1); - smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; - } - - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - STRETCH_ENABLE, 0x0); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - masterReset, 0x1); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - staticEnable, 0x1); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - masterReset, 0x0); - - /* Populate CKS Lookup Table */ - if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) - stretch_amount2 = 0; - else if (stretch_amount == 3 || stretch_amount == 4) - stretch_amount2 = 1; - else { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ClockStretcher); - PP_ASSERT_WITH_CODE(false, - "Stretch Amount in PPTable not supported\n", - return -EINVAL); - } - - value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixPWR_CKS_CNTL); - value &= 0xFFC2FF87; - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq = - fiji_clock_stretcher_lookup_table[stretch_amount2][0]; - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq = - fiji_clock_stretcher_lookup_table[stretch_amount2][1]; - clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(smu_data->smc_state_table. - GraphicsLevel[smu_data->smc_state_table.GraphicsDpmLevelCount - 1]. - SclkFrequency) / 100); - if (fiji_clock_stretcher_lookup_table[stretch_amount2][0] < - clock_freq_u16 && - fiji_clock_stretcher_lookup_table[stretch_amount2][1] > - clock_freq_u16) { - /* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */ - value |= (fiji_clock_stretcher_lookup_table[stretch_amount2][3]) << 16; - /* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */ - value |= (fiji_clock_stretcher_lookup_table[stretch_amount2][2]) << 18; - /* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */ - value |= (fiji_clock_stretch_amount_conversion - [fiji_clock_stretcher_lookup_table[stretch_amount2][3]] - [stretch_amount]) << 3; - } - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. - CKS_LOOKUPTableEntry[0].minFreq); - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. - CKS_LOOKUPTableEntry[0].maxFreq); - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting = - fiji_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F; - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |= - (fiji_clock_stretcher_lookup_table[stretch_amount2][3]) << 7; - - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixPWR_CKS_CNTL, value); - - /* Populate DDT Lookup Table */ - for (i = 0; i < 4; i++) { - /* Assign the minimum and maximum VID stored - * in the last row of Clock Stretcher Voltage Table. - */ - smu_data->smc_state_table.ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].minVID = - (uint8_t) fiji_clock_stretcher_ddt_table[type][i][2]; - smu_data->smc_state_table.ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].maxVID = - (uint8_t) fiji_clock_stretcher_ddt_table[type][i][3]; - /* Loop through each SCLK and check the frequency - * to see if it lies within the frequency for clock stretcher. - */ - for (j = 0; j < smu_data->smc_state_table.GraphicsDpmLevelCount; j++) { - cks_setting = 0; - clock_freq = PP_SMC_TO_HOST_UL( - smu_data->smc_state_table.GraphicsLevel[j].SclkFrequency); - /* Check the allowed frequency against the sclk level[j]. - * Sclk's endianness has already been converted, - * and it's in 10Khz unit, - * as opposed to Data table, which is in Mhz unit. - */ - if (clock_freq >= - (fiji_clock_stretcher_ddt_table[type][i][0]) * 100) { - cks_setting |= 0x2; - if (clock_freq < - (fiji_clock_stretcher_ddt_table[type][i][1]) * 100) - cks_setting |= 0x1; - } - smu_data->smc_state_table.ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].setting |= cks_setting << (j * 2); - } - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table. - ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].setting); - } - - value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL); - value &= 0xFFFFFFFE; - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value); - - return 0; -} - -/** -* Populates the SMC VRConfig field in DPM table. -* -* @param hwmgr the address of the hardware manager -* @param table the SMC DPM table structure to be populated -* @return always 0 -*/ -static int fiji_populate_vr_config(struct pp_hwmgr *hwmgr, - struct SMU73_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint16_t config; - - config = VR_MERGED_WITH_VDDC; - table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT); - - /* Set Vddc Voltage Controller */ - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) { - config = VR_SVI2_PLANE_1; - table->VRConfig |= config; - } else { - PP_ASSERT_WITH_CODE(false, - "VDDC should be on SVI2 control in merged mode!", - ); - } - /* Set Vddci Voltage Controller */ - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { - config = VR_SVI2_PLANE_2; /* only in merged mode */ - table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); - } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { - config = VR_SMIO_PATTERN_1; - table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); - } else { - config = VR_STATIC_VOLTAGE; - table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); - } - /* Set Mvdd Voltage Controller */ - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) { - config = VR_SVI2_PLANE_2; - table->VRConfig |= (config << VRCONF_MVDD_SHIFT); - } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) { - config = VR_SMIO_PATTERN_2; - table->VRConfig |= (config << VRCONF_MVDD_SHIFT); - } else { - config = VR_STATIC_VOLTAGE; - table->VRConfig |= (config << VRCONF_MVDD_SHIFT); - } - - return 0; -} - -static int fiji_init_arb_table_index(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - uint32_t tmp; - int result; - - /* This is a read-modify-write on the first byte of the ARB table. - * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure - * is the field 'current'. - * This solution is ugly, but we never write the whole table only - * individual fields in it. - * In reality this field should not be in that structure - * but in a soft register. - */ - result = smu7_read_smc_sram_dword(hwmgr, - smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END); - - if (result) - return result; - - tmp &= 0x00FFFFFF; - tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; - - return smu7_write_smc_sram_dword(hwmgr, - smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END); -} - -static int fiji_save_default_power_profile(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct SMU73_Discrete_GraphicsLevel *levels = - data->smc_state_table.GraphicsLevel; - unsigned min_level = 1; - - hwmgr->default_gfx_power_profile.activity_threshold = - be16_to_cpu(levels[0].ActivityLevel); - hwmgr->default_gfx_power_profile.up_hyst = levels[0].UpHyst; - hwmgr->default_gfx_power_profile.down_hyst = levels[0].DownHyst; - hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE; - - hwmgr->default_compute_power_profile = hwmgr->default_gfx_power_profile; - hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE; - - /* Workaround compute SDMA instability: disable lowest SCLK - * DPM level. Optimize compute power profile: Use only highest - * 2 power levels (if more than 2 are available), Hysteresis: - * 0ms up, 5ms down - */ - if (data->smc_state_table.GraphicsDpmLevelCount > 2) - min_level = data->smc_state_table.GraphicsDpmLevelCount - 2; - else if (data->smc_state_table.GraphicsDpmLevelCount == 2) - min_level = 1; - else - min_level = 0; - hwmgr->default_compute_power_profile.min_sclk = - be32_to_cpu(levels[min_level].SclkFrequency); - hwmgr->default_compute_power_profile.up_hyst = 0; - hwmgr->default_compute_power_profile.down_hyst = 5; - - hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile; - hwmgr->compute_power_profile = hwmgr->default_compute_power_profile; - - return 0; -} - -static int fiji_setup_dpm_led_config(struct pp_hwmgr *hwmgr) -{ - pp_atomctrl_voltage_table param_led_dpm; - int result = 0; - u32 mask = 0; - - result = atomctrl_get_voltage_table_v3(hwmgr, - VOLTAGE_TYPE_LEDDPM, VOLTAGE_OBJ_GPIO_LUT, - ¶m_led_dpm); - if (result == 0) { - int i, j; - u32 tmp = param_led_dpm.mask_low; - - for (i = 0, j = 0; i < 32; i++) { - if (tmp & 1) { - mask |= (i << (8 * j)); - if (++j >= 3) - break; - } - tmp >>= 1; - } - } - if (mask) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_LedConfig, - mask); - return 0; -} - -/** -* Initializes the SMC table and uploads it -* -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data (PowerState) -* @return always 0 -*/ -int fiji_init_smc_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct SMU73_Discrete_DpmTable *table = &(smu_data->smc_state_table); - uint8_t i; - struct pp_atomctrl_gpio_pin_assignment gpio_pin; - - fiji_initialize_power_tune_defaults(hwmgr); - - if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) - fiji_populate_smc_voltage_tables(hwmgr, table); - - table->SystemFlags = 0; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StepVddc)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; - - if (data->is_memory_gddr5) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; - - if (data->ulv_supported && table_info->us_ulv_voltage_offset) { - result = fiji_populate_ulv_state(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ULV state!", return result); - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixCG_ULV_PARAMETER, 0x40035); - } - - result = fiji_populate_smc_link_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Link Level!", return result); - - result = fiji_populate_all_graphic_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Graphics Level!", return result); - - result = fiji_populate_all_memory_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Memory Level!", return result); - - result = fiji_populate_smc_acpi_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ACPI Level!", return result); - - result = fiji_populate_smc_vce_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize VCE Level!", return result); - - result = fiji_populate_smc_acp_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ACP Level!", return result); - - result = fiji_populate_smc_samu_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize SAMU Level!", return result); - - /* Since only the initial state is completely set up at this point - * (the other states are just copies of the boot state) we only - * need to populate the ARB settings for the initial state. - */ - result = fiji_program_memory_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to Write ARB settings for the initial state.", return result); - - result = fiji_populate_smc_uvd_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize UVD Level!", return result); - - result = fiji_populate_smc_boot_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Boot Level!", return result); - - result = fiji_populate_smc_initailial_state(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Boot State!", return result); - - result = fiji_populate_bapm_parameters_in_dpm_table(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate BAPM Parameters!", return result); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ClockStretcher)) { - result = fiji_populate_clock_stretcher_data_table(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate Clock Stretcher Data Table!", - return result); - } - - table->GraphicsVoltageChangeEnable = 1; - table->GraphicsThermThrottleEnable = 1; - table->GraphicsInterval = 1; - table->VoltageInterval = 1; - table->ThermalInterval = 1; - table->TemperatureLimitHigh = - table_info->cac_dtp_table->usTargetOperatingTemp * - SMU7_Q88_FORMAT_CONVERSION_UNIT; - table->TemperatureLimitLow = - (table_info->cac_dtp_table->usTargetOperatingTemp - 1) * - SMU7_Q88_FORMAT_CONVERSION_UNIT; - table->MemoryVoltageChangeEnable = 1; - table->MemoryInterval = 1; - table->VoltageResponseTime = 0; - table->PhaseResponseTime = 0; - table->MemoryThermThrottleEnable = 1; - table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/ - table->PCIeGenInterval = 1; - table->VRConfig = 0; - - result = fiji_populate_vr_config(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate VRConfig setting!", return result); - - table->ThermGpio = 17; - table->SclkStepSize = 0x4000; - - if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) { - table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift; - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot); - } else { - table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot); - } - - if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID, - &gpio_pin)) { - table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift; - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition); - } else { - table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition); - } - - /* Thermal Output GPIO */ - if (atomctrl_get_pp_assign_pin(hwmgr, THERMAL_INT_OUTPUT_GPIO_PINID, - &gpio_pin)) { - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ThermalOutGPIO); - - table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift; - - /* For porlarity read GPIOPAD_A with assigned Gpio pin - * since VBIOS will program this register to set 'inactive state', - * driver can then determine 'active state' from this and - * program SMU with correct polarity - */ - table->ThermOutPolarity = (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) & - (1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0; - table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY; - - /* if required, combine VRHot/PCC with thermal out GPIO */ - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot) && - phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_CombinePCCWithThermalSignal)) - table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT; - } else { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ThermalOutGPIO); - table->ThermOutGpio = 17; - table->ThermOutPolarity = 1; - table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE; - } - - for (i = 0; i < SMU73_MAX_ENTRIES_SMIO; i++) - table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]); - - CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); - CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2); - CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); - CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); - CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); - - /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ - result = smu7_copy_bytes_to_smc(hwmgr, - smu_data->smu7_data.dpm_table_start + - offsetof(SMU73_Discrete_DpmTable, SystemFlags), - (uint8_t *)&(table->SystemFlags), - sizeof(SMU73_Discrete_DpmTable) - 3 * sizeof(SMU73_PIDController), - SMC_RAM_END); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to upload dpm data to SMC memory!", return result); - - result = fiji_init_arb_table_index(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to upload arb data to SMC memory!", return result); - - result = fiji_populate_pm_fuses(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate PM fuses to SMC memory!", return result); - - result = fiji_setup_dpm_led_config(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to setup dpm led config", return result); - - fiji_save_default_power_profile(hwmgr); - - return 0; -} - -/** -* Set up the fan table to control the fan using the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ -int fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - - SMU73_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; - uint32_t duty100; - uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; - uint16_t fdo_min, slope1, slope2; - uint32_t reference_clock; - int res; - uint64_t tmp64; - - if (hwmgr->thermal_controller.fanInfo.bNoFan) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - if (smu_data->smu7_data.fan_table_start == 0) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, - CG_FDO_CTRL1, FMAX_DUTY100); - - if (duty100 == 0) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - tmp64 = hwmgr->thermal_controller.advanceFanControlParameters. - usPWMMin * duty100; - do_div(tmp64, 10000); - fdo_min = (uint16_t)tmp64; - - t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - - hwmgr->thermal_controller.advanceFanControlParameters.usTMin; - t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - - hwmgr->thermal_controller.advanceFanControlParameters.usTMed; - - pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; - pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; - - slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); - slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); - - fan_table.TempMin = cpu_to_be16((50 + hwmgr-> - thermal_controller.advanceFanControlParameters.usTMin) / 100); - fan_table.TempMed = cpu_to_be16((50 + hwmgr-> - thermal_controller.advanceFanControlParameters.usTMed) / 100); - fan_table.TempMax = cpu_to_be16((50 + hwmgr-> - thermal_controller.advanceFanControlParameters.usTMax) / 100); - - fan_table.Slope1 = cpu_to_be16(slope1); - fan_table.Slope2 = cpu_to_be16(slope2); - - fan_table.FdoMin = cpu_to_be16(fdo_min); - - fan_table.HystDown = cpu_to_be16(hwmgr-> - thermal_controller.advanceFanControlParameters.ucTHyst); - - fan_table.HystUp = cpu_to_be16(1); - - fan_table.HystSlope = cpu_to_be16(1); - - fan_table.TempRespLim = cpu_to_be16(5); - - reference_clock = smu7_get_xclk(hwmgr); - - fan_table.RefreshPeriod = cpu_to_be32((hwmgr-> - thermal_controller.advanceFanControlParameters.ulCycleDelay * - reference_clock) / 1600); - - fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); - - fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD( - hwmgr->device, CGS_IND_REG__SMC, - CG_MULT_THERMAL_CTRL, TEMP_SEL); - - res = smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.fan_table_start, - (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), - SMC_RAM_END); - - if (!res && hwmgr->thermal_controller. - advanceFanControlParameters.ucMinimumPWMLimit) - res = smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetFanMinPwm, - hwmgr->thermal_controller. - advanceFanControlParameters.ucMinimumPWMLimit); - - if (!res && hwmgr->thermal_controller. - advanceFanControlParameters.ulMinFanSCLKAcousticLimit) - res = smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetFanSclkTarget, - hwmgr->thermal_controller. - advanceFanControlParameters.ulMinFanSCLKAcousticLimit); - - if (res) - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - - return 0; -} - - -int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr) -{ - int ret; - struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); - - if (smu_data->avfs.avfs_btc_status != AVFS_BTC_ENABLEAVFS) - return 0; - - ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs); - - if (!ret) - /* If this param is not changed, this function could fire unnecessarily */ - smu_data->avfs.avfs_btc_status = AVFS_BTC_COMPLETED_PREVIOUSLY; - - return ret; -} - -static int fiji_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (data->need_update_smu7_dpm_table & - (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) - return fiji_program_memory_timing_parameters(hwmgr); - - return 0; -} - -int fiji_update_sclk_threshold(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - - int result = 0; - uint32_t low_sclk_interrupt_threshold = 0; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkThrottleLowNotification) - && (hwmgr->gfx_arbiter.sclk_threshold != - data->low_sclk_interrupt_threshold)) { - data->low_sclk_interrupt_threshold = - hwmgr->gfx_arbiter.sclk_threshold; - low_sclk_interrupt_threshold = - data->low_sclk_interrupt_threshold; - - CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); - - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.dpm_table_start + - offsetof(SMU73_Discrete_DpmTable, - LowSclkInterruptThreshold), - (uint8_t *)&low_sclk_interrupt_threshold, - sizeof(uint32_t), - SMC_RAM_END); - } - result = fiji_program_mem_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE((result == 0), - "Failed to program memory timing parameters!", - ); - return result; -} - -uint32_t fiji_get_offsetof(uint32_t type, uint32_t member) -{ - switch (type) { - case SMU_SoftRegisters: - switch (member) { - case HandshakeDisables: - return offsetof(SMU73_SoftRegisters, HandshakeDisables); - case VoltageChangeTimeout: - return offsetof(SMU73_SoftRegisters, VoltageChangeTimeout); - case AverageGraphicsActivity: - return offsetof(SMU73_SoftRegisters, AverageGraphicsActivity); - case PreVBlankGap: - return offsetof(SMU73_SoftRegisters, PreVBlankGap); - case VBlankTimeout: - return offsetof(SMU73_SoftRegisters, VBlankTimeout); - case UcodeLoadStatus: - return offsetof(SMU73_SoftRegisters, UcodeLoadStatus); - case DRAM_LOG_ADDR_H: - return offsetof(SMU73_SoftRegisters, DRAM_LOG_ADDR_H); - case DRAM_LOG_ADDR_L: - return offsetof(SMU73_SoftRegisters, DRAM_LOG_ADDR_L); - case DRAM_LOG_PHY_ADDR_H: - return offsetof(SMU73_SoftRegisters, DRAM_LOG_PHY_ADDR_H); - case DRAM_LOG_PHY_ADDR_L: - return offsetof(SMU73_SoftRegisters, DRAM_LOG_PHY_ADDR_L); - case DRAM_LOG_BUFF_SIZE: - return offsetof(SMU73_SoftRegisters, DRAM_LOG_BUFF_SIZE); - } - case SMU_Discrete_DpmTable: - switch (member) { - case UvdBootLevel: - return offsetof(SMU73_Discrete_DpmTable, UvdBootLevel); - case VceBootLevel: - return offsetof(SMU73_Discrete_DpmTable, VceBootLevel); - case SamuBootLevel: - return offsetof(SMU73_Discrete_DpmTable, SamuBootLevel); - case LowSclkInterruptThreshold: - return offsetof(SMU73_Discrete_DpmTable, LowSclkInterruptThreshold); - } - } - pr_warn("can't get the offset of type %x member %x\n", type, member); - return 0; -} - -uint32_t fiji_get_mac_definition(uint32_t value) -{ - switch (value) { - case SMU_MAX_LEVELS_GRAPHICS: - return SMU73_MAX_LEVELS_GRAPHICS; - case SMU_MAX_LEVELS_MEMORY: - return SMU73_MAX_LEVELS_MEMORY; - case SMU_MAX_LEVELS_LINK: - return SMU73_MAX_LEVELS_LINK; - case SMU_MAX_ENTRIES_SMIO: - return SMU73_MAX_ENTRIES_SMIO; - case SMU_MAX_LEVELS_VDDC: - return SMU73_MAX_LEVELS_VDDC; - case SMU_MAX_LEVELS_VDDGFX: - return SMU73_MAX_LEVELS_VDDGFX; - case SMU_MAX_LEVELS_VDDCI: - return SMU73_MAX_LEVELS_VDDCI; - case SMU_MAX_LEVELS_MVDD: - return SMU73_MAX_LEVELS_MVDD; - } - - pr_warn("can't get the mac of %x\n", value); - return 0; -} - - -static int fiji_update_uvd_smc_table(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - smu_data->smc_state_table.UvdBootLevel = 0; - if (table_info->mm_dep_table->count > 0) - smu_data->smc_state_table.UvdBootLevel = - (uint8_t) (table_info->mm_dep_table->count - 1); - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + offsetof(SMU73_Discrete_DpmTable, - UvdBootLevel); - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0x00FFFFFF; - mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_UVDDPM) || - phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_UVDDPM_SetEnabledMask, - (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel)); - return 0; -} - -static int fiji_update_vce_smc_table(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smu_data->smc_state_table.VceBootLevel = - (uint8_t) (table_info->mm_dep_table->count - 1); - else - smu_data->smc_state_table.VceBootLevel = 0; - - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + - offsetof(SMU73_Discrete_DpmTable, VceBootLevel); - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0xFF00FFFF; - mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_VCEDPM_SetEnabledMask, - (uint32_t)1 << smu_data->smc_state_table.VceBootLevel); - return 0; -} - -static int fiji_update_samu_smc_table(struct pp_hwmgr *hwmgr) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - - - smu_data->smc_state_table.SamuBootLevel = 0; - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + - offsetof(SMU73_Discrete_DpmTable, SamuBootLevel); - - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0xFFFFFF00; - mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SAMUDPM_SetEnabledMask, - (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); - return 0; -} - -int fiji_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) -{ - switch (type) { - case SMU_UVD_TABLE: - fiji_update_uvd_smc_table(hwmgr); - break; - case SMU_VCE_TABLE: - fiji_update_vce_smc_table(hwmgr); - break; - case SMU_SAMU_TABLE: - fiji_update_samu_smc_table(hwmgr); - break; - default: - break; - } - return 0; -} - - -/** -* Get the location of various tables inside the FW image. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ -int fiji_process_firmware_header(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); - uint32_t tmp; - int result; - bool error = false; - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU73_Firmware_Header, DpmTable), - &tmp, SMC_RAM_END); - - if (0 == result) - smu_data->smu7_data.dpm_table_start = tmp; - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU73_Firmware_Header, SoftRegisters), - &tmp, SMC_RAM_END); - - if (!result) { - data->soft_regs_start = tmp; - smu_data->smu7_data.soft_regs_start = tmp; - } - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU73_Firmware_Header, mcRegisterTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.mc_reg_table_start = tmp; - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU73_Firmware_Header, FanTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.fan_table_start = tmp; - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU73_Firmware_Header, mcArbDramTimingTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.arb_table_start = tmp; - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU73_Firmware_Header, Version), - &tmp, SMC_RAM_END); - - if (!result) - hwmgr->microcode_version_info.SMC = tmp; - - error |= (0 != result); - - return error ? -1 : 0; -} - -int fiji_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - - /* Program additional LP registers - * that are no longer programmed by VBIOS - */ - cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); - - return 0; -} - -bool fiji_is_dpm_running(struct pp_hwmgr *hwmgr) -{ - return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, - CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) - ? true : false; -} - -int fiji_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request) -{ - struct fiji_smumgr *smu_data = (struct fiji_smumgr *) - (hwmgr->smu_backend); - struct SMU73_Discrete_GraphicsLevel *levels = - smu_data->smc_state_table.GraphicsLevel; - uint32_t array = smu_data->smu7_data.dpm_table_start + - offsetof(SMU73_Discrete_DpmTable, GraphicsLevel); - uint32_t array_size = sizeof(struct SMU73_Discrete_GraphicsLevel) * - SMU73_MAX_LEVELS_GRAPHICS; - uint32_t i; - - for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { - levels[i].ActivityLevel = - cpu_to_be16(request->activity_threshold); - levels[i].EnabledForActivity = 1; - levels[i].UpHyst = request->up_hyst; - levels[i].DownHyst = request->down_hyst; - } - - return smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - array_size, SMC_RAM_END); -} diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h deleted file mode 100644 index d9c72d992e30..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - */ -#ifndef FIJI_SMC_H -#define FIJI_SMC_H - -#include "smumgr.h" -#include "smu73.h" - -struct fiji_pt_defaults { - uint8_t SviLoadLineEn; - uint8_t SviLoadLineVddC; - uint8_t TDC_VDDC_ThrottleReleaseLimitPerc; - uint8_t TDC_MAWt; - uint8_t TdcWaterfallCtl; - uint8_t DTEAmbientTempBase; -}; - -int fiji_populate_all_graphic_levels(struct pp_hwmgr *hwmgr); -int fiji_populate_all_memory_levels(struct pp_hwmgr *hwmgr); -int fiji_init_smc_table(struct pp_hwmgr *hwmgr); -int fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr); -int fiji_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type); -int fiji_update_sclk_threshold(struct pp_hwmgr *hwmgr); -uint32_t fiji_get_offsetof(uint32_t type, uint32_t member); -uint32_t fiji_get_mac_definition(uint32_t value); -int fiji_process_firmware_header(struct pp_hwmgr *hwmgr); -int fiji_initialize_mc_reg_table(struct pp_hwmgr *hwmgr); -bool fiji_is_dpm_running(struct pp_hwmgr *hwmgr); -int fiji_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request); -int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr); -#endif - diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index ba951c7c2b41..f572beff197f 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -23,6 +23,7 @@ #include "pp_debug.h" #include "smumgr.h" +#include "smu7_dyn_defaults.h" #include "smu73.h" #include "smu_ucode_xfer_vi.h" #include "fiji_smumgr.h" @@ -37,13 +38,54 @@ #include "gca/gfx_8_0_d.h" #include "bif/bif_5_0_d.h" #include "bif/bif_5_0_sh_mask.h" -#include "fiji_smc.h" +#include "dce/dce_10_0_d.h" +#include "dce/dce_10_0_sh_mask.h" +#include "hardwaremanager.h" +#include "cgs_common.h" +#include "atombios.h" +#include "pppcielanes.h" +#include "hwmgr.h" +#include "smu7_hwmgr.h" + #define AVFS_EN_MSB 1568 #define AVFS_EN_LSB 1568 #define FIJI_SMC_SIZE 0x20000 +#define VOLTAGE_SCALE 4 +#define POWERTUNE_DEFAULT_SET_MAX 1 +#define VOLTAGE_VID_OFFSET_SCALE1 625 +#define VOLTAGE_VID_OFFSET_SCALE2 100 +#define VDDC_VDDCI_DELTA 300 +#define MC_CG_ARB_FREQ_F1 0x0b + +/* [2.5%,~2.5%] Clock stretched is multiple of 2.5% vs + * not and [Fmin, Fmax, LDO_REFSEL, USE_FOR_LOW_FREQ] + */ +static const uint16_t fiji_clock_stretcher_lookup_table[2][4] = { + {600, 1050, 3, 0}, {600, 1050, 6, 1} }; + +/* [FF, SS] type, [] 4 voltage ranges, and + * [Floor Freq, Boundary Freq, VID min , VID max] + */ +static const uint32_t fiji_clock_stretcher_ddt_table[2][4][4] = { + { {265, 529, 120, 128}, {325, 650, 96, 119}, {430, 860, 32, 95}, {0, 0, 0, 31} }, + { {275, 550, 104, 112}, {319, 638, 96, 103}, {360, 720, 64, 95}, {384, 768, 32, 63} } }; + +/* [Use_For_Low_freq] value, [0%, 5%, 10%, 7.14%, 14.28%, 20%] + * (coming from PWR_CKS_CNTL.stretch_amount reg spec) + */ +static const uint8_t fiji_clock_stretch_amount_conversion[2][6] = { + {0, 1, 3, 2, 4, 5}, {0, 2, 4, 5, 6, 5} }; + +static const struct fiji_pt_defaults fiji_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { + /*sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc */ + {1, 0xF, 0xFD, + /* TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase */ + 0x19, 5, 45} +}; + static const struct SMU73_Discrete_GraphicsLevel avfs_graphics_level[8] = { /* Min Sclk pcie DeepSleep Activity CgSpll CgSpll spllSpread SpllSpread CcPwr CcPwr Sclk Display Enabled Enabled Voltage Power */ /* Voltage, Frequency, DpmLevel, DivId, Level, FuncCntl3, FuncCntl4, Spectrum, Spectrum2, DynRm, DynRm1 Did, Watermark, ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */ @@ -324,13 +366,6 @@ static bool fiji_is_hw_avfs_present(struct pp_hwmgr *hwmgr) return false; } -/** -* Write a 32bit value to the SMC SRAM space. -* ALL PARAMETERS ARE IN HOST BYTE ORDER. -* @param smumgr the address of the powerplay hardware manager. -* @param smc_addr the address in the SMC RAM to access. -* @param value to write to the SMC SRAM. -*/ static int fiji_smu_init(struct pp_hwmgr *hwmgr) { int i; @@ -352,6 +387,2334 @@ static int fiji_smu_init(struct pp_hwmgr *hwmgr) return 0; } +static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, + struct phm_ppt_v1_clock_voltage_dependency_table *dep_table, + uint32_t clock, uint32_t *voltage, uint32_t *mvdd) +{ + uint32_t i; + uint16_t vddci; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + *voltage = *mvdd = 0; + + + /* clock - voltage dependency table is empty table */ + if (dep_table->count == 0) + return -EINVAL; + + for (i = 0; i < dep_table->count; i++) { + /* find first sclk bigger than request */ + if (dep_table->entries[i].clk >= clock) { + *voltage |= (dep_table->entries[i].vddc * + VOLTAGE_SCALE) << VDDC_SHIFT; + if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) + *voltage |= (data->vbios_boot_state.vddci_bootup_value * + VOLTAGE_SCALE) << VDDCI_SHIFT; + else if (dep_table->entries[i].vddci) + *voltage |= (dep_table->entries[i].vddci * + VOLTAGE_SCALE) << VDDCI_SHIFT; + else { + vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), + (dep_table->entries[i].vddc - + VDDC_VDDCI_DELTA)); + *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + } + + if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) + *mvdd = data->vbios_boot_state.mvdd_bootup_value * + VOLTAGE_SCALE; + else if (dep_table->entries[i].mvdd) + *mvdd = (uint32_t) dep_table->entries[i].mvdd * + VOLTAGE_SCALE; + + *voltage |= 1 << PHASES_SHIFT; + return 0; + } + } + + /* sclk is bigger than max sclk in the dependence table */ + *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; + + if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) + *voltage |= (data->vbios_boot_state.vddci_bootup_value * + VOLTAGE_SCALE) << VDDCI_SHIFT; + else if (dep_table->entries[i-1].vddci) { + vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), + (dep_table->entries[i].vddc - + VDDC_VDDCI_DELTA)); + *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + } + + if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) + *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE; + else if (dep_table->entries[i].mvdd) + *mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE; + + return 0; +} + + +static uint16_t scale_fan_gain_settings(uint16_t raw_setting) +{ + uint32_t tmp; + tmp = raw_setting * 4096 / 100; + return (uint16_t)tmp; +} + +static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t *sda) +{ + switch (line) { + case SMU7_I2CLineID_DDC1: + *scl = SMU7_I2C_DDC1CLK; + *sda = SMU7_I2C_DDC1DATA; + break; + case SMU7_I2CLineID_DDC2: + *scl = SMU7_I2C_DDC2CLK; + *sda = SMU7_I2C_DDC2DATA; + break; + case SMU7_I2CLineID_DDC3: + *scl = SMU7_I2C_DDC3CLK; + *sda = SMU7_I2C_DDC3DATA; + break; + case SMU7_I2CLineID_DDC4: + *scl = SMU7_I2C_DDC4CLK; + *sda = SMU7_I2C_DDC4DATA; + break; + case SMU7_I2CLineID_DDC5: + *scl = SMU7_I2C_DDC5CLK; + *sda = SMU7_I2C_DDC5DATA; + break; + case SMU7_I2CLineID_DDC6: + *scl = SMU7_I2C_DDC6CLK; + *sda = SMU7_I2C_DDC6DATA; + break; + case SMU7_I2CLineID_SCLSDA: + *scl = SMU7_I2C_SCL; + *sda = SMU7_I2C_SDA; + break; + case SMU7_I2CLineID_DDCVGA: + *scl = SMU7_I2C_DDCVGACLK; + *sda = SMU7_I2C_DDCVGADATA; + break; + default: + *scl = 0; + *sda = 0; + break; + } +} + +static void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + if (table_info && + table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && + table_info->cac_dtp_table->usPowerTuneDataSetID) + smu_data->power_tune_defaults = + &fiji_power_tune_data_set_array + [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; + else + smu_data->power_tune_defaults = &fiji_power_tune_data_set_array[0]; + +} + +static int fiji_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) +{ + + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; + + SMU73_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); + + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; + struct pp_advance_fan_control_parameters *fan_table = + &hwmgr->thermal_controller.advanceFanControlParameters; + uint8_t uc_scl, uc_sda; + + /* TDP number of fraction bits are changed from 8 to 7 for Fiji + * as requested by SMC team + */ + dpm_table->DefaultTdp = PP_HOST_TO_SMC_US( + (uint16_t)(cac_dtp_table->usTDP * 128)); + dpm_table->TargetTdp = PP_HOST_TO_SMC_US( + (uint16_t)(cac_dtp_table->usTDP * 128)); + + PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, + "Target Operating Temp is out of Range!", + ); + + dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp); + dpm_table->GpuTjHyst = 8; + + dpm_table->DTEAmbientTempBase = defaults->DTEAmbientTempBase; + + /* The following are for new Fiji Multi-input fan/thermal control */ + dpm_table->TemperatureLimitEdge = PP_HOST_TO_SMC_US( + cac_dtp_table->usTargetOperatingTemp * 256); + dpm_table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US( + cac_dtp_table->usTemperatureLimitHotspot * 256); + dpm_table->TemperatureLimitLiquid1 = PP_HOST_TO_SMC_US( + cac_dtp_table->usTemperatureLimitLiquid1 * 256); + dpm_table->TemperatureLimitLiquid2 = PP_HOST_TO_SMC_US( + cac_dtp_table->usTemperatureLimitLiquid2 * 256); + dpm_table->TemperatureLimitVrVddc = PP_HOST_TO_SMC_US( + cac_dtp_table->usTemperatureLimitVrVddc * 256); + dpm_table->TemperatureLimitVrMvdd = PP_HOST_TO_SMC_US( + cac_dtp_table->usTemperatureLimitVrMvdd * 256); + dpm_table->TemperatureLimitPlx = PP_HOST_TO_SMC_US( + cac_dtp_table->usTemperatureLimitPlx * 256); + + dpm_table->FanGainEdge = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainEdge)); + dpm_table->FanGainHotspot = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainHotspot)); + dpm_table->FanGainLiquid = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainLiquid)); + dpm_table->FanGainVrVddc = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainVrVddc)); + dpm_table->FanGainVrMvdd = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainVrMvdd)); + dpm_table->FanGainPlx = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainPlx)); + dpm_table->FanGainHbm = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainHbm)); + + dpm_table->Liquid1_I2C_address = cac_dtp_table->ucLiquid1_I2C_address; + dpm_table->Liquid2_I2C_address = cac_dtp_table->ucLiquid2_I2C_address; + dpm_table->Vr_I2C_address = cac_dtp_table->ucVr_I2C_address; + dpm_table->Plx_I2C_address = cac_dtp_table->ucPlx_I2C_address; + + get_scl_sda_value(cac_dtp_table->ucLiquid_I2C_Line, &uc_scl, &uc_sda); + dpm_table->Liquid_I2C_LineSCL = uc_scl; + dpm_table->Liquid_I2C_LineSDA = uc_sda; + + get_scl_sda_value(cac_dtp_table->ucVr_I2C_Line, &uc_scl, &uc_sda); + dpm_table->Vr_I2C_LineSCL = uc_scl; + dpm_table->Vr_I2C_LineSDA = uc_sda; + + get_scl_sda_value(cac_dtp_table->ucPlx_I2C_Line, &uc_scl, &uc_sda); + dpm_table->Plx_I2C_LineSCL = uc_scl; + dpm_table->Plx_I2C_LineSDA = uc_sda; + + return 0; +} + + +static int fiji_populate_svi_load_line(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; + + smu_data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn; + smu_data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC; + smu_data->power_tune_table.SviLoadLineTrimVddC = 3; + smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; + + return 0; +} + + +static int fiji_populate_tdc_limit(struct pp_hwmgr *hwmgr) +{ + uint16_t tdc_limit; + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; + + /* TDC number of fraction bits are changed from 8 to 7 + * for Fiji as requested by SMC team + */ + tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128); + smu_data->power_tune_table.TDC_VDDC_PkgLimit = + CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); + smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = + defaults->TDC_VDDC_ThrottleReleaseLimitPerc; + smu_data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt; + + return 0; +} + +static int fiji_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + const struct fiji_pt_defaults *defaults = smu_data->power_tune_defaults; + uint32_t temp; + + if (smu7_read_smc_sram_dword(hwmgr, + fuse_table_offset + + offsetof(SMU73_Discrete_PmFuses, TdcWaterfallCtl), + (uint32_t *)&temp, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", + return -EINVAL); + else { + smu_data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl; + smu_data->power_tune_table.LPMLTemperatureMin = + (uint8_t)((temp >> 16) & 0xff); + smu_data->power_tune_table.LPMLTemperatureMax = + (uint8_t)((temp >> 8) & 0xff); + smu_data->power_tune_table.Reserved = (uint8_t)(temp & 0xff); + } + return 0; +} + +static int fiji_populate_temperature_scaler(struct pp_hwmgr *hwmgr) +{ + int i; + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + + /* Currently not used. Set all to zero. */ + for (i = 0; i < 16; i++) + smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0; + + return 0; +} + +static int fiji_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + + if ((hwmgr->thermal_controller.advanceFanControlParameters. + usFanOutputSensitivity & (1 << 15)) || + 0 == hwmgr->thermal_controller.advanceFanControlParameters. + usFanOutputSensitivity) + hwmgr->thermal_controller.advanceFanControlParameters. + usFanOutputSensitivity = hwmgr->thermal_controller. + advanceFanControlParameters.usDefaultFanOutputSensitivity; + + smu_data->power_tune_table.FuzzyFan_PwmSetDelta = + PP_HOST_TO_SMC_US(hwmgr->thermal_controller. + advanceFanControlParameters.usFanOutputSensitivity); + return 0; +} + +static int fiji_populate_gnb_lpml(struct pp_hwmgr *hwmgr) +{ + int i; + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + + /* Currently not used. Set all to zero. */ + for (i = 0; i < 16; i++) + smu_data->power_tune_table.GnbLPML[i] = 0; + + return 0; +} + +static int fiji_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint16_t HiSidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; + uint16_t LoSidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; + struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; + + HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); + LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); + + smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = + CONVERT_FROM_HOST_TO_SMC_US(HiSidd); + smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = + CONVERT_FROM_HOST_TO_SMC_US(LoSidd); + + return 0; +} + +static int fiji_populate_pm_fuses(struct pp_hwmgr *hwmgr) +{ + uint32_t pm_fuse_table_offset; + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment)) { + if (smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU73_Firmware_Header, PmFuseTable), + &pm_fuse_table_offset, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to get pm_fuse_table_offset Failed!", + return -EINVAL); + + /* DW6 */ + if (fiji_populate_svi_load_line(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate SviLoadLine Failed!", + return -EINVAL); + /* DW7 */ + if (fiji_populate_tdc_limit(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TDCLimit Failed!", return -EINVAL); + /* DW8 */ + if (fiji_populate_dw8(hwmgr, pm_fuse_table_offset)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TdcWaterfallCtl, " + "LPMLTemperature Min and Max Failed!", + return -EINVAL); + + /* DW9-DW12 */ + if (0 != fiji_populate_temperature_scaler(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate LPMLTemperatureScaler Failed!", + return -EINVAL); + + /* DW13-DW14 */ + if (fiji_populate_fuzzy_fan(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate Fuzzy Fan Control parameters Failed!", + return -EINVAL); + + /* DW15-DW18 */ + if (fiji_populate_gnb_lpml(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate GnbLPML Failed!", + return -EINVAL); + + /* DW20 */ + if (fiji_populate_bapm_vddc_base_leakage_sidd(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate BapmVddCBaseLeakage Hi and Lo " + "Sidd Failed!", return -EINVAL); + + if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, + (uint8_t *)&smu_data->power_tune_table, + sizeof(struct SMU73_Discrete_PmFuses), SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to download PmFuseTable Failed!", + return -EINVAL); + } + return 0; +} + +static int fiji_populate_cac_table(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_DpmTable *table) +{ + uint32_t count; + uint8_t index; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_voltage_lookup_table *lookup_table = + table_info->vddc_lookup_table; + /* tables is already swapped, so in order to use the value from it, + * we need to swap it back. + * We are populating vddc CAC data to BapmVddc table + * in split and merged mode + */ + + for (count = 0; count < lookup_table->count; count++) { + index = phm_get_voltage_index(lookup_table, + data->vddc_voltage_table.entries[count].value); + table->BapmVddcVidLoSidd[count] = + convert_to_vid(lookup_table->entries[index].us_cac_low); + table->BapmVddcVidHiSidd[count] = + convert_to_vid(lookup_table->entries[index].us_cac_high); + } + + return 0; +} + +static int fiji_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_DpmTable *table) +{ + int result; + + result = fiji_populate_cac_table(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "can not populate CAC voltage tables to SMC", + return -EINVAL); + + return 0; +} + +static int fiji_populate_ulv_level(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_Ulv *state) +{ + int result = 0; + + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + state->CcPwrDynRm = 0; + state->CcPwrDynRm1 = 0; + + state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset; + state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset * + VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1); + + state->VddcPhase = 1; + + if (!result) { + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); + CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); + } + return result; +} + +static int fiji_populate_ulv_state(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_DpmTable *table) +{ + return fiji_populate_ulv_level(hwmgr, &table->Ulv); +} + +static int fiji_populate_smc_link_level(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + int i; + + /* Index (dpm_table->pcie_speed_table.count) + * is reserved for PCIE boot level. */ + for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { + table->LinkLevel[i].PcieGenSpeed = + (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; + table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width( + dpm_table->pcie_speed_table.dpm_levels[i].param1); + table->LinkLevel[i].EnabledForActivity = 1; + table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff); + table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5); + table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30); + } + + smu_data->smc_state_table.LinkLevelCount = + (uint8_t)dpm_table->pcie_speed_table.count; + data->dpm_level_enable_mask.pcie_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); + + return 0; +} + +static int fiji_calculate_sclk_params(struct pp_hwmgr *hwmgr, + uint32_t clock, struct SMU73_Discrete_GraphicsLevel *sclk) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct pp_atomctrl_clock_dividers_vi dividers; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + uint32_t ref_clock; + uint32_t ref_divider; + uint32_t fbdiv; + int result; + + /* get the engine clock dividers for this clock value */ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, clock, ÷rs); + + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", + return result); + + /* To get FBDIV we need to multiply this by 16384 and divide it by Fref. */ + ref_clock = atomctrl_get_reference_clock(hwmgr); + ref_divider = 1 + dividers.uc_pll_ref_div; + + /* low 14 bits is fraction and high 12 bits is divider */ + fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; + + /* SPLL_FUNC_CNTL setup */ + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_REF_DIV, dividers.uc_pll_ref_div); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_PDIV_A, dividers.uc_pll_post_div); + + /* SPLL_FUNC_CNTL_3 setup*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, + SPLL_FB_DIV, fbdiv); + + /* set to use fractional accumulation*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, CG_SPLL_FUNC_CNTL_3, + SPLL_DITHEN, 1); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { + struct pp_atomctrl_internal_ss_info ssInfo; + + uint32_t vco_freq = clock * dividers.uc_pll_post_div; + if (!atomctrl_get_engine_clock_spread_spectrum(hwmgr, + vco_freq, &ssInfo)) { + /* + * ss_info.speed_spectrum_percentage -- in unit of 0.01% + * ss_info.speed_spectrum_rate -- in unit of khz + * + * clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 + */ + uint32_t clk_s = ref_clock * 5 / + (ref_divider * ssInfo.speed_spectrum_rate); + /* clkv = 2 * D * fbdiv / NS */ + uint32_t clk_v = 4 * ssInfo.speed_spectrum_percentage * + fbdiv / (clk_s * 10000); + + cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, + CG_SPLL_SPREAD_SPECTRUM, CLKS, clk_s); + cg_spll_spread_spectrum = PHM_SET_FIELD(cg_spll_spread_spectrum, + CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); + cg_spll_spread_spectrum_2 = PHM_SET_FIELD(cg_spll_spread_spectrum_2, + CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clk_v); + } + } + + sclk->SclkFrequency = clock; + sclk->CgSpllFuncCntl3 = spll_func_cntl_3; + sclk->CgSpllFuncCntl4 = spll_func_cntl_4; + sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; + sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; + sclk->SclkDid = (uint8_t)dividers.pll_post_divider; + + return 0; +} + +static int fiji_populate_single_graphic_level(struct pp_hwmgr *hwmgr, + uint32_t clock, uint16_t sclk_al_threshold, + struct SMU73_Discrete_GraphicsLevel *level) +{ + int result; + /* PP_Clocks minClocks; */ + uint32_t threshold, mvdd; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + result = fiji_calculate_sclk_params(hwmgr, clock, level); + + /* populate graphics levels */ + result = fiji_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_sclk, clock, + (uint32_t *)(&level->MinVoltage), &mvdd); + PP_ASSERT_WITH_CODE((0 == result), + "can not find VDDC voltage value for " + "VDDC engine clock dependency table", + return result); + + level->SclkFrequency = clock; + level->ActivityLevel = sclk_al_threshold; + level->CcPwrDynRm = 0; + level->CcPwrDynRm1 = 0; + level->EnabledForActivity = 0; + level->EnabledForThrottle = 1; + level->UpHyst = 10; + level->DownHyst = 0; + level->VoltageDownHyst = 0; + level->PowerThrottle = 0; + + threshold = clock * data->fast_watermark_threshold / 100; + + data->display_timing.min_clock_in_sr = hwmgr->display_config.min_core_set_clock_in_sr; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) + level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock, + hwmgr->display_config.min_core_set_clock_in_sr); + + + /* Default to slow, highest DPM level will be + * set to PPSMC_DISPLAY_WATERMARK_LOW later. + */ + level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage); + CONVERT_FROM_HOST_TO_SMC_UL(level->SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(level->CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(level->SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1); + + return 0; +} + +static int fiji_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + + struct smu7_dpm_table *dpm_table = &data->dpm_table; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table; + uint8_t pcie_entry_cnt = (uint8_t) data->dpm_table.pcie_speed_table.count; + int result = 0; + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU73_Discrete_DpmTable, GraphicsLevel); + uint32_t array_size = sizeof(struct SMU73_Discrete_GraphicsLevel) * + SMU73_MAX_LEVELS_GRAPHICS; + struct SMU73_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t i, max_entry; + uint8_t hightest_pcie_level_enabled = 0, + lowest_pcie_level_enabled = 0, + mid_pcie_level_enabled = 0, + count = 0; + + for (i = 0; i < dpm_table->sclk_table.count; i++) { + result = fiji_populate_single_graphic_level(hwmgr, + dpm_table->sclk_table.dpm_levels[i].value, + (uint16_t)smu_data->activity_target[i], + &levels[i]); + if (result) + return result; + + /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ + if (i > 1) + levels[i].DeepSleepDivId = 0; + } + + /* Only enable level 0 for now.*/ + levels[0].EnabledForActivity = 1; + + /* set highest level watermark to high */ + levels[dpm_table->sclk_table.count - 1].DisplayWatermark = + PPSMC_DISPLAY_WATERMARK_HIGH; + + smu_data->smc_state_table.GraphicsDpmLevelCount = + (uint8_t)dpm_table->sclk_table.count; + data->dpm_level_enable_mask.sclk_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); + + if (pcie_table != NULL) { + PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt), + "There must be 1 or more PCIE levels defined in PPTable.", + return -EINVAL); + max_entry = pcie_entry_cnt - 1; + for (i = 0; i < dpm_table->sclk_table.count; i++) + levels[i].pcieDpmLevel = + (uint8_t) ((i < max_entry) ? i : max_entry); + } else { + while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && + ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << (hightest_pcie_level_enabled + 1))) != 0)) + hightest_pcie_level_enabled++; + + while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && + ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << lowest_pcie_level_enabled)) == 0)) + lowest_pcie_level_enabled++; + + while ((count < hightest_pcie_level_enabled) && + ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << (lowest_pcie_level_enabled + 1 + count))) == 0)) + count++; + + mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1 + count) < + hightest_pcie_level_enabled ? + (lowest_pcie_level_enabled + 1 + count) : + hightest_pcie_level_enabled; + + /* set pcieDpmLevel to hightest_pcie_level_enabled */ + for (i = 2; i < dpm_table->sclk_table.count; i++) + levels[i].pcieDpmLevel = hightest_pcie_level_enabled; + + /* set pcieDpmLevel to lowest_pcie_level_enabled */ + levels[0].pcieDpmLevel = lowest_pcie_level_enabled; + + /* set pcieDpmLevel to mid_pcie_level_enabled */ + levels[1].pcieDpmLevel = mid_pcie_level_enabled; + } + /* level count will send to smc once at init smc table and never change */ + result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + (uint32_t)array_size, SMC_RAM_END); + + return result; +} + + +/** + * MCLK Frequency Ratio + * SEQ_CG_RESP Bit[31:24] - 0x0 + * Bit[27:24] \96 DDR3 Frequency ratio + * 0x0 <= 100MHz, 450 < 0x8 <= 500MHz + * 100 < 0x1 <= 150MHz, 500 < 0x9 <= 550MHz + * 150 < 0x2 <= 200MHz, 550 < 0xA <= 600MHz + * 200 < 0x3 <= 250MHz, 600 < 0xB <= 650MHz + * 250 < 0x4 <= 300MHz, 650 < 0xC <= 700MHz + * 300 < 0x5 <= 350MHz, 700 < 0xD <= 750MHz + * 350 < 0x6 <= 400MHz, 750 < 0xE <= 800MHz + * 400 < 0x7 <= 450MHz, 800 < 0xF + */ +static uint8_t fiji_get_mclk_frequency_ratio(uint32_t mem_clock) +{ + if (mem_clock <= 10000) + return 0x0; + if (mem_clock <= 15000) + return 0x1; + if (mem_clock <= 20000) + return 0x2; + if (mem_clock <= 25000) + return 0x3; + if (mem_clock <= 30000) + return 0x4; + if (mem_clock <= 35000) + return 0x5; + if (mem_clock <= 40000) + return 0x6; + if (mem_clock <= 45000) + return 0x7; + if (mem_clock <= 50000) + return 0x8; + if (mem_clock <= 55000) + return 0x9; + if (mem_clock <= 60000) + return 0xa; + if (mem_clock <= 65000) + return 0xb; + if (mem_clock <= 70000) + return 0xc; + if (mem_clock <= 75000) + return 0xd; + if (mem_clock <= 80000) + return 0xe; + /* mem_clock > 800MHz */ + return 0xf; +} + +static int fiji_calculate_mclk_params(struct pp_hwmgr *hwmgr, + uint32_t clock, struct SMU73_Discrete_MemoryLevel *mclk) +{ + struct pp_atomctrl_memory_clock_param mem_param; + int result; + + result = atomctrl_get_memory_pll_dividers_vi(hwmgr, clock, &mem_param); + PP_ASSERT_WITH_CODE((0 == result), + "Failed to get Memory PLL Dividers.", + ); + + /* Save the result data to outpupt memory level structure */ + mclk->MclkFrequency = clock; + mclk->MclkDivider = (uint8_t)mem_param.mpll_post_divider; + mclk->FreqRange = fiji_get_mclk_frequency_ratio(clock); + + return result; +} + +static int fiji_populate_single_memory_level(struct pp_hwmgr *hwmgr, + uint32_t clock, struct SMU73_Discrete_MemoryLevel *mem_level) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + int result = 0; + uint32_t mclk_stutter_mode_threshold = 60000; + + if (table_info->vdd_dep_on_mclk) { + result = fiji_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_mclk, clock, + (uint32_t *)(&mem_level->MinVoltage), &mem_level->MinMvdd); + PP_ASSERT_WITH_CODE((0 == result), + "can not find MinVddc voltage value from memory " + "VDDC voltage dependency table", return result); + } + + mem_level->EnabledForThrottle = 1; + mem_level->EnabledForActivity = 0; + mem_level->UpHyst = 0; + mem_level->DownHyst = 100; + mem_level->VoltageDownHyst = 0; + mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target; + mem_level->StutterEnable = false; + + mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + /* enable stutter mode if all the follow condition applied + * PECI_GetNumberOfActiveDisplays(hwmgr->pPECI, + * &(data->DisplayTiming.numExistingDisplays)); + */ + data->display_timing.num_existing_displays = 1; + + if (mclk_stutter_mode_threshold && + (clock <= mclk_stutter_mode_threshold) && + (!data->is_uvd_enabled) && + (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, + STUTTER_ENABLE) & 0x1)) + mem_level->StutterEnable = true; + + result = fiji_calculate_mclk_params(hwmgr, clock, mem_level); + if (!result) { + CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinMvdd); + CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(mem_level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinVoltage); + } + return result; +} + +static int fiji_populate_all_memory_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + int result; + /* populate MCLK dpm table to SMU7 */ + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU73_Discrete_DpmTable, MemoryLevel); + uint32_t array_size = sizeof(SMU73_Discrete_MemoryLevel) * + SMU73_MAX_LEVELS_MEMORY; + struct SMU73_Discrete_MemoryLevel *levels = + smu_data->smc_state_table.MemoryLevel; + uint32_t i; + + for (i = 0; i < dpm_table->mclk_table.count; i++) { + PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), + "can not populate memory level as memory clock is zero", + return -EINVAL); + result = fiji_populate_single_memory_level(hwmgr, + dpm_table->mclk_table.dpm_levels[i].value, + &levels[i]); + if (result) + return result; + } + + /* Only enable level 0 for now. */ + levels[0].EnabledForActivity = 1; + + /* in order to prevent MC activity from stutter mode to push DPM up. + * the UVD change complements this by putting the MCLK in + * a higher state by default such that we are not effected by + * up threshold or and MCLK DPM latency. + */ + levels[0].ActivityLevel = (uint16_t)data->mclk_dpm0_activity_target; + CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel); + + smu_data->smc_state_table.MemoryDpmLevelCount = + (uint8_t)dpm_table->mclk_table.count; + data->dpm_level_enable_mask.mclk_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); + /* set highest level watermark to high */ + levels[dpm_table->mclk_table.count - 1].DisplayWatermark = + PPSMC_DISPLAY_WATERMARK_HIGH; + + /* level count will send to smc once at init smc table and never change */ + result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + (uint32_t)array_size, SMC_RAM_END); + + return result; +} + +static int fiji_populate_mvdd_value(struct pp_hwmgr *hwmgr, + uint32_t mclk, SMIO_Pattern *smio_pat) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint32_t i = 0; + + if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { + /* find mvdd value which clock is more than request */ + for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) { + if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) { + smio_pat->Voltage = data->mvdd_voltage_table.entries[i].value; + break; + } + } + PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count, + "MVDD Voltage is outside the supported range.", + return -EINVAL); + } else + return -EINVAL; + + return 0; +} + +static int fiji_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, + SMU73_Discrete_DpmTable *table) +{ + int result = 0; + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct pp_atomctrl_clock_dividers_vi dividers; + SMIO_Pattern vol_level; + uint32_t mvdd; + uint16_t us_mvdd; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; + + table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; + + if (!data->sclk_dpm_key_disabled) { + /* Get MinVoltage and Frequency from DPM0, + * already converted to SMC_UL */ + table->ACPILevel.SclkFrequency = + data->dpm_table.sclk_table.dpm_levels[0].value; + result = fiji_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_sclk, + table->ACPILevel.SclkFrequency, + (uint32_t *)(&table->ACPILevel.MinVoltage), &mvdd); + PP_ASSERT_WITH_CODE((0 == result), + "Cannot find ACPI VDDC voltage value " \ + "in Clock Dependency Table", + ); + } else { + table->ACPILevel.SclkFrequency = + data->vbios_boot_state.sclk_bootup_value; + table->ACPILevel.MinVoltage = + data->vbios_boot_state.vddc_bootup_value * VOLTAGE_SCALE; + } + + /* get the engine clock dividers for this clock value */ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, + table->ACPILevel.SclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", + return result); + + table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; + table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + table->ACPILevel.DeepSleepDivId = 0; + + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_PWRON, 0); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_RESET, 1); + spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, CG_SPLL_FUNC_CNTL_2, + SCLK_MUX_SEL, 4); + + table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; + table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; + table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + table->ACPILevel.CcPwrDynRm = 0; + table->ACPILevel.CcPwrDynRm1 = 0; + + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.MinVoltage); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); + + if (!data->mclk_dpm_key_disabled) { + /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */ + table->MemoryACPILevel.MclkFrequency = + data->dpm_table.mclk_table.dpm_levels[0].value; + result = fiji_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_mclk, + table->MemoryACPILevel.MclkFrequency, + (uint32_t *)(&table->MemoryACPILevel.MinVoltage), &mvdd); + PP_ASSERT_WITH_CODE((0 == result), + "Cannot find ACPI VDDCI voltage value in Clock Dependency Table", + ); + } else { + table->MemoryACPILevel.MclkFrequency = + data->vbios_boot_state.mclk_bootup_value; + table->MemoryACPILevel.MinVoltage = + data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE; + } + + us_mvdd = 0; + if ((SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) || + (data->mclk_dpm_key_disabled)) + us_mvdd = data->vbios_boot_state.mvdd_bootup_value; + else { + if (!fiji_populate_mvdd_value(hwmgr, + data->dpm_table.mclk_table.dpm_levels[0].value, + &vol_level)) + us_mvdd = vol_level.Voltage; + } + + table->MemoryACPILevel.MinMvdd = + PP_HOST_TO_SMC_UL(us_mvdd * VOLTAGE_SCALE); + + table->MemoryACPILevel.EnabledForThrottle = 0; + table->MemoryACPILevel.EnabledForActivity = 0; + table->MemoryACPILevel.UpHyst = 0; + table->MemoryACPILevel.DownHyst = 100; + table->MemoryACPILevel.VoltageDownHyst = 0; + table->MemoryACPILevel.ActivityLevel = + PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); + + table->MemoryACPILevel.StutterEnable = false; + CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage); + + return result; +} + +static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr, + SMU73_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + table_info->mm_dep_table; + + table->VceLevelCount = (uint8_t)(mm_table->count); + table->VceBootLevel = 0; + + for (count = 0; count < table->VceLevelCount; count++) { + table->VceLevel[count].Frequency = mm_table->entries[count].eclk; + table->VceLevel[count].MinVoltage = 0; + table->VceLevel[count].MinVoltage |= + (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; + table->VceLevel[count].MinVoltage |= + ((mm_table->entries[count].vddc - VDDC_VDDCI_DELTA) * + VOLTAGE_SCALE) << VDDCI_SHIFT; + table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT; + + /*retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->VceLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for VCE engine clock", + return result); + + table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage); + } + return result; +} + +static int fiji_populate_smc_acp_level(struct pp_hwmgr *hwmgr, + SMU73_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + table_info->mm_dep_table; + + table->AcpLevelCount = (uint8_t)(mm_table->count); + table->AcpBootLevel = 0; + + for (count = 0; count < table->AcpLevelCount; count++) { + table->AcpLevel[count].Frequency = mm_table->entries[count].aclk; + table->AcpLevel[count].MinVoltage |= (mm_table->entries[count].vddc * + VOLTAGE_SCALE) << VDDC_SHIFT; + table->AcpLevel[count].MinVoltage |= ((mm_table->entries[count].vddc - + VDDC_VDDCI_DELTA) * VOLTAGE_SCALE) << VDDCI_SHIFT; + table->AcpLevel[count].MinVoltage |= 1 << PHASES_SHIFT; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->AcpLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for engine clock", return result); + + table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].MinVoltage); + } + return result; +} + +static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr, + SMU73_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + table_info->mm_dep_table; + + table->SamuBootLevel = 0; + table->SamuLevelCount = (uint8_t)(mm_table->count); + + for (count = 0; count < table->SamuLevelCount; count++) { + /* not sure whether we need evclk or not */ + table->SamuLevel[count].MinVoltage = 0; + table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; + table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * + VOLTAGE_SCALE) << VDDC_SHIFT; + table->SamuLevel[count].MinVoltage |= ((mm_table->entries[count].vddc - + VDDC_VDDCI_DELTA) * VOLTAGE_SCALE) << VDDCI_SHIFT; + table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->SamuLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for samu clock", return result); + + table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage); + } + return result; +} + +static int fiji_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr, + int32_t eng_clock, int32_t mem_clock, + struct SMU73_Discrete_MCArbDramTimingTableEntry *arb_regs) +{ + uint32_t dram_timing; + uint32_t dram_timing2; + uint32_t burstTime; + ULONG state, trrds, trrdl; + int result; + + result = atomctrl_set_engine_dram_timings_rv770(hwmgr, + eng_clock, mem_clock); + PP_ASSERT_WITH_CODE(result == 0, + "Error calling VBIOS to set DRAM_TIMING.", return result); + + dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); + dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); + burstTime = cgs_read_register(hwmgr->device, mmMC_ARB_BURST_TIME); + + state = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, STATE0); + trrds = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, TRRDS0); + trrdl = PHM_GET_FIELD(burstTime, MC_ARB_BURST_TIME, TRRDL0); + + arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dram_timing); + arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dram_timing2); + arb_regs->McArbBurstTime = (uint8_t)burstTime; + arb_regs->TRRDS = (uint8_t)trrds; + arb_regs->TRRDL = (uint8_t)trrdl; + + return 0; +} + +static int fiji_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct SMU73_Discrete_MCArbDramTimingTable arb_regs; + uint32_t i, j; + int result = 0; + + for (i = 0; i < data->dpm_table.sclk_table.count; i++) { + for (j = 0; j < data->dpm_table.mclk_table.count; j++) { + result = fiji_populate_memory_timing_parameters(hwmgr, + data->dpm_table.sclk_table.dpm_levels[i].value, + data->dpm_table.mclk_table.dpm_levels[j].value, + &arb_regs.entries[i][j]); + if (result) + break; + } + } + + if (!result) + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.arb_table_start, + (uint8_t *)&arb_regs, + sizeof(SMU73_Discrete_MCArbDramTimingTable), + SMC_RAM_END); + return result; +} + +static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + table_info->mm_dep_table; + + table->UvdLevelCount = (uint8_t)(mm_table->count); + table->UvdBootLevel = 0; + + for (count = 0; count < table->UvdLevelCount; count++) { + table->UvdLevel[count].MinVoltage = 0; + table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; + table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; + table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * + VOLTAGE_SCALE) << VDDC_SHIFT; + table->UvdLevel[count].MinVoltage |= ((mm_table->entries[count].vddc - + VDDC_VDDCI_DELTA) * VOLTAGE_SCALE) << VDDCI_SHIFT; + table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->UvdLevel[count].VclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for Vclk clock", return result); + + table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; + + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->UvdLevel[count].DclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for Dclk clock", return result); + + table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage); + + } + return result; +} + +static int fiji_populate_smc_boot_level(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_DpmTable *table) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + table->GraphicsBootLevel = 0; + table->MemoryBootLevel = 0; + + /* find boot level from dpm table */ + result = phm_find_boot_level(&(data->dpm_table.sclk_table), + data->vbios_boot_state.sclk_bootup_value, + (uint32_t *)&(table->GraphicsBootLevel)); + + result = phm_find_boot_level(&(data->dpm_table.mclk_table), + data->vbios_boot_state.mclk_bootup_value, + (uint32_t *)&(table->MemoryBootLevel)); + + table->BootVddc = data->vbios_boot_state.vddc_bootup_value * + VOLTAGE_SCALE; + table->BootVddci = data->vbios_boot_state.vddci_bootup_value * + VOLTAGE_SCALE; + table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value * + VOLTAGE_SCALE; + + CONVERT_FROM_HOST_TO_SMC_US(table->BootVddc); + CONVERT_FROM_HOST_TO_SMC_US(table->BootVddci); + CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd); + + return 0; +} + +static int fiji_populate_smc_initailial_state(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint8_t count, level; + + count = (uint8_t)(table_info->vdd_dep_on_sclk->count); + for (level = 0; level < count; level++) { + if (table_info->vdd_dep_on_sclk->entries[level].clk >= + data->vbios_boot_state.sclk_bootup_value) { + smu_data->smc_state_table.GraphicsBootLevel = level; + break; + } + } + + count = (uint8_t)(table_info->vdd_dep_on_mclk->count); + for (level = 0; level < count; level++) { + if (table_info->vdd_dep_on_mclk->entries[level].clk >= + data->vbios_boot_state.mclk_bootup_value) { + smu_data->smc_state_table.MemoryBootLevel = level; + break; + } + } + + return 0; +} + +static int fiji_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) +{ + uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks, + volt_with_cks, value; + uint16_t clock_freq_u16; + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2, + volt_offset = 0; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = + table_info->vdd_dep_on_sclk; + + stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount; + + /* Read SMU_Eefuse to read and calculate RO and determine + * if the part is SS or FF. if RO >= 1660MHz, part is FF. + */ + efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixSMU_EFUSE_0 + (146 * 4)); + efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixSMU_EFUSE_0 + (148 * 4)); + efuse &= 0xFF000000; + efuse = efuse >> 24; + efuse2 &= 0xF; + + if (efuse2 == 1) + ro = (2300 - 1350) * efuse / 255 + 1350; + else + ro = (2500 - 1000) * efuse / 255 + 1000; + + if (ro >= 1660) + type = 0; + else + type = 1; + + /* Populate Stretch amount */ + smu_data->smc_state_table.ClockStretcherAmount = stretch_amount; + + /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ + for (i = 0; i < sclk_table->count; i++) { + smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= + sclk_table->entries[i].cks_enable << i; + volt_without_cks = (uint32_t)((14041 * + (sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 / + (4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000))); + volt_with_cks = (uint32_t)((13946 * + (sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 / + (3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000))); + if (volt_without_cks >= volt_with_cks) + volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + + sclk_table->entries[i].cks_voffset) * 100 / 625) + 1); + smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; + } + + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + STRETCH_ENABLE, 0x0); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + masterReset, 0x1); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + staticEnable, 0x1); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + masterReset, 0x0); + + /* Populate CKS Lookup Table */ + if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) + stretch_amount2 = 0; + else if (stretch_amount == 3 || stretch_amount == 4) + stretch_amount2 = 1; + else { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ClockStretcher); + PP_ASSERT_WITH_CODE(false, + "Stretch Amount in PPTable not supported\n", + return -EINVAL); + } + + value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixPWR_CKS_CNTL); + value &= 0xFFC2FF87; + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq = + fiji_clock_stretcher_lookup_table[stretch_amount2][0]; + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq = + fiji_clock_stretcher_lookup_table[stretch_amount2][1]; + clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(smu_data->smc_state_table. + GraphicsLevel[smu_data->smc_state_table.GraphicsDpmLevelCount - 1]. + SclkFrequency) / 100); + if (fiji_clock_stretcher_lookup_table[stretch_amount2][0] < + clock_freq_u16 && + fiji_clock_stretcher_lookup_table[stretch_amount2][1] > + clock_freq_u16) { + /* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */ + value |= (fiji_clock_stretcher_lookup_table[stretch_amount2][3]) << 16; + /* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */ + value |= (fiji_clock_stretcher_lookup_table[stretch_amount2][2]) << 18; + /* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */ + value |= (fiji_clock_stretch_amount_conversion + [fiji_clock_stretcher_lookup_table[stretch_amount2][3]] + [stretch_amount]) << 3; + } + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. + CKS_LOOKUPTableEntry[0].minFreq); + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. + CKS_LOOKUPTableEntry[0].maxFreq); + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting = + fiji_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F; + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |= + (fiji_clock_stretcher_lookup_table[stretch_amount2][3]) << 7; + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixPWR_CKS_CNTL, value); + + /* Populate DDT Lookup Table */ + for (i = 0; i < 4; i++) { + /* Assign the minimum and maximum VID stored + * in the last row of Clock Stretcher Voltage Table. + */ + smu_data->smc_state_table.ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].minVID = + (uint8_t) fiji_clock_stretcher_ddt_table[type][i][2]; + smu_data->smc_state_table.ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].maxVID = + (uint8_t) fiji_clock_stretcher_ddt_table[type][i][3]; + /* Loop through each SCLK and check the frequency + * to see if it lies within the frequency for clock stretcher. + */ + for (j = 0; j < smu_data->smc_state_table.GraphicsDpmLevelCount; j++) { + cks_setting = 0; + clock_freq = PP_SMC_TO_HOST_UL( + smu_data->smc_state_table.GraphicsLevel[j].SclkFrequency); + /* Check the allowed frequency against the sclk level[j]. + * Sclk's endianness has already been converted, + * and it's in 10Khz unit, + * as opposed to Data table, which is in Mhz unit. + */ + if (clock_freq >= + (fiji_clock_stretcher_ddt_table[type][i][0]) * 100) { + cks_setting |= 0x2; + if (clock_freq < + (fiji_clock_stretcher_ddt_table[type][i][1]) * 100) + cks_setting |= 0x1; + } + smu_data->smc_state_table.ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].setting |= cks_setting << (j * 2); + } + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table. + ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].setting); + } + + value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL); + value &= 0xFFFFFFFE; + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value); + + return 0; +} + +static int fiji_populate_vr_config(struct pp_hwmgr *hwmgr, + struct SMU73_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint16_t config; + + config = VR_MERGED_WITH_VDDC; + table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT); + + /* Set Vddc Voltage Controller */ + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) { + config = VR_SVI2_PLANE_1; + table->VRConfig |= config; + } else { + PP_ASSERT_WITH_CODE(false, + "VDDC should be on SVI2 control in merged mode!", + ); + } + /* Set Vddci Voltage Controller */ + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { + config = VR_SVI2_PLANE_2; /* only in merged mode */ + table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); + } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { + config = VR_SMIO_PATTERN_1; + table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); + } else { + config = VR_STATIC_VOLTAGE; + table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); + } + /* Set Mvdd Voltage Controller */ + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) { + config = VR_SVI2_PLANE_2; + table->VRConfig |= (config << VRCONF_MVDD_SHIFT); + } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) { + config = VR_SMIO_PATTERN_2; + table->VRConfig |= (config << VRCONF_MVDD_SHIFT); + } else { + config = VR_STATIC_VOLTAGE; + table->VRConfig |= (config << VRCONF_MVDD_SHIFT); + } + + return 0; +} + +static int fiji_init_arb_table_index(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + uint32_t tmp; + int result; + + /* This is a read-modify-write on the first byte of the ARB table. + * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure + * is the field 'current'. + * This solution is ugly, but we never write the whole table only + * individual fields in it. + * In reality this field should not be in that structure + * but in a soft register. + */ + result = smu7_read_smc_sram_dword(hwmgr, + smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END); + + if (result) + return result; + + tmp &= 0x00FFFFFF; + tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; + + return smu7_write_smc_sram_dword(hwmgr, + smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END); +} + +static int fiji_save_default_power_profile(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct SMU73_Discrete_GraphicsLevel *levels = + data->smc_state_table.GraphicsLevel; + unsigned min_level = 1; + + hwmgr->default_gfx_power_profile.activity_threshold = + be16_to_cpu(levels[0].ActivityLevel); + hwmgr->default_gfx_power_profile.up_hyst = levels[0].UpHyst; + hwmgr->default_gfx_power_profile.down_hyst = levels[0].DownHyst; + hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE; + + hwmgr->default_compute_power_profile = hwmgr->default_gfx_power_profile; + hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE; + + /* Workaround compute SDMA instability: disable lowest SCLK + * DPM level. Optimize compute power profile: Use only highest + * 2 power levels (if more than 2 are available), Hysteresis: + * 0ms up, 5ms down + */ + if (data->smc_state_table.GraphicsDpmLevelCount > 2) + min_level = data->smc_state_table.GraphicsDpmLevelCount - 2; + else if (data->smc_state_table.GraphicsDpmLevelCount == 2) + min_level = 1; + else + min_level = 0; + hwmgr->default_compute_power_profile.min_sclk = + be32_to_cpu(levels[min_level].SclkFrequency); + hwmgr->default_compute_power_profile.up_hyst = 0; + hwmgr->default_compute_power_profile.down_hyst = 5; + + hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile; + hwmgr->compute_power_profile = hwmgr->default_compute_power_profile; + + return 0; +} + +static int fiji_setup_dpm_led_config(struct pp_hwmgr *hwmgr) +{ + pp_atomctrl_voltage_table param_led_dpm; + int result = 0; + u32 mask = 0; + + result = atomctrl_get_voltage_table_v3(hwmgr, + VOLTAGE_TYPE_LEDDPM, VOLTAGE_OBJ_GPIO_LUT, + ¶m_led_dpm); + if (result == 0) { + int i, j; + u32 tmp = param_led_dpm.mask_low; + + for (i = 0, j = 0; i < 32; i++) { + if (tmp & 1) { + mask |= (i << (8 * j)); + if (++j >= 3) + break; + } + tmp >>= 1; + } + } + if (mask) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_LedConfig, + mask); + return 0; +} + +static int fiji_init_smc_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct SMU73_Discrete_DpmTable *table = &(smu_data->smc_state_table); + uint8_t i; + struct pp_atomctrl_gpio_pin_assignment gpio_pin; + + fiji_initialize_power_tune_defaults(hwmgr); + + if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) + fiji_populate_smc_voltage_tables(hwmgr, table); + + table->SystemFlags = 0; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StepVddc)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; + + if (data->is_memory_gddr5) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; + + if (data->ulv_supported && table_info->us_ulv_voltage_offset) { + result = fiji_populate_ulv_state(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ULV state!", return result); + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixCG_ULV_PARAMETER, 0x40035); + } + + result = fiji_populate_smc_link_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Link Level!", return result); + + result = fiji_populate_all_graphic_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Graphics Level!", return result); + + result = fiji_populate_all_memory_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Memory Level!", return result); + + result = fiji_populate_smc_acpi_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ACPI Level!", return result); + + result = fiji_populate_smc_vce_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize VCE Level!", return result); + + result = fiji_populate_smc_acp_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ACP Level!", return result); + + result = fiji_populate_smc_samu_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize SAMU Level!", return result); + + /* Since only the initial state is completely set up at this point + * (the other states are just copies of the boot state) we only + * need to populate the ARB settings for the initial state. + */ + result = fiji_program_memory_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to Write ARB settings for the initial state.", return result); + + result = fiji_populate_smc_uvd_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize UVD Level!", return result); + + result = fiji_populate_smc_boot_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Boot Level!", return result); + + result = fiji_populate_smc_initailial_state(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Boot State!", return result); + + result = fiji_populate_bapm_parameters_in_dpm_table(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate BAPM Parameters!", return result); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ClockStretcher)) { + result = fiji_populate_clock_stretcher_data_table(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate Clock Stretcher Data Table!", + return result); + } + + table->GraphicsVoltageChangeEnable = 1; + table->GraphicsThermThrottleEnable = 1; + table->GraphicsInterval = 1; + table->VoltageInterval = 1; + table->ThermalInterval = 1; + table->TemperatureLimitHigh = + table_info->cac_dtp_table->usTargetOperatingTemp * + SMU7_Q88_FORMAT_CONVERSION_UNIT; + table->TemperatureLimitLow = + (table_info->cac_dtp_table->usTargetOperatingTemp - 1) * + SMU7_Q88_FORMAT_CONVERSION_UNIT; + table->MemoryVoltageChangeEnable = 1; + table->MemoryInterval = 1; + table->VoltageResponseTime = 0; + table->PhaseResponseTime = 0; + table->MemoryThermThrottleEnable = 1; + table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/ + table->PCIeGenInterval = 1; + table->VRConfig = 0; + + result = fiji_populate_vr_config(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate VRConfig setting!", return result); + + table->ThermGpio = 17; + table->SclkStepSize = 0x4000; + + if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) { + table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift; + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot); + } else { + table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot); + } + + if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID, + &gpio_pin)) { + table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift; + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition); + } else { + table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition); + } + + /* Thermal Output GPIO */ + if (atomctrl_get_pp_assign_pin(hwmgr, THERMAL_INT_OUTPUT_GPIO_PINID, + &gpio_pin)) { + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ThermalOutGPIO); + + table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift; + + /* For porlarity read GPIOPAD_A with assigned Gpio pin + * since VBIOS will program this register to set 'inactive state', + * driver can then determine 'active state' from this and + * program SMU with correct polarity + */ + table->ThermOutPolarity = (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) & + (1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0; + table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY; + + /* if required, combine VRHot/PCC with thermal out GPIO */ + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot) && + phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_CombinePCCWithThermalSignal)) + table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT; + } else { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ThermalOutGPIO); + table->ThermOutGpio = 17; + table->ThermOutPolarity = 1; + table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE; + } + + for (i = 0; i < SMU73_MAX_ENTRIES_SMIO; i++) + table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]); + + CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); + CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2); + CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); + CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); + CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); + + /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ + result = smu7_copy_bytes_to_smc(hwmgr, + smu_data->smu7_data.dpm_table_start + + offsetof(SMU73_Discrete_DpmTable, SystemFlags), + (uint8_t *)&(table->SystemFlags), + sizeof(SMU73_Discrete_DpmTable) - 3 * sizeof(SMU73_PIDController), + SMC_RAM_END); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to upload dpm data to SMC memory!", return result); + + result = fiji_init_arb_table_index(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to upload arb data to SMC memory!", return result); + + result = fiji_populate_pm_fuses(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate PM fuses to SMC memory!", return result); + + result = fiji_setup_dpm_led_config(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to setup dpm led config", return result); + + fiji_save_default_power_profile(hwmgr); + + return 0; +} + +static int fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + + SMU73_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; + uint32_t duty100; + uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; + uint16_t fdo_min, slope1, slope2; + uint32_t reference_clock; + int res; + uint64_t tmp64; + + if (hwmgr->thermal_controller.fanInfo.bNoFan) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + if (smu_data->smu7_data.fan_table_start == 0) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, + CG_FDO_CTRL1, FMAX_DUTY100); + + if (duty100 == 0) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + tmp64 = hwmgr->thermal_controller.advanceFanControlParameters. + usPWMMin * duty100; + do_div(tmp64, 10000); + fdo_min = (uint16_t)tmp64; + + t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - + hwmgr->thermal_controller.advanceFanControlParameters.usTMin; + t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - + hwmgr->thermal_controller.advanceFanControlParameters.usTMed; + + pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; + pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; + + slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); + slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + + fan_table.TempMin = cpu_to_be16((50 + hwmgr-> + thermal_controller.advanceFanControlParameters.usTMin) / 100); + fan_table.TempMed = cpu_to_be16((50 + hwmgr-> + thermal_controller.advanceFanControlParameters.usTMed) / 100); + fan_table.TempMax = cpu_to_be16((50 + hwmgr-> + thermal_controller.advanceFanControlParameters.usTMax) / 100); + + fan_table.Slope1 = cpu_to_be16(slope1); + fan_table.Slope2 = cpu_to_be16(slope2); + + fan_table.FdoMin = cpu_to_be16(fdo_min); + + fan_table.HystDown = cpu_to_be16(hwmgr-> + thermal_controller.advanceFanControlParameters.ucTHyst); + + fan_table.HystUp = cpu_to_be16(1); + + fan_table.HystSlope = cpu_to_be16(1); + + fan_table.TempRespLim = cpu_to_be16(5); + + reference_clock = smu7_get_xclk(hwmgr); + + fan_table.RefreshPeriod = cpu_to_be32((hwmgr-> + thermal_controller.advanceFanControlParameters.ulCycleDelay * + reference_clock) / 1600); + + fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); + + fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD( + hwmgr->device, CGS_IND_REG__SMC, + CG_MULT_THERMAL_CTRL, TEMP_SEL); + + res = smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.fan_table_start, + (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), + SMC_RAM_END); + + if (!res && hwmgr->thermal_controller. + advanceFanControlParameters.ucMinimumPWMLimit) + res = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SetFanMinPwm, + hwmgr->thermal_controller. + advanceFanControlParameters.ucMinimumPWMLimit); + + if (!res && hwmgr->thermal_controller. + advanceFanControlParameters.ulMinFanSCLKAcousticLimit) + res = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SetFanSclkTarget, + hwmgr->thermal_controller. + advanceFanControlParameters.ulMinFanSCLKAcousticLimit); + + if (res) + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + + return 0; +} + + +static int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr) +{ + int ret; + struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); + + if (smu_data->avfs.avfs_btc_status != AVFS_BTC_ENABLEAVFS) + return 0; + + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs); + + if (!ret) + /* If this param is not changed, this function could fire unnecessarily */ + smu_data->avfs.avfs_btc_status = AVFS_BTC_COMPLETED_PREVIOUSLY; + + return ret; +} + +static int fiji_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (data->need_update_smu7_dpm_table & + (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) + return fiji_program_memory_timing_parameters(hwmgr); + + return 0; +} + +static int fiji_update_sclk_threshold(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + + int result = 0; + uint32_t low_sclk_interrupt_threshold = 0; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkThrottleLowNotification) + && (hwmgr->gfx_arbiter.sclk_threshold != + data->low_sclk_interrupt_threshold)) { + data->low_sclk_interrupt_threshold = + hwmgr->gfx_arbiter.sclk_threshold; + low_sclk_interrupt_threshold = + data->low_sclk_interrupt_threshold; + + CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); + + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.dpm_table_start + + offsetof(SMU73_Discrete_DpmTable, + LowSclkInterruptThreshold), + (uint8_t *)&low_sclk_interrupt_threshold, + sizeof(uint32_t), + SMC_RAM_END); + } + result = fiji_program_mem_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE((result == 0), + "Failed to program memory timing parameters!", + ); + return result; +} + +static uint32_t fiji_get_offsetof(uint32_t type, uint32_t member) +{ + switch (type) { + case SMU_SoftRegisters: + switch (member) { + case HandshakeDisables: + return offsetof(SMU73_SoftRegisters, HandshakeDisables); + case VoltageChangeTimeout: + return offsetof(SMU73_SoftRegisters, VoltageChangeTimeout); + case AverageGraphicsActivity: + return offsetof(SMU73_SoftRegisters, AverageGraphicsActivity); + case PreVBlankGap: + return offsetof(SMU73_SoftRegisters, PreVBlankGap); + case VBlankTimeout: + return offsetof(SMU73_SoftRegisters, VBlankTimeout); + case UcodeLoadStatus: + return offsetof(SMU73_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU73_SoftRegisters, DRAM_LOG_BUFF_SIZE); + } + case SMU_Discrete_DpmTable: + switch (member) { + case UvdBootLevel: + return offsetof(SMU73_Discrete_DpmTable, UvdBootLevel); + case VceBootLevel: + return offsetof(SMU73_Discrete_DpmTable, VceBootLevel); + case SamuBootLevel: + return offsetof(SMU73_Discrete_DpmTable, SamuBootLevel); + case LowSclkInterruptThreshold: + return offsetof(SMU73_Discrete_DpmTable, LowSclkInterruptThreshold); + } + } + pr_warn("can't get the offset of type %x member %x\n", type, member); + return 0; +} + +static uint32_t fiji_get_mac_definition(uint32_t value) +{ + switch (value) { + case SMU_MAX_LEVELS_GRAPHICS: + return SMU73_MAX_LEVELS_GRAPHICS; + case SMU_MAX_LEVELS_MEMORY: + return SMU73_MAX_LEVELS_MEMORY; + case SMU_MAX_LEVELS_LINK: + return SMU73_MAX_LEVELS_LINK; + case SMU_MAX_ENTRIES_SMIO: + return SMU73_MAX_ENTRIES_SMIO; + case SMU_MAX_LEVELS_VDDC: + return SMU73_MAX_LEVELS_VDDC; + case SMU_MAX_LEVELS_VDDGFX: + return SMU73_MAX_LEVELS_VDDGFX; + case SMU_MAX_LEVELS_VDDCI: + return SMU73_MAX_LEVELS_VDDCI; + case SMU_MAX_LEVELS_MVDD: + return SMU73_MAX_LEVELS_MVDD; + } + + pr_warn("can't get the mac of %x\n", value); + return 0; +} + + +static int fiji_update_uvd_smc_table(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + smu_data->smc_state_table.UvdBootLevel = 0; + if (table_info->mm_dep_table->count > 0) + smu_data->smc_state_table.UvdBootLevel = + (uint8_t) (table_info->mm_dep_table->count - 1); + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + offsetof(SMU73_Discrete_DpmTable, + UvdBootLevel); + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0x00FFFFFF; + mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_UVDDPM) || + phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_UVDDPM_SetEnabledMask, + (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel)); + return 0; +} + +static int fiji_update_vce_smc_table(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smu_data->smc_state_table.VceBootLevel = + (uint8_t) (table_info->mm_dep_table->count - 1); + else + smu_data->smc_state_table.VceBootLevel = 0; + + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + + offsetof(SMU73_Discrete_DpmTable, VceBootLevel); + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0xFF00FFFF; + mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_VCEDPM_SetEnabledMask, + (uint32_t)1 << smu_data->smc_state_table.VceBootLevel); + return 0; +} + +static int fiji_update_samu_smc_table(struct pp_hwmgr *hwmgr) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + + + smu_data->smc_state_table.SamuBootLevel = 0; + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + + offsetof(SMU73_Discrete_DpmTable, SamuBootLevel); + + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0xFFFFFF00; + mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SAMUDPM_SetEnabledMask, + (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); + return 0; +} + +static int fiji_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) +{ + switch (type) { + case SMU_UVD_TABLE: + fiji_update_uvd_smc_table(hwmgr); + break; + case SMU_VCE_TABLE: + fiji_update_vce_smc_table(hwmgr); + break; + case SMU_SAMU_TABLE: + fiji_update_samu_smc_table(hwmgr); + break; + default: + break; + } + return 0; +} + +static int fiji_process_firmware_header(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); + uint32_t tmp; + int result; + bool error = false; + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU73_Firmware_Header, DpmTable), + &tmp, SMC_RAM_END); + + if (0 == result) + smu_data->smu7_data.dpm_table_start = tmp; + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU73_Firmware_Header, SoftRegisters), + &tmp, SMC_RAM_END); + + if (!result) { + data->soft_regs_start = tmp; + smu_data->smu7_data.soft_regs_start = tmp; + } + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU73_Firmware_Header, mcRegisterTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.mc_reg_table_start = tmp; + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU73_Firmware_Header, FanTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.fan_table_start = tmp; + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU73_Firmware_Header, mcArbDramTimingTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.arb_table_start = tmp; + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU73_Firmware_Header, Version), + &tmp, SMC_RAM_END); + + if (!result) + hwmgr->microcode_version_info.SMC = tmp; + + error |= (0 != result); + + return error ? -1 : 0; +} + +static int fiji_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + + /* Program additional LP registers + * that are no longer programmed by VBIOS + */ + cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); + + return 0; +} + +static bool fiji_is_dpm_running(struct pp_hwmgr *hwmgr) +{ + return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) + ? true : false; +} + +static int fiji_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, + struct amd_pp_profile *request) +{ + struct fiji_smumgr *smu_data = (struct fiji_smumgr *) + (hwmgr->smu_backend); + struct SMU73_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU73_Discrete_DpmTable, GraphicsLevel); + uint32_t array_size = sizeof(struct SMU73_Discrete_GraphicsLevel) * + SMU73_MAX_LEVELS_GRAPHICS; + uint32_t i; + + for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { + levels[i].ActivityLevel = + cpu_to_be16(request->activity_threshold); + levels[i].EnabledForActivity = 1; + levels[i].UpHyst = request->up_hyst; + levels[i].DownHyst = request->down_hyst; + } + + return smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + array_size, SMC_RAM_END); +} const struct pp_smumgr_func fiji_smu_funcs = { .smu_init = &fiji_smu_init, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h index 175bf9f8ef9c..279647772578 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h @@ -28,6 +28,15 @@ #include "smu7_smumgr.h" +struct fiji_pt_defaults { + uint8_t SviLoadLineEn; + uint8_t SviLoadLineVddC; + uint8_t TDC_VDDC_ThrottleReleaseLimitPerc; + uint8_t TDC_MAWt; + uint8_t TdcWaterfallCtl; + uint8_t DTEAmbientTempBase; +}; + struct fiji_smumgr { struct smu7_smumgr smu7_data; struct SMU73_Discrete_DpmTable smc_state_table; -- cgit v1.2.3 From 907bfec7cce0a8fa9a4cd552f97d171f23c79dac Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 16:04:39 +0800 Subject: drm/amd/pp: remove iceland_smc/smumgr split. move functions in iceland_smc.c to iceland_smumgr.c and make all functions in iceland_smumgr.c static. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/Makefile | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c | 2578 -------------------- drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.h | 40 - .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 2489 ++++++++++++++++++- 4 files changed, 2480 insertions(+), 2629 deletions(-) delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.h (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile index ec8229e0e9d0..33ab0bca5c25 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile @@ -4,7 +4,7 @@ SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o \ polaris10_smumgr.o iceland_smumgr.o polaris10_smc.o tonga_smc.o \ - smu7_smumgr.o iceland_smc.o vega10_smumgr.o rv_smumgr.o ci_smumgr.o + smu7_smumgr.o vega10_smumgr.o rv_smumgr.o ci_smumgr.o AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c deleted file mode 100644 index da0c93b73c49..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c +++ /dev/null @@ -1,2578 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * 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 shall be included in - * all copies or substantial portions of the Software. - * - * - */ - -#include "pp_debug.h" -#include "iceland_smc.h" -#include "smu7_dyn_defaults.h" - -#include "smu7_hwmgr.h" -#include "hardwaremanager.h" -#include "ppatomctrl.h" -#include "cgs_common.h" -#include "atombios.h" -#include "pppcielanes.h" -#include "pp_endian.h" -#include "smu7_ppsmc.h" - -#include "smu71_discrete.h" - -#include "smu/smu_7_1_1_d.h" -#include "smu/smu_7_1_1_sh_mask.h" - -#include "gmc/gmc_8_1_d.h" -#include "gmc/gmc_8_1_sh_mask.h" - -#include "bif/bif_5_0_d.h" -#include "bif/bif_5_0_sh_mask.h" - -#include "dce/dce_10_0_d.h" -#include "dce/dce_10_0_sh_mask.h" -#include "processpptables.h" - -#include "iceland_smumgr.h" - -#define VOLTAGE_SCALE 4 -#define POWERTUNE_DEFAULT_SET_MAX 1 -#define VOLTAGE_VID_OFFSET_SCALE1 625 -#define VOLTAGE_VID_OFFSET_SCALE2 100 -#define MC_CG_ARB_FREQ_F1 0x0b -#define VDDC_VDDCI_DELTA 200 - -#define DEVICE_ID_VI_ICELAND_M_6900 0x6900 -#define DEVICE_ID_VI_ICELAND_M_6901 0x6901 -#define DEVICE_ID_VI_ICELAND_M_6902 0x6902 -#define DEVICE_ID_VI_ICELAND_M_6903 0x6903 - -static const struct iceland_pt_defaults defaults_iceland = { - /* - * sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, - * TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT - */ - 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, - { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61 }, - { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } -}; - -/* 35W - XT, XTL */ -static const struct iceland_pt_defaults defaults_icelandxt = { - /* - * sviLoadLIneEn, SviLoadLineVddC, - * TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, - * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, - * BAPM_TEMP_GRADIENT - */ - 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x0, - { 0xA7, 0x0, 0x0, 0xB5, 0x0, 0x0, 0x9F, 0x0, 0x0, 0xD6, 0x0, 0x0, 0xD7, 0x0, 0x0}, - { 0x1EA, 0x0, 0x0, 0x224, 0x0, 0x0, 0x25E, 0x0, 0x0, 0x28E, 0x0, 0x0, 0x2AB, 0x0, 0x0} -}; - -/* 25W - PRO, LE */ -static const struct iceland_pt_defaults defaults_icelandpro = { - /* - * sviLoadLIneEn, SviLoadLineVddC, - * TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, - * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, - * BAPM_TEMP_GRADIENT - */ - 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x0, - { 0xB7, 0x0, 0x0, 0xC3, 0x0, 0x0, 0xB5, 0x0, 0x0, 0xEA, 0x0, 0x0, 0xE6, 0x0, 0x0}, - { 0x1EA, 0x0, 0x0, 0x224, 0x0, 0x0, 0x25E, 0x0, 0x0, 0x28E, 0x0, 0x0, 0x2AB, 0x0, 0x0} -}; - -static void iceland_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) -{ - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - struct cgs_system_info sys_info = {0}; - uint32_t dev_id; - - sys_info.size = sizeof(struct cgs_system_info); - sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; - cgs_query_system_info(hwmgr->device, &sys_info); - dev_id = (uint32_t)sys_info.value; - - switch (dev_id) { - case DEVICE_ID_VI_ICELAND_M_6900: - case DEVICE_ID_VI_ICELAND_M_6903: - smu_data->power_tune_defaults = &defaults_icelandxt; - break; - - case DEVICE_ID_VI_ICELAND_M_6901: - case DEVICE_ID_VI_ICELAND_M_6902: - smu_data->power_tune_defaults = &defaults_icelandpro; - break; - default: - smu_data->power_tune_defaults = &defaults_iceland; - pr_warn("Unknown V.I. Device ID.\n"); - break; - } - return; -} - -static int iceland_populate_svi_load_line(struct pp_hwmgr *hwmgr) -{ - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; - - smu_data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; - smu_data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddc; - smu_data->power_tune_table.SviLoadLineTrimVddC = 3; - smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; - - return 0; -} - -static int iceland_populate_tdc_limit(struct pp_hwmgr *hwmgr) -{ - uint16_t tdc_limit; - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; - - tdc_limit = (uint16_t)(hwmgr->dyn_state.cac_dtp_table->usTDC * 256); - smu_data->power_tune_table.TDC_VDDC_PkgLimit = - CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); - smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = - defaults->tdc_vddc_throttle_release_limit_perc; - smu_data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; - - return 0; -} - -static int iceland_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) -{ - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; - uint32_t temp; - - if (smu7_read_smc_sram_dword(hwmgr, - fuse_table_offset + - offsetof(SMU71_Discrete_PmFuses, TdcWaterfallCtl), - (uint32_t *)&temp, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", - return -EINVAL); - else - smu_data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; - - return 0; -} - -static int iceland_populate_temperature_scaler(struct pp_hwmgr *hwmgr) -{ - return 0; -} - -static int iceland_populate_gnb_lpml(struct pp_hwmgr *hwmgr) -{ - int i; - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - - /* Currently not used. Set all to zero. */ - for (i = 0; i < 8; i++) - smu_data->power_tune_table.GnbLPML[i] = 0; - - return 0; -} - -static int iceland_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) -{ - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - uint16_t HiSidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; - uint16_t LoSidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; - struct phm_cac_tdp_table *cac_table = hwmgr->dyn_state.cac_dtp_table; - - HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); - LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); - - smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = - CONVERT_FROM_HOST_TO_SMC_US(HiSidd); - smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = - CONVERT_FROM_HOST_TO_SMC_US(LoSidd); - - return 0; -} - -static int iceland_populate_bapm_vddc_vid_sidd(struct pp_hwmgr *hwmgr) -{ - int i; - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - uint8_t *hi_vid = smu_data->power_tune_table.BapmVddCVidHiSidd; - uint8_t *lo_vid = smu_data->power_tune_table.BapmVddCVidLoSidd; - - PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.cac_leakage_table, - "The CAC Leakage table does not exist!", return -EINVAL); - PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count <= 8, - "There should never be more than 8 entries for BapmVddcVid!!!", return -EINVAL); - PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count == hwmgr->dyn_state.vddc_dependency_on_sclk->count, - "CACLeakageTable->count and VddcDependencyOnSCLk->count not equal", return -EINVAL); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_EVV)) { - for (i = 0; (uint32_t) i < hwmgr->dyn_state.cac_leakage_table->count; i++) { - lo_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc1); - hi_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc2); - } - } else { - PP_ASSERT_WITH_CODE(false, "Iceland should always support EVV", return -EINVAL); - } - - return 0; -} - -static int iceland_populate_vddc_vid(struct pp_hwmgr *hwmgr) -{ - int i; - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - uint8_t *vid = smu_data->power_tune_table.VddCVid; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - PP_ASSERT_WITH_CODE(data->vddc_voltage_table.count <= 8, - "There should never be more than 8 entries for VddcVid!!!", - return -EINVAL); - - for (i = 0; i < (int)data->vddc_voltage_table.count; i++) { - vid[i] = convert_to_vid(data->vddc_voltage_table.entries[i].value); - } - - return 0; -} - - - -static int iceland_populate_pm_fuses(struct pp_hwmgr *hwmgr) -{ - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - uint32_t pm_fuse_table_offset; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment)) { - if (smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, PmFuseTable), - &pm_fuse_table_offset, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to get pm_fuse_table_offset Failed!", - return -EINVAL); - - /* DW0 - DW3 */ - if (iceland_populate_bapm_vddc_vid_sidd(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate bapm vddc vid Failed!", - return -EINVAL); - - /* DW4 - DW5 */ - if (iceland_populate_vddc_vid(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate vddc vid Failed!", - return -EINVAL); - - /* DW6 */ - if (iceland_populate_svi_load_line(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate SviLoadLine Failed!", - return -EINVAL); - /* DW7 */ - if (iceland_populate_tdc_limit(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TDCLimit Failed!", return -EINVAL); - /* DW8 */ - if (iceland_populate_dw8(hwmgr, pm_fuse_table_offset)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TdcWaterfallCtl, " - "LPMLTemperature Min and Max Failed!", - return -EINVAL); - - /* DW9-DW12 */ - if (0 != iceland_populate_temperature_scaler(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate LPMLTemperatureScaler Failed!", - return -EINVAL); - - /* DW13-DW16 */ - if (iceland_populate_gnb_lpml(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate GnbLPML Failed!", - return -EINVAL); - - /* DW18 */ - if (iceland_populate_bapm_vddc_base_leakage_sidd(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate BapmVddCBaseLeakage Hi and Lo Sidd Failed!", - return -EINVAL); - - if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, - (uint8_t *)&smu_data->power_tune_table, - sizeof(struct SMU71_Discrete_PmFuses), SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to download PmFuseTable Failed!", - return -EINVAL); - } - return 0; -} - -static int iceland_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, - struct phm_clock_voltage_dependency_table *allowed_clock_voltage_table, - uint32_t clock, uint32_t *vol) -{ - uint32_t i = 0; - - /* clock - voltage dependency table is empty table */ - if (allowed_clock_voltage_table->count == 0) - return -EINVAL; - - for (i = 0; i < allowed_clock_voltage_table->count; i++) { - /* find first sclk bigger than request */ - if (allowed_clock_voltage_table->entries[i].clk >= clock) { - *vol = allowed_clock_voltage_table->entries[i].v; - return 0; - } - } - - /* sclk is bigger than max sclk in the dependence table */ - *vol = allowed_clock_voltage_table->entries[i - 1].v; - - return 0; -} - -static int iceland_get_std_voltage_value_sidd(struct pp_hwmgr *hwmgr, - pp_atomctrl_voltage_table_entry *tab, uint16_t *hi, - uint16_t *lo) -{ - uint16_t v_index; - bool vol_found = false; - *hi = tab->value * VOLTAGE_SCALE; - *lo = tab->value * VOLTAGE_SCALE; - - /* SCLK/VDDC Dependency Table has to exist. */ - PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.vddc_dependency_on_sclk, - "The SCLK/VDDC Dependency Table does not exist.\n", - return -EINVAL); - - if (NULL == hwmgr->dyn_state.cac_leakage_table) { - pr_warn("CAC Leakage Table does not exist, using vddc.\n"); - return 0; - } - - /* - * Since voltage in the sclk/vddc dependency table is not - * necessarily in ascending order because of ELB voltage - * patching, loop through entire list to find exact voltage. - */ - for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { - if (tab->value == hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { - vol_found = true; - if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { - *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage * VOLTAGE_SCALE); - } else { - pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index, using maximum index from CAC table.\n"); - *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); - } - break; - } - } - - /* - * If voltage is not found in the first pass, loop again to - * find the best match, equal or higher value. - */ - if (!vol_found) { - for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { - if (tab->value <= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { - vol_found = true; - if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { - *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage) * VOLTAGE_SCALE; - } else { - pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index in second look up, using maximum index from CAC table."); - *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; - *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); - } - break; - } - } - - if (!vol_found) - pr_warn("Unable to get std_vddc from SCLK/VDDC Dependency Table, using vddc.\n"); - } - - return 0; -} - -static int iceland_populate_smc_voltage_table(struct pp_hwmgr *hwmgr, - pp_atomctrl_voltage_table_entry *tab, - SMU71_Discrete_VoltageLevel *smc_voltage_tab) -{ - int result; - - result = iceland_get_std_voltage_value_sidd(hwmgr, tab, - &smc_voltage_tab->StdVoltageHiSidd, - &smc_voltage_tab->StdVoltageLoSidd); - if (0 != result) { - smc_voltage_tab->StdVoltageHiSidd = tab->value * VOLTAGE_SCALE; - smc_voltage_tab->StdVoltageLoSidd = tab->value * VOLTAGE_SCALE; - } - - smc_voltage_tab->Voltage = PP_HOST_TO_SMC_US(tab->value * VOLTAGE_SCALE); - CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd); - CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd); - - return 0; -} - -static int iceland_populate_smc_vddc_table(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - unsigned int count; - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - table->VddcLevelCount = data->vddc_voltage_table.count; - for (count = 0; count < table->VddcLevelCount; count++) { - result = iceland_populate_smc_voltage_table(hwmgr, - &(data->vddc_voltage_table.entries[count]), - &(table->VddcLevel[count])); - PP_ASSERT_WITH_CODE(0 == result, "do not populate SMC VDDC voltage table", return -EINVAL); - - /* GPIO voltage control */ - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->voltage_control) - table->VddcLevel[count].Smio |= data->vddc_voltage_table.entries[count].smio_low; - else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) - table->VddcLevel[count].Smio = 0; - } - - CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount); - - return 0; -} - -static int iceland_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t count; - int result; - - table->VddciLevelCount = data->vddci_voltage_table.count; - - for (count = 0; count < table->VddciLevelCount; count++) { - result = iceland_populate_smc_voltage_table(hwmgr, - &(data->vddci_voltage_table.entries[count]), - &(table->VddciLevel[count])); - PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC VDDCI voltage table", return -EINVAL); - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) - table->VddciLevel[count].Smio |= data->vddci_voltage_table.entries[count].smio_low; - else - table->VddciLevel[count].Smio |= 0; - } - - CONVERT_FROM_HOST_TO_SMC_UL(table->VddciLevelCount); - - return 0; -} - -static int iceland_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t count; - int result; - - table->MvddLevelCount = data->mvdd_voltage_table.count; - - for (count = 0; count < table->VddciLevelCount; count++) { - result = iceland_populate_smc_voltage_table(hwmgr, - &(data->mvdd_voltage_table.entries[count]), - &table->MvddLevel[count]); - PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC mvdd voltage table", return -EINVAL); - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) - table->MvddLevel[count].Smio |= data->mvdd_voltage_table.entries[count].smio_low; - else - table->MvddLevel[count].Smio |= 0; - } - - CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount); - - return 0; -} - - -static int iceland_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - int result; - - result = iceland_populate_smc_vddc_table(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "can not populate VDDC voltage table to SMC", return -EINVAL); - - result = iceland_populate_smc_vdd_ci_table(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "can not populate VDDCI voltage table to SMC", return -EINVAL); - - result = iceland_populate_smc_mvdd_table(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "can not populate MVDD voltage table to SMC", return -EINVAL); - - return 0; -} - -static int iceland_populate_ulv_level(struct pp_hwmgr *hwmgr, - struct SMU71_Discrete_Ulv *state) -{ - uint32_t voltage_response_time, ulv_voltage; - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - state->CcPwrDynRm = 0; - state->CcPwrDynRm1 = 0; - - result = pp_tables_get_response_times(hwmgr, &voltage_response_time, &ulv_voltage); - PP_ASSERT_WITH_CODE((0 == result), "can not get ULV voltage value", return result;); - - if (ulv_voltage == 0) { - data->ulv_supported = false; - return 0; - } - - if (data->voltage_control != SMU7_VOLTAGE_CONTROL_BY_SVID2) { - /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ - if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) - state->VddcOffset = 0; - else - /* used in SMIO Mode. not implemented for now. this is backup only for CI. */ - state->VddcOffset = (uint16_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage); - } else { - /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ - if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) - state->VddcOffsetVid = 0; - else /* used in SVI2 Mode */ - state->VddcOffsetVid = (uint8_t)( - (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage) - * VOLTAGE_VID_OFFSET_SCALE2 - / VOLTAGE_VID_OFFSET_SCALE1); - } - state->VddcPhase = 1; - - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); - CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); - - return 0; -} - -static int iceland_populate_ulv_state(struct pp_hwmgr *hwmgr, - SMU71_Discrete_Ulv *ulv_level) -{ - return iceland_populate_ulv_level(hwmgr, ulv_level); -} - -static int iceland_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU71_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - uint32_t i; - - /* Index (dpm_table->pcie_speed_table.count) is reserved for PCIE boot level. */ - for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { - table->LinkLevel[i].PcieGenSpeed = - (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; - table->LinkLevel[i].PcieLaneCount = - (uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1); - table->LinkLevel[i].EnabledForActivity = - 1; - table->LinkLevel[i].SPC = - (uint8_t)(data->pcie_spc_cap & 0xff); - table->LinkLevel[i].DownThreshold = - PP_HOST_TO_SMC_UL(5); - table->LinkLevel[i].UpThreshold = - PP_HOST_TO_SMC_UL(30); - } - - smu_data->smc_state_table.LinkLevelCount = - (uint8_t)dpm_table->pcie_speed_table.count; - data->dpm_level_enable_mask.pcie_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); - - return 0; -} - -/** - * Calculates the SCLK dividers using the provided engine clock - * - * @param hwmgr the address of the hardware manager - * @param engine_clock the engine clock to use to populate the structure - * @param sclk the SMC SCLK structure to be populated - */ -static int iceland_calculate_sclk_params(struct pp_hwmgr *hwmgr, - uint32_t engine_clock, SMU71_Discrete_GraphicsLevel *sclk) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - pp_atomctrl_clock_dividers_vi dividers; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - uint32_t reference_clock; - uint32_t reference_divider; - uint32_t fbdiv; - int result; - - /* get the engine clock dividers for this clock value*/ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, engine_clock, ÷rs); - - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", return result); - - /* To get FBDIV we need to multiply this by 16384 and divide it by Fref.*/ - reference_clock = atomctrl_get_reference_clock(hwmgr); - - reference_divider = 1 + dividers.uc_pll_ref_div; - - /* low 14 bits is fraction and high 12 bits is divider*/ - fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; - - /* SPLL_FUNC_CNTL setup*/ - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_REF_DIV, dividers.uc_pll_ref_div); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_PDIV_A, dividers.uc_pll_post_div); - - /* SPLL_FUNC_CNTL_3 setup*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, - CG_SPLL_FUNC_CNTL_3, SPLL_FB_DIV, fbdiv); - - /* set to use fractional accumulation*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, - CG_SPLL_FUNC_CNTL_3, SPLL_DITHEN, 1); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { - pp_atomctrl_internal_ss_info ss_info; - - uint32_t vcoFreq = engine_clock * dividers.uc_pll_post_div; - if (0 == atomctrl_get_engine_clock_spread_spectrum(hwmgr, vcoFreq, &ss_info)) { - /* - * ss_info.speed_spectrum_percentage -- in unit of 0.01% - * ss_info.speed_spectrum_rate -- in unit of khz - */ - /* clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 */ - uint32_t clkS = reference_clock * 5 / (reference_divider * ss_info.speed_spectrum_rate); - - /* clkv = 2 * D * fbdiv / NS */ - uint32_t clkV = 4 * ss_info.speed_spectrum_percentage * fbdiv / (clkS * 10000); - - cg_spll_spread_spectrum = - PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, CLKS, clkS); - cg_spll_spread_spectrum = - PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); - cg_spll_spread_spectrum_2 = - PHM_SET_FIELD(cg_spll_spread_spectrum_2, CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clkV); - } - } - - sclk->SclkFrequency = engine_clock; - sclk->CgSpllFuncCntl3 = spll_func_cntl_3; - sclk->CgSpllFuncCntl4 = spll_func_cntl_4; - sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; - sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; - sclk->SclkDid = (uint8_t)dividers.pll_post_divider; - - return 0; -} - -static int iceland_populate_phase_value_based_on_sclk(struct pp_hwmgr *hwmgr, - const struct phm_phase_shedding_limits_table *pl, - uint32_t sclk, uint32_t *p_shed) -{ - unsigned int i; - - /* use the minimum phase shedding */ - *p_shed = 1; - - for (i = 0; i < pl->count; i++) { - if (sclk < pl->entries[i].Sclk) { - *p_shed = i; - break; - } - } - return 0; -} - -/** - * Populates single SMC SCLK structure using the provided engine clock - * - * @param hwmgr the address of the hardware manager - * @param engine_clock the engine clock to use to populate the structure - * @param sclk the SMC SCLK structure to be populated - */ -static int iceland_populate_single_graphic_level(struct pp_hwmgr *hwmgr, - uint32_t engine_clock, - uint16_t sclk_activity_level_threshold, - SMU71_Discrete_GraphicsLevel *graphic_level) -{ - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - result = iceland_calculate_sclk_params(hwmgr, engine_clock, graphic_level); - - /* populate graphics levels*/ - result = iceland_get_dependency_volt_by_clk(hwmgr, - hwmgr->dyn_state.vddc_dependency_on_sclk, engine_clock, - &graphic_level->MinVddc); - PP_ASSERT_WITH_CODE((0 == result), - "can not find VDDC voltage value for VDDC \ - engine clock dependency table", return result); - - /* SCLK frequency in units of 10KHz*/ - graphic_level->SclkFrequency = engine_clock; - graphic_level->MinVddcPhases = 1; - - if (data->vddc_phase_shed_control) - iceland_populate_phase_value_based_on_sclk(hwmgr, - hwmgr->dyn_state.vddc_phase_shed_limits_table, - engine_clock, - &graphic_level->MinVddcPhases); - - /* Indicates maximum activity level for this performance level. 50% for now*/ - graphic_level->ActivityLevel = sclk_activity_level_threshold; - - graphic_level->CcPwrDynRm = 0; - graphic_level->CcPwrDynRm1 = 0; - /* this level can be used if activity is high enough.*/ - graphic_level->EnabledForActivity = 0; - /* this level can be used for throttling.*/ - graphic_level->EnabledForThrottle = 1; - graphic_level->UpHyst = 0; - graphic_level->DownHyst = 100; - graphic_level->VoltageDownHyst = 0; - graphic_level->PowerThrottle = 0; - - data->display_timing.min_clock_in_sr = - hwmgr->display_config.min_core_set_clock_in_sr; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkDeepSleep)) - graphic_level->DeepSleepDivId = - smu7_get_sleep_divider_id_from_clock(engine_clock, - data->display_timing.min_clock_in_sr); - - /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ - graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - if (0 == result) { - graphic_level->MinVddc = PP_HOST_TO_SMC_UL(graphic_level->MinVddc * VOLTAGE_SCALE); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(graphic_level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm1); - } - - return result; -} - -/** - * Populates all SMC SCLK levels' structure based on the trimmed allowed dpm engine clock states - * - * @param hwmgr the address of the hardware manager - */ -int iceland_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - uint32_t level_array_adress = smu_data->smu7_data.dpm_table_start + - offsetof(SMU71_Discrete_DpmTable, GraphicsLevel); - - uint32_t level_array_size = sizeof(SMU71_Discrete_GraphicsLevel) * - SMU71_MAX_LEVELS_GRAPHICS; - - SMU71_Discrete_GraphicsLevel *levels = smu_data->smc_state_table.GraphicsLevel; - - uint32_t i; - uint8_t highest_pcie_level_enabled = 0; - uint8_t lowest_pcie_level_enabled = 0, mid_pcie_level_enabled = 0; - uint8_t count = 0; - int result = 0; - - memset(levels, 0x00, level_array_size); - - for (i = 0; i < dpm_table->sclk_table.count; i++) { - result = iceland_populate_single_graphic_level(hwmgr, - dpm_table->sclk_table.dpm_levels[i].value, - (uint16_t)smu_data->activity_target[i], - &(smu_data->smc_state_table.GraphicsLevel[i])); - if (result != 0) - return result; - - /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ - if (i > 1) - smu_data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0; - } - - /* Only enable level 0 for now. */ - smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; - - /* set highest level watermark to high */ - if (dpm_table->sclk_table.count > 1) - smu_data->smc_state_table.GraphicsLevel[dpm_table->sclk_table.count-1].DisplayWatermark = - PPSMC_DISPLAY_WATERMARK_HIGH; - - smu_data->smc_state_table.GraphicsDpmLevelCount = - (uint8_t)dpm_table->sclk_table.count; - data->dpm_level_enable_mask.sclk_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); - - while ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << (highest_pcie_level_enabled + 1))) != 0) { - highest_pcie_level_enabled++; - } - - while ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << lowest_pcie_level_enabled)) == 0) { - lowest_pcie_level_enabled++; - } - - while ((count < highest_pcie_level_enabled) && - ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << (lowest_pcie_level_enabled + 1 + count))) == 0)) { - count++; - } - - mid_pcie_level_enabled = (lowest_pcie_level_enabled+1+count) < highest_pcie_level_enabled ? - (lowest_pcie_level_enabled+1+count) : highest_pcie_level_enabled; - - - /* set pcieDpmLevel to highest_pcie_level_enabled*/ - for (i = 2; i < dpm_table->sclk_table.count; i++) { - smu_data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = highest_pcie_level_enabled; - } - - /* set pcieDpmLevel to lowest_pcie_level_enabled*/ - smu_data->smc_state_table.GraphicsLevel[0].pcieDpmLevel = lowest_pcie_level_enabled; - - /* set pcieDpmLevel to mid_pcie_level_enabled*/ - smu_data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled; - - /* level count will send to smc once at init smc table and never change*/ - result = smu7_copy_bytes_to_smc(hwmgr, level_array_adress, - (uint8_t *)levels, (uint32_t)level_array_size, - SMC_RAM_END); - - return result; -} - -/** - * Populates the SMC MCLK structure using the provided memory clock - * - * @param hwmgr the address of the hardware manager - * @param memory_clock the memory clock to use to populate the structure - * @param sclk the SMC SCLK structure to be populated - */ -static int iceland_calculate_mclk_params( - struct pp_hwmgr *hwmgr, - uint32_t memory_clock, - SMU71_Discrete_MemoryLevel *mclk, - bool strobe_mode, - bool dllStateOn - ) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; - uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; - uint32_t mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL; - uint32_t mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL; - uint32_t mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL; - uint32_t mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1; - uint32_t mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2; - uint32_t mpll_ss1 = data->clock_registers.vMPLL_SS1; - uint32_t mpll_ss2 = data->clock_registers.vMPLL_SS2; - - pp_atomctrl_memory_clock_param mpll_param; - int result; - - result = atomctrl_get_memory_pll_dividers_si(hwmgr, - memory_clock, &mpll_param, strobe_mode); - PP_ASSERT_WITH_CODE(0 == result, - "Error retrieving Memory Clock Parameters from VBIOS.", return result); - - /* MPLL_FUNC_CNTL setup*/ - mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl); - - /* MPLL_FUNC_CNTL_1 setup*/ - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, CLKF, mpll_param.mpll_fb_divider.cl_kf); - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, CLKFRAC, mpll_param.mpll_fb_divider.clk_frac); - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, VCO_MODE, mpll_param.vco_mode); - - /* MPLL_AD_FUNC_CNTL setup*/ - mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl, - MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); - - if (data->is_memory_gddr5) { - /* MPLL_DQ_FUNC_CNTL setup*/ - mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, - MPLL_DQ_FUNC_CNTL, YCLK_SEL, mpll_param.yclk_sel); - mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, - MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); - } - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MemorySpreadSpectrumSupport)) { - /* - ************************************ - Fref = Reference Frequency - NF = Feedback divider ratio - NR = Reference divider ratio - Fnom = Nominal VCO output frequency = Fref * NF / NR - Fs = Spreading Rate - D = Percentage down-spread / 2 - Fint = Reference input frequency to PFD = Fref / NR - NS = Spreading rate divider ratio = int(Fint / (2 * Fs)) - CLKS = NS - 1 = ISS_STEP_NUM[11:0] - NV = D * Fs / Fnom * 4 * ((Fnom/Fref * NR) ^ 2) - CLKV = 65536 * NV = ISS_STEP_SIZE[25:0] - ************************************* - */ - pp_atomctrl_internal_ss_info ss_info; - uint32_t freq_nom; - uint32_t tmp; - uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr); - - /* for GDDR5 for all modes and DDR3 */ - if (1 == mpll_param.qdr) - freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider); - else - freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider); - - /* tmp = (freq_nom / reference_clock * reference_divider) ^ 2 Note: S.I. reference_divider = 1*/ - tmp = (freq_nom / reference_clock); - tmp = tmp * tmp; - - if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) { - /* ss_info.speed_spectrum_percentage -- in unit of 0.01% */ - /* ss.Info.speed_spectrum_rate -- in unit of khz */ - /* CLKS = reference_clock / (2 * speed_spectrum_rate * reference_divider) * 10 */ - /* = reference_clock * 5 / speed_spectrum_rate */ - uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate; - - /* CLKV = 65536 * speed_spectrum_percentage / 2 * spreadSpecrumRate / freq_nom * 4 / 100000 * ((freq_nom / reference_clock) ^ 2) */ - /* = 131 * speed_spectrum_percentage * speed_spectrum_rate / 100 * ((freq_nom / reference_clock) ^ 2) / freq_nom */ - uint32_t clkv = - (uint32_t)((((131 * ss_info.speed_spectrum_percentage * - ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom); - - mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv); - mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks); - } - } - - /* MCLK_PWRMGT_CNTL setup */ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn); - - - /* Save the result data to outpupt memory level structure */ - mclk->MclkFrequency = memory_clock; - mclk->MpllFuncCntl = mpll_func_cntl; - mclk->MpllFuncCntl_1 = mpll_func_cntl_1; - mclk->MpllFuncCntl_2 = mpll_func_cntl_2; - mclk->MpllAdFuncCntl = mpll_ad_func_cntl; - mclk->MpllDqFuncCntl = mpll_dq_func_cntl; - mclk->MclkPwrmgtCntl = mclk_pwrmgt_cntl; - mclk->DllCntl = dll_cntl; - mclk->MpllSs1 = mpll_ss1; - mclk->MpllSs2 = mpll_ss2; - - return 0; -} - -static uint8_t iceland_get_mclk_frequency_ratio(uint32_t memory_clock, - bool strobe_mode) -{ - uint8_t mc_para_index; - - if (strobe_mode) { - if (memory_clock < 12500) { - mc_para_index = 0x00; - } else if (memory_clock > 47500) { - mc_para_index = 0x0f; - } else { - mc_para_index = (uint8_t)((memory_clock - 10000) / 2500); - } - } else { - if (memory_clock < 65000) { - mc_para_index = 0x00; - } else if (memory_clock > 135000) { - mc_para_index = 0x0f; - } else { - mc_para_index = (uint8_t)((memory_clock - 60000) / 5000); - } - } - - return mc_para_index; -} - -static uint8_t iceland_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock) -{ - uint8_t mc_para_index; - - if (memory_clock < 10000) { - mc_para_index = 0; - } else if (memory_clock >= 80000) { - mc_para_index = 0x0f; - } else { - mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1); - } - - return mc_para_index; -} - -static int iceland_populate_phase_value_based_on_mclk(struct pp_hwmgr *hwmgr, const struct phm_phase_shedding_limits_table *pl, - uint32_t memory_clock, uint32_t *p_shed) -{ - unsigned int i; - - *p_shed = 1; - - for (i = 0; i < pl->count; i++) { - if (memory_clock < pl->entries[i].Mclk) { - *p_shed = i; - break; - } - } - - return 0; -} - -static int iceland_populate_single_memory_level( - struct pp_hwmgr *hwmgr, - uint32_t memory_clock, - SMU71_Discrete_MemoryLevel *memory_level - ) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - int result = 0; - bool dll_state_on; - struct cgs_display_info info = {0}; - uint32_t mclk_edc_wr_enable_threshold = 40000; - uint32_t mclk_edc_enable_threshold = 40000; - uint32_t mclk_strobe_mode_threshold = 40000; - - if (hwmgr->dyn_state.vddc_dependency_on_mclk != NULL) { - result = iceland_get_dependency_volt_by_clk(hwmgr, - hwmgr->dyn_state.vddc_dependency_on_mclk, memory_clock, &memory_level->MinVddc); - PP_ASSERT_WITH_CODE((0 == result), - "can not find MinVddc voltage value from memory VDDC voltage dependency table", return result); - } - - if (data->vddci_control == SMU7_VOLTAGE_CONTROL_NONE) { - memory_level->MinVddci = memory_level->MinVddc; - } else if (NULL != hwmgr->dyn_state.vddci_dependency_on_mclk) { - result = iceland_get_dependency_volt_by_clk(hwmgr, - hwmgr->dyn_state.vddci_dependency_on_mclk, - memory_clock, - &memory_level->MinVddci); - PP_ASSERT_WITH_CODE((0 == result), - "can not find MinVddci voltage value from memory VDDCI voltage dependency table", return result); - } - - memory_level->MinVddcPhases = 1; - - if (data->vddc_phase_shed_control) { - iceland_populate_phase_value_based_on_mclk(hwmgr, hwmgr->dyn_state.vddc_phase_shed_limits_table, - memory_clock, &memory_level->MinVddcPhases); - } - - memory_level->EnabledForThrottle = 1; - memory_level->EnabledForActivity = 0; - memory_level->UpHyst = 0; - memory_level->DownHyst = 100; - memory_level->VoltageDownHyst = 0; - - /* Indicates maximum activity level for this performance level.*/ - memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target; - memory_level->StutterEnable = 0; - memory_level->StrobeEnable = 0; - memory_level->EdcReadEnable = 0; - memory_level->EdcWriteEnable = 0; - memory_level->RttEnable = 0; - - /* default set to low watermark. Highest level will be set to high later.*/ - memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - cgs_get_active_displays_info(hwmgr->device, &info); - data->display_timing.num_existing_displays = info.display_count; - - /* stutter mode not support on iceland */ - - /* decide strobe mode*/ - memory_level->StrobeEnable = (mclk_strobe_mode_threshold != 0) && - (memory_clock <= mclk_strobe_mode_threshold); - - /* decide EDC mode and memory clock ratio*/ - if (data->is_memory_gddr5) { - memory_level->StrobeRatio = iceland_get_mclk_frequency_ratio(memory_clock, - memory_level->StrobeEnable); - - if ((mclk_edc_enable_threshold != 0) && - (memory_clock > mclk_edc_enable_threshold)) { - memory_level->EdcReadEnable = 1; - } - - if ((mclk_edc_wr_enable_threshold != 0) && - (memory_clock > mclk_edc_wr_enable_threshold)) { - memory_level->EdcWriteEnable = 1; - } - - if (memory_level->StrobeEnable) { - if (iceland_get_mclk_frequency_ratio(memory_clock, 1) >= - ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; - else - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0; - } else - dll_state_on = data->dll_default_on; - } else { - memory_level->StrobeRatio = - iceland_get_ddr3_mclk_frequency_ratio(memory_clock); - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; - } - - result = iceland_calculate_mclk_params(hwmgr, - memory_clock, memory_level, memory_level->StrobeEnable, dll_state_on); - - if (0 == result) { - memory_level->MinVddc = PP_HOST_TO_SMC_UL(memory_level->MinVddc * VOLTAGE_SCALE); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinVddcPhases); - memory_level->MinVddci = PP_HOST_TO_SMC_UL(memory_level->MinVddci * VOLTAGE_SCALE); - memory_level->MinMvdd = PP_HOST_TO_SMC_UL(memory_level->MinMvdd * VOLTAGE_SCALE); - /* MCLK frequency in units of 10KHz*/ - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency); - /* Indicates maximum activity level for this performance level.*/ - CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2); - } - - return result; -} - -/** - * Populates all SMC MCLK levels' structure based on the trimmed allowed dpm memory clock states - * - * @param hwmgr the address of the hardware manager - */ - -int iceland_populate_all_memory_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - int result; - - /* populate MCLK dpm table to SMU7 */ - uint32_t level_array_adress = smu_data->smu7_data.dpm_table_start + offsetof(SMU71_Discrete_DpmTable, MemoryLevel); - uint32_t level_array_size = sizeof(SMU71_Discrete_MemoryLevel) * SMU71_MAX_LEVELS_MEMORY; - SMU71_Discrete_MemoryLevel *levels = smu_data->smc_state_table.MemoryLevel; - uint32_t i; - - memset(levels, 0x00, level_array_size); - - for (i = 0; i < dpm_table->mclk_table.count; i++) { - PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), - "can not populate memory level as memory clock is zero", return -EINVAL); - result = iceland_populate_single_memory_level(hwmgr, dpm_table->mclk_table.dpm_levels[i].value, - &(smu_data->smc_state_table.MemoryLevel[i])); - if (0 != result) { - return result; - } - } - - /* Only enable level 0 for now.*/ - smu_data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1; - - /* - * in order to prevent MC activity from stutter mode to push DPM up. - * the UVD change complements this by putting the MCLK in a higher state - * by default such that we are not effected by up threshold or and MCLK DPM latency. - */ - smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F; - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel); - - smu_data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count; - data->dpm_level_enable_mask.mclk_dpm_enable_mask = phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); - /* set highest level watermark to high*/ - smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; - - /* level count will send to smc once at init smc table and never change*/ - result = smu7_copy_bytes_to_smc(hwmgr, - level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, - SMC_RAM_END); - - return result; -} - -static int iceland_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, - SMU71_Discrete_VoltageLevel *voltage) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - uint32_t i = 0; - - if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { - /* find mvdd value which clock is more than request */ - for (i = 0; i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count; i++) { - if (mclk <= hwmgr->dyn_state.mvdd_dependency_on_mclk->entries[i].clk) { - /* Always round to higher voltage. */ - voltage->Voltage = data->mvdd_voltage_table.entries[i].value; - break; - } - } - - PP_ASSERT_WITH_CODE(i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count, - "MVDD Voltage is outside the supported range.", return -EINVAL); - - } else { - return -EINVAL; - } - - return 0; -} - -static int iceland_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - int result = 0; - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct pp_atomctrl_clock_dividers_vi dividers; - uint32_t vddc_phase_shed_control = 0; - - SMU71_Discrete_VoltageLevel voltage_level; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; - uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; - uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; - - - /* The ACPI state should not do DPM on DC (or ever).*/ - table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; - - if (data->acpi_vddc) - table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->acpi_vddc * VOLTAGE_SCALE); - else - table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->min_vddc_in_pptable * VOLTAGE_SCALE); - - table->ACPILevel.MinVddcPhases = vddc_phase_shed_control ? 0 : 1; - /* assign zero for now*/ - table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr); - - /* get the engine clock dividers for this clock value*/ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, - table->ACPILevel.SclkFrequency, ÷rs); - - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", return result); - - /* divider ID for required SCLK*/ - table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; - table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - table->ACPILevel.DeepSleepDivId = 0; - - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_PWRON, 0); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_RESET, 1); - spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, - CG_SPLL_FUNC_CNTL_2, SCLK_MUX_SEL, 4); - - table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; - table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; - table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - table->ACPILevel.CcPwrDynRm = 0; - table->ACPILevel.CcPwrDynRm1 = 0; - - - /* For various features to be enabled/disabled while this level is active.*/ - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); - /* SCLK frequency in units of 10KHz*/ - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); - - /* table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;*/ - table->MemoryACPILevel.MinVddc = table->ACPILevel.MinVddc; - table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases; - - if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) - table->MemoryACPILevel.MinVddci = table->MemoryACPILevel.MinVddc; - else { - if (data->acpi_vddci != 0) - table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->acpi_vddci * VOLTAGE_SCALE); - else - table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->min_vddci_in_pptable * VOLTAGE_SCALE); - } - - if (0 == iceland_populate_mvdd_value(hwmgr, 0, &voltage_level)) - table->MemoryACPILevel.MinMvdd = - PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE); - else - table->MemoryACPILevel.MinMvdd = 0; - - /* Force reset on DLL*/ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1); - - /* Disable DLL in ACPIState*/ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0); - - /* Enable DLL bypass signal*/ - dll_cntl = PHM_SET_FIELD(dll_cntl, - DLL_CNTL, MRDCK0_BYPASS, 0); - dll_cntl = PHM_SET_FIELD(dll_cntl, - DLL_CNTL, MRDCK1_BYPASS, 0); - - table->MemoryACPILevel.DllCntl = - PP_HOST_TO_SMC_UL(dll_cntl); - table->MemoryACPILevel.MclkPwrmgtCntl = - PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl); - table->MemoryACPILevel.MpllAdFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL); - table->MemoryACPILevel.MpllDqFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL); - table->MemoryACPILevel.MpllFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL); - table->MemoryACPILevel.MpllFuncCntl_1 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1); - table->MemoryACPILevel.MpllFuncCntl_2 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2); - table->MemoryACPILevel.MpllSs1 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1); - table->MemoryACPILevel.MpllSs2 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2); - - table->MemoryACPILevel.EnabledForThrottle = 0; - table->MemoryACPILevel.EnabledForActivity = 0; - table->MemoryACPILevel.UpHyst = 0; - table->MemoryACPILevel.DownHyst = 100; - table->MemoryACPILevel.VoltageDownHyst = 0; - /* Indicates maximum activity level for this performance level.*/ - table->MemoryACPILevel.ActivityLevel = PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); - - table->MemoryACPILevel.StutterEnable = 0; - table->MemoryACPILevel.StrobeEnable = 0; - table->MemoryACPILevel.EdcReadEnable = 0; - table->MemoryACPILevel.EdcWriteEnable = 0; - table->MemoryACPILevel.RttEnable = 0; - - return result; -} - -static int iceland_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - return 0; -} - -static int iceland_populate_smc_vce_level(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - return 0; -} - -static int iceland_populate_smc_acp_level(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - return 0; -} - -static int iceland_populate_smc_samu_level(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - return 0; -} - -static int iceland_populate_memory_timing_parameters( - struct pp_hwmgr *hwmgr, - uint32_t engine_clock, - uint32_t memory_clock, - struct SMU71_Discrete_MCArbDramTimingTableEntry *arb_regs - ) -{ - uint32_t dramTiming; - uint32_t dramTiming2; - uint32_t burstTime; - int result; - - result = atomctrl_set_engine_dram_timings_rv770(hwmgr, - engine_clock, memory_clock); - - PP_ASSERT_WITH_CODE(result == 0, - "Error calling VBIOS to set DRAM_TIMING.", return result); - - dramTiming = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); - dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); - burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); - - arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dramTiming); - arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2); - arb_regs->McArbBurstTime = (uint8_t)burstTime; - - return 0; -} - -/** - * Setup parameters for the MC ARB. - * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 - * This function is to be called from the SetPowerState table. - */ -static int iceland_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - int result = 0; - SMU71_Discrete_MCArbDramTimingTable arb_regs; - uint32_t i, j; - - memset(&arb_regs, 0x00, sizeof(SMU71_Discrete_MCArbDramTimingTable)); - - for (i = 0; i < data->dpm_table.sclk_table.count; i++) { - for (j = 0; j < data->dpm_table.mclk_table.count; j++) { - result = iceland_populate_memory_timing_parameters - (hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value, - data->dpm_table.mclk_table.dpm_levels[j].value, - &arb_regs.entries[i][j]); - - if (0 != result) { - break; - } - } - } - - if (0 == result) { - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.arb_table_start, - (uint8_t *)&arb_regs, - sizeof(SMU71_Discrete_MCArbDramTimingTable), - SMC_RAM_END - ); - } - - return result; -} - -static int iceland_populate_smc_boot_level(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *table) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - table->GraphicsBootLevel = 0; - table->MemoryBootLevel = 0; - - /* find boot level from dpm table*/ - result = phm_find_boot_level(&(data->dpm_table.sclk_table), - data->vbios_boot_state.sclk_bootup_value, - (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); - - if (0 != result) { - smu_data->smc_state_table.GraphicsBootLevel = 0; - pr_err("VBIOS did not find boot engine clock value \ - in dependency table. Using Graphics DPM level 0!"); - result = 0; - } - - result = phm_find_boot_level(&(data->dpm_table.mclk_table), - data->vbios_boot_state.mclk_bootup_value, - (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); - - if (0 != result) { - smu_data->smc_state_table.MemoryBootLevel = 0; - pr_err("VBIOS did not find boot engine clock value \ - in dependency table. Using Memory DPM level 0!"); - result = 0; - } - - table->BootVddc = data->vbios_boot_state.vddc_bootup_value; - if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) - table->BootVddci = table->BootVddc; - else - table->BootVddci = data->vbios_boot_state.vddci_bootup_value; - - table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value; - - return result; -} - -static int iceland_populate_mc_reg_address(struct pp_hwmgr *hwmgr, - SMU71_Discrete_MCRegisters *mc_reg_table) -{ - const struct iceland_smumgr *smu_data = (struct iceland_smumgr *)hwmgr->smu_backend; - - uint32_t i, j; - - for (i = 0, j = 0; j < smu_data->mc_reg_table.last; j++) { - if (smu_data->mc_reg_table.validflag & 1<address[] array out of boundary", return -EINVAL); - mc_reg_table->address[i].s0 = - PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s0); - mc_reg_table->address[i].s1 = - PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s1); - i++; - } - } - - mc_reg_table->last = (uint8_t)i; - - return 0; -} - -/*convert register values from driver to SMC format */ -static void iceland_convert_mc_registers( - const struct iceland_mc_reg_entry *entry, - SMU71_Discrete_MCRegisterSet *data, - uint32_t num_entries, uint32_t valid_flag) -{ - uint32_t i, j; - - for (i = 0, j = 0; j < num_entries; j++) { - if (valid_flag & 1<value[i] = PP_HOST_TO_SMC_UL(entry->mc_data[j]); - i++; - } - } -} - -static int iceland_convert_mc_reg_table_entry_to_smc(struct pp_hwmgr *hwmgr, - const uint32_t memory_clock, - SMU71_Discrete_MCRegisterSet *mc_reg_table_data - ) -{ - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - uint32_t i = 0; - - for (i = 0; i < smu_data->mc_reg_table.num_entries; i++) { - if (memory_clock <= - smu_data->mc_reg_table.mc_reg_table_entry[i].mclk_max) { - break; - } - } - - if ((i == smu_data->mc_reg_table.num_entries) && (i > 0)) - --i; - - iceland_convert_mc_registers(&smu_data->mc_reg_table.mc_reg_table_entry[i], - mc_reg_table_data, smu_data->mc_reg_table.last, - smu_data->mc_reg_table.validflag); - - return 0; -} - -static int iceland_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr, - SMU71_Discrete_MCRegisters *mc_regs) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - int res; - uint32_t i; - - for (i = 0; i < data->dpm_table.mclk_table.count; i++) { - res = iceland_convert_mc_reg_table_entry_to_smc( - hwmgr, - data->dpm_table.mclk_table.dpm_levels[i].value, - &mc_regs->data[i] - ); - - if (0 != res) - result = res; - } - - return result; -} - -static int iceland_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t address; - int32_t result; - - if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) - return 0; - - - memset(&smu_data->mc_regs, 0, sizeof(SMU71_Discrete_MCRegisters)); - - result = iceland_convert_mc_reg_table_to_smc(hwmgr, &(smu_data->mc_regs)); - - if (result != 0) - return result; - - - address = smu_data->smu7_data.mc_reg_table_start + (uint32_t)offsetof(SMU71_Discrete_MCRegisters, data[0]); - - return smu7_copy_bytes_to_smc(hwmgr, address, - (uint8_t *)&smu_data->mc_regs.data[0], - sizeof(SMU71_Discrete_MCRegisterSet) * data->dpm_table.mclk_table.count, - SMC_RAM_END); -} - -static int iceland_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - - memset(&smu_data->mc_regs, 0x00, sizeof(SMU71_Discrete_MCRegisters)); - result = iceland_populate_mc_reg_address(hwmgr, &(smu_data->mc_regs)); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize MCRegTable for the MC register addresses!", return result;); - - result = iceland_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize MCRegTable for driver state!", return result;); - - return smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.mc_reg_table_start, - (uint8_t *)&smu_data->mc_regs, sizeof(SMU71_Discrete_MCRegisters), SMC_RAM_END); -} - -static int iceland_populate_smc_initial_state(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - uint8_t count, level; - - count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->count); - - for (level = 0; level < count; level++) { - if (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[level].clk - >= data->vbios_boot_state.sclk_bootup_value) { - smu_data->smc_state_table.GraphicsBootLevel = level; - break; - } - } - - count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_mclk->count); - - for (level = 0; level < count; level++) { - if (hwmgr->dyn_state.vddc_dependency_on_mclk->entries[level].clk - >= data->vbios_boot_state.mclk_bootup_value) { - smu_data->smc_state_table.MemoryBootLevel = level; - break; - } - } - - return 0; -} - -static int iceland_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; - SMU71_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); - struct phm_cac_tdp_table *cac_dtp_table = hwmgr->dyn_state.cac_dtp_table; - struct phm_ppm_table *ppm = hwmgr->dyn_state.ppm_parameter_table; - const uint16_t *def1, *def2; - int i, j, k; - - - /* - * TDP number of fraction bits are changed from 8 to 7 for Iceland - * as requested by SMC team - */ - - dpm_table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 256)); - dpm_table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); - - - dpm_table->DTETjOffset = 0; - - dpm_table->GpuTjMax = (uint8_t)(data->thermal_temp_setting.temperature_high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES); - dpm_table->GpuTjHyst = 8; - - dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; - - /* The following are for new Iceland Multi-input fan/thermal control */ - if (NULL != ppm) { - dpm_table->PPM_PkgPwrLimit = (uint16_t)ppm->dgpu_tdp * 256 / 1000; - dpm_table->PPM_TemperatureLimit = (uint16_t)ppm->tj_max * 256; - } else { - dpm_table->PPM_PkgPwrLimit = 0; - dpm_table->PPM_TemperatureLimit = 0; - } - - CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_PkgPwrLimit); - CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_TemperatureLimit); - - dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bapm_temp_gradient); - def1 = defaults->bapmti_r; - def2 = defaults->bapmti_rc; - - for (i = 0; i < SMU71_DTE_ITERATIONS; i++) { - for (j = 0; j < SMU71_DTE_SOURCES; j++) { - for (k = 0; k < SMU71_DTE_SINKS; k++) { - dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*def1); - dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*def2); - def1++; - def2++; - } - } - } - - return 0; -} - -static int iceland_populate_smc_svi2_config(struct pp_hwmgr *hwmgr, - SMU71_Discrete_DpmTable *tab) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) - tab->SVI2Enable |= VDDC_ON_SVI2; - - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) - tab->SVI2Enable |= VDDCI_ON_SVI2; - else - tab->MergedVddci = 1; - - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) - tab->SVI2Enable |= MVDD_ON_SVI2; - - PP_ASSERT_WITH_CODE(tab->SVI2Enable != (VDDC_ON_SVI2 | VDDCI_ON_SVI2 | MVDD_ON_SVI2) && - (tab->SVI2Enable & VDDC_ON_SVI2), "SVI2 domain configuration is incorrect!", return -EINVAL); - - return 0; -} - -/** - * Initializes the SMC table and uploads it - * - * @param hwmgr the address of the powerplay hardware manager. - * @param pInput the pointer to input data (PowerState) - * @return always 0 - */ -int iceland_init_smc_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - SMU71_Discrete_DpmTable *table = &(smu_data->smc_state_table); - - - iceland_initialize_power_tune_defaults(hwmgr); - memset(&(smu_data->smc_state_table), 0x00, sizeof(smu_data->smc_state_table)); - - if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) { - iceland_populate_smc_voltage_tables(hwmgr, table); - } - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; - - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StepVddc)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; - - if (data->is_memory_gddr5) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; - - - if (data->ulv_supported) { - result = iceland_populate_ulv_state(hwmgr, &(smu_data->ulv_setting)); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ULV state!", return result;); - - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixCG_ULV_PARAMETER, 0x40035); - } - - result = iceland_populate_smc_link_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Link Level!", return result;); - - result = iceland_populate_all_graphic_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Graphics Level!", return result;); - - result = iceland_populate_all_memory_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Memory Level!", return result;); - - result = iceland_populate_smc_acpi_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ACPI Level!", return result;); - - result = iceland_populate_smc_vce_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize VCE Level!", return result;); - - result = iceland_populate_smc_acp_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ACP Level!", return result;); - - result = iceland_populate_smc_samu_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize SAMU Level!", return result;); - - /* Since only the initial state is completely set up at this point (the other states are just copies of the boot state) we only */ - /* need to populate the ARB settings for the initial state. */ - result = iceland_program_memory_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to Write ARB settings for the initial state.", return result;); - - result = iceland_populate_smc_uvd_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize UVD Level!", return result;); - - table->GraphicsBootLevel = 0; - table->MemoryBootLevel = 0; - - result = iceland_populate_smc_boot_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Boot Level!", return result;); - - result = iceland_populate_smc_initial_state(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, "Failed to initialize Boot State!", return result); - - result = iceland_populate_bapm_parameters_in_dpm_table(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, "Failed to populate BAPM Parameters!", return result); - - table->GraphicsVoltageChangeEnable = 1; - table->GraphicsThermThrottleEnable = 1; - table->GraphicsInterval = 1; - table->VoltageInterval = 1; - table->ThermalInterval = 1; - - table->TemperatureLimitHigh = - (data->thermal_temp_setting.temperature_high * - SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - table->TemperatureLimitLow = - (data->thermal_temp_setting.temperature_low * - SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - - table->MemoryVoltageChangeEnable = 1; - table->MemoryInterval = 1; - table->VoltageResponseTime = 0; - table->PhaseResponseTime = 0; - table->MemoryThermThrottleEnable = 1; - table->PCIeBootLinkLevel = 0; - table->PCIeGenInterval = 1; - - result = iceland_populate_smc_svi2_config(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate SVI2 setting!", return result); - - table->ThermGpio = 17; - table->SclkStepSize = 0x4000; - - CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcVid); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcPhase); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddciVid); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskMvddVid); - CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); - CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); - CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); - - table->BootVddc = PP_HOST_TO_SMC_US(table->BootVddc * VOLTAGE_SCALE); - table->BootVddci = PP_HOST_TO_SMC_US(table->BootVddci * VOLTAGE_SCALE); - table->BootMVdd = PP_HOST_TO_SMC_US(table->BootMVdd * VOLTAGE_SCALE); - - /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ - result = smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.dpm_table_start + - offsetof(SMU71_Discrete_DpmTable, SystemFlags), - (uint8_t *)&(table->SystemFlags), - sizeof(SMU71_Discrete_DpmTable)-3 * sizeof(SMU71_PIDController), - SMC_RAM_END); - - PP_ASSERT_WITH_CODE(0 == result, - "Failed to upload dpm data to SMC memory!", return result;); - - /* Upload all ulv setting to SMC memory.(dpm level, dpm level count etc) */ - result = smu7_copy_bytes_to_smc(hwmgr, - smu_data->smu7_data.ulv_setting_starts, - (uint8_t *)&(smu_data->ulv_setting), - sizeof(SMU71_Discrete_Ulv), - SMC_RAM_END); - - - result = iceland_populate_initial_mc_reg_table(hwmgr); - PP_ASSERT_WITH_CODE((0 == result), - "Failed to populate initialize MC Reg table!", return result); - - result = iceland_populate_pm_fuses(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate PM fuses to SMC memory!", return result); - - return 0; -} - -/** -* Set up the fan table to control the fan using the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ -int iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) -{ - struct smu7_smumgr *smu7_data = (struct smu7_smumgr *)(hwmgr->smu_backend); - SMU71_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; - uint32_t duty100; - uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; - uint16_t fdo_min, slope1, slope2; - uint32_t reference_clock; - int res; - uint64_t tmp64; - - if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) - return 0; - - if (hwmgr->thermal_controller.fanInfo.bNoFan) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - if (0 == smu7_data->fan_table_start) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100); - - if (0 == duty100) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100; - do_div(tmp64, 10000); - fdo_min = (uint16_t)tmp64; - - t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - hwmgr->thermal_controller.advanceFanControlParameters.usTMin; - t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - hwmgr->thermal_controller.advanceFanControlParameters.usTMed; - - pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; - pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; - - slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); - slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); - - fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100); - fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100); - fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100); - - fan_table.Slope1 = cpu_to_be16(slope1); - fan_table.Slope2 = cpu_to_be16(slope2); - - fan_table.FdoMin = cpu_to_be16(fdo_min); - - fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst); - - fan_table.HystUp = cpu_to_be16(1); - - fan_table.HystSlope = cpu_to_be16(1); - - fan_table.TempRespLim = cpu_to_be16(5); - - reference_clock = smu7_get_xclk(hwmgr); - - fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600); - - fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); - - fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL); - - /* fan_table.FanControl_GL_Flag = 1; */ - - res = smu7_copy_bytes_to_smc(hwmgr, smu7_data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), SMC_RAM_END); - - return 0; -} - - -static int iceland_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (data->need_update_smu7_dpm_table & - (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) - return iceland_program_memory_timing_parameters(hwmgr); - - return 0; -} - -int iceland_update_sclk_threshold(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); - - int result = 0; - uint32_t low_sclk_interrupt_threshold = 0; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkThrottleLowNotification) - && (hwmgr->gfx_arbiter.sclk_threshold != - data->low_sclk_interrupt_threshold)) { - data->low_sclk_interrupt_threshold = - hwmgr->gfx_arbiter.sclk_threshold; - low_sclk_interrupt_threshold = - data->low_sclk_interrupt_threshold; - - CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); - - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.dpm_table_start + - offsetof(SMU71_Discrete_DpmTable, - LowSclkInterruptThreshold), - (uint8_t *)&low_sclk_interrupt_threshold, - sizeof(uint32_t), - SMC_RAM_END); - } - - result = iceland_update_and_upload_mc_reg_table(hwmgr); - - PP_ASSERT_WITH_CODE((0 == result), "Failed to upload MC reg table!", return result); - - result = iceland_program_mem_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE((result == 0), - "Failed to program memory timing parameters!", - ); - - return result; -} - -uint32_t iceland_get_offsetof(uint32_t type, uint32_t member) -{ - switch (type) { - case SMU_SoftRegisters: - switch (member) { - case HandshakeDisables: - return offsetof(SMU71_SoftRegisters, HandshakeDisables); - case VoltageChangeTimeout: - return offsetof(SMU71_SoftRegisters, VoltageChangeTimeout); - case AverageGraphicsActivity: - return offsetof(SMU71_SoftRegisters, AverageGraphicsActivity); - case PreVBlankGap: - return offsetof(SMU71_SoftRegisters, PreVBlankGap); - case VBlankTimeout: - return offsetof(SMU71_SoftRegisters, VBlankTimeout); - case UcodeLoadStatus: - return offsetof(SMU71_SoftRegisters, UcodeLoadStatus); - case DRAM_LOG_ADDR_H: - return offsetof(SMU71_SoftRegisters, DRAM_LOG_ADDR_H); - case DRAM_LOG_ADDR_L: - return offsetof(SMU71_SoftRegisters, DRAM_LOG_ADDR_L); - case DRAM_LOG_PHY_ADDR_H: - return offsetof(SMU71_SoftRegisters, DRAM_LOG_PHY_ADDR_H); - case DRAM_LOG_PHY_ADDR_L: - return offsetof(SMU71_SoftRegisters, DRAM_LOG_PHY_ADDR_L); - case DRAM_LOG_BUFF_SIZE: - return offsetof(SMU71_SoftRegisters, DRAM_LOG_BUFF_SIZE); - } - case SMU_Discrete_DpmTable: - switch (member) { - case LowSclkInterruptThreshold: - return offsetof(SMU71_Discrete_DpmTable, LowSclkInterruptThreshold); - } - } - pr_warn("can't get the offset of type %x member %x\n", type, member); - return 0; -} - -uint32_t iceland_get_mac_definition(uint32_t value) -{ - switch (value) { - case SMU_MAX_LEVELS_GRAPHICS: - return SMU71_MAX_LEVELS_GRAPHICS; - case SMU_MAX_LEVELS_MEMORY: - return SMU71_MAX_LEVELS_MEMORY; - case SMU_MAX_LEVELS_LINK: - return SMU71_MAX_LEVELS_LINK; - case SMU_MAX_ENTRIES_SMIO: - return SMU71_MAX_ENTRIES_SMIO; - case SMU_MAX_LEVELS_VDDC: - return SMU71_MAX_LEVELS_VDDC; - case SMU_MAX_LEVELS_VDDCI: - return SMU71_MAX_LEVELS_VDDCI; - case SMU_MAX_LEVELS_MVDD: - return SMU71_MAX_LEVELS_MVDD; - } - - pr_warn("can't get the mac of %x\n", value); - return 0; -} - -/** - * Get the location of various tables inside the FW image. - * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 - */ -int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct smu7_smumgr *smu7_data = (struct smu7_smumgr *)(hwmgr->smu_backend); - - uint32_t tmp; - int result; - bool error = false; - - result = smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, DpmTable), - &tmp, SMC_RAM_END); - - if (0 == result) { - smu7_data->dpm_table_start = tmp; - } - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, SoftRegisters), - &tmp, SMC_RAM_END); - - if (0 == result) { - data->soft_regs_start = tmp; - smu7_data->soft_regs_start = tmp; - } - - error |= (0 != result); - - - result = smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, mcRegisterTable), - &tmp, SMC_RAM_END); - - if (0 == result) { - smu7_data->mc_reg_table_start = tmp; - } - - result = smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, FanTable), - &tmp, SMC_RAM_END); - - if (0 == result) { - smu7_data->fan_table_start = tmp; - } - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, mcArbDramTimingTable), - &tmp, SMC_RAM_END); - - if (0 == result) { - smu7_data->arb_table_start = tmp; - } - - error |= (0 != result); - - - result = smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, Version), - &tmp, SMC_RAM_END); - - if (0 == result) { - hwmgr->microcode_version_info.SMC = tmp; - } - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU71_FIRMWARE_HEADER_LOCATION + - offsetof(SMU71_Firmware_Header, UlvSettings), - &tmp, SMC_RAM_END); - - if (0 == result) { - smu7_data->ulv_setting_starts = tmp; - } - - error |= (0 != result); - - return error ? 1 : 0; -} - -/*---------------------------MC----------------------------*/ - -static uint8_t iceland_get_memory_modile_index(struct pp_hwmgr *hwmgr) -{ - return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16)); -} - -static bool iceland_check_s0_mc_reg_index(uint16_t in_reg, uint16_t *out_reg) -{ - bool result = true; - - switch (in_reg) { - case mmMC_SEQ_RAS_TIMING: - *out_reg = mmMC_SEQ_RAS_TIMING_LP; - break; - - case mmMC_SEQ_DLL_STBY: - *out_reg = mmMC_SEQ_DLL_STBY_LP; - break; - - case mmMC_SEQ_G5PDX_CMD0: - *out_reg = mmMC_SEQ_G5PDX_CMD0_LP; - break; - - case mmMC_SEQ_G5PDX_CMD1: - *out_reg = mmMC_SEQ_G5PDX_CMD1_LP; - break; - - case mmMC_SEQ_G5PDX_CTRL: - *out_reg = mmMC_SEQ_G5PDX_CTRL_LP; - break; - - case mmMC_SEQ_CAS_TIMING: - *out_reg = mmMC_SEQ_CAS_TIMING_LP; - break; - - case mmMC_SEQ_MISC_TIMING: - *out_reg = mmMC_SEQ_MISC_TIMING_LP; - break; - - case mmMC_SEQ_MISC_TIMING2: - *out_reg = mmMC_SEQ_MISC_TIMING2_LP; - break; - - case mmMC_SEQ_PMG_DVS_CMD: - *out_reg = mmMC_SEQ_PMG_DVS_CMD_LP; - break; - - case mmMC_SEQ_PMG_DVS_CTL: - *out_reg = mmMC_SEQ_PMG_DVS_CTL_LP; - break; - - case mmMC_SEQ_RD_CTL_D0: - *out_reg = mmMC_SEQ_RD_CTL_D0_LP; - break; - - case mmMC_SEQ_RD_CTL_D1: - *out_reg = mmMC_SEQ_RD_CTL_D1_LP; - break; - - case mmMC_SEQ_WR_CTL_D0: - *out_reg = mmMC_SEQ_WR_CTL_D0_LP; - break; - - case mmMC_SEQ_WR_CTL_D1: - *out_reg = mmMC_SEQ_WR_CTL_D1_LP; - break; - - case mmMC_PMG_CMD_EMRS: - *out_reg = mmMC_SEQ_PMG_CMD_EMRS_LP; - break; - - case mmMC_PMG_CMD_MRS: - *out_reg = mmMC_SEQ_PMG_CMD_MRS_LP; - break; - - case mmMC_PMG_CMD_MRS1: - *out_reg = mmMC_SEQ_PMG_CMD_MRS1_LP; - break; - - case mmMC_SEQ_PMG_TIMING: - *out_reg = mmMC_SEQ_PMG_TIMING_LP; - break; - - case mmMC_PMG_CMD_MRS2: - *out_reg = mmMC_SEQ_PMG_CMD_MRS2_LP; - break; - - case mmMC_SEQ_WR_CTL_2: - *out_reg = mmMC_SEQ_WR_CTL_2_LP; - break; - - default: - result = false; - break; - } - - return result; -} - -static int iceland_set_s0_mc_reg_index(struct iceland_mc_reg_table *table) -{ - uint32_t i; - uint16_t address; - - for (i = 0; i < table->last; i++) { - table->mc_reg_address[i].s0 = - iceland_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) - ? address : table->mc_reg_address[i].s1; - } - return 0; -} - -static int iceland_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, - struct iceland_mc_reg_table *ni_table) -{ - uint8_t i, j; - - PP_ASSERT_WITH_CODE((table->last <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES), - "Invalid VramInfo table.", return -EINVAL); - - for (i = 0; i < table->last; i++) { - ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1; - } - ni_table->last = table->last; - - for (i = 0; i < table->num_entries; i++) { - ni_table->mc_reg_table_entry[i].mclk_max = - table->mc_reg_table_entry[i].mclk_max; - for (j = 0; j < table->last; j++) { - ni_table->mc_reg_table_entry[i].mc_data[j] = - table->mc_reg_table_entry[i].mc_data[j]; - } - } - - ni_table->num_entries = table->num_entries; - - return 0; -} - -/** - * VBIOS omits some information to reduce size, we need to recover them here. - * 1. when we see mmMC_SEQ_MISC1, bit[31:16] EMRS1, need to be write to mmMC_PMG_CMD_EMRS /_LP[15:0]. - * Bit[15:0] MRS, need to be update mmMC_PMG_CMD_MRS/_LP[15:0] - * 2. when we see mmMC_SEQ_RESERVE_M, bit[15:0] EMRS2, need to be write to mmMC_PMG_CMD_MRS1/_LP[15:0]. - * 3. need to set these data for each clock range - * - * @param hwmgr the address of the powerplay hardware manager. - * @param table the address of MCRegTable - * @return always 0 - */ -static int iceland_set_mc_special_registers(struct pp_hwmgr *hwmgr, - struct iceland_mc_reg_table *table) -{ - uint8_t i, j, k; - uint32_t temp_reg; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - for (i = 0, j = table->last; i < table->last; i++) { - PP_ASSERT_WITH_CODE((j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - switch (table->mc_reg_address[i].s1) { - - case mmMC_SEQ_MISC1: - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - ((temp_reg & 0xffff0000)) | - ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16); - } - j++; - PP_ASSERT_WITH_CODE((j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (temp_reg & 0xffff0000) | - (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); - - if (!data->is_memory_gddr5) { - table->mc_reg_table_entry[k].mc_data[j] |= 0x100; - } - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - if (!data->is_memory_gddr5 && j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE) { - table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD; - table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16; - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - } - - break; - - case mmMC_SEQ_RESERVE_M: - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (temp_reg & 0xffff0000) | - (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - break; - - default: - break; - } - - } - - table->last = j; - - return 0; -} - -static int iceland_set_valid_flag(struct iceland_mc_reg_table *table) -{ - uint8_t i, j; - for (i = 0; i < table->last; i++) { - for (j = 1; j < table->num_entries; j++) { - if (table->mc_reg_table_entry[j-1].mc_data[i] != - table->mc_reg_table_entry[j].mc_data[i]) { - table->validflag |= (1<smu_backend); - pp_atomctrl_mc_reg_table *table; - struct iceland_mc_reg_table *ni_table = &smu_data->mc_reg_table; - uint8_t module_index = iceland_get_memory_modile_index(hwmgr); - - table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); - - if (NULL == table) - return -ENOMEM; - - /* Program additional LP registers that are no longer programmed by VBIOS */ - cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL)); - cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2)); - - memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table)); - - result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); - - if (0 == result) - result = iceland_copy_vbios_smc_reg_table(table, ni_table); - - if (0 == result) { - iceland_set_s0_mc_reg_index(ni_table); - result = iceland_set_mc_special_registers(hwmgr, ni_table); - } - - if (0 == result) - iceland_set_valid_flag(ni_table); - - kfree(table); - - return result; -} - -bool iceland_is_dpm_running(struct pp_hwmgr *hwmgr) -{ - return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, - CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) - ? true : false; -} diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.h b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.h deleted file mode 100644 index 13c8dbbccaf2..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - */ -#ifndef _ICELAND_SMC_H -#define _ICELAND_SMC_H - -#include "smumgr.h" - - -int iceland_populate_all_graphic_levels(struct pp_hwmgr *hwmgr); -int iceland_populate_all_memory_levels(struct pp_hwmgr *hwmgr); -int iceland_init_smc_table(struct pp_hwmgr *hwmgr); -int iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr); -int iceland_update_sclk_threshold(struct pp_hwmgr *hwmgr); -uint32_t iceland_get_offsetof(uint32_t type, uint32_t member); -uint32_t iceland_get_mac_definition(uint32_t value); -int iceland_process_firmware_header(struct pp_hwmgr *hwmgr); -int iceland_initialize_mc_reg_table(struct pp_hwmgr *hwmgr); -bool iceland_is_dpm_running(struct pp_hwmgr *hwmgr); -#endif - diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c index a778e174ba01..34128822b8fb 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c @@ -30,15 +30,84 @@ #include "smumgr.h" #include "iceland_smumgr.h" -#include "smu_ucode_xfer_vi.h" + #include "ppsmc.h" + +#include "cgs_common.h" + +#include "smu7_dyn_defaults.h" +#include "smu7_hwmgr.h" +#include "hardwaremanager.h" +#include "ppatomctrl.h" +#include "atombios.h" +#include "pppcielanes.h" +#include "pp_endian.h" +#include "processpptables.h" + + #include "smu/smu_7_1_1_d.h" #include "smu/smu_7_1_1_sh_mask.h" -#include "cgs_common.h" -#include "iceland_smc.h" +#include "smu71_discrete.h" + +#include "smu_ucode_xfer_vi.h" +#include "gmc/gmc_8_1_d.h" +#include "gmc/gmc_8_1_sh_mask.h" +#include "bif/bif_5_0_d.h" +#include "bif/bif_5_0_sh_mask.h" +#include "dce/dce_10_0_d.h" +#include "dce/dce_10_0_sh_mask.h" + #define ICELAND_SMC_SIZE 0x20000 +#define VOLTAGE_SCALE 4 +#define POWERTUNE_DEFAULT_SET_MAX 1 +#define VOLTAGE_VID_OFFSET_SCALE1 625 +#define VOLTAGE_VID_OFFSET_SCALE2 100 +#define MC_CG_ARB_FREQ_F1 0x0b +#define VDDC_VDDCI_DELTA 200 + +#define DEVICE_ID_VI_ICELAND_M_6900 0x6900 +#define DEVICE_ID_VI_ICELAND_M_6901 0x6901 +#define DEVICE_ID_VI_ICELAND_M_6902 0x6902 +#define DEVICE_ID_VI_ICELAND_M_6903 0x6903 + +static const struct iceland_pt_defaults defaults_iceland = { + /* + * sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, + * TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT + */ + 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, + { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61 }, + { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } +}; + +/* 35W - XT, XTL */ +static const struct iceland_pt_defaults defaults_icelandxt = { + /* + * sviLoadLIneEn, SviLoadLineVddC, + * TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, + * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, + * BAPM_TEMP_GRADIENT + */ + 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x0, + { 0xA7, 0x0, 0x0, 0xB5, 0x0, 0x0, 0x9F, 0x0, 0x0, 0xD6, 0x0, 0x0, 0xD7, 0x0, 0x0}, + { 0x1EA, 0x0, 0x0, 0x224, 0x0, 0x0, 0x25E, 0x0, 0x0, 0x28E, 0x0, 0x0, 0x2AB, 0x0, 0x0} +}; + +/* 25W - PRO, LE */ +static const struct iceland_pt_defaults defaults_icelandpro = { + /* + * sviLoadLIneEn, SviLoadLineVddC, + * TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, + * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, + * BAPM_TEMP_GRADIENT + */ + 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x0, + { 0xB7, 0x0, 0x0, 0xC3, 0x0, 0x0, 0xB5, 0x0, 0x0, 0xEA, 0x0, 0x0, 0xE6, 0x0, 0x0}, + { 0x1EA, 0x0, 0x0, 0x224, 0x0, 0x0, 0x25E, 0x0, 0x0, 0x28E, 0x0, 0x0, 0x2AB, 0x0, 0x0} +}; + static int iceland_start_smc(struct pp_hwmgr *hwmgr) { PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, @@ -191,13 +260,6 @@ static int iceland_start_smu(struct pp_hwmgr *hwmgr) return result; } -/** - * Write a 32bit value to the SMC SRAM space. - * ALL PARAMETERS ARE IN HOST BYTE ORDER. - * @param smumgr the address of the powerplay hardware manager. - * @param smcAddress the address in the SMC RAM to access. - * @param value to write to the SMC SRAM. - */ static int iceland_smu_init(struct pp_hwmgr *hwmgr) { int i; @@ -219,6 +281,2413 @@ static int iceland_smu_init(struct pp_hwmgr *hwmgr) return 0; } + +static void iceland_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) +{ + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + struct cgs_system_info sys_info = {0}; + uint32_t dev_id; + + sys_info.size = sizeof(struct cgs_system_info); + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; + cgs_query_system_info(hwmgr->device, &sys_info); + dev_id = (uint32_t)sys_info.value; + + switch (dev_id) { + case DEVICE_ID_VI_ICELAND_M_6900: + case DEVICE_ID_VI_ICELAND_M_6903: + smu_data->power_tune_defaults = &defaults_icelandxt; + break; + + case DEVICE_ID_VI_ICELAND_M_6901: + case DEVICE_ID_VI_ICELAND_M_6902: + smu_data->power_tune_defaults = &defaults_icelandpro; + break; + default: + smu_data->power_tune_defaults = &defaults_iceland; + pr_warn("Unknown V.I. Device ID.\n"); + break; + } + return; +} + +static int iceland_populate_svi_load_line(struct pp_hwmgr *hwmgr) +{ + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; + + smu_data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; + smu_data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddc; + smu_data->power_tune_table.SviLoadLineTrimVddC = 3; + smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; + + return 0; +} + +static int iceland_populate_tdc_limit(struct pp_hwmgr *hwmgr) +{ + uint16_t tdc_limit; + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; + + tdc_limit = (uint16_t)(hwmgr->dyn_state.cac_dtp_table->usTDC * 256); + smu_data->power_tune_table.TDC_VDDC_PkgLimit = + CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); + smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = + defaults->tdc_vddc_throttle_release_limit_perc; + smu_data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; + + return 0; +} + +static int iceland_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) +{ + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; + uint32_t temp; + + if (smu7_read_smc_sram_dword(hwmgr, + fuse_table_offset + + offsetof(SMU71_Discrete_PmFuses, TdcWaterfallCtl), + (uint32_t *)&temp, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", + return -EINVAL); + else + smu_data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; + + return 0; +} + +static int iceland_populate_temperature_scaler(struct pp_hwmgr *hwmgr) +{ + return 0; +} + +static int iceland_populate_gnb_lpml(struct pp_hwmgr *hwmgr) +{ + int i; + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + + /* Currently not used. Set all to zero. */ + for (i = 0; i < 8; i++) + smu_data->power_tune_table.GnbLPML[i] = 0; + + return 0; +} + +static int iceland_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) +{ + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + uint16_t HiSidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; + uint16_t LoSidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; + struct phm_cac_tdp_table *cac_table = hwmgr->dyn_state.cac_dtp_table; + + HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); + LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); + + smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = + CONVERT_FROM_HOST_TO_SMC_US(HiSidd); + smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = + CONVERT_FROM_HOST_TO_SMC_US(LoSidd); + + return 0; +} + +static int iceland_populate_bapm_vddc_vid_sidd(struct pp_hwmgr *hwmgr) +{ + int i; + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + uint8_t *hi_vid = smu_data->power_tune_table.BapmVddCVidHiSidd; + uint8_t *lo_vid = smu_data->power_tune_table.BapmVddCVidLoSidd; + + PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.cac_leakage_table, + "The CAC Leakage table does not exist!", return -EINVAL); + PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count <= 8, + "There should never be more than 8 entries for BapmVddcVid!!!", return -EINVAL); + PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count == hwmgr->dyn_state.vddc_dependency_on_sclk->count, + "CACLeakageTable->count and VddcDependencyOnSCLk->count not equal", return -EINVAL); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_EVV)) { + for (i = 0; (uint32_t) i < hwmgr->dyn_state.cac_leakage_table->count; i++) { + lo_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc1); + hi_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc2); + } + } else { + PP_ASSERT_WITH_CODE(false, "Iceland should always support EVV", return -EINVAL); + } + + return 0; +} + +static int iceland_populate_vddc_vid(struct pp_hwmgr *hwmgr) +{ + int i; + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + uint8_t *vid = smu_data->power_tune_table.VddCVid; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + PP_ASSERT_WITH_CODE(data->vddc_voltage_table.count <= 8, + "There should never be more than 8 entries for VddcVid!!!", + return -EINVAL); + + for (i = 0; i < (int)data->vddc_voltage_table.count; i++) { + vid[i] = convert_to_vid(data->vddc_voltage_table.entries[i].value); + } + + return 0; +} + + + +static int iceland_populate_pm_fuses(struct pp_hwmgr *hwmgr) +{ + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + uint32_t pm_fuse_table_offset; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment)) { + if (smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, PmFuseTable), + &pm_fuse_table_offset, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to get pm_fuse_table_offset Failed!", + return -EINVAL); + + /* DW0 - DW3 */ + if (iceland_populate_bapm_vddc_vid_sidd(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate bapm vddc vid Failed!", + return -EINVAL); + + /* DW4 - DW5 */ + if (iceland_populate_vddc_vid(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate vddc vid Failed!", + return -EINVAL); + + /* DW6 */ + if (iceland_populate_svi_load_line(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate SviLoadLine Failed!", + return -EINVAL); + /* DW7 */ + if (iceland_populate_tdc_limit(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TDCLimit Failed!", return -EINVAL); + /* DW8 */ + if (iceland_populate_dw8(hwmgr, pm_fuse_table_offset)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TdcWaterfallCtl, " + "LPMLTemperature Min and Max Failed!", + return -EINVAL); + + /* DW9-DW12 */ + if (0 != iceland_populate_temperature_scaler(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate LPMLTemperatureScaler Failed!", + return -EINVAL); + + /* DW13-DW16 */ + if (iceland_populate_gnb_lpml(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate GnbLPML Failed!", + return -EINVAL); + + /* DW18 */ + if (iceland_populate_bapm_vddc_base_leakage_sidd(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate BapmVddCBaseLeakage Hi and Lo Sidd Failed!", + return -EINVAL); + + if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, + (uint8_t *)&smu_data->power_tune_table, + sizeof(struct SMU71_Discrete_PmFuses), SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to download PmFuseTable Failed!", + return -EINVAL); + } + return 0; +} + +static int iceland_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, + struct phm_clock_voltage_dependency_table *allowed_clock_voltage_table, + uint32_t clock, uint32_t *vol) +{ + uint32_t i = 0; + + /* clock - voltage dependency table is empty table */ + if (allowed_clock_voltage_table->count == 0) + return -EINVAL; + + for (i = 0; i < allowed_clock_voltage_table->count; i++) { + /* find first sclk bigger than request */ + if (allowed_clock_voltage_table->entries[i].clk >= clock) { + *vol = allowed_clock_voltage_table->entries[i].v; + return 0; + } + } + + /* sclk is bigger than max sclk in the dependence table */ + *vol = allowed_clock_voltage_table->entries[i - 1].v; + + return 0; +} + +static int iceland_get_std_voltage_value_sidd(struct pp_hwmgr *hwmgr, + pp_atomctrl_voltage_table_entry *tab, uint16_t *hi, + uint16_t *lo) +{ + uint16_t v_index; + bool vol_found = false; + *hi = tab->value * VOLTAGE_SCALE; + *lo = tab->value * VOLTAGE_SCALE; + + /* SCLK/VDDC Dependency Table has to exist. */ + PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.vddc_dependency_on_sclk, + "The SCLK/VDDC Dependency Table does not exist.\n", + return -EINVAL); + + if (NULL == hwmgr->dyn_state.cac_leakage_table) { + pr_warn("CAC Leakage Table does not exist, using vddc.\n"); + return 0; + } + + /* + * Since voltage in the sclk/vddc dependency table is not + * necessarily in ascending order because of ELB voltage + * patching, loop through entire list to find exact voltage. + */ + for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { + if (tab->value == hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { + vol_found = true; + if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { + *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage * VOLTAGE_SCALE); + } else { + pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index, using maximum index from CAC table.\n"); + *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); + } + break; + } + } + + /* + * If voltage is not found in the first pass, loop again to + * find the best match, equal or higher value. + */ + if (!vol_found) { + for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) { + if (tab->value <= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) { + vol_found = true; + if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) { + *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage) * VOLTAGE_SCALE; + } else { + pr_warn("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index in second look up, using maximum index from CAC table."); + *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE; + *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE); + } + break; + } + } + + if (!vol_found) + pr_warn("Unable to get std_vddc from SCLK/VDDC Dependency Table, using vddc.\n"); + } + + return 0; +} + +static int iceland_populate_smc_voltage_table(struct pp_hwmgr *hwmgr, + pp_atomctrl_voltage_table_entry *tab, + SMU71_Discrete_VoltageLevel *smc_voltage_tab) +{ + int result; + + result = iceland_get_std_voltage_value_sidd(hwmgr, tab, + &smc_voltage_tab->StdVoltageHiSidd, + &smc_voltage_tab->StdVoltageLoSidd); + if (0 != result) { + smc_voltage_tab->StdVoltageHiSidd = tab->value * VOLTAGE_SCALE; + smc_voltage_tab->StdVoltageLoSidd = tab->value * VOLTAGE_SCALE; + } + + smc_voltage_tab->Voltage = PP_HOST_TO_SMC_US(tab->value * VOLTAGE_SCALE); + CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd); + CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd); + + return 0; +} + +static int iceland_populate_smc_vddc_table(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + unsigned int count; + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + table->VddcLevelCount = data->vddc_voltage_table.count; + for (count = 0; count < table->VddcLevelCount; count++) { + result = iceland_populate_smc_voltage_table(hwmgr, + &(data->vddc_voltage_table.entries[count]), + &(table->VddcLevel[count])); + PP_ASSERT_WITH_CODE(0 == result, "do not populate SMC VDDC voltage table", return -EINVAL); + + /* GPIO voltage control */ + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->voltage_control) + table->VddcLevel[count].Smio |= data->vddc_voltage_table.entries[count].smio_low; + else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) + table->VddcLevel[count].Smio = 0; + } + + CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount); + + return 0; +} + +static int iceland_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t count; + int result; + + table->VddciLevelCount = data->vddci_voltage_table.count; + + for (count = 0; count < table->VddciLevelCount; count++) { + result = iceland_populate_smc_voltage_table(hwmgr, + &(data->vddci_voltage_table.entries[count]), + &(table->VddciLevel[count])); + PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC VDDCI voltage table", return -EINVAL); + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) + table->VddciLevel[count].Smio |= data->vddci_voltage_table.entries[count].smio_low; + else + table->VddciLevel[count].Smio |= 0; + } + + CONVERT_FROM_HOST_TO_SMC_UL(table->VddciLevelCount); + + return 0; +} + +static int iceland_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t count; + int result; + + table->MvddLevelCount = data->mvdd_voltage_table.count; + + for (count = 0; count < table->VddciLevelCount; count++) { + result = iceland_populate_smc_voltage_table(hwmgr, + &(data->mvdd_voltage_table.entries[count]), + &table->MvddLevel[count]); + PP_ASSERT_WITH_CODE(result == 0, "do not populate SMC mvdd voltage table", return -EINVAL); + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) + table->MvddLevel[count].Smio |= data->mvdd_voltage_table.entries[count].smio_low; + else + table->MvddLevel[count].Smio |= 0; + } + + CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount); + + return 0; +} + + +static int iceland_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + int result; + + result = iceland_populate_smc_vddc_table(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "can not populate VDDC voltage table to SMC", return -EINVAL); + + result = iceland_populate_smc_vdd_ci_table(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "can not populate VDDCI voltage table to SMC", return -EINVAL); + + result = iceland_populate_smc_mvdd_table(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "can not populate MVDD voltage table to SMC", return -EINVAL); + + return 0; +} + +static int iceland_populate_ulv_level(struct pp_hwmgr *hwmgr, + struct SMU71_Discrete_Ulv *state) +{ + uint32_t voltage_response_time, ulv_voltage; + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + state->CcPwrDynRm = 0; + state->CcPwrDynRm1 = 0; + + result = pp_tables_get_response_times(hwmgr, &voltage_response_time, &ulv_voltage); + PP_ASSERT_WITH_CODE((0 == result), "can not get ULV voltage value", return result;); + + if (ulv_voltage == 0) { + data->ulv_supported = false; + return 0; + } + + if (data->voltage_control != SMU7_VOLTAGE_CONTROL_BY_SVID2) { + /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ + if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) + state->VddcOffset = 0; + else + /* used in SMIO Mode. not implemented for now. this is backup only for CI. */ + state->VddcOffset = (uint16_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage); + } else { + /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */ + if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) + state->VddcOffsetVid = 0; + else /* used in SVI2 Mode */ + state->VddcOffsetVid = (uint8_t)( + (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage) + * VOLTAGE_VID_OFFSET_SCALE2 + / VOLTAGE_VID_OFFSET_SCALE1); + } + state->VddcPhase = 1; + + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); + CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); + + return 0; +} + +static int iceland_populate_ulv_state(struct pp_hwmgr *hwmgr, + SMU71_Discrete_Ulv *ulv_level) +{ + return iceland_populate_ulv_level(hwmgr, ulv_level); +} + +static int iceland_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU71_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + uint32_t i; + + /* Index (dpm_table->pcie_speed_table.count) is reserved for PCIE boot level. */ + for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { + table->LinkLevel[i].PcieGenSpeed = + (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; + table->LinkLevel[i].PcieLaneCount = + (uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1); + table->LinkLevel[i].EnabledForActivity = + 1; + table->LinkLevel[i].SPC = + (uint8_t)(data->pcie_spc_cap & 0xff); + table->LinkLevel[i].DownThreshold = + PP_HOST_TO_SMC_UL(5); + table->LinkLevel[i].UpThreshold = + PP_HOST_TO_SMC_UL(30); + } + + smu_data->smc_state_table.LinkLevelCount = + (uint8_t)dpm_table->pcie_speed_table.count; + data->dpm_level_enable_mask.pcie_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); + + return 0; +} + +static int iceland_calculate_sclk_params(struct pp_hwmgr *hwmgr, + uint32_t engine_clock, SMU71_Discrete_GraphicsLevel *sclk) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + pp_atomctrl_clock_dividers_vi dividers; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + uint32_t reference_clock; + uint32_t reference_divider; + uint32_t fbdiv; + int result; + + /* get the engine clock dividers for this clock value*/ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, engine_clock, ÷rs); + + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", return result); + + /* To get FBDIV we need to multiply this by 16384 and divide it by Fref.*/ + reference_clock = atomctrl_get_reference_clock(hwmgr); + + reference_divider = 1 + dividers.uc_pll_ref_div; + + /* low 14 bits is fraction and high 12 bits is divider*/ + fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; + + /* SPLL_FUNC_CNTL setup*/ + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_REF_DIV, dividers.uc_pll_ref_div); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_PDIV_A, dividers.uc_pll_post_div); + + /* SPLL_FUNC_CNTL_3 setup*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, + CG_SPLL_FUNC_CNTL_3, SPLL_FB_DIV, fbdiv); + + /* set to use fractional accumulation*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, + CG_SPLL_FUNC_CNTL_3, SPLL_DITHEN, 1); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { + pp_atomctrl_internal_ss_info ss_info; + + uint32_t vcoFreq = engine_clock * dividers.uc_pll_post_div; + if (0 == atomctrl_get_engine_clock_spread_spectrum(hwmgr, vcoFreq, &ss_info)) { + /* + * ss_info.speed_spectrum_percentage -- in unit of 0.01% + * ss_info.speed_spectrum_rate -- in unit of khz + */ + /* clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 */ + uint32_t clkS = reference_clock * 5 / (reference_divider * ss_info.speed_spectrum_rate); + + /* clkv = 2 * D * fbdiv / NS */ + uint32_t clkV = 4 * ss_info.speed_spectrum_percentage * fbdiv / (clkS * 10000); + + cg_spll_spread_spectrum = + PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, CLKS, clkS); + cg_spll_spread_spectrum = + PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); + cg_spll_spread_spectrum_2 = + PHM_SET_FIELD(cg_spll_spread_spectrum_2, CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clkV); + } + } + + sclk->SclkFrequency = engine_clock; + sclk->CgSpllFuncCntl3 = spll_func_cntl_3; + sclk->CgSpllFuncCntl4 = spll_func_cntl_4; + sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; + sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; + sclk->SclkDid = (uint8_t)dividers.pll_post_divider; + + return 0; +} + +static int iceland_populate_phase_value_based_on_sclk(struct pp_hwmgr *hwmgr, + const struct phm_phase_shedding_limits_table *pl, + uint32_t sclk, uint32_t *p_shed) +{ + unsigned int i; + + /* use the minimum phase shedding */ + *p_shed = 1; + + for (i = 0; i < pl->count; i++) { + if (sclk < pl->entries[i].Sclk) { + *p_shed = i; + break; + } + } + return 0; +} + +static int iceland_populate_single_graphic_level(struct pp_hwmgr *hwmgr, + uint32_t engine_clock, + uint16_t sclk_activity_level_threshold, + SMU71_Discrete_GraphicsLevel *graphic_level) +{ + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + result = iceland_calculate_sclk_params(hwmgr, engine_clock, graphic_level); + + /* populate graphics levels*/ + result = iceland_get_dependency_volt_by_clk(hwmgr, + hwmgr->dyn_state.vddc_dependency_on_sclk, engine_clock, + &graphic_level->MinVddc); + PP_ASSERT_WITH_CODE((0 == result), + "can not find VDDC voltage value for VDDC \ + engine clock dependency table", return result); + + /* SCLK frequency in units of 10KHz*/ + graphic_level->SclkFrequency = engine_clock; + graphic_level->MinVddcPhases = 1; + + if (data->vddc_phase_shed_control) + iceland_populate_phase_value_based_on_sclk(hwmgr, + hwmgr->dyn_state.vddc_phase_shed_limits_table, + engine_clock, + &graphic_level->MinVddcPhases); + + /* Indicates maximum activity level for this performance level. 50% for now*/ + graphic_level->ActivityLevel = sclk_activity_level_threshold; + + graphic_level->CcPwrDynRm = 0; + graphic_level->CcPwrDynRm1 = 0; + /* this level can be used if activity is high enough.*/ + graphic_level->EnabledForActivity = 0; + /* this level can be used for throttling.*/ + graphic_level->EnabledForThrottle = 1; + graphic_level->UpHyst = 0; + graphic_level->DownHyst = 100; + graphic_level->VoltageDownHyst = 0; + graphic_level->PowerThrottle = 0; + + data->display_timing.min_clock_in_sr = + hwmgr->display_config.min_core_set_clock_in_sr; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkDeepSleep)) + graphic_level->DeepSleepDivId = + smu7_get_sleep_divider_id_from_clock(engine_clock, + data->display_timing.min_clock_in_sr); + + /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ + graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + if (0 == result) { + graphic_level->MinVddc = PP_HOST_TO_SMC_UL(graphic_level->MinVddc * VOLTAGE_SCALE); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(graphic_level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm1); + } + + return result; +} + +static int iceland_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + uint32_t level_array_adress = smu_data->smu7_data.dpm_table_start + + offsetof(SMU71_Discrete_DpmTable, GraphicsLevel); + + uint32_t level_array_size = sizeof(SMU71_Discrete_GraphicsLevel) * + SMU71_MAX_LEVELS_GRAPHICS; + + SMU71_Discrete_GraphicsLevel *levels = smu_data->smc_state_table.GraphicsLevel; + + uint32_t i; + uint8_t highest_pcie_level_enabled = 0; + uint8_t lowest_pcie_level_enabled = 0, mid_pcie_level_enabled = 0; + uint8_t count = 0; + int result = 0; + + memset(levels, 0x00, level_array_size); + + for (i = 0; i < dpm_table->sclk_table.count; i++) { + result = iceland_populate_single_graphic_level(hwmgr, + dpm_table->sclk_table.dpm_levels[i].value, + (uint16_t)smu_data->activity_target[i], + &(smu_data->smc_state_table.GraphicsLevel[i])); + if (result != 0) + return result; + + /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ + if (i > 1) + smu_data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0; + } + + /* Only enable level 0 for now. */ + smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; + + /* set highest level watermark to high */ + if (dpm_table->sclk_table.count > 1) + smu_data->smc_state_table.GraphicsLevel[dpm_table->sclk_table.count-1].DisplayWatermark = + PPSMC_DISPLAY_WATERMARK_HIGH; + + smu_data->smc_state_table.GraphicsDpmLevelCount = + (uint8_t)dpm_table->sclk_table.count; + data->dpm_level_enable_mask.sclk_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); + + while ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << (highest_pcie_level_enabled + 1))) != 0) { + highest_pcie_level_enabled++; + } + + while ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << lowest_pcie_level_enabled)) == 0) { + lowest_pcie_level_enabled++; + } + + while ((count < highest_pcie_level_enabled) && + ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << (lowest_pcie_level_enabled + 1 + count))) == 0)) { + count++; + } + + mid_pcie_level_enabled = (lowest_pcie_level_enabled+1+count) < highest_pcie_level_enabled ? + (lowest_pcie_level_enabled+1+count) : highest_pcie_level_enabled; + + + /* set pcieDpmLevel to highest_pcie_level_enabled*/ + for (i = 2; i < dpm_table->sclk_table.count; i++) { + smu_data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = highest_pcie_level_enabled; + } + + /* set pcieDpmLevel to lowest_pcie_level_enabled*/ + smu_data->smc_state_table.GraphicsLevel[0].pcieDpmLevel = lowest_pcie_level_enabled; + + /* set pcieDpmLevel to mid_pcie_level_enabled*/ + smu_data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled; + + /* level count will send to smc once at init smc table and never change*/ + result = smu7_copy_bytes_to_smc(hwmgr, level_array_adress, + (uint8_t *)levels, (uint32_t)level_array_size, + SMC_RAM_END); + + return result; +} + +static int iceland_calculate_mclk_params( + struct pp_hwmgr *hwmgr, + uint32_t memory_clock, + SMU71_Discrete_MemoryLevel *mclk, + bool strobe_mode, + bool dllStateOn + ) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; + uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; + uint32_t mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL; + uint32_t mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL; + uint32_t mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL; + uint32_t mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1; + uint32_t mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2; + uint32_t mpll_ss1 = data->clock_registers.vMPLL_SS1; + uint32_t mpll_ss2 = data->clock_registers.vMPLL_SS2; + + pp_atomctrl_memory_clock_param mpll_param; + int result; + + result = atomctrl_get_memory_pll_dividers_si(hwmgr, + memory_clock, &mpll_param, strobe_mode); + PP_ASSERT_WITH_CODE(0 == result, + "Error retrieving Memory Clock Parameters from VBIOS.", return result); + + /* MPLL_FUNC_CNTL setup*/ + mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl); + + /* MPLL_FUNC_CNTL_1 setup*/ + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, CLKF, mpll_param.mpll_fb_divider.cl_kf); + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, CLKFRAC, mpll_param.mpll_fb_divider.clk_frac); + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, VCO_MODE, mpll_param.vco_mode); + + /* MPLL_AD_FUNC_CNTL setup*/ + mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl, + MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); + + if (data->is_memory_gddr5) { + /* MPLL_DQ_FUNC_CNTL setup*/ + mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, + MPLL_DQ_FUNC_CNTL, YCLK_SEL, mpll_param.yclk_sel); + mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, + MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider); + } + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MemorySpreadSpectrumSupport)) { + /* + ************************************ + Fref = Reference Frequency + NF = Feedback divider ratio + NR = Reference divider ratio + Fnom = Nominal VCO output frequency = Fref * NF / NR + Fs = Spreading Rate + D = Percentage down-spread / 2 + Fint = Reference input frequency to PFD = Fref / NR + NS = Spreading rate divider ratio = int(Fint / (2 * Fs)) + CLKS = NS - 1 = ISS_STEP_NUM[11:0] + NV = D * Fs / Fnom * 4 * ((Fnom/Fref * NR) ^ 2) + CLKV = 65536 * NV = ISS_STEP_SIZE[25:0] + ************************************* + */ + pp_atomctrl_internal_ss_info ss_info; + uint32_t freq_nom; + uint32_t tmp; + uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr); + + /* for GDDR5 for all modes and DDR3 */ + if (1 == mpll_param.qdr) + freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider); + else + freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider); + + /* tmp = (freq_nom / reference_clock * reference_divider) ^ 2 Note: S.I. reference_divider = 1*/ + tmp = (freq_nom / reference_clock); + tmp = tmp * tmp; + + if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) { + /* ss_info.speed_spectrum_percentage -- in unit of 0.01% */ + /* ss.Info.speed_spectrum_rate -- in unit of khz */ + /* CLKS = reference_clock / (2 * speed_spectrum_rate * reference_divider) * 10 */ + /* = reference_clock * 5 / speed_spectrum_rate */ + uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate; + + /* CLKV = 65536 * speed_spectrum_percentage / 2 * spreadSpecrumRate / freq_nom * 4 / 100000 * ((freq_nom / reference_clock) ^ 2) */ + /* = 131 * speed_spectrum_percentage * speed_spectrum_rate / 100 * ((freq_nom / reference_clock) ^ 2) / freq_nom */ + uint32_t clkv = + (uint32_t)((((131 * ss_info.speed_spectrum_percentage * + ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom); + + mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv); + mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks); + } + } + + /* MCLK_PWRMGT_CNTL setup */ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn); + + + /* Save the result data to outpupt memory level structure */ + mclk->MclkFrequency = memory_clock; + mclk->MpllFuncCntl = mpll_func_cntl; + mclk->MpllFuncCntl_1 = mpll_func_cntl_1; + mclk->MpllFuncCntl_2 = mpll_func_cntl_2; + mclk->MpllAdFuncCntl = mpll_ad_func_cntl; + mclk->MpllDqFuncCntl = mpll_dq_func_cntl; + mclk->MclkPwrmgtCntl = mclk_pwrmgt_cntl; + mclk->DllCntl = dll_cntl; + mclk->MpllSs1 = mpll_ss1; + mclk->MpllSs2 = mpll_ss2; + + return 0; +} + +static uint8_t iceland_get_mclk_frequency_ratio(uint32_t memory_clock, + bool strobe_mode) +{ + uint8_t mc_para_index; + + if (strobe_mode) { + if (memory_clock < 12500) { + mc_para_index = 0x00; + } else if (memory_clock > 47500) { + mc_para_index = 0x0f; + } else { + mc_para_index = (uint8_t)((memory_clock - 10000) / 2500); + } + } else { + if (memory_clock < 65000) { + mc_para_index = 0x00; + } else if (memory_clock > 135000) { + mc_para_index = 0x0f; + } else { + mc_para_index = (uint8_t)((memory_clock - 60000) / 5000); + } + } + + return mc_para_index; +} + +static uint8_t iceland_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock) +{ + uint8_t mc_para_index; + + if (memory_clock < 10000) { + mc_para_index = 0; + } else if (memory_clock >= 80000) { + mc_para_index = 0x0f; + } else { + mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1); + } + + return mc_para_index; +} + +static int iceland_populate_phase_value_based_on_mclk(struct pp_hwmgr *hwmgr, const struct phm_phase_shedding_limits_table *pl, + uint32_t memory_clock, uint32_t *p_shed) +{ + unsigned int i; + + *p_shed = 1; + + for (i = 0; i < pl->count; i++) { + if (memory_clock < pl->entries[i].Mclk) { + *p_shed = i; + break; + } + } + + return 0; +} + +static int iceland_populate_single_memory_level( + struct pp_hwmgr *hwmgr, + uint32_t memory_clock, + SMU71_Discrete_MemoryLevel *memory_level + ) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int result = 0; + bool dll_state_on; + struct cgs_display_info info = {0}; + uint32_t mclk_edc_wr_enable_threshold = 40000; + uint32_t mclk_edc_enable_threshold = 40000; + uint32_t mclk_strobe_mode_threshold = 40000; + + if (hwmgr->dyn_state.vddc_dependency_on_mclk != NULL) { + result = iceland_get_dependency_volt_by_clk(hwmgr, + hwmgr->dyn_state.vddc_dependency_on_mclk, memory_clock, &memory_level->MinVddc); + PP_ASSERT_WITH_CODE((0 == result), + "can not find MinVddc voltage value from memory VDDC voltage dependency table", return result); + } + + if (data->vddci_control == SMU7_VOLTAGE_CONTROL_NONE) { + memory_level->MinVddci = memory_level->MinVddc; + } else if (NULL != hwmgr->dyn_state.vddci_dependency_on_mclk) { + result = iceland_get_dependency_volt_by_clk(hwmgr, + hwmgr->dyn_state.vddci_dependency_on_mclk, + memory_clock, + &memory_level->MinVddci); + PP_ASSERT_WITH_CODE((0 == result), + "can not find MinVddci voltage value from memory VDDCI voltage dependency table", return result); + } + + memory_level->MinVddcPhases = 1; + + if (data->vddc_phase_shed_control) { + iceland_populate_phase_value_based_on_mclk(hwmgr, hwmgr->dyn_state.vddc_phase_shed_limits_table, + memory_clock, &memory_level->MinVddcPhases); + } + + memory_level->EnabledForThrottle = 1; + memory_level->EnabledForActivity = 0; + memory_level->UpHyst = 0; + memory_level->DownHyst = 100; + memory_level->VoltageDownHyst = 0; + + /* Indicates maximum activity level for this performance level.*/ + memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target; + memory_level->StutterEnable = 0; + memory_level->StrobeEnable = 0; + memory_level->EdcReadEnable = 0; + memory_level->EdcWriteEnable = 0; + memory_level->RttEnable = 0; + + /* default set to low watermark. Highest level will be set to high later.*/ + memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + cgs_get_active_displays_info(hwmgr->device, &info); + data->display_timing.num_existing_displays = info.display_count; + + /* stutter mode not support on iceland */ + + /* decide strobe mode*/ + memory_level->StrobeEnable = (mclk_strobe_mode_threshold != 0) && + (memory_clock <= mclk_strobe_mode_threshold); + + /* decide EDC mode and memory clock ratio*/ + if (data->is_memory_gddr5) { + memory_level->StrobeRatio = iceland_get_mclk_frequency_ratio(memory_clock, + memory_level->StrobeEnable); + + if ((mclk_edc_enable_threshold != 0) && + (memory_clock > mclk_edc_enable_threshold)) { + memory_level->EdcReadEnable = 1; + } + + if ((mclk_edc_wr_enable_threshold != 0) && + (memory_clock > mclk_edc_wr_enable_threshold)) { + memory_level->EdcWriteEnable = 1; + } + + if (memory_level->StrobeEnable) { + if (iceland_get_mclk_frequency_ratio(memory_clock, 1) >= + ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; + else + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0; + } else + dll_state_on = data->dll_default_on; + } else { + memory_level->StrobeRatio = + iceland_get_ddr3_mclk_frequency_ratio(memory_clock); + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; + } + + result = iceland_calculate_mclk_params(hwmgr, + memory_clock, memory_level, memory_level->StrobeEnable, dll_state_on); + + if (0 == result) { + memory_level->MinVddc = PP_HOST_TO_SMC_UL(memory_level->MinVddc * VOLTAGE_SCALE); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinVddcPhases); + memory_level->MinVddci = PP_HOST_TO_SMC_UL(memory_level->MinVddci * VOLTAGE_SCALE); + memory_level->MinMvdd = PP_HOST_TO_SMC_UL(memory_level->MinMvdd * VOLTAGE_SCALE); + /* MCLK frequency in units of 10KHz*/ + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency); + /* Indicates maximum activity level for this performance level.*/ + CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2); + } + + return result; +} + +static int iceland_populate_all_memory_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + int result; + + /* populate MCLK dpm table to SMU7 */ + uint32_t level_array_adress = smu_data->smu7_data.dpm_table_start + offsetof(SMU71_Discrete_DpmTable, MemoryLevel); + uint32_t level_array_size = sizeof(SMU71_Discrete_MemoryLevel) * SMU71_MAX_LEVELS_MEMORY; + SMU71_Discrete_MemoryLevel *levels = smu_data->smc_state_table.MemoryLevel; + uint32_t i; + + memset(levels, 0x00, level_array_size); + + for (i = 0; i < dpm_table->mclk_table.count; i++) { + PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), + "can not populate memory level as memory clock is zero", return -EINVAL); + result = iceland_populate_single_memory_level(hwmgr, dpm_table->mclk_table.dpm_levels[i].value, + &(smu_data->smc_state_table.MemoryLevel[i])); + if (0 != result) { + return result; + } + } + + /* Only enable level 0 for now.*/ + smu_data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1; + + /* + * in order to prevent MC activity from stutter mode to push DPM up. + * the UVD change complements this by putting the MCLK in a higher state + * by default such that we are not effected by up threshold or and MCLK DPM latency. + */ + smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F; + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel); + + smu_data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count; + data->dpm_level_enable_mask.mclk_dpm_enable_mask = phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); + /* set highest level watermark to high*/ + smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; + + /* level count will send to smc once at init smc table and never change*/ + result = smu7_copy_bytes_to_smc(hwmgr, + level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, + SMC_RAM_END); + + return result; +} + +static int iceland_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, + SMU71_Discrete_VoltageLevel *voltage) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + uint32_t i = 0; + + if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { + /* find mvdd value which clock is more than request */ + for (i = 0; i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count; i++) { + if (mclk <= hwmgr->dyn_state.mvdd_dependency_on_mclk->entries[i].clk) { + /* Always round to higher voltage. */ + voltage->Voltage = data->mvdd_voltage_table.entries[i].value; + break; + } + } + + PP_ASSERT_WITH_CODE(i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count, + "MVDD Voltage is outside the supported range.", return -EINVAL); + + } else { + return -EINVAL; + } + + return 0; +} + +static int iceland_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + int result = 0; + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct pp_atomctrl_clock_dividers_vi dividers; + uint32_t vddc_phase_shed_control = 0; + + SMU71_Discrete_VoltageLevel voltage_level; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; + uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; + uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; + + + /* The ACPI state should not do DPM on DC (or ever).*/ + table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; + + if (data->acpi_vddc) + table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->acpi_vddc * VOLTAGE_SCALE); + else + table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->min_vddc_in_pptable * VOLTAGE_SCALE); + + table->ACPILevel.MinVddcPhases = vddc_phase_shed_control ? 0 : 1; + /* assign zero for now*/ + table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr); + + /* get the engine clock dividers for this clock value*/ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, + table->ACPILevel.SclkFrequency, ÷rs); + + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", return result); + + /* divider ID for required SCLK*/ + table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; + table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + table->ACPILevel.DeepSleepDivId = 0; + + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_PWRON, 0); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_RESET, 1); + spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, + CG_SPLL_FUNC_CNTL_2, SCLK_MUX_SEL, 4); + + table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; + table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; + table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + table->ACPILevel.CcPwrDynRm = 0; + table->ACPILevel.CcPwrDynRm1 = 0; + + + /* For various features to be enabled/disabled while this level is active.*/ + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); + /* SCLK frequency in units of 10KHz*/ + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); + + /* table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;*/ + table->MemoryACPILevel.MinVddc = table->ACPILevel.MinVddc; + table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases; + + if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) + table->MemoryACPILevel.MinVddci = table->MemoryACPILevel.MinVddc; + else { + if (data->acpi_vddci != 0) + table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->acpi_vddci * VOLTAGE_SCALE); + else + table->MemoryACPILevel.MinVddci = PP_HOST_TO_SMC_UL(data->min_vddci_in_pptable * VOLTAGE_SCALE); + } + + if (0 == iceland_populate_mvdd_value(hwmgr, 0, &voltage_level)) + table->MemoryACPILevel.MinMvdd = + PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE); + else + table->MemoryACPILevel.MinMvdd = 0; + + /* Force reset on DLL*/ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1); + + /* Disable DLL in ACPIState*/ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0); + + /* Enable DLL bypass signal*/ + dll_cntl = PHM_SET_FIELD(dll_cntl, + DLL_CNTL, MRDCK0_BYPASS, 0); + dll_cntl = PHM_SET_FIELD(dll_cntl, + DLL_CNTL, MRDCK1_BYPASS, 0); + + table->MemoryACPILevel.DllCntl = + PP_HOST_TO_SMC_UL(dll_cntl); + table->MemoryACPILevel.MclkPwrmgtCntl = + PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl); + table->MemoryACPILevel.MpllAdFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL); + table->MemoryACPILevel.MpllDqFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL); + table->MemoryACPILevel.MpllFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL); + table->MemoryACPILevel.MpllFuncCntl_1 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1); + table->MemoryACPILevel.MpllFuncCntl_2 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2); + table->MemoryACPILevel.MpllSs1 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1); + table->MemoryACPILevel.MpllSs2 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2); + + table->MemoryACPILevel.EnabledForThrottle = 0; + table->MemoryACPILevel.EnabledForActivity = 0; + table->MemoryACPILevel.UpHyst = 0; + table->MemoryACPILevel.DownHyst = 100; + table->MemoryACPILevel.VoltageDownHyst = 0; + /* Indicates maximum activity level for this performance level.*/ + table->MemoryACPILevel.ActivityLevel = PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); + + table->MemoryACPILevel.StutterEnable = 0; + table->MemoryACPILevel.StrobeEnable = 0; + table->MemoryACPILevel.EdcReadEnable = 0; + table->MemoryACPILevel.EdcWriteEnable = 0; + table->MemoryACPILevel.RttEnable = 0; + + return result; +} + +static int iceland_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + return 0; +} + +static int iceland_populate_smc_vce_level(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + return 0; +} + +static int iceland_populate_smc_acp_level(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + return 0; +} + +static int iceland_populate_smc_samu_level(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + return 0; +} + +static int iceland_populate_memory_timing_parameters( + struct pp_hwmgr *hwmgr, + uint32_t engine_clock, + uint32_t memory_clock, + struct SMU71_Discrete_MCArbDramTimingTableEntry *arb_regs + ) +{ + uint32_t dramTiming; + uint32_t dramTiming2; + uint32_t burstTime; + int result; + + result = atomctrl_set_engine_dram_timings_rv770(hwmgr, + engine_clock, memory_clock); + + PP_ASSERT_WITH_CODE(result == 0, + "Error calling VBIOS to set DRAM_TIMING.", return result); + + dramTiming = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); + dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); + burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); + + arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dramTiming); + arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2); + arb_regs->McArbBurstTime = (uint8_t)burstTime; + + return 0; +} + +static int iceland_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + int result = 0; + SMU71_Discrete_MCArbDramTimingTable arb_regs; + uint32_t i, j; + + memset(&arb_regs, 0x00, sizeof(SMU71_Discrete_MCArbDramTimingTable)); + + for (i = 0; i < data->dpm_table.sclk_table.count; i++) { + for (j = 0; j < data->dpm_table.mclk_table.count; j++) { + result = iceland_populate_memory_timing_parameters + (hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value, + data->dpm_table.mclk_table.dpm_levels[j].value, + &arb_regs.entries[i][j]); + + if (0 != result) { + break; + } + } + } + + if (0 == result) { + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.arb_table_start, + (uint8_t *)&arb_regs, + sizeof(SMU71_Discrete_MCArbDramTimingTable), + SMC_RAM_END + ); + } + + return result; +} + +static int iceland_populate_smc_boot_level(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *table) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + table->GraphicsBootLevel = 0; + table->MemoryBootLevel = 0; + + /* find boot level from dpm table*/ + result = phm_find_boot_level(&(data->dpm_table.sclk_table), + data->vbios_boot_state.sclk_bootup_value, + (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); + + if (0 != result) { + smu_data->smc_state_table.GraphicsBootLevel = 0; + pr_err("VBIOS did not find boot engine clock value \ + in dependency table. Using Graphics DPM level 0!"); + result = 0; + } + + result = phm_find_boot_level(&(data->dpm_table.mclk_table), + data->vbios_boot_state.mclk_bootup_value, + (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); + + if (0 != result) { + smu_data->smc_state_table.MemoryBootLevel = 0; + pr_err("VBIOS did not find boot engine clock value \ + in dependency table. Using Memory DPM level 0!"); + result = 0; + } + + table->BootVddc = data->vbios_boot_state.vddc_bootup_value; + if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) + table->BootVddci = table->BootVddc; + else + table->BootVddci = data->vbios_boot_state.vddci_bootup_value; + + table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value; + + return result; +} + +static int iceland_populate_mc_reg_address(struct pp_hwmgr *hwmgr, + SMU71_Discrete_MCRegisters *mc_reg_table) +{ + const struct iceland_smumgr *smu_data = (struct iceland_smumgr *)hwmgr->smu_backend; + + uint32_t i, j; + + for (i = 0, j = 0; j < smu_data->mc_reg_table.last; j++) { + if (smu_data->mc_reg_table.validflag & 1<address[] array out of boundary", return -EINVAL); + mc_reg_table->address[i].s0 = + PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s0); + mc_reg_table->address[i].s1 = + PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s1); + i++; + } + } + + mc_reg_table->last = (uint8_t)i; + + return 0; +} + +/*convert register values from driver to SMC format */ +static void iceland_convert_mc_registers( + const struct iceland_mc_reg_entry *entry, + SMU71_Discrete_MCRegisterSet *data, + uint32_t num_entries, uint32_t valid_flag) +{ + uint32_t i, j; + + for (i = 0, j = 0; j < num_entries; j++) { + if (valid_flag & 1<value[i] = PP_HOST_TO_SMC_UL(entry->mc_data[j]); + i++; + } + } +} + +static int iceland_convert_mc_reg_table_entry_to_smc(struct pp_hwmgr *hwmgr, + const uint32_t memory_clock, + SMU71_Discrete_MCRegisterSet *mc_reg_table_data + ) +{ + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + uint32_t i = 0; + + for (i = 0; i < smu_data->mc_reg_table.num_entries; i++) { + if (memory_clock <= + smu_data->mc_reg_table.mc_reg_table_entry[i].mclk_max) { + break; + } + } + + if ((i == smu_data->mc_reg_table.num_entries) && (i > 0)) + --i; + + iceland_convert_mc_registers(&smu_data->mc_reg_table.mc_reg_table_entry[i], + mc_reg_table_data, smu_data->mc_reg_table.last, + smu_data->mc_reg_table.validflag); + + return 0; +} + +static int iceland_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr, + SMU71_Discrete_MCRegisters *mc_regs) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int res; + uint32_t i; + + for (i = 0; i < data->dpm_table.mclk_table.count; i++) { + res = iceland_convert_mc_reg_table_entry_to_smc( + hwmgr, + data->dpm_table.mclk_table.dpm_levels[i].value, + &mc_regs->data[i] + ); + + if (0 != res) + result = res; + } + + return result; +} + +static int iceland_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t address; + int32_t result; + + if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) + return 0; + + + memset(&smu_data->mc_regs, 0, sizeof(SMU71_Discrete_MCRegisters)); + + result = iceland_convert_mc_reg_table_to_smc(hwmgr, &(smu_data->mc_regs)); + + if (result != 0) + return result; + + + address = smu_data->smu7_data.mc_reg_table_start + (uint32_t)offsetof(SMU71_Discrete_MCRegisters, data[0]); + + return smu7_copy_bytes_to_smc(hwmgr, address, + (uint8_t *)&smu_data->mc_regs.data[0], + sizeof(SMU71_Discrete_MCRegisterSet) * data->dpm_table.mclk_table.count, + SMC_RAM_END); +} + +static int iceland_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + + memset(&smu_data->mc_regs, 0x00, sizeof(SMU71_Discrete_MCRegisters)); + result = iceland_populate_mc_reg_address(hwmgr, &(smu_data->mc_regs)); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize MCRegTable for the MC register addresses!", return result;); + + result = iceland_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize MCRegTable for driver state!", return result;); + + return smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.mc_reg_table_start, + (uint8_t *)&smu_data->mc_regs, sizeof(SMU71_Discrete_MCRegisters), SMC_RAM_END); +} + +static int iceland_populate_smc_initial_state(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + uint8_t count, level; + + count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->count); + + for (level = 0; level < count; level++) { + if (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[level].clk + >= data->vbios_boot_state.sclk_bootup_value) { + smu_data->smc_state_table.GraphicsBootLevel = level; + break; + } + } + + count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_mclk->count); + + for (level = 0; level < count; level++) { + if (hwmgr->dyn_state.vddc_dependency_on_mclk->entries[level].clk + >= data->vbios_boot_state.mclk_bootup_value) { + smu_data->smc_state_table.MemoryBootLevel = level; + break; + } + } + + return 0; +} + +static int iceland_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + const struct iceland_pt_defaults *defaults = smu_data->power_tune_defaults; + SMU71_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); + struct phm_cac_tdp_table *cac_dtp_table = hwmgr->dyn_state.cac_dtp_table; + struct phm_ppm_table *ppm = hwmgr->dyn_state.ppm_parameter_table; + const uint16_t *def1, *def2; + int i, j, k; + + + /* + * TDP number of fraction bits are changed from 8 to 7 for Iceland + * as requested by SMC team + */ + + dpm_table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 256)); + dpm_table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); + + + dpm_table->DTETjOffset = 0; + + dpm_table->GpuTjMax = (uint8_t)(data->thermal_temp_setting.temperature_high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES); + dpm_table->GpuTjHyst = 8; + + dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; + + /* The following are for new Iceland Multi-input fan/thermal control */ + if (NULL != ppm) { + dpm_table->PPM_PkgPwrLimit = (uint16_t)ppm->dgpu_tdp * 256 / 1000; + dpm_table->PPM_TemperatureLimit = (uint16_t)ppm->tj_max * 256; + } else { + dpm_table->PPM_PkgPwrLimit = 0; + dpm_table->PPM_TemperatureLimit = 0; + } + + CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_PkgPwrLimit); + CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_TemperatureLimit); + + dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bapm_temp_gradient); + def1 = defaults->bapmti_r; + def2 = defaults->bapmti_rc; + + for (i = 0; i < SMU71_DTE_ITERATIONS; i++) { + for (j = 0; j < SMU71_DTE_SOURCES; j++) { + for (k = 0; k < SMU71_DTE_SINKS; k++) { + dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*def1); + dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*def2); + def1++; + def2++; + } + } + } + + return 0; +} + +static int iceland_populate_smc_svi2_config(struct pp_hwmgr *hwmgr, + SMU71_Discrete_DpmTable *tab) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) + tab->SVI2Enable |= VDDC_ON_SVI2; + + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) + tab->SVI2Enable |= VDDCI_ON_SVI2; + else + tab->MergedVddci = 1; + + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) + tab->SVI2Enable |= MVDD_ON_SVI2; + + PP_ASSERT_WITH_CODE(tab->SVI2Enable != (VDDC_ON_SVI2 | VDDCI_ON_SVI2 | MVDD_ON_SVI2) && + (tab->SVI2Enable & VDDC_ON_SVI2), "SVI2 domain configuration is incorrect!", return -EINVAL); + + return 0; +} + +static int iceland_init_smc_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + SMU71_Discrete_DpmTable *table = &(smu_data->smc_state_table); + + + iceland_initialize_power_tune_defaults(hwmgr); + memset(&(smu_data->smc_state_table), 0x00, sizeof(smu_data->smc_state_table)); + + if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) { + iceland_populate_smc_voltage_tables(hwmgr, table); + } + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; + + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StepVddc)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; + + if (data->is_memory_gddr5) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; + + + if (data->ulv_supported) { + result = iceland_populate_ulv_state(hwmgr, &(smu_data->ulv_setting)); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ULV state!", return result;); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixCG_ULV_PARAMETER, 0x40035); + } + + result = iceland_populate_smc_link_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Link Level!", return result;); + + result = iceland_populate_all_graphic_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Graphics Level!", return result;); + + result = iceland_populate_all_memory_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Memory Level!", return result;); + + result = iceland_populate_smc_acpi_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ACPI Level!", return result;); + + result = iceland_populate_smc_vce_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize VCE Level!", return result;); + + result = iceland_populate_smc_acp_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ACP Level!", return result;); + + result = iceland_populate_smc_samu_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize SAMU Level!", return result;); + + /* Since only the initial state is completely set up at this point (the other states are just copies of the boot state) we only */ + /* need to populate the ARB settings for the initial state. */ + result = iceland_program_memory_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to Write ARB settings for the initial state.", return result;); + + result = iceland_populate_smc_uvd_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize UVD Level!", return result;); + + table->GraphicsBootLevel = 0; + table->MemoryBootLevel = 0; + + result = iceland_populate_smc_boot_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Boot Level!", return result;); + + result = iceland_populate_smc_initial_state(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, "Failed to initialize Boot State!", return result); + + result = iceland_populate_bapm_parameters_in_dpm_table(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, "Failed to populate BAPM Parameters!", return result); + + table->GraphicsVoltageChangeEnable = 1; + table->GraphicsThermThrottleEnable = 1; + table->GraphicsInterval = 1; + table->VoltageInterval = 1; + table->ThermalInterval = 1; + + table->TemperatureLimitHigh = + (data->thermal_temp_setting.temperature_high * + SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + table->TemperatureLimitLow = + (data->thermal_temp_setting.temperature_low * + SMU7_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + + table->MemoryVoltageChangeEnable = 1; + table->MemoryInterval = 1; + table->VoltageResponseTime = 0; + table->PhaseResponseTime = 0; + table->MemoryThermThrottleEnable = 1; + table->PCIeBootLinkLevel = 0; + table->PCIeGenInterval = 1; + + result = iceland_populate_smc_svi2_config(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate SVI2 setting!", return result); + + table->ThermGpio = 17; + table->SclkStepSize = 0x4000; + + CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcVid); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcPhase); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddciVid); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskMvddVid); + CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); + CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); + CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); + + table->BootVddc = PP_HOST_TO_SMC_US(table->BootVddc * VOLTAGE_SCALE); + table->BootVddci = PP_HOST_TO_SMC_US(table->BootVddci * VOLTAGE_SCALE); + table->BootMVdd = PP_HOST_TO_SMC_US(table->BootMVdd * VOLTAGE_SCALE); + + /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ + result = smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.dpm_table_start + + offsetof(SMU71_Discrete_DpmTable, SystemFlags), + (uint8_t *)&(table->SystemFlags), + sizeof(SMU71_Discrete_DpmTable)-3 * sizeof(SMU71_PIDController), + SMC_RAM_END); + + PP_ASSERT_WITH_CODE(0 == result, + "Failed to upload dpm data to SMC memory!", return result;); + + /* Upload all ulv setting to SMC memory.(dpm level, dpm level count etc) */ + result = smu7_copy_bytes_to_smc(hwmgr, + smu_data->smu7_data.ulv_setting_starts, + (uint8_t *)&(smu_data->ulv_setting), + sizeof(SMU71_Discrete_Ulv), + SMC_RAM_END); + + + result = iceland_populate_initial_mc_reg_table(hwmgr); + PP_ASSERT_WITH_CODE((0 == result), + "Failed to populate initialize MC Reg table!", return result); + + result = iceland_populate_pm_fuses(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate PM fuses to SMC memory!", return result); + + return 0; +} + +int iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) +{ + struct smu7_smumgr *smu7_data = (struct smu7_smumgr *)(hwmgr->smu_backend); + SMU71_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; + uint32_t duty100; + uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; + uint16_t fdo_min, slope1, slope2; + uint32_t reference_clock; + int res; + uint64_t tmp64; + + if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) + return 0; + + if (hwmgr->thermal_controller.fanInfo.bNoFan) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + if (0 == smu7_data->fan_table_start) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100); + + if (0 == duty100) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100; + do_div(tmp64, 10000); + fdo_min = (uint16_t)tmp64; + + t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - hwmgr->thermal_controller.advanceFanControlParameters.usTMin; + t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - hwmgr->thermal_controller.advanceFanControlParameters.usTMed; + + pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; + pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; + + slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); + slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + + fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100); + fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100); + fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100); + + fan_table.Slope1 = cpu_to_be16(slope1); + fan_table.Slope2 = cpu_to_be16(slope2); + + fan_table.FdoMin = cpu_to_be16(fdo_min); + + fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst); + + fan_table.HystUp = cpu_to_be16(1); + + fan_table.HystSlope = cpu_to_be16(1); + + fan_table.TempRespLim = cpu_to_be16(5); + + reference_clock = smu7_get_xclk(hwmgr); + + fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600); + + fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); + + fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL); + + /* fan_table.FanControl_GL_Flag = 1; */ + + res = smu7_copy_bytes_to_smc(hwmgr, smu7_data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), SMC_RAM_END); + + return 0; +} + + +static int iceland_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (data->need_update_smu7_dpm_table & + (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) + return iceland_program_memory_timing_parameters(hwmgr); + + return 0; +} + +static int iceland_update_sclk_threshold(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct iceland_smumgr *smu_data = (struct iceland_smumgr *)(hwmgr->smu_backend); + + int result = 0; + uint32_t low_sclk_interrupt_threshold = 0; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkThrottleLowNotification) + && (hwmgr->gfx_arbiter.sclk_threshold != + data->low_sclk_interrupt_threshold)) { + data->low_sclk_interrupt_threshold = + hwmgr->gfx_arbiter.sclk_threshold; + low_sclk_interrupt_threshold = + data->low_sclk_interrupt_threshold; + + CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); + + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.dpm_table_start + + offsetof(SMU71_Discrete_DpmTable, + LowSclkInterruptThreshold), + (uint8_t *)&low_sclk_interrupt_threshold, + sizeof(uint32_t), + SMC_RAM_END); + } + + result = iceland_update_and_upload_mc_reg_table(hwmgr); + + PP_ASSERT_WITH_CODE((0 == result), "Failed to upload MC reg table!", return result); + + result = iceland_program_mem_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE((result == 0), + "Failed to program memory timing parameters!", + ); + + return result; +} + +static uint32_t iceland_get_offsetof(uint32_t type, uint32_t member) +{ + switch (type) { + case SMU_SoftRegisters: + switch (member) { + case HandshakeDisables: + return offsetof(SMU71_SoftRegisters, HandshakeDisables); + case VoltageChangeTimeout: + return offsetof(SMU71_SoftRegisters, VoltageChangeTimeout); + case AverageGraphicsActivity: + return offsetof(SMU71_SoftRegisters, AverageGraphicsActivity); + case PreVBlankGap: + return offsetof(SMU71_SoftRegisters, PreVBlankGap); + case VBlankTimeout: + return offsetof(SMU71_SoftRegisters, VBlankTimeout); + case UcodeLoadStatus: + return offsetof(SMU71_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU71_SoftRegisters, DRAM_LOG_BUFF_SIZE); + } + case SMU_Discrete_DpmTable: + switch (member) { + case LowSclkInterruptThreshold: + return offsetof(SMU71_Discrete_DpmTable, LowSclkInterruptThreshold); + } + } + pr_warn("can't get the offset of type %x member %x\n", type, member); + return 0; +} + +static uint32_t iceland_get_mac_definition(uint32_t value) +{ + switch (value) { + case SMU_MAX_LEVELS_GRAPHICS: + return SMU71_MAX_LEVELS_GRAPHICS; + case SMU_MAX_LEVELS_MEMORY: + return SMU71_MAX_LEVELS_MEMORY; + case SMU_MAX_LEVELS_LINK: + return SMU71_MAX_LEVELS_LINK; + case SMU_MAX_ENTRIES_SMIO: + return SMU71_MAX_ENTRIES_SMIO; + case SMU_MAX_LEVELS_VDDC: + return SMU71_MAX_LEVELS_VDDC; + case SMU_MAX_LEVELS_VDDCI: + return SMU71_MAX_LEVELS_VDDCI; + case SMU_MAX_LEVELS_MVDD: + return SMU71_MAX_LEVELS_MVDD; + } + + pr_warn("can't get the mac of %x\n", value); + return 0; +} + +static int iceland_process_firmware_header(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct smu7_smumgr *smu7_data = (struct smu7_smumgr *)(hwmgr->smu_backend); + + uint32_t tmp; + int result; + bool error = false; + + result = smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, DpmTable), + &tmp, SMC_RAM_END); + + if (0 == result) { + smu7_data->dpm_table_start = tmp; + } + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, SoftRegisters), + &tmp, SMC_RAM_END); + + if (0 == result) { + data->soft_regs_start = tmp; + smu7_data->soft_regs_start = tmp; + } + + error |= (0 != result); + + + result = smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, mcRegisterTable), + &tmp, SMC_RAM_END); + + if (0 == result) { + smu7_data->mc_reg_table_start = tmp; + } + + result = smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, FanTable), + &tmp, SMC_RAM_END); + + if (0 == result) { + smu7_data->fan_table_start = tmp; + } + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, mcArbDramTimingTable), + &tmp, SMC_RAM_END); + + if (0 == result) { + smu7_data->arb_table_start = tmp; + } + + error |= (0 != result); + + + result = smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, Version), + &tmp, SMC_RAM_END); + + if (0 == result) { + hwmgr->microcode_version_info.SMC = tmp; + } + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU71_FIRMWARE_HEADER_LOCATION + + offsetof(SMU71_Firmware_Header, UlvSettings), + &tmp, SMC_RAM_END); + + if (0 == result) { + smu7_data->ulv_setting_starts = tmp; + } + + error |= (0 != result); + + return error ? 1 : 0; +} + +/*---------------------------MC----------------------------*/ + +static uint8_t iceland_get_memory_modile_index(struct pp_hwmgr *hwmgr) +{ + return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16)); +} + +static bool iceland_check_s0_mc_reg_index(uint16_t in_reg, uint16_t *out_reg) +{ + bool result = true; + + switch (in_reg) { + case mmMC_SEQ_RAS_TIMING: + *out_reg = mmMC_SEQ_RAS_TIMING_LP; + break; + + case mmMC_SEQ_DLL_STBY: + *out_reg = mmMC_SEQ_DLL_STBY_LP; + break; + + case mmMC_SEQ_G5PDX_CMD0: + *out_reg = mmMC_SEQ_G5PDX_CMD0_LP; + break; + + case mmMC_SEQ_G5PDX_CMD1: + *out_reg = mmMC_SEQ_G5PDX_CMD1_LP; + break; + + case mmMC_SEQ_G5PDX_CTRL: + *out_reg = mmMC_SEQ_G5PDX_CTRL_LP; + break; + + case mmMC_SEQ_CAS_TIMING: + *out_reg = mmMC_SEQ_CAS_TIMING_LP; + break; + + case mmMC_SEQ_MISC_TIMING: + *out_reg = mmMC_SEQ_MISC_TIMING_LP; + break; + + case mmMC_SEQ_MISC_TIMING2: + *out_reg = mmMC_SEQ_MISC_TIMING2_LP; + break; + + case mmMC_SEQ_PMG_DVS_CMD: + *out_reg = mmMC_SEQ_PMG_DVS_CMD_LP; + break; + + case mmMC_SEQ_PMG_DVS_CTL: + *out_reg = mmMC_SEQ_PMG_DVS_CTL_LP; + break; + + case mmMC_SEQ_RD_CTL_D0: + *out_reg = mmMC_SEQ_RD_CTL_D0_LP; + break; + + case mmMC_SEQ_RD_CTL_D1: + *out_reg = mmMC_SEQ_RD_CTL_D1_LP; + break; + + case mmMC_SEQ_WR_CTL_D0: + *out_reg = mmMC_SEQ_WR_CTL_D0_LP; + break; + + case mmMC_SEQ_WR_CTL_D1: + *out_reg = mmMC_SEQ_WR_CTL_D1_LP; + break; + + case mmMC_PMG_CMD_EMRS: + *out_reg = mmMC_SEQ_PMG_CMD_EMRS_LP; + break; + + case mmMC_PMG_CMD_MRS: + *out_reg = mmMC_SEQ_PMG_CMD_MRS_LP; + break; + + case mmMC_PMG_CMD_MRS1: + *out_reg = mmMC_SEQ_PMG_CMD_MRS1_LP; + break; + + case mmMC_SEQ_PMG_TIMING: + *out_reg = mmMC_SEQ_PMG_TIMING_LP; + break; + + case mmMC_PMG_CMD_MRS2: + *out_reg = mmMC_SEQ_PMG_CMD_MRS2_LP; + break; + + case mmMC_SEQ_WR_CTL_2: + *out_reg = mmMC_SEQ_WR_CTL_2_LP; + break; + + default: + result = false; + break; + } + + return result; +} + +static int iceland_set_s0_mc_reg_index(struct iceland_mc_reg_table *table) +{ + uint32_t i; + uint16_t address; + + for (i = 0; i < table->last; i++) { + table->mc_reg_address[i].s0 = + iceland_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) + ? address : table->mc_reg_address[i].s1; + } + return 0; +} + +static int iceland_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, + struct iceland_mc_reg_table *ni_table) +{ + uint8_t i, j; + + PP_ASSERT_WITH_CODE((table->last <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES), + "Invalid VramInfo table.", return -EINVAL); + + for (i = 0; i < table->last; i++) { + ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1; + } + ni_table->last = table->last; + + for (i = 0; i < table->num_entries; i++) { + ni_table->mc_reg_table_entry[i].mclk_max = + table->mc_reg_table_entry[i].mclk_max; + for (j = 0; j < table->last; j++) { + ni_table->mc_reg_table_entry[i].mc_data[j] = + table->mc_reg_table_entry[i].mc_data[j]; + } + } + + ni_table->num_entries = table->num_entries; + + return 0; +} + +static int iceland_set_mc_special_registers(struct pp_hwmgr *hwmgr, + struct iceland_mc_reg_table *table) +{ + uint8_t i, j, k; + uint32_t temp_reg; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + for (i = 0, j = table->last; i < table->last; i++) { + PP_ASSERT_WITH_CODE((j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + switch (table->mc_reg_address[i].s1) { + + case mmMC_SEQ_MISC1: + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + ((temp_reg & 0xffff0000)) | + ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16); + } + j++; + PP_ASSERT_WITH_CODE((j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (temp_reg & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + + if (!data->is_memory_gddr5) { + table->mc_reg_table_entry[k].mc_data[j] |= 0x100; + } + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + if (!data->is_memory_gddr5 && j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE) { + table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD; + table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16; + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + } + + break; + + case mmMC_SEQ_RESERVE_M: + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (temp_reg & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + break; + + default: + break; + } + + } + + table->last = j; + + return 0; +} + +static int iceland_set_valid_flag(struct iceland_mc_reg_table *table) +{ + uint8_t i, j; + for (i = 0; i < table->last; i++) { + for (j = 1; j < table->num_entries; j++) { + if (table->mc_reg_table_entry[j-1].mc_data[i] != + table->mc_reg_table_entry[j].mc_data[i]) { + table->validflag |= (1<smu_backend); + pp_atomctrl_mc_reg_table *table; + struct iceland_mc_reg_table *ni_table = &smu_data->mc_reg_table; + uint8_t module_index = iceland_get_memory_modile_index(hwmgr); + + table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); + + if (NULL == table) + return -ENOMEM; + + /* Program additional LP registers that are no longer programmed by VBIOS */ + cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL)); + cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2)); + + memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table)); + + result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); + + if (0 == result) + result = iceland_copy_vbios_smc_reg_table(table, ni_table); + + if (0 == result) { + iceland_set_s0_mc_reg_index(ni_table); + result = iceland_set_mc_special_registers(hwmgr, ni_table); + } + + if (0 == result) + iceland_set_valid_flag(ni_table); + + kfree(table); + + return result; +} + +static bool iceland_is_dpm_running(struct pp_hwmgr *hwmgr) +{ + return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) + ? true : false; +} + const struct pp_smumgr_func iceland_smu_funcs = { .smu_init = &iceland_smu_init, .smu_fini = &smu7_smu_fini, -- cgit v1.2.3 From 4dddc212a354cc3924d60ca240cd338b0a3f6c49 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 16:20:49 +0800 Subject: drm/amd/pp: remove tonga_smc/smumgr split. move functions in tonga_smc.c to tonga_smumgr.c and make all functions in tonga_smumgr.c static. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/Makefile | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c | 3271 -------------------- drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.h | 62 - .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c | 3117 ++++++++++++++++++- .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h | 20 +- 5 files changed, 3128 insertions(+), 3344 deletions(-) delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.h (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile index 33ab0bca5c25..e3c783a07cbd 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile @@ -3,7 +3,7 @@ # It provides the smu management services for the driver. SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o \ - polaris10_smumgr.o iceland_smumgr.o polaris10_smc.o tonga_smc.o \ + polaris10_smumgr.o iceland_smumgr.o polaris10_smc.o \ smu7_smumgr.o vega10_smumgr.o rv_smumgr.o ci_smumgr.o AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c deleted file mode 100644 index 6675a85b482b..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c +++ /dev/null @@ -1,3271 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * 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 shall be included in - * all copies or substantial portions of the Software. - * - * - */ - -#include "pp_debug.h" -#include "tonga_smc.h" -#include "smu7_dyn_defaults.h" - -#include "smu7_hwmgr.h" -#include "hardwaremanager.h" -#include "ppatomctrl.h" -#include "cgs_common.h" -#include "atombios.h" -#include "tonga_smumgr.h" -#include "pppcielanes.h" -#include "pp_endian.h" -#include "smu7_ppsmc.h" - -#include "smu72_discrete.h" - -#include "smu/smu_7_1_2_d.h" -#include "smu/smu_7_1_2_sh_mask.h" - -#include "gmc/gmc_8_1_d.h" -#include "gmc/gmc_8_1_sh_mask.h" - -#include "bif/bif_5_0_d.h" -#include "bif/bif_5_0_sh_mask.h" - -#include "dce/dce_10_0_d.h" -#include "dce/dce_10_0_sh_mask.h" - - -#define VOLTAGE_SCALE 4 -#define POWERTUNE_DEFAULT_SET_MAX 1 -#define VOLTAGE_VID_OFFSET_SCALE1 625 -#define VOLTAGE_VID_OFFSET_SCALE2 100 -#define MC_CG_ARB_FREQ_F1 0x0b -#define VDDC_VDDCI_DELTA 200 - - -static const struct tonga_pt_defaults tonga_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { -/* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, - * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT - */ - {1, 0xF, 0xFD, 0x19, - 5, 45, 0, 0xB0000, - {0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, - 0xC9, 0xC9, 0x2F, 0x4D, 0x61}, - {0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, - 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4} - }, -}; - -/* [Fmin, Fmax, LDO_REFSEL, USE_FOR_LOW_FREQ] */ -static const uint16_t tonga_clock_stretcher_lookup_table[2][4] = { - {600, 1050, 3, 0}, - {600, 1050, 6, 1} -}; - -/* [FF, SS] type, [] 4 voltage ranges, - * and [Floor Freq, Boundary Freq, VID min , VID max] - */ -static const uint32_t tonga_clock_stretcher_ddt_table[2][4][4] = { - { {265, 529, 120, 128}, {325, 650, 96, 119}, {430, 860, 32, 95}, {0, 0, 0, 31} }, - { {275, 550, 104, 112}, {319, 638, 96, 103}, {360, 720, 64, 95}, {384, 768, 32, 63} } -}; - -/* [Use_For_Low_freq] value, [0%, 5%, 10%, 7.14%, 14.28%, 20%] */ -static const uint8_t tonga_clock_stretch_amount_conversion[2][6] = { - {0, 1, 3, 2, 4, 5}, - {0, 2, 4, 5, 6, 5} -}; - -/* PPGen has the gain setting generated in x * 100 unit - * This function is to convert the unit to x * 4096(0x1000) unit. - * This is the unit expected by SMC firmware - */ - - -static int tonga_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, - phm_ppt_v1_clock_voltage_dependency_table *allowed_clock_voltage_table, - uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd) -{ - uint32_t i = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - /* clock - voltage dependency table is empty table */ - if (allowed_clock_voltage_table->count == 0) - return -EINVAL; - - for (i = 0; i < allowed_clock_voltage_table->count; i++) { - /* find first sclk bigger than request */ - if (allowed_clock_voltage_table->entries[i].clk >= clock) { - voltage->VddGfx = phm_get_voltage_index( - pptable_info->vddgfx_lookup_table, - allowed_clock_voltage_table->entries[i].vddgfx); - voltage->Vddc = phm_get_voltage_index( - pptable_info->vddc_lookup_table, - allowed_clock_voltage_table->entries[i].vddc); - - if (allowed_clock_voltage_table->entries[i].vddci) - voltage->Vddci = - phm_get_voltage_id(&data->vddci_voltage_table, allowed_clock_voltage_table->entries[i].vddci); - else - voltage->Vddci = - phm_get_voltage_id(&data->vddci_voltage_table, - allowed_clock_voltage_table->entries[i].vddc - VDDC_VDDCI_DELTA); - - - if (allowed_clock_voltage_table->entries[i].mvdd) - *mvdd = (uint32_t) allowed_clock_voltage_table->entries[i].mvdd; - - voltage->Phases = 1; - return 0; - } - } - - /* sclk is bigger than max sclk in the dependence table */ - voltage->VddGfx = phm_get_voltage_index(pptable_info->vddgfx_lookup_table, - allowed_clock_voltage_table->entries[i-1].vddgfx); - voltage->Vddc = phm_get_voltage_index(pptable_info->vddc_lookup_table, - allowed_clock_voltage_table->entries[i-1].vddc); - - if (allowed_clock_voltage_table->entries[i-1].vddci) - voltage->Vddci = phm_get_voltage_id(&data->vddci_voltage_table, - allowed_clock_voltage_table->entries[i-1].vddci); - - if (allowed_clock_voltage_table->entries[i-1].mvdd) - *mvdd = (uint32_t) allowed_clock_voltage_table->entries[i-1].mvdd; - - return 0; -} - - -/** - * Vddc table preparation for SMC. - * - * @param hwmgr the address of the hardware manager - * @param table the SMC DPM table structure to be populated - * @return always 0 - */ -static int tonga_populate_smc_vddc_table(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - unsigned int count; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) { - table->VddcLevelCount = data->vddc_voltage_table.count; - for (count = 0; count < table->VddcLevelCount; count++) { - table->VddcTable[count] = - PP_HOST_TO_SMC_US(data->vddc_voltage_table.entries[count].value * VOLTAGE_SCALE); - } - CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount); - } - return 0; -} - -/** - * VddGfx table preparation for SMC. - * - * @param hwmgr the address of the hardware manager - * @param table the SMC DPM table structure to be populated - * @return always 0 - */ -static int tonga_populate_smc_vdd_gfx_table(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - unsigned int count; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_gfx_control) { - table->VddGfxLevelCount = data->vddgfx_voltage_table.count; - for (count = 0; count < data->vddgfx_voltage_table.count; count++) { - table->VddGfxTable[count] = - PP_HOST_TO_SMC_US(data->vddgfx_voltage_table.entries[count].value * VOLTAGE_SCALE); - } - CONVERT_FROM_HOST_TO_SMC_UL(table->VddGfxLevelCount); - } - return 0; -} - -/** - * Vddci table preparation for SMC. - * - * @param *hwmgr The address of the hardware manager. - * @param *table The SMC DPM table structure to be populated. - * @return 0 - */ -static int tonga_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t count; - - table->VddciLevelCount = data->vddci_voltage_table.count; - for (count = 0; count < table->VddciLevelCount; count++) { - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { - table->VddciTable[count] = - PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE); - } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { - table->SmioTable1.Pattern[count].Voltage = - PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE); - /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level. */ - table->SmioTable1.Pattern[count].Smio = - (uint8_t) count; - table->Smio[count] |= - data->vddci_voltage_table.entries[count].smio_low; - table->VddciTable[count] = - PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE); - } - } - - table->SmioMask1 = data->vddci_voltage_table.mask_low; - CONVERT_FROM_HOST_TO_SMC_UL(table->VddciLevelCount); - - return 0; -} - -/** - * Mvdd table preparation for SMC. - * - * @param *hwmgr The address of the hardware manager. - * @param *table The SMC DPM table structure to be populated. - * @return 0 - */ -static int tonga_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t count; - - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) { - table->MvddLevelCount = data->mvdd_voltage_table.count; - for (count = 0; count < table->MvddLevelCount; count++) { - table->SmioTable2.Pattern[count].Voltage = - PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); - /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ - table->SmioTable2.Pattern[count].Smio = - (uint8_t) count; - table->Smio[count] |= - data->mvdd_voltage_table.entries[count].smio_low; - } - table->SmioMask2 = data->mvdd_voltage_table.mask_low; - - CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount); - } - - return 0; -} - -/** - * Preparation of vddc and vddgfx CAC tables for SMC. - * - * @param hwmgr the address of the hardware manager - * @param table the SMC DPM table structure to be populated - * @return always 0 - */ -static int tonga_populate_cac_tables(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - uint32_t count; - uint8_t index = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_voltage_lookup_table *vddgfx_lookup_table = - pptable_info->vddgfx_lookup_table; - struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table = - pptable_info->vddc_lookup_table; - - /* table is already swapped, so in order to use the value from it - * we need to swap it back. - */ - uint32_t vddc_level_count = PP_SMC_TO_HOST_UL(table->VddcLevelCount); - uint32_t vddgfx_level_count = PP_SMC_TO_HOST_UL(table->VddGfxLevelCount); - - for (count = 0; count < vddc_level_count; count++) { - /* We are populating vddc CAC data to BapmVddc table in split and merged mode */ - index = phm_get_voltage_index(vddc_lookup_table, - data->vddc_voltage_table.entries[count].value); - table->BapmVddcVidLoSidd[count] = - convert_to_vid(vddc_lookup_table->entries[index].us_cac_low); - table->BapmVddcVidHiSidd[count] = - convert_to_vid(vddc_lookup_table->entries[index].us_cac_mid); - table->BapmVddcVidHiSidd2[count] = - convert_to_vid(vddc_lookup_table->entries[index].us_cac_high); - } - - if ((data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2)) { - /* We are populating vddgfx CAC data to BapmVddgfx table in split mode */ - for (count = 0; count < vddgfx_level_count; count++) { - index = phm_get_voltage_index(vddgfx_lookup_table, - convert_to_vid(vddgfx_lookup_table->entries[index].us_cac_mid)); - table->BapmVddGfxVidHiSidd2[count] = - convert_to_vid(vddgfx_lookup_table->entries[index].us_cac_high); - } - } else { - for (count = 0; count < vddc_level_count; count++) { - index = phm_get_voltage_index(vddc_lookup_table, - data->vddc_voltage_table.entries[count].value); - table->BapmVddGfxVidLoSidd[count] = - convert_to_vid(vddc_lookup_table->entries[index].us_cac_low); - table->BapmVddGfxVidHiSidd[count] = - convert_to_vid(vddc_lookup_table->entries[index].us_cac_mid); - table->BapmVddGfxVidHiSidd2[count] = - convert_to_vid(vddc_lookup_table->entries[index].us_cac_high); - } - } - - return 0; -} - -/** - * Preparation of voltage tables for SMC. - * - * @param hwmgr the address of the hardware manager - * @param table the SMC DPM table structure to be populated - * @return always 0 - */ - -static int tonga_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - int result; - - result = tonga_populate_smc_vddc_table(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "can not populate VDDC voltage table to SMC", - return -EINVAL); - - result = tonga_populate_smc_vdd_ci_table(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "can not populate VDDCI voltage table to SMC", - return -EINVAL); - - result = tonga_populate_smc_vdd_gfx_table(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "can not populate VDDGFX voltage table to SMC", - return -EINVAL); - - result = tonga_populate_smc_mvdd_table(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "can not populate MVDD voltage table to SMC", - return -EINVAL); - - result = tonga_populate_cac_tables(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "can not populate CAC voltage tables to SMC", - return -EINVAL); - - return 0; -} - -static int tonga_populate_ulv_level(struct pp_hwmgr *hwmgr, - struct SMU72_Discrete_Ulv *state) -{ - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - state->CcPwrDynRm = 0; - state->CcPwrDynRm1 = 0; - - state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset; - state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset * - VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1); - - state->VddcPhase = 1; - - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); - CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); - - return 0; -} - -static int tonga_populate_ulv_state(struct pp_hwmgr *hwmgr, - struct SMU72_Discrete_DpmTable *table) -{ - return tonga_populate_ulv_level(hwmgr, &table->Ulv); -} - -static int tonga_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU72_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - uint32_t i; - - /* Index (dpm_table->pcie_speed_table.count) is reserved for PCIE boot level. */ - for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { - table->LinkLevel[i].PcieGenSpeed = - (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; - table->LinkLevel[i].PcieLaneCount = - (uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1); - table->LinkLevel[i].EnabledForActivity = - 1; - table->LinkLevel[i].SPC = - (uint8_t)(data->pcie_spc_cap & 0xff); - table->LinkLevel[i].DownThreshold = - PP_HOST_TO_SMC_UL(5); - table->LinkLevel[i].UpThreshold = - PP_HOST_TO_SMC_UL(30); - } - - smu_data->smc_state_table.LinkLevelCount = - (uint8_t)dpm_table->pcie_speed_table.count; - data->dpm_level_enable_mask.pcie_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); - - return 0; -} - -/** - * Calculates the SCLK dividers using the provided engine clock - * - * @param hwmgr the address of the hardware manager - * @param engine_clock the engine clock to use to populate the structure - * @param sclk the SMC SCLK structure to be populated - */ -static int tonga_calculate_sclk_params(struct pp_hwmgr *hwmgr, - uint32_t engine_clock, SMU72_Discrete_GraphicsLevel *sclk) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - pp_atomctrl_clock_dividers_vi dividers; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - uint32_t reference_clock; - uint32_t reference_divider; - uint32_t fbdiv; - int result; - - /* get the engine clock dividers for this clock value*/ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, engine_clock, ÷rs); - - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", return result); - - /* To get FBDIV we need to multiply this by 16384 and divide it by Fref.*/ - reference_clock = atomctrl_get_reference_clock(hwmgr); - - reference_divider = 1 + dividers.uc_pll_ref_div; - - /* low 14 bits is fraction and high 12 bits is divider*/ - fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; - - /* SPLL_FUNC_CNTL setup*/ - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_REF_DIV, dividers.uc_pll_ref_div); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, - CG_SPLL_FUNC_CNTL, SPLL_PDIV_A, dividers.uc_pll_post_div); - - /* SPLL_FUNC_CNTL_3 setup*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, - CG_SPLL_FUNC_CNTL_3, SPLL_FB_DIV, fbdiv); - - /* set to use fractional accumulation*/ - spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, - CG_SPLL_FUNC_CNTL_3, SPLL_DITHEN, 1); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { - pp_atomctrl_internal_ss_info ss_info; - - uint32_t vcoFreq = engine_clock * dividers.uc_pll_post_div; - if (0 == atomctrl_get_engine_clock_spread_spectrum(hwmgr, vcoFreq, &ss_info)) { - /* - * ss_info.speed_spectrum_percentage -- in unit of 0.01% - * ss_info.speed_spectrum_rate -- in unit of khz - */ - /* clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 */ - uint32_t clkS = reference_clock * 5 / (reference_divider * ss_info.speed_spectrum_rate); - - /* clkv = 2 * D * fbdiv / NS */ - uint32_t clkV = 4 * ss_info.speed_spectrum_percentage * fbdiv / (clkS * 10000); - - cg_spll_spread_spectrum = - PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, CLKS, clkS); - cg_spll_spread_spectrum = - PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); - cg_spll_spread_spectrum_2 = - PHM_SET_FIELD(cg_spll_spread_spectrum_2, CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clkV); - } - } - - sclk->SclkFrequency = engine_clock; - sclk->CgSpllFuncCntl3 = spll_func_cntl_3; - sclk->CgSpllFuncCntl4 = spll_func_cntl_4; - sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; - sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; - sclk->SclkDid = (uint8_t)dividers.pll_post_divider; - - return 0; -} - -/** - * Populates single SMC SCLK structure using the provided engine clock - * - * @param hwmgr the address of the hardware manager - * @param engine_clock the engine clock to use to populate the structure - * @param sclk the SMC SCLK structure to be populated - */ -static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr, - uint32_t engine_clock, - uint16_t sclk_activity_level_threshold, - SMU72_Discrete_GraphicsLevel *graphic_level) -{ - int result; - uint32_t mvdd; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - result = tonga_calculate_sclk_params(hwmgr, engine_clock, graphic_level); - - /* populate graphics levels*/ - result = tonga_get_dependency_volt_by_clk(hwmgr, - pptable_info->vdd_dep_on_sclk, engine_clock, - &graphic_level->MinVoltage, &mvdd); - PP_ASSERT_WITH_CODE((!result), - "can not find VDDC voltage value for VDDC " - "engine clock dependency table", return result); - - /* SCLK frequency in units of 10KHz*/ - graphic_level->SclkFrequency = engine_clock; - /* Indicates maximum activity level for this performance level. 50% for now*/ - graphic_level->ActivityLevel = sclk_activity_level_threshold; - - graphic_level->CcPwrDynRm = 0; - graphic_level->CcPwrDynRm1 = 0; - /* this level can be used if activity is high enough.*/ - graphic_level->EnabledForActivity = 0; - /* this level can be used for throttling.*/ - graphic_level->EnabledForThrottle = 1; - graphic_level->UpHyst = 0; - graphic_level->DownHyst = 0; - graphic_level->VoltageDownHyst = 0; - graphic_level->PowerThrottle = 0; - - data->display_timing.min_clock_in_sr = - hwmgr->display_config.min_core_set_clock_in_sr; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkDeepSleep)) - graphic_level->DeepSleepDivId = - smu7_get_sleep_divider_id_from_clock(engine_clock, - data->display_timing.min_clock_in_sr); - - /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ - graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - if (!result) { - /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVoltage);*/ - /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases);*/ - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(graphic_level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm1); - } - - return result; -} - -/** - * Populates all SMC SCLK levels' structure based on the trimmed allowed dpm engine clock states - * - * @param hwmgr the address of the hardware manager - */ -int tonga_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - struct phm_ppt_v1_pcie_table *pcie_table = pptable_info->pcie_table; - uint8_t pcie_entry_count = (uint8_t) data->dpm_table.pcie_speed_table.count; - uint32_t level_array_address = smu_data->smu7_data.dpm_table_start + - offsetof(SMU72_Discrete_DpmTable, GraphicsLevel); - - uint32_t level_array_size = sizeof(SMU72_Discrete_GraphicsLevel) * - SMU72_MAX_LEVELS_GRAPHICS; - - SMU72_Discrete_GraphicsLevel *levels = smu_data->smc_state_table.GraphicsLevel; - - uint32_t i, max_entry; - uint8_t highest_pcie_level_enabled = 0; - uint8_t lowest_pcie_level_enabled = 0, mid_pcie_level_enabled = 0; - uint8_t count = 0; - int result = 0; - - memset(levels, 0x00, level_array_size); - - for (i = 0; i < dpm_table->sclk_table.count; i++) { - result = tonga_populate_single_graphic_level(hwmgr, - dpm_table->sclk_table.dpm_levels[i].value, - (uint16_t)smu_data->activity_target[i], - &(smu_data->smc_state_table.GraphicsLevel[i])); - if (result != 0) - return result; - - /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ - if (i > 1) - smu_data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0; - } - - /* Only enable level 0 for now. */ - smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; - - /* set highest level watermark to high */ - if (dpm_table->sclk_table.count > 1) - smu_data->smc_state_table.GraphicsLevel[dpm_table->sclk_table.count-1].DisplayWatermark = - PPSMC_DISPLAY_WATERMARK_HIGH; - - smu_data->smc_state_table.GraphicsDpmLevelCount = - (uint8_t)dpm_table->sclk_table.count; - data->dpm_level_enable_mask.sclk_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); - - if (pcie_table != NULL) { - PP_ASSERT_WITH_CODE((pcie_entry_count >= 1), - "There must be 1 or more PCIE levels defined in PPTable.", - return -EINVAL); - max_entry = pcie_entry_count - 1; /* for indexing, we need to decrement by 1.*/ - for (i = 0; i < dpm_table->sclk_table.count; i++) { - smu_data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = - (uint8_t) ((i < max_entry) ? i : max_entry); - } - } else { - if (0 == data->dpm_level_enable_mask.pcie_dpm_enable_mask) - pr_err("Pcie Dpm Enablemask is 0 !"); - - while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && - ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1<<(highest_pcie_level_enabled+1))) != 0)) { - highest_pcie_level_enabled++; - } - - while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && - ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1<dpm_level_enable_mask.pcie_dpm_enable_mask & - (1<<(lowest_pcie_level_enabled+1+count))) == 0)) { - count++; - } - mid_pcie_level_enabled = (lowest_pcie_level_enabled+1+count) < highest_pcie_level_enabled ? - (lowest_pcie_level_enabled+1+count) : highest_pcie_level_enabled; - - - /* set pcieDpmLevel to highest_pcie_level_enabled*/ - for (i = 2; i < dpm_table->sclk_table.count; i++) - smu_data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = highest_pcie_level_enabled; - - /* set pcieDpmLevel to lowest_pcie_level_enabled*/ - smu_data->smc_state_table.GraphicsLevel[0].pcieDpmLevel = lowest_pcie_level_enabled; - - /* set pcieDpmLevel to mid_pcie_level_enabled*/ - smu_data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled; - } - /* level count will send to smc once at init smc table and never change*/ - result = smu7_copy_bytes_to_smc(hwmgr, level_array_address, - (uint8_t *)levels, (uint32_t)level_array_size, - SMC_RAM_END); - - return result; -} - -/** - * Populates the SMC MCLK structure using the provided memory clock - * - * @param hwmgr the address of the hardware manager - * @param memory_clock the memory clock to use to populate the structure - * @param sclk the SMC SCLK structure to be populated - */ -static int tonga_calculate_mclk_params( - struct pp_hwmgr *hwmgr, - uint32_t memory_clock, - SMU72_Discrete_MemoryLevel *mclk, - bool strobe_mode, - bool dllStateOn - ) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; - uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; - uint32_t mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL; - uint32_t mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL; - uint32_t mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL; - uint32_t mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1; - uint32_t mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2; - uint32_t mpll_ss1 = data->clock_registers.vMPLL_SS1; - uint32_t mpll_ss2 = data->clock_registers.vMPLL_SS2; - - pp_atomctrl_memory_clock_param mpll_param; - int result; - - result = atomctrl_get_memory_pll_dividers_si(hwmgr, - memory_clock, &mpll_param, strobe_mode); - PP_ASSERT_WITH_CODE( - !result, - "Error retrieving Memory Clock Parameters from VBIOS.", - return result); - - /* MPLL_FUNC_CNTL setup*/ - mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, - mpll_param.bw_ctrl); - - /* MPLL_FUNC_CNTL_1 setup*/ - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, CLKF, - mpll_param.mpll_fb_divider.cl_kf); - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, CLKFRAC, - mpll_param.mpll_fb_divider.clk_frac); - mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, - MPLL_FUNC_CNTL_1, VCO_MODE, - mpll_param.vco_mode); - - /* MPLL_AD_FUNC_CNTL setup*/ - mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl, - MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, - mpll_param.mpll_post_divider); - - if (data->is_memory_gddr5) { - /* MPLL_DQ_FUNC_CNTL setup*/ - mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, - MPLL_DQ_FUNC_CNTL, YCLK_SEL, - mpll_param.yclk_sel); - mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, - MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, - mpll_param.mpll_post_divider); - } - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MemorySpreadSpectrumSupport)) { - /* - ************************************ - Fref = Reference Frequency - NF = Feedback divider ratio - NR = Reference divider ratio - Fnom = Nominal VCO output frequency = Fref * NF / NR - Fs = Spreading Rate - D = Percentage down-spread / 2 - Fint = Reference input frequency to PFD = Fref / NR - NS = Spreading rate divider ratio = int(Fint / (2 * Fs)) - CLKS = NS - 1 = ISS_STEP_NUM[11:0] - NV = D * Fs / Fnom * 4 * ((Fnom/Fref * NR) ^ 2) - CLKV = 65536 * NV = ISS_STEP_SIZE[25:0] - ************************************* - */ - pp_atomctrl_internal_ss_info ss_info; - uint32_t freq_nom; - uint32_t tmp; - uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr); - - /* for GDDR5 for all modes and DDR3 */ - if (1 == mpll_param.qdr) - freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider); - else - freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider); - - /* tmp = (freq_nom / reference_clock * reference_divider) ^ 2 Note: S.I. reference_divider = 1*/ - tmp = (freq_nom / reference_clock); - tmp = tmp * tmp; - - if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) { - /* ss_info.speed_spectrum_percentage -- in unit of 0.01% */ - /* ss.Info.speed_spectrum_rate -- in unit of khz */ - /* CLKS = reference_clock / (2 * speed_spectrum_rate * reference_divider) * 10 */ - /* = reference_clock * 5 / speed_spectrum_rate */ - uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate; - - /* CLKV = 65536 * speed_spectrum_percentage / 2 * spreadSpecrumRate / freq_nom * 4 / 100000 * ((freq_nom / reference_clock) ^ 2) */ - /* = 131 * speed_spectrum_percentage * speed_spectrum_rate / 100 * ((freq_nom / reference_clock) ^ 2) / freq_nom */ - uint32_t clkv = - (uint32_t)((((131 * ss_info.speed_spectrum_percentage * - ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom); - - mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv); - mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks); - } - } - - /* MCLK_PWRMGT_CNTL setup */ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn); - - /* Save the result data to outpupt memory level structure */ - mclk->MclkFrequency = memory_clock; - mclk->MpllFuncCntl = mpll_func_cntl; - mclk->MpllFuncCntl_1 = mpll_func_cntl_1; - mclk->MpllFuncCntl_2 = mpll_func_cntl_2; - mclk->MpllAdFuncCntl = mpll_ad_func_cntl; - mclk->MpllDqFuncCntl = mpll_dq_func_cntl; - mclk->MclkPwrmgtCntl = mclk_pwrmgt_cntl; - mclk->DllCntl = dll_cntl; - mclk->MpllSs1 = mpll_ss1; - mclk->MpllSs2 = mpll_ss2; - - return 0; -} - -static uint8_t tonga_get_mclk_frequency_ratio(uint32_t memory_clock, - bool strobe_mode) -{ - uint8_t mc_para_index; - - if (strobe_mode) { - if (memory_clock < 12500) - mc_para_index = 0x00; - else if (memory_clock > 47500) - mc_para_index = 0x0f; - else - mc_para_index = (uint8_t)((memory_clock - 10000) / 2500); - } else { - if (memory_clock < 65000) - mc_para_index = 0x00; - else if (memory_clock > 135000) - mc_para_index = 0x0f; - else - mc_para_index = (uint8_t)((memory_clock - 60000) / 5000); - } - - return mc_para_index; -} - -static uint8_t tonga_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock) -{ - uint8_t mc_para_index; - - if (memory_clock < 10000) - mc_para_index = 0; - else if (memory_clock >= 80000) - mc_para_index = 0x0f; - else - mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1); - - return mc_para_index; -} - - -static int tonga_populate_single_memory_level( - struct pp_hwmgr *hwmgr, - uint32_t memory_clock, - SMU72_Discrete_MemoryLevel *memory_level - ) -{ - uint32_t mvdd = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - int result = 0; - bool dll_state_on; - struct cgs_display_info info = {0}; - uint32_t mclk_edc_wr_enable_threshold = 40000; - uint32_t mclk_stutter_mode_threshold = 30000; - uint32_t mclk_edc_enable_threshold = 40000; - uint32_t mclk_strobe_mode_threshold = 40000; - - if (NULL != pptable_info->vdd_dep_on_mclk) { - result = tonga_get_dependency_volt_by_clk(hwmgr, - pptable_info->vdd_dep_on_mclk, - memory_clock, - &memory_level->MinVoltage, &mvdd); - PP_ASSERT_WITH_CODE( - !result, - "can not find MinVddc voltage value from memory VDDC " - "voltage dependency table", - return result); - } - - if (data->mvdd_control == SMU7_VOLTAGE_CONTROL_NONE) - memory_level->MinMvdd = data->vbios_boot_state.mvdd_bootup_value; - else - memory_level->MinMvdd = mvdd; - - memory_level->EnabledForThrottle = 1; - memory_level->EnabledForActivity = 0; - memory_level->UpHyst = 0; - memory_level->DownHyst = 100; - memory_level->VoltageDownHyst = 0; - - /* Indicates maximum activity level for this performance level.*/ - memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target; - memory_level->StutterEnable = 0; - memory_level->StrobeEnable = 0; - memory_level->EdcReadEnable = 0; - memory_level->EdcWriteEnable = 0; - memory_level->RttEnable = 0; - - /* default set to low watermark. Highest level will be set to high later.*/ - memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - cgs_get_active_displays_info(hwmgr->device, &info); - data->display_timing.num_existing_displays = info.display_count; - - if ((mclk_stutter_mode_threshold != 0) && - (memory_clock <= mclk_stutter_mode_threshold) && - (!data->is_uvd_enabled) - && (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, STUTTER_ENABLE) & 0x1) - && (data->display_timing.num_existing_displays <= 2) - && (data->display_timing.num_existing_displays != 0)) - memory_level->StutterEnable = 1; - - /* decide strobe mode*/ - memory_level->StrobeEnable = (mclk_strobe_mode_threshold != 0) && - (memory_clock <= mclk_strobe_mode_threshold); - - /* decide EDC mode and memory clock ratio*/ - if (data->is_memory_gddr5) { - memory_level->StrobeRatio = tonga_get_mclk_frequency_ratio(memory_clock, - memory_level->StrobeEnable); - - if ((mclk_edc_enable_threshold != 0) && - (memory_clock > mclk_edc_enable_threshold)) { - memory_level->EdcReadEnable = 1; - } - - if ((mclk_edc_wr_enable_threshold != 0) && - (memory_clock > mclk_edc_wr_enable_threshold)) { - memory_level->EdcWriteEnable = 1; - } - - if (memory_level->StrobeEnable) { - if (tonga_get_mclk_frequency_ratio(memory_clock, 1) >= - ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) { - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; - } else { - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0; - } - - } else { - dll_state_on = data->dll_default_on; - } - } else { - memory_level->StrobeRatio = - tonga_get_ddr3_mclk_frequency_ratio(memory_clock); - dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; - } - - result = tonga_calculate_mclk_params(hwmgr, - memory_clock, memory_level, memory_level->StrobeEnable, dll_state_on); - - if (!result) { - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinMvdd); - /* MCLK frequency in units of 10KHz*/ - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency); - /* Indicates maximum activity level for this performance level.*/ - CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1); - CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2); - } - - return result; -} - -int tonga_populate_all_memory_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - int result; - - /* populate MCLK dpm table to SMU7 */ - uint32_t level_array_address = - smu_data->smu7_data.dpm_table_start + - offsetof(SMU72_Discrete_DpmTable, MemoryLevel); - uint32_t level_array_size = - sizeof(SMU72_Discrete_MemoryLevel) * - SMU72_MAX_LEVELS_MEMORY; - SMU72_Discrete_MemoryLevel *levels = - smu_data->smc_state_table.MemoryLevel; - uint32_t i; - - memset(levels, 0x00, level_array_size); - - for (i = 0; i < dpm_table->mclk_table.count; i++) { - PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), - "can not populate memory level as memory clock is zero", - return -EINVAL); - result = tonga_populate_single_memory_level( - hwmgr, - dpm_table->mclk_table.dpm_levels[i].value, - &(smu_data->smc_state_table.MemoryLevel[i])); - if (result) - return result; - } - - /* Only enable level 0 for now.*/ - smu_data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1; - - /* - * in order to prevent MC activity from stutter mode to push DPM up. - * the UVD change complements this by putting the MCLK in a higher state - * by default such that we are not effected by up threshold or and MCLK DPM latency. - */ - smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F; - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel); - - smu_data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count; - data->dpm_level_enable_mask.mclk_dpm_enable_mask = phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); - /* set highest level watermark to high*/ - smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; - - /* level count will send to smc once at init smc table and never change*/ - result = smu7_copy_bytes_to_smc(hwmgr, - level_array_address, (uint8_t *)levels, (uint32_t)level_array_size, - SMC_RAM_END); - - return result; -} - -static int tonga_populate_mvdd_value(struct pp_hwmgr *hwmgr, - uint32_t mclk, SMIO_Pattern *smio_pattern) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint32_t i = 0; - - if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { - /* find mvdd value which clock is more than request */ - for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) { - if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) { - /* Always round to higher voltage. */ - smio_pattern->Voltage = - data->mvdd_voltage_table.entries[i].value; - break; - } - } - - PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count, - "MVDD Voltage is outside the supported range.", - return -EINVAL); - } else { - return -EINVAL; - } - - return 0; -} - - -static int tonga_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - int result = 0; - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct pp_atomctrl_clock_dividers_vi dividers; - - SMIO_Pattern voltage_level; - uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; - uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; - uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; - uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; - - /* The ACPI state should not do DPM on DC (or ever).*/ - table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; - - table->ACPILevel.MinVoltage = - smu_data->smc_state_table.GraphicsLevel[0].MinVoltage; - - /* assign zero for now*/ - table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr); - - /* get the engine clock dividers for this clock value*/ - result = atomctrl_get_engine_pll_dividers_vi(hwmgr, - table->ACPILevel.SclkFrequency, ÷rs); - - PP_ASSERT_WITH_CODE(result == 0, - "Error retrieving Engine Clock dividers from VBIOS.", - return result); - - /* divider ID for required SCLK*/ - table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; - table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - table->ACPILevel.DeepSleepDivId = 0; - - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_PWRON, 0); - spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, - SPLL_RESET, 1); - spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, CG_SPLL_FUNC_CNTL_2, - SCLK_MUX_SEL, 4); - - table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; - table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; - table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; - table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; - table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; - table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; - table->ACPILevel.CcPwrDynRm = 0; - table->ACPILevel.CcPwrDynRm1 = 0; - - - /* For various features to be enabled/disabled while this level is active.*/ - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); - /* SCLK frequency in units of 10KHz*/ - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); - - /* table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;*/ - table->MemoryACPILevel.MinVoltage = - smu_data->smc_state_table.MemoryLevel[0].MinVoltage; - - /* CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage);*/ - - if (0 == tonga_populate_mvdd_value(hwmgr, 0, &voltage_level)) - table->MemoryACPILevel.MinMvdd = - PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE); - else - table->MemoryACPILevel.MinMvdd = 0; - - /* Force reset on DLL*/ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1); - - /* Disable DLL in ACPIState*/ - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0); - mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, - MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0); - - /* Enable DLL bypass signal*/ - dll_cntl = PHM_SET_FIELD(dll_cntl, - DLL_CNTL, MRDCK0_BYPASS, 0); - dll_cntl = PHM_SET_FIELD(dll_cntl, - DLL_CNTL, MRDCK1_BYPASS, 0); - - table->MemoryACPILevel.DllCntl = - PP_HOST_TO_SMC_UL(dll_cntl); - table->MemoryACPILevel.MclkPwrmgtCntl = - PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl); - table->MemoryACPILevel.MpllAdFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL); - table->MemoryACPILevel.MpllDqFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL); - table->MemoryACPILevel.MpllFuncCntl = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL); - table->MemoryACPILevel.MpllFuncCntl_1 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1); - table->MemoryACPILevel.MpllFuncCntl_2 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2); - table->MemoryACPILevel.MpllSs1 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1); - table->MemoryACPILevel.MpllSs2 = - PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2); - - table->MemoryACPILevel.EnabledForThrottle = 0; - table->MemoryACPILevel.EnabledForActivity = 0; - table->MemoryACPILevel.UpHyst = 0; - table->MemoryACPILevel.DownHyst = 100; - table->MemoryACPILevel.VoltageDownHyst = 0; - /* Indicates maximum activity level for this performance level.*/ - table->MemoryACPILevel.ActivityLevel = - PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); - - table->MemoryACPILevel.StutterEnable = 0; - table->MemoryACPILevel.StrobeEnable = 0; - table->MemoryACPILevel.EdcReadEnable = 0; - table->MemoryACPILevel.EdcWriteEnable = 0; - table->MemoryACPILevel.RttEnable = 0; - - return result; -} - -static int tonga_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - int result = 0; - - uint8_t count; - pp_atomctrl_clock_dividers_vi dividers; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - pptable_info->mm_dep_table; - - table->UvdLevelCount = (uint8_t) (mm_table->count); - table->UvdBootLevel = 0; - - for (count = 0; count < table->UvdLevelCount; count++) { - table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; - table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; - table->UvdLevel[count].MinVoltage.Vddc = - phm_get_voltage_index(pptable_info->vddc_lookup_table, - mm_table->entries[count].vddc); - table->UvdLevel[count].MinVoltage.VddGfx = - (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? - phm_get_voltage_index(pptable_info->vddgfx_lookup_table, - mm_table->entries[count].vddgfx) : 0; - table->UvdLevel[count].MinVoltage.Vddci = - phm_get_voltage_id(&data->vddci_voltage_table, - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); - table->UvdLevel[count].MinVoltage.Phases = 1; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi( - hwmgr, - table->UvdLevel[count].VclkFrequency, - ÷rs); - - PP_ASSERT_WITH_CODE((!result), - "can not find divide id for Vclk clock", - return result); - - table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; - - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->UvdLevel[count].DclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE((!result), - "can not find divide id for Dclk clock", - return result); - - table->UvdLevel[count].DclkDivider = - (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); - } - - return result; - -} - -static int tonga_populate_smc_vce_level(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - int result = 0; - - uint8_t count; - pp_atomctrl_clock_dividers_vi dividers; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - pptable_info->mm_dep_table; - - table->VceLevelCount = (uint8_t) (mm_table->count); - table->VceBootLevel = 0; - - for (count = 0; count < table->VceLevelCount; count++) { - table->VceLevel[count].Frequency = - mm_table->entries[count].eclk; - table->VceLevel[count].MinVoltage.Vddc = - phm_get_voltage_index(pptable_info->vddc_lookup_table, - mm_table->entries[count].vddc); - table->VceLevel[count].MinVoltage.VddGfx = - (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? - phm_get_voltage_index(pptable_info->vddgfx_lookup_table, - mm_table->entries[count].vddgfx) : 0; - table->VceLevel[count].MinVoltage.Vddci = - phm_get_voltage_id(&data->vddci_voltage_table, - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); - table->VceLevel[count].MinVoltage.Phases = 1; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->VceLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((!result), - "can not find divide id for VCE engine clock", - return result); - - table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); - } - - return result; -} - -static int tonga_populate_smc_acp_level(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - int result = 0; - uint8_t count; - pp_atomctrl_clock_dividers_vi dividers; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - pptable_info->mm_dep_table; - - table->AcpLevelCount = (uint8_t) (mm_table->count); - table->AcpBootLevel = 0; - - for (count = 0; count < table->AcpLevelCount; count++) { - table->AcpLevel[count].Frequency = - pptable_info->mm_dep_table->entries[count].aclk; - table->AcpLevel[count].MinVoltage.Vddc = - phm_get_voltage_index(pptable_info->vddc_lookup_table, - mm_table->entries[count].vddc); - table->AcpLevel[count].MinVoltage.VddGfx = - (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? - phm_get_voltage_index(pptable_info->vddgfx_lookup_table, - mm_table->entries[count].vddgfx) : 0; - table->AcpLevel[count].MinVoltage.Vddci = - phm_get_voltage_id(&data->vddci_voltage_table, - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); - table->AcpLevel[count].MinVoltage.Phases = 1; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->AcpLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((!result), - "can not find divide id for engine clock", return result); - - table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency); - } - - return result; -} - -static int tonga_populate_smc_samu_level(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - int result = 0; - uint8_t count; - pp_atomctrl_clock_dividers_vi dividers; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *pptable_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - pptable_info->mm_dep_table; - - table->SamuBootLevel = 0; - table->SamuLevelCount = (uint8_t) (mm_table->count); - - for (count = 0; count < table->SamuLevelCount; count++) { - /* not sure whether we need evclk or not */ - table->SamuLevel[count].Frequency = - pptable_info->mm_dep_table->entries[count].samclock; - table->SamuLevel[count].MinVoltage.Vddc = - phm_get_voltage_index(pptable_info->vddc_lookup_table, - mm_table->entries[count].vddc); - table->SamuLevel[count].MinVoltage.VddGfx = - (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? - phm_get_voltage_index(pptable_info->vddgfx_lookup_table, - mm_table->entries[count].vddgfx) : 0; - table->SamuLevel[count].MinVoltage.Vddci = - phm_get_voltage_id(&data->vddci_voltage_table, - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); - table->SamuLevel[count].MinVoltage.Phases = 1; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->SamuLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((!result), - "can not find divide id for samu clock", return result); - - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); - } - - return result; -} - -static int tonga_populate_memory_timing_parameters( - struct pp_hwmgr *hwmgr, - uint32_t engine_clock, - uint32_t memory_clock, - struct SMU72_Discrete_MCArbDramTimingTableEntry *arb_regs - ) -{ - uint32_t dramTiming; - uint32_t dramTiming2; - uint32_t burstTime; - int result; - - result = atomctrl_set_engine_dram_timings_rv770(hwmgr, - engine_clock, memory_clock); - - PP_ASSERT_WITH_CODE(result == 0, - "Error calling VBIOS to set DRAM_TIMING.", return result); - - dramTiming = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); - dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); - burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); - - arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dramTiming); - arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2); - arb_regs->McArbBurstTime = (uint8_t)burstTime; - - return 0; -} - -/** - * Setup parameters for the MC ARB. - * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 - * This function is to be called from the SetPowerState table. - */ -static int tonga_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - int result = 0; - SMU72_Discrete_MCArbDramTimingTable arb_regs; - uint32_t i, j; - - memset(&arb_regs, 0x00, sizeof(SMU72_Discrete_MCArbDramTimingTable)); - - for (i = 0; i < data->dpm_table.sclk_table.count; i++) { - for (j = 0; j < data->dpm_table.mclk_table.count; j++) { - result = tonga_populate_memory_timing_parameters - (hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value, - data->dpm_table.mclk_table.dpm_levels[j].value, - &arb_regs.entries[i][j]); - - if (result) - break; - } - } - - if (!result) { - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.arb_table_start, - (uint8_t *)&arb_regs, - sizeof(SMU72_Discrete_MCArbDramTimingTable), - SMC_RAM_END - ); - } - - return result; -} - -static int tonga_populate_smc_boot_level(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - table->GraphicsBootLevel = 0; - table->MemoryBootLevel = 0; - - /* find boot level from dpm table*/ - result = phm_find_boot_level(&(data->dpm_table.sclk_table), - data->vbios_boot_state.sclk_bootup_value, - (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); - - if (result != 0) { - smu_data->smc_state_table.GraphicsBootLevel = 0; - pr_err("[powerplay] VBIOS did not find boot engine " - "clock value in dependency table. " - "Using Graphics DPM level 0 !"); - result = 0; - } - - result = phm_find_boot_level(&(data->dpm_table.mclk_table), - data->vbios_boot_state.mclk_bootup_value, - (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); - - if (result != 0) { - smu_data->smc_state_table.MemoryBootLevel = 0; - pr_err("[powerplay] VBIOS did not find boot " - "engine clock value in dependency table." - "Using Memory DPM level 0 !"); - result = 0; - } - - table->BootVoltage.Vddc = - phm_get_voltage_id(&(data->vddc_voltage_table), - data->vbios_boot_state.vddc_bootup_value); - table->BootVoltage.VddGfx = - phm_get_voltage_id(&(data->vddgfx_voltage_table), - data->vbios_boot_state.vddgfx_bootup_value); - table->BootVoltage.Vddci = - phm_get_voltage_id(&(data->vddci_voltage_table), - data->vbios_boot_state.vddci_bootup_value); - table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value; - - CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd); - - return result; -} - -static int tonga_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) -{ - uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks, - volt_with_cks, value; - uint16_t clock_freq_u16; - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2, - volt_offset = 0; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = - table_info->vdd_dep_on_sclk; - uint32_t hw_revision, dev_id; - struct cgs_system_info sys_info = {0}; - - stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount; - - sys_info.size = sizeof(struct cgs_system_info); - - sys_info.info_id = CGS_SYSTEM_INFO_PCIE_REV; - cgs_query_system_info(hwmgr->device, &sys_info); - hw_revision = (uint32_t)sys_info.value; - - sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; - cgs_query_system_info(hwmgr->device, &sys_info); - dev_id = (uint32_t)sys_info.value; - - /* Read SMU_Eefuse to read and calculate RO and determine - * if the part is SS or FF. if RO >= 1660MHz, part is FF. - */ - efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixSMU_EFUSE_0 + (146 * 4)); - efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixSMU_EFUSE_0 + (148 * 4)); - efuse &= 0xFF000000; - efuse = efuse >> 24; - efuse2 &= 0xF; - - if (efuse2 == 1) - ro = (2300 - 1350) * efuse / 255 + 1350; - else - ro = (2500 - 1000) * efuse / 255 + 1000; - - if (ro >= 1660) - type = 0; - else - type = 1; - - /* Populate Stretch amount */ - smu_data->smc_state_table.ClockStretcherAmount = stretch_amount; - - - /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ - for (i = 0; i < sclk_table->count; i++) { - smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= - sclk_table->entries[i].cks_enable << i; - if (ASICID_IS_TONGA_P(dev_id, hw_revision)) { - volt_without_cks = (uint32_t)((7732 + 60 - ro - 20838 * - (sclk_table->entries[i].clk/100) / 10000) * 1000 / - (8730 - (5301 * (sclk_table->entries[i].clk/100) / 1000))); - volt_with_cks = (uint32_t)((5250 + 51 - ro - 2404 * - (sclk_table->entries[i].clk/100) / 100000) * 1000 / - (6146 - (3193 * (sclk_table->entries[i].clk/100) / 1000))); - } else { - volt_without_cks = (uint32_t)((14041 * - (sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 / - (4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000))); - volt_with_cks = (uint32_t)((13946 * - (sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 / - (3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000))); - } - if (volt_without_cks >= volt_with_cks) - volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + - sclk_table->entries[i].cks_voffset) * 100 / 625) + 1); - smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; - } - - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - STRETCH_ENABLE, 0x0); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - masterReset, 0x1); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - staticEnable, 0x1); - PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, - masterReset, 0x0); - - /* Populate CKS Lookup Table */ - if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) - stretch_amount2 = 0; - else if (stretch_amount == 3 || stretch_amount == 4) - stretch_amount2 = 1; - else { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ClockStretcher); - PP_ASSERT_WITH_CODE(false, - "Stretch Amount in PPTable not supported\n", - return -EINVAL); - } - - value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixPWR_CKS_CNTL); - value &= 0xFFC2FF87; - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq = - tonga_clock_stretcher_lookup_table[stretch_amount2][0]; - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq = - tonga_clock_stretcher_lookup_table[stretch_amount2][1]; - clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(smu_data->smc_state_table. - GraphicsLevel[smu_data->smc_state_table.GraphicsDpmLevelCount - 1]. - SclkFrequency) / 100); - if (tonga_clock_stretcher_lookup_table[stretch_amount2][0] < - clock_freq_u16 && - tonga_clock_stretcher_lookup_table[stretch_amount2][1] > - clock_freq_u16) { - /* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */ - value |= (tonga_clock_stretcher_lookup_table[stretch_amount2][3]) << 16; - /* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */ - value |= (tonga_clock_stretcher_lookup_table[stretch_amount2][2]) << 18; - /* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */ - value |= (tonga_clock_stretch_amount_conversion - [tonga_clock_stretcher_lookup_table[stretch_amount2][3]] - [stretch_amount]) << 3; - } - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. - CKS_LOOKUPTableEntry[0].minFreq); - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. - CKS_LOOKUPTableEntry[0].maxFreq); - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting = - tonga_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F; - smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |= - (tonga_clock_stretcher_lookup_table[stretch_amount2][3]) << 7; - - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixPWR_CKS_CNTL, value); - - /* Populate DDT Lookup Table */ - for (i = 0; i < 4; i++) { - /* Assign the minimum and maximum VID stored - * in the last row of Clock Stretcher Voltage Table. - */ - smu_data->smc_state_table.ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].minVID = - (uint8_t) tonga_clock_stretcher_ddt_table[type][i][2]; - smu_data->smc_state_table.ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].maxVID = - (uint8_t) tonga_clock_stretcher_ddt_table[type][i][3]; - /* Loop through each SCLK and check the frequency - * to see if it lies within the frequency for clock stretcher. - */ - for (j = 0; j < smu_data->smc_state_table.GraphicsDpmLevelCount; j++) { - cks_setting = 0; - clock_freq = PP_SMC_TO_HOST_UL( - smu_data->smc_state_table.GraphicsLevel[j].SclkFrequency); - /* Check the allowed frequency against the sclk level[j]. - * Sclk's endianness has already been converted, - * and it's in 10Khz unit, - * as opposed to Data table, which is in Mhz unit. - */ - if (clock_freq >= tonga_clock_stretcher_ddt_table[type][i][0] * 100) { - cks_setting |= 0x2; - if (clock_freq < tonga_clock_stretcher_ddt_table[type][i][1] * 100) - cks_setting |= 0x1; - } - smu_data->smc_state_table.ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].setting |= cks_setting << (j * 2); - } - CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table. - ClockStretcherDataTable. - ClockStretcherDataTableEntry[i].setting); - } - - value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixPWR_CKS_CNTL); - value &= 0xFFFFFFFE; - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixPWR_CKS_CNTL, value); - - return 0; -} - -/** - * Populates the SMC VRConfig field in DPM table. - * - * @param hwmgr the address of the hardware manager - * @param table the SMC DPM table structure to be populated - * @return always 0 - */ -static int tonga_populate_vr_config(struct pp_hwmgr *hwmgr, - SMU72_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint16_t config; - - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_gfx_control) { - /* Splitted mode */ - config = VR_SVI2_PLANE_1; - table->VRConfig |= (config<voltage_control) { - config = VR_SVI2_PLANE_2; - table->VRConfig |= config; - } else { - pr_err("VDDC and VDDGFX should " - "be both on SVI2 control in splitted mode !\n"); - } - } else { - /* Merged mode */ - config = VR_MERGED_WITH_VDDC; - table->VRConfig |= (config<voltage_control) { - config = VR_SVI2_PLANE_1; - table->VRConfig |= config; - } else { - pr_err("VDDC should be on " - "SVI2 control in merged mode !\n"); - } - } - - /* Set Vddci Voltage Controller */ - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { - config = VR_SVI2_PLANE_2; /* only in merged mode */ - table->VRConfig |= (config<vddci_control) { - config = VR_SMIO_PATTERN_1; - table->VRConfig |= (config<mvdd_control) { - config = VR_SMIO_PATTERN_2; - table->VRConfig |= (config<smu_backend); - uint32_t tmp; - int result; - - /* - * This is a read-modify-write on the first byte of the ARB table. - * The first byte in the SMU72_Discrete_MCArbDramTimingTable structure - * is the field 'current'. - * This solution is ugly, but we never write the whole table only - * individual fields in it. - * In reality this field should not be in that structure - * but in a soft register. - */ - result = smu7_read_smc_sram_dword(hwmgr, - smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END); - - if (result != 0) - return result; - - tmp &= 0x00FFFFFF; - tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; - - return smu7_write_smc_sram_dword(hwmgr, - smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END); -} - - -static int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; - SMU72_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; - int i, j, k; - const uint16_t *pdef1, *pdef2; - - dpm_table->DefaultTdp = PP_HOST_TO_SMC_US( - (uint16_t)(cac_dtp_table->usTDP * 256)); - dpm_table->TargetTdp = PP_HOST_TO_SMC_US( - (uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); - - PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, - "Target Operating Temp is out of Range !", - ); - - dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp); - dpm_table->GpuTjHyst = 8; - - dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; - - dpm_table->BAPM_TEMP_GRADIENT = - PP_HOST_TO_SMC_UL(defaults->bapm_temp_gradient); - pdef1 = defaults->bapmti_r; - pdef2 = defaults->bapmti_rc; - - for (i = 0; i < SMU72_DTE_ITERATIONS; i++) { - for (j = 0; j < SMU72_DTE_SOURCES; j++) { - for (k = 0; k < SMU72_DTE_SINKS; k++) { - dpm_table->BAPMTI_R[i][j][k] = - PP_HOST_TO_SMC_US(*pdef1); - dpm_table->BAPMTI_RC[i][j][k] = - PP_HOST_TO_SMC_US(*pdef2); - pdef1++; - pdef2++; - } - } - } - - return 0; -} - -static int tonga_populate_svi_load_line(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; - - smu_data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; - smu_data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddC; - smu_data->power_tune_table.SviLoadLineTrimVddC = 3; - smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; - - return 0; -} - -static int tonga_populate_tdc_limit(struct pp_hwmgr *hwmgr) -{ - uint16_t tdc_limit; - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - /* TDC number of fraction bits are changed from 8 to 7 - * for Fiji as requested by SMC team - */ - tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 256); - smu_data->power_tune_table.TDC_VDDC_PkgLimit = - CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); - smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = - defaults->tdc_vddc_throttle_release_limit_perc; - smu_data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; - - return 0; -} - -static int tonga_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; - uint32_t temp; - - if (smu7_read_smc_sram_dword(hwmgr, - fuse_table_offset + - offsetof(SMU72_Discrete_PmFuses, TdcWaterfallCtl), - (uint32_t *)&temp, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to read PmFuses.DW6 " - "(SviLoadLineEn) from SMC Failed !", - return -EINVAL); - else - smu_data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; - - return 0; -} - -static int tonga_populate_temperature_scaler(struct pp_hwmgr *hwmgr) -{ - int i; - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - - /* Currently not used. Set all to zero. */ - for (i = 0; i < 16; i++) - smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0; - - return 0; -} - -static int tonga_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - - if ((hwmgr->thermal_controller.advanceFanControlParameters. - usFanOutputSensitivity & (1 << 15)) || - (hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity == 0)) - hwmgr->thermal_controller.advanceFanControlParameters. - usFanOutputSensitivity = hwmgr->thermal_controller. - advanceFanControlParameters.usDefaultFanOutputSensitivity; - - smu_data->power_tune_table.FuzzyFan_PwmSetDelta = - PP_HOST_TO_SMC_US(hwmgr->thermal_controller. - advanceFanControlParameters.usFanOutputSensitivity); - return 0; -} - -static int tonga_populate_gnb_lpml(struct pp_hwmgr *hwmgr) -{ - int i; - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - - /* Currently not used. Set all to zero. */ - for (i = 0; i < 16; i++) - smu_data->power_tune_table.GnbLPML[i] = 0; - - return 0; -} - -static int tonga_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint16_t hi_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; - uint16_t lo_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; - struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; - - hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); - lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); - - smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = - CONVERT_FROM_HOST_TO_SMC_US(hi_sidd); - smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = - CONVERT_FROM_HOST_TO_SMC_US(lo_sidd); - - return 0; -} - -static int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - uint32_t pm_fuse_table_offset; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment)) { - if (smu7_read_smc_sram_dword(hwmgr, - SMU72_FIRMWARE_HEADER_LOCATION + - offsetof(SMU72_Firmware_Header, PmFuseTable), - &pm_fuse_table_offset, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to get pm_fuse_table_offset Failed !", - return -EINVAL); - - /* DW6 */ - if (tonga_populate_svi_load_line(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate SviLoadLine Failed !", - return -EINVAL); - /* DW7 */ - if (tonga_populate_tdc_limit(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TDCLimit Failed !", - return -EINVAL); - /* DW8 */ - if (tonga_populate_dw8(hwmgr, pm_fuse_table_offset)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TdcWaterfallCtl Failed !", - return -EINVAL); - - /* DW9-DW12 */ - if (tonga_populate_temperature_scaler(hwmgr) != 0) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate LPMLTemperatureScaler Failed !", - return -EINVAL); - - /* DW13-DW14 */ - if (tonga_populate_fuzzy_fan(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate Fuzzy Fan " - "Control parameters Failed !", - return -EINVAL); - - /* DW15-DW18 */ - if (tonga_populate_gnb_lpml(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate GnbLPML Failed !", - return -EINVAL); - - /* DW20 */ - if (tonga_populate_bapm_vddc_base_leakage_sidd(hwmgr)) - PP_ASSERT_WITH_CODE( - false, - "Attempt to populate BapmVddCBaseLeakage " - "Hi and Lo Sidd Failed !", - return -EINVAL); - - if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, - (uint8_t *)&smu_data->power_tune_table, - sizeof(struct SMU72_Discrete_PmFuses), SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to download PmFuseTable Failed !", - return -EINVAL); - } - return 0; -} - -static int tonga_populate_mc_reg_address(struct pp_hwmgr *hwmgr, - SMU72_Discrete_MCRegisters *mc_reg_table) -{ - const struct tonga_smumgr *smu_data = (struct tonga_smumgr *)hwmgr->smu_backend; - - uint32_t i, j; - - for (i = 0, j = 0; j < smu_data->mc_reg_table.last; j++) { - if (smu_data->mc_reg_table.validflag & 1<address[] array " - "out of boundary", - return -EINVAL); - mc_reg_table->address[i].s0 = - PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s0); - mc_reg_table->address[i].s1 = - PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s1); - i++; - } - } - - mc_reg_table->last = (uint8_t)i; - - return 0; -} - -/*convert register values from driver to SMC format */ -static void tonga_convert_mc_registers( - const struct tonga_mc_reg_entry *entry, - SMU72_Discrete_MCRegisterSet *data, - uint32_t num_entries, uint32_t valid_flag) -{ - uint32_t i, j; - - for (i = 0, j = 0; j < num_entries; j++) { - if (valid_flag & 1<value[i] = PP_HOST_TO_SMC_UL(entry->mc_data[j]); - i++; - } - } -} - -static int tonga_convert_mc_reg_table_entry_to_smc( - struct pp_hwmgr *hwmgr, - const uint32_t memory_clock, - SMU72_Discrete_MCRegisterSet *mc_reg_table_data - ) -{ - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - uint32_t i = 0; - - for (i = 0; i < smu_data->mc_reg_table.num_entries; i++) { - if (memory_clock <= - smu_data->mc_reg_table.mc_reg_table_entry[i].mclk_max) { - break; - } - } - - if ((i == smu_data->mc_reg_table.num_entries) && (i > 0)) - --i; - - tonga_convert_mc_registers(&smu_data->mc_reg_table.mc_reg_table_entry[i], - mc_reg_table_data, smu_data->mc_reg_table.last, - smu_data->mc_reg_table.validflag); - - return 0; -} - -static int tonga_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr, - SMU72_Discrete_MCRegisters *mc_regs) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - int res; - uint32_t i; - - for (i = 0; i < data->dpm_table.mclk_table.count; i++) { - res = tonga_convert_mc_reg_table_entry_to_smc( - hwmgr, - data->dpm_table.mclk_table.dpm_levels[i].value, - &mc_regs->data[i] - ); - - if (0 != res) - result = res; - } - - return result; -} - -static int tonga_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t address; - int32_t result; - - if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) - return 0; - - - memset(&smu_data->mc_regs, 0, sizeof(SMU72_Discrete_MCRegisters)); - - result = tonga_convert_mc_reg_table_to_smc(hwmgr, &(smu_data->mc_regs)); - - if (result != 0) - return result; - - - address = smu_data->smu7_data.mc_reg_table_start + - (uint32_t)offsetof(SMU72_Discrete_MCRegisters, data[0]); - - return smu7_copy_bytes_to_smc( - hwmgr, address, - (uint8_t *)&smu_data->mc_regs.data[0], - sizeof(SMU72_Discrete_MCRegisterSet) * - data->dpm_table.mclk_table.count, - SMC_RAM_END); -} - -static int tonga_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - - memset(&smu_data->mc_regs, 0x00, sizeof(SMU72_Discrete_MCRegisters)); - result = tonga_populate_mc_reg_address(hwmgr, &(smu_data->mc_regs)); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize MCRegTable for the MC register addresses !", - return result;); - - result = tonga_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize MCRegTable for driver state !", - return result;); - - return smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.mc_reg_table_start, - (uint8_t *)&smu_data->mc_regs, sizeof(SMU72_Discrete_MCRegisters), SMC_RAM_END); -} - -static void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - if (table_info && - table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && - table_info->cac_dtp_table->usPowerTuneDataSetID) - smu_data->power_tune_defaults = - &tonga_power_tune_data_set_array - [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; - else - smu_data->power_tune_defaults = &tonga_power_tune_data_set_array[0]; -} - -static void tonga_save_default_power_profile(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *data = (struct tonga_smumgr *)(hwmgr->smu_backend); - struct SMU72_Discrete_GraphicsLevel *levels = - data->smc_state_table.GraphicsLevel; - unsigned min_level = 1; - - hwmgr->default_gfx_power_profile.activity_threshold = - be16_to_cpu(levels[0].ActivityLevel); - hwmgr->default_gfx_power_profile.up_hyst = levels[0].UpHyst; - hwmgr->default_gfx_power_profile.down_hyst = levels[0].DownHyst; - hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE; - - hwmgr->default_compute_power_profile = hwmgr->default_gfx_power_profile; - hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE; - - /* Workaround compute SDMA instability: disable lowest SCLK - * DPM level. Optimize compute power profile: Use only highest - * 2 power levels (if more than 2 are available), Hysteresis: - * 0ms up, 5ms down - */ - if (data->smc_state_table.GraphicsDpmLevelCount > 2) - min_level = data->smc_state_table.GraphicsDpmLevelCount - 2; - else if (data->smc_state_table.GraphicsDpmLevelCount == 2) - min_level = 1; - else - min_level = 0; - hwmgr->default_compute_power_profile.min_sclk = - be32_to_cpu(levels[min_level].SclkFrequency); - hwmgr->default_compute_power_profile.up_hyst = 0; - hwmgr->default_compute_power_profile.down_hyst = 5; - - hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile; - hwmgr->compute_power_profile = hwmgr->default_compute_power_profile; -} - -/** - * Initializes the SMC table and uploads it - * - * @param hwmgr the address of the powerplay hardware manager. - * @param pInput the pointer to input data (PowerState) - * @return always 0 - */ -int tonga_init_smc_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - SMU72_Discrete_DpmTable *table = &(smu_data->smc_state_table); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - uint8_t i; - pp_atomctrl_gpio_pin_assignment gpio_pin_assignment; - - - memset(&(smu_data->smc_state_table), 0x00, sizeof(smu_data->smc_state_table)); - - tonga_initialize_power_tune_defaults(hwmgr); - - if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) - tonga_populate_smc_voltage_tables(hwmgr, table); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; - - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StepVddc)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; - - if (data->is_memory_gddr5) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; - - i = PHM_READ_FIELD(hwmgr->device, CC_MC_MAX_CHANNEL, NOOFCHAN); - - if (i == 1 || i == 0) - table->SystemFlags |= 0x40; - - if (data->ulv_supported && table_info->us_ulv_voltage_offset) { - result = tonga_populate_ulv_state(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize ULV state !", - return result;); - - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixCG_ULV_PARAMETER, 0x40035); - } - - result = tonga_populate_smc_link_level(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize Link Level !", return result); - - result = tonga_populate_all_graphic_levels(hwmgr); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize Graphics Level !", return result); - - result = tonga_populate_all_memory_levels(hwmgr); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize Memory Level !", return result); - - result = tonga_populate_smc_acpi_level(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize ACPI Level !", return result); - - result = tonga_populate_smc_vce_level(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize VCE Level !", return result); - - result = tonga_populate_smc_acp_level(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize ACP Level !", return result); - - result = tonga_populate_smc_samu_level(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize SAMU Level !", return result); - - /* Since only the initial state is completely set up at this - * point (the other states are just copies of the boot state) we only - * need to populate the ARB settings for the initial state. - */ - result = tonga_program_memory_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE(!result, - "Failed to Write ARB settings for the initial state.", - return result;); - - result = tonga_populate_smc_uvd_level(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize UVD Level !", return result); - - result = tonga_populate_smc_boot_level(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to initialize Boot Level !", return result); - - tonga_populate_bapm_parameters_in_dpm_table(hwmgr); - PP_ASSERT_WITH_CODE(!result, - "Failed to populate BAPM Parameters !", return result); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ClockStretcher)) { - result = tonga_populate_clock_stretcher_data_table(hwmgr); - PP_ASSERT_WITH_CODE(!result, - "Failed to populate Clock Stretcher Data Table !", - return result;); - } - table->GraphicsVoltageChangeEnable = 1; - table->GraphicsThermThrottleEnable = 1; - table->GraphicsInterval = 1; - table->VoltageInterval = 1; - table->ThermalInterval = 1; - table->TemperatureLimitHigh = - table_info->cac_dtp_table->usTargetOperatingTemp * - SMU7_Q88_FORMAT_CONVERSION_UNIT; - table->TemperatureLimitLow = - (table_info->cac_dtp_table->usTargetOperatingTemp - 1) * - SMU7_Q88_FORMAT_CONVERSION_UNIT; - table->MemoryVoltageChangeEnable = 1; - table->MemoryInterval = 1; - table->VoltageResponseTime = 0; - table->PhaseResponseTime = 0; - table->MemoryThermThrottleEnable = 1; - - /* - * Cail reads current link status and reports it as cap (we cannot - * change this due to some previous issues we had) - * SMC drops the link status to lowest level after enabling - * DPM by PowerPlay. After pnp or toggling CF, driver gets reloaded again - * but this time Cail reads current link status which was set to low by - * SMC and reports it as cap to powerplay - * To avoid it, we set PCIeBootLinkLevel to highest dpm level - */ - PP_ASSERT_WITH_CODE((1 <= data->dpm_table.pcie_speed_table.count), - "There must be 1 or more PCIE levels defined in PPTable.", - return -EINVAL); - - table->PCIeBootLinkLevel = (uint8_t) (data->dpm_table.pcie_speed_table.count); - - table->PCIeGenInterval = 1; - - result = tonga_populate_vr_config(hwmgr, table); - PP_ASSERT_WITH_CODE(!result, - "Failed to populate VRConfig setting !", return result); - - table->ThermGpio = 17; - table->SclkStepSize = 0x4000; - - if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, - &gpio_pin_assignment)) { - table->VRHotGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot); - } else { - table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot); - } - - if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID, - &gpio_pin_assignment)) { - table->AcDcGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition); - } else { - table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition); - } - - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_Falcon_QuickTransition); - - if (0) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition); - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_Falcon_QuickTransition); - } - - if (atomctrl_get_pp_assign_pin(hwmgr, - THERMAL_INT_OUTPUT_GPIO_PINID, &gpio_pin_assignment)) { - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ThermalOutGPIO); - - table->ThermOutGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; - - table->ThermOutPolarity = - (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) & - (1 << gpio_pin_assignment.uc_gpio_pin_bit_shift))) ? 1 : 0; - - table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY; - - /* if required, combine VRHot/PCC with thermal out GPIO*/ - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot) && - phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_CombinePCCWithThermalSignal)){ - table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT; - } - } else { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ThermalOutGPIO); - - table->ThermOutGpio = 17; - table->ThermOutPolarity = 1; - table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE; - } - - for (i = 0; i < SMU72_MAX_ENTRIES_SMIO; i++) - table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]); - - CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); - CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2); - CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); - CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); - CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); - - /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.dpm_table_start + offsetof(SMU72_Discrete_DpmTable, SystemFlags), - (uint8_t *)&(table->SystemFlags), - sizeof(SMU72_Discrete_DpmTable) - 3 * sizeof(SMU72_PIDController), - SMC_RAM_END); - - PP_ASSERT_WITH_CODE(!result, - "Failed to upload dpm data to SMC memory !", return result;); - - result = tonga_init_arb_table_index(hwmgr); - PP_ASSERT_WITH_CODE(!result, - "Failed to upload arb data to SMC memory !", return result); - - tonga_populate_pm_fuses(hwmgr); - PP_ASSERT_WITH_CODE((!result), - "Failed to populate initialize pm fuses !", return result); - - result = tonga_populate_initial_mc_reg_table(hwmgr); - PP_ASSERT_WITH_CODE((!result), - "Failed to populate initialize MC Reg table !", return result); - - tonga_save_default_power_profile(hwmgr); - - return 0; -} - -/** -* Set up the fan table to control the fan using the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ -int tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - SMU72_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; - uint32_t duty100; - uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; - uint16_t fdo_min, slope1, slope2; - uint32_t reference_clock; - int res; - uint64_t tmp64; - - if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl)) - return 0; - - if (hwmgr->thermal_controller.fanInfo.bNoFan) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - if (0 == smu_data->smu7_data.fan_table_start) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, - CGS_IND_REG__SMC, - CG_FDO_CTRL1, FMAX_DUTY100); - - if (0 == duty100) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100; - do_div(tmp64, 10000); - fdo_min = (uint16_t)tmp64; - - t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - - hwmgr->thermal_controller.advanceFanControlParameters.usTMin; - t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - - hwmgr->thermal_controller.advanceFanControlParameters.usTMed; - - pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; - pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; - - slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); - slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); - - fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100); - fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100); - fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100); - - fan_table.Slope1 = cpu_to_be16(slope1); - fan_table.Slope2 = cpu_to_be16(slope2); - - fan_table.FdoMin = cpu_to_be16(fdo_min); - - fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst); - - fan_table.HystUp = cpu_to_be16(1); - - fan_table.HystSlope = cpu_to_be16(1); - - fan_table.TempRespLim = cpu_to_be16(5); - - reference_clock = smu7_get_xclk(hwmgr); - - fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600); - - fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); - - fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL); - - fan_table.FanControl_GL_Flag = 1; - - res = smu7_copy_bytes_to_smc(hwmgr, - smu_data->smu7_data.fan_table_start, - (uint8_t *)&fan_table, - (uint32_t)sizeof(fan_table), - SMC_RAM_END); - - return 0; -} - - -static int tonga_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (data->need_update_smu7_dpm_table & - (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) - return tonga_program_memory_timing_parameters(hwmgr); - - return 0; -} - -int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - - int result = 0; - uint32_t low_sclk_interrupt_threshold = 0; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkThrottleLowNotification) - && (hwmgr->gfx_arbiter.sclk_threshold != - data->low_sclk_interrupt_threshold)) { - data->low_sclk_interrupt_threshold = - hwmgr->gfx_arbiter.sclk_threshold; - low_sclk_interrupt_threshold = - data->low_sclk_interrupt_threshold; - - CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); - - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.dpm_table_start + - offsetof(SMU72_Discrete_DpmTable, - LowSclkInterruptThreshold), - (uint8_t *)&low_sclk_interrupt_threshold, - sizeof(uint32_t), - SMC_RAM_END); - } - - result = tonga_update_and_upload_mc_reg_table(hwmgr); - - PP_ASSERT_WITH_CODE((!result), - "Failed to upload MC reg table !", - return result); - - result = tonga_program_mem_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE((result == 0), - "Failed to program memory timing parameters !", - ); - - return result; -} - -uint32_t tonga_get_offsetof(uint32_t type, uint32_t member) -{ - switch (type) { - case SMU_SoftRegisters: - switch (member) { - case HandshakeDisables: - return offsetof(SMU72_SoftRegisters, HandshakeDisables); - case VoltageChangeTimeout: - return offsetof(SMU72_SoftRegisters, VoltageChangeTimeout); - case AverageGraphicsActivity: - return offsetof(SMU72_SoftRegisters, AverageGraphicsActivity); - case PreVBlankGap: - return offsetof(SMU72_SoftRegisters, PreVBlankGap); - case VBlankTimeout: - return offsetof(SMU72_SoftRegisters, VBlankTimeout); - case UcodeLoadStatus: - return offsetof(SMU72_SoftRegisters, UcodeLoadStatus); - case DRAM_LOG_ADDR_H: - return offsetof(SMU72_SoftRegisters, DRAM_LOG_ADDR_H); - case DRAM_LOG_ADDR_L: - return offsetof(SMU72_SoftRegisters, DRAM_LOG_ADDR_L); - case DRAM_LOG_PHY_ADDR_H: - return offsetof(SMU72_SoftRegisters, DRAM_LOG_PHY_ADDR_H); - case DRAM_LOG_PHY_ADDR_L: - return offsetof(SMU72_SoftRegisters, DRAM_LOG_PHY_ADDR_L); - case DRAM_LOG_BUFF_SIZE: - return offsetof(SMU72_SoftRegisters, DRAM_LOG_BUFF_SIZE); - } - case SMU_Discrete_DpmTable: - switch (member) { - case UvdBootLevel: - return offsetof(SMU72_Discrete_DpmTable, UvdBootLevel); - case VceBootLevel: - return offsetof(SMU72_Discrete_DpmTable, VceBootLevel); - case SamuBootLevel: - return offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); - case LowSclkInterruptThreshold: - return offsetof(SMU72_Discrete_DpmTable, LowSclkInterruptThreshold); - } - } - pr_warn("can't get the offset of type %x member %x\n", type, member); - return 0; -} - -uint32_t tonga_get_mac_definition(uint32_t value) -{ - switch (value) { - case SMU_MAX_LEVELS_GRAPHICS: - return SMU72_MAX_LEVELS_GRAPHICS; - case SMU_MAX_LEVELS_MEMORY: - return SMU72_MAX_LEVELS_MEMORY; - case SMU_MAX_LEVELS_LINK: - return SMU72_MAX_LEVELS_LINK; - case SMU_MAX_ENTRIES_SMIO: - return SMU72_MAX_ENTRIES_SMIO; - case SMU_MAX_LEVELS_VDDC: - return SMU72_MAX_LEVELS_VDDC; - case SMU_MAX_LEVELS_VDDGFX: - return SMU72_MAX_LEVELS_VDDGFX; - case SMU_MAX_LEVELS_VDDCI: - return SMU72_MAX_LEVELS_VDDCI; - case SMU_MAX_LEVELS_MVDD: - return SMU72_MAX_LEVELS_MVDD; - } - pr_warn("can't get the mac value %x\n", value); - - return 0; -} - - -static int tonga_update_uvd_smc_table(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - smu_data->smc_state_table.UvdBootLevel = 0; - if (table_info->mm_dep_table->count > 0) - smu_data->smc_state_table.UvdBootLevel = - (uint8_t) (table_info->mm_dep_table->count - 1); - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + - offsetof(SMU72_Discrete_DpmTable, UvdBootLevel); - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0x00FFFFFF; - mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, - mm_boot_level_offset, mm_boot_level_value); - - if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_UVDDPM) || - phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_UVDDPM_SetEnabledMask, - (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel)); - return 0; -} - -static int tonga_update_vce_smc_table(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = - (struct tonga_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - - smu_data->smc_state_table.VceBootLevel = - (uint8_t) (table_info->mm_dep_table->count - 1); - - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + - offsetof(SMU72_Discrete_DpmTable, VceBootLevel); - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0xFF00FFFF; - mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_VCEDPM_SetEnabledMask, - (uint32_t)1 << smu_data->smc_state_table.VceBootLevel); - return 0; -} - -static int tonga_update_samu_smc_table(struct pp_hwmgr *hwmgr) -{ - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - - smu_data->smc_state_table.SamuBootLevel = 0; - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + - offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); - - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0xFFFFFF00; - mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SAMUDPM_SetEnabledMask, - (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); - return 0; -} - -int tonga_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) -{ - switch (type) { - case SMU_UVD_TABLE: - tonga_update_uvd_smc_table(hwmgr); - break; - case SMU_VCE_TABLE: - tonga_update_vce_smc_table(hwmgr); - break; - case SMU_SAMU_TABLE: - tonga_update_samu_smc_table(hwmgr); - break; - default: - break; - } - return 0; -} - - -/** - * Get the location of various tables inside the FW image. - * - * @param hwmgr the address of the powerplay hardware manager. - * @return always 0 - */ -int tonga_process_firmware_header(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); - - uint32_t tmp; - int result; - bool error = false; - - result = smu7_read_smc_sram_dword(hwmgr, - SMU72_FIRMWARE_HEADER_LOCATION + - offsetof(SMU72_Firmware_Header, DpmTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.dpm_table_start = tmp; - - error |= (result != 0); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU72_FIRMWARE_HEADER_LOCATION + - offsetof(SMU72_Firmware_Header, SoftRegisters), - &tmp, SMC_RAM_END); - - if (!result) { - data->soft_regs_start = tmp; - smu_data->smu7_data.soft_regs_start = tmp; - } - - error |= (result != 0); - - - result = smu7_read_smc_sram_dword(hwmgr, - SMU72_FIRMWARE_HEADER_LOCATION + - offsetof(SMU72_Firmware_Header, mcRegisterTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.mc_reg_table_start = tmp; - - result = smu7_read_smc_sram_dword(hwmgr, - SMU72_FIRMWARE_HEADER_LOCATION + - offsetof(SMU72_Firmware_Header, FanTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.fan_table_start = tmp; - - error |= (result != 0); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU72_FIRMWARE_HEADER_LOCATION + - offsetof(SMU72_Firmware_Header, mcArbDramTimingTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.arb_table_start = tmp; - - error |= (result != 0); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU72_FIRMWARE_HEADER_LOCATION + - offsetof(SMU72_Firmware_Header, Version), - &tmp, SMC_RAM_END); - - if (!result) - hwmgr->microcode_version_info.SMC = tmp; - - error |= (result != 0); - - return error ? 1 : 0; -} - -/*---------------------------MC----------------------------*/ - -static uint8_t tonga_get_memory_modile_index(struct pp_hwmgr *hwmgr) -{ - return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16)); -} - -static bool tonga_check_s0_mc_reg_index(uint16_t in_reg, uint16_t *out_reg) -{ - bool result = true; - - switch (in_reg) { - case mmMC_SEQ_RAS_TIMING: - *out_reg = mmMC_SEQ_RAS_TIMING_LP; - break; - - case mmMC_SEQ_DLL_STBY: - *out_reg = mmMC_SEQ_DLL_STBY_LP; - break; - - case mmMC_SEQ_G5PDX_CMD0: - *out_reg = mmMC_SEQ_G5PDX_CMD0_LP; - break; - - case mmMC_SEQ_G5PDX_CMD1: - *out_reg = mmMC_SEQ_G5PDX_CMD1_LP; - break; - - case mmMC_SEQ_G5PDX_CTRL: - *out_reg = mmMC_SEQ_G5PDX_CTRL_LP; - break; - - case mmMC_SEQ_CAS_TIMING: - *out_reg = mmMC_SEQ_CAS_TIMING_LP; - break; - - case mmMC_SEQ_MISC_TIMING: - *out_reg = mmMC_SEQ_MISC_TIMING_LP; - break; - - case mmMC_SEQ_MISC_TIMING2: - *out_reg = mmMC_SEQ_MISC_TIMING2_LP; - break; - - case mmMC_SEQ_PMG_DVS_CMD: - *out_reg = mmMC_SEQ_PMG_DVS_CMD_LP; - break; - - case mmMC_SEQ_PMG_DVS_CTL: - *out_reg = mmMC_SEQ_PMG_DVS_CTL_LP; - break; - - case mmMC_SEQ_RD_CTL_D0: - *out_reg = mmMC_SEQ_RD_CTL_D0_LP; - break; - - case mmMC_SEQ_RD_CTL_D1: - *out_reg = mmMC_SEQ_RD_CTL_D1_LP; - break; - - case mmMC_SEQ_WR_CTL_D0: - *out_reg = mmMC_SEQ_WR_CTL_D0_LP; - break; - - case mmMC_SEQ_WR_CTL_D1: - *out_reg = mmMC_SEQ_WR_CTL_D1_LP; - break; - - case mmMC_PMG_CMD_EMRS: - *out_reg = mmMC_SEQ_PMG_CMD_EMRS_LP; - break; - - case mmMC_PMG_CMD_MRS: - *out_reg = mmMC_SEQ_PMG_CMD_MRS_LP; - break; - - case mmMC_PMG_CMD_MRS1: - *out_reg = mmMC_SEQ_PMG_CMD_MRS1_LP; - break; - - case mmMC_SEQ_PMG_TIMING: - *out_reg = mmMC_SEQ_PMG_TIMING_LP; - break; - - case mmMC_PMG_CMD_MRS2: - *out_reg = mmMC_SEQ_PMG_CMD_MRS2_LP; - break; - - case mmMC_SEQ_WR_CTL_2: - *out_reg = mmMC_SEQ_WR_CTL_2_LP; - break; - - default: - result = false; - break; - } - - return result; -} - -static int tonga_set_s0_mc_reg_index(struct tonga_mc_reg_table *table) -{ - uint32_t i; - uint16_t address; - - for (i = 0; i < table->last; i++) { - table->mc_reg_address[i].s0 = - tonga_check_s0_mc_reg_index(table->mc_reg_address[i].s1, - &address) ? - address : - table->mc_reg_address[i].s1; - } - return 0; -} - -static int tonga_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, - struct tonga_mc_reg_table *ni_table) -{ - uint8_t i, j; - - PP_ASSERT_WITH_CODE((table->last <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES), - "Invalid VramInfo table.", return -EINVAL); - - for (i = 0; i < table->last; i++) - ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1; - - ni_table->last = table->last; - - for (i = 0; i < table->num_entries; i++) { - ni_table->mc_reg_table_entry[i].mclk_max = - table->mc_reg_table_entry[i].mclk_max; - for (j = 0; j < table->last; j++) { - ni_table->mc_reg_table_entry[i].mc_data[j] = - table->mc_reg_table_entry[i].mc_data[j]; - } - } - - ni_table->num_entries = table->num_entries; - - return 0; -} - -/** - * VBIOS omits some information to reduce size, we need to recover them here. - * 1. when we see mmMC_SEQ_MISC1, bit[31:16] EMRS1, need to be write to - * mmMC_PMG_CMD_EMRS /_LP[15:0]. Bit[15:0] MRS, need to be update - * mmMC_PMG_CMD_MRS/_LP[15:0] - * 2. when we see mmMC_SEQ_RESERVE_M, bit[15:0] EMRS2, need to be write to - * mmMC_PMG_CMD_MRS1/_LP[15:0]. - * 3. need to set these data for each clock range - * @param hwmgr the address of the powerplay hardware manager. - * @param table the address of MCRegTable - * @return always 0 - */ -static int tonga_set_mc_special_registers(struct pp_hwmgr *hwmgr, - struct tonga_mc_reg_table *table) -{ - uint8_t i, j, k; - uint32_t temp_reg; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - for (i = 0, j = table->last; i < table->last; i++) { - PP_ASSERT_WITH_CODE((j < SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - switch (table->mc_reg_address[i].s1) { - - case mmMC_SEQ_MISC1: - temp_reg = cgs_read_register(hwmgr->device, - mmMC_PMG_CMD_EMRS); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - ((temp_reg & 0xffff0000)) | - ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16); - } - j++; - PP_ASSERT_WITH_CODE((j < SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (temp_reg & 0xffff0000) | - (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); - - if (!data->is_memory_gddr5) - table->mc_reg_table_entry[k].mc_data[j] |= 0x100; - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - - if (!data->is_memory_gddr5) { - table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD; - table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD; - for (k = 0; k < table->num_entries; k++) - table->mc_reg_table_entry[k].mc_data[j] = - (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16; - j++; - PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - } - - break; - - case mmMC_SEQ_RESERVE_M: - temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1); - table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1; - table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP; - for (k = 0; k < table->num_entries; k++) { - table->mc_reg_table_entry[k].mc_data[j] = - (temp_reg & 0xffff0000) | - (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); - } - j++; - PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), - "Invalid VramInfo table.", return -EINVAL); - break; - - default: - break; - } - - } - - table->last = j; - - return 0; -} - -static int tonga_set_valid_flag(struct tonga_mc_reg_table *table) -{ - uint8_t i, j; - - for (i = 0; i < table->last; i++) { - for (j = 1; j < table->num_entries; j++) { - if (table->mc_reg_table_entry[j-1].mc_data[i] != - table->mc_reg_table_entry[j].mc_data[i]) { - table->validflag |= (1<smu_backend); - pp_atomctrl_mc_reg_table *table; - struct tonga_mc_reg_table *ni_table = &smu_data->mc_reg_table; - uint8_t module_index = tonga_get_memory_modile_index(hwmgr); - - table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); - - if (table == NULL) - return -ENOMEM; - - /* Program additional LP registers that are no longer programmed by VBIOS */ - cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL)); - cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, - cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, - cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, - cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); - cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); - cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, - cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2)); - cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, - cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2)); - - memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table)); - - result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); - - if (!result) - result = tonga_copy_vbios_smc_reg_table(table, ni_table); - - if (!result) { - tonga_set_s0_mc_reg_index(ni_table); - result = tonga_set_mc_special_registers(hwmgr, ni_table); - } - - if (!result) - tonga_set_valid_flag(ni_table); - - kfree(table); - - return result; -} - -bool tonga_is_dpm_running(struct pp_hwmgr *hwmgr) -{ - return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, - CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) - ? true : false; -} - -int tonga_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request) -{ - struct tonga_smumgr *smu_data = (struct tonga_smumgr *) - (hwmgr->smu_backend); - struct SMU72_Discrete_GraphicsLevel *levels = - smu_data->smc_state_table.GraphicsLevel; - uint32_t array = smu_data->smu7_data.dpm_table_start + - offsetof(SMU72_Discrete_DpmTable, GraphicsLevel); - uint32_t array_size = sizeof(struct SMU72_Discrete_GraphicsLevel) * - SMU72_MAX_LEVELS_GRAPHICS; - uint32_t i; - - for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { - levels[i].ActivityLevel = - cpu_to_be16(request->activity_threshold); - levels[i].EnabledForActivity = 1; - levels[i].UpHyst = request->up_hyst; - levels[i].DownHyst = request->down_hyst; - } - - return smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - array_size, SMC_RAM_END); -} diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.h b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.h deleted file mode 100644 index 9d6a78a65976..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - */ -#ifndef _TONGA_SMC_H -#define _TONGA_SMC_H - -#include "smumgr.h" -#include "smu72.h" - - -#define ASICID_IS_TONGA_P(wDID, bRID) \ - (((wDID == 0x6930) && ((bRID == 0xF0) || (bRID == 0xF1) || (bRID == 0xFF))) \ - || ((wDID == 0x6920) && ((bRID == 0) || (bRID == 1)))) - - -struct tonga_pt_defaults { - uint8_t svi_load_line_en; - uint8_t svi_load_line_vddC; - uint8_t tdc_vddc_throttle_release_limit_perc; - uint8_t tdc_mawt; - uint8_t tdc_waterfall_ctl; - uint8_t dte_ambient_temp_base; - uint32_t display_cac; - uint32_t bapm_temp_gradient; - uint16_t bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; - uint16_t bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; -}; - -int tonga_populate_all_graphic_levels(struct pp_hwmgr *hwmgr); -int tonga_populate_all_memory_levels(struct pp_hwmgr *hwmgr); -int tonga_init_smc_table(struct pp_hwmgr *hwmgr); -int tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr); -int tonga_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type); -int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr); -uint32_t tonga_get_offsetof(uint32_t type, uint32_t member); -uint32_t tonga_get_mac_definition(uint32_t value); -int tonga_process_firmware_header(struct pp_hwmgr *hwmgr); -int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr); -bool tonga_is_dpm_running(struct pp_hwmgr *hwmgr); -int tonga_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request); -#endif - diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c index d22cf218cf18..0a8e48bff219 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c @@ -33,9 +33,69 @@ #include "smu/smu_7_1_2_d.h" #include "smu/smu_7_1_2_sh_mask.h" #include "cgs_common.h" -#include "tonga_smc.h" #include "smu7_smumgr.h" +#include "smu7_dyn_defaults.h" + +#include "smu7_hwmgr.h" +#include "hardwaremanager.h" +#include "ppatomctrl.h" + +#include "atombios.h" + +#include "pppcielanes.h" +#include "pp_endian.h" + +#include "gmc/gmc_8_1_d.h" +#include "gmc/gmc_8_1_sh_mask.h" + +#include "bif/bif_5_0_d.h" +#include "bif/bif_5_0_sh_mask.h" + +#include "dce/dce_10_0_d.h" +#include "dce/dce_10_0_sh_mask.h" + + +#define VOLTAGE_SCALE 4 +#define POWERTUNE_DEFAULT_SET_MAX 1 +#define VOLTAGE_VID_OFFSET_SCALE1 625 +#define VOLTAGE_VID_OFFSET_SCALE2 100 +#define MC_CG_ARB_FREQ_F1 0x0b +#define VDDC_VDDCI_DELTA 200 + + +static const struct tonga_pt_defaults tonga_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { +/* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, + * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT + */ + {1, 0xF, 0xFD, 0x19, + 5, 45, 0, 0xB0000, + {0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, + 0xC9, 0xC9, 0x2F, 0x4D, 0x61}, + {0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, + 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4} + }, +}; + +/* [Fmin, Fmax, LDO_REFSEL, USE_FOR_LOW_FREQ] */ +static const uint16_t tonga_clock_stretcher_lookup_table[2][4] = { + {600, 1050, 3, 0}, + {600, 1050, 6, 1} +}; + +/* [FF, SS] type, [] 4 voltage ranges, + * and [Floor Freq, Boundary Freq, VID min , VID max] + */ +static const uint32_t tonga_clock_stretcher_ddt_table[2][4][4] = { + { {265, 529, 120, 128}, {325, 650, 96, 119}, {430, 860, 32, 95}, {0, 0, 0, 31} }, + { {275, 550, 104, 112}, {319, 638, 96, 103}, {360, 720, 64, 95}, {384, 768, 32, 63} } +}; + +/* [Use_For_Low_freq] value, [0%, 5%, 10%, 7.14%, 14.28%, 20%] */ +static const uint8_t tonga_clock_stretch_amount_conversion[2][6] = { + {0, 1, 3, 2, 4, 5}, + {0, 2, 4, 5, 6, 5} +}; static int tonga_start_in_protection_mode(struct pp_hwmgr *hwmgr) { @@ -95,7 +155,6 @@ static int tonga_start_in_protection_mode(struct pp_hwmgr *hwmgr) return 0; } - static int tonga_start_in_non_protection_mode(struct pp_hwmgr *hwmgr) { int result = 0; @@ -160,13 +219,6 @@ static int tonga_start_smu(struct pp_hwmgr *hwmgr) return result; } -/** - * Write a 32bit value to the SMC SRAM space. - * ALL PARAMETERS ARE IN HOST BYTE ORDER. - * @param smumgr the address of the powerplay hardware manager. - * @param smcAddress the address in the SMC RAM to access. - * @param value to write to the SMC SRAM. - */ static int tonga_smu_init(struct pp_hwmgr *hwmgr) { struct tonga_smumgr *tonga_priv = NULL; @@ -187,6 +239,3053 @@ static int tonga_smu_init(struct pp_hwmgr *hwmgr) return 0; } + +static int tonga_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, + phm_ppt_v1_clock_voltage_dependency_table *allowed_clock_voltage_table, + uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd) +{ + uint32_t i = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + /* clock - voltage dependency table is empty table */ + if (allowed_clock_voltage_table->count == 0) + return -EINVAL; + + for (i = 0; i < allowed_clock_voltage_table->count; i++) { + /* find first sclk bigger than request */ + if (allowed_clock_voltage_table->entries[i].clk >= clock) { + voltage->VddGfx = phm_get_voltage_index( + pptable_info->vddgfx_lookup_table, + allowed_clock_voltage_table->entries[i].vddgfx); + voltage->Vddc = phm_get_voltage_index( + pptable_info->vddc_lookup_table, + allowed_clock_voltage_table->entries[i].vddc); + + if (allowed_clock_voltage_table->entries[i].vddci) + voltage->Vddci = + phm_get_voltage_id(&data->vddci_voltage_table, allowed_clock_voltage_table->entries[i].vddci); + else + voltage->Vddci = + phm_get_voltage_id(&data->vddci_voltage_table, + allowed_clock_voltage_table->entries[i].vddc - VDDC_VDDCI_DELTA); + + + if (allowed_clock_voltage_table->entries[i].mvdd) + *mvdd = (uint32_t) allowed_clock_voltage_table->entries[i].mvdd; + + voltage->Phases = 1; + return 0; + } + } + + /* sclk is bigger than max sclk in the dependence table */ + voltage->VddGfx = phm_get_voltage_index(pptable_info->vddgfx_lookup_table, + allowed_clock_voltage_table->entries[i-1].vddgfx); + voltage->Vddc = phm_get_voltage_index(pptable_info->vddc_lookup_table, + allowed_clock_voltage_table->entries[i-1].vddc); + + if (allowed_clock_voltage_table->entries[i-1].vddci) + voltage->Vddci = phm_get_voltage_id(&data->vddci_voltage_table, + allowed_clock_voltage_table->entries[i-1].vddci); + + if (allowed_clock_voltage_table->entries[i-1].mvdd) + *mvdd = (uint32_t) allowed_clock_voltage_table->entries[i-1].mvdd; + + return 0; +} + +static int tonga_populate_smc_vddc_table(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + unsigned int count; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) { + table->VddcLevelCount = data->vddc_voltage_table.count; + for (count = 0; count < table->VddcLevelCount; count++) { + table->VddcTable[count] = + PP_HOST_TO_SMC_US(data->vddc_voltage_table.entries[count].value * VOLTAGE_SCALE); + } + CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount); + } + return 0; +} + +static int tonga_populate_smc_vdd_gfx_table(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + unsigned int count; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_gfx_control) { + table->VddGfxLevelCount = data->vddgfx_voltage_table.count; + for (count = 0; count < data->vddgfx_voltage_table.count; count++) { + table->VddGfxTable[count] = + PP_HOST_TO_SMC_US(data->vddgfx_voltage_table.entries[count].value * VOLTAGE_SCALE); + } + CONVERT_FROM_HOST_TO_SMC_UL(table->VddGfxLevelCount); + } + return 0; +} + +static int tonga_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t count; + + table->VddciLevelCount = data->vddci_voltage_table.count; + for (count = 0; count < table->VddciLevelCount; count++) { + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { + table->VddciTable[count] = + PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE); + } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { + table->SmioTable1.Pattern[count].Voltage = + PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE); + /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level. */ + table->SmioTable1.Pattern[count].Smio = + (uint8_t) count; + table->Smio[count] |= + data->vddci_voltage_table.entries[count].smio_low; + table->VddciTable[count] = + PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[count].value * VOLTAGE_SCALE); + } + } + + table->SmioMask1 = data->vddci_voltage_table.mask_low; + CONVERT_FROM_HOST_TO_SMC_UL(table->VddciLevelCount); + + return 0; +} + +static int tonga_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t count; + + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) { + table->MvddLevelCount = data->mvdd_voltage_table.count; + for (count = 0; count < table->MvddLevelCount; count++) { + table->SmioTable2.Pattern[count].Voltage = + PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); + /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ + table->SmioTable2.Pattern[count].Smio = + (uint8_t) count; + table->Smio[count] |= + data->mvdd_voltage_table.entries[count].smio_low; + } + table->SmioMask2 = data->mvdd_voltage_table.mask_low; + + CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount); + } + + return 0; +} + +static int tonga_populate_cac_tables(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + uint32_t count; + uint8_t index = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_voltage_lookup_table *vddgfx_lookup_table = + pptable_info->vddgfx_lookup_table; + struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table = + pptable_info->vddc_lookup_table; + + /* table is already swapped, so in order to use the value from it + * we need to swap it back. + */ + uint32_t vddc_level_count = PP_SMC_TO_HOST_UL(table->VddcLevelCount); + uint32_t vddgfx_level_count = PP_SMC_TO_HOST_UL(table->VddGfxLevelCount); + + for (count = 0; count < vddc_level_count; count++) { + /* We are populating vddc CAC data to BapmVddc table in split and merged mode */ + index = phm_get_voltage_index(vddc_lookup_table, + data->vddc_voltage_table.entries[count].value); + table->BapmVddcVidLoSidd[count] = + convert_to_vid(vddc_lookup_table->entries[index].us_cac_low); + table->BapmVddcVidHiSidd[count] = + convert_to_vid(vddc_lookup_table->entries[index].us_cac_mid); + table->BapmVddcVidHiSidd2[count] = + convert_to_vid(vddc_lookup_table->entries[index].us_cac_high); + } + + if ((data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2)) { + /* We are populating vddgfx CAC data to BapmVddgfx table in split mode */ + for (count = 0; count < vddgfx_level_count; count++) { + index = phm_get_voltage_index(vddgfx_lookup_table, + convert_to_vid(vddgfx_lookup_table->entries[index].us_cac_mid)); + table->BapmVddGfxVidHiSidd2[count] = + convert_to_vid(vddgfx_lookup_table->entries[index].us_cac_high); + } + } else { + for (count = 0; count < vddc_level_count; count++) { + index = phm_get_voltage_index(vddc_lookup_table, + data->vddc_voltage_table.entries[count].value); + table->BapmVddGfxVidLoSidd[count] = + convert_to_vid(vddc_lookup_table->entries[index].us_cac_low); + table->BapmVddGfxVidHiSidd[count] = + convert_to_vid(vddc_lookup_table->entries[index].us_cac_mid); + table->BapmVddGfxVidHiSidd2[count] = + convert_to_vid(vddc_lookup_table->entries[index].us_cac_high); + } + } + + return 0; +} + +static int tonga_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + int result; + + result = tonga_populate_smc_vddc_table(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "can not populate VDDC voltage table to SMC", + return -EINVAL); + + result = tonga_populate_smc_vdd_ci_table(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "can not populate VDDCI voltage table to SMC", + return -EINVAL); + + result = tonga_populate_smc_vdd_gfx_table(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "can not populate VDDGFX voltage table to SMC", + return -EINVAL); + + result = tonga_populate_smc_mvdd_table(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "can not populate MVDD voltage table to SMC", + return -EINVAL); + + result = tonga_populate_cac_tables(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "can not populate CAC voltage tables to SMC", + return -EINVAL); + + return 0; +} + +static int tonga_populate_ulv_level(struct pp_hwmgr *hwmgr, + struct SMU72_Discrete_Ulv *state) +{ + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + state->CcPwrDynRm = 0; + state->CcPwrDynRm1 = 0; + + state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset; + state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset * + VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1); + + state->VddcPhase = 1; + + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); + CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); + + return 0; +} + +static int tonga_populate_ulv_state(struct pp_hwmgr *hwmgr, + struct SMU72_Discrete_DpmTable *table) +{ + return tonga_populate_ulv_level(hwmgr, &table->Ulv); +} + +static int tonga_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU72_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + uint32_t i; + + /* Index (dpm_table->pcie_speed_table.count) is reserved for PCIE boot level. */ + for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { + table->LinkLevel[i].PcieGenSpeed = + (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; + table->LinkLevel[i].PcieLaneCount = + (uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1); + table->LinkLevel[i].EnabledForActivity = + 1; + table->LinkLevel[i].SPC = + (uint8_t)(data->pcie_spc_cap & 0xff); + table->LinkLevel[i].DownThreshold = + PP_HOST_TO_SMC_UL(5); + table->LinkLevel[i].UpThreshold = + PP_HOST_TO_SMC_UL(30); + } + + smu_data->smc_state_table.LinkLevelCount = + (uint8_t)dpm_table->pcie_speed_table.count; + data->dpm_level_enable_mask.pcie_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); + + return 0; +} + +static int tonga_calculate_sclk_params(struct pp_hwmgr *hwmgr, + uint32_t engine_clock, SMU72_Discrete_GraphicsLevel *sclk) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + pp_atomctrl_clock_dividers_vi dividers; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + uint32_t reference_clock; + uint32_t reference_divider; + uint32_t fbdiv; + int result; + + /* get the engine clock dividers for this clock value*/ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, engine_clock, ÷rs); + + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", return result); + + /* To get FBDIV we need to multiply this by 16384 and divide it by Fref.*/ + reference_clock = atomctrl_get_reference_clock(hwmgr); + + reference_divider = 1 + dividers.uc_pll_ref_div; + + /* low 14 bits is fraction and high 12 bits is divider*/ + fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF; + + /* SPLL_FUNC_CNTL setup*/ + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_REF_DIV, dividers.uc_pll_ref_div); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, + CG_SPLL_FUNC_CNTL, SPLL_PDIV_A, dividers.uc_pll_post_div); + + /* SPLL_FUNC_CNTL_3 setup*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, + CG_SPLL_FUNC_CNTL_3, SPLL_FB_DIV, fbdiv); + + /* set to use fractional accumulation*/ + spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3, + CG_SPLL_FUNC_CNTL_3, SPLL_DITHEN, 1); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_EngineSpreadSpectrumSupport)) { + pp_atomctrl_internal_ss_info ss_info; + + uint32_t vcoFreq = engine_clock * dividers.uc_pll_post_div; + if (0 == atomctrl_get_engine_clock_spread_spectrum(hwmgr, vcoFreq, &ss_info)) { + /* + * ss_info.speed_spectrum_percentage -- in unit of 0.01% + * ss_info.speed_spectrum_rate -- in unit of khz + */ + /* clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 */ + uint32_t clkS = reference_clock * 5 / (reference_divider * ss_info.speed_spectrum_rate); + + /* clkv = 2 * D * fbdiv / NS */ + uint32_t clkV = 4 * ss_info.speed_spectrum_percentage * fbdiv / (clkS * 10000); + + cg_spll_spread_spectrum = + PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, CLKS, clkS); + cg_spll_spread_spectrum = + PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, SSEN, 1); + cg_spll_spread_spectrum_2 = + PHM_SET_FIELD(cg_spll_spread_spectrum_2, CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clkV); + } + } + + sclk->SclkFrequency = engine_clock; + sclk->CgSpllFuncCntl3 = spll_func_cntl_3; + sclk->CgSpllFuncCntl4 = spll_func_cntl_4; + sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum; + sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2; + sclk->SclkDid = (uint8_t)dividers.pll_post_divider; + + return 0; +} + +static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr, + uint32_t engine_clock, + uint16_t sclk_activity_level_threshold, + SMU72_Discrete_GraphicsLevel *graphic_level) +{ + int result; + uint32_t mvdd; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + result = tonga_calculate_sclk_params(hwmgr, engine_clock, graphic_level); + + /* populate graphics levels*/ + result = tonga_get_dependency_volt_by_clk(hwmgr, + pptable_info->vdd_dep_on_sclk, engine_clock, + &graphic_level->MinVoltage, &mvdd); + PP_ASSERT_WITH_CODE((!result), + "can not find VDDC voltage value for VDDC " + "engine clock dependency table", return result); + + /* SCLK frequency in units of 10KHz*/ + graphic_level->SclkFrequency = engine_clock; + /* Indicates maximum activity level for this performance level. 50% for now*/ + graphic_level->ActivityLevel = sclk_activity_level_threshold; + + graphic_level->CcPwrDynRm = 0; + graphic_level->CcPwrDynRm1 = 0; + /* this level can be used if activity is high enough.*/ + graphic_level->EnabledForActivity = 0; + /* this level can be used for throttling.*/ + graphic_level->EnabledForThrottle = 1; + graphic_level->UpHyst = 0; + graphic_level->DownHyst = 0; + graphic_level->VoltageDownHyst = 0; + graphic_level->PowerThrottle = 0; + + data->display_timing.min_clock_in_sr = + hwmgr->display_config.min_core_set_clock_in_sr; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkDeepSleep)) + graphic_level->DeepSleepDivId = + smu7_get_sleep_divider_id_from_clock(engine_clock, + data->display_timing.min_clock_in_sr); + + /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ + graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + if (!result) { + /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVoltage);*/ + /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases);*/ + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(graphic_level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm1); + } + + return result; +} + +static int tonga_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + struct phm_ppt_v1_pcie_table *pcie_table = pptable_info->pcie_table; + uint8_t pcie_entry_count = (uint8_t) data->dpm_table.pcie_speed_table.count; + uint32_t level_array_address = smu_data->smu7_data.dpm_table_start + + offsetof(SMU72_Discrete_DpmTable, GraphicsLevel); + + uint32_t level_array_size = sizeof(SMU72_Discrete_GraphicsLevel) * + SMU72_MAX_LEVELS_GRAPHICS; + + SMU72_Discrete_GraphicsLevel *levels = smu_data->smc_state_table.GraphicsLevel; + + uint32_t i, max_entry; + uint8_t highest_pcie_level_enabled = 0; + uint8_t lowest_pcie_level_enabled = 0, mid_pcie_level_enabled = 0; + uint8_t count = 0; + int result = 0; + + memset(levels, 0x00, level_array_size); + + for (i = 0; i < dpm_table->sclk_table.count; i++) { + result = tonga_populate_single_graphic_level(hwmgr, + dpm_table->sclk_table.dpm_levels[i].value, + (uint16_t)smu_data->activity_target[i], + &(smu_data->smc_state_table.GraphicsLevel[i])); + if (result != 0) + return result; + + /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ + if (i > 1) + smu_data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0; + } + + /* Only enable level 0 for now. */ + smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; + + /* set highest level watermark to high */ + if (dpm_table->sclk_table.count > 1) + smu_data->smc_state_table.GraphicsLevel[dpm_table->sclk_table.count-1].DisplayWatermark = + PPSMC_DISPLAY_WATERMARK_HIGH; + + smu_data->smc_state_table.GraphicsDpmLevelCount = + (uint8_t)dpm_table->sclk_table.count; + data->dpm_level_enable_mask.sclk_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); + + if (pcie_table != NULL) { + PP_ASSERT_WITH_CODE((pcie_entry_count >= 1), + "There must be 1 or more PCIE levels defined in PPTable.", + return -EINVAL); + max_entry = pcie_entry_count - 1; /* for indexing, we need to decrement by 1.*/ + for (i = 0; i < dpm_table->sclk_table.count; i++) { + smu_data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = + (uint8_t) ((i < max_entry) ? i : max_entry); + } + } else { + if (0 == data->dpm_level_enable_mask.pcie_dpm_enable_mask) + pr_err("Pcie Dpm Enablemask is 0 !"); + + while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && + ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1<<(highest_pcie_level_enabled+1))) != 0)) { + highest_pcie_level_enabled++; + } + + while (data->dpm_level_enable_mask.pcie_dpm_enable_mask && + ((data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1<dpm_level_enable_mask.pcie_dpm_enable_mask & + (1<<(lowest_pcie_level_enabled+1+count))) == 0)) { + count++; + } + mid_pcie_level_enabled = (lowest_pcie_level_enabled+1+count) < highest_pcie_level_enabled ? + (lowest_pcie_level_enabled+1+count) : highest_pcie_level_enabled; + + + /* set pcieDpmLevel to highest_pcie_level_enabled*/ + for (i = 2; i < dpm_table->sclk_table.count; i++) + smu_data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = highest_pcie_level_enabled; + + /* set pcieDpmLevel to lowest_pcie_level_enabled*/ + smu_data->smc_state_table.GraphicsLevel[0].pcieDpmLevel = lowest_pcie_level_enabled; + + /* set pcieDpmLevel to mid_pcie_level_enabled*/ + smu_data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled; + } + /* level count will send to smc once at init smc table and never change*/ + result = smu7_copy_bytes_to_smc(hwmgr, level_array_address, + (uint8_t *)levels, (uint32_t)level_array_size, + SMC_RAM_END); + + return result; +} + +static int tonga_calculate_mclk_params( + struct pp_hwmgr *hwmgr, + uint32_t memory_clock, + SMU72_Discrete_MemoryLevel *mclk, + bool strobe_mode, + bool dllStateOn + ) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; + uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; + uint32_t mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL; + uint32_t mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL; + uint32_t mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL; + uint32_t mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1; + uint32_t mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2; + uint32_t mpll_ss1 = data->clock_registers.vMPLL_SS1; + uint32_t mpll_ss2 = data->clock_registers.vMPLL_SS2; + + pp_atomctrl_memory_clock_param mpll_param; + int result; + + result = atomctrl_get_memory_pll_dividers_si(hwmgr, + memory_clock, &mpll_param, strobe_mode); + PP_ASSERT_WITH_CODE( + !result, + "Error retrieving Memory Clock Parameters from VBIOS.", + return result); + + /* MPLL_FUNC_CNTL setup*/ + mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, + mpll_param.bw_ctrl); + + /* MPLL_FUNC_CNTL_1 setup*/ + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, CLKF, + mpll_param.mpll_fb_divider.cl_kf); + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, CLKFRAC, + mpll_param.mpll_fb_divider.clk_frac); + mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1, + MPLL_FUNC_CNTL_1, VCO_MODE, + mpll_param.vco_mode); + + /* MPLL_AD_FUNC_CNTL setup*/ + mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl, + MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, + mpll_param.mpll_post_divider); + + if (data->is_memory_gddr5) { + /* MPLL_DQ_FUNC_CNTL setup*/ + mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, + MPLL_DQ_FUNC_CNTL, YCLK_SEL, + mpll_param.yclk_sel); + mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl, + MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, + mpll_param.mpll_post_divider); + } + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MemorySpreadSpectrumSupport)) { + /* + ************************************ + Fref = Reference Frequency + NF = Feedback divider ratio + NR = Reference divider ratio + Fnom = Nominal VCO output frequency = Fref * NF / NR + Fs = Spreading Rate + D = Percentage down-spread / 2 + Fint = Reference input frequency to PFD = Fref / NR + NS = Spreading rate divider ratio = int(Fint / (2 * Fs)) + CLKS = NS - 1 = ISS_STEP_NUM[11:0] + NV = D * Fs / Fnom * 4 * ((Fnom/Fref * NR) ^ 2) + CLKV = 65536 * NV = ISS_STEP_SIZE[25:0] + ************************************* + */ + pp_atomctrl_internal_ss_info ss_info; + uint32_t freq_nom; + uint32_t tmp; + uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr); + + /* for GDDR5 for all modes and DDR3 */ + if (1 == mpll_param.qdr) + freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider); + else + freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider); + + /* tmp = (freq_nom / reference_clock * reference_divider) ^ 2 Note: S.I. reference_divider = 1*/ + tmp = (freq_nom / reference_clock); + tmp = tmp * tmp; + + if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) { + /* ss_info.speed_spectrum_percentage -- in unit of 0.01% */ + /* ss.Info.speed_spectrum_rate -- in unit of khz */ + /* CLKS = reference_clock / (2 * speed_spectrum_rate * reference_divider) * 10 */ + /* = reference_clock * 5 / speed_spectrum_rate */ + uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate; + + /* CLKV = 65536 * speed_spectrum_percentage / 2 * spreadSpecrumRate / freq_nom * 4 / 100000 * ((freq_nom / reference_clock) ^ 2) */ + /* = 131 * speed_spectrum_percentage * speed_spectrum_rate / 100 * ((freq_nom / reference_clock) ^ 2) / freq_nom */ + uint32_t clkv = + (uint32_t)((((131 * ss_info.speed_spectrum_percentage * + ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom); + + mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv); + mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks); + } + } + + /* MCLK_PWRMGT_CNTL setup */ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn); + + /* Save the result data to outpupt memory level structure */ + mclk->MclkFrequency = memory_clock; + mclk->MpllFuncCntl = mpll_func_cntl; + mclk->MpllFuncCntl_1 = mpll_func_cntl_1; + mclk->MpllFuncCntl_2 = mpll_func_cntl_2; + mclk->MpllAdFuncCntl = mpll_ad_func_cntl; + mclk->MpllDqFuncCntl = mpll_dq_func_cntl; + mclk->MclkPwrmgtCntl = mclk_pwrmgt_cntl; + mclk->DllCntl = dll_cntl; + mclk->MpllSs1 = mpll_ss1; + mclk->MpllSs2 = mpll_ss2; + + return 0; +} + +static uint8_t tonga_get_mclk_frequency_ratio(uint32_t memory_clock, + bool strobe_mode) +{ + uint8_t mc_para_index; + + if (strobe_mode) { + if (memory_clock < 12500) + mc_para_index = 0x00; + else if (memory_clock > 47500) + mc_para_index = 0x0f; + else + mc_para_index = (uint8_t)((memory_clock - 10000) / 2500); + } else { + if (memory_clock < 65000) + mc_para_index = 0x00; + else if (memory_clock > 135000) + mc_para_index = 0x0f; + else + mc_para_index = (uint8_t)((memory_clock - 60000) / 5000); + } + + return mc_para_index; +} + +static uint8_t tonga_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock) +{ + uint8_t mc_para_index; + + if (memory_clock < 10000) + mc_para_index = 0; + else if (memory_clock >= 80000) + mc_para_index = 0x0f; + else + mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1); + + return mc_para_index; +} + + +static int tonga_populate_single_memory_level( + struct pp_hwmgr *hwmgr, + uint32_t memory_clock, + SMU72_Discrete_MemoryLevel *memory_level + ) +{ + uint32_t mvdd = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + int result = 0; + bool dll_state_on; + struct cgs_display_info info = {0}; + uint32_t mclk_edc_wr_enable_threshold = 40000; + uint32_t mclk_stutter_mode_threshold = 30000; + uint32_t mclk_edc_enable_threshold = 40000; + uint32_t mclk_strobe_mode_threshold = 40000; + + if (NULL != pptable_info->vdd_dep_on_mclk) { + result = tonga_get_dependency_volt_by_clk(hwmgr, + pptable_info->vdd_dep_on_mclk, + memory_clock, + &memory_level->MinVoltage, &mvdd); + PP_ASSERT_WITH_CODE( + !result, + "can not find MinVddc voltage value from memory VDDC " + "voltage dependency table", + return result); + } + + if (data->mvdd_control == SMU7_VOLTAGE_CONTROL_NONE) + memory_level->MinMvdd = data->vbios_boot_state.mvdd_bootup_value; + else + memory_level->MinMvdd = mvdd; + + memory_level->EnabledForThrottle = 1; + memory_level->EnabledForActivity = 0; + memory_level->UpHyst = 0; + memory_level->DownHyst = 100; + memory_level->VoltageDownHyst = 0; + + /* Indicates maximum activity level for this performance level.*/ + memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target; + memory_level->StutterEnable = 0; + memory_level->StrobeEnable = 0; + memory_level->EdcReadEnable = 0; + memory_level->EdcWriteEnable = 0; + memory_level->RttEnable = 0; + + /* default set to low watermark. Highest level will be set to high later.*/ + memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + cgs_get_active_displays_info(hwmgr->device, &info); + data->display_timing.num_existing_displays = info.display_count; + + if ((mclk_stutter_mode_threshold != 0) && + (memory_clock <= mclk_stutter_mode_threshold) && + (!data->is_uvd_enabled) + && (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, STUTTER_ENABLE) & 0x1) + && (data->display_timing.num_existing_displays <= 2) + && (data->display_timing.num_existing_displays != 0)) + memory_level->StutterEnable = 1; + + /* decide strobe mode*/ + memory_level->StrobeEnable = (mclk_strobe_mode_threshold != 0) && + (memory_clock <= mclk_strobe_mode_threshold); + + /* decide EDC mode and memory clock ratio*/ + if (data->is_memory_gddr5) { + memory_level->StrobeRatio = tonga_get_mclk_frequency_ratio(memory_clock, + memory_level->StrobeEnable); + + if ((mclk_edc_enable_threshold != 0) && + (memory_clock > mclk_edc_enable_threshold)) { + memory_level->EdcReadEnable = 1; + } + + if ((mclk_edc_wr_enable_threshold != 0) && + (memory_clock > mclk_edc_wr_enable_threshold)) { + memory_level->EdcWriteEnable = 1; + } + + if (memory_level->StrobeEnable) { + if (tonga_get_mclk_frequency_ratio(memory_clock, 1) >= + ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) { + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; + } else { + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0; + } + + } else { + dll_state_on = data->dll_default_on; + } + } else { + memory_level->StrobeRatio = + tonga_get_ddr3_mclk_frequency_ratio(memory_clock); + dll_state_on = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0; + } + + result = tonga_calculate_mclk_params(hwmgr, + memory_clock, memory_level, memory_level->StrobeEnable, dll_state_on); + + if (!result) { + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinMvdd); + /* MCLK frequency in units of 10KHz*/ + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency); + /* Indicates maximum activity level for this performance level.*/ + CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1); + CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2); + } + + return result; +} + +int tonga_populate_all_memory_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + int result; + + /* populate MCLK dpm table to SMU7 */ + uint32_t level_array_address = + smu_data->smu7_data.dpm_table_start + + offsetof(SMU72_Discrete_DpmTable, MemoryLevel); + uint32_t level_array_size = + sizeof(SMU72_Discrete_MemoryLevel) * + SMU72_MAX_LEVELS_MEMORY; + SMU72_Discrete_MemoryLevel *levels = + smu_data->smc_state_table.MemoryLevel; + uint32_t i; + + memset(levels, 0x00, level_array_size); + + for (i = 0; i < dpm_table->mclk_table.count; i++) { + PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), + "can not populate memory level as memory clock is zero", + return -EINVAL); + result = tonga_populate_single_memory_level( + hwmgr, + dpm_table->mclk_table.dpm_levels[i].value, + &(smu_data->smc_state_table.MemoryLevel[i])); + if (result) + return result; + } + + /* Only enable level 0 for now.*/ + smu_data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1; + + /* + * in order to prevent MC activity from stutter mode to push DPM up. + * the UVD change complements this by putting the MCLK in a higher state + * by default such that we are not effected by up threshold or and MCLK DPM latency. + */ + smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F; + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel); + + smu_data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count; + data->dpm_level_enable_mask.mclk_dpm_enable_mask = phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); + /* set highest level watermark to high*/ + smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; + + /* level count will send to smc once at init smc table and never change*/ + result = smu7_copy_bytes_to_smc(hwmgr, + level_array_address, (uint8_t *)levels, (uint32_t)level_array_size, + SMC_RAM_END); + + return result; +} + +static int tonga_populate_mvdd_value(struct pp_hwmgr *hwmgr, + uint32_t mclk, SMIO_Pattern *smio_pattern) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint32_t i = 0; + + if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { + /* find mvdd value which clock is more than request */ + for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) { + if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) { + /* Always round to higher voltage. */ + smio_pattern->Voltage = + data->mvdd_voltage_table.entries[i].value; + break; + } + } + + PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count, + "MVDD Voltage is outside the supported range.", + return -EINVAL); + } else { + return -EINVAL; + } + + return 0; +} + + +static int tonga_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + int result = 0; + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct pp_atomctrl_clock_dividers_vi dividers; + + SMIO_Pattern voltage_level; + uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL; + uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2; + uint32_t dll_cntl = data->clock_registers.vDLL_CNTL; + uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL; + + /* The ACPI state should not do DPM on DC (or ever).*/ + table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; + + table->ACPILevel.MinVoltage = + smu_data->smc_state_table.GraphicsLevel[0].MinVoltage; + + /* assign zero for now*/ + table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr); + + /* get the engine clock dividers for this clock value*/ + result = atomctrl_get_engine_pll_dividers_vi(hwmgr, + table->ACPILevel.SclkFrequency, ÷rs); + + PP_ASSERT_WITH_CODE(result == 0, + "Error retrieving Engine Clock dividers from VBIOS.", + return result); + + /* divider ID for required SCLK*/ + table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider; + table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + table->ACPILevel.DeepSleepDivId = 0; + + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_PWRON, 0); + spll_func_cntl = PHM_SET_FIELD(spll_func_cntl, CG_SPLL_FUNC_CNTL, + SPLL_RESET, 1); + spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2, CG_SPLL_FUNC_CNTL_2, + SCLK_MUX_SEL, 4); + + table->ACPILevel.CgSpllFuncCntl = spll_func_cntl; + table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2; + table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3; + table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4; + table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM; + table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2; + table->ACPILevel.CcPwrDynRm = 0; + table->ACPILevel.CcPwrDynRm1 = 0; + + + /* For various features to be enabled/disabled while this level is active.*/ + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); + /* SCLK frequency in units of 10KHz*/ + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); + + /* table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;*/ + table->MemoryACPILevel.MinVoltage = + smu_data->smc_state_table.MemoryLevel[0].MinVoltage; + + /* CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage);*/ + + if (0 == tonga_populate_mvdd_value(hwmgr, 0, &voltage_level)) + table->MemoryACPILevel.MinMvdd = + PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE); + else + table->MemoryACPILevel.MinMvdd = 0; + + /* Force reset on DLL*/ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1); + + /* Disable DLL in ACPIState*/ + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0); + mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl, + MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0); + + /* Enable DLL bypass signal*/ + dll_cntl = PHM_SET_FIELD(dll_cntl, + DLL_CNTL, MRDCK0_BYPASS, 0); + dll_cntl = PHM_SET_FIELD(dll_cntl, + DLL_CNTL, MRDCK1_BYPASS, 0); + + table->MemoryACPILevel.DllCntl = + PP_HOST_TO_SMC_UL(dll_cntl); + table->MemoryACPILevel.MclkPwrmgtCntl = + PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl); + table->MemoryACPILevel.MpllAdFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL); + table->MemoryACPILevel.MpllDqFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL); + table->MemoryACPILevel.MpllFuncCntl = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL); + table->MemoryACPILevel.MpllFuncCntl_1 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1); + table->MemoryACPILevel.MpllFuncCntl_2 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2); + table->MemoryACPILevel.MpllSs1 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1); + table->MemoryACPILevel.MpllSs2 = + PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2); + + table->MemoryACPILevel.EnabledForThrottle = 0; + table->MemoryACPILevel.EnabledForActivity = 0; + table->MemoryACPILevel.UpHyst = 0; + table->MemoryACPILevel.DownHyst = 100; + table->MemoryACPILevel.VoltageDownHyst = 0; + /* Indicates maximum activity level for this performance level.*/ + table->MemoryACPILevel.ActivityLevel = + PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); + + table->MemoryACPILevel.StutterEnable = 0; + table->MemoryACPILevel.StrobeEnable = 0; + table->MemoryACPILevel.EdcReadEnable = 0; + table->MemoryACPILevel.EdcWriteEnable = 0; + table->MemoryACPILevel.RttEnable = 0; + + return result; +} + +static int tonga_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + int result = 0; + + uint8_t count; + pp_atomctrl_clock_dividers_vi dividers; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + pptable_info->mm_dep_table; + + table->UvdLevelCount = (uint8_t) (mm_table->count); + table->UvdBootLevel = 0; + + for (count = 0; count < table->UvdLevelCount; count++) { + table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; + table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; + table->UvdLevel[count].MinVoltage.Vddc = + phm_get_voltage_index(pptable_info->vddc_lookup_table, + mm_table->entries[count].vddc); + table->UvdLevel[count].MinVoltage.VddGfx = + (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? + phm_get_voltage_index(pptable_info->vddgfx_lookup_table, + mm_table->entries[count].vddgfx) : 0; + table->UvdLevel[count].MinVoltage.Vddci = + phm_get_voltage_id(&data->vddci_voltage_table, + mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); + table->UvdLevel[count].MinVoltage.Phases = 1; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi( + hwmgr, + table->UvdLevel[count].VclkFrequency, + ÷rs); + + PP_ASSERT_WITH_CODE((!result), + "can not find divide id for Vclk clock", + return result); + + table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; + + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->UvdLevel[count].DclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE((!result), + "can not find divide id for Dclk clock", + return result); + + table->UvdLevel[count].DclkDivider = + (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); + } + + return result; + +} + +static int tonga_populate_smc_vce_level(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + int result = 0; + + uint8_t count; + pp_atomctrl_clock_dividers_vi dividers; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + pptable_info->mm_dep_table; + + table->VceLevelCount = (uint8_t) (mm_table->count); + table->VceBootLevel = 0; + + for (count = 0; count < table->VceLevelCount; count++) { + table->VceLevel[count].Frequency = + mm_table->entries[count].eclk; + table->VceLevel[count].MinVoltage.Vddc = + phm_get_voltage_index(pptable_info->vddc_lookup_table, + mm_table->entries[count].vddc); + table->VceLevel[count].MinVoltage.VddGfx = + (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? + phm_get_voltage_index(pptable_info->vddgfx_lookup_table, + mm_table->entries[count].vddgfx) : 0; + table->VceLevel[count].MinVoltage.Vddci = + phm_get_voltage_id(&data->vddci_voltage_table, + mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); + table->VceLevel[count].MinVoltage.Phases = 1; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->VceLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((!result), + "can not find divide id for VCE engine clock", + return result); + + table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); + } + + return result; +} + +static int tonga_populate_smc_acp_level(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + int result = 0; + uint8_t count; + pp_atomctrl_clock_dividers_vi dividers; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + pptable_info->mm_dep_table; + + table->AcpLevelCount = (uint8_t) (mm_table->count); + table->AcpBootLevel = 0; + + for (count = 0; count < table->AcpLevelCount; count++) { + table->AcpLevel[count].Frequency = + pptable_info->mm_dep_table->entries[count].aclk; + table->AcpLevel[count].MinVoltage.Vddc = + phm_get_voltage_index(pptable_info->vddc_lookup_table, + mm_table->entries[count].vddc); + table->AcpLevel[count].MinVoltage.VddGfx = + (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? + phm_get_voltage_index(pptable_info->vddgfx_lookup_table, + mm_table->entries[count].vddgfx) : 0; + table->AcpLevel[count].MinVoltage.Vddci = + phm_get_voltage_id(&data->vddci_voltage_table, + mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); + table->AcpLevel[count].MinVoltage.Phases = 1; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->AcpLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((!result), + "can not find divide id for engine clock", return result); + + table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->AcpLevel[count].Frequency); + } + + return result; +} + +static int tonga_populate_smc_samu_level(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + int result = 0; + uint8_t count; + pp_atomctrl_clock_dividers_vi dividers; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *pptable_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + pptable_info->mm_dep_table; + + table->SamuBootLevel = 0; + table->SamuLevelCount = (uint8_t) (mm_table->count); + + for (count = 0; count < table->SamuLevelCount; count++) { + /* not sure whether we need evclk or not */ + table->SamuLevel[count].Frequency = + pptable_info->mm_dep_table->entries[count].samclock; + table->SamuLevel[count].MinVoltage.Vddc = + phm_get_voltage_index(pptable_info->vddc_lookup_table, + mm_table->entries[count].vddc); + table->SamuLevel[count].MinVoltage.VddGfx = + (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? + phm_get_voltage_index(pptable_info->vddgfx_lookup_table, + mm_table->entries[count].vddgfx) : 0; + table->SamuLevel[count].MinVoltage.Vddci = + phm_get_voltage_id(&data->vddci_voltage_table, + mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); + table->SamuLevel[count].MinVoltage.Phases = 1; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->SamuLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((!result), + "can not find divide id for samu clock", return result); + + table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); + } + + return result; +} + +static int tonga_populate_memory_timing_parameters( + struct pp_hwmgr *hwmgr, + uint32_t engine_clock, + uint32_t memory_clock, + struct SMU72_Discrete_MCArbDramTimingTableEntry *arb_regs + ) +{ + uint32_t dramTiming; + uint32_t dramTiming2; + uint32_t burstTime; + int result; + + result = atomctrl_set_engine_dram_timings_rv770(hwmgr, + engine_clock, memory_clock); + + PP_ASSERT_WITH_CODE(result == 0, + "Error calling VBIOS to set DRAM_TIMING.", return result); + + dramTiming = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); + dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); + burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); + + arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dramTiming); + arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2); + arb_regs->McArbBurstTime = (uint8_t)burstTime; + + return 0; +} + +static int tonga_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + int result = 0; + SMU72_Discrete_MCArbDramTimingTable arb_regs; + uint32_t i, j; + + memset(&arb_regs, 0x00, sizeof(SMU72_Discrete_MCArbDramTimingTable)); + + for (i = 0; i < data->dpm_table.sclk_table.count; i++) { + for (j = 0; j < data->dpm_table.mclk_table.count; j++) { + result = tonga_populate_memory_timing_parameters + (hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value, + data->dpm_table.mclk_table.dpm_levels[j].value, + &arb_regs.entries[i][j]); + + if (result) + break; + } + } + + if (!result) { + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.arb_table_start, + (uint8_t *)&arb_regs, + sizeof(SMU72_Discrete_MCArbDramTimingTable), + SMC_RAM_END + ); + } + + return result; +} + +static int tonga_populate_smc_boot_level(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + table->GraphicsBootLevel = 0; + table->MemoryBootLevel = 0; + + /* find boot level from dpm table*/ + result = phm_find_boot_level(&(data->dpm_table.sclk_table), + data->vbios_boot_state.sclk_bootup_value, + (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); + + if (result != 0) { + smu_data->smc_state_table.GraphicsBootLevel = 0; + pr_err("[powerplay] VBIOS did not find boot engine " + "clock value in dependency table. " + "Using Graphics DPM level 0 !"); + result = 0; + } + + result = phm_find_boot_level(&(data->dpm_table.mclk_table), + data->vbios_boot_state.mclk_bootup_value, + (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); + + if (result != 0) { + smu_data->smc_state_table.MemoryBootLevel = 0; + pr_err("[powerplay] VBIOS did not find boot " + "engine clock value in dependency table." + "Using Memory DPM level 0 !"); + result = 0; + } + + table->BootVoltage.Vddc = + phm_get_voltage_id(&(data->vddc_voltage_table), + data->vbios_boot_state.vddc_bootup_value); + table->BootVoltage.VddGfx = + phm_get_voltage_id(&(data->vddgfx_voltage_table), + data->vbios_boot_state.vddgfx_bootup_value); + table->BootVoltage.Vddci = + phm_get_voltage_id(&(data->vddci_voltage_table), + data->vbios_boot_state.vddci_bootup_value); + table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value; + + CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd); + + return result; +} + +static int tonga_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) +{ + uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks, + volt_with_cks, value; + uint16_t clock_freq_u16; + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2, + volt_offset = 0; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = + table_info->vdd_dep_on_sclk; + uint32_t hw_revision, dev_id; + struct cgs_system_info sys_info = {0}; + + stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount; + + sys_info.size = sizeof(struct cgs_system_info); + + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_REV; + cgs_query_system_info(hwmgr->device, &sys_info); + hw_revision = (uint32_t)sys_info.value; + + sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV; + cgs_query_system_info(hwmgr->device, &sys_info); + dev_id = (uint32_t)sys_info.value; + + /* Read SMU_Eefuse to read and calculate RO and determine + * if the part is SS or FF. if RO >= 1660MHz, part is FF. + */ + efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixSMU_EFUSE_0 + (146 * 4)); + efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixSMU_EFUSE_0 + (148 * 4)); + efuse &= 0xFF000000; + efuse = efuse >> 24; + efuse2 &= 0xF; + + if (efuse2 == 1) + ro = (2300 - 1350) * efuse / 255 + 1350; + else + ro = (2500 - 1000) * efuse / 255 + 1000; + + if (ro >= 1660) + type = 0; + else + type = 1; + + /* Populate Stretch amount */ + smu_data->smc_state_table.ClockStretcherAmount = stretch_amount; + + + /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ + for (i = 0; i < sclk_table->count; i++) { + smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= + sclk_table->entries[i].cks_enable << i; + if (ASICID_IS_TONGA_P(dev_id, hw_revision)) { + volt_without_cks = (uint32_t)((7732 + 60 - ro - 20838 * + (sclk_table->entries[i].clk/100) / 10000) * 1000 / + (8730 - (5301 * (sclk_table->entries[i].clk/100) / 1000))); + volt_with_cks = (uint32_t)((5250 + 51 - ro - 2404 * + (sclk_table->entries[i].clk/100) / 100000) * 1000 / + (6146 - (3193 * (sclk_table->entries[i].clk/100) / 1000))); + } else { + volt_without_cks = (uint32_t)((14041 * + (sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 / + (4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000))); + volt_with_cks = (uint32_t)((13946 * + (sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 / + (3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000))); + } + if (volt_without_cks >= volt_with_cks) + volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + + sclk_table->entries[i].cks_voffset) * 100 / 625) + 1); + smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; + } + + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + STRETCH_ENABLE, 0x0); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + masterReset, 0x1); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + staticEnable, 0x1); + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, + masterReset, 0x0); + + /* Populate CKS Lookup Table */ + if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) + stretch_amount2 = 0; + else if (stretch_amount == 3 || stretch_amount == 4) + stretch_amount2 = 1; + else { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ClockStretcher); + PP_ASSERT_WITH_CODE(false, + "Stretch Amount in PPTable not supported\n", + return -EINVAL); + } + + value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixPWR_CKS_CNTL); + value &= 0xFFC2FF87; + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq = + tonga_clock_stretcher_lookup_table[stretch_amount2][0]; + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq = + tonga_clock_stretcher_lookup_table[stretch_amount2][1]; + clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(smu_data->smc_state_table. + GraphicsLevel[smu_data->smc_state_table.GraphicsDpmLevelCount - 1]. + SclkFrequency) / 100); + if (tonga_clock_stretcher_lookup_table[stretch_amount2][0] < + clock_freq_u16 && + tonga_clock_stretcher_lookup_table[stretch_amount2][1] > + clock_freq_u16) { + /* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */ + value |= (tonga_clock_stretcher_lookup_table[stretch_amount2][3]) << 16; + /* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */ + value |= (tonga_clock_stretcher_lookup_table[stretch_amount2][2]) << 18; + /* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */ + value |= (tonga_clock_stretch_amount_conversion + [tonga_clock_stretcher_lookup_table[stretch_amount2][3]] + [stretch_amount]) << 3; + } + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. + CKS_LOOKUPTableEntry[0].minFreq); + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.CKS_LOOKUPTable. + CKS_LOOKUPTableEntry[0].maxFreq); + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting = + tonga_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F; + smu_data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |= + (tonga_clock_stretcher_lookup_table[stretch_amount2][3]) << 7; + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixPWR_CKS_CNTL, value); + + /* Populate DDT Lookup Table */ + for (i = 0; i < 4; i++) { + /* Assign the minimum and maximum VID stored + * in the last row of Clock Stretcher Voltage Table. + */ + smu_data->smc_state_table.ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].minVID = + (uint8_t) tonga_clock_stretcher_ddt_table[type][i][2]; + smu_data->smc_state_table.ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].maxVID = + (uint8_t) tonga_clock_stretcher_ddt_table[type][i][3]; + /* Loop through each SCLK and check the frequency + * to see if it lies within the frequency for clock stretcher. + */ + for (j = 0; j < smu_data->smc_state_table.GraphicsDpmLevelCount; j++) { + cks_setting = 0; + clock_freq = PP_SMC_TO_HOST_UL( + smu_data->smc_state_table.GraphicsLevel[j].SclkFrequency); + /* Check the allowed frequency against the sclk level[j]. + * Sclk's endianness has already been converted, + * and it's in 10Khz unit, + * as opposed to Data table, which is in Mhz unit. + */ + if (clock_freq >= tonga_clock_stretcher_ddt_table[type][i][0] * 100) { + cks_setting |= 0x2; + if (clock_freq < tonga_clock_stretcher_ddt_table[type][i][1] * 100) + cks_setting |= 0x1; + } + smu_data->smc_state_table.ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].setting |= cks_setting << (j * 2); + } + CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table. + ClockStretcherDataTable. + ClockStretcherDataTableEntry[i].setting); + } + + value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixPWR_CKS_CNTL); + value &= 0xFFFFFFFE; + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixPWR_CKS_CNTL, value); + + return 0; +} + +static int tonga_populate_vr_config(struct pp_hwmgr *hwmgr, + SMU72_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint16_t config; + + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_gfx_control) { + /* Splitted mode */ + config = VR_SVI2_PLANE_1; + table->VRConfig |= (config<voltage_control) { + config = VR_SVI2_PLANE_2; + table->VRConfig |= config; + } else { + pr_err("VDDC and VDDGFX should " + "be both on SVI2 control in splitted mode !\n"); + } + } else { + /* Merged mode */ + config = VR_MERGED_WITH_VDDC; + table->VRConfig |= (config<voltage_control) { + config = VR_SVI2_PLANE_1; + table->VRConfig |= config; + } else { + pr_err("VDDC should be on " + "SVI2 control in merged mode !\n"); + } + } + + /* Set Vddci Voltage Controller */ + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { + config = VR_SVI2_PLANE_2; /* only in merged mode */ + table->VRConfig |= (config<vddci_control) { + config = VR_SMIO_PATTERN_1; + table->VRConfig |= (config<mvdd_control) { + config = VR_SMIO_PATTERN_2; + table->VRConfig |= (config<smu_backend); + uint32_t tmp; + int result; + + /* + * This is a read-modify-write on the first byte of the ARB table. + * The first byte in the SMU72_Discrete_MCArbDramTimingTable structure + * is the field 'current'. + * This solution is ugly, but we never write the whole table only + * individual fields in it. + * In reality this field should not be in that structure + * but in a soft register. + */ + result = smu7_read_smc_sram_dword(hwmgr, + smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END); + + if (result != 0) + return result; + + tmp &= 0x00FFFFFF; + tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; + + return smu7_write_smc_sram_dword(hwmgr, + smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END); +} + + +static int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; + SMU72_Discrete_DpmTable *dpm_table = &(smu_data->smc_state_table); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; + int i, j, k; + const uint16_t *pdef1, *pdef2; + + dpm_table->DefaultTdp = PP_HOST_TO_SMC_US( + (uint16_t)(cac_dtp_table->usTDP * 256)); + dpm_table->TargetTdp = PP_HOST_TO_SMC_US( + (uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); + + PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, + "Target Operating Temp is out of Range !", + ); + + dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp); + dpm_table->GpuTjHyst = 8; + + dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; + + dpm_table->BAPM_TEMP_GRADIENT = + PP_HOST_TO_SMC_UL(defaults->bapm_temp_gradient); + pdef1 = defaults->bapmti_r; + pdef2 = defaults->bapmti_rc; + + for (i = 0; i < SMU72_DTE_ITERATIONS; i++) { + for (j = 0; j < SMU72_DTE_SOURCES; j++) { + for (k = 0; k < SMU72_DTE_SINKS; k++) { + dpm_table->BAPMTI_R[i][j][k] = + PP_HOST_TO_SMC_US(*pdef1); + dpm_table->BAPMTI_RC[i][j][k] = + PP_HOST_TO_SMC_US(*pdef2); + pdef1++; + pdef2++; + } + } + } + + return 0; +} + +static int tonga_populate_svi_load_line(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; + + smu_data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; + smu_data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddC; + smu_data->power_tune_table.SviLoadLineTrimVddC = 3; + smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; + + return 0; +} + +static int tonga_populate_tdc_limit(struct pp_hwmgr *hwmgr) +{ + uint16_t tdc_limit; + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + /* TDC number of fraction bits are changed from 8 to 7 + * for Fiji as requested by SMC team + */ + tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 256); + smu_data->power_tune_table.TDC_VDDC_PkgLimit = + CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); + smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = + defaults->tdc_vddc_throttle_release_limit_perc; + smu_data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; + + return 0; +} + +static int tonga_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + const struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; + uint32_t temp; + + if (smu7_read_smc_sram_dword(hwmgr, + fuse_table_offset + + offsetof(SMU72_Discrete_PmFuses, TdcWaterfallCtl), + (uint32_t *)&temp, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to read PmFuses.DW6 " + "(SviLoadLineEn) from SMC Failed !", + return -EINVAL); + else + smu_data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; + + return 0; +} + +static int tonga_populate_temperature_scaler(struct pp_hwmgr *hwmgr) +{ + int i; + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + + /* Currently not used. Set all to zero. */ + for (i = 0; i < 16; i++) + smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0; + + return 0; +} + +static int tonga_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + + if ((hwmgr->thermal_controller.advanceFanControlParameters. + usFanOutputSensitivity & (1 << 15)) || + (hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity == 0)) + hwmgr->thermal_controller.advanceFanControlParameters. + usFanOutputSensitivity = hwmgr->thermal_controller. + advanceFanControlParameters.usDefaultFanOutputSensitivity; + + smu_data->power_tune_table.FuzzyFan_PwmSetDelta = + PP_HOST_TO_SMC_US(hwmgr->thermal_controller. + advanceFanControlParameters.usFanOutputSensitivity); + return 0; +} + +static int tonga_populate_gnb_lpml(struct pp_hwmgr *hwmgr) +{ + int i; + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + + /* Currently not used. Set all to zero. */ + for (i = 0; i < 16; i++) + smu_data->power_tune_table.GnbLPML[i] = 0; + + return 0; +} + +static int tonga_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint16_t hi_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; + uint16_t lo_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; + struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; + + hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); + lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); + + smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = + CONVERT_FROM_HOST_TO_SMC_US(hi_sidd); + smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = + CONVERT_FROM_HOST_TO_SMC_US(lo_sidd); + + return 0; +} + +static int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + uint32_t pm_fuse_table_offset; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment)) { + if (smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, PmFuseTable), + &pm_fuse_table_offset, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to get pm_fuse_table_offset Failed !", + return -EINVAL); + + /* DW6 */ + if (tonga_populate_svi_load_line(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate SviLoadLine Failed !", + return -EINVAL); + /* DW7 */ + if (tonga_populate_tdc_limit(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TDCLimit Failed !", + return -EINVAL); + /* DW8 */ + if (tonga_populate_dw8(hwmgr, pm_fuse_table_offset)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TdcWaterfallCtl Failed !", + return -EINVAL); + + /* DW9-DW12 */ + if (tonga_populate_temperature_scaler(hwmgr) != 0) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate LPMLTemperatureScaler Failed !", + return -EINVAL); + + /* DW13-DW14 */ + if (tonga_populate_fuzzy_fan(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate Fuzzy Fan " + "Control parameters Failed !", + return -EINVAL); + + /* DW15-DW18 */ + if (tonga_populate_gnb_lpml(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate GnbLPML Failed !", + return -EINVAL); + + /* DW20 */ + if (tonga_populate_bapm_vddc_base_leakage_sidd(hwmgr)) + PP_ASSERT_WITH_CODE( + false, + "Attempt to populate BapmVddCBaseLeakage " + "Hi and Lo Sidd Failed !", + return -EINVAL); + + if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, + (uint8_t *)&smu_data->power_tune_table, + sizeof(struct SMU72_Discrete_PmFuses), SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to download PmFuseTable Failed !", + return -EINVAL); + } + return 0; +} + +static int tonga_populate_mc_reg_address(struct pp_hwmgr *hwmgr, + SMU72_Discrete_MCRegisters *mc_reg_table) +{ + const struct tonga_smumgr *smu_data = (struct tonga_smumgr *)hwmgr->smu_backend; + + uint32_t i, j; + + for (i = 0, j = 0; j < smu_data->mc_reg_table.last; j++) { + if (smu_data->mc_reg_table.validflag & 1<address[] array " + "out of boundary", + return -EINVAL); + mc_reg_table->address[i].s0 = + PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s0); + mc_reg_table->address[i].s1 = + PP_HOST_TO_SMC_US(smu_data->mc_reg_table.mc_reg_address[j].s1); + i++; + } + } + + mc_reg_table->last = (uint8_t)i; + + return 0; +} + +/*convert register values from driver to SMC format */ +static void tonga_convert_mc_registers( + const struct tonga_mc_reg_entry *entry, + SMU72_Discrete_MCRegisterSet *data, + uint32_t num_entries, uint32_t valid_flag) +{ + uint32_t i, j; + + for (i = 0, j = 0; j < num_entries; j++) { + if (valid_flag & 1<value[i] = PP_HOST_TO_SMC_UL(entry->mc_data[j]); + i++; + } + } +} + +static int tonga_convert_mc_reg_table_entry_to_smc( + struct pp_hwmgr *hwmgr, + const uint32_t memory_clock, + SMU72_Discrete_MCRegisterSet *mc_reg_table_data + ) +{ + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + uint32_t i = 0; + + for (i = 0; i < smu_data->mc_reg_table.num_entries; i++) { + if (memory_clock <= + smu_data->mc_reg_table.mc_reg_table_entry[i].mclk_max) { + break; + } + } + + if ((i == smu_data->mc_reg_table.num_entries) && (i > 0)) + --i; + + tonga_convert_mc_registers(&smu_data->mc_reg_table.mc_reg_table_entry[i], + mc_reg_table_data, smu_data->mc_reg_table.last, + smu_data->mc_reg_table.validflag); + + return 0; +} + +static int tonga_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr, + SMU72_Discrete_MCRegisters *mc_regs) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + int res; + uint32_t i; + + for (i = 0; i < data->dpm_table.mclk_table.count; i++) { + res = tonga_convert_mc_reg_table_entry_to_smc( + hwmgr, + data->dpm_table.mclk_table.dpm_levels[i].value, + &mc_regs->data[i] + ); + + if (0 != res) + result = res; + } + + return result; +} + +static int tonga_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t address; + int32_t result; + + if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) + return 0; + + + memset(&smu_data->mc_regs, 0, sizeof(SMU72_Discrete_MCRegisters)); + + result = tonga_convert_mc_reg_table_to_smc(hwmgr, &(smu_data->mc_regs)); + + if (result != 0) + return result; + + + address = smu_data->smu7_data.mc_reg_table_start + + (uint32_t)offsetof(SMU72_Discrete_MCRegisters, data[0]); + + return smu7_copy_bytes_to_smc( + hwmgr, address, + (uint8_t *)&smu_data->mc_regs.data[0], + sizeof(SMU72_Discrete_MCRegisterSet) * + data->dpm_table.mclk_table.count, + SMC_RAM_END); +} + +static int tonga_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + + memset(&smu_data->mc_regs, 0x00, sizeof(SMU72_Discrete_MCRegisters)); + result = tonga_populate_mc_reg_address(hwmgr, &(smu_data->mc_regs)); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize MCRegTable for the MC register addresses !", + return result;); + + result = tonga_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize MCRegTable for driver state !", + return result;); + + return smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.mc_reg_table_start, + (uint8_t *)&smu_data->mc_regs, sizeof(SMU72_Discrete_MCRegisters), SMC_RAM_END); +} + +static void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + if (table_info && + table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && + table_info->cac_dtp_table->usPowerTuneDataSetID) + smu_data->power_tune_defaults = + &tonga_power_tune_data_set_array + [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; + else + smu_data->power_tune_defaults = &tonga_power_tune_data_set_array[0]; +} + +static void tonga_save_default_power_profile(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *data = (struct tonga_smumgr *)(hwmgr->smu_backend); + struct SMU72_Discrete_GraphicsLevel *levels = + data->smc_state_table.GraphicsLevel; + unsigned min_level = 1; + + hwmgr->default_gfx_power_profile.activity_threshold = + be16_to_cpu(levels[0].ActivityLevel); + hwmgr->default_gfx_power_profile.up_hyst = levels[0].UpHyst; + hwmgr->default_gfx_power_profile.down_hyst = levels[0].DownHyst; + hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE; + + hwmgr->default_compute_power_profile = hwmgr->default_gfx_power_profile; + hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE; + + /* Workaround compute SDMA instability: disable lowest SCLK + * DPM level. Optimize compute power profile: Use only highest + * 2 power levels (if more than 2 are available), Hysteresis: + * 0ms up, 5ms down + */ + if (data->smc_state_table.GraphicsDpmLevelCount > 2) + min_level = data->smc_state_table.GraphicsDpmLevelCount - 2; + else if (data->smc_state_table.GraphicsDpmLevelCount == 2) + min_level = 1; + else + min_level = 0; + hwmgr->default_compute_power_profile.min_sclk = + be32_to_cpu(levels[min_level].SclkFrequency); + hwmgr->default_compute_power_profile.up_hyst = 0; + hwmgr->default_compute_power_profile.down_hyst = 5; + + hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile; + hwmgr->compute_power_profile = hwmgr->default_compute_power_profile; +} + +static int tonga_init_smc_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + SMU72_Discrete_DpmTable *table = &(smu_data->smc_state_table); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + uint8_t i; + pp_atomctrl_gpio_pin_assignment gpio_pin_assignment; + + + memset(&(smu_data->smc_state_table), 0x00, sizeof(smu_data->smc_state_table)); + + tonga_initialize_power_tune_defaults(hwmgr); + + if (SMU7_VOLTAGE_CONTROL_NONE != data->voltage_control) + tonga_populate_smc_voltage_tables(hwmgr, table); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; + + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StepVddc)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; + + if (data->is_memory_gddr5) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; + + i = PHM_READ_FIELD(hwmgr->device, CC_MC_MAX_CHANNEL, NOOFCHAN); + + if (i == 1 || i == 0) + table->SystemFlags |= 0x40; + + if (data->ulv_supported && table_info->us_ulv_voltage_offset) { + result = tonga_populate_ulv_state(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize ULV state !", + return result;); + + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixCG_ULV_PARAMETER, 0x40035); + } + + result = tonga_populate_smc_link_level(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize Link Level !", return result); + + result = tonga_populate_all_graphic_levels(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize Graphics Level !", return result); + + result = tonga_populate_all_memory_levels(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize Memory Level !", return result); + + result = tonga_populate_smc_acpi_level(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize ACPI Level !", return result); + + result = tonga_populate_smc_vce_level(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize VCE Level !", return result); + + result = tonga_populate_smc_acp_level(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize ACP Level !", return result); + + result = tonga_populate_smc_samu_level(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize SAMU Level !", return result); + + /* Since only the initial state is completely set up at this + * point (the other states are just copies of the boot state) we only + * need to populate the ARB settings for the initial state. + */ + result = tonga_program_memory_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to Write ARB settings for the initial state.", + return result;); + + result = tonga_populate_smc_uvd_level(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize UVD Level !", return result); + + result = tonga_populate_smc_boot_level(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to initialize Boot Level !", return result); + + tonga_populate_bapm_parameters_in_dpm_table(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to populate BAPM Parameters !", return result); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ClockStretcher)) { + result = tonga_populate_clock_stretcher_data_table(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to populate Clock Stretcher Data Table !", + return result;); + } + table->GraphicsVoltageChangeEnable = 1; + table->GraphicsThermThrottleEnable = 1; + table->GraphicsInterval = 1; + table->VoltageInterval = 1; + table->ThermalInterval = 1; + table->TemperatureLimitHigh = + table_info->cac_dtp_table->usTargetOperatingTemp * + SMU7_Q88_FORMAT_CONVERSION_UNIT; + table->TemperatureLimitLow = + (table_info->cac_dtp_table->usTargetOperatingTemp - 1) * + SMU7_Q88_FORMAT_CONVERSION_UNIT; + table->MemoryVoltageChangeEnable = 1; + table->MemoryInterval = 1; + table->VoltageResponseTime = 0; + table->PhaseResponseTime = 0; + table->MemoryThermThrottleEnable = 1; + + /* + * Cail reads current link status and reports it as cap (we cannot + * change this due to some previous issues we had) + * SMC drops the link status to lowest level after enabling + * DPM by PowerPlay. After pnp or toggling CF, driver gets reloaded again + * but this time Cail reads current link status which was set to low by + * SMC and reports it as cap to powerplay + * To avoid it, we set PCIeBootLinkLevel to highest dpm level + */ + PP_ASSERT_WITH_CODE((1 <= data->dpm_table.pcie_speed_table.count), + "There must be 1 or more PCIE levels defined in PPTable.", + return -EINVAL); + + table->PCIeBootLinkLevel = (uint8_t) (data->dpm_table.pcie_speed_table.count); + + table->PCIeGenInterval = 1; + + result = tonga_populate_vr_config(hwmgr, table); + PP_ASSERT_WITH_CODE(!result, + "Failed to populate VRConfig setting !", return result); + + table->ThermGpio = 17; + table->SclkStepSize = 0x4000; + + if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, + &gpio_pin_assignment)) { + table->VRHotGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot); + } else { + table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot); + } + + if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID, + &gpio_pin_assignment)) { + table->AcDcGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition); + } else { + table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition); + } + + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_Falcon_QuickTransition); + + if (0) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition); + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_Falcon_QuickTransition); + } + + if (atomctrl_get_pp_assign_pin(hwmgr, + THERMAL_INT_OUTPUT_GPIO_PINID, &gpio_pin_assignment)) { + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ThermalOutGPIO); + + table->ThermOutGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; + + table->ThermOutPolarity = + (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) & + (1 << gpio_pin_assignment.uc_gpio_pin_bit_shift))) ? 1 : 0; + + table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY; + + /* if required, combine VRHot/PCC with thermal out GPIO*/ + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot) && + phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_CombinePCCWithThermalSignal)){ + table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT; + } + } else { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ThermalOutGPIO); + + table->ThermOutGpio = 17; + table->ThermOutPolarity = 1; + table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE; + } + + for (i = 0; i < SMU72_MAX_ENTRIES_SMIO; i++) + table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]); + + CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); + CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2); + CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); + CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); + CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); + + /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.dpm_table_start + offsetof(SMU72_Discrete_DpmTable, SystemFlags), + (uint8_t *)&(table->SystemFlags), + sizeof(SMU72_Discrete_DpmTable) - 3 * sizeof(SMU72_PIDController), + SMC_RAM_END); + + PP_ASSERT_WITH_CODE(!result, + "Failed to upload dpm data to SMC memory !", return result;); + + result = tonga_init_arb_table_index(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to upload arb data to SMC memory !", return result); + + tonga_populate_pm_fuses(hwmgr); + PP_ASSERT_WITH_CODE((!result), + "Failed to populate initialize pm fuses !", return result); + + result = tonga_populate_initial_mc_reg_table(hwmgr); + PP_ASSERT_WITH_CODE((!result), + "Failed to populate initialize MC Reg table !", return result); + + tonga_save_default_power_profile(hwmgr); + + return 0; +} + +static int tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + SMU72_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; + uint32_t duty100; + uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; + uint16_t fdo_min, slope1, slope2; + uint32_t reference_clock; + int res; + uint64_t tmp64; + + if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl)) + return 0; + + if (hwmgr->thermal_controller.fanInfo.bNoFan) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + if (0 == smu_data->smu7_data.fan_table_start) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, + CG_FDO_CTRL1, FMAX_DUTY100); + + if (0 == duty100) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100; + do_div(tmp64, 10000); + fdo_min = (uint16_t)tmp64; + + t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - + hwmgr->thermal_controller.advanceFanControlParameters.usTMin; + t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - + hwmgr->thermal_controller.advanceFanControlParameters.usTMed; + + pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; + pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; + + slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); + slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + + fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100); + fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100); + fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100); + + fan_table.Slope1 = cpu_to_be16(slope1); + fan_table.Slope2 = cpu_to_be16(slope2); + + fan_table.FdoMin = cpu_to_be16(fdo_min); + + fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst); + + fan_table.HystUp = cpu_to_be16(1); + + fan_table.HystSlope = cpu_to_be16(1); + + fan_table.TempRespLim = cpu_to_be16(5); + + reference_clock = smu7_get_xclk(hwmgr); + + fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600); + + fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); + + fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL); + + fan_table.FanControl_GL_Flag = 1; + + res = smu7_copy_bytes_to_smc(hwmgr, + smu_data->smu7_data.fan_table_start, + (uint8_t *)&fan_table, + (uint32_t)sizeof(fan_table), + SMC_RAM_END); + + return 0; +} + + +static int tonga_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (data->need_update_smu7_dpm_table & + (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) + return tonga_program_memory_timing_parameters(hwmgr); + + return 0; +} + +static int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + + int result = 0; + uint32_t low_sclk_interrupt_threshold = 0; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkThrottleLowNotification) + && (hwmgr->gfx_arbiter.sclk_threshold != + data->low_sclk_interrupt_threshold)) { + data->low_sclk_interrupt_threshold = + hwmgr->gfx_arbiter.sclk_threshold; + low_sclk_interrupt_threshold = + data->low_sclk_interrupt_threshold; + + CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); + + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.dpm_table_start + + offsetof(SMU72_Discrete_DpmTable, + LowSclkInterruptThreshold), + (uint8_t *)&low_sclk_interrupt_threshold, + sizeof(uint32_t), + SMC_RAM_END); + } + + result = tonga_update_and_upload_mc_reg_table(hwmgr); + + PP_ASSERT_WITH_CODE((!result), + "Failed to upload MC reg table !", + return result); + + result = tonga_program_mem_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE((result == 0), + "Failed to program memory timing parameters !", + ); + + return result; +} + +static uint32_t tonga_get_offsetof(uint32_t type, uint32_t member) +{ + switch (type) { + case SMU_SoftRegisters: + switch (member) { + case HandshakeDisables: + return offsetof(SMU72_SoftRegisters, HandshakeDisables); + case VoltageChangeTimeout: + return offsetof(SMU72_SoftRegisters, VoltageChangeTimeout); + case AverageGraphicsActivity: + return offsetof(SMU72_SoftRegisters, AverageGraphicsActivity); + case PreVBlankGap: + return offsetof(SMU72_SoftRegisters, PreVBlankGap); + case VBlankTimeout: + return offsetof(SMU72_SoftRegisters, VBlankTimeout); + case UcodeLoadStatus: + return offsetof(SMU72_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU72_SoftRegisters, DRAM_LOG_BUFF_SIZE); + } + case SMU_Discrete_DpmTable: + switch (member) { + case UvdBootLevel: + return offsetof(SMU72_Discrete_DpmTable, UvdBootLevel); + case VceBootLevel: + return offsetof(SMU72_Discrete_DpmTable, VceBootLevel); + case SamuBootLevel: + return offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); + case LowSclkInterruptThreshold: + return offsetof(SMU72_Discrete_DpmTable, LowSclkInterruptThreshold); + } + } + pr_warn("can't get the offset of type %x member %x\n", type, member); + return 0; +} + +static uint32_t tonga_get_mac_definition(uint32_t value) +{ + switch (value) { + case SMU_MAX_LEVELS_GRAPHICS: + return SMU72_MAX_LEVELS_GRAPHICS; + case SMU_MAX_LEVELS_MEMORY: + return SMU72_MAX_LEVELS_MEMORY; + case SMU_MAX_LEVELS_LINK: + return SMU72_MAX_LEVELS_LINK; + case SMU_MAX_ENTRIES_SMIO: + return SMU72_MAX_ENTRIES_SMIO; + case SMU_MAX_LEVELS_VDDC: + return SMU72_MAX_LEVELS_VDDC; + case SMU_MAX_LEVELS_VDDGFX: + return SMU72_MAX_LEVELS_VDDGFX; + case SMU_MAX_LEVELS_VDDCI: + return SMU72_MAX_LEVELS_VDDCI; + case SMU_MAX_LEVELS_MVDD: + return SMU72_MAX_LEVELS_MVDD; + } + pr_warn("can't get the mac value %x\n", value); + + return 0; +} + +static int tonga_update_uvd_smc_table(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + smu_data->smc_state_table.UvdBootLevel = 0; + if (table_info->mm_dep_table->count > 0) + smu_data->smc_state_table.UvdBootLevel = + (uint8_t) (table_info->mm_dep_table->count - 1); + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + + offsetof(SMU72_Discrete_DpmTable, UvdBootLevel); + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0x00FFFFFF; + mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, + mm_boot_level_offset, mm_boot_level_value); + + if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_UVDDPM) || + phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_UVDDPM_SetEnabledMask, + (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel)); + return 0; +} + +static int tonga_update_vce_smc_table(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = + (struct tonga_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + + smu_data->smc_state_table.VceBootLevel = + (uint8_t) (table_info->mm_dep_table->count - 1); + + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + + offsetof(SMU72_Discrete_DpmTable, VceBootLevel); + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0xFF00FFFF; + mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_VCEDPM_SetEnabledMask, + (uint32_t)1 << smu_data->smc_state_table.VceBootLevel); + return 0; +} + +static int tonga_update_samu_smc_table(struct pp_hwmgr *hwmgr) +{ + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + + smu_data->smc_state_table.SamuBootLevel = 0; + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + + offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); + + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0xFFFFFF00; + mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SAMUDPM_SetEnabledMask, + (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); + return 0; +} + +static int tonga_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) +{ + switch (type) { + case SMU_UVD_TABLE: + tonga_update_uvd_smc_table(hwmgr); + break; + case SMU_VCE_TABLE: + tonga_update_vce_smc_table(hwmgr); + break; + case SMU_SAMU_TABLE: + tonga_update_samu_smc_table(hwmgr); + break; + default: + break; + } + return 0; +} + +static int tonga_process_firmware_header(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); + + uint32_t tmp; + int result; + bool error = false; + + result = smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, DpmTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.dpm_table_start = tmp; + + error |= (result != 0); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, SoftRegisters), + &tmp, SMC_RAM_END); + + if (!result) { + data->soft_regs_start = tmp; + smu_data->smu7_data.soft_regs_start = tmp; + } + + error |= (result != 0); + + + result = smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, mcRegisterTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.mc_reg_table_start = tmp; + + result = smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, FanTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.fan_table_start = tmp; + + error |= (result != 0); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, mcArbDramTimingTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.arb_table_start = tmp; + + error |= (result != 0); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU72_FIRMWARE_HEADER_LOCATION + + offsetof(SMU72_Firmware_Header, Version), + &tmp, SMC_RAM_END); + + if (!result) + hwmgr->microcode_version_info.SMC = tmp; + + error |= (result != 0); + + return error ? 1 : 0; +} + +/*---------------------------MC----------------------------*/ + +static uint8_t tonga_get_memory_modile_index(struct pp_hwmgr *hwmgr) +{ + return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16)); +} + +static bool tonga_check_s0_mc_reg_index(uint16_t in_reg, uint16_t *out_reg) +{ + bool result = true; + + switch (in_reg) { + case mmMC_SEQ_RAS_TIMING: + *out_reg = mmMC_SEQ_RAS_TIMING_LP; + break; + + case mmMC_SEQ_DLL_STBY: + *out_reg = mmMC_SEQ_DLL_STBY_LP; + break; + + case mmMC_SEQ_G5PDX_CMD0: + *out_reg = mmMC_SEQ_G5PDX_CMD0_LP; + break; + + case mmMC_SEQ_G5PDX_CMD1: + *out_reg = mmMC_SEQ_G5PDX_CMD1_LP; + break; + + case mmMC_SEQ_G5PDX_CTRL: + *out_reg = mmMC_SEQ_G5PDX_CTRL_LP; + break; + + case mmMC_SEQ_CAS_TIMING: + *out_reg = mmMC_SEQ_CAS_TIMING_LP; + break; + + case mmMC_SEQ_MISC_TIMING: + *out_reg = mmMC_SEQ_MISC_TIMING_LP; + break; + + case mmMC_SEQ_MISC_TIMING2: + *out_reg = mmMC_SEQ_MISC_TIMING2_LP; + break; + + case mmMC_SEQ_PMG_DVS_CMD: + *out_reg = mmMC_SEQ_PMG_DVS_CMD_LP; + break; + + case mmMC_SEQ_PMG_DVS_CTL: + *out_reg = mmMC_SEQ_PMG_DVS_CTL_LP; + break; + + case mmMC_SEQ_RD_CTL_D0: + *out_reg = mmMC_SEQ_RD_CTL_D0_LP; + break; + + case mmMC_SEQ_RD_CTL_D1: + *out_reg = mmMC_SEQ_RD_CTL_D1_LP; + break; + + case mmMC_SEQ_WR_CTL_D0: + *out_reg = mmMC_SEQ_WR_CTL_D0_LP; + break; + + case mmMC_SEQ_WR_CTL_D1: + *out_reg = mmMC_SEQ_WR_CTL_D1_LP; + break; + + case mmMC_PMG_CMD_EMRS: + *out_reg = mmMC_SEQ_PMG_CMD_EMRS_LP; + break; + + case mmMC_PMG_CMD_MRS: + *out_reg = mmMC_SEQ_PMG_CMD_MRS_LP; + break; + + case mmMC_PMG_CMD_MRS1: + *out_reg = mmMC_SEQ_PMG_CMD_MRS1_LP; + break; + + case mmMC_SEQ_PMG_TIMING: + *out_reg = mmMC_SEQ_PMG_TIMING_LP; + break; + + case mmMC_PMG_CMD_MRS2: + *out_reg = mmMC_SEQ_PMG_CMD_MRS2_LP; + break; + + case mmMC_SEQ_WR_CTL_2: + *out_reg = mmMC_SEQ_WR_CTL_2_LP; + break; + + default: + result = false; + break; + } + + return result; +} + +static int tonga_set_s0_mc_reg_index(struct tonga_mc_reg_table *table) +{ + uint32_t i; + uint16_t address; + + for (i = 0; i < table->last; i++) { + table->mc_reg_address[i].s0 = + tonga_check_s0_mc_reg_index(table->mc_reg_address[i].s1, + &address) ? + address : + table->mc_reg_address[i].s1; + } + return 0; +} + +static int tonga_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, + struct tonga_mc_reg_table *ni_table) +{ + uint8_t i, j; + + PP_ASSERT_WITH_CODE((table->last <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES), + "Invalid VramInfo table.", return -EINVAL); + + for (i = 0; i < table->last; i++) + ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1; + + ni_table->last = table->last; + + for (i = 0; i < table->num_entries; i++) { + ni_table->mc_reg_table_entry[i].mclk_max = + table->mc_reg_table_entry[i].mclk_max; + for (j = 0; j < table->last; j++) { + ni_table->mc_reg_table_entry[i].mc_data[j] = + table->mc_reg_table_entry[i].mc_data[j]; + } + } + + ni_table->num_entries = table->num_entries; + + return 0; +} + +static int tonga_set_mc_special_registers(struct pp_hwmgr *hwmgr, + struct tonga_mc_reg_table *table) +{ + uint8_t i, j, k; + uint32_t temp_reg; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + for (i = 0, j = table->last; i < table->last; i++) { + PP_ASSERT_WITH_CODE((j < SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + switch (table->mc_reg_address[i].s1) { + + case mmMC_SEQ_MISC1: + temp_reg = cgs_read_register(hwmgr->device, + mmMC_PMG_CMD_EMRS); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + ((temp_reg & 0xffff0000)) | + ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16); + } + j++; + PP_ASSERT_WITH_CODE((j < SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (temp_reg & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + + if (!data->is_memory_gddr5) + table->mc_reg_table_entry[k].mc_data[j] |= 0x100; + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + + if (!data->is_memory_gddr5) { + table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD; + table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD; + for (k = 0; k < table->num_entries; k++) + table->mc_reg_table_entry[k].mc_data[j] = + (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16; + j++; + PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + } + + break; + + case mmMC_SEQ_RESERVE_M: + temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1); + table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1; + table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (temp_reg & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + } + j++; + PP_ASSERT_WITH_CODE((j <= SMU72_DISCRETE_MC_REGISTER_ARRAY_SIZE), + "Invalid VramInfo table.", return -EINVAL); + break; + + default: + break; + } + + } + + table->last = j; + + return 0; +} + +static int tonga_set_valid_flag(struct tonga_mc_reg_table *table) +{ + uint8_t i, j; + + for (i = 0; i < table->last; i++) { + for (j = 1; j < table->num_entries; j++) { + if (table->mc_reg_table_entry[j-1].mc_data[i] != + table->mc_reg_table_entry[j].mc_data[i]) { + table->validflag |= (1<smu_backend); + pp_atomctrl_mc_reg_table *table; + struct tonga_mc_reg_table *ni_table = &smu_data->mc_reg_table; + uint8_t module_index = tonga_get_memory_modile_index(hwmgr); + + table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); + + if (table == NULL) + return -ENOMEM; + + /* Program additional LP registers that are no longer programmed by VBIOS */ + cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL)); + cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, + cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, + cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, + cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0)); + cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING)); + cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, + cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2)); + cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, + cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2)); + + memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table)); + + result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); + + if (!result) + result = tonga_copy_vbios_smc_reg_table(table, ni_table); + + if (!result) { + tonga_set_s0_mc_reg_index(ni_table); + result = tonga_set_mc_special_registers(hwmgr, ni_table); + } + + if (!result) + tonga_set_valid_flag(ni_table); + + kfree(table); + + return result; +} + +static bool tonga_is_dpm_running(struct pp_hwmgr *hwmgr) +{ + return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) + ? true : false; +} + +static int tonga_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, + struct amd_pp_profile *request) +{ + struct tonga_smumgr *smu_data = (struct tonga_smumgr *) + (hwmgr->smu_backend); + struct SMU72_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU72_Discrete_DpmTable, GraphicsLevel); + uint32_t array_size = sizeof(struct SMU72_Discrete_GraphicsLevel) * + SMU72_MAX_LEVELS_GRAPHICS; + uint32_t i; + + for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { + levels[i].ActivityLevel = + cpu_to_be16(request->activity_threshold); + levels[i].EnabledForActivity = 1; + levels[i].UpHyst = request->up_hyst; + levels[i].DownHyst = request->down_hyst; + } + + return smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + array_size, SMC_RAM_END); +} + const struct pp_smumgr_func tonga_smu_funcs = { .smu_init = &tonga_smu_init, .smu_fini = &smu7_smu_fini, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h index 8c4f761d5bc8..5d70a00348e2 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h @@ -25,8 +25,26 @@ #define _TONGA_SMUMGR_H_ #include "smu72_discrete.h" - #include "smu7_smumgr.h" +#include "smu72.h" + + +#define ASICID_IS_TONGA_P(wDID, bRID) \ + (((wDID == 0x6930) && ((bRID == 0xF0) || (bRID == 0xF1) || (bRID == 0xFF))) \ + || ((wDID == 0x6920) && ((bRID == 0) || (bRID == 1)))) + +struct tonga_pt_defaults { + uint8_t svi_load_line_en; + uint8_t svi_load_line_vddC; + uint8_t tdc_vddc_throttle_release_limit_perc; + uint8_t tdc_mawt; + uint8_t tdc_waterfall_ctl; + uint8_t dte_ambient_temp_base; + uint32_t display_cac; + uint32_t bapm_temp_gradient; + uint16_t bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; + uint16_t bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; +}; struct tonga_mc_reg_entry { uint32_t mclk_max; -- cgit v1.2.3 From 37a49343b467a8a475fc86d9e9e267f6fc679ac0 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 9 Oct 2017 16:33:06 +0800 Subject: drm/amd/pp: remove polaris10_smc/smumgr split. move functions in polaris_smc.c to polaris10_smumgr.c and make all functions in polaris10_smumgr.c static. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/Makefile | 2 +- .../gpu/drm/amd/powerplay/smumgr/polaris10_smc.c | 2354 -------------------- .../gpu/drm/amd/powerplay/smumgr/polaris10_smc.h | 44 - .../drm/amd/powerplay/smumgr/polaris10_smumgr.c | 2226 +++++++++++++++++- 4 files changed, 2226 insertions(+), 2400 deletions(-) delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c delete mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.h (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile index e3c783a07cbd..b24b0f203a51 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile @@ -3,7 +3,7 @@ # It provides the smu management services for the driver. SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o \ - polaris10_smumgr.o iceland_smumgr.o polaris10_smc.o \ + polaris10_smumgr.o iceland_smumgr.o \ smu7_smumgr.o vega10_smumgr.o rv_smumgr.o ci_smumgr.o AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c deleted file mode 100644 index 113cadbb722e..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c +++ /dev/null @@ -1,2354 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "pp_debug.h" -#include "polaris10_smc.h" -#include "smu7_dyn_defaults.h" - -#include "smu7_hwmgr.h" -#include "hardwaremanager.h" -#include "ppatomctrl.h" -#include "cgs_common.h" -#include "atombios.h" -#include "polaris10_smumgr.h" -#include "pppcielanes.h" - -#include "smu_ucode_xfer_vi.h" -#include "smu74_discrete.h" -#include "smu/smu_7_1_3_d.h" -#include "smu/smu_7_1_3_sh_mask.h" -#include "gmc/gmc_8_1_d.h" -#include "gmc/gmc_8_1_sh_mask.h" -#include "oss/oss_3_0_d.h" -#include "gca/gfx_8_0_d.h" -#include "bif/bif_5_0_d.h" -#include "bif/bif_5_0_sh_mask.h" -#include "dce/dce_10_0_d.h" -#include "dce/dce_10_0_sh_mask.h" -#include "polaris10_pwrvirus.h" -#include "smu7_ppsmc.h" -#include "smu7_smumgr.h" - -#define POLARIS10_SMC_SIZE 0x20000 -#define VOLTAGE_VID_OFFSET_SCALE1 625 -#define VOLTAGE_VID_OFFSET_SCALE2 100 -#define POWERTUNE_DEFAULT_SET_MAX 1 -#define VDDC_VDDCI_DELTA 200 -#define MC_CG_ARB_FREQ_F1 0x0b - -static const struct polaris10_pt_defaults polaris10_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { - /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, - * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */ - { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, - { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61}, - { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } }, -}; - -static const sclkFcwRange_t Range_Table[NUM_SCLK_RANGE] = { - {VCO_2_4, POSTDIV_DIV_BY_16, 75, 160, 112}, - {VCO_3_6, POSTDIV_DIV_BY_16, 112, 224, 160}, - {VCO_2_4, POSTDIV_DIV_BY_8, 75, 160, 112}, - {VCO_3_6, POSTDIV_DIV_BY_8, 112, 224, 160}, - {VCO_2_4, POSTDIV_DIV_BY_4, 75, 160, 112}, - {VCO_3_6, POSTDIV_DIV_BY_4, 112, 216, 160}, - {VCO_2_4, POSTDIV_DIV_BY_2, 75, 160, 108}, - {VCO_3_6, POSTDIV_DIV_BY_2, 112, 216, 160} }; - -static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, - struct phm_ppt_v1_clock_voltage_dependency_table *dep_table, - uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd) -{ - uint32_t i; - uint16_t vddci; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - *voltage = *mvdd = 0; - - /* clock - voltage dependency table is empty table */ - if (dep_table->count == 0) - return -EINVAL; - - for (i = 0; i < dep_table->count; i++) { - /* find first sclk bigger than request */ - if (dep_table->entries[i].clk >= clock) { - *voltage |= (dep_table->entries[i].vddc * - VOLTAGE_SCALE) << VDDC_SHIFT; - if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) - *voltage |= (data->vbios_boot_state.vddci_bootup_value * - VOLTAGE_SCALE) << VDDCI_SHIFT; - else if (dep_table->entries[i].vddci) - *voltage |= (dep_table->entries[i].vddci * - VOLTAGE_SCALE) << VDDCI_SHIFT; - else { - vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), - (dep_table->entries[i].vddc - - (uint16_t)VDDC_VDDCI_DELTA)); - *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; - } - - if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) - *mvdd = data->vbios_boot_state.mvdd_bootup_value * - VOLTAGE_SCALE; - else if (dep_table->entries[i].mvdd) - *mvdd = (uint32_t) dep_table->entries[i].mvdd * - VOLTAGE_SCALE; - - *voltage |= 1 << PHASES_SHIFT; - return 0; - } - } - - /* sclk is bigger than max sclk in the dependence table */ - *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; - - if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) - *voltage |= (data->vbios_boot_state.vddci_bootup_value * - VOLTAGE_SCALE) << VDDCI_SHIFT; - else if (dep_table->entries[i-1].vddci) { - vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), - (dep_table->entries[i].vddc - - (uint16_t)VDDC_VDDCI_DELTA)); - *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; - } - - if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) - *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE; - else if (dep_table->entries[i].mvdd) - *mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE; - - return 0; -} - -static uint16_t scale_fan_gain_settings(uint16_t raw_setting) -{ - uint32_t tmp; - tmp = raw_setting * 4096 / 100; - return (uint16_t)tmp; -} - -static int polaris10_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - - const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; - SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; - struct pp_advance_fan_control_parameters *fan_table = - &hwmgr->thermal_controller.advanceFanControlParameters; - int i, j, k; - const uint16_t *pdef1; - const uint16_t *pdef2; - - table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128)); - table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128)); - - PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, - "Target Operating Temp is out of Range!", - ); - - table->TemperatureLimitEdge = PP_HOST_TO_SMC_US( - cac_dtp_table->usTargetOperatingTemp * 256); - table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US( - cac_dtp_table->usTemperatureLimitHotspot * 256); - table->FanGainEdge = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainEdge)); - table->FanGainHotspot = PP_HOST_TO_SMC_US( - scale_fan_gain_settings(fan_table->usFanGainHotspot)); - - pdef1 = defaults->BAPMTI_R; - pdef2 = defaults->BAPMTI_RC; - - for (i = 0; i < SMU74_DTE_ITERATIONS; i++) { - for (j = 0; j < SMU74_DTE_SOURCES; j++) { - for (k = 0; k < SMU74_DTE_SINKS; k++) { - table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1); - table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2); - pdef1++; - pdef2++; - } - } - } - - return 0; -} - -static int polaris10_populate_svi_load_line(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; - - smu_data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn; - smu_data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC; - smu_data->power_tune_table.SviLoadLineTrimVddC = 3; - smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; - - return 0; -} - -static int polaris10_populate_tdc_limit(struct pp_hwmgr *hwmgr) -{ - uint16_t tdc_limit; - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; - - tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128); - smu_data->power_tune_table.TDC_VDDC_PkgLimit = - CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); - smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = - defaults->TDC_VDDC_ThrottleReleaseLimitPerc; - smu_data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt; - - return 0; -} - -static int polaris10_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; - uint32_t temp; - - if (smu7_read_smc_sram_dword(hwmgr, - fuse_table_offset + - offsetof(SMU74_Discrete_PmFuses, TdcWaterfallCtl), - (uint32_t *)&temp, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", - return -EINVAL); - else { - smu_data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl; - smu_data->power_tune_table.LPMLTemperatureMin = - (uint8_t)((temp >> 16) & 0xff); - smu_data->power_tune_table.LPMLTemperatureMax = - (uint8_t)((temp >> 8) & 0xff); - smu_data->power_tune_table.Reserved = (uint8_t)(temp & 0xff); - } - return 0; -} - -static int polaris10_populate_temperature_scaler(struct pp_hwmgr *hwmgr) -{ - int i; - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - - /* Currently not used. Set all to zero. */ - for (i = 0; i < 16; i++) - smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0; - - return 0; -} - -static int polaris10_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - -/* TO DO move to hwmgr */ - if ((hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity & (1 << 15)) - || 0 == hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity) - hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity = - hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity; - - smu_data->power_tune_table.FuzzyFan_PwmSetDelta = PP_HOST_TO_SMC_US( - hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity); - return 0; -} - -static int polaris10_populate_gnb_lpml(struct pp_hwmgr *hwmgr) -{ - int i; - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - - /* Currently not used. Set all to zero. */ - for (i = 0; i < 16; i++) - smu_data->power_tune_table.GnbLPML[i] = 0; - - return 0; -} - -static int polaris10_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint16_t hi_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; - uint16_t lo_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; - struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; - - hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); - lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); - - smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = - CONVERT_FROM_HOST_TO_SMC_US(hi_sidd); - smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = - CONVERT_FROM_HOST_TO_SMC_US(lo_sidd); - - return 0; -} - -static int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - uint32_t pm_fuse_table_offset; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_PowerContainment)) { - if (smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU74_Firmware_Header, PmFuseTable), - &pm_fuse_table_offset, SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to get pm_fuse_table_offset Failed!", - return -EINVAL); - - if (polaris10_populate_svi_load_line(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate SviLoadLine Failed!", - return -EINVAL); - - if (polaris10_populate_tdc_limit(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TDCLimit Failed!", return -EINVAL); - - if (polaris10_populate_dw8(hwmgr, pm_fuse_table_offset)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate TdcWaterfallCtl, " - "LPMLTemperature Min and Max Failed!", - return -EINVAL); - - if (0 != polaris10_populate_temperature_scaler(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate LPMLTemperatureScaler Failed!", - return -EINVAL); - - if (polaris10_populate_fuzzy_fan(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate Fuzzy Fan Control parameters Failed!", - return -EINVAL); - - if (polaris10_populate_gnb_lpml(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate GnbLPML Failed!", - return -EINVAL); - - if (polaris10_populate_bapm_vddc_base_leakage_sidd(hwmgr)) - PP_ASSERT_WITH_CODE(false, - "Attempt to populate BapmVddCBaseLeakage Hi and Lo " - "Sidd Failed!", return -EINVAL); - - if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, - (uint8_t *)&smu_data->power_tune_table, - (sizeof(struct SMU74_Discrete_PmFuses) - 92), SMC_RAM_END)) - PP_ASSERT_WITH_CODE(false, - "Attempt to download PmFuseTable Failed!", - return -EINVAL); - } - return 0; -} - -/** - * Mvdd table preparation for SMC. - * - * @param *hwmgr The address of the hardware manager. - * @param *table The SMC DPM table structure to be populated. - * @return 0 - */ -static int polaris10_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, - SMU74_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t count, level; - - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) { - count = data->mvdd_voltage_table.count; - if (count > SMU_MAX_SMIO_LEVELS) - count = SMU_MAX_SMIO_LEVELS; - for (level = 0; level < count; level++) { - table->SmioTable2.Pattern[level].Voltage = - PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); - /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ - table->SmioTable2.Pattern[level].Smio = - (uint8_t) level; - table->Smio[level] |= - data->mvdd_voltage_table.entries[level].smio_low; - } - table->SmioMask2 = data->mvdd_voltage_table.mask_low; - - table->MvddLevelCount = (uint32_t) PP_HOST_TO_SMC_UL(count); - } - - return 0; -} - -static int polaris10_populate_smc_vddci_table(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - uint32_t count, level; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - count = data->vddci_voltage_table.count; - - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { - if (count > SMU_MAX_SMIO_LEVELS) - count = SMU_MAX_SMIO_LEVELS; - for (level = 0; level < count; ++level) { - table->SmioTable1.Pattern[level].Voltage = - PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[level].value * VOLTAGE_SCALE); - table->SmioTable1.Pattern[level].Smio = (uint8_t) level; - - table->Smio[level] |= data->vddci_voltage_table.entries[level].smio_low; - } - } - - table->SmioMask1 = data->vddci_voltage_table.mask_low; - - return 0; -} - -/** -* Preparation of vddc and vddgfx CAC tables for SMC. -* -* @param hwmgr the address of the hardware manager -* @param table the SMC DPM table structure to be populated -* @return always 0 -*/ -static int polaris10_populate_cac_table(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - uint32_t count; - uint8_t index; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_voltage_lookup_table *lookup_table = - table_info->vddc_lookup_table; - /* tables is already swapped, so in order to use the value from it, - * we need to swap it back. - * We are populating vddc CAC data to BapmVddc table - * in split and merged mode - */ - for (count = 0; count < lookup_table->count; count++) { - index = phm_get_voltage_index(lookup_table, - data->vddc_voltage_table.entries[count].value); - table->BapmVddcVidLoSidd[count] = convert_to_vid(lookup_table->entries[index].us_cac_low); - table->BapmVddcVidHiSidd[count] = convert_to_vid(lookup_table->entries[index].us_cac_mid); - table->BapmVddcVidHiSidd2[count] = convert_to_vid(lookup_table->entries[index].us_cac_high); - } - - return 0; -} - -/** -* Preparation of voltage tables for SMC. -* -* @param hwmgr the address of the hardware manager -* @param table the SMC DPM table structure to be populated -* @return always 0 -*/ - -static int polaris10_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - polaris10_populate_smc_vddci_table(hwmgr, table); - polaris10_populate_smc_mvdd_table(hwmgr, table); - polaris10_populate_cac_table(hwmgr, table); - - return 0; -} - -static int polaris10_populate_ulv_level(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_Ulv *state) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - state->CcPwrDynRm = 0; - state->CcPwrDynRm1 = 0; - - state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset; - state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset * - VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1); - - if (hwmgr->chip_id == CHIP_POLARIS12 || hwmgr->is_kicker) - state->VddcPhase = data->vddc_phase_shed_control ^ 0x3; - else - state->VddcPhase = (data->vddc_phase_shed_control) ? 0 : 1; - - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); - CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); - - return 0; -} - -static int polaris10_populate_ulv_state(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - return polaris10_populate_ulv_level(hwmgr, &table->Ulv); -} - -static int polaris10_populate_smc_link_level(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &data->dpm_table; - int i; - - /* Index (dpm_table->pcie_speed_table.count) - * is reserved for PCIE boot level. */ - for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { - table->LinkLevel[i].PcieGenSpeed = - (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; - table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width( - dpm_table->pcie_speed_table.dpm_levels[i].param1); - table->LinkLevel[i].EnabledForActivity = 1; - table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff); - table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5); - table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30); - } - - smu_data->smc_state_table.LinkLevelCount = - (uint8_t)dpm_table->pcie_speed_table.count; - -/* To Do move to hwmgr */ - data->dpm_level_enable_mask.pcie_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); - - return 0; -} - - -static void polaris10_get_sclk_range_table(struct pp_hwmgr *hwmgr, - SMU74_Discrete_DpmTable *table) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - uint32_t i, ref_clk; - - struct pp_atom_ctrl_sclk_range_table range_table_from_vbios = { { {0} } }; - - ref_clk = smu7_get_xclk(hwmgr); - - if (0 == atomctrl_get_smc_sclk_range_table(hwmgr, &range_table_from_vbios)) { - for (i = 0; i < NUM_SCLK_RANGE; i++) { - table->SclkFcwRangeTable[i].vco_setting = range_table_from_vbios.entry[i].ucVco_setting; - table->SclkFcwRangeTable[i].postdiv = range_table_from_vbios.entry[i].ucPostdiv; - table->SclkFcwRangeTable[i].fcw_pcc = range_table_from_vbios.entry[i].usFcw_pcc; - - table->SclkFcwRangeTable[i].fcw_trans_upper = range_table_from_vbios.entry[i].usFcw_trans_upper; - table->SclkFcwRangeTable[i].fcw_trans_lower = range_table_from_vbios.entry[i].usRcw_trans_lower; - - CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc); - CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper); - CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower); - } - return; - } - - for (i = 0; i < NUM_SCLK_RANGE; i++) { - smu_data->range_table[i].trans_lower_frequency = (ref_clk * Range_Table[i].fcw_trans_lower) >> Range_Table[i].postdiv; - smu_data->range_table[i].trans_upper_frequency = (ref_clk * Range_Table[i].fcw_trans_upper) >> Range_Table[i].postdiv; - - table->SclkFcwRangeTable[i].vco_setting = Range_Table[i].vco_setting; - table->SclkFcwRangeTable[i].postdiv = Range_Table[i].postdiv; - table->SclkFcwRangeTable[i].fcw_pcc = Range_Table[i].fcw_pcc; - - table->SclkFcwRangeTable[i].fcw_trans_upper = Range_Table[i].fcw_trans_upper; - table->SclkFcwRangeTable[i].fcw_trans_lower = Range_Table[i].fcw_trans_lower; - - CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc); - CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper); - CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower); - } -} - -/** -* Calculates the SCLK dividers using the provided engine clock -* -* @param hwmgr the address of the hardware manager -* @param clock the engine clock to use to populate the structure -* @param sclk the SMC SCLK structure to be populated -*/ -static int polaris10_calculate_sclk_params(struct pp_hwmgr *hwmgr, - uint32_t clock, SMU_SclkSetting *sclk_setting) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - const SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); - struct pp_atomctrl_clock_dividers_ai dividers; - uint32_t ref_clock; - uint32_t pcc_target_percent, pcc_target_freq, ss_target_percent, ss_target_freq; - uint8_t i; - int result; - uint64_t temp; - - sclk_setting->SclkFrequency = clock; - /* get the engine clock dividers for this clock value */ - result = atomctrl_get_engine_pll_dividers_ai(hwmgr, clock, ÷rs); - if (result == 0) { - sclk_setting->Fcw_int = dividers.usSclk_fcw_int; - sclk_setting->Fcw_frac = dividers.usSclk_fcw_frac; - sclk_setting->Pcc_fcw_int = dividers.usPcc_fcw_int; - sclk_setting->PllRange = dividers.ucSclkPllRange; - sclk_setting->Sclk_slew_rate = 0x400; - sclk_setting->Pcc_up_slew_rate = dividers.usPcc_fcw_slew_frac; - sclk_setting->Pcc_down_slew_rate = 0xffff; - sclk_setting->SSc_En = dividers.ucSscEnable; - sclk_setting->Fcw1_int = dividers.usSsc_fcw1_int; - sclk_setting->Fcw1_frac = dividers.usSsc_fcw1_frac; - sclk_setting->Sclk_ss_slew_rate = dividers.usSsc_fcw_slew_frac; - return result; - } - - ref_clock = smu7_get_xclk(hwmgr); - - for (i = 0; i < NUM_SCLK_RANGE; i++) { - if (clock > smu_data->range_table[i].trans_lower_frequency - && clock <= smu_data->range_table[i].trans_upper_frequency) { - sclk_setting->PllRange = i; - break; - } - } - - sclk_setting->Fcw_int = (uint16_t)((clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock); - temp = clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv; - temp <<= 0x10; - do_div(temp, ref_clock); - sclk_setting->Fcw_frac = temp & 0xffff; - - pcc_target_percent = 10; /* Hardcode 10% for now. */ - pcc_target_freq = clock - (clock * pcc_target_percent / 100); - sclk_setting->Pcc_fcw_int = (uint16_t)((pcc_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock); - - ss_target_percent = 2; /* Hardcode 2% for now. */ - sclk_setting->SSc_En = 0; - if (ss_target_percent) { - sclk_setting->SSc_En = 1; - ss_target_freq = clock - (clock * ss_target_percent / 100); - sclk_setting->Fcw1_int = (uint16_t)((ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock); - temp = ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv; - temp <<= 0x10; - do_div(temp, ref_clock); - sclk_setting->Fcw1_frac = temp & 0xffff; - } - - return 0; -} - -/** -* Populates single SMC SCLK structure using the provided engine clock -* -* @param hwmgr the address of the hardware manager -* @param clock the engine clock to use to populate the structure -* @param sclk the SMC SCLK structure to be populated -*/ - -static int polaris10_populate_single_graphic_level(struct pp_hwmgr *hwmgr, - uint32_t clock, uint16_t sclk_al_threshold, - struct SMU74_Discrete_GraphicsLevel *level) -{ - int result; - /* PP_Clocks minClocks; */ - uint32_t mvdd; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - SMU_SclkSetting curr_sclk_setting = { 0 }; - - result = polaris10_calculate_sclk_params(hwmgr, clock, &curr_sclk_setting); - - /* populate graphics levels */ - result = polaris10_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_sclk, clock, - &level->MinVoltage, &mvdd); - - PP_ASSERT_WITH_CODE((0 == result), - "can not find VDDC voltage value for " - "VDDC engine clock dependency table", - return result); - level->ActivityLevel = sclk_al_threshold; - - level->CcPwrDynRm = 0; - level->CcPwrDynRm1 = 0; - level->EnabledForActivity = 0; - level->EnabledForThrottle = 1; - level->UpHyst = 10; - level->DownHyst = 0; - level->VoltageDownHyst = 0; - level->PowerThrottle = 0; - data->display_timing.min_clock_in_sr = hwmgr->display_config.min_core_set_clock_in_sr; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) - level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock, - hwmgr->display_config.min_core_set_clock_in_sr); - - /* Default to slow, highest DPM level will be - * set to PPSMC_DISPLAY_WATERMARK_LOW later. - */ - if (data->update_up_hyst) - level->UpHyst = (uint8_t)data->up_hyst; - if (data->update_down_hyst) - level->DownHyst = (uint8_t)data->down_hyst; - - level->SclkSetting = curr_sclk_setting; - - CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage); - CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1); - CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(level->SclkSetting.SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_int); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_frac); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_fcw_int); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_slew_rate); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_up_slew_rate); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_down_slew_rate); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_int); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_frac); - CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_ss_slew_rate); - return 0; -} - -/** -* Populates all SMC SCLK levels' structure based on the trimmed allowed dpm engine clock states -* -* @param hwmgr the address of the hardware manager -*/ -int polaris10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &hw_data->dpm_table; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table; - uint8_t pcie_entry_cnt = (uint8_t) hw_data->dpm_table.pcie_speed_table.count; - int result = 0; - uint32_t array = smu_data->smu7_data.dpm_table_start + - offsetof(SMU74_Discrete_DpmTable, GraphicsLevel); - uint32_t array_size = sizeof(struct SMU74_Discrete_GraphicsLevel) * - SMU74_MAX_LEVELS_GRAPHICS; - struct SMU74_Discrete_GraphicsLevel *levels = - smu_data->smc_state_table.GraphicsLevel; - uint32_t i, max_entry; - uint8_t hightest_pcie_level_enabled = 0, - lowest_pcie_level_enabled = 0, - mid_pcie_level_enabled = 0, - count = 0; - - polaris10_get_sclk_range_table(hwmgr, &(smu_data->smc_state_table)); - - for (i = 0; i < dpm_table->sclk_table.count; i++) { - - result = polaris10_populate_single_graphic_level(hwmgr, - dpm_table->sclk_table.dpm_levels[i].value, - (uint16_t)smu_data->activity_target[i], - &(smu_data->smc_state_table.GraphicsLevel[i])); - if (result) - return result; - - /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ - if (i > 1) - levels[i].DeepSleepDivId = 0; - } - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SPLLShutdownSupport)) - smu_data->smc_state_table.GraphicsLevel[0].SclkSetting.SSc_En = 0; - - smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; - smu_data->smc_state_table.GraphicsDpmLevelCount = - (uint8_t)dpm_table->sclk_table.count; - hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); - - - if (pcie_table != NULL) { - PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt), - "There must be 1 or more PCIE levels defined in PPTable.", - return -EINVAL); - max_entry = pcie_entry_cnt - 1; - for (i = 0; i < dpm_table->sclk_table.count; i++) - levels[i].pcieDpmLevel = - (uint8_t) ((i < max_entry) ? i : max_entry); - } else { - while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask && - ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << (hightest_pcie_level_enabled + 1))) != 0)) - hightest_pcie_level_enabled++; - - while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask && - ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << lowest_pcie_level_enabled)) == 0)) - lowest_pcie_level_enabled++; - - while ((count < hightest_pcie_level_enabled) && - ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask & - (1 << (lowest_pcie_level_enabled + 1 + count))) == 0)) - count++; - - mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1 + count) < - hightest_pcie_level_enabled ? - (lowest_pcie_level_enabled + 1 + count) : - hightest_pcie_level_enabled; - - /* set pcieDpmLevel to hightest_pcie_level_enabled */ - for (i = 2; i < dpm_table->sclk_table.count; i++) - levels[i].pcieDpmLevel = hightest_pcie_level_enabled; - - /* set pcieDpmLevel to lowest_pcie_level_enabled */ - levels[0].pcieDpmLevel = lowest_pcie_level_enabled; - - /* set pcieDpmLevel to mid_pcie_level_enabled */ - levels[1].pcieDpmLevel = mid_pcie_level_enabled; - } - /* level count will send to smc once at init smc table and never change */ - result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - (uint32_t)array_size, SMC_RAM_END); - - return result; -} - - -static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr, - uint32_t clock, struct SMU74_Discrete_MemoryLevel *mem_level) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - int result = 0; - struct cgs_display_info info = {0, 0, NULL}; - uint32_t mclk_stutter_mode_threshold = 40000; - - cgs_get_active_displays_info(hwmgr->device, &info); - - if (table_info->vdd_dep_on_mclk) { - result = polaris10_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_mclk, clock, - &mem_level->MinVoltage, &mem_level->MinMvdd); - PP_ASSERT_WITH_CODE((0 == result), - "can not find MinVddc voltage value from memory " - "VDDC voltage dependency table", return result); - } - - mem_level->MclkFrequency = clock; - mem_level->EnabledForThrottle = 1; - mem_level->EnabledForActivity = 0; - mem_level->UpHyst = 0; - mem_level->DownHyst = 100; - mem_level->VoltageDownHyst = 0; - mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target; - mem_level->StutterEnable = false; - mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; - - data->display_timing.num_existing_displays = info.display_count; - - if (mclk_stutter_mode_threshold && - (clock <= mclk_stutter_mode_threshold) && - (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, - STUTTER_ENABLE) & 0x1)) - mem_level->StutterEnable = true; - - if (!result) { - CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinMvdd); - CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(mem_level->ActivityLevel); - CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinVoltage); - } - return result; -} - -/** -* Populates all SMC MCLK levels' structure based on the trimmed allowed dpm memory clock states -* -* @param hwmgr the address of the hardware manager -*/ -int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct smu7_dpm_table *dpm_table = &hw_data->dpm_table; - int result; - /* populate MCLK dpm table to SMU7 */ - uint32_t array = smu_data->smu7_data.dpm_table_start + - offsetof(SMU74_Discrete_DpmTable, MemoryLevel); - uint32_t array_size = sizeof(SMU74_Discrete_MemoryLevel) * - SMU74_MAX_LEVELS_MEMORY; - struct SMU74_Discrete_MemoryLevel *levels = - smu_data->smc_state_table.MemoryLevel; - uint32_t i; - - for (i = 0; i < dpm_table->mclk_table.count; i++) { - PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), - "can not populate memory level as memory clock is zero", - return -EINVAL); - result = polaris10_populate_single_memory_level(hwmgr, - dpm_table->mclk_table.dpm_levels[i].value, - &levels[i]); - if (i == dpm_table->mclk_table.count - 1) { - levels[i].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; - levels[i].EnabledForActivity = 1; - } - if (result) - return result; - } - - /* In order to prevent MC activity from stutter mode to push DPM up, - * the UVD change complements this by putting the MCLK in - * a higher state by default such that we are not affected by - * up threshold or and MCLK DPM latency. - */ - levels[0].ActivityLevel = 0x1f; - CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel); - - smu_data->smc_state_table.MemoryDpmLevelCount = - (uint8_t)dpm_table->mclk_table.count; - hw_data->dpm_level_enable_mask.mclk_dpm_enable_mask = - phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); - - /* level count will send to smc once at init smc table and never change */ - result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - (uint32_t)array_size, SMC_RAM_END); - - return result; -} - -/** -* Populates the SMC MVDD structure using the provided memory clock. -* -* @param hwmgr the address of the hardware manager -* @param mclk the MCLK value to be used in the decision if MVDD should be high or low. -* @param voltage the SMC VOLTAGE structure to be populated -*/ -static int polaris10_populate_mvdd_value(struct pp_hwmgr *hwmgr, - uint32_t mclk, SMIO_Pattern *smio_pat) -{ - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint32_t i = 0; - - if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { - /* find mvdd value which clock is more than request */ - for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) { - if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) { - smio_pat->Voltage = data->mvdd_voltage_table.entries[i].value; - break; - } - } - PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count, - "MVDD Voltage is outside the supported range.", - return -EINVAL); - } else - return -EINVAL; - - return 0; -} - -static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, - SMU74_Discrete_DpmTable *table) -{ - int result = 0; - uint32_t sclk_frequency; - const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - SMIO_Pattern vol_level; - uint32_t mvdd; - uint16_t us_mvdd; - - table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; - - /* Get MinVoltage and Frequency from DPM0, - * already converted to SMC_UL */ - sclk_frequency = data->vbios_boot_state.sclk_bootup_value; - result = polaris10_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_sclk, - sclk_frequency, - &table->ACPILevel.MinVoltage, &mvdd); - PP_ASSERT_WITH_CODE((0 == result), - "Cannot find ACPI VDDC voltage value " - "in Clock Dependency Table", - ); - - result = polaris10_calculate_sclk_params(hwmgr, sclk_frequency, &(table->ACPILevel.SclkSetting)); - PP_ASSERT_WITH_CODE(result == 0, "Error retrieving Engine Clock dividers from VBIOS.", return result); - - table->ACPILevel.DeepSleepDivId = 0; - table->ACPILevel.CcPwrDynRm = 0; - table->ACPILevel.CcPwrDynRm1 = 0; - - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.MinVoltage); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); - - CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkSetting.SclkFrequency); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_int); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_frac); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_fcw_int); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_slew_rate); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_up_slew_rate); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_down_slew_rate); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_int); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac); - CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate); - - - /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */ - table->MemoryACPILevel.MclkFrequency = data->vbios_boot_state.mclk_bootup_value; - result = polaris10_get_dependency_volt_by_clk(hwmgr, - table_info->vdd_dep_on_mclk, - table->MemoryACPILevel.MclkFrequency, - &table->MemoryACPILevel.MinVoltage, &mvdd); - PP_ASSERT_WITH_CODE((0 == result), - "Cannot find ACPI VDDCI voltage value " - "in Clock Dependency Table", - ); - - us_mvdd = 0; - if ((SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) || - (data->mclk_dpm_key_disabled)) - us_mvdd = data->vbios_boot_state.mvdd_bootup_value; - else { - if (!polaris10_populate_mvdd_value(hwmgr, - data->dpm_table.mclk_table.dpm_levels[0].value, - &vol_level)) - us_mvdd = vol_level.Voltage; - } - - if (0 == polaris10_populate_mvdd_value(hwmgr, 0, &vol_level)) - table->MemoryACPILevel.MinMvdd = PP_HOST_TO_SMC_UL(vol_level.Voltage); - else - table->MemoryACPILevel.MinMvdd = 0; - - table->MemoryACPILevel.StutterEnable = false; - - table->MemoryACPILevel.EnabledForThrottle = 0; - table->MemoryACPILevel.EnabledForActivity = 0; - table->MemoryACPILevel.UpHyst = 0; - table->MemoryACPILevel.DownHyst = 100; - table->MemoryACPILevel.VoltageDownHyst = 0; - table->MemoryACPILevel.ActivityLevel = - PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); - - CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage); - - return result; -} - -static int polaris10_populate_smc_vce_level(struct pp_hwmgr *hwmgr, - SMU74_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - table_info->mm_dep_table; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t vddci; - - table->VceLevelCount = (uint8_t)(mm_table->count); - table->VceBootLevel = 0; - - for (count = 0; count < table->VceLevelCount; count++) { - table->VceLevel[count].Frequency = mm_table->entries[count].eclk; - table->VceLevel[count].MinVoltage = 0; - table->VceLevel[count].MinVoltage |= - (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; - - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) - vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); - else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) - vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; - else - vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; - - - table->VceLevel[count].MinVoltage |= - (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; - table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT; - - /*retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->VceLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for VCE engine clock", - return result); - - table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage); - } - return result; -} - - -static int polaris10_populate_smc_samu_level(struct pp_hwmgr *hwmgr, - SMU74_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - table_info->mm_dep_table; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t vddci; - - table->SamuBootLevel = 0; - table->SamuLevelCount = (uint8_t)(mm_table->count); - - for (count = 0; count < table->SamuLevelCount; count++) { - /* not sure whether we need evclk or not */ - table->SamuLevel[count].MinVoltage = 0; - table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; - table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * - VOLTAGE_SCALE) << VDDC_SHIFT; - - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) - vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); - else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) - vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; - else - vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; - - table->SamuLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; - table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->SamuLevel[count].Frequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for samu clock", return result); - - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage); - } - return result; -} - -static int polaris10_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr, - int32_t eng_clock, int32_t mem_clock, - SMU74_Discrete_MCArbDramTimingTableEntry *arb_regs) -{ - uint32_t dram_timing; - uint32_t dram_timing2; - uint32_t burst_time; - int result; - - result = atomctrl_set_engine_dram_timings_rv770(hwmgr, - eng_clock, mem_clock); - PP_ASSERT_WITH_CODE(result == 0, - "Error calling VBIOS to set DRAM_TIMING.", return result); - - dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); - dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); - burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); - - - arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dram_timing); - arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dram_timing2); - arb_regs->McArbBurstTime = (uint8_t)burst_time; - - return 0; -} - -static int polaris10_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct SMU74_Discrete_MCArbDramTimingTable arb_regs; - uint32_t i, j; - int result = 0; - - for (i = 0; i < hw_data->dpm_table.sclk_table.count; i++) { - for (j = 0; j < hw_data->dpm_table.mclk_table.count; j++) { - result = polaris10_populate_memory_timing_parameters(hwmgr, - hw_data->dpm_table.sclk_table.dpm_levels[i].value, - hw_data->dpm_table.mclk_table.dpm_levels[j].value, - &arb_regs.entries[i][j]); - if (result == 0) - result = atomctrl_set_ac_timing_ai(hwmgr, hw_data->dpm_table.mclk_table.dpm_levels[j].value, j); - if (result != 0) - return result; - } - } - - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.arb_table_start, - (uint8_t *)&arb_regs, - sizeof(SMU74_Discrete_MCArbDramTimingTable), - SMC_RAM_END); - return result; -} - -static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - int result = -EINVAL; - uint8_t count; - struct pp_atomctrl_clock_dividers_vi dividers; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = - table_info->mm_dep_table; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t vddci; - - table->UvdLevelCount = (uint8_t)(mm_table->count); - table->UvdBootLevel = 0; - - for (count = 0; count < table->UvdLevelCount; count++) { - table->UvdLevel[count].MinVoltage = 0; - table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; - table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; - table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * - VOLTAGE_SCALE) << VDDC_SHIFT; - - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) - vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); - else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) - vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; - else - vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; - - table->UvdLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; - table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT; - - /* retrieve divider value for VBIOS */ - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->UvdLevel[count].VclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for Vclk clock", return result); - - table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; - - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, - table->UvdLevel[count].DclkFrequency, ÷rs); - PP_ASSERT_WITH_CODE((0 == result), - "can not find divide id for Dclk clock", return result); - - table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider; - - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); - CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage); - } - - return result; -} - -static int polaris10_populate_smc_boot_level(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - int result = 0; - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - table->GraphicsBootLevel = 0; - table->MemoryBootLevel = 0; - - /* find boot level from dpm table */ - result = phm_find_boot_level(&(data->dpm_table.sclk_table), - data->vbios_boot_state.sclk_bootup_value, - (uint32_t *)&(table->GraphicsBootLevel)); - - result = phm_find_boot_level(&(data->dpm_table.mclk_table), - data->vbios_boot_state.mclk_bootup_value, - (uint32_t *)&(table->MemoryBootLevel)); - - table->BootVddc = data->vbios_boot_state.vddc_bootup_value * - VOLTAGE_SCALE; - table->BootVddci = data->vbios_boot_state.vddci_bootup_value * - VOLTAGE_SCALE; - table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value * - VOLTAGE_SCALE; - - CONVERT_FROM_HOST_TO_SMC_US(table->BootVddc); - CONVERT_FROM_HOST_TO_SMC_US(table->BootVddci); - CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd); - - return 0; -} - -static int polaris10_populate_smc_initailial_state(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - uint8_t count, level; - - count = (uint8_t)(table_info->vdd_dep_on_sclk->count); - - for (level = 0; level < count; level++) { - if (table_info->vdd_dep_on_sclk->entries[level].clk >= - hw_data->vbios_boot_state.sclk_bootup_value) { - smu_data->smc_state_table.GraphicsBootLevel = level; - break; - } - } - - count = (uint8_t)(table_info->vdd_dep_on_mclk->count); - for (level = 0; level < count; level++) { - if (table_info->vdd_dep_on_mclk->entries[level].clk >= - hw_data->vbios_boot_state.mclk_bootup_value) { - smu_data->smc_state_table.MemoryBootLevel = level; - break; - } - } - - return 0; -} - - -static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) -{ - uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min; - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - - uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = - table_info->vdd_dep_on_sclk; - - stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount; - - /* Read SMU_Eefuse to read and calculate RO and determine - * if the part is SS or FF. if RO >= 1660MHz, part is FF. - */ - efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixSMU_EFUSE_0 + (67 * 4)); - efuse &= 0xFF000000; - efuse = efuse >> 24; - - if (hwmgr->chip_id == CHIP_POLARIS10) { - min = 1000; - max = 2300; - } else { - min = 1100; - max = 2100; - } - - ro = efuse * (max - min) / 255 + min; - - /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ - for (i = 0; i < sclk_table->count; i++) { - smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= - sclk_table->entries[i].cks_enable << i; - if (hwmgr->chip_id == CHIP_POLARIS10) { - volt_without_cks = (uint32_t)((2753594000U + (sclk_table->entries[i].clk/100) * 136418 - (ro - 70) * 1000000) / \ - (2424180 - (sclk_table->entries[i].clk/100) * 1132925/1000)); - volt_with_cks = (uint32_t)((2797202000U + sclk_table->entries[i].clk/100 * 3232 - (ro - 65) * 1000000) / \ - (2522480 - sclk_table->entries[i].clk/100 * 115764/100)); - } else { - volt_without_cks = (uint32_t)((2416794800U + (sclk_table->entries[i].clk/100) * 1476925/10 - (ro - 50) * 1000000) / \ - (2625416 - (sclk_table->entries[i].clk/100) * (12586807/10000))); - volt_with_cks = (uint32_t)((2999656000U - sclk_table->entries[i].clk/100 * 392803 - (ro - 44) * 1000000) / \ - (3422454 - sclk_table->entries[i].clk/100 * (18886376/10000))); - } - - if (volt_without_cks >= volt_with_cks) - volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + - sclk_table->entries[i].cks_voffset) * 100 + 624) / 625); - - smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; - } - - smu_data->smc_state_table.LdoRefSel = (table_info->cac_dtp_table->ucCKS_LDO_REFSEL != 0) ? table_info->cac_dtp_table->ucCKS_LDO_REFSEL : 6; - /* Populate CKS Lookup Table */ - if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) - stretch_amount2 = 0; - else if (stretch_amount == 3 || stretch_amount == 4) - stretch_amount2 = 1; - else { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ClockStretcher); - PP_ASSERT_WITH_CODE(false, - "Stretch Amount in PPTable not supported\n", - return -EINVAL); - } - - value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL); - value &= 0xFFFFFFFE; - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value); - - return 0; -} - -/** -* Populates the SMC VRConfig field in DPM table. -* -* @param hwmgr the address of the hardware manager -* @param table the SMC DPM table structure to be populated -* @return always 0 -*/ -static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr, - struct SMU74_Discrete_DpmTable *table) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - uint16_t config; - - config = VR_MERGED_WITH_VDDC; - table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT); - - /* Set Vddc Voltage Controller */ - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) { - config = VR_SVI2_PLANE_1; - table->VRConfig |= config; - } else { - PP_ASSERT_WITH_CODE(false, - "VDDC should be on SVI2 control in merged mode!", - ); - } - /* Set Vddci Voltage Controller */ - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { - config = VR_SVI2_PLANE_2; /* only in merged mode */ - table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); - } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { - config = VR_SMIO_PATTERN_1; - table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); - } else { - config = VR_STATIC_VOLTAGE; - table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); - } - /* Set Mvdd Voltage Controller */ - if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) { - config = VR_SVI2_PLANE_2; - table->VRConfig |= (config << VRCONF_MVDD_SHIFT); - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, smu_data->smu7_data.soft_regs_start + - offsetof(SMU74_SoftRegisters, AllowMvddSwitch), 0x1); - } else { - config = VR_STATIC_VOLTAGE; - table->VRConfig |= (config << VRCONF_MVDD_SHIFT); - } - - return 0; -} - - -static int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - - SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); - int result = 0; - struct pp_atom_ctrl__avfs_parameters avfs_params = {0}; - AVFS_meanNsigma_t AVFS_meanNsigma = { {0} }; - AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} }; - uint32_t tmp, i; - - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)hwmgr->pptable; - struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = - table_info->vdd_dep_on_sclk; - - - if (((struct smu7_smumgr *)smu_data)->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED) - return result; - - result = atomctrl_get_avfs_information(hwmgr, &avfs_params); - - if (0 == result) { - table->BTCGB_VDROOP_TABLE[0].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0); - table->BTCGB_VDROOP_TABLE[0].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1); - table->BTCGB_VDROOP_TABLE[0].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2); - table->BTCGB_VDROOP_TABLE[1].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0); - table->BTCGB_VDROOP_TABLE[1].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1); - table->BTCGB_VDROOP_TABLE[1].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2); - table->AVFSGB_VDROOP_TABLE[0].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1); - table->AVFSGB_VDROOP_TABLE[0].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2); - table->AVFSGB_VDROOP_TABLE[0].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b); - table->AVFSGB_VDROOP_TABLE[0].m1_shift = 24; - table->AVFSGB_VDROOP_TABLE[0].m2_shift = 12; - table->AVFSGB_VDROOP_TABLE[1].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1); - table->AVFSGB_VDROOP_TABLE[1].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2); - table->AVFSGB_VDROOP_TABLE[1].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b); - table->AVFSGB_VDROOP_TABLE[1].m1_shift = 24; - table->AVFSGB_VDROOP_TABLE[1].m2_shift = 12; - table->MaxVoltage = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv); - AVFS_meanNsigma.Aconstant[0] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0); - AVFS_meanNsigma.Aconstant[1] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1); - AVFS_meanNsigma.Aconstant[2] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2); - AVFS_meanNsigma.DC_tol_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma); - AVFS_meanNsigma.Platform_mean = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean); - AVFS_meanNsigma.PSM_Age_CompFactor = PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor); - AVFS_meanNsigma.Platform_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma); - - for (i = 0; i < NUM_VFT_COLUMNS; i++) { - AVFS_meanNsigma.Static_Voltage_Offset[i] = (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625); - AVFS_SclkOffset.Sclk_Offset[i] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table->entries[i].sclk_offset) / 100); - } - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsMeanNSigma), - &tmp, SMC_RAM_END); - - smu7_copy_bytes_to_smc(hwmgr, - tmp, - (uint8_t *)&AVFS_meanNsigma, - sizeof(AVFS_meanNsigma_t), - SMC_RAM_END); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsSclkOffsetTable), - &tmp, SMC_RAM_END); - smu7_copy_bytes_to_smc(hwmgr, - tmp, - (uint8_t *)&AVFS_SclkOffset, - sizeof(AVFS_Sclk_Offset_t), - SMC_RAM_END); - - data->avfs_vdroop_override_setting = (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT) | - (avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) | - (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) | - (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT); - data->apply_avfs_cks_off_voltage = (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false; - } - return result; -} - - -/** -* Initialize the ARB DRAM timing table's index field. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ -static int polaris10_init_arb_table_index(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - uint32_t tmp; - int result; - - /* This is a read-modify-write on the first byte of the ARB table. - * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure - * is the field 'current'. - * This solution is ugly, but we never write the whole table only - * individual fields in it. - * In reality this field should not be in that structure - * but in a soft register. - */ - result = smu7_read_smc_sram_dword(hwmgr, - smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END); - - if (result) - return result; - - tmp &= 0x00FFFFFF; - tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; - - return smu7_write_smc_sram_dword(hwmgr, - smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END); -} - -static void polaris10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - if (table_info && - table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && - table_info->cac_dtp_table->usPowerTuneDataSetID) - smu_data->power_tune_defaults = - &polaris10_power_tune_data_set_array - [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; - else - smu_data->power_tune_defaults = &polaris10_power_tune_data_set_array[0]; - -} - -static void polaris10_save_default_power_profile(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct SMU74_Discrete_GraphicsLevel *levels = - data->smc_state_table.GraphicsLevel; - unsigned min_level = 1; - - hwmgr->default_gfx_power_profile.activity_threshold = - be16_to_cpu(levels[0].ActivityLevel); - hwmgr->default_gfx_power_profile.up_hyst = levels[0].UpHyst; - hwmgr->default_gfx_power_profile.down_hyst = levels[0].DownHyst; - hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE; - - hwmgr->default_compute_power_profile = hwmgr->default_gfx_power_profile; - hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE; - - /* Workaround compute SDMA instability: disable lowest SCLK - * DPM level. Optimize compute power profile: Use only highest - * 2 power levels (if more than 2 are available), Hysteresis: - * 0ms up, 5ms down - */ - if (data->smc_state_table.GraphicsDpmLevelCount > 2) - min_level = data->smc_state_table.GraphicsDpmLevelCount - 2; - else if (data->smc_state_table.GraphicsDpmLevelCount == 2) - min_level = 1; - else - min_level = 0; - hwmgr->default_compute_power_profile.min_sclk = - be32_to_cpu(levels[min_level].SclkSetting.SclkFrequency); - hwmgr->default_compute_power_profile.up_hyst = 0; - hwmgr->default_compute_power_profile.down_hyst = 5; - - hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile; - hwmgr->compute_power_profile = hwmgr->default_compute_power_profile; -} - -/** -* Initializes the SMC table and uploads it -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ -int polaris10_init_smc_table(struct pp_hwmgr *hwmgr) -{ - int result; - struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); - uint8_t i; - struct pp_atomctrl_gpio_pin_assignment gpio_pin; - pp_atomctrl_clock_dividers_vi dividers; - - polaris10_initialize_power_tune_defaults(hwmgr); - - if (SMU7_VOLTAGE_CONTROL_NONE != hw_data->voltage_control) - polaris10_populate_smc_voltage_tables(hwmgr, table); - - table->SystemFlags = 0; - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StepVddc)) - table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; - - if (hw_data->is_memory_gddr5) - table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; - - if (hw_data->ulv_supported && table_info->us_ulv_voltage_offset) { - result = polaris10_populate_ulv_state(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ULV state!", return result); - cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, - ixCG_ULV_PARAMETER, SMU7_CGULVPARAMETER_DFLT); - } - - result = polaris10_populate_smc_link_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Link Level!", return result); - - result = polaris10_populate_all_graphic_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Graphics Level!", return result); - - result = polaris10_populate_all_memory_levels(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Memory Level!", return result); - - result = polaris10_populate_smc_acpi_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize ACPI Level!", return result); - - result = polaris10_populate_smc_vce_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize VCE Level!", return result); - - result = polaris10_populate_smc_samu_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize SAMU Level!", return result); - - /* Since only the initial state is completely set up at this point - * (the other states are just copies of the boot state) we only - * need to populate the ARB settings for the initial state. - */ - result = polaris10_program_memory_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to Write ARB settings for the initial state.", return result); - - result = polaris10_populate_smc_uvd_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize UVD Level!", return result); - - result = polaris10_populate_smc_boot_level(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Boot Level!", return result); - - result = polaris10_populate_smc_initailial_state(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to initialize Boot State!", return result); - - result = polaris10_populate_bapm_parameters_in_dpm_table(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate BAPM Parameters!", return result); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ClockStretcher)) { - result = polaris10_populate_clock_stretcher_data_table(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate Clock Stretcher Data Table!", - return result); - } - - result = polaris10_populate_avfs_parameters(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, "Failed to populate AVFS Parameters!", return result;); - - table->CurrSclkPllRange = 0xff; - table->GraphicsVoltageChangeEnable = 1; - table->GraphicsThermThrottleEnable = 1; - table->GraphicsInterval = 1; - table->VoltageInterval = 1; - table->ThermalInterval = 1; - table->TemperatureLimitHigh = - table_info->cac_dtp_table->usTargetOperatingTemp * - SMU7_Q88_FORMAT_CONVERSION_UNIT; - table->TemperatureLimitLow = - (table_info->cac_dtp_table->usTargetOperatingTemp - 1) * - SMU7_Q88_FORMAT_CONVERSION_UNIT; - table->MemoryVoltageChangeEnable = 1; - table->MemoryInterval = 1; - table->VoltageResponseTime = 0; - table->PhaseResponseTime = 0; - table->MemoryThermThrottleEnable = 1; - table->PCIeBootLinkLevel = 0; - table->PCIeGenInterval = 1; - table->VRConfig = 0; - - result = polaris10_populate_vr_config(hwmgr, table); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate VRConfig setting!", return result); - - table->ThermGpio = 17; - table->SclkStepSize = 0x4000; - - if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) { - table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift; - } else { - table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_RegulatorHot); - } - - if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID, - &gpio_pin)) { - table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift; - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition); - } else { - table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_AutomaticDCTransition); - } - - /* Thermal Output GPIO */ - if (atomctrl_get_pp_assign_pin(hwmgr, THERMAL_INT_OUTPUT_GPIO_PINID, - &gpio_pin)) { - phm_cap_set(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_ThermalOutGPIO); - - table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift; - - /* For porlarity read GPIOPAD_A with assigned Gpio pin - * since VBIOS will program this register to set 'inactive state', - * driver can then determine 'active state' from this and - * program SMU with correct polarity - */ - table->ThermOutPolarity = (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) - & (1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0; - table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY; - - /* if required, combine VRHot/PCC with thermal out GPIO */ - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_RegulatorHot) - && phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_CombinePCCWithThermalSignal)) - table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT; - } else { - table->ThermOutGpio = 17; - table->ThermOutPolarity = 1; - table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE; - } - - /* Populate BIF_SCLK levels into SMC DPM table */ - for (i = 0; i <= hw_data->dpm_table.pcie_speed_table.count; i++) { - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, smu_data->bif_sclk_table[i], ÷rs); - PP_ASSERT_WITH_CODE((result == 0), "Can not find DFS divide id for Sclk", return result); - - if (i == 0) - table->Ulv.BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider)); - else - table->LinkLevel[i-1].BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider)); - } - - for (i = 0; i < SMU74_MAX_ENTRIES_SMIO; i++) - table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]); - - CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); - CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1); - CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2); - CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); - CONVERT_FROM_HOST_TO_SMC_UL(table->CurrSclkPllRange); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); - CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); - CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); - CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); - - /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ - result = smu7_copy_bytes_to_smc(hwmgr, - smu_data->smu7_data.dpm_table_start + - offsetof(SMU74_Discrete_DpmTable, SystemFlags), - (uint8_t *)&(table->SystemFlags), - sizeof(SMU74_Discrete_DpmTable) - 3 * sizeof(SMU74_PIDController), - SMC_RAM_END); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to upload dpm data to SMC memory!", return result); - - result = polaris10_init_arb_table_index(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to upload arb data to SMC memory!", return result); - - result = polaris10_populate_pm_fuses(hwmgr); - PP_ASSERT_WITH_CODE(0 == result, - "Failed to populate PM fuses to SMC memory!", return result); - - polaris10_save_default_power_profile(hwmgr); - - return 0; -} - -static int polaris10_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (data->need_update_smu7_dpm_table & - (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) - return polaris10_program_memory_timing_parameters(hwmgr); - - return 0; -} - -int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr) -{ - int ret; - struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - - if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED) - return 0; - - ret = smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting); - - ret = (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs) == 0) ? - 0 : -1; - - if (!ret) - /* If this param is not changed, this function could fire unnecessarily */ - smu_data->avfs.avfs_btc_status = AVFS_BTC_COMPLETED_PREVIOUSLY; - - return ret; -} - -/** -* Set up the fan table to control the fan using the SMC. -* @param hwmgr the address of the powerplay hardware manager. -* @param pInput the pointer to input data -* @param pOutput the pointer to output data -* @param pStorage the pointer to temporary storage -* @param Result the last failure code -* @return result from set temperature range routine -*/ -int polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - SMU74_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; - uint32_t duty100; - uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; - uint16_t fdo_min, slope1, slope2; - uint32_t reference_clock; - int res; - uint64_t tmp64; - - if (hwmgr->thermal_controller.fanInfo.bNoFan) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - if (smu_data->smu7_data.fan_table_start == 0) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, - CG_FDO_CTRL1, FMAX_DUTY100); - - if (duty100 == 0) { - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - return 0; - } - - tmp64 = hwmgr->thermal_controller.advanceFanControlParameters. - usPWMMin * duty100; - do_div(tmp64, 10000); - fdo_min = (uint16_t)tmp64; - - t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - - hwmgr->thermal_controller.advanceFanControlParameters.usTMin; - t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - - hwmgr->thermal_controller.advanceFanControlParameters.usTMed; - - pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; - pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; - - slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); - slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); - - fan_table.TempMin = cpu_to_be16((50 + hwmgr-> - thermal_controller.advanceFanControlParameters.usTMin) / 100); - fan_table.TempMed = cpu_to_be16((50 + hwmgr-> - thermal_controller.advanceFanControlParameters.usTMed) / 100); - fan_table.TempMax = cpu_to_be16((50 + hwmgr-> - thermal_controller.advanceFanControlParameters.usTMax) / 100); - - fan_table.Slope1 = cpu_to_be16(slope1); - fan_table.Slope2 = cpu_to_be16(slope2); - - fan_table.FdoMin = cpu_to_be16(fdo_min); - - fan_table.HystDown = cpu_to_be16(hwmgr-> - thermal_controller.advanceFanControlParameters.ucTHyst); - - fan_table.HystUp = cpu_to_be16(1); - - fan_table.HystSlope = cpu_to_be16(1); - - fan_table.TempRespLim = cpu_to_be16(5); - - reference_clock = smu7_get_xclk(hwmgr); - - fan_table.RefreshPeriod = cpu_to_be32((hwmgr-> - thermal_controller.advanceFanControlParameters.ulCycleDelay * - reference_clock) / 1600); - - fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); - - fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD( - hwmgr->device, CGS_IND_REG__SMC, - CG_MULT_THERMAL_CTRL, TEMP_SEL); - - res = smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.fan_table_start, - (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), - SMC_RAM_END); - - if (!res && hwmgr->thermal_controller. - advanceFanControlParameters.ucMinimumPWMLimit) - res = smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetFanMinPwm, - hwmgr->thermal_controller. - advanceFanControlParameters.ucMinimumPWMLimit); - - if (!res && hwmgr->thermal_controller. - advanceFanControlParameters.ulMinFanSCLKAcousticLimit) - res = smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetFanSclkTarget, - hwmgr->thermal_controller. - advanceFanControlParameters.ulMinFanSCLKAcousticLimit); - - if (res) - phm_cap_unset(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_MicrocodeFanControl); - - return 0; -} - -static int polaris10_update_uvd_smc_table(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - smu_data->smc_state_table.UvdBootLevel = 0; - if (table_info->mm_dep_table->count > 0) - smu_data->smc_state_table.UvdBootLevel = - (uint8_t) (table_info->mm_dep_table->count - 1); - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + offsetof(SMU74_Discrete_DpmTable, - UvdBootLevel); - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0x00FFFFFF; - mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_UVDDPM) || - phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_UVDDPM_SetEnabledMask, - (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel)); - return 0; -} - -static int polaris10_update_vce_smc_table(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smu_data->smc_state_table.VceBootLevel = - (uint8_t) (table_info->mm_dep_table->count - 1); - else - smu_data->smc_state_table.VceBootLevel = 0; - - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + - offsetof(SMU74_Discrete_DpmTable, VceBootLevel); - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0xFF00FFFF; - mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_VCEDPM_SetEnabledMask, - (uint32_t)1 << smu_data->smc_state_table.VceBootLevel); - return 0; -} - -static int polaris10_update_samu_smc_table(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - uint32_t mm_boot_level_offset, mm_boot_level_value; - - - smu_data->smc_state_table.SamuBootLevel = 0; - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + - offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); - - mm_boot_level_offset /= 4; - mm_boot_level_offset *= 4; - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset); - mm_boot_level_value &= 0xFFFFFF00; - mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; - cgs_write_ind_register(hwmgr->device, - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SAMUDPM_SetEnabledMask, - (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); - return 0; -} - - -static int polaris10_update_bif_smc_table(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)(hwmgr->pptable); - struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table; - int max_entry, i; - - max_entry = (SMU74_MAX_LEVELS_LINK < pcie_table->count) ? - SMU74_MAX_LEVELS_LINK : - pcie_table->count; - /* Setup BIF_SCLK levels */ - for (i = 0; i < max_entry; i++) - smu_data->bif_sclk_table[i] = pcie_table->entries[i].pcie_sclk; - return 0; -} - -int polaris10_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) -{ - switch (type) { - case SMU_UVD_TABLE: - polaris10_update_uvd_smc_table(hwmgr); - break; - case SMU_VCE_TABLE: - polaris10_update_vce_smc_table(hwmgr); - break; - case SMU_SAMU_TABLE: - polaris10_update_samu_smc_table(hwmgr); - break; - case SMU_BIF_TABLE: - polaris10_update_bif_smc_table(hwmgr); - default: - break; - } - return 0; -} - -int polaris10_update_sclk_threshold(struct pp_hwmgr *hwmgr) -{ - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - - int result = 0; - uint32_t low_sclk_interrupt_threshold = 0; - - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_SclkThrottleLowNotification) - && (hwmgr->gfx_arbiter.sclk_threshold != - data->low_sclk_interrupt_threshold)) { - data->low_sclk_interrupt_threshold = - hwmgr->gfx_arbiter.sclk_threshold; - low_sclk_interrupt_threshold = - data->low_sclk_interrupt_threshold; - - CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); - - result = smu7_copy_bytes_to_smc( - hwmgr, - smu_data->smu7_data.dpm_table_start + - offsetof(SMU74_Discrete_DpmTable, - LowSclkInterruptThreshold), - (uint8_t *)&low_sclk_interrupt_threshold, - sizeof(uint32_t), - SMC_RAM_END); - } - PP_ASSERT_WITH_CODE((result == 0), - "Failed to update SCLK threshold!", return result); - - result = polaris10_program_mem_timing_parameters(hwmgr); - PP_ASSERT_WITH_CODE((result == 0), - "Failed to program memory timing parameters!", - ); - - return result; -} - -uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member) -{ - switch (type) { - case SMU_SoftRegisters: - switch (member) { - case HandshakeDisables: - return offsetof(SMU74_SoftRegisters, HandshakeDisables); - case VoltageChangeTimeout: - return offsetof(SMU74_SoftRegisters, VoltageChangeTimeout); - case AverageGraphicsActivity: - return offsetof(SMU74_SoftRegisters, AverageGraphicsActivity); - case PreVBlankGap: - return offsetof(SMU74_SoftRegisters, PreVBlankGap); - case VBlankTimeout: - return offsetof(SMU74_SoftRegisters, VBlankTimeout); - case UcodeLoadStatus: - return offsetof(SMU74_SoftRegisters, UcodeLoadStatus); - case DRAM_LOG_ADDR_H: - return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_H); - case DRAM_LOG_ADDR_L: - return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_L); - case DRAM_LOG_PHY_ADDR_H: - return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_H); - case DRAM_LOG_PHY_ADDR_L: - return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_L); - case DRAM_LOG_BUFF_SIZE: - return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE); - } - case SMU_Discrete_DpmTable: - switch (member) { - case UvdBootLevel: - return offsetof(SMU74_Discrete_DpmTable, UvdBootLevel); - case VceBootLevel: - return offsetof(SMU74_Discrete_DpmTable, VceBootLevel); - case SamuBootLevel: - return offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); - case LowSclkInterruptThreshold: - return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold); - } - } - pr_warn("can't get the offset of type %x member %x\n", type, member); - return 0; -} - -uint32_t polaris10_get_mac_definition(uint32_t value) -{ - switch (value) { - case SMU_MAX_LEVELS_GRAPHICS: - return SMU74_MAX_LEVELS_GRAPHICS; - case SMU_MAX_LEVELS_MEMORY: - return SMU74_MAX_LEVELS_MEMORY; - case SMU_MAX_LEVELS_LINK: - return SMU74_MAX_LEVELS_LINK; - case SMU_MAX_ENTRIES_SMIO: - return SMU74_MAX_ENTRIES_SMIO; - case SMU_MAX_LEVELS_VDDC: - return SMU74_MAX_LEVELS_VDDC; - case SMU_MAX_LEVELS_VDDGFX: - return SMU74_MAX_LEVELS_VDDGFX; - case SMU_MAX_LEVELS_VDDCI: - return SMU74_MAX_LEVELS_VDDCI; - case SMU_MAX_LEVELS_MVDD: - return SMU74_MAX_LEVELS_MVDD; - case SMU_UVD_MCLK_HANDSHAKE_DISABLE: - return SMU7_UVD_MCLK_HANDSHAKE_DISABLE; - } - - pr_warn("can't get the mac of %x\n", value); - return 0; -} - -/** -* Get the location of various tables inside the FW image. -* -* @param hwmgr the address of the powerplay hardware manager. -* @return always 0 -*/ -int polaris10_process_firmware_header(struct pp_hwmgr *hwmgr) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); - uint32_t tmp; - int result; - bool error = false; - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU74_Firmware_Header, DpmTable), - &tmp, SMC_RAM_END); - - if (0 == result) - smu_data->smu7_data.dpm_table_start = tmp; - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU74_Firmware_Header, SoftRegisters), - &tmp, SMC_RAM_END); - - if (!result) { - data->soft_regs_start = tmp; - smu_data->smu7_data.soft_regs_start = tmp; - } - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU74_Firmware_Header, mcRegisterTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.mc_reg_table_start = tmp; - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU74_Firmware_Header, FanTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.fan_table_start = tmp; - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU74_Firmware_Header, mcArbDramTimingTable), - &tmp, SMC_RAM_END); - - if (!result) - smu_data->smu7_data.arb_table_start = tmp; - - error |= (0 != result); - - result = smu7_read_smc_sram_dword(hwmgr, - SMU7_FIRMWARE_HEADER_LOCATION + - offsetof(SMU74_Firmware_Header, Version), - &tmp, SMC_RAM_END); - - if (!result) - hwmgr->microcode_version_info.SMC = tmp; - - error |= (0 != result); - - return error ? -1 : 0; -} - -bool polaris10_is_dpm_running(struct pp_hwmgr *hwmgr) -{ - return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, - CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) - ? true : false; -} - -int polaris10_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request) -{ - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *) - (hwmgr->smu_backend); - struct SMU74_Discrete_GraphicsLevel *levels = - smu_data->smc_state_table.GraphicsLevel; - uint32_t array = smu_data->smu7_data.dpm_table_start + - offsetof(SMU74_Discrete_DpmTable, GraphicsLevel); - uint32_t array_size = sizeof(struct SMU74_Discrete_GraphicsLevel) * - SMU74_MAX_LEVELS_GRAPHICS; - uint32_t i; - - for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { - levels[i].ActivityLevel = - cpu_to_be16(request->activity_threshold); - levels[i].EnabledForActivity = 1; - levels[i].UpHyst = request->up_hyst; - levels[i].DownHyst = request->down_hyst; - } - - return smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, - array_size, SMC_RAM_END); -} diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.h b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.h deleted file mode 100644 index 1df8154d0626..000000000000 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - */ -#ifndef POLARIS10_SMC_H -#define POLARIS10_SMC_H - -#include "smumgr.h" - - -int polaris10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr); -int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr); -int polaris10_init_smc_table(struct pp_hwmgr *hwmgr); -int polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr); -int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr); -int polaris10_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type); -int polaris10_update_sclk_threshold(struct pp_hwmgr *hwmgr); -uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member); -uint32_t polaris10_get_mac_definition(uint32_t value); -int polaris10_process_firmware_header(struct pp_hwmgr *hwmgr); -bool polaris10_is_dpm_running(struct pp_hwmgr *hwmgr); -int polaris10_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, - struct amd_pp_profile *request); - -#endif - diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 454bfc14335d..bd6be7793ca7 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -37,10 +37,45 @@ #include "bif/bif_5_0_sh_mask.h" #include "ppatomctrl.h" #include "cgs_common.h" -#include "polaris10_smc.h" #include "smu7_ppsmc.h" #include "smu7_smumgr.h" +#include "smu7_dyn_defaults.h" + +#include "smu7_hwmgr.h" +#include "hardwaremanager.h" +#include "ppatomctrl.h" +#include "atombios.h" +#include "pppcielanes.h" + +#include "dce/dce_10_0_d.h" +#include "dce/dce_10_0_sh_mask.h" + +#define POLARIS10_SMC_SIZE 0x20000 +#define VOLTAGE_VID_OFFSET_SCALE1 625 +#define VOLTAGE_VID_OFFSET_SCALE2 100 +#define POWERTUNE_DEFAULT_SET_MAX 1 +#define VDDC_VDDCI_DELTA 200 +#define MC_CG_ARB_FREQ_F1 0x0b + +static const struct polaris10_pt_defaults polaris10_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { + /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, + * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */ + { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, + { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61}, + { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } }, +}; + +static const sclkFcwRange_t Range_Table[NUM_SCLK_RANGE] = { + {VCO_2_4, POSTDIV_DIV_BY_16, 75, 160, 112}, + {VCO_3_6, POSTDIV_DIV_BY_16, 112, 224, 160}, + {VCO_2_4, POSTDIV_DIV_BY_8, 75, 160, 112}, + {VCO_3_6, POSTDIV_DIV_BY_8, 112, 224, 160}, + {VCO_2_4, POSTDIV_DIV_BY_4, 75, 160, 112}, + {VCO_3_6, POSTDIV_DIV_BY_4, 112, 216, 160}, + {VCO_2_4, POSTDIV_DIV_BY_2, 75, 160, 108}, + {VCO_3_6, POSTDIV_DIV_BY_2, 112, 216, 160} }; + #define PPPOLARIS10_TARGETACTIVITY_DFLT 50 static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = { @@ -348,6 +383,2195 @@ static int polaris10_smu_init(struct pp_hwmgr *hwmgr) return 0; } +static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, + struct phm_ppt_v1_clock_voltage_dependency_table *dep_table, + uint32_t clock, SMU_VoltageLevel *voltage, uint32_t *mvdd) +{ + uint32_t i; + uint16_t vddci; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + *voltage = *mvdd = 0; + + /* clock - voltage dependency table is empty table */ + if (dep_table->count == 0) + return -EINVAL; + + for (i = 0; i < dep_table->count; i++) { + /* find first sclk bigger than request */ + if (dep_table->entries[i].clk >= clock) { + *voltage |= (dep_table->entries[i].vddc * + VOLTAGE_SCALE) << VDDC_SHIFT; + if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) + *voltage |= (data->vbios_boot_state.vddci_bootup_value * + VOLTAGE_SCALE) << VDDCI_SHIFT; + else if (dep_table->entries[i].vddci) + *voltage |= (dep_table->entries[i].vddci * + VOLTAGE_SCALE) << VDDCI_SHIFT; + else { + vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), + (dep_table->entries[i].vddc - + (uint16_t)VDDC_VDDCI_DELTA)); + *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + } + + if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) + *mvdd = data->vbios_boot_state.mvdd_bootup_value * + VOLTAGE_SCALE; + else if (dep_table->entries[i].mvdd) + *mvdd = (uint32_t) dep_table->entries[i].mvdd * + VOLTAGE_SCALE; + + *voltage |= 1 << PHASES_SHIFT; + return 0; + } + } + + /* sclk is bigger than max sclk in the dependence table */ + *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; + + if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) + *voltage |= (data->vbios_boot_state.vddci_bootup_value * + VOLTAGE_SCALE) << VDDCI_SHIFT; + else if (dep_table->entries[i-1].vddci) { + vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), + (dep_table->entries[i].vddc - + (uint16_t)VDDC_VDDCI_DELTA)); + *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + } + + if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) + *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE; + else if (dep_table->entries[i].mvdd) + *mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE; + + return 0; +} + +static uint16_t scale_fan_gain_settings(uint16_t raw_setting) +{ + uint32_t tmp; + tmp = raw_setting * 4096 / 100; + return (uint16_t)tmp; +} + +static int polaris10_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + + const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; + SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; + struct pp_advance_fan_control_parameters *fan_table = + &hwmgr->thermal_controller.advanceFanControlParameters; + int i, j, k; + const uint16_t *pdef1; + const uint16_t *pdef2; + + table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128)); + table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 128)); + + PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, + "Target Operating Temp is out of Range!", + ); + + table->TemperatureLimitEdge = PP_HOST_TO_SMC_US( + cac_dtp_table->usTargetOperatingTemp * 256); + table->TemperatureLimitHotspot = PP_HOST_TO_SMC_US( + cac_dtp_table->usTemperatureLimitHotspot * 256); + table->FanGainEdge = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainEdge)); + table->FanGainHotspot = PP_HOST_TO_SMC_US( + scale_fan_gain_settings(fan_table->usFanGainHotspot)); + + pdef1 = defaults->BAPMTI_R; + pdef2 = defaults->BAPMTI_RC; + + for (i = 0; i < SMU74_DTE_ITERATIONS; i++) { + for (j = 0; j < SMU74_DTE_SOURCES; j++) { + for (k = 0; k < SMU74_DTE_SINKS; k++) { + table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1); + table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2); + pdef1++; + pdef2++; + } + } + } + + return 0; +} + +static int polaris10_populate_svi_load_line(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; + + smu_data->power_tune_table.SviLoadLineEn = defaults->SviLoadLineEn; + smu_data->power_tune_table.SviLoadLineVddC = defaults->SviLoadLineVddC; + smu_data->power_tune_table.SviLoadLineTrimVddC = 3; + smu_data->power_tune_table.SviLoadLineOffsetVddC = 0; + + return 0; +} + +static int polaris10_populate_tdc_limit(struct pp_hwmgr *hwmgr) +{ + uint16_t tdc_limit; + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; + + tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 128); + smu_data->power_tune_table.TDC_VDDC_PkgLimit = + CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); + smu_data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = + defaults->TDC_VDDC_ThrottleReleaseLimitPerc; + smu_data->power_tune_table.TDC_MAWt = defaults->TDC_MAWt; + + return 0; +} + +static int polaris10_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + const struct polaris10_pt_defaults *defaults = smu_data->power_tune_defaults; + uint32_t temp; + + if (smu7_read_smc_sram_dword(hwmgr, + fuse_table_offset + + offsetof(SMU74_Discrete_PmFuses, TdcWaterfallCtl), + (uint32_t *)&temp, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", + return -EINVAL); + else { + smu_data->power_tune_table.TdcWaterfallCtl = defaults->TdcWaterfallCtl; + smu_data->power_tune_table.LPMLTemperatureMin = + (uint8_t)((temp >> 16) & 0xff); + smu_data->power_tune_table.LPMLTemperatureMax = + (uint8_t)((temp >> 8) & 0xff); + smu_data->power_tune_table.Reserved = (uint8_t)(temp & 0xff); + } + return 0; +} + +static int polaris10_populate_temperature_scaler(struct pp_hwmgr *hwmgr) +{ + int i; + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + + /* Currently not used. Set all to zero. */ + for (i = 0; i < 16; i++) + smu_data->power_tune_table.LPMLTemperatureScaler[i] = 0; + + return 0; +} + +static int polaris10_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + +/* TO DO move to hwmgr */ + if ((hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity & (1 << 15)) + || 0 == hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity) + hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity = + hwmgr->thermal_controller.advanceFanControlParameters.usDefaultFanOutputSensitivity; + + smu_data->power_tune_table.FuzzyFan_PwmSetDelta = PP_HOST_TO_SMC_US( + hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity); + return 0; +} + +static int polaris10_populate_gnb_lpml(struct pp_hwmgr *hwmgr) +{ + int i; + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + + /* Currently not used. Set all to zero. */ + for (i = 0; i < 16; i++) + smu_data->power_tune_table.GnbLPML[i] = 0; + + return 0; +} + +static int polaris10_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint16_t hi_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd; + uint16_t lo_sidd = smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd; + struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; + + hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); + lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); + + smu_data->power_tune_table.BapmVddCBaseLeakageHiSidd = + CONVERT_FROM_HOST_TO_SMC_US(hi_sidd); + smu_data->power_tune_table.BapmVddCBaseLeakageLoSidd = + CONVERT_FROM_HOST_TO_SMC_US(lo_sidd); + + return 0; +} + +static int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + uint32_t pm_fuse_table_offset; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_PowerContainment)) { + if (smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU74_Firmware_Header, PmFuseTable), + &pm_fuse_table_offset, SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to get pm_fuse_table_offset Failed!", + return -EINVAL); + + if (polaris10_populate_svi_load_line(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate SviLoadLine Failed!", + return -EINVAL); + + if (polaris10_populate_tdc_limit(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TDCLimit Failed!", return -EINVAL); + + if (polaris10_populate_dw8(hwmgr, pm_fuse_table_offset)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate TdcWaterfallCtl, " + "LPMLTemperature Min and Max Failed!", + return -EINVAL); + + if (0 != polaris10_populate_temperature_scaler(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate LPMLTemperatureScaler Failed!", + return -EINVAL); + + if (polaris10_populate_fuzzy_fan(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate Fuzzy Fan Control parameters Failed!", + return -EINVAL); + + if (polaris10_populate_gnb_lpml(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate GnbLPML Failed!", + return -EINVAL); + + if (polaris10_populate_bapm_vddc_base_leakage_sidd(hwmgr)) + PP_ASSERT_WITH_CODE(false, + "Attempt to populate BapmVddCBaseLeakage Hi and Lo " + "Sidd Failed!", return -EINVAL); + + if (smu7_copy_bytes_to_smc(hwmgr, pm_fuse_table_offset, + (uint8_t *)&smu_data->power_tune_table, + (sizeof(struct SMU74_Discrete_PmFuses) - 92), SMC_RAM_END)) + PP_ASSERT_WITH_CODE(false, + "Attempt to download PmFuseTable Failed!", + return -EINVAL); + } + return 0; +} + +static int polaris10_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, + SMU74_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t count, level; + + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) { + count = data->mvdd_voltage_table.count; + if (count > SMU_MAX_SMIO_LEVELS) + count = SMU_MAX_SMIO_LEVELS; + for (level = 0; level < count; level++) { + table->SmioTable2.Pattern[level].Voltage = + PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); + /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ + table->SmioTable2.Pattern[level].Smio = + (uint8_t) level; + table->Smio[level] |= + data->mvdd_voltage_table.entries[level].smio_low; + } + table->SmioMask2 = data->mvdd_voltage_table.mask_low; + + table->MvddLevelCount = (uint32_t) PP_HOST_TO_SMC_UL(count); + } + + return 0; +} + +static int polaris10_populate_smc_vddci_table(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + uint32_t count, level; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + count = data->vddci_voltage_table.count; + + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { + if (count > SMU_MAX_SMIO_LEVELS) + count = SMU_MAX_SMIO_LEVELS; + for (level = 0; level < count; ++level) { + table->SmioTable1.Pattern[level].Voltage = + PP_HOST_TO_SMC_US(data->vddci_voltage_table.entries[level].value * VOLTAGE_SCALE); + table->SmioTable1.Pattern[level].Smio = (uint8_t) level; + + table->Smio[level] |= data->vddci_voltage_table.entries[level].smio_low; + } + } + + table->SmioMask1 = data->vddci_voltage_table.mask_low; + + return 0; +} + +static int polaris10_populate_cac_table(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + uint32_t count; + uint8_t index; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_voltage_lookup_table *lookup_table = + table_info->vddc_lookup_table; + /* tables is already swapped, so in order to use the value from it, + * we need to swap it back. + * We are populating vddc CAC data to BapmVddc table + * in split and merged mode + */ + for (count = 0; count < lookup_table->count; count++) { + index = phm_get_voltage_index(lookup_table, + data->vddc_voltage_table.entries[count].value); + table->BapmVddcVidLoSidd[count] = convert_to_vid(lookup_table->entries[index].us_cac_low); + table->BapmVddcVidHiSidd[count] = convert_to_vid(lookup_table->entries[index].us_cac_mid); + table->BapmVddcVidHiSidd2[count] = convert_to_vid(lookup_table->entries[index].us_cac_high); + } + + return 0; +} + +static int polaris10_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + polaris10_populate_smc_vddci_table(hwmgr, table); + polaris10_populate_smc_mvdd_table(hwmgr, table); + polaris10_populate_cac_table(hwmgr, table); + + return 0; +} + +static int polaris10_populate_ulv_level(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_Ulv *state) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + state->CcPwrDynRm = 0; + state->CcPwrDynRm1 = 0; + + state->VddcOffset = (uint16_t) table_info->us_ulv_voltage_offset; + state->VddcOffsetVid = (uint8_t)(table_info->us_ulv_voltage_offset * + VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1); + + if (hwmgr->chip_id == CHIP_POLARIS12 || hwmgr->is_kicker) + state->VddcPhase = data->vddc_phase_shed_control ^ 0x3; + else + state->VddcPhase = (data->vddc_phase_shed_control) ? 0 : 1; + + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(state->CcPwrDynRm1); + CONVERT_FROM_HOST_TO_SMC_US(state->VddcOffset); + + return 0; +} + +static int polaris10_populate_ulv_state(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + return polaris10_populate_ulv_level(hwmgr, &table->Ulv); +} + +static int polaris10_populate_smc_link_level(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &data->dpm_table; + int i; + + /* Index (dpm_table->pcie_speed_table.count) + * is reserved for PCIE boot level. */ + for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) { + table->LinkLevel[i].PcieGenSpeed = + (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value; + table->LinkLevel[i].PcieLaneCount = (uint8_t)encode_pcie_lane_width( + dpm_table->pcie_speed_table.dpm_levels[i].param1); + table->LinkLevel[i].EnabledForActivity = 1; + table->LinkLevel[i].SPC = (uint8_t)(data->pcie_spc_cap & 0xff); + table->LinkLevel[i].DownThreshold = PP_HOST_TO_SMC_UL(5); + table->LinkLevel[i].UpThreshold = PP_HOST_TO_SMC_UL(30); + } + + smu_data->smc_state_table.LinkLevelCount = + (uint8_t)dpm_table->pcie_speed_table.count; + +/* To Do move to hwmgr */ + data->dpm_level_enable_mask.pcie_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table); + + return 0; +} + + +static void polaris10_get_sclk_range_table(struct pp_hwmgr *hwmgr, + SMU74_Discrete_DpmTable *table) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + uint32_t i, ref_clk; + + struct pp_atom_ctrl_sclk_range_table range_table_from_vbios = { { {0} } }; + + ref_clk = smu7_get_xclk(hwmgr); + + if (0 == atomctrl_get_smc_sclk_range_table(hwmgr, &range_table_from_vbios)) { + for (i = 0; i < NUM_SCLK_RANGE; i++) { + table->SclkFcwRangeTable[i].vco_setting = range_table_from_vbios.entry[i].ucVco_setting; + table->SclkFcwRangeTable[i].postdiv = range_table_from_vbios.entry[i].ucPostdiv; + table->SclkFcwRangeTable[i].fcw_pcc = range_table_from_vbios.entry[i].usFcw_pcc; + + table->SclkFcwRangeTable[i].fcw_trans_upper = range_table_from_vbios.entry[i].usFcw_trans_upper; + table->SclkFcwRangeTable[i].fcw_trans_lower = range_table_from_vbios.entry[i].usRcw_trans_lower; + + CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc); + CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper); + CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower); + } + return; + } + + for (i = 0; i < NUM_SCLK_RANGE; i++) { + smu_data->range_table[i].trans_lower_frequency = (ref_clk * Range_Table[i].fcw_trans_lower) >> Range_Table[i].postdiv; + smu_data->range_table[i].trans_upper_frequency = (ref_clk * Range_Table[i].fcw_trans_upper) >> Range_Table[i].postdiv; + + table->SclkFcwRangeTable[i].vco_setting = Range_Table[i].vco_setting; + table->SclkFcwRangeTable[i].postdiv = Range_Table[i].postdiv; + table->SclkFcwRangeTable[i].fcw_pcc = Range_Table[i].fcw_pcc; + + table->SclkFcwRangeTable[i].fcw_trans_upper = Range_Table[i].fcw_trans_upper; + table->SclkFcwRangeTable[i].fcw_trans_lower = Range_Table[i].fcw_trans_lower; + + CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_pcc); + CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_upper); + CONVERT_FROM_HOST_TO_SMC_US(table->SclkFcwRangeTable[i].fcw_trans_lower); + } +} + +static int polaris10_calculate_sclk_params(struct pp_hwmgr *hwmgr, + uint32_t clock, SMU_SclkSetting *sclk_setting) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + const SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); + struct pp_atomctrl_clock_dividers_ai dividers; + uint32_t ref_clock; + uint32_t pcc_target_percent, pcc_target_freq, ss_target_percent, ss_target_freq; + uint8_t i; + int result; + uint64_t temp; + + sclk_setting->SclkFrequency = clock; + /* get the engine clock dividers for this clock value */ + result = atomctrl_get_engine_pll_dividers_ai(hwmgr, clock, ÷rs); + if (result == 0) { + sclk_setting->Fcw_int = dividers.usSclk_fcw_int; + sclk_setting->Fcw_frac = dividers.usSclk_fcw_frac; + sclk_setting->Pcc_fcw_int = dividers.usPcc_fcw_int; + sclk_setting->PllRange = dividers.ucSclkPllRange; + sclk_setting->Sclk_slew_rate = 0x400; + sclk_setting->Pcc_up_slew_rate = dividers.usPcc_fcw_slew_frac; + sclk_setting->Pcc_down_slew_rate = 0xffff; + sclk_setting->SSc_En = dividers.ucSscEnable; + sclk_setting->Fcw1_int = dividers.usSsc_fcw1_int; + sclk_setting->Fcw1_frac = dividers.usSsc_fcw1_frac; + sclk_setting->Sclk_ss_slew_rate = dividers.usSsc_fcw_slew_frac; + return result; + } + + ref_clock = smu7_get_xclk(hwmgr); + + for (i = 0; i < NUM_SCLK_RANGE; i++) { + if (clock > smu_data->range_table[i].trans_lower_frequency + && clock <= smu_data->range_table[i].trans_upper_frequency) { + sclk_setting->PllRange = i; + break; + } + } + + sclk_setting->Fcw_int = (uint16_t)((clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock); + temp = clock << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv; + temp <<= 0x10; + do_div(temp, ref_clock); + sclk_setting->Fcw_frac = temp & 0xffff; + + pcc_target_percent = 10; /* Hardcode 10% for now. */ + pcc_target_freq = clock - (clock * pcc_target_percent / 100); + sclk_setting->Pcc_fcw_int = (uint16_t)((pcc_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock); + + ss_target_percent = 2; /* Hardcode 2% for now. */ + sclk_setting->SSc_En = 0; + if (ss_target_percent) { + sclk_setting->SSc_En = 1; + ss_target_freq = clock - (clock * ss_target_percent / 100); + sclk_setting->Fcw1_int = (uint16_t)((ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv) / ref_clock); + temp = ss_target_freq << table->SclkFcwRangeTable[sclk_setting->PllRange].postdiv; + temp <<= 0x10; + do_div(temp, ref_clock); + sclk_setting->Fcw1_frac = temp & 0xffff; + } + + return 0; +} + +static int polaris10_populate_single_graphic_level(struct pp_hwmgr *hwmgr, + uint32_t clock, uint16_t sclk_al_threshold, + struct SMU74_Discrete_GraphicsLevel *level) +{ + int result; + /* PP_Clocks minClocks; */ + uint32_t mvdd; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + SMU_SclkSetting curr_sclk_setting = { 0 }; + + result = polaris10_calculate_sclk_params(hwmgr, clock, &curr_sclk_setting); + + /* populate graphics levels */ + result = polaris10_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_sclk, clock, + &level->MinVoltage, &mvdd); + + PP_ASSERT_WITH_CODE((0 == result), + "can not find VDDC voltage value for " + "VDDC engine clock dependency table", + return result); + level->ActivityLevel = sclk_al_threshold; + + level->CcPwrDynRm = 0; + level->CcPwrDynRm1 = 0; + level->EnabledForActivity = 0; + level->EnabledForThrottle = 1; + level->UpHyst = 10; + level->DownHyst = 0; + level->VoltageDownHyst = 0; + level->PowerThrottle = 0; + data->display_timing.min_clock_in_sr = hwmgr->display_config.min_core_set_clock_in_sr; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) + level->DeepSleepDivId = smu7_get_sleep_divider_id_from_clock(clock, + hwmgr->display_config.min_core_set_clock_in_sr); + + /* Default to slow, highest DPM level will be + * set to PPSMC_DISPLAY_WATERMARK_LOW later. + */ + if (data->update_up_hyst) + level->UpHyst = (uint8_t)data->up_hyst; + if (data->update_down_hyst) + level->DownHyst = (uint8_t)data->down_hyst; + + level->SclkSetting = curr_sclk_setting; + + CONVERT_FROM_HOST_TO_SMC_UL(level->MinVoltage); + CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(level->CcPwrDynRm1); + CONVERT_FROM_HOST_TO_SMC_US(level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(level->SclkSetting.SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_int); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw_frac); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_fcw_int); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_slew_rate); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_up_slew_rate); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Pcc_down_slew_rate); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_int); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Fcw1_frac); + CONVERT_FROM_HOST_TO_SMC_US(level->SclkSetting.Sclk_ss_slew_rate); + return 0; +} + +static int polaris10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &hw_data->dpm_table; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table; + uint8_t pcie_entry_cnt = (uint8_t) hw_data->dpm_table.pcie_speed_table.count; + int result = 0; + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, GraphicsLevel); + uint32_t array_size = sizeof(struct SMU74_Discrete_GraphicsLevel) * + SMU74_MAX_LEVELS_GRAPHICS; + struct SMU74_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t i, max_entry; + uint8_t hightest_pcie_level_enabled = 0, + lowest_pcie_level_enabled = 0, + mid_pcie_level_enabled = 0, + count = 0; + + polaris10_get_sclk_range_table(hwmgr, &(smu_data->smc_state_table)); + + for (i = 0; i < dpm_table->sclk_table.count; i++) { + + result = polaris10_populate_single_graphic_level(hwmgr, + dpm_table->sclk_table.dpm_levels[i].value, + (uint16_t)smu_data->activity_target[i], + &(smu_data->smc_state_table.GraphicsLevel[i])); + if (result) + return result; + + /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */ + if (i > 1) + levels[i].DeepSleepDivId = 0; + } + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SPLLShutdownSupport)) + smu_data->smc_state_table.GraphicsLevel[0].SclkSetting.SSc_En = 0; + + smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; + smu_data->smc_state_table.GraphicsDpmLevelCount = + (uint8_t)dpm_table->sclk_table.count; + hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table); + + + if (pcie_table != NULL) { + PP_ASSERT_WITH_CODE((1 <= pcie_entry_cnt), + "There must be 1 or more PCIE levels defined in PPTable.", + return -EINVAL); + max_entry = pcie_entry_cnt - 1; + for (i = 0; i < dpm_table->sclk_table.count; i++) + levels[i].pcieDpmLevel = + (uint8_t) ((i < max_entry) ? i : max_entry); + } else { + while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask && + ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << (hightest_pcie_level_enabled + 1))) != 0)) + hightest_pcie_level_enabled++; + + while (hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask && + ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << lowest_pcie_level_enabled)) == 0)) + lowest_pcie_level_enabled++; + + while ((count < hightest_pcie_level_enabled) && + ((hw_data->dpm_level_enable_mask.pcie_dpm_enable_mask & + (1 << (lowest_pcie_level_enabled + 1 + count))) == 0)) + count++; + + mid_pcie_level_enabled = (lowest_pcie_level_enabled + 1 + count) < + hightest_pcie_level_enabled ? + (lowest_pcie_level_enabled + 1 + count) : + hightest_pcie_level_enabled; + + /* set pcieDpmLevel to hightest_pcie_level_enabled */ + for (i = 2; i < dpm_table->sclk_table.count; i++) + levels[i].pcieDpmLevel = hightest_pcie_level_enabled; + + /* set pcieDpmLevel to lowest_pcie_level_enabled */ + levels[0].pcieDpmLevel = lowest_pcie_level_enabled; + + /* set pcieDpmLevel to mid_pcie_level_enabled */ + levels[1].pcieDpmLevel = mid_pcie_level_enabled; + } + /* level count will send to smc once at init smc table and never change */ + result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + (uint32_t)array_size, SMC_RAM_END); + + return result; +} + + +static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr, + uint32_t clock, struct SMU74_Discrete_MemoryLevel *mem_level) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + int result = 0; + struct cgs_display_info info = {0, 0, NULL}; + uint32_t mclk_stutter_mode_threshold = 40000; + + cgs_get_active_displays_info(hwmgr->device, &info); + + if (table_info->vdd_dep_on_mclk) { + result = polaris10_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_mclk, clock, + &mem_level->MinVoltage, &mem_level->MinMvdd); + PP_ASSERT_WITH_CODE((0 == result), + "can not find MinVddc voltage value from memory " + "VDDC voltage dependency table", return result); + } + + mem_level->MclkFrequency = clock; + mem_level->EnabledForThrottle = 1; + mem_level->EnabledForActivity = 0; + mem_level->UpHyst = 0; + mem_level->DownHyst = 100; + mem_level->VoltageDownHyst = 0; + mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target; + mem_level->StutterEnable = false; + mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; + + data->display_timing.num_existing_displays = info.display_count; + + if (mclk_stutter_mode_threshold && + (clock <= mclk_stutter_mode_threshold) && + (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, + STUTTER_ENABLE) & 0x1)) + mem_level->StutterEnable = true; + + if (!result) { + CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinMvdd); + CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(mem_level->ActivityLevel); + CONVERT_FROM_HOST_TO_SMC_UL(mem_level->MinVoltage); + } + return result; +} + +static int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct smu7_dpm_table *dpm_table = &hw_data->dpm_table; + int result; + /* populate MCLK dpm table to SMU7 */ + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, MemoryLevel); + uint32_t array_size = sizeof(SMU74_Discrete_MemoryLevel) * + SMU74_MAX_LEVELS_MEMORY; + struct SMU74_Discrete_MemoryLevel *levels = + smu_data->smc_state_table.MemoryLevel; + uint32_t i; + + for (i = 0; i < dpm_table->mclk_table.count; i++) { + PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value), + "can not populate memory level as memory clock is zero", + return -EINVAL); + result = polaris10_populate_single_memory_level(hwmgr, + dpm_table->mclk_table.dpm_levels[i].value, + &levels[i]); + if (i == dpm_table->mclk_table.count - 1) { + levels[i].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; + levels[i].EnabledForActivity = 1; + } + if (result) + return result; + } + + /* In order to prevent MC activity from stutter mode to push DPM up, + * the UVD change complements this by putting the MCLK in + * a higher state by default such that we are not affected by + * up threshold or and MCLK DPM latency. + */ + levels[0].ActivityLevel = 0x1f; + CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel); + + smu_data->smc_state_table.MemoryDpmLevelCount = + (uint8_t)dpm_table->mclk_table.count; + hw_data->dpm_level_enable_mask.mclk_dpm_enable_mask = + phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table); + + /* level count will send to smc once at init smc table and never change */ + result = smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + (uint32_t)array_size, SMC_RAM_END); + + return result; +} + +static int polaris10_populate_mvdd_value(struct pp_hwmgr *hwmgr, + uint32_t mclk, SMIO_Pattern *smio_pat) +{ + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint32_t i = 0; + + if (SMU7_VOLTAGE_CONTROL_NONE != data->mvdd_control) { + /* find mvdd value which clock is more than request */ + for (i = 0; i < table_info->vdd_dep_on_mclk->count; i++) { + if (mclk <= table_info->vdd_dep_on_mclk->entries[i].clk) { + smio_pat->Voltage = data->mvdd_voltage_table.entries[i].value; + break; + } + } + PP_ASSERT_WITH_CODE(i < table_info->vdd_dep_on_mclk->count, + "MVDD Voltage is outside the supported range.", + return -EINVAL); + } else + return -EINVAL; + + return 0; +} + +static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr, + SMU74_Discrete_DpmTable *table) +{ + int result = 0; + uint32_t sclk_frequency; + const struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + SMIO_Pattern vol_level; + uint32_t mvdd; + uint16_t us_mvdd; + + table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC; + + /* Get MinVoltage and Frequency from DPM0, + * already converted to SMC_UL */ + sclk_frequency = data->vbios_boot_state.sclk_bootup_value; + result = polaris10_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_sclk, + sclk_frequency, + &table->ACPILevel.MinVoltage, &mvdd); + PP_ASSERT_WITH_CODE((0 == result), + "Cannot find ACPI VDDC voltage value " + "in Clock Dependency Table", + ); + + result = polaris10_calculate_sclk_params(hwmgr, sclk_frequency, &(table->ACPILevel.SclkSetting)); + PP_ASSERT_WITH_CODE(result == 0, "Error retrieving Engine Clock dividers from VBIOS.", return result); + + table->ACPILevel.DeepSleepDivId = 0; + table->ACPILevel.CcPwrDynRm = 0; + table->ACPILevel.CcPwrDynRm1 = 0; + + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.MinVoltage); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm); + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1); + + CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkSetting.SclkFrequency); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_int); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw_frac); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_fcw_int); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_slew_rate); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_up_slew_rate); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Pcc_down_slew_rate); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_int); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Fcw1_frac); + CONVERT_FROM_HOST_TO_SMC_US(table->ACPILevel.SclkSetting.Sclk_ss_slew_rate); + + + /* Get MinVoltage and Frequency from DPM0, already converted to SMC_UL */ + table->MemoryACPILevel.MclkFrequency = data->vbios_boot_state.mclk_bootup_value; + result = polaris10_get_dependency_volt_by_clk(hwmgr, + table_info->vdd_dep_on_mclk, + table->MemoryACPILevel.MclkFrequency, + &table->MemoryACPILevel.MinVoltage, &mvdd); + PP_ASSERT_WITH_CODE((0 == result), + "Cannot find ACPI VDDCI voltage value " + "in Clock Dependency Table", + ); + + us_mvdd = 0; + if ((SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) || + (data->mclk_dpm_key_disabled)) + us_mvdd = data->vbios_boot_state.mvdd_bootup_value; + else { + if (!polaris10_populate_mvdd_value(hwmgr, + data->dpm_table.mclk_table.dpm_levels[0].value, + &vol_level)) + us_mvdd = vol_level.Voltage; + } + + if (0 == polaris10_populate_mvdd_value(hwmgr, 0, &vol_level)) + table->MemoryACPILevel.MinMvdd = PP_HOST_TO_SMC_UL(vol_level.Voltage); + else + table->MemoryACPILevel.MinMvdd = 0; + + table->MemoryACPILevel.StutterEnable = false; + + table->MemoryACPILevel.EnabledForThrottle = 0; + table->MemoryACPILevel.EnabledForActivity = 0; + table->MemoryACPILevel.UpHyst = 0; + table->MemoryACPILevel.DownHyst = 100; + table->MemoryACPILevel.VoltageDownHyst = 0; + table->MemoryACPILevel.ActivityLevel = + PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target); + + CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage); + + return result; +} + +static int polaris10_populate_smc_vce_level(struct pp_hwmgr *hwmgr, + SMU74_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + table_info->mm_dep_table; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t vddci; + + table->VceLevelCount = (uint8_t)(mm_table->count); + table->VceBootLevel = 0; + + for (count = 0; count < table->VceLevelCount; count++) { + table->VceLevel[count].Frequency = mm_table->entries[count].eclk; + table->VceLevel[count].MinVoltage = 0; + table->VceLevel[count].MinVoltage |= + (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; + + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) + vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), + mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); + else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) + vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; + else + vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; + + + table->VceLevel[count].MinVoltage |= + (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + table->VceLevel[count].MinVoltage |= 1 << PHASES_SHIFT; + + /*retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->VceLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for VCE engine clock", + return result); + + table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].MinVoltage); + } + return result; +} + + +static int polaris10_populate_smc_samu_level(struct pp_hwmgr *hwmgr, + SMU74_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + table_info->mm_dep_table; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t vddci; + + table->SamuBootLevel = 0; + table->SamuLevelCount = (uint8_t)(mm_table->count); + + for (count = 0; count < table->SamuLevelCount; count++) { + /* not sure whether we need evclk or not */ + table->SamuLevel[count].MinVoltage = 0; + table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; + table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * + VOLTAGE_SCALE) << VDDC_SHIFT; + + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) + vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), + mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); + else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) + vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; + else + vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; + + table->SamuLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->SamuLevel[count].Frequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for samu clock", return result); + + table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage); + } + return result; +} + +static int polaris10_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr, + int32_t eng_clock, int32_t mem_clock, + SMU74_Discrete_MCArbDramTimingTableEntry *arb_regs) +{ + uint32_t dram_timing; + uint32_t dram_timing2; + uint32_t burst_time; + int result; + + result = atomctrl_set_engine_dram_timings_rv770(hwmgr, + eng_clock, mem_clock); + PP_ASSERT_WITH_CODE(result == 0, + "Error calling VBIOS to set DRAM_TIMING.", return result); + + dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING); + dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2); + burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0); + + + arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dram_timing); + arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dram_timing2); + arb_regs->McArbBurstTime = (uint8_t)burst_time; + + return 0; +} + +static int polaris10_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct SMU74_Discrete_MCArbDramTimingTable arb_regs; + uint32_t i, j; + int result = 0; + + for (i = 0; i < hw_data->dpm_table.sclk_table.count; i++) { + for (j = 0; j < hw_data->dpm_table.mclk_table.count; j++) { + result = polaris10_populate_memory_timing_parameters(hwmgr, + hw_data->dpm_table.sclk_table.dpm_levels[i].value, + hw_data->dpm_table.mclk_table.dpm_levels[j].value, + &arb_regs.entries[i][j]); + if (result == 0) + result = atomctrl_set_ac_timing_ai(hwmgr, hw_data->dpm_table.mclk_table.dpm_levels[j].value, j); + if (result != 0) + return result; + } + } + + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.arb_table_start, + (uint8_t *)&arb_regs, + sizeof(SMU74_Discrete_MCArbDramTimingTable), + SMC_RAM_END); + return result; +} + +static int polaris10_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + int result = -EINVAL; + uint8_t count; + struct pp_atomctrl_clock_dividers_vi dividers; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = + table_info->mm_dep_table; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t vddci; + + table->UvdLevelCount = (uint8_t)(mm_table->count); + table->UvdBootLevel = 0; + + for (count = 0; count < table->UvdLevelCount; count++) { + table->UvdLevel[count].MinVoltage = 0; + table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; + table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; + table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * + VOLTAGE_SCALE) << VDDC_SHIFT; + + if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) + vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), + mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); + else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) + vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; + else + vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; + + table->UvdLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + table->UvdLevel[count].MinVoltage |= 1 << PHASES_SHIFT; + + /* retrieve divider value for VBIOS */ + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->UvdLevel[count].VclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for Vclk clock", return result); + + table->UvdLevel[count].VclkDivider = (uint8_t)dividers.pll_post_divider; + + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, + table->UvdLevel[count].DclkFrequency, ÷rs); + PP_ASSERT_WITH_CODE((0 == result), + "can not find divide id for Dclk clock", return result); + + table->UvdLevel[count].DclkDivider = (uint8_t)dividers.pll_post_divider; + + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency); + CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].MinVoltage); + } + + return result; +} + +static int polaris10_populate_smc_boot_level(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + int result = 0; + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + table->GraphicsBootLevel = 0; + table->MemoryBootLevel = 0; + + /* find boot level from dpm table */ + result = phm_find_boot_level(&(data->dpm_table.sclk_table), + data->vbios_boot_state.sclk_bootup_value, + (uint32_t *)&(table->GraphicsBootLevel)); + + result = phm_find_boot_level(&(data->dpm_table.mclk_table), + data->vbios_boot_state.mclk_bootup_value, + (uint32_t *)&(table->MemoryBootLevel)); + + table->BootVddc = data->vbios_boot_state.vddc_bootup_value * + VOLTAGE_SCALE; + table->BootVddci = data->vbios_boot_state.vddci_bootup_value * + VOLTAGE_SCALE; + table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value * + VOLTAGE_SCALE; + + CONVERT_FROM_HOST_TO_SMC_US(table->BootVddc); + CONVERT_FROM_HOST_TO_SMC_US(table->BootVddci); + CONVERT_FROM_HOST_TO_SMC_US(table->BootMVdd); + + return 0; +} + +static int polaris10_populate_smc_initailial_state(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + uint8_t count, level; + + count = (uint8_t)(table_info->vdd_dep_on_sclk->count); + + for (level = 0; level < count; level++) { + if (table_info->vdd_dep_on_sclk->entries[level].clk >= + hw_data->vbios_boot_state.sclk_bootup_value) { + smu_data->smc_state_table.GraphicsBootLevel = level; + break; + } + } + + count = (uint8_t)(table_info->vdd_dep_on_mclk->count); + for (level = 0; level < count; level++) { + if (table_info->vdd_dep_on_mclk->entries[level].clk >= + hw_data->vbios_boot_state.mclk_bootup_value) { + smu_data->smc_state_table.MemoryBootLevel = level; + break; + } + } + + return 0; +} + +static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) +{ + uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min; + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + + uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = + table_info->vdd_dep_on_sclk; + + stretch_amount = (uint8_t)table_info->cac_dtp_table->usClockStretchAmount; + + /* Read SMU_Eefuse to read and calculate RO and determine + * if the part is SS or FF. if RO >= 1660MHz, part is FF. + */ + efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixSMU_EFUSE_0 + (67 * 4)); + efuse &= 0xFF000000; + efuse = efuse >> 24; + + if (hwmgr->chip_id == CHIP_POLARIS10) { + min = 1000; + max = 2300; + } else { + min = 1100; + max = 2100; + } + + ro = efuse * (max - min) / 255 + min; + + /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ + for (i = 0; i < sclk_table->count; i++) { + smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= + sclk_table->entries[i].cks_enable << i; + if (hwmgr->chip_id == CHIP_POLARIS10) { + volt_without_cks = (uint32_t)((2753594000U + (sclk_table->entries[i].clk/100) * 136418 - (ro - 70) * 1000000) / \ + (2424180 - (sclk_table->entries[i].clk/100) * 1132925/1000)); + volt_with_cks = (uint32_t)((2797202000U + sclk_table->entries[i].clk/100 * 3232 - (ro - 65) * 1000000) / \ + (2522480 - sclk_table->entries[i].clk/100 * 115764/100)); + } else { + volt_without_cks = (uint32_t)((2416794800U + (sclk_table->entries[i].clk/100) * 1476925/10 - (ro - 50) * 1000000) / \ + (2625416 - (sclk_table->entries[i].clk/100) * (12586807/10000))); + volt_with_cks = (uint32_t)((2999656000U - sclk_table->entries[i].clk/100 * 392803 - (ro - 44) * 1000000) / \ + (3422454 - sclk_table->entries[i].clk/100 * (18886376/10000))); + } + + if (volt_without_cks >= volt_with_cks) + volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + + sclk_table->entries[i].cks_voffset) * 100 + 624) / 625); + + smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; + } + + smu_data->smc_state_table.LdoRefSel = (table_info->cac_dtp_table->ucCKS_LDO_REFSEL != 0) ? table_info->cac_dtp_table->ucCKS_LDO_REFSEL : 6; + /* Populate CKS Lookup Table */ + if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) + stretch_amount2 = 0; + else if (stretch_amount == 3 || stretch_amount == 4) + stretch_amount2 = 1; + else { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ClockStretcher); + PP_ASSERT_WITH_CODE(false, + "Stretch Amount in PPTable not supported\n", + return -EINVAL); + } + + value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL); + value &= 0xFFFFFFFE; + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value); + + return 0; +} + +static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr, + struct SMU74_Discrete_DpmTable *table) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + uint16_t config; + + config = VR_MERGED_WITH_VDDC; + table->VRConfig |= (config << VRCONF_VDDGFX_SHIFT); + + /* Set Vddc Voltage Controller */ + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) { + config = VR_SVI2_PLANE_1; + table->VRConfig |= config; + } else { + PP_ASSERT_WITH_CODE(false, + "VDDC should be on SVI2 control in merged mode!", + ); + } + /* Set Vddci Voltage Controller */ + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) { + config = VR_SVI2_PLANE_2; /* only in merged mode */ + table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); + } else if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) { + config = VR_SMIO_PATTERN_1; + table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); + } else { + config = VR_STATIC_VOLTAGE; + table->VRConfig |= (config << VRCONF_VDDCI_SHIFT); + } + /* Set Mvdd Voltage Controller */ + if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) { + config = VR_SVI2_PLANE_2; + table->VRConfig |= (config << VRCONF_MVDD_SHIFT); + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, smu_data->smu7_data.soft_regs_start + + offsetof(SMU74_SoftRegisters, AllowMvddSwitch), 0x1); + } else { + config = VR_STATIC_VOLTAGE; + table->VRConfig |= (config << VRCONF_MVDD_SHIFT); + } + + return 0; +} + + +static int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + + SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); + int result = 0; + struct pp_atom_ctrl__avfs_parameters avfs_params = {0}; + AVFS_meanNsigma_t AVFS_meanNsigma = { {0} }; + AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} }; + uint32_t tmp, i; + + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)hwmgr->pptable; + struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = + table_info->vdd_dep_on_sclk; + + + if (((struct smu7_smumgr *)smu_data)->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED) + return result; + + result = atomctrl_get_avfs_information(hwmgr, &avfs_params); + + if (0 == result) { + table->BTCGB_VDROOP_TABLE[0].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0); + table->BTCGB_VDROOP_TABLE[0].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1); + table->BTCGB_VDROOP_TABLE[0].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2); + table->BTCGB_VDROOP_TABLE[1].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0); + table->BTCGB_VDROOP_TABLE[1].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1); + table->BTCGB_VDROOP_TABLE[1].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2); + table->AVFSGB_VDROOP_TABLE[0].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1); + table->AVFSGB_VDROOP_TABLE[0].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2); + table->AVFSGB_VDROOP_TABLE[0].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b); + table->AVFSGB_VDROOP_TABLE[0].m1_shift = 24; + table->AVFSGB_VDROOP_TABLE[0].m2_shift = 12; + table->AVFSGB_VDROOP_TABLE[1].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1); + table->AVFSGB_VDROOP_TABLE[1].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2); + table->AVFSGB_VDROOP_TABLE[1].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b); + table->AVFSGB_VDROOP_TABLE[1].m1_shift = 24; + table->AVFSGB_VDROOP_TABLE[1].m2_shift = 12; + table->MaxVoltage = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv); + AVFS_meanNsigma.Aconstant[0] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0); + AVFS_meanNsigma.Aconstant[1] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1); + AVFS_meanNsigma.Aconstant[2] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2); + AVFS_meanNsigma.DC_tol_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma); + AVFS_meanNsigma.Platform_mean = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean); + AVFS_meanNsigma.PSM_Age_CompFactor = PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor); + AVFS_meanNsigma.Platform_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma); + + for (i = 0; i < NUM_VFT_COLUMNS; i++) { + AVFS_meanNsigma.Static_Voltage_Offset[i] = (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625); + AVFS_SclkOffset.Sclk_Offset[i] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table->entries[i].sclk_offset) / 100); + } + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsMeanNSigma), + &tmp, SMC_RAM_END); + + smu7_copy_bytes_to_smc(hwmgr, + tmp, + (uint8_t *)&AVFS_meanNsigma, + sizeof(AVFS_meanNsigma_t), + SMC_RAM_END); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsSclkOffsetTable), + &tmp, SMC_RAM_END); + smu7_copy_bytes_to_smc(hwmgr, + tmp, + (uint8_t *)&AVFS_SclkOffset, + sizeof(AVFS_Sclk_Offset_t), + SMC_RAM_END); + + data->avfs_vdroop_override_setting = (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT) | + (avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) | + (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) | + (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT); + data->apply_avfs_cks_off_voltage = (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false; + } + return result; +} + +static int polaris10_init_arb_table_index(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + uint32_t tmp; + int result; + + /* This is a read-modify-write on the first byte of the ARB table. + * The first byte in the SMU73_Discrete_MCArbDramTimingTable structure + * is the field 'current'. + * This solution is ugly, but we never write the whole table only + * individual fields in it. + * In reality this field should not be in that structure + * but in a soft register. + */ + result = smu7_read_smc_sram_dword(hwmgr, + smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END); + + if (result) + return result; + + tmp &= 0x00FFFFFF; + tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; + + return smu7_write_smc_sram_dword(hwmgr, + smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END); +} + +static void polaris10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + if (table_info && + table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && + table_info->cac_dtp_table->usPowerTuneDataSetID) + smu_data->power_tune_defaults = + &polaris10_power_tune_data_set_array + [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; + else + smu_data->power_tune_defaults = &polaris10_power_tune_data_set_array[0]; + +} + +static void polaris10_save_default_power_profile(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct SMU74_Discrete_GraphicsLevel *levels = + data->smc_state_table.GraphicsLevel; + unsigned min_level = 1; + + hwmgr->default_gfx_power_profile.activity_threshold = + be16_to_cpu(levels[0].ActivityLevel); + hwmgr->default_gfx_power_profile.up_hyst = levels[0].UpHyst; + hwmgr->default_gfx_power_profile.down_hyst = levels[0].DownHyst; + hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE; + + hwmgr->default_compute_power_profile = hwmgr->default_gfx_power_profile; + hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE; + + /* Workaround compute SDMA instability: disable lowest SCLK + * DPM level. Optimize compute power profile: Use only highest + * 2 power levels (if more than 2 are available), Hysteresis: + * 0ms up, 5ms down + */ + if (data->smc_state_table.GraphicsDpmLevelCount > 2) + min_level = data->smc_state_table.GraphicsDpmLevelCount - 2; + else if (data->smc_state_table.GraphicsDpmLevelCount == 2) + min_level = 1; + else + min_level = 0; + hwmgr->default_compute_power_profile.min_sclk = + be32_to_cpu(levels[min_level].SclkSetting.SclkFrequency); + hwmgr->default_compute_power_profile.up_hyst = 0; + hwmgr->default_compute_power_profile.down_hyst = 5; + + hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile; + hwmgr->compute_power_profile = hwmgr->default_compute_power_profile; +} + +static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr) +{ + int result; + struct smu7_hwmgr *hw_data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct SMU74_Discrete_DpmTable *table = &(smu_data->smc_state_table); + uint8_t i; + struct pp_atomctrl_gpio_pin_assignment gpio_pin; + pp_atomctrl_clock_dividers_vi dividers; + + polaris10_initialize_power_tune_defaults(hwmgr); + + if (SMU7_VOLTAGE_CONTROL_NONE != hw_data->voltage_control) + polaris10_populate_smc_voltage_tables(hwmgr, table); + + table->SystemFlags = 0; + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StepVddc)) + table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; + + if (hw_data->is_memory_gddr5) + table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5; + + if (hw_data->ulv_supported && table_info->us_ulv_voltage_offset) { + result = polaris10_populate_ulv_state(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ULV state!", return result); + cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, + ixCG_ULV_PARAMETER, SMU7_CGULVPARAMETER_DFLT); + } + + result = polaris10_populate_smc_link_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Link Level!", return result); + + result = polaris10_populate_all_graphic_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Graphics Level!", return result); + + result = polaris10_populate_all_memory_levels(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Memory Level!", return result); + + result = polaris10_populate_smc_acpi_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize ACPI Level!", return result); + + result = polaris10_populate_smc_vce_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize VCE Level!", return result); + + result = polaris10_populate_smc_samu_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize SAMU Level!", return result); + + /* Since only the initial state is completely set up at this point + * (the other states are just copies of the boot state) we only + * need to populate the ARB settings for the initial state. + */ + result = polaris10_program_memory_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to Write ARB settings for the initial state.", return result); + + result = polaris10_populate_smc_uvd_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize UVD Level!", return result); + + result = polaris10_populate_smc_boot_level(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Boot Level!", return result); + + result = polaris10_populate_smc_initailial_state(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to initialize Boot State!", return result); + + result = polaris10_populate_bapm_parameters_in_dpm_table(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate BAPM Parameters!", return result); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ClockStretcher)) { + result = polaris10_populate_clock_stretcher_data_table(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate Clock Stretcher Data Table!", + return result); + } + + result = polaris10_populate_avfs_parameters(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, "Failed to populate AVFS Parameters!", return result;); + + table->CurrSclkPllRange = 0xff; + table->GraphicsVoltageChangeEnable = 1; + table->GraphicsThermThrottleEnable = 1; + table->GraphicsInterval = 1; + table->VoltageInterval = 1; + table->ThermalInterval = 1; + table->TemperatureLimitHigh = + table_info->cac_dtp_table->usTargetOperatingTemp * + SMU7_Q88_FORMAT_CONVERSION_UNIT; + table->TemperatureLimitLow = + (table_info->cac_dtp_table->usTargetOperatingTemp - 1) * + SMU7_Q88_FORMAT_CONVERSION_UNIT; + table->MemoryVoltageChangeEnable = 1; + table->MemoryInterval = 1; + table->VoltageResponseTime = 0; + table->PhaseResponseTime = 0; + table->MemoryThermThrottleEnable = 1; + table->PCIeBootLinkLevel = 0; + table->PCIeGenInterval = 1; + table->VRConfig = 0; + + result = polaris10_populate_vr_config(hwmgr, table); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate VRConfig setting!", return result); + + table->ThermGpio = 17; + table->SclkStepSize = 0x4000; + + if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, &gpio_pin)) { + table->VRHotGpio = gpio_pin.uc_gpio_pin_bit_shift; + } else { + table->VRHotGpio = SMU7_UNUSED_GPIO_PIN; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_RegulatorHot); + } + + if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID, + &gpio_pin)) { + table->AcDcGpio = gpio_pin.uc_gpio_pin_bit_shift; + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition); + } else { + table->AcDcGpio = SMU7_UNUSED_GPIO_PIN; + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_AutomaticDCTransition); + } + + /* Thermal Output GPIO */ + if (atomctrl_get_pp_assign_pin(hwmgr, THERMAL_INT_OUTPUT_GPIO_PINID, + &gpio_pin)) { + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_ThermalOutGPIO); + + table->ThermOutGpio = gpio_pin.uc_gpio_pin_bit_shift; + + /* For porlarity read GPIOPAD_A with assigned Gpio pin + * since VBIOS will program this register to set 'inactive state', + * driver can then determine 'active state' from this and + * program SMU with correct polarity + */ + table->ThermOutPolarity = (0 == (cgs_read_register(hwmgr->device, mmGPIOPAD_A) + & (1 << gpio_pin.uc_gpio_pin_bit_shift))) ? 1:0; + table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_ONLY; + + /* if required, combine VRHot/PCC with thermal out GPIO */ + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_RegulatorHot) + && phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_CombinePCCWithThermalSignal)) + table->ThermOutMode = SMU7_THERM_OUT_MODE_THERM_VRHOT; + } else { + table->ThermOutGpio = 17; + table->ThermOutPolarity = 1; + table->ThermOutMode = SMU7_THERM_OUT_MODE_DISABLE; + } + + /* Populate BIF_SCLK levels into SMC DPM table */ + for (i = 0; i <= hw_data->dpm_table.pcie_speed_table.count; i++) { + result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, smu_data->bif_sclk_table[i], ÷rs); + PP_ASSERT_WITH_CODE((result == 0), "Can not find DFS divide id for Sclk", return result); + + if (i == 0) + table->Ulv.BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider)); + else + table->LinkLevel[i-1].BifSclkDfs = PP_HOST_TO_SMC_US((USHORT)(dividers.pll_post_divider)); + } + + for (i = 0; i < SMU74_MAX_ENTRIES_SMIO; i++) + table->Smio[i] = PP_HOST_TO_SMC_UL(table->Smio[i]); + + CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags); + CONVERT_FROM_HOST_TO_SMC_UL(table->VRConfig); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1); + CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2); + CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); + CONVERT_FROM_HOST_TO_SMC_UL(table->CurrSclkPllRange); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); + CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); + CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); + CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); + + /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ + result = smu7_copy_bytes_to_smc(hwmgr, + smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, SystemFlags), + (uint8_t *)&(table->SystemFlags), + sizeof(SMU74_Discrete_DpmTable) - 3 * sizeof(SMU74_PIDController), + SMC_RAM_END); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to upload dpm data to SMC memory!", return result); + + result = polaris10_init_arb_table_index(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to upload arb data to SMC memory!", return result); + + result = polaris10_populate_pm_fuses(hwmgr); + PP_ASSERT_WITH_CODE(0 == result, + "Failed to populate PM fuses to SMC memory!", return result); + + polaris10_save_default_power_profile(hwmgr); + + return 0; +} + +static int polaris10_program_mem_timing_parameters(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (data->need_update_smu7_dpm_table & + (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK)) + return polaris10_program_memory_timing_parameters(hwmgr); + + return 0; +} + +int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr) +{ + int ret; + struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + + if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED) + return 0; + + ret = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting); + + ret = (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs) == 0) ? + 0 : -1; + + if (!ret) + /* If this param is not changed, this function could fire unnecessarily */ + smu_data->avfs.avfs_btc_status = AVFS_BTC_COMPLETED_PREVIOUSLY; + + return ret; +} + +static int polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + SMU74_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; + uint32_t duty100; + uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2; + uint16_t fdo_min, slope1, slope2; + uint32_t reference_clock; + int res; + uint64_t tmp64; + + if (hwmgr->thermal_controller.fanInfo.bNoFan) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + if (smu_data->smu7_data.fan_table_start == 0) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, + CG_FDO_CTRL1, FMAX_DUTY100); + + if (duty100 == 0) { + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + return 0; + } + + tmp64 = hwmgr->thermal_controller.advanceFanControlParameters. + usPWMMin * duty100; + do_div(tmp64, 10000); + fdo_min = (uint16_t)tmp64; + + t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - + hwmgr->thermal_controller.advanceFanControlParameters.usTMin; + t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - + hwmgr->thermal_controller.advanceFanControlParameters.usTMed; + + pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin; + pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - + hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed; + + slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); + slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + + fan_table.TempMin = cpu_to_be16((50 + hwmgr-> + thermal_controller.advanceFanControlParameters.usTMin) / 100); + fan_table.TempMed = cpu_to_be16((50 + hwmgr-> + thermal_controller.advanceFanControlParameters.usTMed) / 100); + fan_table.TempMax = cpu_to_be16((50 + hwmgr-> + thermal_controller.advanceFanControlParameters.usTMax) / 100); + + fan_table.Slope1 = cpu_to_be16(slope1); + fan_table.Slope2 = cpu_to_be16(slope2); + + fan_table.FdoMin = cpu_to_be16(fdo_min); + + fan_table.HystDown = cpu_to_be16(hwmgr-> + thermal_controller.advanceFanControlParameters.ucTHyst); + + fan_table.HystUp = cpu_to_be16(1); + + fan_table.HystSlope = cpu_to_be16(1); + + fan_table.TempRespLim = cpu_to_be16(5); + + reference_clock = smu7_get_xclk(hwmgr); + + fan_table.RefreshPeriod = cpu_to_be32((hwmgr-> + thermal_controller.advanceFanControlParameters.ulCycleDelay * + reference_clock) / 1600); + + fan_table.FdoMax = cpu_to_be16((uint16_t)duty100); + + fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD( + hwmgr->device, CGS_IND_REG__SMC, + CG_MULT_THERMAL_CTRL, TEMP_SEL); + + res = smu7_copy_bytes_to_smc(hwmgr, smu_data->smu7_data.fan_table_start, + (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), + SMC_RAM_END); + + if (!res && hwmgr->thermal_controller. + advanceFanControlParameters.ucMinimumPWMLimit) + res = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SetFanMinPwm, + hwmgr->thermal_controller. + advanceFanControlParameters.ucMinimumPWMLimit); + + if (!res && hwmgr->thermal_controller. + advanceFanControlParameters.ulMinFanSCLKAcousticLimit) + res = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SetFanSclkTarget, + hwmgr->thermal_controller. + advanceFanControlParameters.ulMinFanSCLKAcousticLimit); + + if (res) + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_MicrocodeFanControl); + + return 0; +} + +static int polaris10_update_uvd_smc_table(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + smu_data->smc_state_table.UvdBootLevel = 0; + if (table_info->mm_dep_table->count > 0) + smu_data->smc_state_table.UvdBootLevel = + (uint8_t) (table_info->mm_dep_table->count - 1); + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + offsetof(SMU74_Discrete_DpmTable, + UvdBootLevel); + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0x00FFFFFF; + mm_boot_level_value |= smu_data->smc_state_table.UvdBootLevel << 24; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_UVDDPM) || + phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_UVDDPM_SetEnabledMask, + (uint32_t)(1 << smu_data->smc_state_table.UvdBootLevel)); + return 0; +} + +static int polaris10_update_vce_smc_table(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smu_data->smc_state_table.VceBootLevel = + (uint8_t) (table_info->mm_dep_table->count - 1); + else + smu_data->smc_state_table.VceBootLevel = 0; + + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, VceBootLevel); + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0xFF00FFFF; + mm_boot_level_value |= smu_data->smc_state_table.VceBootLevel << 16; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_VCEDPM_SetEnabledMask, + (uint32_t)1 << smu_data->smc_state_table.VceBootLevel); + return 0; +} + +static int polaris10_update_samu_smc_table(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + uint32_t mm_boot_level_offset, mm_boot_level_value; + + + smu_data->smc_state_table.SamuBootLevel = 0; + mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); + + mm_boot_level_offset /= 4; + mm_boot_level_offset *= 4; + mm_boot_level_value = cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset); + mm_boot_level_value &= 0xFFFFFF00; + mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; + cgs_write_ind_register(hwmgr->device, + CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_StablePState)) + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_SAMUDPM_SetEnabledMask, + (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); + return 0; +} + + +static int polaris10_update_bif_smc_table(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)(hwmgr->pptable); + struct phm_ppt_v1_pcie_table *pcie_table = table_info->pcie_table; + int max_entry, i; + + max_entry = (SMU74_MAX_LEVELS_LINK < pcie_table->count) ? + SMU74_MAX_LEVELS_LINK : + pcie_table->count; + /* Setup BIF_SCLK levels */ + for (i = 0; i < max_entry; i++) + smu_data->bif_sclk_table[i] = pcie_table->entries[i].pcie_sclk; + return 0; +} + +static int polaris10_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) +{ + switch (type) { + case SMU_UVD_TABLE: + polaris10_update_uvd_smc_table(hwmgr); + break; + case SMU_VCE_TABLE: + polaris10_update_vce_smc_table(hwmgr); + break; + case SMU_SAMU_TABLE: + polaris10_update_samu_smc_table(hwmgr); + break; + case SMU_BIF_TABLE: + polaris10_update_bif_smc_table(hwmgr); + default: + break; + } + return 0; +} + +static int polaris10_update_sclk_threshold(struct pp_hwmgr *hwmgr) +{ + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + + int result = 0; + uint32_t low_sclk_interrupt_threshold = 0; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_SclkThrottleLowNotification) + && (hwmgr->gfx_arbiter.sclk_threshold != + data->low_sclk_interrupt_threshold)) { + data->low_sclk_interrupt_threshold = + hwmgr->gfx_arbiter.sclk_threshold; + low_sclk_interrupt_threshold = + data->low_sclk_interrupt_threshold; + + CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); + + result = smu7_copy_bytes_to_smc( + hwmgr, + smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, + LowSclkInterruptThreshold), + (uint8_t *)&low_sclk_interrupt_threshold, + sizeof(uint32_t), + SMC_RAM_END); + } + PP_ASSERT_WITH_CODE((result == 0), + "Failed to update SCLK threshold!", return result); + + result = polaris10_program_mem_timing_parameters(hwmgr); + PP_ASSERT_WITH_CODE((result == 0), + "Failed to program memory timing parameters!", + ); + + return result; +} + +static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member) +{ + switch (type) { + case SMU_SoftRegisters: + switch (member) { + case HandshakeDisables: + return offsetof(SMU74_SoftRegisters, HandshakeDisables); + case VoltageChangeTimeout: + return offsetof(SMU74_SoftRegisters, VoltageChangeTimeout); + case AverageGraphicsActivity: + return offsetof(SMU74_SoftRegisters, AverageGraphicsActivity); + case PreVBlankGap: + return offsetof(SMU74_SoftRegisters, PreVBlankGap); + case VBlankTimeout: + return offsetof(SMU74_SoftRegisters, VBlankTimeout); + case UcodeLoadStatus: + return offsetof(SMU74_SoftRegisters, UcodeLoadStatus); + case DRAM_LOG_ADDR_H: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_H); + case DRAM_LOG_ADDR_L: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_ADDR_L); + case DRAM_LOG_PHY_ADDR_H: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_H); + case DRAM_LOG_PHY_ADDR_L: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_PHY_ADDR_L); + case DRAM_LOG_BUFF_SIZE: + return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE); + } + case SMU_Discrete_DpmTable: + switch (member) { + case UvdBootLevel: + return offsetof(SMU74_Discrete_DpmTable, UvdBootLevel); + case VceBootLevel: + return offsetof(SMU74_Discrete_DpmTable, VceBootLevel); + case SamuBootLevel: + return offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); + case LowSclkInterruptThreshold: + return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold); + } + } + pr_warn("can't get the offset of type %x member %x\n", type, member); + return 0; +} + +static uint32_t polaris10_get_mac_definition(uint32_t value) +{ + switch (value) { + case SMU_MAX_LEVELS_GRAPHICS: + return SMU74_MAX_LEVELS_GRAPHICS; + case SMU_MAX_LEVELS_MEMORY: + return SMU74_MAX_LEVELS_MEMORY; + case SMU_MAX_LEVELS_LINK: + return SMU74_MAX_LEVELS_LINK; + case SMU_MAX_ENTRIES_SMIO: + return SMU74_MAX_ENTRIES_SMIO; + case SMU_MAX_LEVELS_VDDC: + return SMU74_MAX_LEVELS_VDDC; + case SMU_MAX_LEVELS_VDDGFX: + return SMU74_MAX_LEVELS_VDDGFX; + case SMU_MAX_LEVELS_VDDCI: + return SMU74_MAX_LEVELS_VDDCI; + case SMU_MAX_LEVELS_MVDD: + return SMU74_MAX_LEVELS_MVDD; + case SMU_UVD_MCLK_HANDSHAKE_DISABLE: + return SMU7_UVD_MCLK_HANDSHAKE_DISABLE; + } + + pr_warn("can't get the mac of %x\n", value); + return 0; +} + +static int polaris10_process_firmware_header(struct pp_hwmgr *hwmgr) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); + uint32_t tmp; + int result; + bool error = false; + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU74_Firmware_Header, DpmTable), + &tmp, SMC_RAM_END); + + if (0 == result) + smu_data->smu7_data.dpm_table_start = tmp; + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU74_Firmware_Header, SoftRegisters), + &tmp, SMC_RAM_END); + + if (!result) { + data->soft_regs_start = tmp; + smu_data->smu7_data.soft_regs_start = tmp; + } + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU74_Firmware_Header, mcRegisterTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.mc_reg_table_start = tmp; + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU74_Firmware_Header, FanTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.fan_table_start = tmp; + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU74_Firmware_Header, mcArbDramTimingTable), + &tmp, SMC_RAM_END); + + if (!result) + smu_data->smu7_data.arb_table_start = tmp; + + error |= (0 != result); + + result = smu7_read_smc_sram_dword(hwmgr, + SMU7_FIRMWARE_HEADER_LOCATION + + offsetof(SMU74_Firmware_Header, Version), + &tmp, SMC_RAM_END); + + if (!result) + hwmgr->microcode_version_info.SMC = tmp; + + error |= (0 != result); + + return error ? -1 : 0; +} + +static bool polaris10_is_dpm_running(struct pp_hwmgr *hwmgr) +{ + return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) + ? true : false; +} + +static int polaris10_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr, + struct amd_pp_profile *request) +{ + struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *) + (hwmgr->smu_backend); + struct SMU74_Discrete_GraphicsLevel *levels = + smu_data->smc_state_table.GraphicsLevel; + uint32_t array = smu_data->smu7_data.dpm_table_start + + offsetof(SMU74_Discrete_DpmTable, GraphicsLevel); + uint32_t array_size = sizeof(struct SMU74_Discrete_GraphicsLevel) * + SMU74_MAX_LEVELS_GRAPHICS; + uint32_t i; + + for (i = 0; i < smu_data->smc_state_table.GraphicsDpmLevelCount; i++) { + levels[i].ActivityLevel = + cpu_to_be16(request->activity_threshold); + levels[i].EnabledForActivity = 1; + levels[i].UpHyst = request->up_hyst; + levels[i].DownHyst = request->down_hyst; + } + + return smu7_copy_bytes_to_smc(hwmgr, array, (uint8_t *)levels, + array_size, SMC_RAM_END); +} + const struct pp_smumgr_func polaris10_smu_funcs = { .smu_init = polaris10_smu_init, .smu_fini = smu7_smu_fini, -- cgit v1.2.3 From f15507a1ac0dcdbda0c6c4fe4dc168bfe0034535 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 11 Oct 2017 10:21:11 +0100 Subject: drm/amdgpu: make function uvd_v6_0_enc_get_destroy_msg static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function uvd_v6_0_enc_get_destroy_msg is local to the source and does not need to be in global scope, so make it static. Cleans up sparse warning: symbol 'uvd_v6_0_enc_get_destroy_msg' was not declared. Should it be static? Reviewed-by: Christian König Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 60af7310a234..71299c67c517 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -268,8 +268,9 @@ err: * * Close up a stream for HW test or if userspace failed to do so */ -int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - bool direct, struct dma_fence **fence) +static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, + uint32_t handle, + bool direct, struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; -- cgit v1.2.3 From ad864d243826cedc53404a1c0db7d1e38ddceb84 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 10 Oct 2017 16:50:16 -0400 Subject: drm/amdgpu: Refactor amdgpu_cs_ib_vm_chunk and amdgpu_cs_ib_fill. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This enables old fence waiting before reservation lock is aquired which in turn is part of a bigger solution to deadlock happening when gpu reset with VRAM recovery accures during intensive rendering. Signed-off-by: Andrey Grodzovsky Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 112 ++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index fe7dd44ac9fe..9166d5e1e557 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -845,15 +845,60 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_ring *ring = p->job->ring; - int i, r; + int i, j, r; + + for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { + + struct amdgpu_cs_chunk *chunk; + struct amdgpu_ib *ib; + struct drm_amdgpu_cs_chunk_ib *chunk_ib; + + chunk = &p->chunks[i]; + ib = &p->job->ibs[j]; + chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; + + if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) + continue; + + if (p->job->ring->funcs->parse_cs) { + struct amdgpu_bo_va_mapping *m; + struct amdgpu_bo *aobj = NULL; + uint64_t offset; + uint8_t *kptr; + + r = amdgpu_cs_find_mapping(p, chunk_ib->va_start, + &aobj, &m); + if (r) { + DRM_ERROR("IB va_start is invalid\n"); + return r; + } - /* Only for UVD/VCE VM emulation */ - if (ring->funcs->parse_cs) { - for (i = 0; i < p->job->num_ibs; i++) { - r = amdgpu_ring_parse_cs(ring, p, i); + if ((chunk_ib->va_start + chunk_ib->ib_bytes) > + (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { + DRM_ERROR("IB va_start+ib_bytes is invalid\n"); + return -EINVAL; + } + + /* the IB should be reserved at this point */ + r = amdgpu_bo_kmap(aobj, (void **)&kptr); + if (r) { + return r; + } + + offset = m->start * AMDGPU_GPU_PAGE_SIZE; + kptr += chunk_ib->va_start - offset; + + memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); + amdgpu_bo_kunmap(aobj); + + /* Only for UVD/VCE VM emulation */ + r = amdgpu_ring_parse_cs(ring, p, j); if (r) return r; + } + + j++; } if (p->job->vm) { @@ -919,54 +964,18 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, parser->job->ring = ring; - if (ring->funcs->parse_cs) { - struct amdgpu_bo_va_mapping *m; - struct amdgpu_bo *aobj = NULL; - uint64_t offset; - uint8_t *kptr; - - r = amdgpu_cs_find_mapping(parser, chunk_ib->va_start, - &aobj, &m); - if (r) { - DRM_ERROR("IB va_start is invalid\n"); - return r; - } - - if ((chunk_ib->va_start + chunk_ib->ib_bytes) > - (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { - DRM_ERROR("IB va_start+ib_bytes is invalid\n"); - return -EINVAL; - } - - /* the IB should be reserved at this point */ - r = amdgpu_bo_kmap(aobj, (void **)&kptr); - if (r) { - return r; - } - - offset = m->start * AMDGPU_GPU_PAGE_SIZE; - kptr += chunk_ib->va_start - offset; - - r = amdgpu_ib_get(adev, vm, chunk_ib->ib_bytes, ib); - if (r) { - DRM_ERROR("Failed to get ib !\n"); - return r; - } - - memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); - amdgpu_bo_kunmap(aobj); - } else { - r = amdgpu_ib_get(adev, vm, 0, ib); - if (r) { - DRM_ERROR("Failed to get ib !\n"); - return r; - } - + r = amdgpu_ib_get(adev, vm, + ring->funcs->parse_cs ? chunk_ib->ib_bytes : 0, + ib); + if (r) { + DRM_ERROR("Failed to get ib !\n"); + return r; } ib->gpu_addr = chunk_ib->va_start; ib->length_dw = chunk_ib->ib_bytes / 4; ib->flags = chunk_ib->flags; + j++; } @@ -1212,6 +1221,10 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) goto out; } + r = amdgpu_cs_ib_fill(adev, &parser); + if (r) + goto out; + r = amdgpu_cs_parser_bos(&parser, data); if (r) { if (r == -ENOMEM) @@ -1222,9 +1235,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } reserved_buffers = true; - r = amdgpu_cs_ib_fill(adev, &parser); - if (r) - goto out; r = amdgpu_cs_dependencies(adev, &parser); if (r) { -- cgit v1.2.3 From 0ae94444c08a0adf2fab4aab26be0646ee445a19 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 10 Oct 2017 16:50:17 -0400 Subject: drm/amdgpu: Move old fence waiting before reservation lock is aquired v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helps avoiding deadlock during GPU reset. Added mutex to amdgpu_ctx to preserve order of fences on a ring. v2: Put waiting logic in a function in a seperate function in amdgpu_ctx.c Signed-off-by: Andrey Grodzovsky Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 10 ++++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 30 ++++++++++++++++++++++++------ 3 files changed, 34 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 951c8db01412..76033e2cdba8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -738,6 +738,7 @@ struct amdgpu_ctx { bool preamble_presented; enum amd_sched_priority init_priority; enum amd_sched_priority override_priority; + struct mutex lock; }; struct amdgpu_ctx_mgr { @@ -760,9 +761,12 @@ void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id); + void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr); void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); + /* * file private structure */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 9166d5e1e557..5de092eab0fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -90,6 +90,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) goto free_chunk; } + mutex_lock(&p->ctx->lock); + /* get chunks */ chunk_array_user = u64_to_user_ptr(cs->in.chunks); if (copy_from_user(chunk_array, chunk_array_user, @@ -737,8 +739,10 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, dma_fence_put(parser->fence); - if (parser->ctx) + if (parser->ctx) { + mutex_unlock(&parser->ctx->lock); amdgpu_ctx_put(parser->ctx); + } if (parser->bo_list) amdgpu_bo_list_put(parser->bo_list); @@ -895,9 +899,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, r = amdgpu_ring_parse_cs(ring, p, j); if (r) return r; - } - j++; } @@ -985,7 +987,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, parser->job->ring->funcs->type == AMDGPU_RING_TYPE_VCE)) return -EINVAL; - return 0; + return amdgpu_ctx_wait_prev_fence(parser->ctx, parser->job->ring->idx); } static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index a78b03f65c69..4309820658c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -67,6 +67,8 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, if (!ctx->fences) return -ENOMEM; + mutex_init(&ctx->lock); + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { ctx->rings[i].sequence = 1; ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i]; @@ -126,6 +128,8 @@ static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) &ctx->rings[i].entity); amdgpu_queue_mgr_fini(adev, &ctx->queue_mgr); + + mutex_destroy(&ctx->lock); } static int amdgpu_ctx_alloc(struct amdgpu_device *adev, @@ -296,12 +300,8 @@ int amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, idx = seq & (amdgpu_sched_jobs - 1); other = cring->fences[idx]; - if (other) { - signed long r; - r = dma_fence_wait_timeout(other, true, MAX_SCHEDULE_TIMEOUT); - if (r < 0) - return r; - } + if (other) + BUG_ON(!dma_fence_is_signaled(other)); dma_fence_get(fence); @@ -372,6 +372,24 @@ void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, } } +int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id) +{ + struct amdgpu_ctx_ring *cring = &ctx->rings[ring_id]; + unsigned idx = cring->sequence & (amdgpu_sched_jobs - 1); + struct dma_fence *other = cring->fences[idx]; + + if (other) { + signed long r; + r = dma_fence_wait_timeout(other, false, MAX_SCHEDULE_TIMEOUT); + if (r < 0) { + DRM_ERROR("Error (%ld) waiting for fence!\n", r); + return r; + } + } + + return 0; +} + void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr) { mutex_init(&mgr->lock); -- cgit v1.2.3 From 2dc8f81e4f822cfe8f6475da968ab2dd5881b8d8 Mon Sep 17 00:00:00 2001 From: Horace Chen Date: Mon, 9 Oct 2017 16:17:16 +0800 Subject: drm/amdgpu: SR-IOV data exchange between PF&VF SR-IOV need to exchange some data between PF&VF through shared VRAM PF will copy some necessary firmware and information to the shared VRAM. It also requires some information from VF. PF will send a key through mailbox2 to help guest calculate checksum so that it can verify whether the data is correct. So check the data on the specified offset of the shared VRAM, if the checksum is right, read values from it and write some VF information next to the data from PF. Signed-off-by: Horace Chen Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 75 ++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 178 +++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | 6 + 4 files changed, 262 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1f793eb301ef..9cdaba4af216 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2300,6 +2300,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (r) DRM_ERROR("ib ring test failed (%d).\n", r); + if (amdgpu_sriov_vf(adev)) + amdgpu_virt_init_data_exchange(adev); + amdgpu_fbdev_init(adev); r = amdgpu_pm_sysfs_init(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index ab05121b9272..ed7be2eb24b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -274,3 +274,78 @@ void amdgpu_virt_free_mm_table(struct amdgpu_device *adev) (void *)&adev->virt.mm_table.cpu_addr); adev->virt.mm_table.gpu_addr = 0; } + + +int amdgpu_virt_fw_reserve_get_checksum(void *obj, + unsigned long obj_size, + unsigned int key, + unsigned int chksum) +{ + unsigned int ret = key; + unsigned long i = 0; + unsigned char *pos; + + pos = (char *)obj; + /* calculate checksum */ + for (i = 0; i < obj_size; ++i) + ret += *(pos + i); + /* minus the chksum itself */ + pos = (char *)&chksum; + for (i = 0; i < sizeof(chksum); ++i) + ret -= *(pos + i); + return ret; +} + +void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) +{ + uint32_t pf2vf_ver = 0; + uint32_t pf2vf_size = 0; + uint32_t checksum = 0; + uint32_t checkval; + char *str; + + adev->virt.fw_reserve.p_pf2vf = NULL; + adev->virt.fw_reserve.p_vf2pf = NULL; + + if (adev->fw_vram_usage.va != NULL) { + adev->virt.fw_reserve.p_pf2vf = + (struct amdgim_pf2vf_info_header *)( + adev->fw_vram_usage.va + AMDGIM_DATAEXCHANGE_OFFSET); + pf2vf_ver = adev->virt.fw_reserve.p_pf2vf->version; + AMDGPU_FW_VRAM_PF2VF_READ(adev, header.size, &pf2vf_size); + AMDGPU_FW_VRAM_PF2VF_READ(adev, checksum, &checksum); + + /* pf2vf message must be in 4K */ + if (pf2vf_size > 0 && pf2vf_size < 4096) { + checkval = amdgpu_virt_fw_reserve_get_checksum( + adev->virt.fw_reserve.p_pf2vf, pf2vf_size, + adev->virt.fw_reserve.checksum_key, checksum); + if (checkval == checksum) { + adev->virt.fw_reserve.p_vf2pf = + ((void *)adev->virt.fw_reserve.p_pf2vf + + pf2vf_size); + memset((void *)adev->virt.fw_reserve.p_vf2pf, 0, + sizeof(amdgim_vf2pf_info)); + AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.version, + AMDGPU_FW_VRAM_VF2PF_VER); + AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.size, + sizeof(amdgim_vf2pf_info)); + AMDGPU_FW_VRAM_VF2PF_READ(adev, driver_version, + &str); + if (THIS_MODULE->version != NULL) + strcpy(str, THIS_MODULE->version); + else + strcpy(str, "N/A"); + AMDGPU_FW_VRAM_VF2PF_WRITE(adev, driver_cert, + 0); + AMDGPU_FW_VRAM_VF2PF_WRITE(adev, checksum, + amdgpu_virt_fw_reserve_get_checksum( + adev->virt.fw_reserve.p_vf2pf, + pf2vf_size, + adev->virt.fw_reserve.checksum_key, 0)); + } + } + } +} + + diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index e5fd0ff6b29d..b89d37fc406f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h @@ -58,6 +58,179 @@ struct amdgpu_virt_ops { void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); }; +/* + * Firmware Reserve Frame buffer + */ +struct amdgpu_virt_fw_reserve { + struct amdgim_pf2vf_info_header *p_pf2vf; + struct amdgim_vf2pf_info_header *p_vf2pf; + unsigned int checksum_key; +}; +/* + * Defination between PF and VF + * Structures forcibly aligned to 4 to keep the same style as PF. + */ +#define AMDGIM_DATAEXCHANGE_OFFSET (64 * 1024) + +#define AMDGIM_GET_STRUCTURE_RESERVED_SIZE(total, u8, u16, u32, u64) \ + (total - (((u8)+3) / 4 + ((u16)+1) / 2 + (u32) + (u64)*2)) + +enum AMDGIM_FEATURE_FLAG { + /* GIM supports feature of Error log collecting */ + AMDGIM_FEATURE_ERROR_LOG_COLLECT = 0x1, + /* GIM supports feature of loading uCodes */ + AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2, +}; + +struct amdgim_pf2vf_info_header { + /* the total structure size in byte. */ + uint32_t size; + /* version of this structure, written by the GIM */ + uint32_t version; +} __aligned(4); +struct amdgim_pf2vf_info_v1 { + /* header contains size and version */ + struct amdgim_pf2vf_info_header header; + /* max_width * max_height */ + unsigned int uvd_enc_max_pixels_count; + /* 16x16 pixels/sec, codec independent */ + unsigned int uvd_enc_max_bandwidth; + /* max_width * max_height */ + unsigned int vce_enc_max_pixels_count; + /* 16x16 pixels/sec, codec independent */ + unsigned int vce_enc_max_bandwidth; + /* MEC FW position in kb from the start of visible frame buffer */ + unsigned int mecfw_kboffset; + /* The features flags of the GIM driver supports. */ + unsigned int feature_flags; + /* use private key from mailbox 2 to create chueksum */ + unsigned int checksum; +} __aligned(4); + +struct amdgim_pf2vf_info_v2 { + /* header contains size and version */ + struct amdgim_pf2vf_info_header header; + /* use private key from mailbox 2 to create chueksum */ + uint32_t checksum; + /* The features flags of the GIM driver supports. */ + uint32_t feature_flags; + /* max_width * max_height */ + uint32_t uvd_enc_max_pixels_count; + /* 16x16 pixels/sec, codec independent */ + uint32_t uvd_enc_max_bandwidth; + /* max_width * max_height */ + uint32_t vce_enc_max_pixels_count; + /* 16x16 pixels/sec, codec independent */ + uint32_t vce_enc_max_bandwidth; + /* MEC FW position in kb from the start of VF visible frame buffer */ + uint64_t mecfw_kboffset; + /* MEC FW size in KB */ + uint32_t mecfw_ksize; + /* UVD FW position in kb from the start of VF visible frame buffer */ + uint64_t uvdfw_kboffset; + /* UVD FW size in KB */ + uint32_t uvdfw_ksize; + /* VCE FW position in kb from the start of VF visible frame buffer */ + uint64_t vcefw_kboffset; + /* VCE FW size in KB */ + uint32_t vcefw_ksize; + uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 0, 0, (9 + sizeof(struct amdgim_pf2vf_info_header)/sizeof(uint32_t)), 3)]; +} __aligned(4); + + +struct amdgim_vf2pf_info_header { + /* the total structure size in byte. */ + uint32_t size; + /*version of this structure, written by the guest */ + uint32_t version; +} __aligned(4); + +struct amdgim_vf2pf_info_v1 { + /* header contains size and version */ + struct amdgim_vf2pf_info_header header; + /* driver version */ + char driver_version[64]; + /* driver certification, 1=WHQL, 0=None */ + unsigned int driver_cert; + /* guest OS type and version: need a define */ + unsigned int os_info; + /* in the unit of 1M */ + unsigned int fb_usage; + /* guest gfx engine usage percentage */ + unsigned int gfx_usage; + /* guest gfx engine health percentage */ + unsigned int gfx_health; + /* guest compute engine usage percentage */ + unsigned int compute_usage; + /* guest compute engine health percentage */ + unsigned int compute_health; + /* guest vce engine usage percentage. 0xffff means N/A. */ + unsigned int vce_enc_usage; + /* guest vce engine health percentage. 0xffff means N/A. */ + unsigned int vce_enc_health; + /* guest uvd engine usage percentage. 0xffff means N/A. */ + unsigned int uvd_enc_usage; + /* guest uvd engine usage percentage. 0xffff means N/A. */ + unsigned int uvd_enc_health; + unsigned int checksum; +} __aligned(4); + +struct amdgim_vf2pf_info_v2 { + /* header contains size and version */ + struct amdgim_vf2pf_info_header header; + uint32_t checksum; + /* driver version */ + uint8_t driver_version[64]; + /* driver certification, 1=WHQL, 0=None */ + uint32_t driver_cert; + /* guest OS type and version: need a define */ + uint32_t os_info; + /* in the unit of 1M */ + uint32_t fb_usage; + /* guest gfx engine usage percentage */ + uint32_t gfx_usage; + /* guest gfx engine health percentage */ + uint32_t gfx_health; + /* guest compute engine usage percentage */ + uint32_t compute_usage; + /* guest compute engine health percentage */ + uint32_t compute_health; + /* guest vce engine usage percentage. 0xffff means N/A. */ + uint32_t vce_enc_usage; + /* guest vce engine health percentage. 0xffff means N/A. */ + uint32_t vce_enc_health; + /* guest uvd engine usage percentage. 0xffff means N/A. */ + uint32_t uvd_enc_usage; + /* guest uvd engine usage percentage. 0xffff means N/A. */ + uint32_t uvd_enc_health; + uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 64, 0, (12 + sizeof(struct amdgim_vf2pf_info_header)/sizeof(uint32_t)), 0)]; +} __aligned(4); + +#define AMDGPU_FW_VRAM_VF2PF_VER 2 +typedef struct amdgim_vf2pf_info_v2 amdgim_vf2pf_info ; + +#define AMDGPU_FW_VRAM_VF2PF_WRITE(adev, field, val) \ + do { \ + ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field = (val); \ + } while (0) + +#define AMDGPU_FW_VRAM_VF2PF_READ(adev, field, val) \ + do { \ + (*val) = ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field; \ + } while (0) + +#define AMDGPU_FW_VRAM_PF2VF_READ(adev, field, val) \ + do { \ + if (!adev->virt.fw_reserve.p_pf2vf) \ + *(val) = 0; \ + else { \ + if (adev->virt.fw_reserve.p_pf2vf->version == 1) \ + *(val) = ((struct amdgim_pf2vf_info_v1 *)adev->virt.fw_reserve.p_pf2vf)->field; \ + if (adev->virt.fw_reserve.p_pf2vf->version == 2) \ + *(val) = ((struct amdgim_pf2vf_info_v2 *)adev->virt.fw_reserve.p_pf2vf)->field; \ + } \ + } while (0) + /* GPU virtualization */ struct amdgpu_virt { uint32_t caps; @@ -72,6 +245,7 @@ struct amdgpu_virt { struct amdgpu_mm_table mm_table; const struct amdgpu_virt_ops *ops; struct amdgpu_vf_error_buffer vf_errors; + struct amdgpu_virt_fw_reserve fw_reserve; }; #define AMDGPU_CSA_SIZE (8 * 1024) @@ -114,5 +288,9 @@ int amdgpu_virt_reset_gpu(struct amdgpu_device *adev); int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job); int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); +int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size, + unsigned int key, + unsigned int chksum); +void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index 2812d88a8bdd..b4906d2f30d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c @@ -183,6 +183,12 @@ static int xgpu_ai_send_access_requests(struct amdgpu_device *adev, pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n"); return r; } + /* Retrieve checksum from mailbox2 */ + if (req == IDH_REQ_GPU_INIT_ACCESS) { + adev->virt.fw_reserve.checksum_key = + RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, + mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW2)); + } } return 0; -- cgit v1.2.3 From 76d6172b6fab16455af4b67bb18a3f66011592f8 Mon Sep 17 00:00:00 2001 From: Ken Wang Date: Fri, 29 Sep 2017 15:41:43 +0800 Subject: drm/amdgpu: correct reference clock value on vega10 Old value from bringup was wrong. Cc: stable@vger.kernel.org Signed-off-by: Ken Wang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 1c006ba9d826..3ca9d114f630 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -279,10 +279,7 @@ static void soc15_init_golden_registers(struct amdgpu_device *adev) } static u32 soc15_get_xclk(struct amdgpu_device *adev) { - if (adev->asic_type == CHIP_VEGA10) - return adev->clock.spll.reference_freq/4; - else - return adev->clock.spll.reference_freq; + return adev->clock.spll.reference_freq; } -- cgit v1.2.3 From f4c809914a7c3e4a59cf543da6c2a15d0f75ee38 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 9 Oct 2017 14:34:13 +0200 Subject: drm/ttm: don't use compound pages for now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to figure out first how to correctly map them into the CPU page tables. bug: https://bugs.freedesktop.org/show_bug.cgi?id=103138 Signed-off-by: Christian König Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index e5ef10d34748..96ad12906621 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -913,6 +913,7 @@ static gfp_t ttm_dma_pool_gfp_flags(struct ttm_dma_tt *ttm_dma, bool huge) if (huge) { gfp_flags |= GFP_TRANSHUGE; gfp_flags &= ~__GFP_MOVABLE; + gfp_flags &= ~__GFP_COMP; } return gfp_flags; -- cgit v1.2.3 From 0284f1ead87463bc17cf5e81a24fc65c052486f3 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 20 Sep 2017 15:06:12 +0200 Subject: drm/ttm: add transparent huge page support for cached allocations v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to allocate huge pages when it makes sense. v2: avoid compound pages for now Signed-off-by: Christian König Acked-by: Felix Kuehling Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 50 ++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 6c852e81660b..1bc6053b4581 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -685,12 +685,24 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, if (pool == NULL) { /* No pool for this memory type so free the pages */ - for (i = 0; i < npages; i++) { - if (pages[i]) { - if (page_count(pages[i]) != 1) - pr_err("Erroneous page count. Leaking pages.\n"); - __free_page(pages[i]); - pages[i] = NULL; + i = 0; + while (i < npages) { + unsigned order; + + if (!pages[i]) { + ++i; + continue; + } + + if (page_count(pages[i]) != 1) + pr_err("Erroneous page count. Leaking pages.\n"); + order = compound_order(pages[i]); + __free_pages(pages[i], order); + + order = 1 << order; + while (order) { + pages[i++] = NULL; + --order; } } return; @@ -740,12 +752,33 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, /* No pool for cached pages */ if (pool == NULL) { + unsigned i, j; + if (flags & TTM_PAGE_FLAG_DMA32) gfp_flags |= GFP_DMA32; else gfp_flags |= GFP_HIGHUSER; - for (r = 0; r < npages; ++r) { + i = 0; +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + while (npages >= HPAGE_PMD_NR) { + gfp_t huge_flags = gfp_flags; + + huge_flags |= GFP_TRANSHUGE; + huge_flags &= ~__GFP_MOVABLE; + huge_flags &= ~__GFP_COMP; + p = alloc_pages(huge_flags, HPAGE_PMD_ORDER); + if (!p) + break; + + for (j = 0; j < HPAGE_PMD_NR; ++j) + pages[i++] = p++; + + npages -= HPAGE_PMD_NR; + } +#endif + + while (npages) { p = alloc_page(gfp_flags); if (!p) { @@ -753,7 +786,8 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, return -ENOMEM; } - pages[r] = p; + pages[i++] = p; + --npages; } return 0; } -- cgit v1.2.3 From 8593e9b85e0aa67db62ec395774021a139efc2cd Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 21 Sep 2017 11:28:25 +0200 Subject: drm/ttm: move more logic into ttm_page_pool_get_pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it easier to add huge page pool. Signed-off-by: Christian König Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 98 +++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 1bc6053b4581..39747326bf3e 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -627,19 +627,20 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, } /** - * Cut 'count' number of pages from the pool and put them on the return list. + * Allocate pages from the pool and put them on the return list. * - * @return count of pages still required to fulfill the request. + * @return zero for success or negative error code. */ -static unsigned ttm_page_pool_get_pages(struct ttm_page_pool *pool, - struct list_head *pages, - int ttm_flags, - enum ttm_caching_state cstate, - unsigned count) +static int ttm_page_pool_get_pages(struct ttm_page_pool *pool, + struct list_head *pages, + int ttm_flags, + enum ttm_caching_state cstate, + unsigned count) { unsigned long irq_flags; struct list_head *p; unsigned i; + int r = 0; spin_lock_irqsave(&pool->lock, irq_flags); ttm_page_pool_fill_locked(pool, ttm_flags, cstate, count, &irq_flags); @@ -672,7 +673,35 @@ static unsigned ttm_page_pool_get_pages(struct ttm_page_pool *pool, count = 0; out: spin_unlock_irqrestore(&pool->lock, irq_flags); - return count; + + /* clear the pages coming from the pool if requested */ + if (ttm_flags & TTM_PAGE_FLAG_ZERO_ALLOC) { + struct page *page; + + list_for_each_entry(page, pages, lru) { + if (PageHighMem(page)) + clear_highpage(page); + else + clear_page(page_address(page)); + } + } + + /* If pool didn't have enough pages allocate new one. */ + if (count) { + gfp_t gfp_flags = pool->gfp_flags; + + /* set zero flag for page allocation if required */ + if (ttm_flags & TTM_PAGE_FLAG_ZERO_ALLOC) + gfp_flags |= __GFP_ZERO; + + /* ttm_alloc_new_pages doesn't reference pool so we can run + * multiple requests in parallel. + **/ + r = ttm_alloc_new_pages(pages, gfp_flags, ttm_flags, cstate, + count); + } + + return r; } /* Put all pages in pages list to correct pool to wait for reuse */ @@ -742,18 +771,18 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); struct list_head plist; struct page *p = NULL; - gfp_t gfp_flags = GFP_USER; unsigned count; int r; - /* set zero flag for page allocation if required */ - if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) - gfp_flags |= __GFP_ZERO; - /* No pool for cached pages */ if (pool == NULL) { + gfp_t gfp_flags = GFP_USER; unsigned i, j; + /* set zero flag for page allocation if required */ + if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) + gfp_flags |= __GFP_ZERO; + if (flags & TTM_PAGE_FLAG_DMA32) gfp_flags |= GFP_DMA32; else @@ -792,44 +821,21 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, return 0; } - /* combine zero flag to pool flags */ - gfp_flags |= pool->gfp_flags; - /* First we take pages from the pool */ INIT_LIST_HEAD(&plist); - npages = ttm_page_pool_get_pages(pool, &plist, flags, cstate, npages); + r = ttm_page_pool_get_pages(pool, &plist, flags, cstate, npages); + count = 0; - list_for_each_entry(p, &plist, lru) { + list_for_each_entry(p, &plist, lru) pages[count++] = p; - } - - /* clear the pages coming from the pool if requested */ - if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { - list_for_each_entry(p, &plist, lru) { - if (PageHighMem(p)) - clear_highpage(p); - else - clear_page(page_address(p)); - } - } - /* If pool didn't have enough pages allocate new one. */ - if (npages > 0) { - /* ttm_alloc_new_pages doesn't reference pool so we can run - * multiple requests in parallel. - **/ - INIT_LIST_HEAD(&plist); - r = ttm_alloc_new_pages(&plist, gfp_flags, flags, cstate, npages); - list_for_each_entry(p, &plist, lru) { - pages[count++] = p; - } - if (r) { - /* If there is any pages in the list put them back to - * the pool. */ - pr_err("Failed to allocate extra pages for large request\n"); - ttm_put_pages(pages, count, flags, cstate); - return r; - } + if (r) { + /* If there is any pages in the list put them back to + * the pool. + */ + pr_err("Failed to allocate extra pages for large request\n"); + ttm_put_pages(pages, count, flags, cstate); + return r; } return 0; -- cgit v1.2.3 From 6ed4e2e673d348df6623012a628a8ab8624e3222 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 5 Oct 2017 14:27:34 +0200 Subject: drm/ttm: add transparent huge page support for wc or uc allocations v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new huge page pool and try to allocate from it when it makes sense. v2: avoid compound pages for now Signed-off-by: Christian König Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 136 ++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 39747326bf3e..b6f16e7ffff3 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -95,7 +95,7 @@ struct ttm_pool_opts { unsigned small; }; -#define NUM_POOLS 4 +#define NUM_POOLS 6 /** * struct ttm_pool_manager - Holds memory pools for fst allocation @@ -122,6 +122,8 @@ struct ttm_pool_manager { struct ttm_page_pool uc_pool; struct ttm_page_pool wc_pool_dma32; struct ttm_page_pool uc_pool_dma32; + struct ttm_page_pool wc_pool_huge; + struct ttm_page_pool uc_pool_huge; } ; }; }; @@ -256,8 +258,8 @@ static int set_pages_array_uc(struct page **pages, int addrinarray) /** * Select the right pool or requested caching state and ttm flags. */ -static struct ttm_page_pool *ttm_get_pool(int flags, - enum ttm_caching_state cstate) +static struct ttm_page_pool *ttm_get_pool(int flags, bool huge, + enum ttm_caching_state cstate) { int pool_index; @@ -269,9 +271,15 @@ static struct ttm_page_pool *ttm_get_pool(int flags, else pool_index = 0x1; - if (flags & TTM_PAGE_FLAG_DMA32) + if (flags & TTM_PAGE_FLAG_DMA32) { + if (huge) + return NULL; pool_index |= 0x2; + } else if (huge) { + pool_index |= 0x4; + } + return &_manager->pools[pool_index]; } @@ -494,12 +502,14 @@ static void ttm_handle_caching_state_failure(struct list_head *pages, * pages returned in pages array. */ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, - int ttm_flags, enum ttm_caching_state cstate, unsigned count) + int ttm_flags, enum ttm_caching_state cstate, + unsigned count, unsigned order) { struct page **caching_array; struct page *p; int r = 0; - unsigned i, cpages; + unsigned i, j, cpages; + unsigned npages = 1 << order; unsigned max_cpages = min(count, (unsigned)(PAGE_SIZE/sizeof(struct page *))); @@ -512,7 +522,7 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, } for (i = 0, cpages = 0; i < count; ++i) { - p = alloc_page(gfp_flags); + p = alloc_pages(gfp_flags, order); if (!p) { pr_err("Unable to get page %u\n", i); @@ -531,14 +541,18 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, goto out; } + list_add(&p->lru, pages); + #ifdef CONFIG_HIGHMEM /* gfp flags of highmem page should never be dma32 so we * we should be fine in such case */ - if (!PageHighMem(p)) + if (PageHighMem(p)) + continue; + #endif - { - caching_array[cpages++] = p; + for (j = 0; j < npages; ++j) { + caching_array[cpages++] = p++; if (cpages == max_cpages) { r = ttm_set_pages_caching(caching_array, @@ -552,8 +566,6 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, cpages = 0; } } - - list_add(&p->lru, pages); } if (cpages) { @@ -573,9 +585,9 @@ out: * Fill the given pool if there aren't enough pages and the requested number of * pages is small. */ -static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, - int ttm_flags, enum ttm_caching_state cstate, unsigned count, - unsigned long *irq_flags) +static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, int ttm_flags, + enum ttm_caching_state cstate, + unsigned count, unsigned long *irq_flags) { struct page *p; int r; @@ -605,7 +617,7 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, INIT_LIST_HEAD(&new_pages); r = ttm_alloc_new_pages(&new_pages, pool->gfp_flags, ttm_flags, - cstate, alloc_size); + cstate, alloc_size, 0); spin_lock_irqsave(&pool->lock, *irq_flags); if (!r) { @@ -635,7 +647,7 @@ static int ttm_page_pool_get_pages(struct ttm_page_pool *pool, struct list_head *pages, int ttm_flags, enum ttm_caching_state cstate, - unsigned count) + unsigned count, unsigned order) { unsigned long irq_flags; struct list_head *p; @@ -643,7 +655,9 @@ static int ttm_page_pool_get_pages(struct ttm_page_pool *pool, int r = 0; spin_lock_irqsave(&pool->lock, irq_flags); - ttm_page_pool_fill_locked(pool, ttm_flags, cstate, count, &irq_flags); + if (!order) + ttm_page_pool_fill_locked(pool, ttm_flags, cstate, count, + &irq_flags); if (count >= pool->npages) { /* take all pages from the pool */ @@ -698,7 +712,7 @@ out: * multiple requests in parallel. **/ r = ttm_alloc_new_pages(pages, gfp_flags, ttm_flags, cstate, - count); + count, order); } return r; @@ -708,8 +722,9 @@ out: static void ttm_put_pages(struct page **pages, unsigned npages, int flags, enum ttm_caching_state cstate) { + struct ttm_page_pool *pool = ttm_get_pool(flags, false, cstate); + struct ttm_page_pool *huge = ttm_get_pool(flags, true, cstate); unsigned long irq_flags; - struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); unsigned i; if (pool == NULL) { @@ -737,8 +752,48 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, return; } + i = 0; +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + if (huge) { + unsigned max_size, n2free; + + spin_lock_irqsave(&huge->lock, irq_flags); + while (i < npages) { + struct page *p = pages[i]; + unsigned j; + + if (!p) + break; + + for (j = 0; j < HPAGE_PMD_NR; ++j) + if (p++ != pages[i + j]) + break; + + if (j != HPAGE_PMD_NR) + break; + + list_add_tail(&pages[i]->lru, &huge->list); + + for (j = 0; j < HPAGE_PMD_NR; ++j) + pages[i++] = NULL; + huge->npages++; + } + + /* Check that we don't go over the pool limit */ + max_size = _manager->options.max_size; + max_size /= HPAGE_PMD_NR; + if (huge->npages > max_size) + n2free = huge->npages - max_size; + else + n2free = 0; + spin_unlock_irqrestore(&huge->lock, irq_flags); + if (n2free) + ttm_page_pool_free(huge, n2free, false); + } +#endif + spin_lock_irqsave(&pool->lock, irq_flags); - for (i = 0; i < npages; i++) { + while (i < npages) { if (pages[i]) { if (page_count(pages[i]) != 1) pr_err("Erroneous page count. Leaking pages.\n"); @@ -746,6 +801,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, pages[i] = NULL; pool->npages++; } + ++i; } /* Check that we don't go over the pool limit */ npages = 0; @@ -768,7 +824,8 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, static int ttm_get_pages(struct page **pages, unsigned npages, int flags, enum ttm_caching_state cstate) { - struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); + struct ttm_page_pool *pool = ttm_get_pool(flags, false, cstate); + struct ttm_page_pool *huge = ttm_get_pool(flags, true, cstate); struct list_head plist; struct page *p = NULL; unsigned count; @@ -821,11 +878,28 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, return 0; } - /* First we take pages from the pool */ + count = 0; + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + if (huge && npages >= HPAGE_PMD_NR) { + INIT_LIST_HEAD(&plist); + ttm_page_pool_get_pages(huge, &plist, flags, cstate, + npages / HPAGE_PMD_NR, + HPAGE_PMD_ORDER); + + list_for_each_entry(p, &plist, lru) { + unsigned j; + + for (j = 0; j < HPAGE_PMD_NR; ++j) + pages[count++] = &p[j]; + } + } +#endif + INIT_LIST_HEAD(&plist); - r = ttm_page_pool_get_pages(pool, &plist, flags, cstate, npages); + r = ttm_page_pool_get_pages(pool, &plist, flags, cstate, + npages - count, 0); - count = 0; list_for_each_entry(p, &plist, lru) pages[count++] = p; @@ -872,6 +946,14 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) ttm_page_pool_init_locked(&_manager->uc_pool_dma32, GFP_USER | GFP_DMA32, "uc dma"); + ttm_page_pool_init_locked(&_manager->wc_pool_huge, + GFP_TRANSHUGE & ~(__GFP_MOVABLE | __GFP_COMP), + "wc huge"); + + ttm_page_pool_init_locked(&_manager->uc_pool_huge, + GFP_TRANSHUGE & ~(__GFP_MOVABLE | __GFP_COMP) + , "uc huge"); + _manager->options.max_size = max_pages; _manager->options.small = SMALL_ALLOCATION; _manager->options.alloc_size = NUM_PAGES_TO_ALLOC; @@ -1041,12 +1123,12 @@ int ttm_page_alloc_debugfs(struct seq_file *m, void *data) seq_printf(m, "No pool allocator running.\n"); return 0; } - seq_printf(m, "%6s %12s %13s %8s\n", + seq_printf(m, "%7s %12s %13s %8s\n", h[0], h[1], h[2], h[3]); for (i = 0; i < NUM_POOLS; ++i) { p = &_manager->pools[i]; - seq_printf(m, "%6s %12ld %13ld %8d\n", + seq_printf(m, "%7s %12ld %13ld %8d\n", p->name, p->nrefills, p->nfrees, p->npages); } -- cgit v1.2.3 From 396bcb41e035df7b98fb150ca950bf213e70ae7b Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 9 Oct 2017 14:45:09 +0200 Subject: drm/amdgpu: partial revert VRAM lost handling v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep blocking the CS, but revert everything else. Mapping BOs and info IOCTL are harmless and can still happen even when VRAM content ist lost. Signed-off-by: Christian König Reviewed-by: Nicolai Hähnle Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 11 ----------- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 5 ----- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++++++---- 3 files changed, 10 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 5de092eab0fa..0c07df72743c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1272,16 +1272,12 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, { union drm_amdgpu_wait_cs *wait = data; struct amdgpu_device *adev = dev->dev_private; - struct amdgpu_fpriv *fpriv = filp->driver_priv; unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout); struct amdgpu_ring *ring = NULL; struct amdgpu_ctx *ctx; struct dma_fence *fence; long r; - if (amdgpu_kms_vram_lost(adev, fpriv)) - return -ENODEV; - ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id); if (ctx == NULL) return -EINVAL; @@ -1350,16 +1346,12 @@ int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct amdgpu_device *adev = dev->dev_private; - struct amdgpu_fpriv *fpriv = filp->driver_priv; union drm_amdgpu_fence_to_handle *info = data; struct dma_fence *fence; struct drm_syncobj *syncobj; struct sync_file *sync_file; int fd, r; - if (amdgpu_kms_vram_lost(adev, fpriv)) - return -ENODEV; - fence = amdgpu_cs_get_fence(adev, filp, &info->in.fence); if (IS_ERR(fence)) return PTR_ERR(fence); @@ -1521,15 +1513,12 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct amdgpu_device *adev = dev->dev_private; - struct amdgpu_fpriv *fpriv = filp->driver_priv; union drm_amdgpu_wait_fences *wait = data; uint32_t fence_count = wait->in.fence_count; struct drm_amdgpu_fence *fences_user; struct drm_amdgpu_fence *fences; int r; - if (amdgpu_kms_vram_lost(adev, fpriv)) - return -ENODEV; /* Get the fences from userspace */ fences = kmalloc_array(fence_count, sizeof(struct drm_amdgpu_fence), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 21e99366cab3..fb72edc4c026 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -579,11 +579,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, args->operation); return -EINVAL; } - if ((args->operation == AMDGPU_VA_OP_MAP) || - (args->operation == AMDGPU_VA_OP_REPLACE)) { - if (amdgpu_kms_vram_lost(adev, fpriv)) - return -ENODEV; - } INIT_LIST_HEAD(&list); INIT_LIST_HEAD(&duplicates); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 82e8d43b235a..f759836d10ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -270,7 +270,6 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct amdgpu_device *adev = dev->dev_private; - struct amdgpu_fpriv *fpriv = filp->driver_priv; struct drm_amdgpu_info *info = data; struct amdgpu_mode_info *minfo = &adev->mode_info; void __user *out = (void __user *)(uintptr_t)info->return_pointer; @@ -283,8 +282,6 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file if (!info->return_size || !info->return_pointer) return -EINVAL; - if (amdgpu_kms_vram_lost(adev, fpriv)) - return -ENODEV; switch (info->query) { case AMDGPU_INFO_ACCEL_WORKING: @@ -792,10 +789,19 @@ void amdgpu_driver_lastclose_kms(struct drm_device *dev) vga_switcheroo_process_delayed_switch(); } +/** + * amdgpu_kms_vram_lost - check if VRAM was lost for this client + * + * @adev: amdgpu device + * @fpriv: client private + * + * Check if all CS is blocked for the client because of lost VRAM + */ bool amdgpu_kms_vram_lost(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv) { - return fpriv->vram_lost_counter != atomic_read(&adev->vram_lost_counter); + return fpriv->vram_lost_counter != + atomic_read(&adev->vram_lost_counter); } /** -- cgit v1.2.3 From 14e47f93c5cc4a1237dbacc137e174706093b69c Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 9 Oct 2017 15:04:41 +0200 Subject: drm/amdgpu: keep copy of VRAM lost counter in job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of reading the current counter from fpriv. Signed-off-by: Christian König Reviewed-by: Nicolai Hähnle Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 13 +++++++------ 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 76033e2cdba8..aa70f8c045b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1125,6 +1125,7 @@ struct amdgpu_job { uint32_t gds_base, gds_size; uint32_t gws_base, gws_size; uint32_t oa_base, oa_size; + uint32_t vram_lost_counter; /* user fence handling */ uint64_t uf_addr; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 0c07df72743c..9daa7cac0ffb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -172,6 +172,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) if (ret) goto free_all_kdata; + p->job->vram_lost_counter = fpriv->vram_lost_counter; + if (p->uf_entry.robj) p->job->uf_addr = uf_offset; kfree(chunk_array); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 83d13431cbdd..4f2b5acc8743 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -61,6 +61,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->vm = vm; (*job)->ibs = (void *)&(*job)[1]; (*job)->num_ibs = num_ibs; + (*job)->vram_lost_counter = atomic_read(&adev->vram_lost_counter); amdgpu_sync_create(&(*job)->sync); amdgpu_sync_create(&(*job)->dep_sync); @@ -180,8 +181,8 @@ static struct dma_fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) { struct dma_fence *fence = NULL; + struct amdgpu_device *adev; struct amdgpu_job *job; - struct amdgpu_fpriv *fpriv = NULL; int r; if (!sched_job) { @@ -189,17 +190,17 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) return NULL; } job = to_amdgpu_job(sched_job); + adev = job->adev; BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL)); trace_amdgpu_sched_run_job(job); - if (job->vm) - fpriv = container_of(job->vm, struct amdgpu_fpriv, vm); /* skip ib schedule when vram is lost */ - if (fpriv && amdgpu_kms_vram_lost(job->adev, fpriv)) + if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter)) { DRM_ERROR("Skip scheduling IBs!\n"); - else { - r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, &fence); + } else { + r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, + &fence); if (r) DRM_ERROR("Error scheduling IBs (%d)\n", r); } -- cgit v1.2.3 From e55f2b646df3318e24f12b8388ab6e5cccb3e92d Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 9 Oct 2017 15:18:43 +0200 Subject: drm/amdgpu: move the VRAM lost counter per context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of per device track the VRAM lost per context and return ECANCELED instead of ENODEV. Signed-off-by: Christian König Reviewed-by: Nicolai Hähnle Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 ++---- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 9 +++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 16 ---------------- 4 files changed, 8 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index aa70f8c045b1..67b864436be1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -732,10 +732,11 @@ struct amdgpu_ctx { struct amdgpu_device *adev; struct amdgpu_queue_mgr queue_mgr; unsigned reset_counter; + uint32_t vram_lost_counter; spinlock_t ring_lock; struct dma_fence **fences; struct amdgpu_ctx_ring rings[AMDGPU_MAX_RINGS]; - bool preamble_presented; + bool preamble_presented; enum amd_sched_priority init_priority; enum amd_sched_priority override_priority; struct mutex lock; @@ -778,7 +779,6 @@ struct amdgpu_fpriv { struct mutex bo_list_lock; struct idr bo_list_handles; struct amdgpu_ctx_mgr ctx_mgr; - u32 vram_lost_counter; }; /* @@ -1860,8 +1860,6 @@ static inline bool amdgpu_has_atpx(void) { return false; } extern const struct drm_ioctl_desc amdgpu_ioctls_kms[]; extern const int amdgpu_max_kms_ioctl; -bool amdgpu_kms_vram_lost(struct amdgpu_device *adev, - struct amdgpu_fpriv *fpriv); int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags); void amdgpu_driver_unload_kms(struct drm_device *dev); void amdgpu_driver_lastclose_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 9daa7cac0ffb..b355189533d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -172,7 +172,11 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) if (ret) goto free_all_kdata; - p->job->vram_lost_counter = fpriv->vram_lost_counter; + p->job->vram_lost_counter = atomic_read(&p->adev->vram_lost_counter); + if (p->ctx->vram_lost_counter != p->job->vram_lost_counter) { + ret = -ECANCELED; + goto free_all_kdata; + } if (p->uf_entry.robj) p->job->uf_addr = uf_offset; @@ -1205,7 +1209,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct amdgpu_device *adev = dev->dev_private; - struct amdgpu_fpriv *fpriv = filp->driver_priv; union drm_amdgpu_cs *cs = data; struct amdgpu_cs_parser parser = {}; bool reserved_buffers = false; @@ -1213,8 +1216,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (!adev->accel_working) return -EBUSY; - if (amdgpu_kms_vram_lost(adev, fpriv)) - return -ENODEV; parser.adev = adev; parser.filp = filp; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 4309820658c4..c184468e2b2b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -75,6 +75,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, } ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); + ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter); ctx->init_priority = priority; ctx->override_priority = AMD_SCHED_PRIORITY_UNSET; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index f759836d10ef..ff1a416a66c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -789,21 +789,6 @@ void amdgpu_driver_lastclose_kms(struct drm_device *dev) vga_switcheroo_process_delayed_switch(); } -/** - * amdgpu_kms_vram_lost - check if VRAM was lost for this client - * - * @adev: amdgpu device - * @fpriv: client private - * - * Check if all CS is blocked for the client because of lost VRAM - */ -bool amdgpu_kms_vram_lost(struct amdgpu_device *adev, - struct amdgpu_fpriv *fpriv) -{ - return fpriv->vram_lost_counter != - atomic_read(&adev->vram_lost_counter); -} - /** * amdgpu_driver_open_kms - drm callback for open * @@ -860,7 +845,6 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) amdgpu_ctx_mgr_init(&fpriv->ctx_mgr); - fpriv->vram_lost_counter = atomic_read(&adev->vram_lost_counter); file_priv->driver_priv = fpriv; out_suspend: -- cgit v1.2.3 From 7a0a48ddf63bc9944b9690c6fa043ea4305f7f79 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 9 Oct 2017 15:51:10 +0200 Subject: drm/amdgpu: set -ECANCELED when dropping jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And return from the wait functions the fence error code. Signed-off-by: Christian König Reviewed-by: Nicolai Hähnle Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 7 ++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index b355189533d2..2ae5d523ca10 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1298,6 +1298,8 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, r = PTR_ERR(fence); else if (fence) { r = dma_fence_wait_timeout(fence, true, timeout); + if (r > 0 && fence->error) + r = fence->error; dma_fence_put(fence); } else r = 1; @@ -1435,6 +1437,9 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev, if (r == 0) break; + + if (fence->error) + return fence->error; } memset(wait, 0, sizeof(*wait)); @@ -1495,7 +1500,7 @@ out: wait->out.status = (r > 0); wait->out.first_signaled = first; /* set return value 0 to indicate success */ - r = 0; + r = array[first]->error; err_free_fence_array: for (i = 0; i < fence_count; i++) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 4f2b5acc8743..a8357885776e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -197,6 +197,7 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) trace_amdgpu_sched_run_job(job); /* skip ib schedule when vram is lost */ if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter)) { + dma_fence_set_error(&job->base.s_fence->finished, -ECANCELED); DRM_ERROR("Skip scheduling IBs!\n"); } else { r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, -- cgit v1.2.3 From 1f7251b73e08395dbf03602a57ca67cf7da7f9db Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 9 Oct 2017 17:53:06 +0200 Subject: drm/amdgpu: add VRAM lost query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows userspace to figure out if VRAM was lost. Signed-off-by: Christian König Reviewed-by: Nicolai Hähnle Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 3 +++ include/uapi/drm/amdgpu_drm.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ff1a416a66c9..6f0b26dae3b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -763,6 +763,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file } return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; } + case AMDGPU_INFO_VRAM_LOST_COUNTER: + ui32 = atomic_read(&adev->vram_lost_counter); + return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; default: DRM_DEBUG_KMS("Invalid request %d\n", info->query); return -EINVAL; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index d0a3ea69eab6..ff0181829f3d 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -657,6 +657,7 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_SENSOR_VDDGFX 0x7 /* Number of VRAM page faults on CPU access. */ #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E +#define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff -- cgit v1.2.3 From 7d0a42823ba5bdc11b4933749b147b8a6a6caae5 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Thu, 12 Oct 2017 07:25:08 -0400 Subject: drm/ttm: Fix unused variables with huge page support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tom St Denis Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index b6f16e7ffff3..95022473704b 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -723,7 +723,9 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, enum ttm_caching_state cstate) { struct ttm_page_pool *pool = ttm_get_pool(flags, false, cstate); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE struct ttm_page_pool *huge = ttm_get_pool(flags, true, cstate); +#endif unsigned long irq_flags; unsigned i; @@ -825,7 +827,9 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, enum ttm_caching_state cstate) { struct ttm_page_pool *pool = ttm_get_pool(flags, false, cstate); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE struct ttm_page_pool *huge = ttm_get_pool(flags, true, cstate); +#endif struct list_head plist; struct page *p = NULL; unsigned count; @@ -834,7 +838,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, /* No pool for cached pages */ if (pool == NULL) { gfp_t gfp_flags = GFP_USER; - unsigned i, j; + unsigned i; +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + unsigned j; +#endif /* set zero flag for page allocation if required */ if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) -- cgit v1.2.3 From 26eedf6daec4e7937c8f0f1dde5e9b8e3dcebfd3 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Wed, 11 Oct 2017 17:02:02 -0400 Subject: drm/amdgpu: Fix extra call to amdgpu_ctx_put. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In amdgpu_cs_parser_init() in case of error handling amdgpu_ctx_put() is called without setting p->ctx to NULL after that, later amdgpu_cs_parser_fini() also calls amdgpu_ctx_put() again and mess up the reference count. Signed-off-by: Andrey Grodzovsky Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 2ae5d523ca10..dfd37785563f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -97,7 +97,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) if (copy_from_user(chunk_array, chunk_array_user, sizeof(uint64_t)*cs->in.num_chunks)) { ret = -EFAULT; - goto put_ctx; + goto free_chunk; } p->nchunks = cs->in.num_chunks; @@ -105,7 +105,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) GFP_KERNEL); if (!p->chunks) { ret = -ENOMEM; - goto put_ctx; + goto free_chunk; } for (i = 0; i < p->nchunks; i++) { @@ -191,8 +191,6 @@ free_partial_kdata: kfree(p->chunks); p->chunks = NULL; p->nchunks = 0; -put_ctx: - amdgpu_ctx_put(p->ctx); free_chunk: kfree(chunk_array); -- cgit v1.2.3 From 1eca5a530dc3ac0a2fadd21da1c9e6c729a4a2a1 Mon Sep 17 00:00:00 2001 From: Harish Kasiviswanathan Date: Tue, 3 Oct 2017 15:41:56 -0400 Subject: drm/amdgpu: Refactor amdgpu_move_blit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add more generic function amdgpu_copy_ttm_mem_to_mem() that supports arbitrary copy size, offsets and two BOs (source & dest.). This is useful for KFD Cross Memory Attach feature where data needs to be copied from BOs from different processes v2: Add struct amdgpu_copy_mem and changed amdgpu_copy_ttm_mem_to_mem() function parameters to use the struct v3: Minor function name change Signed-off-by: Harish Kasiviswanathan Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 169 +++++++++++++++++++++++--------- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 12 +++ 2 files changed, 132 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index a2282bacf960..382c0ae0561e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -290,97 +290,168 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, return addr; } -static int amdgpu_move_blit(struct ttm_buffer_object *bo, - bool evict, bool no_wait_gpu, - struct ttm_mem_reg *new_mem, - struct ttm_mem_reg *old_mem) +/** + * amdgpu_ttm_copy_mem_to_mem - Helper function for copy + * + * The function copies @size bytes from {src->mem + src->offset} to + * {dst->mem + dst->offset}. src->bo and dst->bo could be same BO for a + * move and different for a BO to BO copy. + * + * @f: Returns the last fence if multiple jobs are submitted. + */ +int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, + struct amdgpu_copy_mem *src, + struct amdgpu_copy_mem *dst, + uint64_t size, + struct reservation_object *resv, + struct dma_fence **f) { - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; - - struct drm_mm_node *old_mm, *new_mm; - uint64_t old_start, old_size, new_start, new_size; - unsigned long num_pages; + struct drm_mm_node *src_mm, *dst_mm; + uint64_t src_node_start, dst_node_start, src_node_size, + dst_node_size, src_page_offset, dst_page_offset; struct dma_fence *fence = NULL; - int r; - - BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0); + int r = 0; + const uint64_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE * + AMDGPU_GPU_PAGE_SIZE); if (!ring->ready) { DRM_ERROR("Trying to move memory with ring turned off.\n"); return -EINVAL; } - old_mm = old_mem->mm_node; - old_size = old_mm->size; - old_start = amdgpu_mm_node_addr(bo, old_mm, old_mem); + src_mm = src->mem->mm_node; + while (src->offset >= (src_mm->size << PAGE_SHIFT)) { + src->offset -= (src_mm->size << PAGE_SHIFT); + ++src_mm; + } + src_node_start = amdgpu_mm_node_addr(src->bo, src_mm, src->mem) + + src->offset; + src_node_size = (src_mm->size << PAGE_SHIFT) - src->offset; + src_page_offset = src_node_start & (PAGE_SIZE - 1); - new_mm = new_mem->mm_node; - new_size = new_mm->size; - new_start = amdgpu_mm_node_addr(bo, new_mm, new_mem); + dst_mm = dst->mem->mm_node; + while (dst->offset >= (dst_mm->size << PAGE_SHIFT)) { + dst->offset -= (dst_mm->size << PAGE_SHIFT); + ++dst_mm; + } + dst_node_start = amdgpu_mm_node_addr(dst->bo, dst_mm, dst->mem) + + dst->offset; + dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst->offset; + dst_page_offset = dst_node_start & (PAGE_SIZE - 1); - num_pages = new_mem->num_pages; mutex_lock(&adev->mman.gtt_window_lock); - while (num_pages) { - unsigned long cur_pages = min(min(old_size, new_size), - (u64)AMDGPU_GTT_MAX_TRANSFER_SIZE); - uint64_t from = old_start, to = new_start; + + while (size) { + unsigned long cur_size; + uint64_t from = src_node_start, to = dst_node_start; struct dma_fence *next; - if (old_mem->mem_type == TTM_PL_TT && - !amdgpu_gtt_mgr_is_allocated(old_mem)) { - r = amdgpu_map_buffer(bo, old_mem, cur_pages, - old_start, 0, ring, &from); + /* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst + * begins at an offset, then adjust the size accordingly + */ + cur_size = min3(min(src_node_size, dst_node_size), size, + GTT_MAX_BYTES); + if (cur_size + src_page_offset > GTT_MAX_BYTES || + cur_size + dst_page_offset > GTT_MAX_BYTES) + cur_size -= max(src_page_offset, dst_page_offset); + + /* Map only what needs to be accessed. Map src to window 0 and + * dst to window 1 + */ + if (src->mem->mem_type == TTM_PL_TT && + !amdgpu_gtt_mgr_is_allocated(src->mem)) { + r = amdgpu_map_buffer(src->bo, src->mem, + PFN_UP(cur_size + src_page_offset), + src_node_start, 0, ring, + &from); if (r) goto error; + /* Adjust the offset because amdgpu_map_buffer returns + * start of mapped page + */ + from += src_page_offset; } - if (new_mem->mem_type == TTM_PL_TT && - !amdgpu_gtt_mgr_is_allocated(new_mem)) { - r = amdgpu_map_buffer(bo, new_mem, cur_pages, - new_start, 1, ring, &to); + if (dst->mem->mem_type == TTM_PL_TT && + !amdgpu_gtt_mgr_is_allocated(dst->mem)) { + r = amdgpu_map_buffer(dst->bo, dst->mem, + PFN_UP(cur_size + dst_page_offset), + dst_node_start, 1, ring, + &to); if (r) goto error; + to += dst_page_offset; } - r = amdgpu_copy_buffer(ring, from, to, - cur_pages * PAGE_SIZE, - bo->resv, &next, false, true); + r = amdgpu_copy_buffer(ring, from, to, cur_size, + resv, &next, false, true); if (r) goto error; dma_fence_put(fence); fence = next; - num_pages -= cur_pages; - if (!num_pages) + size -= cur_size; + if (!size) break; - old_size -= cur_pages; - if (!old_size) { - old_start = amdgpu_mm_node_addr(bo, ++old_mm, old_mem); - old_size = old_mm->size; + src_node_size -= cur_size; + if (!src_node_size) { + src_node_start = amdgpu_mm_node_addr(src->bo, ++src_mm, + src->mem); + src_node_size = (src_mm->size << PAGE_SHIFT); } else { - old_start += cur_pages * PAGE_SIZE; + src_node_start += cur_size; + src_page_offset = src_node_start & (PAGE_SIZE - 1); } - - new_size -= cur_pages; - if (!new_size) { - new_start = amdgpu_mm_node_addr(bo, ++new_mm, new_mem); - new_size = new_mm->size; + dst_node_size -= cur_size; + if (!dst_node_size) { + dst_node_start = amdgpu_mm_node_addr(dst->bo, ++dst_mm, + dst->mem); + dst_node_size = (dst_mm->size << PAGE_SHIFT); } else { - new_start += cur_pages * PAGE_SIZE; + dst_node_start += cur_size; + dst_page_offset = dst_node_start & (PAGE_SIZE - 1); } } +error: mutex_unlock(&adev->mman.gtt_window_lock); + if (f) + *f = dma_fence_get(fence); + dma_fence_put(fence); + return r; +} + + +static int amdgpu_move_blit(struct ttm_buffer_object *bo, + bool evict, bool no_wait_gpu, + struct ttm_mem_reg *new_mem, + struct ttm_mem_reg *old_mem) +{ + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); + struct amdgpu_copy_mem src, dst; + struct dma_fence *fence = NULL; + int r; + + src.bo = bo; + dst.bo = bo; + src.mem = old_mem; + dst.mem = new_mem; + src.offset = 0; + dst.offset = 0; + + r = amdgpu_ttm_copy_mem_to_mem(adev, &src, &dst, + new_mem->num_pages << PAGE_SHIFT, + bo->resv, &fence); + if (r) + goto error; r = ttm_bo_pipeline_move(bo, fence, evict, new_mem); dma_fence_put(fence); return r; error: - mutex_unlock(&adev->mman.gtt_window_lock); - if (fence) dma_fence_wait(fence, false); dma_fence_put(fence); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 7abae6867339..abd4084982a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -58,6 +58,12 @@ struct amdgpu_mman { struct amd_sched_entity entity; }; +struct amdgpu_copy_mem { + struct ttm_buffer_object *bo; + struct ttm_mem_reg *mem; + unsigned long offset; +}; + extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; @@ -72,6 +78,12 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, struct reservation_object *resv, struct dma_fence **fence, bool direct_submit, bool vm_needs_flush); +int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, + struct amdgpu_copy_mem *src, + struct amdgpu_copy_mem *dst, + uint64_t size, + struct reservation_object *resv, + struct dma_fence **f); int amdgpu_fill_buffer(struct amdgpu_bo *bo, uint64_t src_data, struct reservation_object *resv, -- cgit v1.2.3 From e1d515052f9075eb1b791b21467d79db3529db83 Mon Sep 17 00:00:00 2001 From: Harish Kasiviswanathan Date: Fri, 6 Oct 2017 17:36:35 -0400 Subject: drm/amdgpu: Add amdgpu_find_mm_node() Replace some commonly repeated code with a function. v2: Use amdgpu_find_mm_node() in amdgpu_ttm_io_mem_pfn() Signed-off-by: Harish Kasiviswanathan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 49 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 382c0ae0561e..51eacefadea1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -291,7 +291,24 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, } /** - * amdgpu_ttm_copy_mem_to_mem - Helper function for copy + * amdgpu_find_mm_node - Helper function finds the drm_mm_node + * corresponding to @offset. It also modifies the offset to be + * within the drm_mm_node returned + */ +static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, + unsigned long *offset) +{ + struct drm_mm_node *mm_node = mem->mm_node; + + while (*offset >= (mm_node->size << PAGE_SHIFT)) { + *offset -= (mm_node->size << PAGE_SHIFT); + ++mm_node; + } + return mm_node; +} + +/** + * amdgpu_copy_ttm_mem_to_mem - Helper function for copy * * The function copies @size bytes from {src->mem + src->offset} to * {dst->mem + dst->offset}. src->bo and dst->bo could be same BO for a @@ -320,21 +337,13 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, return -EINVAL; } - src_mm = src->mem->mm_node; - while (src->offset >= (src_mm->size << PAGE_SHIFT)) { - src->offset -= (src_mm->size << PAGE_SHIFT); - ++src_mm; - } + src_mm = amdgpu_find_mm_node(src->mem, &src->offset); src_node_start = amdgpu_mm_node_addr(src->bo, src_mm, src->mem) + src->offset; src_node_size = (src_mm->size << PAGE_SHIFT) - src->offset; src_page_offset = src_node_start & (PAGE_SIZE - 1); - dst_mm = dst->mem->mm_node; - while (dst->offset >= (dst_mm->size << PAGE_SHIFT)) { - dst->offset -= (dst_mm->size << PAGE_SHIFT); - ++dst_mm; - } + dst_mm = amdgpu_find_mm_node(dst->mem, &dst->offset); dst_node_start = amdgpu_mm_node_addr(dst->bo, dst_mm, dst->mem) + dst->offset; dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst->offset; @@ -654,13 +663,12 @@ static void amdgpu_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_re static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo, unsigned long page_offset) { - struct drm_mm_node *mm = bo->mem.mm_node; - uint64_t size = mm->size; - uint64_t offset = page_offset; + struct drm_mm_node *mm; + unsigned long offset = (page_offset << PAGE_SHIFT); - page_offset = do_div(offset, size); - mm += offset; - return (bo->mem.bus.base >> PAGE_SHIFT) + mm->start + page_offset; + mm = amdgpu_find_mm_node(&bo->mem, &offset); + return (bo->mem.bus.base >> PAGE_SHIFT) + mm->start + + (offset >> PAGE_SHIFT); } /* @@ -1216,7 +1224,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, { struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); - struct drm_mm_node *nodes = abo->tbo.mem.mm_node; + struct drm_mm_node *nodes; uint32_t value = 0; int ret = 0; uint64_t pos; @@ -1225,10 +1233,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, if (bo->mem.mem_type != TTM_PL_VRAM) return -EIO; - while (offset >= (nodes->size << PAGE_SHIFT)) { - offset -= nodes->size << PAGE_SHIFT; - ++nodes; - } + nodes = amdgpu_find_mm_node(&abo->tbo.mem, &offset); pos = (nodes->start << PAGE_SHIFT) + offset; while (len && pos < adev->mc.mc_vram_size) { -- cgit v1.2.3 From 7fd5e36caec1598c49ef97d3e53cdd89c1da2770 Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 13 Oct 2017 10:58:15 +0200 Subject: drm/amd/sched: fix job tear down order v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the trace before we signal the scheduler fence and drop the scheduler fence reference directly before we free the job. v2: keep extra s_fence reference Signed-off-by: Christian König Reviewed-by: Liu, Monk Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 59f1325d975c..e4d3b4ec4e92 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -406,6 +406,7 @@ static void amd_sched_job_finish(struct work_struct *work) schedule_delayed_work(&next->work_tdr, sched->timeout); } spin_unlock(&sched->job_list_lock); + dma_fence_put(&s_job->s_fence->finished); sched->ops->free_job(s_job); } @@ -586,6 +587,7 @@ static void amd_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb) container_of(cb, struct amd_sched_fence, cb); struct amd_gpu_scheduler *sched = s_fence->sched; + dma_fence_get(&s_fence->finished); atomic_dec(&sched->hw_rq_count); amd_sched_fence_finished(s_fence); @@ -638,9 +640,6 @@ static int amd_sched_main(void *param) fence = sched->ops->run_job(sched_job); amd_sched_fence_scheduled(s_fence); - /* amd_sched_process_job drops the job's reference of the fence. */ - sched_job->s_fence = NULL; - if (fence) { s_fence->parent = dma_fence_get(fence); r = dma_fence_add_callback(fence, &s_fence->cb, -- cgit v1.2.3 From c5795c555bbaca51192ffc6164bb85845ecdf717 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 12 Oct 2017 12:16:33 +0200 Subject: drm/amdgpu: minor CS optimization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We only need to loop over all IBs for old UVD/VCE command stream patching. Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 37 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index dfd37785563f..52dd78ee8fd0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -853,36 +853,37 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_ring *ring = p->job->ring; - int i, j, r; - - for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { - - struct amdgpu_cs_chunk *chunk; - struct amdgpu_ib *ib; - struct drm_amdgpu_cs_chunk_ib *chunk_ib; - - chunk = &p->chunks[i]; - ib = &p->job->ibs[j]; - chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; + int r; - if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) - continue; + /* Only for UVD/VCE VM emulation */ + if (p->job->ring->funcs->parse_cs) { + unsigned i, j; - if (p->job->ring->funcs->parse_cs) { + for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { + struct drm_amdgpu_cs_chunk_ib *chunk_ib; struct amdgpu_bo_va_mapping *m; struct amdgpu_bo *aobj = NULL; + struct amdgpu_cs_chunk *chunk; + struct amdgpu_ib *ib; uint64_t offset; uint8_t *kptr; + chunk = &p->chunks[i]; + ib = &p->job->ibs[j]; + chunk_ib = chunk->kdata; + + if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) + continue; + r = amdgpu_cs_find_mapping(p, chunk_ib->va_start, - &aobj, &m); + &aobj, &m); if (r) { DRM_ERROR("IB va_start is invalid\n"); return r; } if ((chunk_ib->va_start + chunk_ib->ib_bytes) > - (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { + (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { DRM_ERROR("IB va_start+ib_bytes is invalid\n"); return -EINVAL; } @@ -899,12 +900,12 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); amdgpu_bo_kunmap(aobj); - /* Only for UVD/VCE VM emulation */ r = amdgpu_ring_parse_cs(ring, p, j); if (r) return r; + + j++; } - j++; } if (p->job->vm) { -- cgit v1.2.3 From c057c11403e461185a24d7f5dc2fbd059bbd1502 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 12 Oct 2017 16:26:34 -0400 Subject: drm/amdgpu: bump version for vram lost counter query (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: vram -> VRAM in comment Reviewed-by: Michel Dänzer Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index b9a32585f58d..dd2f060d62a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -72,9 +72,10 @@ * - 3.20.0 - Add support for local BOs * - 3.21.0 - Add DRM_AMDGPU_FENCE_TO_HANDLE ioctl * - 3.22.0 - Add DRM_AMDGPU_SCHED ioctl + * - 3.23.0 - Add query for VRAM lost counter */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 22 +#define KMS_DRIVER_MINOR 23 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; -- cgit v1.2.3 From 5c42c64f7d54ba560b0b001e4e73e4a1aeed1355 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 12 Oct 2017 19:28:42 +0200 Subject: drm/ttm: fix the fix for huge compound pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't use compound pages at the moment. Take this into account when freeing them. Signed-off-by: Christian König Reviewed-and-Tested-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 95022473704b..4d688c8d7853 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -733,22 +733,33 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, /* No pool for this memory type so free the pages */ i = 0; while (i < npages) { - unsigned order; +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + struct page *p = pages[i]; +#endif + unsigned order = 0, j; if (!pages[i]) { ++i; continue; } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + for (j = 0; j < HPAGE_PMD_NR; ++j) + if (p++ != pages[i + j]) + break; + + if (j == HPAGE_PMD_NR) + order = HPAGE_PMD_ORDER; +#endif + if (page_count(pages[i]) != 1) pr_err("Erroneous page count. Leaking pages.\n"); - order = compound_order(pages[i]); __free_pages(pages[i], order); - order = 1 << order; - while (order) { + j = 1 << order; + while (j) { pages[i++] = NULL; - --order; + --j; } } return; -- cgit v1.2.3 From 2642cf110d08a403f585a051e4cbf45a90b3adea Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 13 Oct 2017 17:24:31 +0200 Subject: drm/amdgpu: reserve root PD while releasing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise somebody could try to evict it at the same time and try to use half torn down structures. Signed-off-by: Christian König Reviewed-and-Tested-by: Michel Dänzer Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index c559d76ff695..010d14195a5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2759,8 +2759,9 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) { struct amdgpu_bo_va_mapping *mapping, *tmp; bool prt_fini_needed = !!adev->gart.gart_funcs->set_prt; + struct amdgpu_bo *root; u64 fault; - int i; + int i, r; /* Clear pending page faults from IH when the VM is destroyed */ while (kfifo_get(&vm->faults, &fault)) @@ -2795,7 +2796,15 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) amdgpu_vm_free_mapping(adev, vm, mapping, NULL); } - amdgpu_vm_free_levels(&vm->root); + root = amdgpu_bo_ref(vm->root.base.bo); + r = amdgpu_bo_reserve(root, true); + if (r) { + dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); + } else { + amdgpu_vm_free_levels(&vm->root); + amdgpu_bo_unreserve(root); + } + amdgpu_bo_unref(&root); dma_fence_put(vm->last_update); for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) amdgpu_vm_free_reserved_vmid(adev, vm, i); -- cgit v1.2.3 From c1b24a1405ed8720f5837fc77fbc52fd008cbb42 Mon Sep 17 00:00:00 2001 From: Jérémy Lefaure Date: Sun, 15 Oct 2017 22:29:23 -0400 Subject: drm/amdgpu: use ARRAY_SIZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the ARRAY_SIZE macro improves the readability of the code. Found with Coccinelle with the following semantic patch: @r depends on (org || report)@ type T; T[] E; position p; @@ ( (sizeof(E)@p /sizeof(*E)) | (sizeof(E)@p /sizeof(E[...])) | (sizeof(E)@p /sizeof(T)) ) Reviewed-by: Christian König Reviewed-by: Thierry Reding Signed-off-by: Jérémy Lefaure Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 9 +++++---- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 51896b7353b6..b8002ac3e536 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -20,6 +20,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * */ +#include #include #include #include "amdgpu.h" @@ -3952,10 +3953,10 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev) adev->gfx.rlc.reg_list_format_size_bytes >> 2, unique_indices, &indices_count, - sizeof(unique_indices) / sizeof(int), + ARRAY_SIZE(unique_indices), indirect_start_offsets, &offset_count, - sizeof(indirect_start_offsets)/sizeof(int)); + ARRAY_SIZE(indirect_start_offsets)); /* save and restore list */ WREG32_FIELD(RLC_SRM_CNTL, AUTO_INCR_ADDR, 1); @@ -3977,14 +3978,14 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev) /* starting offsets starts */ WREG32(mmRLC_GPM_SCRATCH_ADDR, adev->gfx.rlc.starting_offsets_start); - for (i = 0; i < sizeof(indirect_start_offsets)/sizeof(int); i++) + for (i = 0; i < ARRAY_SIZE(indirect_start_offsets); i++) WREG32(mmRLC_GPM_SCRATCH_DATA, indirect_start_offsets[i]); /* unique indices */ temp = mmRLC_SRM_INDEX_CNTL_ADDR_0; data = mmRLC_SRM_INDEX_CNTL_DATA_0; - for (i = 0; i < sizeof(unique_indices) / sizeof(int); i++) { + for (i = 0; i < ARRAY_SIZE(unique_indices); i++) { if (unique_indices[i] != 0) { WREG32(temp + i, unique_indices[i] & 0x3FFFF); WREG32(data + i, unique_indices[i] >> 20); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 99a5b3b92e8e..7f15bb2c5233 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -20,6 +20,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * */ +#include #include #include #include "amdgpu.h" @@ -1730,10 +1731,10 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev) adev->gfx.rlc.reg_list_format_size_bytes >> 2, unique_indirect_regs, &unique_indirect_reg_count, - sizeof(unique_indirect_regs)/sizeof(int), + ARRAY_SIZE(unique_indirect_regs), indirect_start_offsets, &indirect_start_offsets_count, - sizeof(indirect_start_offsets)/sizeof(int)); + ARRAY_SIZE(indirect_start_offsets)); /* enable auto inc in case it is disabled */ tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL)); @@ -1770,12 +1771,12 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev) /* write the starting offsets to RLC scratch ram */ WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_ADDR), adev->gfx.rlc.starting_offsets_start); - for (i = 0; i < sizeof(indirect_start_offsets)/sizeof(int); i++) + for (i = 0; i < ARRAY_SIZE(indirect_start_offsets); i++) WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_DATA), indirect_start_offsets[i]); /* load unique indirect regs*/ - for (i = 0; i < sizeof(unique_indirect_regs)/sizeof(int); i++) { + for (i = 0; i < ARRAY_SIZE(unique_indirect_regs); i++) { WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_ADDR_0) + i, unique_indirect_regs[i] & 0x3FFFF); WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_DATA_0) + i, -- cgit v1.2.3 From 995e27fbee054cd9eb153ba090ff514379bf5303 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 16 Oct 2017 13:23:55 -0400 Subject: drm/amd/powerplay: Tidy up cz_start_dpm() Remove unused variables. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 96da4fc9c998..75af4d94f902 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -961,18 +961,13 @@ static void cz_clear_voting_clients(struct pp_hwmgr *hwmgr) static int cz_start_dpm(struct pp_hwmgr *hwmgr) { - int ret = 0; struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend); - unsigned long dpm_features = 0; cz_hwmgr->dpm_flags |= DPMFlags_SCLK_Enabled; - dpm_features |= SCLK_DPM_MASK; - ret = smum_send_msg_to_smc_with_parameter(hwmgr, + return smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnableAllSmuFeatures, - dpm_features); - - return ret; + SCLK_DPM_MASK); } static int cz_stop_dpm(struct pp_hwmgr *hwmgr) -- cgit v1.2.3 From 610dd60bf71c441907d74cd109d6405d5a336c08 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 16 Oct 2017 13:25:42 -0400 Subject: drm/amd/powerplay: Tidy up cz_dpm_powerdown_uvd() Use PP_CAP and tidy up indentation. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 75af4d94f902..c2afc0aaa2cb 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1274,10 +1274,8 @@ static int cz_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, int cz_dpm_powerdown_uvd(struct pp_hwmgr *hwmgr) { - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_UVDPowerGating)) - return smum_send_msg_to_smc(hwmgr, - PPSMC_MSG_UVDPowerOFF); + if (PP_CAP(PHM_PlatformCaps_UVDPowerGating)) + return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UVDPowerOFF); return 0; } -- cgit v1.2.3 From 5936470456c51a2d32d8e8ee756dc9a8c2eb1be9 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 16 Oct 2017 13:28:24 -0400 Subject: drm/amd/powerplay: Tidy up cz_dpm_powerup_uvd() Use PP_CAP and simplify enable/disable logic. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index c2afc0aaa2cb..c57f7f3b54ec 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1281,18 +1281,11 @@ int cz_dpm_powerdown_uvd(struct pp_hwmgr *hwmgr) int cz_dpm_powerup_uvd(struct pp_hwmgr *hwmgr) { - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_UVDPowerGating)) { - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_UVDDynamicPowerGating)) { - return smum_send_msg_to_smc_with_parameter( - hwmgr, - PPSMC_MSG_UVDPowerON, 1); - } else { - return smum_send_msg_to_smc_with_parameter( - hwmgr, - PPSMC_MSG_UVDPowerON, 0); - } + if (PP_CAP(PHM_PlatformCaps_UVDPowerGating)) { + return smum_send_msg_to_smc_with_parameter( + hwmgr, + PPSMC_MSG_UVDPowerON, + PP_CAP(PHM_PlatformCaps_UVDDynamicPowerGating) ? 1 : 0); } return 0; -- cgit v1.2.3 From 1f9506f50482e2784d8164f94b5266cffef61119 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 16 Oct 2017 13:30:28 -0400 Subject: drm/amd/powerplay: Tidy up cz_dpm_update_uvd_dpm() Use PP_CAP and tidy up indentation. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index c57f7f3b54ec..b159c035a403 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1299,17 +1299,16 @@ int cz_dpm_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate) if (!bgate) { /* Stable Pstate is enabled and we need to set the UVD DPM to highest level */ - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState) - || hwmgr->en_umd_pstate) { + if (PP_CAP(PHM_PlatformCaps_StablePState) || + hwmgr->en_umd_pstate) { cz_hwmgr->uvd_dpm.hard_min_clk = ptable->entries[ptable->count - 1].vclk; smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetUvdHardMin, - cz_get_uvd_level(hwmgr, - cz_hwmgr->uvd_dpm.hard_min_clk, - PPSMC_MSG_SetUvdHardMin)); + PPSMC_MSG_SetUvdHardMin, + cz_get_uvd_level(hwmgr, + cz_hwmgr->uvd_dpm.hard_min_clk, + PPSMC_MSG_SetUvdHardMin)); cz_enable_disable_uvd_dpm(hwmgr, true); } else { -- cgit v1.2.3 From e03ff809f099d111bfab164334cb1259240ef0cd Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 16 Oct 2017 13:31:49 -0400 Subject: drm/amd/powerplay: Tidy up cz_dpm_update_vce_dpm() Use PP_CAP and tidy up indentation. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index b159c035a403..acd06ada47bc 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1328,17 +1328,16 @@ int cz_dpm_update_vce_dpm(struct pp_hwmgr *hwmgr) hwmgr->dyn_state.vce_clock_voltage_dependency_table; /* Stable Pstate is enabled and we need to set the VCE DPM to highest level */ - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_StablePState) - || hwmgr->en_umd_pstate) { + if (PP_CAP(PHM_PlatformCaps_StablePState) || + hwmgr->en_umd_pstate) { cz_hwmgr->vce_dpm.hard_min_clk = ptable->entries[ptable->count - 1].ecclk; smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetEclkHardMin, - cz_get_eclk_level(hwmgr, - cz_hwmgr->vce_dpm.hard_min_clk, - PPSMC_MSG_SetEclkHardMin)); + PPSMC_MSG_SetEclkHardMin, + cz_get_eclk_level(hwmgr, + cz_hwmgr->vce_dpm.hard_min_clk, + PPSMC_MSG_SetEclkHardMin)); } else { /*Program HardMin based on the vce_arbiter.ecclk */ if (hwmgr->vce_arbiter.ecclk == 0) { @@ -1351,10 +1350,10 @@ int cz_dpm_update_vce_dpm(struct pp_hwmgr *hwmgr) } else { cz_hwmgr->vce_dpm.hard_min_clk = hwmgr->vce_arbiter.ecclk; smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetEclkHardMin, - cz_get_eclk_level(hwmgr, - cz_hwmgr->vce_dpm.hard_min_clk, - PPSMC_MSG_SetEclkHardMin)); + PPSMC_MSG_SetEclkHardMin, + cz_get_eclk_level(hwmgr, + cz_hwmgr->vce_dpm.hard_min_clk, + PPSMC_MSG_SetEclkHardMin)); } } return 0; -- cgit v1.2.3 From 9e599766758d3e20a5a1b91100a725abaef63be6 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 16 Oct 2017 13:32:38 -0400 Subject: drm/amd/powerplay: Tidy up cz_dpm_powerdown_vce() Use PP_CAP macro. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index acd06ada47bc..c97e46ee7daf 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1361,8 +1361,7 @@ int cz_dpm_update_vce_dpm(struct pp_hwmgr *hwmgr) int cz_dpm_powerdown_vce(struct pp_hwmgr *hwmgr) { - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_VCEPowerGating)) + if (PP_CAP(PHM_PlatformCaps_VCEPowerGating)) return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_VCEPowerOFF); return 0; -- cgit v1.2.3 From 09da3c0e5b407eab205f6783bb17b5793da8be79 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 16 Oct 2017 13:33:25 -0400 Subject: drm/amd/powerplay: Tidy up cz_dpm_powerup_vce() Use PP_CAP macro. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index c97e46ee7daf..ad1f6b57884b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1369,8 +1369,7 @@ int cz_dpm_powerdown_vce(struct pp_hwmgr *hwmgr) int cz_dpm_powerup_vce(struct pp_hwmgr *hwmgr) { - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, - PHM_PlatformCaps_VCEPowerGating)) + if (PP_CAP(PHM_PlatformCaps_VCEPowerGating)) return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_VCEPowerON); return 0; -- cgit v1.2.3 From 6e13bdf6b2d71ab2366a9f87c99d11963aed3bad Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 18 Oct 2017 17:19:42 +0800 Subject: drm/amdgpu: fix regresstion on SR-IOV gpu reset failed fw ucode is corrupted after vf flr by PSP so ucode_init() is a must in psp_hw_init othewise KIQ/KCQ enabling will fail Revert "drm/amdgpu: refine code delete duplicated error handling" This reverts commit e57b87ff828f95efe992468e6d18c2c059b27aa9. Revert "drm/amdgpu: move amdgpu_ucode_init_bo to amdgpu_device.c" This reverts commit 815b8f8595148d06a64d2ce4282e8e80dfcb02f1. Reviewed-by: Monk Liu Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 -------- drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 5 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 9 +++++++++ 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9cdaba4af216..0731b4f9b25c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1679,7 +1679,6 @@ static int amdgpu_init(struct amdgpu_device *adev) return r; } adev->ip_blocks[i].status.sw = true; - /* need to do gmc hw init early so we can allocate gpu mem */ if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { r = amdgpu_vram_scratch_init(adev); @@ -1710,11 +1709,6 @@ static int amdgpu_init(struct amdgpu_device *adev) } } - mutex_lock(&adev->firmware.mutex); - if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) - amdgpu_ucode_init_bo(adev); - mutex_unlock(&adev->firmware.mutex); - for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.sw) continue; @@ -1850,8 +1844,6 @@ static int amdgpu_fini(struct amdgpu_device *adev) adev->ip_blocks[i].status.hw = false; } - if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) - amdgpu_ucode_fini_bo(adev); for (i = adev->num_ip_blocks - 1; i >= 0; i--) { if (!adev->ip_blocks[i].status.sw) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 3b42f407971d..5f5aa5fddc16 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -145,6 +145,8 @@ static int amdgpu_pp_hw_init(void *handle) int ret = 0; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) + amdgpu_ucode_init_bo(adev); if (adev->powerplay.ip_funcs->hw_init) ret = adev->powerplay.ip_funcs->hw_init( @@ -162,6 +164,9 @@ static int amdgpu_pp_hw_fini(void *handle) ret = adev->powerplay.ip_funcs->hw_fini( adev->powerplay.pp_handle); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) + amdgpu_ucode_fini_bo(adev); + return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index f1035a689d35..447d446b5015 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -411,6 +411,13 @@ static int psp_hw_init(void *handle) return 0; mutex_lock(&adev->firmware.mutex); + /* + * This sequence is just used on hw_init only once, no need on + * resume. + */ + ret = amdgpu_ucode_init_bo(adev); + if (ret) + goto failed; ret = psp_load_fw(adev); if (ret) { @@ -435,6 +442,8 @@ static int psp_hw_fini(void *handle) if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) return 0; + amdgpu_ucode_fini_bo(adev); + psp_ring_destroy(psp, PSP_RING_TYPE__KM); amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); -- cgit v1.2.3 From 896a664c969307a4954cd8c7754fd5d4e5358396 Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Tue, 17 Oct 2017 19:23:42 +0800 Subject: drm/amdgpu:reduce wb to 512 slot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit with current WB usage we only use 57 slots, so 512 is extreamly sufficient, and reduce to 512 can make WB fit into one page. Signed-off-by: Monk Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 67b864436be1..b8ba1f5ae5e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1151,7 +1151,7 @@ static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p, /* * Writeback */ -#define AMDGPU_MAX_WB 1024 /* Reserve at most 1024 WB slots for amdgpu-owned rings. */ +#define AMDGPU_MAX_WB 512 /* Reserve at most 512 WB slots for amdgpu-owned rings. */ struct amdgpu_wb { struct amdgpu_bo *wb_obj; -- cgit v1.2.3 From c70b78a71e9a283240f72dfdfff8fd2388db51da Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Mon, 16 Oct 2017 20:02:08 +0800 Subject: drm/amdgpu:fix duplicated setting job's vram_lost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Monk Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 52dd78ee8fd0..32cf83e2f2d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -172,7 +172,6 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) if (ret) goto free_all_kdata; - p->job->vram_lost_counter = atomic_read(&p->adev->vram_lost_counter); if (p->ctx->vram_lost_counter != p->job->vram_lost_counter) { ret = -ECANCELED; goto free_all_kdata; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index a8357885776e..0cfc68db575b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -61,11 +61,11 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->vm = vm; (*job)->ibs = (void *)&(*job)[1]; (*job)->num_ibs = num_ibs; - (*job)->vram_lost_counter = atomic_read(&adev->vram_lost_counter); amdgpu_sync_create(&(*job)->sync); amdgpu_sync_create(&(*job)->dep_sync); amdgpu_sync_create(&(*job)->sched_sync); + (*job)->vram_lost_counter = atomic_read(&adev->vram_lost_counter); return 0; } -- cgit v1.2.3 From f993d628a2d3cb5e0a82a5284b24cef745f42b41 Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Mon, 16 Oct 2017 19:46:01 +0800 Subject: drm/amdgpu:don't check soft_reset for sriov MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Monk Liu Ack-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0731b4f9b25c..3a6ce6386ad0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2625,6 +2625,9 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev) int i; bool asic_hang = false; + if (amdgpu_sriov_vf(adev)) + return true; + for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.valid) continue; -- cgit v1.2.3 From e71de0766191d32648cf12dfb2f53f05e52b2dcc Mon Sep 17 00:00:00 2001 From: pding Date: Thu, 12 Oct 2017 13:53:20 +0800 Subject: drm/amdgpu: report more amdgpu_fence_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only for GFX ring. This can help checking MCBP feature. The fence at the end of the frame will indicate the completion status. If the frame completed normally, the fence is written to the address given in the EVENT_WRITE_EOP packet. If preemption occurred in the previous IB the address is adjusted by 2 DWs. If work submitted in the frame was reset before completion, the fence address is adjusted by four DWs. In the case that preemption occurred, and before preemption completed a reset was initiated, the address will be adjusted with six DWs Signed-off-by: pding Reviewed-by: Monk Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 333bad749067..7bdedd788f5a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -641,6 +641,19 @@ static int amdgpu_debugfs_fence_info(struct seq_file *m, void *data) atomic_read(&ring->fence_drv.last_seq)); seq_printf(m, "Last emitted 0x%08x\n", ring->fence_drv.sync_seq); + + if (ring->funcs->type != AMDGPU_RING_TYPE_GFX) + continue; + + /* set in CP_VMID_PREEMPT and preemption occurred */ + seq_printf(m, "Last preempted 0x%08x\n", + le32_to_cpu(*(ring->fence_drv.cpu_addr + 2))); + /* set in CP_VMID_RESET and reset occurred */ + seq_printf(m, "Last reset 0x%08x\n", + le32_to_cpu(*(ring->fence_drv.cpu_addr + 4))); + /* Both preemption and reset occurred */ + seq_printf(m, "Last both 0x%08x\n", + le32_to_cpu(*(ring->fence_drv.cpu_addr + 6))); } return 0; } -- cgit v1.2.3 From 43ca8efa46d9b1c4defa1b27c4dd1ef3866aaad9 Mon Sep 17 00:00:00 2001 From: pding Date: Fri, 13 Oct 2017 15:38:35 +0800 Subject: drm/amdgpu: busywait KIQ register accessing (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register accessing is performed when IRQ is disabled. Never sleep in this function. Known issue: dead sleep in many use cases of index/data registers. v2: - wrap polling fence functions. - don't trigger IRQ for polling in case of wrongly fence signal. v3: - handle wrap round gracefully. - add comments for polling function v4: - don't return negative timeout confused with error code Signed-off-by: pding Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 50 ++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 4 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 30 ++++++++---------- 6 files changed, 71 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index b8ba1f5ae5e7..cbcb6a153aba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -879,7 +879,7 @@ struct amdgpu_mec { struct amdgpu_kiq { u64 eop_gpu_addr; struct amdgpu_bo *eop_obj; - struct mutex ring_mutex; + spinlock_t ring_lock; struct amdgpu_ring ring; struct amdgpu_irq_src irq; }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 3a6ce6386ad0..0b9332e65a4c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -109,10 +109,8 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, { uint32_t ret; - if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) { - BUG_ON(in_interrupt()); + if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) return amdgpu_virt_kiq_rreg(adev, reg); - } if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX)) ret = readl(((void __iomem *)adev->rmmio) + (reg * 4)); @@ -137,10 +135,8 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, adev->last_mm_index = v; } - if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) { - BUG_ON(in_interrupt()); + if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) return amdgpu_virt_kiq_wreg(adev, reg, v); - } if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX)) writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 7bdedd788f5a..fb9f88ef6059 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -168,6 +168,32 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f) return 0; } +/** + * amdgpu_fence_emit_polling - emit a fence on the requeste ring + * + * @ring: ring the fence is associated with + * @s: resulting sequence number + * + * Emits a fence command on the requested ring (all asics). + * Used For polling fence. + * Returns 0 on success, -ENOMEM on failure. + */ +int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s) +{ + uint32_t seq; + + if (!s) + return -EINVAL; + + seq = ++ring->fence_drv.sync_seq; + amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, + seq, AMDGPU_FENCE_FLAG_INT); + + *s = seq; + + return 0; +} + /** * amdgpu_fence_schedule_fallback - schedule fallback check * @@ -281,6 +307,30 @@ int amdgpu_fence_wait_empty(struct amdgpu_ring *ring) return r; } +/** + * amdgpu_fence_wait_polling - busy wait for givn sequence number + * + * @ring: ring index the fence is associated with + * @wait_seq: sequence number to wait + * @timeout: the timeout for waiting in usecs + * + * Wait for all fences on the requested ring to signal (all asics). + * Returns left time if no timeout, 0 or minus if timeout. + */ +signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, + uint32_t wait_seq, + signed long timeout) +{ + uint32_t seq; + + do { + seq = amdgpu_fence_read(ring); + udelay(5); + timeout -= 5; + } while ((int32_t)(wait_seq - seq) > 0 && timeout > 0); + + return timeout > 0 ? timeout : 0; +} /** * amdgpu_fence_count_emitted - get the count of emitted fences * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 83435ccbad44..ef043361009f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -201,7 +201,7 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, struct amdgpu_kiq *kiq = &adev->gfx.kiq; int r = 0; - mutex_init(&kiq->ring_mutex); + spin_lock_init(&kiq->ring_lock); r = amdgpu_wb_get(adev, &adev->virt.reg_val_offs); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 0d9ce141404c..b18c2b96691f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -90,8 +90,12 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, void amdgpu_fence_driver_suspend(struct amdgpu_device *adev); void amdgpu_fence_driver_resume(struct amdgpu_device *adev); int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence); +int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s); void amdgpu_fence_process(struct amdgpu_ring *ring); int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); +signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, + uint32_t wait_seq, + signed long timeout); unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index ed7be2eb24b0..e97f80f86005 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -22,7 +22,7 @@ */ #include "amdgpu.h" -#define MAX_KIQ_REG_WAIT 100000 +#define MAX_KIQ_REG_WAIT 100000000 /* in usecs */ int amdgpu_allocate_static_csa(struct amdgpu_device *adev) { @@ -114,27 +114,24 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev) uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) { signed long r; - uint32_t val; - struct dma_fence *f; + uint32_t val, seq; struct amdgpu_kiq *kiq = &adev->gfx.kiq; struct amdgpu_ring *ring = &kiq->ring; BUG_ON(!ring->funcs->emit_rreg); - mutex_lock(&kiq->ring_mutex); + spin_lock(&kiq->ring_lock); amdgpu_ring_alloc(ring, 32); amdgpu_ring_emit_rreg(ring, reg); - amdgpu_fence_emit(ring, &f); + amdgpu_fence_emit_polling(ring, &seq); amdgpu_ring_commit(ring); - mutex_unlock(&kiq->ring_mutex); + spin_unlock(&kiq->ring_lock); - r = dma_fence_wait_timeout(f, false, msecs_to_jiffies(MAX_KIQ_REG_WAIT)); - dma_fence_put(f); + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); if (r < 1) { - DRM_ERROR("wait for kiq fence error: %ld.\n", r); + DRM_ERROR("wait for kiq fence error: %ld\n", r); return ~0; } - val = adev->wb.wb[adev->virt.reg_val_offs]; return val; @@ -143,23 +140,22 @@ uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) { signed long r; - struct dma_fence *f; + uint32_t seq; struct amdgpu_kiq *kiq = &adev->gfx.kiq; struct amdgpu_ring *ring = &kiq->ring; BUG_ON(!ring->funcs->emit_wreg); - mutex_lock(&kiq->ring_mutex); + spin_lock(&kiq->ring_lock); amdgpu_ring_alloc(ring, 32); amdgpu_ring_emit_wreg(ring, reg, v); - amdgpu_fence_emit(ring, &f); + amdgpu_fence_emit_polling(ring, &seq); amdgpu_ring_commit(ring); - mutex_unlock(&kiq->ring_mutex); + spin_unlock(&kiq->ring_lock); - r = dma_fence_wait_timeout(f, false, msecs_to_jiffies(MAX_KIQ_REG_WAIT)); + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); if (r < 1) - DRM_ERROR("wait for kiq fence error: %ld.\n", r); - dma_fence_put(f); + DRM_ERROR("wait for kiq fence error: %ld\n", r); } /** -- cgit v1.2.3 From 1ed05ff4797a2935f04fbb4f465cd70a8a017709 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 18 Oct 2017 14:31:40 +0800 Subject: drm/amd/pp: thermal control not enabled on vega10. regression issue. caused by "f12f9f5e5d455edebc01" forget to set start_thermal_controller function point. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 1 + drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index ebaea5cf72f0..500f177254ac 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -5108,6 +5108,7 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = { .avfs_control = vega10_avfs_enable, .notify_cac_buffer_info = vega10_notify_cac_buffer_info, .register_internal_thermal_interrupt = vega10_register_thermal_interrupt, + .start_thermal_controller = vega10_start_thermal_controller, }; int vega10_hwmgr_init(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h index f34ce04cfd89..82f10bdd5f07 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h @@ -71,7 +71,8 @@ extern int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, extern int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr); extern int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr); extern int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr); - +extern int vega10_start_thermal_controller(struct pp_hwmgr *hwmgr, + struct PP_TemperatureRange *range); extern uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr); #endif -- cgit v1.2.3 From 658b93913e7a8a8d418b6d1208e88ddacc4d245d Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 18 Oct 2017 17:43:43 +0800 Subject: drm/amd/pp: Fix overflow when setup decf/pix/disp dpm table. Clear the count in the single table setup function to avoid missing any tables. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 500f177254ac..0519338e0e5e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -1161,6 +1161,8 @@ static void vega10_setup_default_single_dpm_table(struct pp_hwmgr *hwmgr, { int i; + dpm_table->count = 0; + for (i = 0; i < dep_table->count; i++) { if (i == 0 || dpm_table->dpm_levels[dpm_table->count - 1].value <= dep_table->entries[i].clk) { @@ -1269,10 +1271,6 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) return -EINVAL); /* Initialize Sclk DPM table based on allow Sclk values */ - data->dpm_table.soc_table.count = 0; - data->dpm_table.gfx_table.count = 0; - data->dpm_table.dcef_table.count = 0; - dpm_table = &(data->dpm_table.soc_table); vega10_setup_default_single_dpm_table(hwmgr, dpm_table, -- cgit v1.2.3 From 4b6b691ee38abae8842aed61d442dfb315c45789 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 16 Oct 2017 10:32:04 +0200 Subject: drm/amdgpu: linear validate first then bind to GART MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For VM emulation for old UVD/VCE we need to validate the BO with linear VRAM flag set first and then eventually bind it to GART. Validating with linear VRAM flag set can move the BO to GART making UVD/VCE read/write from an unbound GART BO. Signed-off-by: Christian König Reviewed-by: Alex Deucher CC: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 32cf83e2f2d9..f7fceb63413c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1582,14 +1582,14 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket) return -EINVAL; - r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem); - if (unlikely(r)) - return r; - - if ((*bo)->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) - return 0; + if (!((*bo)->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) { + (*bo)->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; + amdgpu_ttm_placement_from_domain(*bo, (*bo)->allowed_domains); + r = ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, false, + false); + if (r) + return r; + } - (*bo)->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; - amdgpu_ttm_placement_from_domain(*bo, (*bo)->allowed_domains); - return ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, false, false); + return amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem); } -- cgit v1.2.3 From d2d7cc330dc1f8ea7cf29dfb7d3ad8bccdcde597 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 16 Oct 2017 11:18:54 +0200 Subject: drm/amdgpu: allow GTT overcommit during bind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While binding BOs to GART we need to allow a bit overcommit in the GTT domain. Otherwise we can never use the full GART space when GART size=GTT size. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index 0d15eb7d31d7..33535d347734 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -169,7 +169,8 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man, int r; spin_lock(&mgr->lock); - if (atomic64_read(&mgr->available) < mem->num_pages) { + if ((&tbo->mem == mem || tbo->mem.mem_type != TTM_PL_TT) && + atomic64_read(&mgr->available) < mem->num_pages) { spin_unlock(&mgr->lock); return 0; } @@ -244,8 +245,9 @@ static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man, uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man) { struct amdgpu_gtt_mgr *mgr = man->priv; + s64 result = man->size - atomic64_read(&mgr->available); - return (u64)(man->size - atomic64_read(&mgr->available)) * PAGE_SIZE; + return (result > 0 ? result : 0) * PAGE_SIZE; } /** @@ -265,7 +267,7 @@ static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man, drm_mm_print(&mgr->mm, printer); spin_unlock(&mgr->lock); - drm_printf(printer, "man size:%llu pages, gtt available:%llu pages, usage:%lluMB\n", + drm_printf(printer, "man size:%llu pages, gtt available:%lld pages, usage:%lluMB\n", man->size, (u64)atomic64_read(&mgr->available), amdgpu_gtt_mgr_usage(man) >> 20); } -- cgit v1.2.3 From bada22d021135374332bc7de59c93761778d7989 Mon Sep 17 00:00:00 2001 From: Georgiana Chelu Date: Tue, 17 Oct 2017 23:22:07 +0300 Subject: drm/amd/powerplay: Don't cast kzalloc() return value The kzalloc function returns a void pointer and the assignment operator converts it to the type of pointer it is assigned to. Therefore, there is no need to cast. Issue found by alloc_cast.cocci: * WARNING: casting value returned by memory allocation function to is useless. Path to the cocci script: scripts/coccinelle/api/alloc/alloc_cast.cocci Signed-off-by: Georgiana Chelu Signed-off-by: Alex Deucher --- .../amd/powerplay/hwmgr/vega10_processpptables.c | 24 ++++++++-------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c index e343df190375..d968c3834481 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c @@ -291,8 +291,7 @@ static int get_mm_clock_voltage_table( table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_mm_clock_voltage_dependency_record) * mm_dependency_table->ucNumEntries; - mm_table = (phm_ppt_v1_mm_clock_voltage_dependency_table *) - kzalloc(table_size, GFP_KERNEL); + mm_table = kzalloc(table_size, GFP_KERNEL); if (!mm_table) return -ENOMEM; @@ -519,8 +518,7 @@ static int get_socclk_voltage_dependency_table( sizeof(phm_ppt_v1_clock_voltage_dependency_record) * clk_dep_table->ucNumEntries; - clk_table = (phm_ppt_v1_clock_voltage_dependency_table *) - kzalloc(table_size, GFP_KERNEL); + clk_table = kzalloc(table_size, GFP_KERNEL); if (!clk_table) return -ENOMEM; @@ -554,8 +552,7 @@ static int get_mclk_voltage_dependency_table( sizeof(phm_ppt_v1_clock_voltage_dependency_record) * mclk_dep_table->ucNumEntries; - mclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) - kzalloc(table_size, GFP_KERNEL); + mclk_table = kzalloc(table_size, GFP_KERNEL); if (!mclk_table) return -ENOMEM; @@ -596,8 +593,7 @@ static int get_gfxclk_voltage_dependency_table( sizeof(phm_ppt_v1_clock_voltage_dependency_record) * clk_dep_table->ucNumEntries; - clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *) - kzalloc(table_size, GFP_KERNEL); + clk_table = kzalloc(table_size, GFP_KERNEL); if (!clk_table) return -ENOMEM; @@ -663,8 +659,7 @@ static int get_pix_clk_voltage_dependency_table( sizeof(phm_ppt_v1_clock_voltage_dependency_record) * clk_dep_table->ucNumEntries; - clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *) - kzalloc(table_size, GFP_KERNEL); + clk_table = kzalloc(table_size, GFP_KERNEL); if (!clk_table) return -ENOMEM; @@ -728,8 +723,7 @@ static int get_dcefclk_voltage_dependency_table( sizeof(phm_ppt_v1_clock_voltage_dependency_record) * num_entries; - clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *) - kzalloc(table_size, GFP_KERNEL); + clk_table = kzalloc(table_size, GFP_KERNEL); if (!clk_table) return -ENOMEM; @@ -772,8 +766,7 @@ static int get_pcie_table(struct pp_hwmgr *hwmgr, sizeof(struct phm_ppt_v1_pcie_record) * atom_pcie_table->ucNumEntries; - pcie_table = (struct phm_ppt_v1_pcie_table *) - kzalloc(table_size, GFP_KERNEL); + pcie_table = kzalloc(table_size, GFP_KERNEL); if (!pcie_table) return -ENOMEM; @@ -1026,8 +1019,7 @@ static int get_vddc_lookup_table( table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_voltage_lookup_record) * max_levels; - table = (phm_ppt_v1_voltage_lookup_table *) - kzalloc(table_size, GFP_KERNEL); + table = kzalloc(table_size, GFP_KERNEL); if (NULL == table) return -ENOMEM; -- cgit v1.2.3 From c1537c342086ff7cf064d274db0c03f6698f77d8 Mon Sep 17 00:00:00 2001 From: Georgiana Chelu Date: Tue, 17 Oct 2017 23:22:08 +0300 Subject: drm/amd/powerplay: Remove useless variable The result variable is initialized at the beginning of the function, but its value does not change during the function execution. Thus, remove the variable and return the SUCCESS value, which is 0. Issue found by coccinelle script: * Unneeded variable: "result". Return "0" Path to the cocci script: scripts/coccinelle/misc/returnvar.cocci Signed-off-by: Georgiana Chelu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c index d968c3834481..769ac11a9215 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c @@ -1174,7 +1174,6 @@ int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr) static int vega10_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) { - int result = 0; struct phm_ppt_v2_information *pp_table_info = (struct phm_ppt_v2_information *)(hwmgr->pptable); @@ -1217,7 +1216,7 @@ static int vega10_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) kfree(hwmgr->pptable); hwmgr->pptable = NULL; - return result; + return 0; } const struct pp_table_func vega10_pptable_funcs = { -- cgit v1.2.3 From 96687ec0bb478088cb6941a7dca3bb6808a19313 Mon Sep 17 00:00:00 2001 From: Georgiana Chelu Date: Tue, 17 Oct 2017 23:22:09 +0300 Subject: drm/amd/powerplay: Place the constant on the right side of the test Move the constant on the right side of the comparison in order to make the code easier to read. Issue found by checkpatch script: * WARNING: Comparisons should place the constant on the right side of the test Signed-off-by: Georgiana Chelu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c index 769ac11a9215..f14c7611fad3 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c @@ -1021,7 +1021,7 @@ static int get_vddc_lookup_table( table = kzalloc(table_size, GFP_KERNEL); - if (NULL == table) + if (table == NULL) return -ENOMEM; table->count = vddc_lookup_pp_tables->ucNumEntries; @@ -1130,12 +1130,12 @@ int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr) hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v2_information), GFP_KERNEL); - PP_ASSERT_WITH_CODE((NULL != hwmgr->pptable), + PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL), "Failed to allocate hwmgr->pptable!", return -ENOMEM); powerplay_table = get_powerplay_table(hwmgr); - PP_ASSERT_WITH_CODE((NULL != powerplay_table), + PP_ASSERT_WITH_CODE((powerplay_table != NULL), "Missing PowerPlay Table!", return -1); result = check_powerplay_tables(hwmgr, powerplay_table); @@ -1229,7 +1229,7 @@ int vega10_get_number_of_powerplay_table_entries(struct pp_hwmgr *hwmgr) const ATOM_Vega10_State_Array *state_arrays; const ATOM_Vega10_POWERPLAYTABLE *pp_table = get_powerplay_table(hwmgr); - PP_ASSERT_WITH_CODE((NULL != pp_table), + PP_ASSERT_WITH_CODE((pp_table != NULL), "Missing PowerPlay Table!", return -1); PP_ASSERT_WITH_CODE((pp_table->sHeader.format_revision >= ATOM_Vega10_TABLE_REVISION_VEGA10), -- cgit v1.2.3 From 8f75bc3377fa6f2af16383cc8346abd81909353f Mon Sep 17 00:00:00 2001 From: Damien Riegel Date: Thu, 19 Oct 2017 15:34:55 -0700 Subject: Input: tca8418 - enable interrupt after it has been requested Currently, enabling keypad interrupts is one of the first operations done on the keypad, even before the interrupt is requested, so there is a small time window where the keypad can fire interrupts but the driver is not yet ready to handle them. It's fine for level interrupts because they will be handled anyway, but not so much for edge ones. This commit modifies and moves the function in charge of configuring the keypad. Enabling interrupts is now the last thing done on the keypad, and after the interrupt has been requested by the driver. Writing to the config register was also used to determine if the device was indeed present on the bus or not, this has been replaced by reading the lock/event count register to keep the same functionality. Signed-off-by: Damien Riegel Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tca8418_keypad.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index e37e335e406f..6da607d3b811 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -234,14 +234,7 @@ static irqreturn_t tca8418_irq_handler(int irq, void *dev_id) static int tca8418_configure(struct tca8418_keypad *keypad_data, u32 rows, u32 cols) { - int reg, error; - - /* Write config register, if this fails assume device not present */ - error = tca8418_write_byte(keypad_data, REG_CFG, - CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN); - if (error < 0) - return -ENODEV; - + int reg, error = 0; /* Assemble a mask for row and column registers */ reg = ~(~0 << rows); @@ -257,6 +250,12 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data, error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8); error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16); + if (error) + return error; + + error = tca8418_write_byte(keypad_data, REG_CFG, + CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN); + return error; } @@ -268,6 +267,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, struct input_dev *input; u32 rows = 0, cols = 0; int error, row_shift, max_keys; + u8 reg; /* Check i2c driver capabilities */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { @@ -301,10 +301,10 @@ static int tca8418_keypad_probe(struct i2c_client *client, keypad_data->client = client; keypad_data->row_shift = row_shift; - /* Initialize the chip or fail if chip isn't present */ - error = tca8418_configure(keypad_data, rows, cols); - if (error < 0) - return error; + /* Read key lock register, if this fails assume device not present */ + error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, ®); + if (error) + return -ENODEV; /* Configure input device */ input = devm_input_allocate_device(dev); @@ -340,6 +340,11 @@ static int tca8418_keypad_probe(struct i2c_client *client, return error; } + /* Initialize the chip */ + error = tca8418_configure(keypad_data, rows, cols); + if (error < 0) + return error; + error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device, error: %d\n", -- cgit v1.2.3 From 481c209fa016a9e594427a306718cdf48ceeb1c6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 19 Oct 2017 15:38:50 -0700 Subject: Input: axp20x-pek - fix module not auto-loading for axp221 pek Now that we have a platform_device_id table and multiple supported ids we should be using MODULE_DEVICE_TABLE instead of MODULE_ALIAS. This fixes a regression on Bay and Cherry Trail devices, where the power button is now enumerated as an "axp221-pek" and it was impossible to wakeup these devices from suspend since the module did not load. Fixes: c3cc94470bd3 ("Input: axp20x-pek - add support for AXP221 PEK") Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/misc/axp20x-pek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c index 6cee5adc3b5c..debeeaeb8812 100644 --- a/drivers/input/misc/axp20x-pek.c +++ b/drivers/input/misc/axp20x-pek.c @@ -403,6 +403,7 @@ static const struct platform_device_id axp_pek_id_match[] = { }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(platform, axp_pek_id_match); static struct platform_driver axp20x_pek_driver = { .probe = axp20x_pek_probe, @@ -417,4 +418,3 @@ module_platform_driver(axp20x_pek_driver); MODULE_DESCRIPTION("axp20x Power Button"); MODULE_AUTHOR("Carlo Caione "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:axp20x-pek"); -- cgit v1.2.3 From 9b5db7aab4d6b66f84f5e147c87eff4fe8b48651 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 13 Oct 2017 11:04:48 -0700 Subject: Input: goodix - poll the 'buffer status' bit before reading data The Goodix panel triggers an interrupt on touch events. However, its registers will contain the valid values a short time after the interrupt, and not when it's raised. At that moment, the 'buffer status' bit is set. Previously, if the 'buffer status' bit was not set when the registers were read, the data was discarded and no input event was emitted, causing "finger down" or "finger up" events to be missed sometimes. This went unnoticed until v4.9, as the DesignWare I2C driver commonly used with this driver had enough latency for that bug to never trigger until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only if necessary"). Now, in the IRQ handler we will poll (with a timeout) the 'buffer status' bit and process the data of the panel as soon as this bit gets set. Note that the Goodix panel will send a few spurious interrupts after the 'finger up' event, in which the 'buffer status' bit will never be set. Cc: Bastien Nocera Cc: russianneuromancer@ya.ru Signed-off-by: Paul Cercueil [hdegoede@redhat.com: Change poll loop to use jiffies, add comment about typical poll time] Signed-off-by: Hans de Goede [dtor: rearranged control flow a bit to avoid explicit goto and double check] Reviewed-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 67 +++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 32d2762448aa..b3bbad7d2282 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -72,6 +72,9 @@ struct goodix_ts_data { #define GOODIX_REG_CONFIG_DATA 0x8047 #define GOODIX_REG_ID 0x8140 +#define GOODIX_BUFFER_STATUS_READY BIT(7) +#define GOODIX_BUFFER_STATUS_TIMEOUT 20 + #define RESOLUTION_LOC 1 #define MAX_CONTACTS_LOC 5 #define TRIGGER_LOC 6 @@ -195,35 +198,53 @@ static int goodix_get_cfg_len(u16 id) static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) { + unsigned long max_timeout; int touch_num; int error; - error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data, - GOODIX_CONTACT_SIZE + 1); - if (error) { - dev_err(&ts->client->dev, "I2C transfer error: %d\n", error); - return error; - } + /* + * The 'buffer status' bit, which indicates that the data is valid, is + * not set as soon as the interrupt is raised, but slightly after. + * This takes around 10 ms to happen, so we poll for 20 ms. + */ + max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT); + do { + error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, + data, GOODIX_CONTACT_SIZE + 1); + if (error) { + dev_err(&ts->client->dev, "I2C transfer error: %d\n", + error); + return error; + } - if (!(data[0] & 0x80)) - return -EAGAIN; + if (data[0] & GOODIX_BUFFER_STATUS_READY) { + touch_num = data[0] & 0x0f; + if (touch_num > ts->max_touch_num) + return -EPROTO; + + if (touch_num > 1) { + data += 1 + GOODIX_CONTACT_SIZE; + error = goodix_i2c_read(ts->client, + GOODIX_READ_COOR_ADDR + + 1 + GOODIX_CONTACT_SIZE, + data, + GOODIX_CONTACT_SIZE * + (touch_num - 1)); + if (error) + return error; + } + + return touch_num; + } - touch_num = data[0] & 0x0f; - if (touch_num > ts->max_touch_num) - return -EPROTO; - - if (touch_num > 1) { - data += 1 + GOODIX_CONTACT_SIZE; - error = goodix_i2c_read(ts->client, - GOODIX_READ_COOR_ADDR + - 1 + GOODIX_CONTACT_SIZE, - data, - GOODIX_CONTACT_SIZE * (touch_num - 1)); - if (error) - return error; - } + usleep_range(1000, 2000); /* Poll every 1 - 2 ms */ + } while (time_before(jiffies, max_timeout)); - return touch_num; + /* + * The Goodix panel will send spurious interrupts after a + * 'finger up' event, which will always cause a timeout. + */ + return 0; } static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) -- cgit v1.2.3 From 55dfce873dca46df00304c44a568d7933bffff89 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 9 Oct 2017 11:09:33 -0700 Subject: Input: factor out and export input_device_id matching code Factor out and export input_match_device_id() so that modules may use it. It will be needed by joydev to blacklist accelerometers in composite devices. Tested-by: Roderick Colenbrander Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 83 +++++++++++++++++++++++---------------------------- include/linux/input.h | 3 ++ 2 files changed, 41 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index d268fdc23c64..02e6ea7955fe 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -933,58 +933,51 @@ int input_set_keycode(struct input_dev *dev, } EXPORT_SYMBOL(input_set_keycode); +bool input_match_device_id(const struct input_dev *dev, + const struct input_device_id *id) +{ + if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) + if (id->bustype != dev->id.bustype) + return false; + + if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) + if (id->vendor != dev->id.vendor) + return false; + + if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) + if (id->product != dev->id.product) + return false; + + if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) + if (id->version != dev->id.version) + return false; + + if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX) || + !bitmap_subset(id->keybit, dev->keybit, KEY_MAX) || + !bitmap_subset(id->relbit, dev->relbit, REL_MAX) || + !bitmap_subset(id->absbit, dev->absbit, ABS_MAX) || + !bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX) || + !bitmap_subset(id->ledbit, dev->ledbit, LED_MAX) || + !bitmap_subset(id->sndbit, dev->sndbit, SND_MAX) || + !bitmap_subset(id->ffbit, dev->ffbit, FF_MAX) || + !bitmap_subset(id->swbit, dev->swbit, SW_MAX)) { + return false; + } + + return true; +} +EXPORT_SYMBOL(input_match_device_id); + static const struct input_device_id *input_match_device(struct input_handler *handler, struct input_dev *dev) { const struct input_device_id *id; for (id = handler->id_table; id->flags || id->driver_info; id++) { - - if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) - if (id->bustype != dev->id.bustype) - continue; - - if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) - if (id->vendor != dev->id.vendor) - continue; - - if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) - if (id->product != dev->id.product) - continue; - - if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) - if (id->version != dev->id.version) - continue; - - if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX)) - continue; - - if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX)) - continue; - - if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX)) - continue; - - if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX)) - continue; - - if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX)) - continue; - - if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX)) - continue; - - if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX)) - continue; - - if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX)) - continue; - - if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX)) - continue; - - if (!handler->match || handler->match(handler, dev)) + if (input_match_device_id(dev, id) && + (!handler->match || handler->match(handler, dev))) { return id; + } } return NULL; diff --git a/include/linux/input.h b/include/linux/input.h index fb5e23c7ed98..2a44650e449d 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -469,6 +469,9 @@ int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke); int input_set_keycode(struct input_dev *dev, const struct input_keymap_entry *ke); +bool input_match_device_id(const struct input_dev *dev, + const struct input_device_id *id); + void input_enable_softrepeat(struct input_dev *dev, int delay, int period); extern struct class input_class; -- cgit v1.2.3 From 8724ecb072293f109a6f5dc93be8a98bf61fe14f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 9 Oct 2017 12:01:14 -0700 Subject: Input: allow matching device IDs on property bits Let's allow matching input devices on their property bits, both in-kernel and when generating module aliases. Tested-by: Roderick Colenbrander Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 3 ++- include/linux/input.h | 4 ++++ include/linux/mod_devicetable.h | 3 +++ scripts/mod/devicetable-offsets.c | 1 + scripts/mod/file2alias.c | 6 +++++- 5 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index 02e6ea7955fe..762bfb9487dc 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -960,7 +960,8 @@ bool input_match_device_id(const struct input_dev *dev, !bitmap_subset(id->ledbit, dev->ledbit, LED_MAX) || !bitmap_subset(id->sndbit, dev->sndbit, SND_MAX) || !bitmap_subset(id->ffbit, dev->ffbit, FF_MAX) || - !bitmap_subset(id->swbit, dev->swbit, SW_MAX)) { + !bitmap_subset(id->swbit, dev->swbit, SW_MAX) || + !bitmap_subset(id->propbit, dev->propbit, INPUT_PROP_MAX)) { return false; } diff --git a/include/linux/input.h b/include/linux/input.h index 2a44650e449d..7c7516eb7d76 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -234,6 +234,10 @@ struct input_dev { #error "SW_MAX and INPUT_DEVICE_ID_SW_MAX do not match" #endif +#if INPUT_PROP_MAX != INPUT_DEVICE_ID_PROP_MAX +#error "INPUT_PROP_MAX and INPUT_DEVICE_ID_PROP_MAX do not match" +#endif + #define INPUT_DEVICE_ID_MATCH_DEVICE \ (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) #define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION \ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 3f74ef2281e8..72f0b7f19c59 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -293,6 +293,7 @@ struct pcmcia_device_id { #define INPUT_DEVICE_ID_SND_MAX 0x07 #define INPUT_DEVICE_ID_FF_MAX 0x7f #define INPUT_DEVICE_ID_SW_MAX 0x0f +#define INPUT_DEVICE_ID_PROP_MAX 0x1f #define INPUT_DEVICE_ID_MATCH_BUS 1 #define INPUT_DEVICE_ID_MATCH_VENDOR 2 @@ -308,6 +309,7 @@ struct pcmcia_device_id { #define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400 #define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800 #define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 +#define INPUT_DEVICE_ID_MATCH_PROPBIT 0x2000 struct input_device_id { @@ -327,6 +329,7 @@ struct input_device_id { kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t propbit[INPUT_DEVICE_ID_PROP_MAX / BITS_PER_LONG + 1]; kernel_ulong_t driver_info; }; diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index e4d90e50f6fe..812657ab5aa3 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -105,6 +105,7 @@ int main(void) DEVID_FIELD(input_device_id, sndbit); DEVID_FIELD(input_device_id, ffbit); DEVID_FIELD(input_device_id, swbit); + DEVID_FIELD(input_device_id, propbit); DEVID(eisa_device_id); DEVID_FIELD(eisa_device_id, sig); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 29d6699d5a06..bc25898f6df0 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -761,7 +761,7 @@ static void do_input(char *alias, sprintf(alias + strlen(alias), "%X,*", i); } -/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ +/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwXprX where X is comma-separated %02X. */ static int do_input_entry(const char *filename, void *symval, char *alias) { @@ -779,6 +779,7 @@ static int do_input_entry(const char *filename, void *symval, DEF_FIELD_ADDR(symval, input_device_id, sndbit); DEF_FIELD_ADDR(symval, input_device_id, ffbit); DEF_FIELD_ADDR(symval, input_device_id, swbit); + DEF_FIELD_ADDR(symval, input_device_id, propbit); sprintf(alias, "input:"); @@ -816,6 +817,9 @@ static int do_input_entry(const char *filename, void *symval, sprintf(alias + strlen(alias), "w*"); if (flags & INPUT_DEVICE_ID_MATCH_SWBIT) do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX); + sprintf(alias + strlen(alias), "pr*"); + if (flags & INPUT_DEVICE_ID_MATCH_PROPBIT) + do_input(alias, *propbit, 0, INPUT_DEVICE_ID_PROP_MAX); return 1; } ADD_TO_DEVTABLE("input", input_device_id, do_input_entry); -- cgit v1.2.3 From 20ac95d52a28f55472a54cc751eeec49fd445cb1 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Mon, 9 Oct 2017 12:02:03 -0700 Subject: Input: joydev - blacklist ds3/ds4/udraw motion sensors Introduce a device table used for blacklisting devices. We currently blacklist the motion sensor subdevice of THQ Udraw and Sony ds3/ds4. Signed-off-by: Roderick Colenbrander [dtor: siwtched to blacklist built on input_device_id and using input_match_device_id()] Signed-off-by: Dmitry Torokhov --- drivers/input/joydev.c | 70 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 29d677c714d2..7b29a8944039 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -747,6 +747,68 @@ static void joydev_cleanup(struct joydev *joydev) input_close_device(handle); } +/* + * These codes are copied from from hid-ids.h, unfortunately there is no common + * usb_ids/bt_ids.h header. + */ +#define USB_VENDOR_ID_SONY 0x054c +#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 +#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4 +#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 0x09cc +#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE 0x0ba0 + +#define USB_VENDOR_ID_THQ 0x20d6 +#define USB_DEVICE_ID_THQ_PS3_UDRAW 0xcb17 + +#define ACCEL_DEV(vnd, prd) \ + { \ + .flags = INPUT_DEVICE_ID_MATCH_VENDOR | \ + INPUT_DEVICE_ID_MATCH_PRODUCT | \ + INPUT_DEVICE_ID_MATCH_PROPBIT, \ + .vendor = (vnd), \ + .product = (prd), \ + .propbit = { BIT_MASK(INPUT_PROP_ACCELEROMETER) }, \ + } + +static const struct input_device_id joydev_blacklist[] = { + /* Avoid touchpads and touchscreens */ + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, + }, + /* Avoid tablets, digitisers and similar devices */ + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) }, + }, + /* Disable accelerometers on composite devices */ + ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), + ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), + ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2), + ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE), + ACCEL_DEV(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW), + { /* sentinel */ } +}; + +static bool joydev_dev_is_blacklisted(struct input_dev *dev) +{ + const struct input_device_id *id; + + for (id = joydev_blacklist; id->flags; id++) { + if (input_match_device_id(dev, id)) { + dev_dbg(&dev->dev, + "joydev: blacklisting '%s'\n", dev->name); + return true; + } + } + + return false; +} + static bool joydev_dev_is_absolute_mouse(struct input_dev *dev) { DECLARE_BITMAP(jd_scratch, KEY_CNT); @@ -807,12 +869,8 @@ static bool joydev_dev_is_absolute_mouse(struct input_dev *dev) static bool joydev_match(struct input_handler *handler, struct input_dev *dev) { - /* Avoid touchpads and touchscreens */ - if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit)) - return false; - - /* Avoid tablets, digitisers and similar devices */ - if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) + /* Disable blacklisted devices */ + if (joydev_dev_is_blacklisted(dev)) return false; /* Avoid absolute mice */ -- cgit v1.2.3 From ea04efee7635c9120d015dcdeeeb6988130cb67a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 7 Oct 2017 11:07:47 -0700 Subject: Input: ims-psu - check if CDC union descriptor is sane Before trying to use CDC union descriptor, try to validate whether that it is sane by checking that intf->altsetting->extra is big enough and that descriptor bLength is not too big and not too small. Reported-by: Andrey Konovalov Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ims-pcu.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 6bf82ea8c918..ae473123583b 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf) return NULL; } - while (buflen > 0) { + while (buflen >= sizeof(*union_desc)) { union_desc = (struct usb_cdc_union_desc *)buf; + if (union_desc->bLength > buflen) { + dev_err(&intf->dev, "Too large descriptor\n"); + return NULL; + } + if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE && union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) { dev_dbg(&intf->dev, "Found union header\n"); - return union_desc; + + if (union_desc->bLength >= sizeof(*union_desc)) + return union_desc; + + dev_err(&intf->dev, + "Union descriptor to short (%d vs %zd\n)", + union_desc->bLength, sizeof(*union_desc)); + return NULL; } buflen -= union_desc->bLength; -- cgit v1.2.3 From c5709d37693b72761d866cb1cd556093a6607c80 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 16 Oct 2017 08:13:53 +0200 Subject: dmaengine: altera: Use IRQ-safe spinlock calls in the error paths as well The patch edf10919 [dmaengine: altera: fix spinlock usage] missed to change 2 occurrences of spin_unlock_bh() to spin_unlock_irqrestore(). This patch fixes this by moving to the IRQ-safe call in the error paths as well. Fixes: edf10919 (dmaengine: altera: fix spinlock usage) Signed-off-by: Stefan Roese Reviewed-by: Sylvain Lesne [add fixes tag and fix typo in log] Signed-off-by: Vinod Koul --- drivers/dma/altera-msgdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c index 339186f25a2a..55f9c62ee54b 100644 --- a/drivers/dma/altera-msgdma.c +++ b/drivers/dma/altera-msgdma.c @@ -344,7 +344,7 @@ msgdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst, spin_lock_irqsave(&mdev->lock, irqflags); if (desc_cnt > mdev->desc_free_cnt) { - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, irqflags); dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev); return NULL; } @@ -407,7 +407,7 @@ msgdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, spin_lock_irqsave(&mdev->lock, irqflags); if (desc_cnt > mdev->desc_free_cnt) { - spin_unlock_bh(&mdev->lock); + spin_unlock_irqrestore(&mdev->lock, irqflags); dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev); return NULL; } -- cgit v1.2.3 From 46e5832014480ba70daf41a80489c0d11d431e08 Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Fri, 13 Oct 2017 18:14:59 +0530 Subject: drm/i915: Parse DSI backlight/cabc ports. This patch parse DSI backlight/cabc ports info from VBT and save them inside local structure. This saved info can be directly used while initializing DSI for different platforms instead of parsing for each platform. V2: Changes: - Typo fix in commit message. - Move up newly added port variables (Jani N) - Remove redundant initialization (Jani N) - Don't parse CABC ports if not supported (Jani N) V3: Patch restructure (Suggested by Jani N) Credits-to: Jani Nikula Signed-off-by: Madhav Chauhan Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507898700-20016-1-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_bios.c | 57 ++++++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3c2649c27f88..9bcf1d15485e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1778,6 +1778,8 @@ struct intel_vbt_data { u16 panel_id; struct mipi_config *config; struct mipi_pps_data *pps; + u16 bl_ports; + u16 cabc_ports; u8 seq_version; u32 size; u8 *data; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 9d5b42953436..c5405d173c5f 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -691,6 +691,50 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time; } +static void parse_dsi_backlight_ports(struct drm_i915_private *dev_priv, + u16 version, enum port port) +{ + if (!dev_priv->vbt.dsi.config->dual_link || version < 197) { + dev_priv->vbt.dsi.bl_ports = BIT(port); + if (dev_priv->vbt.dsi.config->cabc_supported) + dev_priv->vbt.dsi.cabc_ports = BIT(port); + + dev_priv->vbt.dsi.config->dl_dcs_cabc_ports = 0; + dev_priv->vbt.dsi.config->dl_dcs_backlight_ports = 0; + return; + } + + switch (dev_priv->vbt.dsi.config->dl_dcs_backlight_ports) { + case DL_DCS_PORT_A: + dev_priv->vbt.dsi.bl_ports = BIT(PORT_A); + break; + case DL_DCS_PORT_C: + dev_priv->vbt.dsi.bl_ports = BIT(PORT_C); + break; + default: + case DL_DCS_PORT_A_AND_C: + dev_priv->vbt.dsi.bl_ports = BIT(PORT_A) | BIT(PORT_C); + break; + } + + if (!dev_priv->vbt.dsi.config->cabc_supported) + return; + + switch (dev_priv->vbt.dsi.config->dl_dcs_cabc_ports) { + case DL_DCS_PORT_A: + dev_priv->vbt.dsi.cabc_ports = BIT(PORT_A); + break; + case DL_DCS_PORT_C: + dev_priv->vbt.dsi.cabc_ports = BIT(PORT_C); + break; + default: + case DL_DCS_PORT_A_AND_C: + dev_priv->vbt.dsi.cabc_ports = + BIT(PORT_A) | BIT(PORT_C); + break; + } +} + static void parse_mipi_config(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) @@ -699,9 +743,10 @@ parse_mipi_config(struct drm_i915_private *dev_priv, const struct mipi_config *config; const struct mipi_pps_data *pps; int panel_type = dev_priv->vbt.panel_type; + enum port port; /* parse MIPI blocks only if LFP type is MIPI */ - if (!intel_bios_is_dsi_present(dev_priv, NULL)) + if (!intel_bios_is_dsi_present(dev_priv, &port)) return; /* Initialize this to undefined indicating no generic MIPI support */ @@ -742,15 +787,7 @@ parse_mipi_config(struct drm_i915_private *dev_priv, return; } - /* - * These fields are introduced from the VBT version 197 onwards, - * so making sure that these bits are set zero in the previous - * versions. - */ - if (dev_priv->vbt.dsi.config->dual_link && bdb->version < 197) { - dev_priv->vbt.dsi.config->dl_dcs_cabc_ports = 0; - dev_priv->vbt.dsi.config->dl_dcs_backlight_ports = 0; - } + parse_dsi_backlight_ports(dev_priv, bdb->version, port); /* We have mandatory mipi config blocks. Initialize as generic panel */ dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; -- cgit v1.2.3 From 6a2f0641d3c268ee8703b9d14fa49c3f900ca30c Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Fri, 13 Oct 2017 18:15:00 +0530 Subject: drm/i915: Use existing DSI backlight ports info This patch re-use already parsed DSI backlight/cabc ports info for saving it inside struct intel_dsi rather than parsing it at the time of DSI initialization. V2: Remove backlight and cabc variable initialization (Jani N). Reviewed-by: Jani Nikula Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1507898700-20016-2-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 2 -- drivers/gpu/drm/i915/intel_dsi.c | 37 ++++--------------------------------- 2 files changed, 4 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index c5405d173c5f..a0c42e6c9873 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -699,8 +699,6 @@ static void parse_dsi_backlight_ports(struct drm_i915_private *dev_priv, if (dev_priv->vbt.dsi.config->cabc_supported) dev_priv->vbt.dsi.cabc_ports = BIT(port); - dev_priv->vbt.dsi.config->dl_dcs_cabc_ports = 0; - dev_priv->vbt.dsi.config->dl_dcs_backlight_ports = 0; return; } diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 66bbedc5fa01..83f15848098a 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1751,42 +1751,13 @@ void intel_dsi_init(struct drm_i915_private *dev_priv) else intel_encoder->crtc_mask = BIT(PIPE_B); - if (dev_priv->vbt.dsi.config->dual_link) { + if (dev_priv->vbt.dsi.config->dual_link) intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C); - - switch (dev_priv->vbt.dsi.config->dl_dcs_backlight_ports) { - case DL_DCS_PORT_A: - intel_dsi->dcs_backlight_ports = BIT(PORT_A); - break; - case DL_DCS_PORT_C: - intel_dsi->dcs_backlight_ports = BIT(PORT_C); - break; - default: - case DL_DCS_PORT_A_AND_C: - intel_dsi->dcs_backlight_ports = BIT(PORT_A) | BIT(PORT_C); - break; - } - - switch (dev_priv->vbt.dsi.config->dl_dcs_cabc_ports) { - case DL_DCS_PORT_A: - intel_dsi->dcs_cabc_ports = BIT(PORT_A); - break; - case DL_DCS_PORT_C: - intel_dsi->dcs_cabc_ports = BIT(PORT_C); - break; - default: - case DL_DCS_PORT_A_AND_C: - intel_dsi->dcs_cabc_ports = BIT(PORT_A) | BIT(PORT_C); - break; - } - } else { + else intel_dsi->ports = BIT(port); - intel_dsi->dcs_backlight_ports = BIT(port); - intel_dsi->dcs_cabc_ports = BIT(port); - } - if (!dev_priv->vbt.dsi.config->cabc_supported) - intel_dsi->dcs_cabc_ports = 0; + intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports; + intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports; /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { -- cgit v1.2.3 From 66b83a4cdd3b73effdc285d1d66763c69ffe2ee8 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Mon, 9 Oct 2017 14:26:56 +0200 Subject: binder: call poll_wait() unconditionally. Because we're not guaranteed that subsequent calls to poll() will have a poll_table_struct parameter with _qproc set. When _qproc is not set, poll_wait() is a noop, and we won't be woken up correctly. Signed-off-by: Martijn Coenen Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 0621a95b8597..fddf76ef5bd6 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3662,12 +3662,6 @@ static void binder_stat_br(struct binder_proc *proc, } } -static int binder_has_thread_work(struct binder_thread *thread) -{ - return !binder_worklist_empty(thread->proc, &thread->todo) || - thread->looper_need_return; -} - static int binder_put_node_cmd(struct binder_proc *proc, struct binder_thread *thread, void __user **ptrp, @@ -4297,12 +4291,9 @@ static unsigned int binder_poll(struct file *filp, binder_inner_proc_unlock(thread->proc); - if (binder_has_work(thread, wait_for_proc_work)) - return POLLIN; - poll_wait(filp, &thread->wait, wait); - if (binder_has_thread_work(thread)) + if (binder_has_work(thread, wait_for_proc_work)) return POLLIN; return 0; -- cgit v1.2.3 From eb39a7c0355393c5a8d930f342ad7a6231b552c4 Mon Sep 17 00:00:00 2001 From: David Kozub Date: Thu, 19 Oct 2017 22:57:02 +0200 Subject: clockevents/drivers/cs5535: Improve resilience to spurious interrupts The interrupt handler mfgpt_tick() is not robust versus spurious interrupts which happen before the clock event device is registered and fully initialized. The reason is that the safe guard against spurious interrupts solely checks for the clockevents shutdown state, but lacks a check for detached state. If the interrupt hits while the device is in detached state it passes the safe guard and dereferences the event handler call back which is NULL. Add the missing state check. Fixes: 8f9327cbb6e8 ("clockevents/drivers/cs5535: Migrate to new 'set-state' interface") Suggested-by: Thomas Gleixner Signed-off-by: David Kozub Signed-off-by: Thomas Gleixner Cc: Daniel Lezcano Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20171020093103.3317F6004D@linux.fjfi.cvut.cz --- drivers/clocksource/cs5535-clockevt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index a1df588343f2..1de8cac99a0e 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c @@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) /* Turn off the clock (and clear the event) */ disable_timer(cs5535_event_clock); - if (clockevent_state_shutdown(&cs5535_clockevent)) + if (clockevent_state_detached(&cs5535_clockevent) || + clockevent_state_shutdown(&cs5535_clockevent)) return IRQ_HANDLED; /* Clear the counter */ -- cgit v1.2.3 From 6a341fdff16e13ed1d60dbedca027df3a6a15f9b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Aug 2017 18:08:42 +0200 Subject: gpu: host1x: Use of_device_get_match_data() Avoid some boilerplate by calling of_device_get_match_data() instead of open-coding the equivalent in the driver. While at it, shuffle around some code to avoid unnecessary local variables. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/dev.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 7f22c5c37660..34a3583e4502 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -116,15 +116,16 @@ MODULE_DEVICE_TABLE(of, host1x_of_match); static int host1x_probe(struct platform_device *pdev) { - const struct of_device_id *id; struct host1x *host; struct resource *regs; int syncpt_irq; int err; - id = of_match_device(host1x_of_match, &pdev->dev); - if (!id) - return -EINVAL; + host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); + if (!host) + return -ENOMEM; + + host->info = of_device_get_match_data(&pdev->dev); regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) { @@ -138,15 +139,10 @@ static int host1x_probe(struct platform_device *pdev) return syncpt_irq; } - host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); - if (!host) - return -ENOMEM; - mutex_init(&host->devices_lock); INIT_LIST_HEAD(&host->devices); INIT_LIST_HEAD(&host->list); host->dev = &pdev->dev; - host->info = id->data; /* set common host1x device data */ platform_set_drvdata(pdev, host); -- cgit v1.2.3 From 617dd7cc490b72345277e2666c8ed34d4f47f0da Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 30 Aug 2017 12:48:31 +0200 Subject: gpu: host1x: syncpt: Request syncpoints per client Rather than request syncpoints for a struct device *, request them for a struct host1x_client *. This is important because subsequent patches are going to break the assumption that host1x will always be the parent for devices requesting a syncpoint. It's also a more natural choice because host1x clients are really the only ones that will know how to deal with syncpoints. Note that host1x clients are always guaranteed to be children of host1x, regardless of their location in the device tree. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 2 +- drivers/gpu/drm/tegra/gr2d.c | 2 +- drivers/gpu/drm/tegra/gr3d.c | 2 +- drivers/gpu/drm/tegra/vic.c | 2 +- drivers/gpu/host1x/syncpt.c | 16 ++++++++-------- drivers/gpu/host1x/syncpt.h | 2 +- include/linux/host1x.h | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 4df39112e38e..bc51eb855bf1 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1756,7 +1756,7 @@ static int tegra_dc_init(struct host1x_client *client) struct drm_plane *cursor = NULL; int err; - dc->syncpt = host1x_syncpt_request(dc->dev, flags); + dc->syncpt = host1x_syncpt_request(client, flags); if (!dc->syncpt) dev_warn(dc->dev, "failed to allocate syncpoint\n"); diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c index 6ea070da7718..9a8ea93016a9 100644 --- a/drivers/gpu/drm/tegra/gr2d.c +++ b/drivers/gpu/drm/tegra/gr2d.c @@ -36,7 +36,7 @@ static int gr2d_init(struct host1x_client *client) if (!gr2d->channel) return -ENOMEM; - client->syncpts[0] = host1x_syncpt_request(client->dev, flags); + client->syncpts[0] = host1x_syncpt_request(client, flags); if (!client->syncpts[0]) { host1x_channel_put(gr2d->channel); return -ENOMEM; diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index cee2ab645cde..28c4ef63065b 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -46,7 +46,7 @@ static int gr3d_init(struct host1x_client *client) if (!gr3d->channel) return -ENOMEM; - client->syncpts[0] = host1x_syncpt_request(client->dev, flags); + client->syncpts[0] = host1x_syncpt_request(client, flags); if (!client->syncpts[0]) { host1x_channel_put(gr3d->channel); return -ENOMEM; diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 2448229fa653..52899fba15e6 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -167,7 +167,7 @@ static int vic_init(struct host1x_client *client) goto detach_device; } - client->syncpts[0] = host1x_syncpt_request(client->dev, 0); + client->syncpts[0] = host1x_syncpt_request(client, 0); if (!client->syncpts[0]) { err = -ENOMEM; goto free_channel; diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c index 048ac9e344ce..fcba94cbf4ed 100644 --- a/drivers/gpu/host1x/syncpt.c +++ b/drivers/gpu/host1x/syncpt.c @@ -54,7 +54,7 @@ static void host1x_syncpt_base_free(struct host1x_syncpt_base *base) } static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, - struct device *dev, + struct host1x_client *client, unsigned long flags) { int i; @@ -76,11 +76,11 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, } name = kasprintf(GFP_KERNEL, "%02u-%s", sp->id, - dev ? dev_name(dev) : NULL); + client ? dev_name(client->dev) : NULL); if (!name) goto free_base; - sp->dev = dev; + sp->client = client; sp->name = name; if (flags & HOST1X_SYNCPT_CLIENT_MANAGED) @@ -419,7 +419,7 @@ int host1x_syncpt_init(struct host1x *host) /** * host1x_syncpt_request() - request a syncpoint - * @dev: device requesting the syncpoint + * @client: client requesting the syncpoint * @flags: flags * * host1x client drivers can use this function to allocate a syncpoint for @@ -427,12 +427,12 @@ int host1x_syncpt_init(struct host1x *host) * use by the client exclusively. When no longer using a syncpoint, a host1x * client driver needs to release it using host1x_syncpt_free(). */ -struct host1x_syncpt *host1x_syncpt_request(struct device *dev, +struct host1x_syncpt *host1x_syncpt_request(struct host1x_client *client, unsigned long flags) { - struct host1x *host = dev_get_drvdata(dev->parent); + struct host1x *host = dev_get_drvdata(client->parent->parent); - return host1x_syncpt_alloc(host, dev, flags); + return host1x_syncpt_alloc(host, client, flags); } EXPORT_SYMBOL(host1x_syncpt_request); @@ -456,7 +456,7 @@ void host1x_syncpt_free(struct host1x_syncpt *sp) host1x_syncpt_base_free(sp->base); kfree(sp->name); sp->base = NULL; - sp->dev = NULL; + sp->client = NULL; sp->name = NULL; sp->client_managed = false; diff --git a/drivers/gpu/host1x/syncpt.h b/drivers/gpu/host1x/syncpt.h index f719205105ac..9d88d37c2397 100644 --- a/drivers/gpu/host1x/syncpt.h +++ b/drivers/gpu/host1x/syncpt.h @@ -44,7 +44,7 @@ struct host1x_syncpt { const char *name; bool client_managed; struct host1x *host; - struct device *dev; + struct host1x_client *client; struct host1x_syncpt_base *base; /* interrupt data */ diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 630b1a98ab58..ddf7f9ca86cc 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -157,7 +157,7 @@ int host1x_syncpt_incr(struct host1x_syncpt *sp); u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs); int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout, u32 *value); -struct host1x_syncpt *host1x_syncpt_request(struct device *dev, +struct host1x_syncpt *host1x_syncpt_request(struct host1x_client *client, unsigned long flags); void host1x_syncpt_free(struct host1x_syncpt *sp); -- cgit v1.2.3 From f1b53c4e2c08cbd805a2fdede0026edb30b59602 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 5 Sep 2017 11:43:05 +0300 Subject: gpu: host1x: Add Tegra186 support Add support for the implementation of Host1x present on the Tegra186. The register space has been shuffled around a little bit, requiring addition of some chip-specific code sections. Tegra186 also adds several new features, most importantly the hypervisor, but those are not yet supported with this commit. Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/host1x/Makefile | 3 +- drivers/gpu/host1x/dev.c | 55 +++++++- drivers/gpu/host1x/dev.h | 4 + drivers/gpu/host1x/hw/cdma_hw.c | 49 ++++--- drivers/gpu/host1x/hw/debug_hw.c | 137 +------------------ drivers/gpu/host1x/hw/debug_hw_1x01.c | 154 +++++++++++++++++++++ drivers/gpu/host1x/hw/debug_hw_1x06.c | 133 ++++++++++++++++++ drivers/gpu/host1x/hw/host1x01.c | 2 + drivers/gpu/host1x/hw/host1x02.c | 2 + drivers/gpu/host1x/hw/host1x04.c | 2 + drivers/gpu/host1x/hw/host1x05.c | 2 + drivers/gpu/host1x/hw/host1x06.c | 44 ++++++ drivers/gpu/host1x/hw/host1x06.h | 26 ++++ drivers/gpu/host1x/hw/host1x06_hardware.h | 142 +++++++++++++++++++ drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h | 32 +++++ drivers/gpu/host1x/hw/hw_host1x06_uclass.h | 181 +++++++++++++++++++++++++ drivers/gpu/host1x/hw/hw_host1x06_vm.h | 47 +++++++ drivers/gpu/host1x/hw/intr_hw.c | 29 ++-- 18 files changed, 876 insertions(+), 168 deletions(-) create mode 100644 drivers/gpu/host1x/hw/debug_hw_1x01.c create mode 100644 drivers/gpu/host1x/hw/debug_hw_1x06.c create mode 100644 drivers/gpu/host1x/hw/host1x06.c create mode 100644 drivers/gpu/host1x/hw/host1x06.h create mode 100644 drivers/gpu/host1x/hw/host1x06_hardware.h create mode 100644 drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h create mode 100644 drivers/gpu/host1x/hw/hw_host1x06_uclass.h create mode 100644 drivers/gpu/host1x/hw/hw_host1x06_vm.h (limited to 'drivers') diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile index a1d9974cfcb5..4fb61bd57aee 100644 --- a/drivers/gpu/host1x/Makefile +++ b/drivers/gpu/host1x/Makefile @@ -11,6 +11,7 @@ host1x-y = \ hw/host1x01.o \ hw/host1x02.o \ hw/host1x04.o \ - hw/host1x05.o + hw/host1x05.o \ + hw/host1x06.o obj-$(CONFIG_TEGRA_HOST1X) += host1x.o diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 34a3583e4502..773d6337aa30 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -39,6 +39,17 @@ #include "hw/host1x02.h" #include "hw/host1x04.h" #include "hw/host1x05.h" +#include "hw/host1x06.h" + +void host1x_hypervisor_writel(struct host1x *host1x, u32 v, u32 r) +{ + writel(v, host1x->hv_regs + r); +} + +u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r) +{ + return readl(host1x->hv_regs + r); +} void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r) { @@ -104,7 +115,19 @@ static const struct host1x_info host1x05_info = { .dma_mask = DMA_BIT_MASK(34), }; +static const struct host1x_info host1x06_info = { + .nb_channels = 63, + .nb_pts = 576, + .nb_mlocks = 24, + .nb_bases = 16, + .init = host1x06_init, + .sync_offset = 0x0, + .dma_mask = DMA_BIT_MASK(34), + .has_hypervisor = true, +}; + static const struct of_device_id host1x_of_match[] = { + { .compatible = "nvidia,tegra186-host1x", .data = &host1x06_info, }, { .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, }, { .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, }, { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, }, @@ -117,7 +140,7 @@ MODULE_DEVICE_TABLE(of, host1x_of_match); static int host1x_probe(struct platform_device *pdev) { struct host1x *host; - struct resource *regs; + struct resource *regs, *hv_regs = NULL; int syncpt_irq; int err; @@ -127,10 +150,26 @@ static int host1x_probe(struct platform_device *pdev) host->info = of_device_get_match_data(&pdev->dev); - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "failed to get registers\n"); - return -ENXIO; + if (host->info->has_hypervisor) { + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vm"); + if (!regs) { + dev_err(&pdev->dev, "failed to get vm registers\n"); + return -ENXIO; + } + + hv_regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "hypervisor"); + if (!hv_regs) { + dev_err(&pdev->dev, + "failed to get hypervisor registers\n"); + return -ENXIO; + } + } else { + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "failed to get registers\n"); + return -ENXIO; + } } syncpt_irq = platform_get_irq(pdev, 0); @@ -151,6 +190,12 @@ static int host1x_probe(struct platform_device *pdev) if (IS_ERR(host->regs)) return PTR_ERR(host->regs); + if (host->info->has_hypervisor) { + host->hv_regs = devm_ioremap_resource(&pdev->dev, hv_regs); + if (IS_ERR(host->hv_regs)) + return PTR_ERR(host->hv_regs); + } + dma_set_mask_and_coherent(host->dev, host->info->dma_mask); if (host->info->init) { diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h index ffdbc15b749b..def802c0a6bf 100644 --- a/drivers/gpu/host1x/dev.h +++ b/drivers/gpu/host1x/dev.h @@ -100,12 +100,14 @@ struct host1x_info { int (*init)(struct host1x *host1x); /* initialize per SoC ops */ unsigned int sync_offset; /* offset of syncpoint registers */ u64 dma_mask; /* mask of addressable memory */ + bool has_hypervisor; /* has hypervisor registers */ }; struct host1x { const struct host1x_info *info; void __iomem *regs; + void __iomem *hv_regs; /* hypervisor region */ struct host1x_syncpt *syncpt; struct host1x_syncpt_base *bases; struct device *dev; @@ -140,6 +142,8 @@ struct host1x { struct list_head list; }; +void host1x_hypervisor_writel(struct host1x *host1x, u32 r, u32 v); +u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r); void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v); u32 host1x_sync_readl(struct host1x *host1x, u32 r); void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v); diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c index 6b231119193e..ce320534cbed 100644 --- a/drivers/gpu/host1x/hw/cdma_hw.c +++ b/drivers/gpu/host1x/hw/cdma_hw.c @@ -172,6 +172,30 @@ static void cdma_stop(struct host1x_cdma *cdma) mutex_unlock(&cdma->lock); } +static void cdma_hw_cmdproc_stop(struct host1x *host, struct host1x_channel *ch, + bool stop) +{ +#if HOST1X_HW >= 6 + host1x_ch_writel(ch, stop ? 0x1 : 0x0, HOST1X_CHANNEL_CMDPROC_STOP); +#else + u32 cmdproc_stop = host1x_sync_readl(host, HOST1X_SYNC_CMDPROC_STOP); + if (stop) + cmdproc_stop |= BIT(ch->id); + else + cmdproc_stop &= ~BIT(ch->id); + host1x_sync_writel(host, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP); +#endif +} + +static void cdma_hw_teardown(struct host1x *host, struct host1x_channel *ch) +{ +#if HOST1X_HW >= 6 + host1x_ch_writel(ch, 0x1, HOST1X_CHANNEL_TEARDOWN); +#else + host1x_sync_writel(host, BIT(ch->id), HOST1X_SYNC_CH_TEARDOWN); +#endif +} + /* * Stops both channel's command processor and CDMA immediately. * Also, tears down the channel and resets corresponding module. @@ -180,7 +204,6 @@ static void cdma_freeze(struct host1x_cdma *cdma) { struct host1x *host = cdma_to_host1x(cdma); struct host1x_channel *ch = cdma_to_channel(cdma); - u32 cmdproc_stop; if (cdma->torndown && !cdma->running) { dev_warn(host->dev, "Already torn down\n"); @@ -189,9 +212,7 @@ static void cdma_freeze(struct host1x_cdma *cdma) dev_dbg(host->dev, "freezing channel (id %d)\n", ch->id); - cmdproc_stop = host1x_sync_readl(host, HOST1X_SYNC_CMDPROC_STOP); - cmdproc_stop |= BIT(ch->id); - host1x_sync_writel(host, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP); + cdma_hw_cmdproc_stop(host, ch, true); dev_dbg(host->dev, "%s: DMA GET 0x%x, PUT HW 0x%x / shadow 0x%x\n", __func__, host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET), @@ -201,7 +222,7 @@ static void cdma_freeze(struct host1x_cdma *cdma) host1x_ch_writel(ch, HOST1X_CHANNEL_DMACTRL_DMASTOP, HOST1X_CHANNEL_DMACTRL); - host1x_sync_writel(host, BIT(ch->id), HOST1X_SYNC_CH_TEARDOWN); + cdma_hw_teardown(host, ch); cdma->running = false; cdma->torndown = true; @@ -211,15 +232,12 @@ static void cdma_resume(struct host1x_cdma *cdma, u32 getptr) { struct host1x *host1x = cdma_to_host1x(cdma); struct host1x_channel *ch = cdma_to_channel(cdma); - u32 cmdproc_stop; dev_dbg(host1x->dev, "resuming channel (id %u, DMAGET restart = 0x%x)\n", ch->id, getptr); - cmdproc_stop = host1x_sync_readl(host1x, HOST1X_SYNC_CMDPROC_STOP); - cmdproc_stop &= ~BIT(ch->id); - host1x_sync_writel(host1x, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP); + cdma_hw_cmdproc_stop(host1x, ch, false); cdma->torndown = false; cdma_timeout_restart(cdma, getptr); @@ -232,7 +250,7 @@ static void cdma_resume(struct host1x_cdma *cdma, u32 getptr) */ static void cdma_timeout_handler(struct work_struct *work) { - u32 prev_cmdproc, cmdproc_stop, syncpt_val; + u32 syncpt_val; struct host1x_cdma *cdma; struct host1x *host1x; struct host1x_channel *ch; @@ -254,12 +272,7 @@ static void cdma_timeout_handler(struct work_struct *work) } /* stop processing to get a clean snapshot */ - prev_cmdproc = host1x_sync_readl(host1x, HOST1X_SYNC_CMDPROC_STOP); - cmdproc_stop = prev_cmdproc | BIT(ch->id); - host1x_sync_writel(host1x, cmdproc_stop, HOST1X_SYNC_CMDPROC_STOP); - - dev_dbg(host1x->dev, "cdma_timeout: cmdproc was 0x%x is 0x%x\n", - prev_cmdproc, cmdproc_stop); + cdma_hw_cmdproc_stop(host1x, ch, true); syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt); @@ -268,9 +281,7 @@ static void cdma_timeout_handler(struct work_struct *work) dev_dbg(host1x->dev, "cdma_timeout: expired, but buffer had completed\n"); /* restore */ - cmdproc_stop = prev_cmdproc & ~(BIT(ch->id)); - host1x_sync_writel(host1x, cmdproc_stop, - HOST1X_SYNC_CMDPROC_STOP); + cdma_hw_cmdproc_stop(host1x, ch, false); mutex_unlock(&cdma->lock); return; } diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c index 7a4a3286e4a7..770d92e62d69 100644 --- a/drivers/gpu/host1x/hw/debug_hw.c +++ b/drivers/gpu/host1x/hw/debug_hw.c @@ -174,138 +174,11 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma) } } -static void host1x_debug_show_channel_cdma(struct host1x *host, - struct host1x_channel *ch, - struct output *o) -{ - struct host1x_cdma *cdma = &ch->cdma; - u32 dmaput, dmaget, dmactrl; - u32 cbstat, cbread; - u32 val, base, baseval; - - dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT); - dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET); - dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL); - cbread = host1x_sync_readl(host, HOST1X_SYNC_CBREAD(ch->id)); - cbstat = host1x_sync_readl(host, HOST1X_SYNC_CBSTAT(ch->id)); - - host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev)); - - if (HOST1X_CHANNEL_DMACTRL_DMASTOP_V(dmactrl) || - !ch->cdma.push_buffer.mapped) { - host1x_debug_output(o, "inactive\n\n"); - return; - } - - if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == HOST1X_CLASS_HOST1X && - HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == - HOST1X_UCLASS_WAIT_SYNCPT) - host1x_debug_output(o, "waiting on syncpt %d val %d\n", - cbread >> 24, cbread & 0xffffff); - else if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == - HOST1X_CLASS_HOST1X && - HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == - HOST1X_UCLASS_WAIT_SYNCPT_BASE) { - base = (cbread >> 16) & 0xff; - baseval = - host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(base)); - val = cbread & 0xffff; - host1x_debug_output(o, "waiting on syncpt %d val %d (base %d = %d; offset = %d)\n", - cbread >> 24, baseval + val, base, - baseval, val); - } else - host1x_debug_output(o, "active class %02x, offset %04x, val %08x\n", - HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat), - HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat), - cbread); - - host1x_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n", - dmaput, dmaget, dmactrl); - host1x_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat); - - show_channel_gathers(o, cdma); - host1x_debug_output(o, "\n"); -} - -static void host1x_debug_show_channel_fifo(struct host1x *host, - struct host1x_channel *ch, - struct output *o) -{ - u32 val, rd_ptr, wr_ptr, start, end; - unsigned int data_count = 0; - - host1x_debug_output(o, "%u: fifo:\n", ch->id); - - val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT); - host1x_debug_output(o, "FIFOSTAT %08x\n", val); - if (HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(val)) { - host1x_debug_output(o, "[empty]\n"); - return; - } - - host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); - host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | - HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id), - HOST1X_SYNC_CFPEEK_CTRL); - - val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_PTRS); - rd_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(val); - wr_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(val); - - val = host1x_sync_readl(host, HOST1X_SYNC_CF_SETUP(ch->id)); - start = HOST1X_SYNC_CF_SETUP_BASE_V(val); - end = HOST1X_SYNC_CF_SETUP_LIMIT_V(val); - - do { - host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); - host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | - HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id) | - HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(rd_ptr), - HOST1X_SYNC_CFPEEK_CTRL); - val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ); - - if (!data_count) { - host1x_debug_output(o, "%08x:", val); - data_count = show_channel_command(o, val); - } else { - host1x_debug_output(o, "%08x%s", val, - data_count > 0 ? ", " : "])\n"); - data_count--; - } - - if (rd_ptr == end) - rd_ptr = start; - else - rd_ptr++; - } while (rd_ptr != wr_ptr); - - if (data_count) - host1x_debug_output(o, ", ...])\n"); - host1x_debug_output(o, "\n"); - - host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); -} - -static void host1x_debug_show_mlocks(struct host1x *host, struct output *o) -{ - unsigned int i; - - host1x_debug_output(o, "---- mlocks ----\n"); - - for (i = 0; i < host1x_syncpt_nb_mlocks(host); i++) { - u32 owner = - host1x_sync_readl(host, HOST1X_SYNC_MLOCK_OWNER(i)); - if (HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(owner)) - host1x_debug_output(o, "%u: locked by channel %u\n", - i, HOST1X_SYNC_MLOCK_OWNER_CHID_V(owner)); - else if (HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(owner)) - host1x_debug_output(o, "%u: locked by cpu\n", i); - else - host1x_debug_output(o, "%u: unlocked\n", i); - } - - host1x_debug_output(o, "\n"); -} +#if HOST1X_HW >= 6 +#include "debug_hw_1x06.c" +#else +#include "debug_hw_1x01.c" +#endif static const struct host1x_debug_ops host1x_debug_ops = { .show_channel_cdma = host1x_debug_show_channel_cdma, diff --git a/drivers/gpu/host1x/hw/debug_hw_1x01.c b/drivers/gpu/host1x/hw/debug_hw_1x01.c new file mode 100644 index 000000000000..8f243903cc7f --- /dev/null +++ b/drivers/gpu/host1x/hw/debug_hw_1x01.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2010 Google, Inc. + * Author: Erik Gilling + * + * Copyright (C) 2011-2013 NVIDIA Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "../dev.h" +#include "../debug.h" +#include "../cdma.h" +#include "../channel.h" + +static void host1x_debug_show_channel_cdma(struct host1x *host, + struct host1x_channel *ch, + struct output *o) +{ + struct host1x_cdma *cdma = &ch->cdma; + u32 dmaput, dmaget, dmactrl; + u32 cbstat, cbread; + u32 val, base, baseval; + + dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT); + dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET); + dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL); + cbread = host1x_sync_readl(host, HOST1X_SYNC_CBREAD(ch->id)); + cbstat = host1x_sync_readl(host, HOST1X_SYNC_CBSTAT(ch->id)); + + host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev)); + + if (HOST1X_CHANNEL_DMACTRL_DMASTOP_V(dmactrl) || + !ch->cdma.push_buffer.mapped) { + host1x_debug_output(o, "inactive\n\n"); + return; + } + + if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == HOST1X_CLASS_HOST1X && + HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == + HOST1X_UCLASS_WAIT_SYNCPT) + host1x_debug_output(o, "waiting on syncpt %d val %d\n", + cbread >> 24, cbread & 0xffffff); + else if (HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat) == + HOST1X_CLASS_HOST1X && + HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat) == + HOST1X_UCLASS_WAIT_SYNCPT_BASE) { + base = (cbread >> 16) & 0xff; + baseval = + host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(base)); + val = cbread & 0xffff; + host1x_debug_output(o, "waiting on syncpt %d val %d (base %d = %d; offset = %d)\n", + cbread >> 24, baseval + val, base, + baseval, val); + } else + host1x_debug_output(o, "active class %02x, offset %04x, val %08x\n", + HOST1X_SYNC_CBSTAT_CBCLASS_V(cbstat), + HOST1X_SYNC_CBSTAT_CBOFFSET_V(cbstat), + cbread); + + host1x_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n", + dmaput, dmaget, dmactrl); + host1x_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat); + + show_channel_gathers(o, cdma); + host1x_debug_output(o, "\n"); +} + +static void host1x_debug_show_channel_fifo(struct host1x *host, + struct host1x_channel *ch, + struct output *o) +{ + u32 val, rd_ptr, wr_ptr, start, end; + unsigned int data_count = 0; + + host1x_debug_output(o, "%u: fifo:\n", ch->id); + + val = host1x_ch_readl(ch, HOST1X_CHANNEL_FIFOSTAT); + host1x_debug_output(o, "FIFOSTAT %08x\n", val); + if (HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(val)) { + host1x_debug_output(o, "[empty]\n"); + return; + } + + host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); + host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | + HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id), + HOST1X_SYNC_CFPEEK_CTRL); + + val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_PTRS); + rd_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(val); + wr_ptr = HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(val); + + val = host1x_sync_readl(host, HOST1X_SYNC_CF_SETUP(ch->id)); + start = HOST1X_SYNC_CF_SETUP_BASE_V(val); + end = HOST1X_SYNC_CF_SETUP_LIMIT_V(val); + + do { + host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); + host1x_sync_writel(host, HOST1X_SYNC_CFPEEK_CTRL_ENA_F(1) | + HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(ch->id) | + HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(rd_ptr), + HOST1X_SYNC_CFPEEK_CTRL); + val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ); + + if (!data_count) { + host1x_debug_output(o, "%08x:", val); + data_count = show_channel_command(o, val); + } else { + host1x_debug_output(o, "%08x%s", val, + data_count > 0 ? ", " : "])\n"); + data_count--; + } + + if (rd_ptr == end) + rd_ptr = start; + else + rd_ptr++; + } while (rd_ptr != wr_ptr); + + if (data_count) + host1x_debug_output(o, ", ...])\n"); + host1x_debug_output(o, "\n"); + + host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); +} + +static void host1x_debug_show_mlocks(struct host1x *host, struct output *o) +{ + unsigned int i; + + host1x_debug_output(o, "---- mlocks ----\n"); + + for (i = 0; i < host1x_syncpt_nb_mlocks(host); i++) { + u32 owner = + host1x_sync_readl(host, HOST1X_SYNC_MLOCK_OWNER(i)); + if (HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(owner)) + host1x_debug_output(o, "%u: locked by channel %u\n", + i, HOST1X_SYNC_MLOCK_OWNER_CHID_V(owner)); + else if (HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(owner)) + host1x_debug_output(o, "%u: locked by cpu\n", i); + else + host1x_debug_output(o, "%u: unlocked\n", i); + } + + host1x_debug_output(o, "\n"); +} diff --git a/drivers/gpu/host1x/hw/debug_hw_1x06.c b/drivers/gpu/host1x/hw/debug_hw_1x06.c new file mode 100644 index 000000000000..9cdee657fb46 --- /dev/null +++ b/drivers/gpu/host1x/hw/debug_hw_1x06.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2010 Google, Inc. + * Author: Erik Gilling + * + * Copyright (C) 2011-2017 NVIDIA Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "../dev.h" +#include "../debug.h" +#include "../cdma.h" +#include "../channel.h" + +static void host1x_debug_show_channel_cdma(struct host1x *host, + struct host1x_channel *ch, + struct output *o) +{ + struct host1x_cdma *cdma = &ch->cdma; + u32 dmaput, dmaget, dmactrl; + u32 offset, class; + u32 ch_stat; + + dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT); + dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET); + dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL); + offset = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_OFFSET); + class = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_CLASS); + ch_stat = host1x_ch_readl(ch, HOST1X_CHANNEL_CHANNELSTAT); + + host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev)); + + if (dmactrl & HOST1X_CHANNEL_DMACTRL_DMASTOP || + !ch->cdma.push_buffer.mapped) { + host1x_debug_output(o, "inactive\n\n"); + return; + } + + if (class == HOST1X_CLASS_HOST1X && offset == HOST1X_UCLASS_WAIT_SYNCPT) + host1x_debug_output(o, "waiting on syncpt\n"); + else + host1x_debug_output(o, "active class %02x, offset %04x\n", + class, offset); + + host1x_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n", + dmaput, dmaget, dmactrl); + host1x_debug_output(o, "CHANNELSTAT %02x\n", ch_stat); + + show_channel_gathers(o, cdma); + host1x_debug_output(o, "\n"); +} + +static void host1x_debug_show_channel_fifo(struct host1x *host, + struct host1x_channel *ch, + struct output *o) +{ + u32 val, rd_ptr, wr_ptr, start, end; + unsigned int data_count = 0; + + host1x_debug_output(o, "%u: fifo:\n", ch->id); + + val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_STAT); + host1x_debug_output(o, "CMDFIFO_STAT %08x\n", val); + if (val & HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY) { + host1x_debug_output(o, "[empty]\n"); + return; + } + + val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_RDATA); + host1x_debug_output(o, "CMDFIFO_RDATA %08x\n", val); + + /* Peek pointer values are invalid during SLCG, so disable it */ + host1x_hypervisor_writel(host, 0x1, HOST1X_HV_ICG_EN_OVERRIDE); + + val = 0; + val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE; + val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id); + host1x_hypervisor_writel(host, val, HOST1X_HV_CMDFIFO_PEEK_CTRL); + + val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_PEEK_PTRS); + rd_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_RD_PTR_V(val); + wr_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_WR_PTR_V(val); + + val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_SETUP(ch->id)); + start = HOST1X_HV_CMDFIFO_SETUP_BASE_V(val); + end = HOST1X_HV_CMDFIFO_SETUP_LIMIT_V(val); + + do { + val = 0; + val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE; + val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id); + val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ADDR(rd_ptr); + host1x_hypervisor_writel(host, val, + HOST1X_HV_CMDFIFO_PEEK_CTRL); + + val = host1x_hypervisor_readl(host, + HOST1X_HV_CMDFIFO_PEEK_READ); + + if (!data_count) { + host1x_debug_output(o, "%08x:", val); + data_count = show_channel_command(o, val); + } else { + host1x_debug_output(o, "%08x%s", val, + data_count > 0 ? ", " : "])\n"); + data_count--; + } + + if (rd_ptr == end) + rd_ptr = start; + else + rd_ptr++; + } while (rd_ptr != wr_ptr); + + if (data_count) + host1x_debug_output(o, ", ...])\n"); + host1x_debug_output(o, "\n"); + + host1x_hypervisor_writel(host, 0x0, HOST1X_HV_CMDFIFO_PEEK_CTRL); + host1x_hypervisor_writel(host, 0x0, HOST1X_HV_ICG_EN_OVERRIDE); +} + +static void host1x_debug_show_mlocks(struct host1x *host, struct output *o) +{ + /* TODO */ +} diff --git a/drivers/gpu/host1x/hw/host1x01.c b/drivers/gpu/host1x/hw/host1x01.c index 859b73beb4d0..bb124f8b4af8 100644 --- a/drivers/gpu/host1x/hw/host1x01.c +++ b/drivers/gpu/host1x/hw/host1x01.c @@ -21,6 +21,8 @@ #include "host1x01_hardware.h" /* include code */ +#define HOST1X_HW 1 + #include "cdma_hw.c" #include "channel_hw.c" #include "debug_hw.c" diff --git a/drivers/gpu/host1x/hw/host1x02.c b/drivers/gpu/host1x/hw/host1x02.c index 928946c2144b..c5f85dbedb98 100644 --- a/drivers/gpu/host1x/hw/host1x02.c +++ b/drivers/gpu/host1x/hw/host1x02.c @@ -21,6 +21,8 @@ #include "host1x02_hardware.h" /* include code */ +#define HOST1X_HW 2 + #include "cdma_hw.c" #include "channel_hw.c" #include "debug_hw.c" diff --git a/drivers/gpu/host1x/hw/host1x04.c b/drivers/gpu/host1x/hw/host1x04.c index 8007c70fa9c4..f102a1a7743f 100644 --- a/drivers/gpu/host1x/hw/host1x04.c +++ b/drivers/gpu/host1x/hw/host1x04.c @@ -21,6 +21,8 @@ #include "host1x04_hardware.h" /* include code */ +#define HOST1X_HW 4 + #include "cdma_hw.c" #include "channel_hw.c" #include "debug_hw.c" diff --git a/drivers/gpu/host1x/hw/host1x05.c b/drivers/gpu/host1x/hw/host1x05.c index 047097ce3bad..2b1239d6ec67 100644 --- a/drivers/gpu/host1x/hw/host1x05.c +++ b/drivers/gpu/host1x/hw/host1x05.c @@ -21,6 +21,8 @@ #include "host1x05_hardware.h" /* include code */ +#define HOST1X_HW 5 + #include "cdma_hw.c" #include "channel_hw.c" #include "debug_hw.c" diff --git a/drivers/gpu/host1x/hw/host1x06.c b/drivers/gpu/host1x/hw/host1x06.c new file mode 100644 index 000000000000..a66230827c59 --- /dev/null +++ b/drivers/gpu/host1x/hw/host1x06.c @@ -0,0 +1,44 @@ +/* + * Host1x init for Tegra186 SoCs + * + * Copyright (c) 2017 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* include hw specification */ +#include "host1x06.h" +#include "host1x06_hardware.h" + +/* include code */ +#define HOST1X_HW 6 + +#include "cdma_hw.c" +#include "channel_hw.c" +#include "debug_hw.c" +#include "intr_hw.c" +#include "syncpt_hw.c" + +#include "../dev.h" + +int host1x06_init(struct host1x *host) +{ + host->channel_op = &host1x_channel_ops; + host->cdma_op = &host1x_cdma_ops; + host->cdma_pb_op = &host1x_pushbuffer_ops; + host->syncpt_op = &host1x_syncpt_ops; + host->intr_op = &host1x_intr_ops; + host->debug_op = &host1x_debug_ops; + + return 0; +} diff --git a/drivers/gpu/host1x/hw/host1x06.h b/drivers/gpu/host1x/hw/host1x06.h new file mode 100644 index 000000000000..d9abe1489241 --- /dev/null +++ b/drivers/gpu/host1x/hw/host1x06.h @@ -0,0 +1,26 @@ +/* + * Host1x init for Tegra186 SoCs + * + * Copyright (c) 2017 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HOST1X_HOST1X06_H +#define HOST1X_HOST1X06_H + +struct host1x; + +int host1x06_init(struct host1x *host); + +#endif diff --git a/drivers/gpu/host1x/hw/host1x06_hardware.h b/drivers/gpu/host1x/hw/host1x06_hardware.h new file mode 100644 index 000000000000..3039c92ea605 --- /dev/null +++ b/drivers/gpu/host1x/hw/host1x06_hardware.h @@ -0,0 +1,142 @@ +/* + * Tegra host1x Register Offsets for Tegra186 + * + * Copyright (c) 2017 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __HOST1X_HOST1X06_HARDWARE_H +#define __HOST1X_HOST1X06_HARDWARE_H + +#include +#include + +#include "hw_host1x06_uclass.h" +#include "hw_host1x06_vm.h" +#include "hw_host1x06_hypervisor.h" + +static inline u32 host1x_class_host_wait_syncpt( + unsigned indx, unsigned threshold) +{ + return host1x_uclass_wait_syncpt_indx_f(indx) + | host1x_uclass_wait_syncpt_thresh_f(threshold); +} + +static inline u32 host1x_class_host_load_syncpt_base( + unsigned indx, unsigned threshold) +{ + return host1x_uclass_load_syncpt_base_base_indx_f(indx) + | host1x_uclass_load_syncpt_base_value_f(threshold); +} + +static inline u32 host1x_class_host_wait_syncpt_base( + unsigned indx, unsigned base_indx, unsigned offset) +{ + return host1x_uclass_wait_syncpt_base_indx_f(indx) + | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx) + | host1x_uclass_wait_syncpt_base_offset_f(offset); +} + +static inline u32 host1x_class_host_incr_syncpt_base( + unsigned base_indx, unsigned offset) +{ + return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx) + | host1x_uclass_incr_syncpt_base_offset_f(offset); +} + +static inline u32 host1x_class_host_incr_syncpt( + unsigned cond, unsigned indx) +{ + return host1x_uclass_incr_syncpt_cond_f(cond) + | host1x_uclass_incr_syncpt_indx_f(indx); +} + +static inline u32 host1x_class_host_indoff_reg_write( + unsigned mod_id, unsigned offset, bool auto_inc) +{ + u32 v = host1x_uclass_indoff_indbe_f(0xf) + | host1x_uclass_indoff_indmodid_f(mod_id) + | host1x_uclass_indoff_indroffset_f(offset); + if (auto_inc) + v |= host1x_uclass_indoff_autoinc_f(1); + return v; +} + +static inline u32 host1x_class_host_indoff_reg_read( + unsigned mod_id, unsigned offset, bool auto_inc) +{ + u32 v = host1x_uclass_indoff_indmodid_f(mod_id) + | host1x_uclass_indoff_indroffset_f(offset) + | host1x_uclass_indoff_rwn_read_v(); + if (auto_inc) + v |= host1x_uclass_indoff_autoinc_f(1); + return v; +} + +/* cdma opcodes */ +static inline u32 host1x_opcode_setclass( + unsigned class_id, unsigned offset, unsigned mask) +{ + return (0 << 28) | (offset << 16) | (class_id << 6) | mask; +} + +static inline u32 host1x_opcode_incr(unsigned offset, unsigned count) +{ + return (1 << 28) | (offset << 16) | count; +} + +static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count) +{ + return (2 << 28) | (offset << 16) | count; +} + +static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask) +{ + return (3 << 28) | (offset << 16) | mask; +} + +static inline u32 host1x_opcode_imm(unsigned offset, unsigned value) +{ + return (4 << 28) | (offset << 16) | value; +} + +static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx) +{ + return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(), + host1x_class_host_incr_syncpt(cond, indx)); +} + +static inline u32 host1x_opcode_restart(unsigned address) +{ + return (5 << 28) | (address >> 4); +} + +static inline u32 host1x_opcode_gather(unsigned count) +{ + return (6 << 28) | count; +} + +static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count) +{ + return (6 << 28) | (offset << 16) | BIT(15) | count; +} + +static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count) +{ + return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count; +} + +#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0) + +#endif diff --git a/drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h b/drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h new file mode 100644 index 000000000000..c05dab8a178b --- /dev/null +++ b/drivers/gpu/host1x/hw/hw_host1x06_hypervisor.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#define HOST1X_HV_SYNCPT_PROT_EN 0x1ac4 +#define HOST1X_HV_SYNCPT_PROT_EN_CH_EN BIT(1) +#define HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(x) (0x2020 + (x * 4)) +#define HOST1X_HV_CMDFIFO_PEEK_CTRL 0x233c +#define HOST1X_HV_CMDFIFO_PEEK_CTRL_ADDR(x) (x) +#define HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(x) ((x) << 16) +#define HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE BIT(31) +#define HOST1X_HV_CMDFIFO_PEEK_READ 0x2340 +#define HOST1X_HV_CMDFIFO_PEEK_PTRS 0x2344 +#define HOST1X_HV_CMDFIFO_PEEK_PTRS_WR_PTR_V(x) (((x) >> 16) & 0xfff) +#define HOST1X_HV_CMDFIFO_PEEK_PTRS_RD_PTR_V(x) ((x) & 0xfff) +#define HOST1X_HV_CMDFIFO_SETUP(x) (0x2588 + (x * 4)) +#define HOST1X_HV_CMDFIFO_SETUP_LIMIT_V(x) (((x) >> 16) & 0xfff) +#define HOST1X_HV_CMDFIFO_SETUP_BASE_V(x) ((x) & 0xfff) +#define HOST1X_HV_ICG_EN_OVERRIDE 0x2aa8 diff --git a/drivers/gpu/host1x/hw/hw_host1x06_uclass.h b/drivers/gpu/host1x/hw/hw_host1x06_uclass.h new file mode 100644 index 000000000000..4457486c72b0 --- /dev/null +++ b/drivers/gpu/host1x/hw/hw_host1x06_uclass.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2017 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + /* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ + +#ifndef HOST1X_HW_HOST1X06_UCLASS_H +#define HOST1X_HW_HOST1X06_UCLASS_H + +static inline u32 host1x_uclass_incr_syncpt_r(void) +{ + return 0x0; +} +#define HOST1X_UCLASS_INCR_SYNCPT \ + host1x_uclass_incr_syncpt_r() +static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v) +{ + return (v & 0xff) << 8; +} +#define HOST1X_UCLASS_INCR_SYNCPT_COND_F(v) \ + host1x_uclass_incr_syncpt_cond_f(v) +static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v) +{ + return (v & 0xff) << 0; +} +#define HOST1X_UCLASS_INCR_SYNCPT_INDX_F(v) \ + host1x_uclass_incr_syncpt_indx_f(v) +static inline u32 host1x_uclass_wait_syncpt_r(void) +{ + return 0x8; +} +#define HOST1X_UCLASS_WAIT_SYNCPT \ + host1x_uclass_wait_syncpt_r() +static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v) +{ + return (v & 0xff) << 24; +} +#define HOST1X_UCLASS_WAIT_SYNCPT_INDX_F(v) \ + host1x_uclass_wait_syncpt_indx_f(v) +static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v) +{ + return (v & 0xffffff) << 0; +} +#define HOST1X_UCLASS_WAIT_SYNCPT_THRESH_F(v) \ + host1x_uclass_wait_syncpt_thresh_f(v) +static inline u32 host1x_uclass_wait_syncpt_base_r(void) +{ + return 0x9; +} +#define HOST1X_UCLASS_WAIT_SYNCPT_BASE \ + host1x_uclass_wait_syncpt_base_r() +static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v) +{ + return (v & 0xff) << 24; +} +#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_INDX_F(v) \ + host1x_uclass_wait_syncpt_base_indx_f(v) +static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v) +{ + return (v & 0xff) << 16; +} +#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_BASE_INDX_F(v) \ + host1x_uclass_wait_syncpt_base_base_indx_f(v) +static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v) +{ + return (v & 0xffff) << 0; +} +#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \ + host1x_uclass_wait_syncpt_base_offset_f(v) +static inline u32 host1x_uclass_load_syncpt_base_r(void) +{ + return 0xb; +} +#define HOST1X_UCLASS_LOAD_SYNCPT_BASE \ + host1x_uclass_load_syncpt_base_r() +static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v) +{ + return (v & 0xff) << 24; +} +#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(v) \ + host1x_uclass_load_syncpt_base_base_indx_f(v) +static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v) +{ + return (v & 0xffffff) << 0; +} +#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(v) \ + host1x_uclass_load_syncpt_base_value_f(v) +static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v) +{ + return (v & 0xff) << 24; +} +#define HOST1X_UCLASS_INCR_SYNCPT_BASE_BASE_INDX_F(v) \ + host1x_uclass_incr_syncpt_base_base_indx_f(v) +static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v) +{ + return (v & 0xffffff) << 0; +} +#define HOST1X_UCLASS_INCR_SYNCPT_BASE_OFFSET_F(v) \ + host1x_uclass_incr_syncpt_base_offset_f(v) +static inline u32 host1x_uclass_indoff_r(void) +{ + return 0x2d; +} +#define HOST1X_UCLASS_INDOFF \ + host1x_uclass_indoff_r() +static inline u32 host1x_uclass_indoff_indbe_f(u32 v) +{ + return (v & 0xf) << 28; +} +#define HOST1X_UCLASS_INDOFF_INDBE_F(v) \ + host1x_uclass_indoff_indbe_f(v) +static inline u32 host1x_uclass_indoff_autoinc_f(u32 v) +{ + return (v & 0x1) << 27; +} +#define HOST1X_UCLASS_INDOFF_AUTOINC_F(v) \ + host1x_uclass_indoff_autoinc_f(v) +static inline u32 host1x_uclass_indoff_indmodid_f(u32 v) +{ + return (v & 0xff) << 18; +} +#define HOST1X_UCLASS_INDOFF_INDMODID_F(v) \ + host1x_uclass_indoff_indmodid_f(v) +static inline u32 host1x_uclass_indoff_indroffset_f(u32 v) +{ + return (v & 0xffff) << 2; +} +#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \ + host1x_uclass_indoff_indroffset_f(v) +static inline u32 host1x_uclass_indoff_rwn_read_v(void) +{ + return 1; +} +#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \ + host1x_uclass_indoff_indroffset_f(v) + +#endif diff --git a/drivers/gpu/host1x/hw/hw_host1x06_vm.h b/drivers/gpu/host1x/hw/hw_host1x06_vm.h new file mode 100644 index 000000000000..e54b33902332 --- /dev/null +++ b/drivers/gpu/host1x/hw/hw_host1x06_vm.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#define HOST1X_CHANNEL_DMASTART 0x0000 +#define HOST1X_CHANNEL_DMASTART_HI 0x0004 +#define HOST1X_CHANNEL_DMAPUT 0x0008 +#define HOST1X_CHANNEL_DMAPUT_HI 0x000c +#define HOST1X_CHANNEL_DMAGET 0x0010 +#define HOST1X_CHANNEL_DMAGET_HI 0x0014 +#define HOST1X_CHANNEL_DMAEND 0x0018 +#define HOST1X_CHANNEL_DMAEND_HI 0x001c +#define HOST1X_CHANNEL_DMACTRL 0x0020 +#define HOST1X_CHANNEL_DMACTRL_DMASTOP BIT(0) +#define HOST1X_CHANNEL_DMACTRL_DMAGETRST BIT(1) +#define HOST1X_CHANNEL_DMACTRL_DMAINITGET BIT(2) +#define HOST1X_CHANNEL_CMDFIFO_STAT 0x0024 +#define HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY BIT(13) +#define HOST1X_CHANNEL_CMDFIFO_RDATA 0x0028 +#define HOST1X_CHANNEL_CMDP_OFFSET 0x0030 +#define HOST1X_CHANNEL_CMDP_CLASS 0x0034 +#define HOST1X_CHANNEL_CHANNELSTAT 0x0038 +#define HOST1X_CHANNEL_CMDPROC_STOP 0x0048 +#define HOST1X_CHANNEL_TEARDOWN 0x004c + +#define HOST1X_SYNC_SYNCPT_CPU_INCR(x) (0x6400 + 4*(x)) +#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(x) (0x6464 + 4*(x)) +#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(x) (0x652c + 4*(x)) +#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(x) (0x6590 + 4*(x)) +#define HOST1X_SYNC_SYNCPT_BASE(x) (0x8000 + 4*(x)) +#define HOST1X_SYNC_SYNCPT(x) (0x8080 + 4*(x)) +#define HOST1X_SYNC_SYNCPT_INT_THRESH(x) (0x8a00 + 4*(x)) +#define HOST1X_SYNC_SYNCPT_CH_APP(x) (0x9384 + 4*(x)) +#define HOST1X_SYNC_SYNCPT_CH_APP_CH(v) (((v) & 0x3f) << 8) diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c index 37ebb51703fa..329239237090 100644 --- a/drivers/gpu/host1x/hw/intr_hw.c +++ b/drivers/gpu/host1x/hw/intr_hw.c @@ -72,6 +72,23 @@ static void _host1x_intr_disable_all_syncpt_intrs(struct host1x *host) } } +static void intr_hw_init(struct host1x *host, u32 cpm) +{ +#if HOST1X_HW < 6 + /* disable the ip_busy_timeout. this prevents write drops */ + host1x_sync_writel(host, 0, HOST1X_SYNC_IP_BUSY_TIMEOUT); + + /* + * increase the auto-ack timout to the maximum value. 2d will hang + * otherwise on Tegra2. + */ + host1x_sync_writel(host, 0xff, HOST1X_SYNC_CTXSW_TIMEOUT_CFG); + + /* update host clocks per usec */ + host1x_sync_writel(host, cpm, HOST1X_SYNC_USEC_CLK); +#endif +} + static int _host1x_intr_init_host_sync(struct host1x *host, u32 cpm, void (*syncpt_thresh_work)(struct work_struct *)) @@ -92,17 +109,7 @@ _host1x_intr_init_host_sync(struct host1x *host, u32 cpm, return err; } - /* disable the ip_busy_timeout. this prevents write drops */ - host1x_sync_writel(host, 0, HOST1X_SYNC_IP_BUSY_TIMEOUT); - - /* - * increase the auto-ack timout to the maximum value. 2d will hang - * otherwise on Tegra2. - */ - host1x_sync_writel(host, 0xff, HOST1X_SYNC_CTXSW_TIMEOUT_CFG); - - /* update host clocks per usec */ - host1x_sync_writel(host, cpm, HOST1X_SYNC_USEC_CLK); + intr_hw_init(host, cpm); return 0; } -- cgit v1.2.3 From 6e44b9ad22f82d4d10b707bcad6b7c701ed11641 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 5 Sep 2017 11:43:06 +0300 Subject: drm/tegra: Add Tegra186 support for VIC Add Tegra186 support for VIC - no changes are required except for new firmware and compatibility string. Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/drm.c | 1 + drivers/gpu/drm/tegra/vic.c | 10 ++++++++++ 2 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 597d563d636a..130d193192ee 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1317,6 +1317,7 @@ static const struct of_device_id host1x_drm_subdevs[] = { { .compatible = "nvidia,tegra210-sor", }, { .compatible = "nvidia,tegra210-sor1", }, { .compatible = "nvidia,tegra210-vic", }, + { .compatible = "nvidia,tegra186-vic", }, { /* sentinel */ } }; diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 52899fba15e6..b66b8d898cb1 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -270,9 +270,16 @@ static const struct vic_config vic_t210_config = { .firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE, }; +#define NVIDIA_TEGRA_186_VIC_FIRMWARE "nvidia/tegra186/vic04_ucode.bin" + +static const struct vic_config vic_t186_config = { + .firmware = NVIDIA_TEGRA_186_VIC_FIRMWARE, +}; + static const struct of_device_id vic_match[] = { { .compatible = "nvidia,tegra124-vic", .data = &vic_t124_config }, { .compatible = "nvidia,tegra210-vic", .data = &vic_t210_config }, + { .compatible = "nvidia,tegra186-vic", .data = &vic_t186_config }, { }, }; @@ -405,3 +412,6 @@ MODULE_FIRMWARE(NVIDIA_TEGRA_124_VIC_FIRMWARE); #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) MODULE_FIRMWARE(NVIDIA_TEGRA_210_VIC_FIRMWARE); #endif +#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) +MODULE_FIRMWARE(NVIDIA_TEGRA_186_VIC_FIRMWARE); +#endif -- cgit v1.2.3 From 2fb0dceb69ce957f01bdb6fddf7baf4c4b9cbc0d Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Sun, 24 Sep 2017 12:04:53 +0300 Subject: gpu: host1x: Call of_dma_configure() after setting bus of_dma_configure() now checks the device's bus before configuring it, so we need to set the device's bus before calling. Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/gpu/host1x/bus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index f9cde03030fd..66ea5acee820 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -403,12 +403,13 @@ static int host1x_device_add(struct host1x *host1x, device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask; device->dev.dma_mask = &device->dev.coherent_dma_mask; dev_set_name(&device->dev, "%s", driver->driver.name); - of_dma_configure(&device->dev, host1x->dev->of_node); device->dev.release = host1x_device_release; device->dev.of_node = host1x->dev->of_node; device->dev.bus = &host1x_bus_type; device->dev.parent = host1x->dev; + of_dma_configure(&device->dev, host1x->dev->of_node); + err = host1x_device_parse_dt(device, driver); if (err < 0) { kfree(device); -- cgit v1.2.3 From c3f52220f276504dea5615cc78750ddc9f468389 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Thu, 28 Sep 2017 15:50:39 +0300 Subject: gpu: host1x: Enable Tegra186 syncpoint protection Since Tegra186 the Host1x hardware allows syncpoints to be assigned to specific channels, preventing any other channels from incrementing them. Enable this feature where available and assign syncpoints to channels when submitting a job. Syncpoints are currently never unassigned from channels since that would require extra work and is unnecessary with the current channel allocation model. Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/host1x/dev.h | 15 +++++++++++++ drivers/gpu/host1x/hw/channel_hw.c | 2 ++ drivers/gpu/host1x/hw/syncpt_hw.c | 46 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/host1x/syncpt.c | 8 +++++++ 4 files changed, 71 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h index def802c0a6bf..502769726480 100644 --- a/drivers/gpu/host1x/dev.h +++ b/drivers/gpu/host1x/dev.h @@ -79,6 +79,9 @@ struct host1x_syncpt_ops { u32 (*load)(struct host1x_syncpt *syncpt); int (*cpu_incr)(struct host1x_syncpt *syncpt); int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr); + void (*assign_to_channel)(struct host1x_syncpt *syncpt, + struct host1x_channel *channel); + void (*enable_protection)(struct host1x *host); }; struct host1x_intr_ops { @@ -186,6 +189,18 @@ static inline int host1x_hw_syncpt_patch_wait(struct host1x *host, return host->syncpt_op->patch_wait(sp, patch_addr); } +static inline void host1x_hw_syncpt_assign_to_channel( + struct host1x *host, struct host1x_syncpt *sp, + struct host1x_channel *ch) +{ + return host->syncpt_op->assign_to_channel(sp, ch); +} + +static inline void host1x_hw_syncpt_enable_protection(struct host1x *host) +{ + return host->syncpt_op->enable_protection(host); +} + static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm, void (*syncpt_thresh_work)(struct work_struct *)) { diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c index 8447a56c41ca..1d3e9bdde2ce 100644 --- a/drivers/gpu/host1x/hw/channel_hw.c +++ b/drivers/gpu/host1x/hw/channel_hw.c @@ -147,6 +147,8 @@ static int channel_submit(struct host1x_job *job) syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs); + host1x_hw_syncpt_assign_to_channel(host, sp, ch); + job->syncpt_end = syncval; /* add a setclass for modules that require it */ diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c b/drivers/gpu/host1x/hw/syncpt_hw.c index 7b0270d60742..7dfd47d74f89 100644 --- a/drivers/gpu/host1x/hw/syncpt_hw.c +++ b/drivers/gpu/host1x/hw/syncpt_hw.c @@ -106,6 +106,50 @@ static int syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr) return 0; } +/** + * syncpt_assign_to_channel() - Assign syncpoint to channel + * @sp: syncpoint + * @ch: channel + * + * On chips with the syncpoint protection feature (Tegra186+), assign @sp to + * @ch, preventing other channels from incrementing the syncpoints. If @ch is + * NULL, unassigns the syncpoint. + * + * On older chips, do nothing. + */ +static void syncpt_assign_to_channel(struct host1x_syncpt *sp, + struct host1x_channel *ch) +{ +#if HOST1X_HW >= 6 + struct host1x *host = sp->host; + + if (!host->hv_regs) + return; + + host1x_sync_writel(host, + HOST1X_SYNC_SYNCPT_CH_APP_CH(ch ? ch->id : 0xff), + HOST1X_SYNC_SYNCPT_CH_APP(sp->id)); +#endif +} + +/** + * syncpt_enable_protection() - Enable syncpoint protection + * @host: host1x instance + * + * On chips with the syncpoint protection feature (Tegra186+), enable this + * feature. On older chips, do nothing. + */ +static void syncpt_enable_protection(struct host1x *host) +{ +#if HOST1X_HW >= 6 + if (!host->hv_regs) + return; + + host1x_hypervisor_writel(host, HOST1X_HV_SYNCPT_PROT_EN_CH_EN, + HOST1X_HV_SYNCPT_PROT_EN); +#endif +} + static const struct host1x_syncpt_ops host1x_syncpt_ops = { .restore = syncpt_restore, .restore_wait_base = syncpt_restore_wait_base, @@ -113,4 +157,6 @@ static const struct host1x_syncpt_ops host1x_syncpt_ops = { .load = syncpt_load, .cpu_incr = syncpt_cpu_incr, .patch_wait = syncpt_patch_wait, + .assign_to_channel = syncpt_assign_to_channel, + .enable_protection = syncpt_enable_protection, }; diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c index fcba94cbf4ed..a2a952adc136 100644 --- a/drivers/gpu/host1x/syncpt.c +++ b/drivers/gpu/host1x/syncpt.c @@ -398,6 +398,13 @@ int host1x_syncpt_init(struct host1x *host) for (i = 0; i < host->info->nb_pts; i++) { syncpt[i].id = i; syncpt[i].host = host; + + /* + * Unassign syncpt from channels for purposes of Tegra186 + * syncpoint protection. This prevents any channel from + * accessing it until it is reassigned. + */ + host1x_hw_syncpt_assign_to_channel(host, &syncpt[i], NULL); } for (i = 0; i < host->info->nb_bases; i++) @@ -408,6 +415,7 @@ int host1x_syncpt_init(struct host1x *host) host->bases = bases; host1x_syncpt_restore(host); + host1x_hw_syncpt_enable_protection(host); /* Allocate sync point to use for clearing waits for expired fences */ host->nop_sp = host1x_syncpt_alloc(host, NULL, 0); -- cgit v1.2.3 From 2316f29fb57932e34a56998073246b8ec4c567f9 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Thu, 28 Sep 2017 15:50:40 +0300 Subject: gpu: host1x: Enable gather filter The gather filter is a feature present on Tegra124 and newer where the hardware prevents GATHERed command buffers from executing commands normally reserved for the CDMA pushbuffer which is maintained by the kernel driver. This commit enables the gather filter on all supporting hardware. Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/channel_hw.c | 22 ++++++++++++++++++++++ drivers/gpu/host1x/hw/hw_host1x04_channel.h | 12 ++++++++++++ drivers/gpu/host1x/hw/hw_host1x05_channel.h | 12 ++++++++++++ 3 files changed, 46 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c index 1d3e9bdde2ce..9af758785a11 100644 --- a/drivers/gpu/host1x/hw/channel_hw.c +++ b/drivers/gpu/host1x/hw/channel_hw.c @@ -180,10 +180,32 @@ error: return err; } +static void enable_gather_filter(struct host1x *host, + struct host1x_channel *ch) +{ +#if HOST1X_HW >= 6 + u32 val; + + if (!host->hv_regs) + return; + + val = host1x_hypervisor_readl( + host, HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(ch->id / 32)); + val |= BIT(ch->id % 32); + host1x_hypervisor_writel( + host, val, HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(ch->id / 32)); +#elif HOST1X_HW >= 4 + host1x_ch_writel(ch, + HOST1X_CHANNEL_CHANNELCTRL_KERNEL_FILTER_GBUFFER(1), + HOST1X_CHANNEL_CHANNELCTRL); +#endif +} + static int host1x_channel_init(struct host1x_channel *ch, struct host1x *dev, unsigned int index) { ch->regs = dev->regs + index * HOST1X_CHANNEL_SIZE; + enable_gather_filter(dev, ch); return 0; } diff --git a/drivers/gpu/host1x/hw/hw_host1x04_channel.h b/drivers/gpu/host1x/hw/hw_host1x04_channel.h index 95e6f96142b9..2e8b635aa660 100644 --- a/drivers/gpu/host1x/hw/hw_host1x04_channel.h +++ b/drivers/gpu/host1x/hw/hw_host1x04_channel.h @@ -117,5 +117,17 @@ static inline u32 host1x_channel_dmactrl_dmainitget(void) } #define HOST1X_CHANNEL_DMACTRL_DMAINITGET \ host1x_channel_dmactrl_dmainitget() +static inline u32 host1x_channel_channelctrl_r(void) +{ + return 0x98; +} +#define HOST1X_CHANNEL_CHANNELCTRL \ + host1x_channel_channelctrl_r() +static inline u32 host1x_channel_channelctrl_kernel_filter_gbuffer_f(u32 v) +{ + return (v & 0x1) << 2; +} +#define HOST1X_CHANNEL_CHANNELCTRL_KERNEL_FILTER_GBUFFER(v) \ + host1x_channel_channelctrl_kernel_filter_gbuffer_f(v) #endif diff --git a/drivers/gpu/host1x/hw/hw_host1x05_channel.h b/drivers/gpu/host1x/hw/hw_host1x05_channel.h index fce6e2c1ff4c..abbbc2641ce6 100644 --- a/drivers/gpu/host1x/hw/hw_host1x05_channel.h +++ b/drivers/gpu/host1x/hw/hw_host1x05_channel.h @@ -117,5 +117,17 @@ static inline u32 host1x_channel_dmactrl_dmainitget(void) } #define HOST1X_CHANNEL_DMACTRL_DMAINITGET \ host1x_channel_dmactrl_dmainitget() +static inline u32 host1x_channel_channelctrl_r(void) +{ + return 0x98; +} +#define HOST1X_CHANNEL_CHANNELCTRL \ + host1x_channel_channelctrl_r() +static inline u32 host1x_channel_channelctrl_kernel_filter_gbuffer_f(u32 v) +{ + return (v & 0x1) << 2; +} +#define HOST1X_CHANNEL_CHANNELCTRL_KERNEL_FILTER_GBUFFER(v) \ + host1x_channel_channelctrl_kernel_filter_gbuffer_f(v) #endif -- cgit v1.2.3 From eb2ee1a28db17155bcee4630e36ea1759b7e10dc Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Thu, 28 Sep 2017 15:50:41 +0300 Subject: gpu: host1x: Improve debug disassembly formatting The host1x driver prints out "disassembly" dumps of the command FIFO and gather contents on submission timeouts. However, the output has been quite difficult to read with unnecessary newlines and occasional missing parentheses. Fix these problems by using pr_cont to remove unnecessary newlines and by fixing other small issues. Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/host1x/debug.c | 14 ++++++++++- drivers/gpu/host1x/debug.h | 14 ++++++++--- drivers/gpu/host1x/hw/debug_hw.c | 46 ++++++++++++++++++++++------------- drivers/gpu/host1x/hw/debug_hw_1x01.c | 8 +++--- drivers/gpu/host1x/hw/debug_hw_1x06.c | 9 ++++--- 5 files changed, 61 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c index 2aae0e63214c..dc77ec452ffc 100644 --- a/drivers/gpu/host1x/debug.c +++ b/drivers/gpu/host1x/debug.c @@ -40,7 +40,19 @@ void host1x_debug_output(struct output *o, const char *fmt, ...) len = vsnprintf(o->buf, sizeof(o->buf), fmt, args); va_end(args); - o->fn(o->ctx, o->buf, len); + o->fn(o->ctx, o->buf, len, false); +} + +void host1x_debug_cont(struct output *o, const char *fmt, ...) +{ + va_list args; + int len; + + va_start(args, fmt); + len = vsnprintf(o->buf, sizeof(o->buf), fmt, args); + va_end(args); + + o->fn(o->ctx, o->buf, len, true); } static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo) diff --git a/drivers/gpu/host1x/debug.h b/drivers/gpu/host1x/debug.h index 4595b2e0799f..990cce47e737 100644 --- a/drivers/gpu/host1x/debug.h +++ b/drivers/gpu/host1x/debug.h @@ -24,22 +24,28 @@ struct host1x; struct output { - void (*fn)(void *ctx, const char *str, size_t len); + void (*fn)(void *ctx, const char *str, size_t len, bool cont); void *ctx; char buf[256]; }; -static inline void write_to_seqfile(void *ctx, const char *str, size_t len) +static inline void write_to_seqfile(void *ctx, const char *str, size_t len, + bool cont) { seq_write((struct seq_file *)ctx, str, len); } -static inline void write_to_printk(void *ctx, const char *str, size_t len) +static inline void write_to_printk(void *ctx, const char *str, size_t len, + bool cont) { - pr_info("%s", str); + if (cont) + pr_cont("%s", str); + else + pr_info("%s", str); } void __printf(2, 3) host1x_debug_output(struct output *o, const char *fmt, ...); +void __printf(2, 3) host1x_debug_cont(struct output *o, const char *fmt, ...); extern unsigned int host1x_debug_trace_cmdbuf; diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c index 770d92e62d69..1e67667e308c 100644 --- a/drivers/gpu/host1x/hw/debug_hw.c +++ b/drivers/gpu/host1x/hw/debug_hw.c @@ -40,48 +40,59 @@ enum { static unsigned int show_channel_command(struct output *o, u32 val) { - unsigned int mask, subop; + unsigned int mask, subop, num; switch (val >> 28) { case HOST1X_OPCODE_SETCLASS: mask = val & 0x3f; if (mask) { - host1x_debug_output(o, "SETCL(class=%03x, offset=%03x, mask=%02x, [", + host1x_debug_cont(o, "SETCL(class=%03x, offset=%03x, mask=%02x, [", val >> 6 & 0x3ff, val >> 16 & 0xfff, mask); return hweight8(mask); } - host1x_debug_output(o, "SETCL(class=%03x)\n", val >> 6 & 0x3ff); + host1x_debug_cont(o, "SETCL(class=%03x)\n", val >> 6 & 0x3ff); return 0; case HOST1X_OPCODE_INCR: - host1x_debug_output(o, "INCR(offset=%03x, [", + num = val & 0xffff; + host1x_debug_cont(o, "INCR(offset=%03x, [", val >> 16 & 0xfff); - return val & 0xffff; + if (!num) + host1x_debug_cont(o, "])\n"); + + return num; case HOST1X_OPCODE_NONINCR: - host1x_debug_output(o, "NONINCR(offset=%03x, [", + num = val & 0xffff; + host1x_debug_cont(o, "NONINCR(offset=%03x, [", val >> 16 & 0xfff); - return val & 0xffff; + if (!num) + host1x_debug_cont(o, "])\n"); + + return num; case HOST1X_OPCODE_MASK: mask = val & 0xffff; - host1x_debug_output(o, "MASK(offset=%03x, mask=%03x, [", + host1x_debug_cont(o, "MASK(offset=%03x, mask=%03x, [", val >> 16 & 0xfff, mask); + if (!mask) + host1x_debug_cont(o, "])\n"); + return hweight16(mask); case HOST1X_OPCODE_IMM: - host1x_debug_output(o, "IMM(offset=%03x, data=%03x)\n", + host1x_debug_cont(o, "IMM(offset=%03x, data=%03x)\n", val >> 16 & 0xfff, val & 0xffff); return 0; case HOST1X_OPCODE_RESTART: - host1x_debug_output(o, "RESTART(offset=%08x)\n", val << 4); + host1x_debug_cont(o, "RESTART(offset=%08x)\n", val << 4); return 0; case HOST1X_OPCODE_GATHER: - host1x_debug_output(o, "GATHER(offset=%03x, insert=%d, type=%d, count=%04x, addr=[", + host1x_debug_cont(o, "GATHER(offset=%03x, insert=%d, type=%d, count=%04x, addr=[", val >> 16 & 0xfff, val >> 15 & 0x1, val >> 14 & 0x1, val & 0x3fff); return 1; @@ -89,16 +100,17 @@ static unsigned int show_channel_command(struct output *o, u32 val) case HOST1X_OPCODE_EXTEND: subop = val >> 24 & 0xf; if (subop == HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK) - host1x_debug_output(o, "ACQUIRE_MLOCK(index=%d)\n", + host1x_debug_cont(o, "ACQUIRE_MLOCK(index=%d)\n", val & 0xff); else if (subop == HOST1X_OPCODE_EXTEND_RELEASE_MLOCK) - host1x_debug_output(o, "RELEASE_MLOCK(index=%d)\n", + host1x_debug_cont(o, "RELEASE_MLOCK(index=%d)\n", val & 0xff); else - host1x_debug_output(o, "EXTEND_UNKNOWN(%08x)\n", val); + host1x_debug_cont(o, "EXTEND_UNKNOWN(%08x)\n", val); return 0; default: + host1x_debug_cont(o, "UNKNOWN\n"); return 0; } } @@ -126,11 +138,11 @@ static void show_gather(struct output *o, phys_addr_t phys_addr, u32 val = *(map_addr + offset / 4 + i); if (!data_count) { - host1x_debug_output(o, "%08x: %08x:", addr, val); + host1x_debug_output(o, "%08x: %08x: ", addr, val); data_count = show_channel_command(o, val); } else { - host1x_debug_output(o, "%08x%s", val, - data_count > 0 ? ", " : "])\n"); + host1x_debug_cont(o, "%08x%s", val, + data_count > 1 ? ", " : "])\n"); data_count--; } } diff --git a/drivers/gpu/host1x/hw/debug_hw_1x01.c b/drivers/gpu/host1x/hw/debug_hw_1x01.c index 8f243903cc7f..09e1aa7bb5dd 100644 --- a/drivers/gpu/host1x/hw/debug_hw_1x01.c +++ b/drivers/gpu/host1x/hw/debug_hw_1x01.c @@ -111,11 +111,11 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ); if (!data_count) { - host1x_debug_output(o, "%08x:", val); + host1x_debug_output(o, "%08x: ", val); data_count = show_channel_command(o, val); } else { - host1x_debug_output(o, "%08x%s", val, - data_count > 0 ? ", " : "])\n"); + host1x_debug_cont(o, "%08x%s", val, + data_count > 1 ? ", " : "])\n"); data_count--; } @@ -126,7 +126,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, } while (rd_ptr != wr_ptr); if (data_count) - host1x_debug_output(o, ", ...])\n"); + host1x_debug_cont(o, ", ...])\n"); host1x_debug_output(o, "\n"); host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); diff --git a/drivers/gpu/host1x/hw/debug_hw_1x06.c b/drivers/gpu/host1x/hw/debug_hw_1x06.c index 9cdee657fb46..bd89da5dc64c 100644 --- a/drivers/gpu/host1x/hw/debug_hw_1x06.c +++ b/drivers/gpu/host1x/hw/debug_hw_1x06.c @@ -105,11 +105,12 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, HOST1X_HV_CMDFIFO_PEEK_READ); if (!data_count) { - host1x_debug_output(o, "%08x:", val); + host1x_debug_output(o, "%03x 0x%08x: ", + rd_ptr - start, val); data_count = show_channel_command(o, val); } else { - host1x_debug_output(o, "%08x%s", val, - data_count > 0 ? ", " : "])\n"); + host1x_debug_cont(o, "%08x%s", val, + data_count > 1 ? ", " : "])\n"); data_count--; } @@ -120,7 +121,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, } while (rd_ptr != wr_ptr); if (data_count) - host1x_debug_output(o, ", ...])\n"); + host1x_debug_cont(o, ", ...])\n"); host1x_debug_output(o, "\n"); host1x_hypervisor_writel(host, 0x0, HOST1X_HV_CMDFIFO_PEEK_CTRL); -- cgit v1.2.3 From 2a79c034b579beb90b34c6942ff7d54ece5d3ea0 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Thu, 28 Sep 2017 15:50:42 +0300 Subject: gpu: host1x: Disassemble more instructions The disassembler for debug dumps was missing some newer host1x opcodes. Add disassembly support for these. Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/debug_hw.c | 59 ++++++++++++++++++++++++++++++++--- drivers/gpu/host1x/hw/debug_hw_1x01.c | 2 +- drivers/gpu/host1x/hw/debug_hw_1x06.c | 3 +- 3 files changed, 58 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c index 1e67667e308c..989476801f9d 100644 --- a/drivers/gpu/host1x/hw/debug_hw.c +++ b/drivers/gpu/host1x/hw/debug_hw.c @@ -30,6 +30,13 @@ enum { HOST1X_OPCODE_IMM = 0x04, HOST1X_OPCODE_RESTART = 0x05, HOST1X_OPCODE_GATHER = 0x06, + HOST1X_OPCODE_SETSTRMID = 0x07, + HOST1X_OPCODE_SETAPPID = 0x08, + HOST1X_OPCODE_SETPYLD = 0x09, + HOST1X_OPCODE_INCR_W = 0x0a, + HOST1X_OPCODE_NONINCR_W = 0x0b, + HOST1X_OPCODE_GATHER_W = 0x0c, + HOST1X_OPCODE_RESTART_W = 0x0d, HOST1X_OPCODE_EXTEND = 0x0e, }; @@ -38,11 +45,16 @@ enum { HOST1X_OPCODE_EXTEND_RELEASE_MLOCK = 0x01, }; -static unsigned int show_channel_command(struct output *o, u32 val) +#define INVALID_PAYLOAD 0xffffffff + +static unsigned int show_channel_command(struct output *o, u32 val, + u32 *payload) { - unsigned int mask, subop, num; + unsigned int mask, subop, num, opcode; + + opcode = val >> 28; - switch (val >> 28) { + switch (opcode) { case HOST1X_OPCODE_SETCLASS: mask = val & 0x3f; if (mask) { @@ -97,6 +109,44 @@ static unsigned int show_channel_command(struct output *o, u32 val) val >> 14 & 0x1, val & 0x3fff); return 1; +#if HOST1X_HW >= 6 + case HOST1X_OPCODE_SETSTRMID: + host1x_debug_cont(o, "SETSTRMID(offset=%06x)\n", + val & 0x3fffff); + return 0; + + case HOST1X_OPCODE_SETAPPID: + host1x_debug_cont(o, "SETAPPID(appid=%02x)\n", val & 0xff); + return 0; + + case HOST1X_OPCODE_SETPYLD: + *payload = val & 0xffff; + host1x_debug_cont(o, "SETPYLD(data=%04x)\n", *payload); + return 0; + + case HOST1X_OPCODE_INCR_W: + case HOST1X_OPCODE_NONINCR_W: + host1x_debug_cont(o, "%s(offset=%06x, ", + opcode == HOST1X_OPCODE_INCR_W ? + "INCR_W" : "NONINCR_W", + val & 0x3fffff); + if (*payload == 0) { + host1x_debug_cont(o, "[])\n"); + return 0; + } else if (*payload == INVALID_PAYLOAD) { + host1x_debug_cont(o, "unknown)\n"); + return 0; + } else { + host1x_debug_cont(o, "["); + return *payload; + } + + case HOST1X_OPCODE_GATHER_W: + host1x_debug_cont(o, "GATHER_W(count=%04x, addr=[", + val & 0x3fff); + return 2; +#endif + case HOST1X_OPCODE_EXTEND: subop = val >> 24 & 0xf; if (subop == HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK) @@ -122,6 +172,7 @@ static void show_gather(struct output *o, phys_addr_t phys_addr, /* Map dmaget cursor to corresponding mem handle */ u32 offset = phys_addr - pin_addr; unsigned int data_count = 0, i; + u32 payload = INVALID_PAYLOAD; /* * Sometimes we're given different hardware address to the same @@ -139,7 +190,7 @@ static void show_gather(struct output *o, phys_addr_t phys_addr, if (!data_count) { host1x_debug_output(o, "%08x: %08x: ", addr, val); - data_count = show_channel_command(o, val); + data_count = show_channel_command(o, val, &payload); } else { host1x_debug_cont(o, "%08x%s", val, data_count > 1 ? ", " : "])\n"); diff --git a/drivers/gpu/host1x/hw/debug_hw_1x01.c b/drivers/gpu/host1x/hw/debug_hw_1x01.c index 09e1aa7bb5dd..8790d5fd5f20 100644 --- a/drivers/gpu/host1x/hw/debug_hw_1x01.c +++ b/drivers/gpu/host1x/hw/debug_hw_1x01.c @@ -112,7 +112,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, if (!data_count) { host1x_debug_output(o, "%08x: ", val); - data_count = show_channel_command(o, val); + data_count = show_channel_command(o, val, NULL); } else { host1x_debug_cont(o, "%08x%s", val, data_count > 1 ? ", " : "])\n"); diff --git a/drivers/gpu/host1x/hw/debug_hw_1x06.c b/drivers/gpu/host1x/hw/debug_hw_1x06.c index bd89da5dc64c..b503c740c022 100644 --- a/drivers/gpu/host1x/hw/debug_hw_1x06.c +++ b/drivers/gpu/host1x/hw/debug_hw_1x06.c @@ -63,6 +63,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, struct output *o) { u32 val, rd_ptr, wr_ptr, start, end; + u32 payload = INVALID_PAYLOAD; unsigned int data_count = 0; host1x_debug_output(o, "%u: fifo:\n", ch->id); @@ -107,7 +108,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, if (!data_count) { host1x_debug_output(o, "%03x 0x%08x: ", rd_ptr - start, val); - data_count = show_channel_command(o, val); + data_count = show_channel_command(o, val, &payload); } else { host1x_debug_cont(o, "%08x%s", val, data_count > 1 ? ", " : "])\n"); -- cgit v1.2.3 From 45bd862c2846414371bc9b5d31be7c5df252c289 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Thu, 28 Sep 2017 15:50:43 +0300 Subject: gpu: host1x: Fix incorrect comment for channel_request This function actually doesn't sleep in the version that was merged. Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/host1x/channel.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c index db9b91d1384c..2fb93c27c1d9 100644 --- a/drivers/gpu/host1x/channel.c +++ b/drivers/gpu/host1x/channel.c @@ -128,8 +128,7 @@ static struct host1x_channel *acquire_unused_channel(struct host1x *host) * host1x_channel_request() - Allocate a channel * @device: Host1x unit this channel will be used to send commands to * - * Allocates a new host1x channel for @device. If there are no free channels, - * this will sleep until one becomes available. May return NULL if CDMA + * Allocates a new host1x channel for @device. May return NULL if CDMA * initialization fails. */ struct host1x_channel *host1x_channel_request(struct device *dev) -- cgit v1.2.3 From a176c67d71508761ec9d66a2d9a4eabb8d6873fd Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Thu, 28 Sep 2017 15:50:44 +0300 Subject: drm/tegra: Use u64_to_user_ptr helper Use the u64_to_user_ptr helper macro to cast IOCTL argument u64 values to user pointers instead of writing out the cast manually. Also do some other cleanup with user pointers to make them stand out more and look cleaner. Signed-off-by: Mikko Perttunen Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/drm.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 130d193192ee..943bdf88c4a2 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -386,12 +386,10 @@ int tegra_drm_submit(struct tegra_drm_context *context, unsigned int num_cmdbufs = args->num_cmdbufs; unsigned int num_relocs = args->num_relocs; unsigned int num_waitchks = args->num_waitchks; - struct drm_tegra_cmdbuf __user *cmdbufs = - (void __user *)(uintptr_t)args->cmdbufs; - struct drm_tegra_reloc __user *relocs = - (void __user *)(uintptr_t)args->relocs; - struct drm_tegra_waitchk __user *waitchks = - (void __user *)(uintptr_t)args->waitchks; + struct drm_tegra_cmdbuf __user *user_cmdbufs; + struct drm_tegra_reloc __user *user_relocs; + struct drm_tegra_waitchk __user *user_waitchks; + struct drm_tegra_syncpt __user *user_syncpt; struct drm_tegra_syncpt syncpt; struct host1x *host1x = dev_get_drvdata(drm->dev->parent); struct drm_gem_object **refs; @@ -400,6 +398,11 @@ int tegra_drm_submit(struct tegra_drm_context *context, unsigned int num_refs; int err; + user_cmdbufs = u64_to_user_ptr(args->cmdbufs); + user_relocs = u64_to_user_ptr(args->relocs); + user_waitchks = u64_to_user_ptr(args->waitchks); + user_syncpt = u64_to_user_ptr(args->syncpts); + /* We don't yet support other than one syncpt_incr struct per submit */ if (args->num_syncpts != 1) return -EINVAL; @@ -440,7 +443,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, struct tegra_bo *obj; u64 offset; - if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) { + if (copy_from_user(&cmdbuf, user_cmdbufs, sizeof(cmdbuf))) { err = -EFAULT; goto fail; } @@ -476,7 +479,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); num_cmdbufs--; - cmdbufs++; + user_cmdbufs++; } /* copy and resolve relocations from submit */ @@ -485,7 +488,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, struct tegra_bo *obj; err = host1x_reloc_copy_from_user(&job->relocarray[num_relocs], - &relocs[num_relocs], drm, + &user_relocs[num_relocs], drm, file); if (err < 0) goto fail; @@ -519,9 +522,8 @@ int tegra_drm_submit(struct tegra_drm_context *context, struct host1x_waitchk *wait = &job->waitchk[num_waitchks]; struct tegra_bo *obj; - err = host1x_waitchk_copy_from_user(wait, - &waitchks[num_waitchks], - file); + err = host1x_waitchk_copy_from_user( + wait, &user_waitchks[num_waitchks], file); if (err < 0) goto fail; @@ -539,8 +541,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, } } - if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts, - sizeof(syncpt))) { + if (copy_from_user(&syncpt, user_syncpt, sizeof(syncpt))) { err = -EFAULT; goto fail; } -- cgit v1.2.3 From b9ff7aeaefbb39d9882547fa4b02e6e34a7b9463 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Aug 2017 16:35:17 +0200 Subject: drm/tegra: dc: Use of_device_get_match_data() Avoid some boilerplate by calling of_device_get_match_data() instead of open-coding the equivalent in the driver. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index bc51eb855bf1..2b5e052fb8d3 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -1985,7 +1986,6 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) static int tegra_dc_probe(struct platform_device *pdev) { - const struct of_device_id *id; struct resource *regs; struct tegra_dc *dc; int err; @@ -1994,14 +1994,11 @@ static int tegra_dc_probe(struct platform_device *pdev) if (!dc) return -ENOMEM; - id = of_match_node(tegra_dc_of_match, pdev->dev.of_node); - if (!id) - return -ENODEV; + dc->soc = of_device_get_match_data(&pdev->dev); spin_lock_init(&dc->lock); INIT_LIST_HEAD(&dc->list); dc->dev = &pdev->dev; - dc->soc = id->data; err = tegra_dc_parse_dt(dc); if (err < 0) -- cgit v1.2.3 From 5e4acd30f308be9ec6eba0b9b296210bbcf0ed3d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Aug 2017 18:05:10 +0200 Subject: drm/tegra: hdmi: Use of_device_get_match_data() Avoid some boilerplate by calling of_device_get_match_data() instead of open-coding the equivalent in the driver. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/hdmi.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 5b9d83b71943..a4e9c769fc7a 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -1663,20 +1664,15 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data) static int tegra_hdmi_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct tegra_hdmi *hdmi; struct resource *regs; int err; - match = of_match_node(tegra_hdmi_of_match, pdev->dev.of_node); - if (!match) - return -ENODEV; - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) return -ENOMEM; - hdmi->config = match->data; + hdmi->config = of_device_get_match_data(&pdev->dev); hdmi->dev = &pdev->dev; hdmi->audio_source = AUTO; -- cgit v1.2.3 From 5faea3d0f80f4fe481bcf994750b96c7429bebe1 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Aug 2017 17:33:14 +0200 Subject: drm/tegra: sor: Use of_device_get_match_data() Avoid some boilerplate by calling of_device_get_match_data() instead of open-coding the equivalent in the driver. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/sor.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 7ab1d1dc7cd7..4bcacd3f4861 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -2536,20 +2536,17 @@ MODULE_DEVICE_TABLE(of, tegra_sor_of_match); static int tegra_sor_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct device_node *np; struct tegra_sor *sor; struct resource *regs; int err; - match = of_match_device(tegra_sor_of_match, &pdev->dev); - sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL); if (!sor) return -ENOMEM; + sor->soc = of_device_get_match_data(&pdev->dev); sor->output.dev = sor->dev = &pdev->dev; - sor->soc = match->data; sor->settings = devm_kmemdup(&pdev->dev, sor->soc->settings, sor->soc->num_settings * -- cgit v1.2.3 From 829ce7a68f20054b9cda762fbbf662b33ca26756 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Aug 2017 18:03:27 +0200 Subject: drm/tegra: vic: Use of_device_get_match_data() Avoid some boilerplate by calling of_device_get_match_data() instead of open-coding the equivalent in the driver. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/vic.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index b66b8d898cb1..18024183aa2b 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -285,21 +285,18 @@ static const struct of_device_id vic_match[] = { static int vic_probe(struct platform_device *pdev) { - struct vic_config *vic_config = NULL; struct device *dev = &pdev->dev; struct host1x_syncpt **syncpts; struct resource *regs; - const struct of_device_id *match; struct vic *vic; int err; - match = of_match_device(vic_match, dev); - vic_config = (struct vic_config *)match->data; - vic = devm_kzalloc(dev, sizeof(*vic), GFP_KERNEL); if (!vic) return -ENOMEM; + vic->config = of_device_get_match_data(dev); + syncpts = devm_kzalloc(dev, sizeof(*syncpts), GFP_KERNEL); if (!syncpts) return -ENOMEM; @@ -328,7 +325,7 @@ static int vic_probe(struct platform_device *pdev) if (err < 0) return err; - err = falcon_read_firmware(&vic->falcon, vic_config->firmware); + err = falcon_read_firmware(&vic->falcon, vic->config->firmware); if (err < 0) goto exit_falcon; @@ -341,7 +338,6 @@ static int vic_probe(struct platform_device *pdev) vic->client.base.syncpts = syncpts; vic->client.base.num_syncpts = 1; vic->dev = dev; - vic->config = vic_config; INIT_LIST_HEAD(&vic->client.list); vic->client.ops = &vic_ops; -- cgit v1.2.3 From 2d1c18fb0d1c566491dfaba09ed24881b1d82152 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 30 Aug 2017 17:25:34 +0200 Subject: drm/tegra: dc: Move some declarations to dc.h Move the DC related declarations in drm.h to dc.h where they belong. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 10 ---- drivers/gpu/drm/tegra/dc.h | 120 ++++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 105 -------------------------------------- 3 files changed, 120 insertions(+), 115 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 2b5e052fb8d3..fd31974e2218 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -24,16 +24,6 @@ #include #include -struct tegra_dc_soc_info { - bool supports_border_color; - bool supports_interlacing; - bool supports_cursor; - bool supports_block_linear; - unsigned int pitch_align; - bool has_powergate; - bool broken_reset; -}; - struct tegra_plane { struct drm_plane base; unsigned int index; diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 4a268635749b..cb100b6e3282 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -10,6 +10,126 @@ #ifndef TEGRA_DC_H #define TEGRA_DC_H 1 +#include + +#include + +#include "drm.h" + +struct tegra_output; + +struct tegra_dc_stats { + unsigned long frames; + unsigned long vblank; + unsigned long underflow; + unsigned long overflow; +}; + +struct tegra_dc_soc_info { + bool supports_border_color; + bool supports_interlacing; + bool supports_cursor; + bool supports_block_linear; + unsigned int pitch_align; + bool has_powergate; + bool broken_reset; +}; + +struct tegra_dc { + struct host1x_client client; + struct host1x_syncpt *syncpt; + struct device *dev; + spinlock_t lock; + + struct drm_crtc base; + unsigned int powergate; + int pipe; + + struct clk *clk; + struct reset_control *rst; + void __iomem *regs; + int irq; + + struct tegra_output *rgb; + + struct tegra_dc_stats stats; + struct list_head list; + + struct drm_info_list *debugfs_files; + struct drm_minor *minor; + struct dentry *debugfs; + + /* page-flip handling */ + struct drm_pending_vblank_event *event; + + const struct tegra_dc_soc_info *soc; + + struct iommu_domain *domain; +}; + +static inline struct tegra_dc * +host1x_client_to_dc(struct host1x_client *client) +{ + return container_of(client, struct tegra_dc, client); +} + +static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc) +{ + return crtc ? container_of(crtc, struct tegra_dc, base) : NULL; +} + +static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value, + unsigned int offset) +{ + trace_dc_writel(dc->dev, offset, value); + writel(value, dc->regs + (offset << 2)); +} + +static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned int offset) +{ + u32 value = readl(dc->regs + (offset << 2)); + + trace_dc_readl(dc->dev, offset, value); + + return value; +} + +struct tegra_dc_window { + struct { + unsigned int x; + unsigned int y; + unsigned int w; + unsigned int h; + } src; + struct { + unsigned int x; + unsigned int y; + unsigned int w; + unsigned int h; + } dst; + unsigned int bits_per_pixel; + unsigned int stride[2]; + unsigned long base[3]; + bool bottom_up; + + struct tegra_bo_tiling tiling; + u32 format; + u32 swap; +}; + +/* from dc.c */ +void tegra_dc_commit(struct tegra_dc *dc); +int tegra_dc_state_setup_clock(struct tegra_dc *dc, + struct drm_crtc_state *crtc_state, + struct clk *clk, unsigned long pclk, + unsigned int div); + +/* from rgb.c */ +int tegra_dc_rgb_probe(struct tegra_dc *dc); +int tegra_dc_rgb_remove(struct tegra_dc *dc); +int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc); +int tegra_dc_rgb_exit(struct tegra_dc *dc); + #define DC_CMD_GENERAL_INCR_SYNCPT 0x000 #define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001 #define SYNCPT_CNTRL_NO_STALL (1 << 8) diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 063f5d397526..9bb6e8ebe40c 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -119,105 +119,6 @@ void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *iova); void tegra_drm_free(struct tegra_drm *tegra, size_t size, void *virt, dma_addr_t iova); -struct tegra_dc_soc_info; -struct tegra_output; - -struct tegra_dc_stats { - unsigned long frames; - unsigned long vblank; - unsigned long underflow; - unsigned long overflow; -}; - -struct tegra_dc { - struct host1x_client client; - struct host1x_syncpt *syncpt; - struct device *dev; - spinlock_t lock; - - struct drm_crtc base; - unsigned int powergate; - int pipe; - - struct clk *clk; - struct reset_control *rst; - void __iomem *regs; - int irq; - - struct tegra_output *rgb; - - struct tegra_dc_stats stats; - struct list_head list; - - struct drm_info_list *debugfs_files; - struct drm_minor *minor; - struct dentry *debugfs; - - /* page-flip handling */ - struct drm_pending_vblank_event *event; - - const struct tegra_dc_soc_info *soc; - - struct iommu_domain *domain; -}; - -static inline struct tegra_dc * -host1x_client_to_dc(struct host1x_client *client) -{ - return container_of(client, struct tegra_dc, client); -} - -static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc) -{ - return crtc ? container_of(crtc, struct tegra_dc, base) : NULL; -} - -static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value, - unsigned int offset) -{ - trace_dc_writel(dc->dev, offset, value); - writel(value, dc->regs + (offset << 2)); -} - -static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned int offset) -{ - u32 value = readl(dc->regs + (offset << 2)); - - trace_dc_readl(dc->dev, offset, value); - - return value; -} - -struct tegra_dc_window { - struct { - unsigned int x; - unsigned int y; - unsigned int w; - unsigned int h; - } src; - struct { - unsigned int x; - unsigned int y; - unsigned int w; - unsigned int h; - } dst; - unsigned int bits_per_pixel; - unsigned int stride[2]; - unsigned long base[3]; - bool bottom_up; - - struct tegra_bo_tiling tiling; - u32 format; - u32 swap; -}; - -/* from dc.c */ -void tegra_dc_commit(struct tegra_dc *dc); -int tegra_dc_state_setup_clock(struct tegra_dc *dc, - struct drm_crtc_state *crtc_state, - struct clk *clk, unsigned long pclk, - unsigned int div); - struct tegra_output { struct device_node *of_node; struct device *dev; @@ -243,12 +144,6 @@ static inline struct tegra_output *connector_to_output(struct drm_connector *c) return container_of(c, struct tegra_output, connector); } -/* from rgb.c */ -int tegra_dc_rgb_probe(struct tegra_dc *dc); -int tegra_dc_rgb_remove(struct tegra_dc *dc); -int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc); -int tegra_dc_rgb_exit(struct tegra_dc *dc); - /* from output.c */ int tegra_output_probe(struct tegra_output *output); void tegra_output_remove(struct tegra_output *output); -- cgit v1.2.3 From a4bfa0961c4bccbfd5f23d1283fa3d40e6af1b59 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 30 Aug 2017 17:34:10 +0200 Subject: drm/tegra: dc: Simplify atomic plane helper functions Remove the tegra_dc_disable_window() function whose only purpose was to allow tegra_plane_atomic_update() to also call it. Fix that by shuffling tegra_plano_atomic_disable() to before tegra_plane_atomic_update(). While at it, also remove the overlay plane helper functions because they are exactly the same as the primary plane helper functions. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index fd31974e2218..6a43dff70822 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -550,14 +550,21 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, return 0; } -static void tegra_dc_disable_window(struct tegra_dc *dc, int index) +static void tegra_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) { + struct tegra_dc *dc = to_tegra_dc(old_state->crtc); + struct tegra_plane *p = to_tegra_plane(plane); unsigned long flags; u32 value; + /* rien ne va plus */ + if (!old_state || !old_state->crtc) + return; + spin_lock_irqsave(&dc->lock, flags); - value = WINDOW_A_SELECT << index; + value = WINDOW_A_SELECT << p->index; tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS); @@ -582,7 +589,7 @@ static void tegra_plane_atomic_update(struct drm_plane *plane, return; if (!plane->state->visible) - return tegra_dc_disable_window(dc, p->index); + return tegra_plane_atomic_disable(plane, old_state); memset(&window, 0, sizeof(window)); window.src.x = plane->state->src.x1 >> 16; @@ -618,25 +625,10 @@ static void tegra_plane_atomic_update(struct drm_plane *plane, tegra_dc_setup_window(dc, p->index, &window); } -static void tegra_plane_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct tegra_plane *p = to_tegra_plane(plane); - struct tegra_dc *dc; - - /* rien ne va plus */ - if (!old_state || !old_state->crtc) - return; - - dc = to_tegra_dc(old_state->crtc); - - tegra_dc_disable_window(dc, p->index); -} - -static const struct drm_plane_helper_funcs tegra_primary_plane_helper_funcs = { +static const struct drm_plane_helper_funcs tegra_plane_helper_funcs = { .atomic_check = tegra_plane_atomic_check, - .atomic_update = tegra_plane_atomic_update, .atomic_disable = tegra_plane_atomic_disable, + .atomic_update = tegra_plane_atomic_update, }; static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm, @@ -676,7 +668,7 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm, return ERR_PTR(err); } - drm_plane_helper_add(&plane->base, &tegra_primary_plane_helper_funcs); + drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs); return &plane->base; } @@ -871,12 +863,6 @@ static const uint32_t tegra_overlay_plane_formats[] = { DRM_FORMAT_YUV422, }; -static const struct drm_plane_helper_funcs tegra_overlay_plane_helper_funcs = { - .atomic_check = tegra_plane_atomic_check, - .atomic_update = tegra_plane_atomic_update, - .atomic_disable = tegra_plane_atomic_disable, -}; - static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, struct tegra_dc *dc, unsigned int index) @@ -904,7 +890,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, return ERR_PTR(err); } - drm_plane_helper_add(&plane->base, &tegra_overlay_plane_helper_funcs); + drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs); return &plane->base; } -- cgit v1.2.3 From 39e08affecf0998be1b01f4752016e33fa98eb9a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 30 Aug 2017 17:38:39 +0200 Subject: drm/tegra: dc: Make sure to set the module clock rate When applying the PLL changes from the computed state object, make sure to set the rate of the display controller module clock. Failing to do so can yield to a situation where the parent will be set to the proper pixel clock, but the module clock will be divided down to the rate that is happened to be set to before the parent rate change. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 6a43dff70822..d5a63230e509 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1138,6 +1138,11 @@ static void tegra_dc_commit_state(struct tegra_dc *dc, value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1; tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); + + err = clk_set_rate(dc->clk, state->pclk); + if (err < 0) + dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", + dc->clk, state->pclk, err); } static void tegra_dc_stop(struct tegra_dc *dc) -- cgit v1.2.3 From a2f2f7403e1ea192ce79584d7050c46e455409dd Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 30 Aug 2017 17:41:00 +0200 Subject: drm/tegra: dc: Perform a complete reset sequence In order for the reset to be applied properly, the module clock must be enabled during the assertion. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index d5a63230e509..24a5ef4f5bb8 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1997,8 +1997,22 @@ static int tegra_dc_probe(struct platform_device *pdev) return PTR_ERR(dc->rst); } - if (!dc->soc->broken_reset) - reset_control_assert(dc->rst); + /* assert reset and disable clock */ + if (!dc->soc->broken_reset) { + err = clk_prepare_enable(dc->clk); + if (err < 0) + return err; + + usleep_range(2000, 4000); + + err = reset_control_assert(dc->rst); + if (err < 0) + return err; + + usleep_range(2000, 4000); + + clk_disable_unprepare(dc->clk); + } if (dc->soc->has_powergate) { if (dc->pipe == 0) -- cgit v1.2.3 From fb83be8873909ba7c089d1c5cb72873cc2cce7d1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 11 Sep 2017 14:29:52 +0200 Subject: drm/tegra: hdmi: Add cec-notifier support In order to support CEC the HDMI driver has to inform the CEC driver whenever the physical address changes. So when the EDID is read the CEC driver has to be informed and whenever the hotplug detect goes away. This is done through the cec-notifier framework. The link between the HDMI driver and the CEC driver is done through the hdmi-phandle property in the tegra-cec node in the device tree. Signed-off-by: Hans Verkuil Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/Kconfig | 1 + drivers/gpu/drm/tegra/drm.h | 3 +++ drivers/gpu/drm/tegra/hdmi.c | 9 +++++++++ drivers/gpu/drm/tegra/output.c | 6 ++++++ 4 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index dc58ab140151..cf54847a8bd1 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -9,6 +9,7 @@ config DRM_TEGRA select DRM_PANEL select TEGRA_HOST1X select IOMMU_IOVA if IOMMU_SUPPORT + select CEC_CORE if CEC_NOTIFIER help Choose this option if you have an NVIDIA Tegra SoC. diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 9bb6e8ebe40c..ddae331ad8b6 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -119,6 +119,8 @@ void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *iova); void tegra_drm_free(struct tegra_drm *tegra, size_t size, void *virt, dma_addr_t iova); +struct cec_notifier; + struct tegra_output { struct device_node *of_node; struct device *dev; @@ -126,6 +128,7 @@ struct tegra_output { struct drm_panel *panel; struct i2c_adapter *ddc; const struct edid *edid; + struct cec_notifier *notifier; unsigned int hpd_irq; int hpd_gpio; enum of_gpio_flags hpd_gpio_flags; diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index a4e9c769fc7a..6434b3d3d1ba 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -22,6 +22,8 @@ #include +#include + #include "hdmi.h" #include "drm.h" #include "dc.h" @@ -1721,6 +1723,10 @@ static int tegra_hdmi_probe(struct platform_device *pdev) return PTR_ERR(hdmi->vdd); } + hdmi->output.notifier = cec_notifier_get(&pdev->dev); + if (hdmi->output.notifier == NULL) + return -ENOMEM; + hdmi->output.dev = &pdev->dev; err = tegra_output_probe(&hdmi->output); @@ -1779,6 +1785,9 @@ static int tegra_hdmi_remove(struct platform_device *pdev) tegra_output_remove(&hdmi->output); + if (hdmi->output.notifier) + cec_notifier_put(hdmi->output.notifier); + return 0; } diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 595d1ec3e02e..1cfbacea8113 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -11,6 +11,8 @@ #include #include "drm.h" +#include + int tegra_output_connector_get_modes(struct drm_connector *connector) { struct tegra_output *output = connector_to_output(connector); @@ -32,6 +34,7 @@ int tegra_output_connector_get_modes(struct drm_connector *connector) else if (output->ddc) edid = drm_get_edid(connector, output->ddc); + cec_notifier_set_phys_addr_from_edid(output->notifier, edid); drm_mode_connector_update_edid_property(connector, edid); if (edid) { @@ -68,6 +71,9 @@ tegra_output_connector_detect(struct drm_connector *connector, bool force) status = connector_status_connected; } + if (status != connector_status_connected) + cec_notifier_phys_addr_invalidate(output->notifier); + return status; } -- cgit v1.2.3 From 9d35593b4f0b89ab0c194349c7d357b3b159e99a Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Wed, 18 Oct 2017 02:08:40 -0700 Subject: vmbus: hvsock: add proper sync for vmbus_hvsock_device_unregister() Without the patch, vmbus_hvsock_device_unregister() can destroy the device prematurely when close() is called, and can cause NULl dereferencing or potential data loss (the last portion of the data stream may be dropped prematurely). Signed-off-by: Dexuan Cui Cc: Haiyang Zhang Cc: Stephen Hemminger Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 018d2e0f8ec5..379b0df123be 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -937,7 +937,10 @@ void vmbus_hvsock_device_unregister(struct vmbus_channel *channel) { BUG_ON(!is_hvsock_channel(channel)); - channel->rescind = true; + /* We always get a rescind msg when a connection is closed. */ + while (!READ_ONCE(channel->probe_done) || !READ_ONCE(channel->rescind)) + msleep(1); + vmbus_device_unregister(channel->device_obj); } EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister); -- cgit v1.2.3 From 91fe77eb9585b45928b93cfe402248c77c28dab2 Mon Sep 17 00:00:00 2001 From: pding Date: Thu, 19 Oct 2017 09:38:39 +0800 Subject: drm/amdgpu: merge bios post checking functions Merge the post checking functions to avoid confusion and take virtualization into account in all cases. Signed-off-by: pding Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 41 +++++++++++++----------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0b9332e65a4c..8cf58911b17b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -744,27 +744,6 @@ bool amdgpu_need_post(struct amdgpu_device *adev) { uint32_t reg; - if (adev->has_hw_reset) { - adev->has_hw_reset = false; - return true; - } - - /* bios scratch used on CIK+ */ - if (adev->asic_type >= CHIP_BONAIRE) - return amdgpu_atombios_scratch_need_asic_init(adev); - - /* check MEM_SIZE for older asics */ - reg = amdgpu_asic_get_config_memsize(adev); - - if ((reg != 0) && (reg != 0xffffffff)) - return false; - - return true; - -} - -static bool amdgpu_vpost_needed(struct amdgpu_device *adev) -{ if (amdgpu_sriov_vf(adev)) return false; @@ -787,7 +766,23 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev) return true; } } - return amdgpu_need_post(adev); + + if (adev->has_hw_reset) { + adev->has_hw_reset = false; + return true; + } + + /* bios scratch used on CIK+ */ + if (adev->asic_type >= CHIP_BONAIRE) + return amdgpu_atombios_scratch_need_asic_init(adev); + + /* check MEM_SIZE for older asics */ + reg = amdgpu_asic_get_config_memsize(adev); + + if ((reg != 0) && (reg != 0xffffffff)) + return false; + + return true; } /** @@ -2208,7 +2203,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, amdgpu_device_detect_sriov_bios(adev); /* Post card if necessary */ - if (amdgpu_vpost_needed(adev)) { + if (amdgpu_need_post(adev)) { if (!adev->bios) { dev_err(adev->dev, "no vBIOS found\n"); amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_NO_VBIOS, 0, 0); -- cgit v1.2.3 From ef4c166dc2335bf20c7a854a0de52d17ed9f2f38 Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Fri, 22 Sep 2017 16:23:34 +0800 Subject: drm/amdgpu/sriov:now must reinit psp otherwise after VF FLR the KIQ cannot work Signed-off-by: Monk Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 8cf58911b17b..07726afd9307 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1946,6 +1946,7 @@ static int amdgpu_sriov_reinit_late(struct amdgpu_device *adev) static enum amd_ip_block_type ip_order[] = { AMD_IP_BLOCK_TYPE_SMC, + AMD_IP_BLOCK_TYPE_PSP, AMD_IP_BLOCK_TYPE_DCE, AMD_IP_BLOCK_TYPE_GFX, AMD_IP_BLOCK_TYPE_SDMA, -- cgit v1.2.3 From 6867e1b5fbd1a9deaf95a1bd23ea930063c8d216 Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Mon, 16 Oct 2017 19:50:44 +0800 Subject: drm/amdgpu:fix vf_error_put 1,it should not work on non-SR-IOV case 2,the NO_VBIOS error is incorrect, should handle it under detect_sriov_bios. 3,wrap the whole detect_sriov_bios with sriov check Signed-off-by: Monk Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 21 +++++++++++---------- drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c | 7 ++++++- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 07726afd9307..e29731c4ada7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2032,12 +2032,17 @@ static int amdgpu_resume(struct amdgpu_device *adev) static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) { - if (adev->is_atom_fw) { - if (amdgpu_atomfirmware_gpu_supports_virtualization(adev)) - adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; - } else { - if (amdgpu_atombios_has_gpu_virtualization_table(adev)) - adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; + if (amdgpu_sriov_vf(adev)) { + if (adev->is_atom_fw) { + if (amdgpu_atomfirmware_gpu_supports_virtualization(adev)) + adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; + } else { + if (amdgpu_atombios_has_gpu_virtualization_table(adev)) + adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; + } + + if (!(adev->virt.caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)) + amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_NO_VBIOS, 0, 0); } } @@ -2207,7 +2212,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (amdgpu_need_post(adev)) { if (!adev->bios) { dev_err(adev->dev, "no vBIOS found\n"); - amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_NO_VBIOS, 0, 0); r = -EINVAL; goto failed; } @@ -2215,7 +2219,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_atom_asic_init(adev->mode_info.atom_context); if (r) { dev_err(adev->dev, "gpu post error!\n"); - amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_GPU_POST_ERROR, 0, 0); goto failed; } } else { @@ -3019,7 +3022,6 @@ out: } } else { dev_err(adev->dev, "asic resume failed (%d).\n", r); - amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ASIC_RESUME_FAIL, 0, r); for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { if (adev->rings[i] && adev->rings[i]->sched.thread) { kthread_unpark(adev->rings[i]->sched.thread); @@ -3033,7 +3035,6 @@ out: if (r) { /* bad news, how to tell it to userspace ? */ dev_info(adev->dev, "GPU reset failed\n"); - amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r); } else { dev_info(adev->dev, "GPU reset successed!\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c index 746b81339835..7f7097931c6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c @@ -31,7 +31,12 @@ void amdgpu_vf_error_put(struct amdgpu_device *adev, uint64_t error_data) { int index; - uint16_t error_code = AMDGIM_ERROR_CODE(AMDGIM_ERROR_CATEGORY_VF, sub_error_code); + uint16_t error_code; + + if (!amdgpu_sriov_vf(adev)) + return; + + error_code = AMDGIM_ERROR_CODE(AMDGIM_ERROR_CATEGORY_VF, sub_error_code); mutex_lock(&adev->virt.vf_errors.lock); index = adev->virt.vf_errors.write_count % AMDGPU_VF_ERROR_ENTRY_SIZE; -- cgit v1.2.3 From 63ae07ca4fb4adcacc19272b05b5c3d398e94a56 Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Tue, 17 Oct 2017 19:18:56 +0800 Subject: drm/amdgpu:fix wb_clear Properly shift the index when clearing so we clear the right bit Signed-off-by: Monk Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e29731c4ada7..efcacb827de7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -546,7 +546,7 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb) if (offset < adev->wb.num_wb) { __set_bit(offset, adev->wb.used); - *wb = offset * 8; /* convert to dw offset */ + *wb = offset << 3; /* convert to dw offset */ return 0; } else { return -EINVAL; @@ -564,7 +564,7 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb) void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb) { if (wb < adev->wb.num_wb) - __clear_bit(wb, adev->wb.used); + __clear_bit(wb >> 3, adev->wb.used); } /** -- cgit v1.2.3 From 570e86963a511c1b404e81c72d2c42169faf9324 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 12 Oct 2017 11:57:49 -0700 Subject: drm: Widen vblank count to 64-bits [v3] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This modifies the datatypes used by the vblank code to provide 64 bits of vblank count. The driver interfaces have been left using 32 bits of vblank count; all of the code necessary to widen that value for the user API was already included to handle devices returning fewer than 32-bits. This will provide the necessary datatypes for the Vulkan API. v2: * Re-write wait_vblank ioctl to ABSOLUTE sequence When an application uses the WAIT_VBLANK ioctl with RELATIVE or NEXTONMISS bits set, the target vblank interval is updated within the kernel. We need to write that target back to the ioctl buffer and update the flags bits so that if the wait is interrupted by a signal, when it is re-started, it will target precisely the same vblank count as before. * Leave driver API with 32-bit vblank count v3: * Rebase on top of Arnd Bergmann's patch which had the switch to ktime_t parts. [airlied: fix conflict with Ville vblank change]. Suggested-by: Michel Dänzer Suggested-by: Daniel Vetter Signed-off-by: Keith Packard Signed-off-by: Dave Airlie (cherry picked from commit 2affbc16983e4fc90960bc7f70e7615f4228199b) --- drivers/gpu/drm/drm_vblank.c | 104 +++++++++++++++++++++++++++++-------------- include/drm/drm_vblank.h | 10 +++-- 2 files changed, 78 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 3af6c20ba03b..c7e5a274f419 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -251,7 +251,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, } DRM_DEBUG_VBL("updating vblank count on crtc %u:" - " current=%u, diff=%u, hw=%u hw_last=%u\n", + " current=%llu, diff=%u, hw=%u hw_last=%u\n", pipe, vblank->count, diff, cur_vblank, vblank->last); if (diff == 0) { @@ -740,17 +740,31 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, * Returns: * The software vblank counter. */ -u32 drm_crtc_vblank_count(struct drm_crtc *crtc) +u64 drm_crtc_vblank_count(struct drm_crtc *crtc) { return drm_vblank_count(crtc->dev, drm_crtc_index(crtc)); } EXPORT_SYMBOL(drm_crtc_vblank_count); -static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, +/** + * drm_vblank_count_and_time - retrieve "cooked" vblank counter value and the + * system timestamp corresponding to that vblank counter value. + * @dev: DRM device + * @pipe: index of CRTC whose counter to retrieve + * @vblanktime: Pointer to ktime_t to receive the vblank timestamp. + * + * Fetches the "cooked" vblank count value that represents the number of + * vblank events since the system was booted, including lost events due to + * modesetting activity. Returns corresponding system timestamp of the time + * of the vblank interval that corresponds to the current vblank counter value. + * + * This is the legacy version of drm_crtc_vblank_count_and_time(). + */ +static u64 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, ktime_t *vblanktime) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; - u32 vblank_count; + u64 vblank_count; unsigned int seq; if (WARN_ON(pipe >= dev->num_crtcs)) { @@ -778,7 +792,7 @@ static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, * modesetting activity. Returns corresponding system timestamp of the time * of the vblank interval that corresponds to the current vblank counter value. */ -u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, +u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, ktime_t *vblanktime) { return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc), @@ -788,7 +802,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_count_and_time); static void send_vblank_event(struct drm_device *dev, struct drm_pending_vblank_event *e, - unsigned long seq, ktime_t now) + u64 seq, ktime_t now) { struct timespec64 tv = ktime_to_timespec64(now); @@ -854,7 +868,7 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, assert_spin_locked(&dev->event_lock); e->pipe = pipe; - e->event.sequence = drm_crtc_accurate_vblank_count(crtc) + 1; + e->sequence = drm_crtc_accurate_vblank_count(crtc) + 1; e->event.crtc_id = crtc->base.id; list_add_tail(&e->base.link, &dev->vblank_event_list); } @@ -875,7 +889,8 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e) { struct drm_device *dev = crtc->dev; - unsigned int seq, pipe = drm_crtc_index(crtc); + u64 seq; + unsigned int pipe = drm_crtc_index(crtc); ktime_t now; if (dev->num_crtcs > 0) { @@ -1088,7 +1103,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc) ktime_t now; unsigned long irqflags; - unsigned int seq; + u64 seq; if (WARN_ON(pipe >= dev->num_crtcs)) return; @@ -1123,8 +1138,8 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc) if (e->pipe != pipe) continue; DRM_DEBUG("Sending premature vblank event on disable: " - "wanted %u, current %u\n", - e->event.sequence, seq); + "wanted %llu, current %llu\n", + e->sequence, seq); list_del(&e->base.link); drm_vblank_put(dev, pipe); send_vblank_event(dev, e, seq, now); @@ -1296,12 +1311,13 @@ int drm_legacy_modeset_ctl_ioctl(struct drm_device *dev, void *data, return 0; } -static inline bool vblank_passed(u32 seq, u32 ref) +static inline bool vblank_passed(u64 seq, u64 ref) { return (seq - ref) <= (1 << 23); } static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, + u64 req_seq, union drm_wait_vblank *vblwait, struct drm_file *file_priv) { @@ -1309,7 +1325,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, struct drm_pending_vblank_event *e; ktime_t now; unsigned long flags; - unsigned int seq; + u64 seq; int ret; e = kzalloc(sizeof(*e), GFP_KERNEL); @@ -1344,21 +1360,20 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, seq = drm_vblank_count_and_time(dev, pipe, &now); - DRM_DEBUG("event on vblank count %u, current %u, crtc %u\n", - vblwait->request.sequence, seq, pipe); + DRM_DEBUG("event on vblank count %llu, current %llu, crtc %u\n", + req_seq, seq, pipe); - trace_drm_vblank_event_queued(file_priv, pipe, - vblwait->request.sequence); + trace_drm_vblank_event_queued(file_priv, pipe, req_seq); - e->event.sequence = vblwait->request.sequence; - if (vblank_passed(seq, vblwait->request.sequence)) { + e->sequence = req_seq; + if (vblank_passed(seq, req_seq)) { drm_vblank_put(dev, pipe); send_vblank_event(dev, e, seq, now); vblwait->reply.sequence = seq; } else { /* drm_handle_vblank_events will call drm_vblank_put */ list_add_tail(&e->base.link, &dev->vblank_event_list); - vblwait->reply.sequence = vblwait->request.sequence; + vblwait->reply.sequence = req_seq; } spin_unlock_irqrestore(&dev->event_lock, flags); @@ -1384,6 +1399,22 @@ static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait) _DRM_VBLANK_NEXTONMISS)); } +/* + * Widen a 32-bit param to 64-bits. + * + * \param narrow 32-bit value (missing upper 32 bits) + * \param near 64-bit value that should be 'close' to near + * + * This function returns a 64-bit value using the lower 32-bits from + * 'narrow' and constructing the upper 32-bits so that the result is + * as close as possible to 'near'. + */ + +static u64 widen_32_to_64(u32 narrow, u64 near) +{ + return near + (s32) (narrow - near); +} + static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe, struct drm_wait_vblank_reply *reply) { @@ -1407,7 +1438,8 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, struct drm_vblank_crtc *vblank; union drm_wait_vblank *vblwait = data; int ret; - unsigned int flags, seq, pipe, high_pipe; + u64 req_seq, seq; + unsigned int flags, pipe, high_pipe; if (!dev->irq_enabled) return -EINVAL; @@ -1455,9 +1487,12 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { case _DRM_VBLANK_RELATIVE: - vblwait->request.sequence += seq; + req_seq = seq + vblwait->request.sequence; + vblwait->request.sequence = req_seq; vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; + break; case _DRM_VBLANK_ABSOLUTE: + req_seq = widen_32_to_64(vblwait->request.sequence, seq); break; default: ret = -EINVAL; @@ -1465,22 +1500,25 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, } if ((flags & _DRM_VBLANK_NEXTONMISS) && - vblank_passed(seq, vblwait->request.sequence)) - vblwait->request.sequence = seq + 1; + vblank_passed(seq, req_seq)) { + req_seq = seq + 1; + vblwait->request.type &= ~_DRM_VBLANK_NEXTONMISS; + vblwait->request.sequence = req_seq; + } if (flags & _DRM_VBLANK_EVENT) { /* must hold on to the vblank ref until the event fires * drm_vblank_put will be called asynchronously */ - return drm_queue_vblank_event(dev, pipe, vblwait, file_priv); + return drm_queue_vblank_event(dev, pipe, req_seq, vblwait, file_priv); } - if (vblwait->request.sequence != seq) { - DRM_DEBUG("waiting on vblank count %u, crtc %u\n", - vblwait->request.sequence, pipe); + if (req_seq != seq) { + DRM_DEBUG("waiting on vblank count %llu, crtc %u\n", + req_seq, pipe); DRM_WAIT_ON(ret, vblank->queue, 3 * HZ, vblank_passed(drm_vblank_count(dev, pipe), - vblwait->request.sequence) || + req_seq) || !READ_ONCE(vblank->enabled)); } @@ -1502,7 +1540,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) { struct drm_pending_vblank_event *e, *t; ktime_t now; - unsigned int seq; + u64 seq; assert_spin_locked(&dev->event_lock); @@ -1511,11 +1549,11 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { if (e->pipe != pipe) continue; - if (!vblank_passed(seq, e->event.sequence)) + if (!vblank_passed(seq, e->sequence)) continue; - DRM_DEBUG("vblank event on %u, current %u\n", - e->event.sequence, seq); + DRM_DEBUG("vblank event on %llu, current %llu\n", + e->sequence, seq); list_del(&e->base.link); drm_vblank_put(dev, pipe); diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index 6a58e2e91a0f..cce53130510f 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -47,6 +47,10 @@ struct drm_pending_vblank_event { * @pipe: drm_crtc_index() of the &drm_crtc this event is for. */ unsigned int pipe; + /** + * @sequence: frame event should be triggered at + */ + u64 sequence; /** * @event: Actual event which will be sent to userspace. */ @@ -88,7 +92,7 @@ struct drm_vblank_crtc { /** * @count: Current software vblank counter. */ - u32 count; + u64 count; /** * @time: Vblank timestamp corresponding to @count. */ @@ -152,8 +156,8 @@ struct drm_vblank_crtc { }; int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); -u32 drm_crtc_vblank_count(struct drm_crtc *crtc); -u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, +u64 drm_crtc_vblank_count(struct drm_crtc *crtc); +u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, ktime_t *vblanktime); void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e); -- cgit v1.2.3 From bd386e51805632abed4a0873a84af35f0c6461e3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 5 Jul 2017 14:34:23 -0700 Subject: drm: Reorganize drm_pending_event to support future event types [v2] Place drm_event_vblank in a new union that includes that and a bare drm_event structure. This will allow new members of that union to be added in the future without changing code related to the existing vbl event type. Assignments to the crtc_id field are now done when the event is allocated, rather than when delievered. This way, delivery doesn't need to have the crtc ID available. v2: * Remove 'dev' argument from create_vblank_event It wasn't being used anyways, and if we need it in the future, we can always get it from crtc->dev. * Check for MODESETTING before looking for crtc in queue_vblank_event UMS drivers will oops if we try to get a crtc, so make sure we're modesetting before we try to find a crtc_id to fill into the event. Signed-off-by: Keith Packard Reviewed-by: Sean Paul Signed-off-by: Dave Airlie (cherry picked from commit dc695b85fde88eca3ef3b03fcd82f15b6bc6e462) --- drivers/gpu/drm/drm_atomic.c | 7 +++--- drivers/gpu/drm/drm_plane.c | 2 +- drivers/gpu/drm/drm_vblank.c | 41 +++++++++++++++++++++--------------- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 4 ++-- include/drm/drm_vblank.h | 8 ++++++- 6 files changed, 40 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 562494873ca5..c2da5585e201 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1812,7 +1812,7 @@ int drm_atomic_debugfs_init(struct drm_minor *minor) */ static struct drm_pending_vblank_event *create_vblank_event( - struct drm_device *dev, uint64_t user_data) + struct drm_crtc *crtc, uint64_t user_data) { struct drm_pending_vblank_event *e = NULL; @@ -1822,7 +1822,8 @@ static struct drm_pending_vblank_event *create_vblank_event( e->event.base.type = DRM_EVENT_FLIP_COMPLETE; e->event.base.length = sizeof(e->event); - e->event.user_data = user_data; + e->event.vbl.crtc_id = crtc->base.id; + e->event.vbl.user_data = user_data; return e; } @@ -2076,7 +2077,7 @@ static int prepare_crtc_signaling(struct drm_device *dev, if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) { struct drm_pending_vblank_event *e; - e = create_vblank_event(dev, arg->user_data); + e = create_vblank_event(crtc, arg->user_data); if (!e) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 8090e50607fa..8d9824804b0c 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -1025,7 +1025,7 @@ retry: } e->event.base.type = DRM_EVENT_FLIP_COMPLETE; e->event.base.length = sizeof(e->event); - e->event.user_data = page_flip->user_data; + e->event.vbl.user_data = page_flip->user_data; ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); if (ret) { kfree(e); diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index c7e5a274f419..27b6db073a5c 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -804,20 +804,23 @@ static void send_vblank_event(struct drm_device *dev, struct drm_pending_vblank_event *e, u64 seq, ktime_t now) { - struct timespec64 tv = ktime_to_timespec64(now); - - e->event.sequence = seq; - /* - * e->event is a user space structure, with hardcoded unsigned - * 32-bit seconds/microseconds. This is safe as we always use - * monotonic timestamps since linux-4.15 - */ - e->event.tv_sec = tv.tv_sec; - e->event.tv_usec = tv.tv_nsec / 1000; - - trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, - e->event.sequence); + struct timespec64 tv; + switch (e->event.base.type) { + case DRM_EVENT_VBLANK: + case DRM_EVENT_FLIP_COMPLETE: + tv = ktime_to_timespec64(now); + e->event.vbl.sequence = seq; + /* + * e->event is a user space structure, with hardcoded unsigned + * 32-bit seconds/microseconds. This is safe as we always use + * monotonic timestamps since linux-4.15 + */ + e->event.vbl.tv_sec = tv.tv_sec; + e->event.vbl.tv_usec = tv.tv_nsec / 1000; + break; + } + trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq); drm_send_event_locked(dev, &e->base); } @@ -869,7 +872,6 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, e->pipe = pipe; e->sequence = drm_crtc_accurate_vblank_count(crtc) + 1; - e->event.crtc_id = crtc->base.id; list_add_tail(&e->base.link, &dev->vblank_event_list); } EXPORT_SYMBOL(drm_crtc_arm_vblank_event); @@ -901,7 +903,6 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, now = ktime_get(); } e->pipe = pipe; - e->event.crtc_id = crtc->base.id; send_vblank_event(dev, e, seq, now); } EXPORT_SYMBOL(drm_crtc_send_vblank_event); @@ -1336,8 +1337,14 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, e->pipe = pipe; e->event.base.type = DRM_EVENT_VBLANK; - e->event.base.length = sizeof(e->event); - e->event.user_data = vblwait->request.signal; + e->event.base.length = sizeof(e->event.vbl); + e->event.vbl.user_data = vblwait->request.signal; + e->event.vbl.crtc_id = 0; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); + if (crtc) + e->event.vbl.crtc_id = crtc->base.id; + } spin_lock_irqsave(&dev->event_lock, flags); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index d1552d3e0652..bc5f6026573d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -360,8 +360,8 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, ret = vmw_event_fence_action_queue(file_priv, fence, &event->base, - &event->event.tv_sec, - &event->event.tv_usec, + &event->event.vbl.tv_sec, + &event->event.vbl.tv_usec, true); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index ca3afae2db1f..90b5437fd787 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -549,8 +549,8 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, ret = vmw_event_fence_action_queue(file_priv, fence, &event->base, - &event->event.tv_sec, - &event->event.tv_usec, + &event->event.vbl.tv_sec, + &event->event.vbl.tv_usec, true); vmw_fence_obj_unreference(&fence); } else { diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index cce53130510f..bf8e07035a0a 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -54,7 +54,10 @@ struct drm_pending_vblank_event { /** * @event: Actual event which will be sent to userspace. */ - struct drm_event_vblank event; + union { + struct drm_event base; + struct drm_event_vblank vbl; + } event; }; /** @@ -163,6 +166,9 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e); void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e); +void drm_vblank_set_event(struct drm_pending_vblank_event *e, + u64 *seq, + ktime_t *now); bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); bool drm_crtc_handle_vblank(struct drm_crtc *crtc); int drm_crtc_vblank_get(struct drm_crtc *crtc); -- cgit v1.2.3 From 2952cd6fb4cc9834baa3774fc4051718f94dc3fe Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 18 Oct 2017 12:54:06 -0700 Subject: drm/i915: Let's use more enum intel_dpll_id pll_id. No functional change expected. Just let's use this enum when possible and also same standard pll_id name so we can rework gen9+ port clock later. Cc: Mika Kahola Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20171018195407.8618-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b8925bc82f30..933c18fd4258 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1156,14 +1156,14 @@ static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, } static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv, - uint32_t dpll) + enum intel_dpll_id pll_id) { i915_reg_t cfgcr1_reg, cfgcr2_reg; uint32_t cfgcr1_val, cfgcr2_val; uint32_t p0, p1, p2, dco_freq; - cfgcr1_reg = DPLL_CFGCR1(dpll); - cfgcr2_reg = DPLL_CFGCR2(dpll); + cfgcr1_reg = DPLL_CFGCR1(pll_id); + cfgcr2_reg = DPLL_CFGCR2(pll_id); cfgcr1_val = I915_READ(cfgcr1_reg); cfgcr2_val = I915_READ(cfgcr2_reg); @@ -1216,7 +1216,7 @@ static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv, } static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, - uint32_t pll_id) + enum intel_dpll_id pll_id) { uint32_t cfgcr0, cfgcr1; uint32_t p0, p1, p2, dco_freq, ref_clock; @@ -1303,7 +1303,8 @@ static void cnl_ddi_clock_get(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int link_clock = 0; - uint32_t cfgcr0, pll_id; + uint32_t cfgcr0; + enum intel_dpll_id pll_id; pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll); @@ -1356,17 +1357,18 @@ static void skl_ddi_clock_get(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int link_clock = 0; - uint32_t dpll_ctl1, dpll; + uint32_t dpll_ctl1; + enum intel_dpll_id pll_id; - dpll = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll); + pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll); dpll_ctl1 = I915_READ(DPLL_CTRL1); - if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) { - link_clock = skl_calc_wrpll_link(dev_priv, dpll); + if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(pll_id)) { + link_clock = skl_calc_wrpll_link(dev_priv, pll_id); } else { - link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll); - link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll); + link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(pll_id); + link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(pll_id); switch (link_clock) { case DPLL_CTRL1_LINK_RATE_810: @@ -1447,17 +1449,17 @@ static void hsw_ddi_clock_get(struct intel_encoder *encoder, } static int bxt_calc_pll_link(struct drm_i915_private *dev_priv, - enum intel_dpll_id dpll) + enum intel_dpll_id pll_id) { struct intel_shared_dpll *pll; struct intel_dpll_hw_state *state; struct dpll clock; /* For DDI ports we always use a shared PLL. */ - if (WARN_ON(dpll == DPLL_ID_PRIVATE)) + if (WARN_ON(pll_id == DPLL_ID_PRIVATE)) return 0; - pll = &dev_priv->shared_dplls[dpll]; + pll = &dev_priv->shared_dplls[pll_id]; state = &pll->state.hw_state; clock.m1 = 2; @@ -1476,9 +1478,9 @@ static void bxt_ddi_clock_get(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = intel_ddi_get_encoder_port(encoder); - uint32_t dpll = port; + enum intel_dpll_id pll_id = port; - pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll); + pipe_config->port_clock = bxt_calc_pll_link(dev_priv, pll_id); ddi_dotclock_get(pipe_config); } -- cgit v1.2.3 From 9c3b2689d01ff03e2b8e8d47538881dbff756d78 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 20 Oct 2017 10:26:41 -0700 Subject: drm/i915/cnl: Map VBT DDC Pin to BSpec DDC Pin. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting on CNL we now need to map VBT DDC Pin to BSPec DDC Pin values. Not a direct translation anymore. According to VBT Block 2 (General Bytes Definition) DDC Bus +----------+-----------+--------------------+ | DDI Type | VBT Value | Bspec Mapped Value | +----------+-----------+--------------------+ | DDI-B | 0x1 | 0x1 | | DDI-C | 0x2 | 0x2 | | DDI-D | 0x3 | 0x4 | | DDI-F | 0x4 | 0x3 | +----------+-----------+--------------------+ v2: Move defines to a better place. This is actually CNL_PCH not CNL only. v3: Accepting Ville's suggestions: enums and array to to make this future proof. v4: Protect the array access as Ville suggested. Also accepting all Jani's suggestions: - use already defined gmbus pin definitions. - use map_ddc_pin for disambiguation. - Add /* sic */ comment on inverted values so people can easily see it it nos a mistake we have the map 3 -> 4 and 4 -> 3 :/ Cc: Jani Nikula Cc: Paulo Zanoni Cc: Anusha Srivatsa Cc: Clinton Taylor Cc: Ville Syrjälä Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171020172641.16029-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 27 +++++++++++++++++---------- drivers/gpu/drm/i915/intel_vbt_defs.h | 8 ++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index a0c42e6c9873..5e122673d32a 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1106,6 +1106,22 @@ static void sanitize_aux_ch(struct drm_i915_private *dev_priv, } } +static const u8 cnp_ddc_pin_map[] = { + [DDC_BUS_DDI_B] = GMBUS_PIN_1_BXT, + [DDC_BUS_DDI_C] = GMBUS_PIN_2_BXT, + [DDC_BUS_DDI_D] = GMBUS_PIN_4_CNP, /* sic */ + [DDC_BUS_DDI_F] = GMBUS_PIN_3_BXT, /* sic */ +}; + +static u8 map_ddc_pin(struct drm_i915_private *dev_priv, u8 vbt_pin) +{ + if (HAS_PCH_CNP(dev_priv) && + vbt_pin > 0 && vbt_pin < ARRAY_SIZE(cnp_ddc_pin_map)) + return cnp_ddc_pin_map[vbt_pin]; + + return vbt_pin; +} + static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, u8 bdb_version) { @@ -1191,16 +1207,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port)); if (is_dvi) { - info->alternate_ddc_pin = ddc_pin; - - /* - * All VBTs that we got so far for B Stepping has this - * information wrong for Port D. So, let's just ignore for now. - */ - if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0) && - port == PORT_D) { - info->alternate_ddc_pin = 0; - } + info->alternate_ddc_pin = map_ddc_pin(dev_priv, ddc_pin); sanitize_ddc_pin(dev_priv, port); } diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h index 404569c9fdfc..f225c288a121 100644 --- a/drivers/gpu/drm/i915/intel_vbt_defs.h +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h @@ -306,6 +306,14 @@ struct bdb_general_features { #define LEGACY_CHILD_DEVICE_CONFIG_SIZE 33 +/* DDC Bus DDI Type 155+ */ +enum vbt_gmbus_ddi { + DDC_BUS_DDI_B = 0x1, + DDC_BUS_DDI_C, + DDC_BUS_DDI_D, + DDC_BUS_DDI_F, +}; + /* * The child device config, aka the display device data structure, provides a * description of a port and its configuration on the platform. -- cgit v1.2.3 From 772e97b57a4aa00170ad505a40ffad31d987ce1d Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Thu, 19 Oct 2017 13:31:28 +0200 Subject: geneve: Fix function matching VNI and tunnel ID on big-endian On big-endian machines, functions converting between tunnel ID and VNI use the three LSBs of tunnel ID storage to map VNI. The comparison function eq_tun_id_and_vni(), on the other hand, attempted to map the VNI from the three MSBs. Fix it by using the same check implemented on LE, which maps VNI from the three LSBs of tunnel ID. Fixes: 2e0b26e10352 ("geneve: Optimize geneve device lookup.") Signed-off-by: Stefano Brivio Reviewed-by: Jakub Sitnicki Signed-off-by: David S. Miller --- drivers/net/geneve.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index f6404074b7b0..ed51018a813e 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -113,13 +113,7 @@ static void tunnel_id_to_vni(__be64 tun_id, __u8 *vni) static bool eq_tun_id_and_vni(u8 *tun_id, u8 *vni) { -#ifdef __BIG_ENDIAN - return (vni[0] == tun_id[2]) && - (vni[1] == tun_id[1]) && - (vni[2] == tun_id[0]); -#else return !memcmp(vni, &tun_id[5], 3); -#endif } static sa_family_t geneve_get_sk_family(struct geneve_sock *gs) -- cgit v1.2.3 From a0c2baaf81bd53dc76fccdddc721ba7dbb62be21 Mon Sep 17 00:00:00 2001 From: Sherry Yang Date: Fri, 20 Oct 2017 20:58:58 -0400 Subject: android: binder: Don't get mm from task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use binder_alloc struct's mm_struct rather than getting a reference to the mm struct through get_task_mm to avoid a potential deadlock between lru lock, task lock and dentry lock, since a thread can be holding the task lock and the dentry lock while trying to acquire the lru lock. Acked-by: Arve Hjønnevåg Signed-off-by: Sherry Yang Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder_alloc.c | 22 +++++++++------------- drivers/android/binder_alloc.h | 1 - 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 064f5e31ec55..e12072b1d507 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -215,17 +215,12 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, } } - if (!vma && need_mm) - mm = get_task_mm(alloc->tsk); + if (!vma && need_mm && mmget_not_zero(alloc->vma_vm_mm)) + mm = alloc->vma_vm_mm; if (mm) { down_write(&mm->mmap_sem); vma = alloc->vma; - if (vma && mm != alloc->vma_vm_mm) { - pr_err("%d: vma mm and task mm mismatch\n", - alloc->pid); - vma = NULL; - } } if (!vma && need_mm) { @@ -720,6 +715,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, barrier(); alloc->vma = vma; alloc->vma_vm_mm = vma->vm_mm; + mmgrab(alloc->vma_vm_mm); return 0; @@ -795,6 +791,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc) vfree(alloc->buffer); } mutex_unlock(&alloc->mutex); + if (alloc->vma_vm_mm) + mmdrop(alloc->vma_vm_mm); binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d buffers %d, pages %d\n", @@ -889,7 +887,6 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc) void binder_alloc_vma_close(struct binder_alloc *alloc) { WRITE_ONCE(alloc->vma, NULL); - WRITE_ONCE(alloc->vma_vm_mm, NULL); } /** @@ -926,9 +923,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item, page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; vma = alloc->vma; if (vma) { - mm = get_task_mm(alloc->tsk); - if (!mm) - goto err_get_task_mm_failed; + if (!mmget_not_zero(alloc->vma_vm_mm)) + goto err_mmget; + mm = alloc->vma_vm_mm; if (!down_write_trylock(&mm->mmap_sem)) goto err_down_write_mmap_sem_failed; } @@ -963,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, err_down_write_mmap_sem_failed: mmput_async(mm); -err_get_task_mm_failed: +err_mmget: err_page_already_freed: mutex_unlock(&alloc->mutex); err_get_alloc_mutex_failed: @@ -1002,7 +999,6 @@ struct shrinker binder_shrinker = { */ void binder_alloc_init(struct binder_alloc *alloc) { - alloc->tsk = current->group_leader; alloc->pid = current->group_leader->pid; mutex_init(&alloc->mutex); INIT_LIST_HEAD(&alloc->buffers); diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index a3a3602c689c..2dd33b6df104 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -100,7 +100,6 @@ struct binder_lru_page { */ struct binder_alloc { struct mutex mutex; - struct task_struct *tsk; struct vm_area_struct *vma; struct mm_struct *vma_vm_mm; void *buffer; -- cgit v1.2.3 From ae65c8510f3319dfb2114cc48d476b81232e27b3 Mon Sep 17 00:00:00 2001 From: Sherry Yang Date: Fri, 20 Oct 2017 20:58:59 -0400 Subject: android: binder: Fix null ptr dereference in debug msg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't access next->data in kernel debug message when the next buffer is null. Acked-by: Arve Hjønnevåg Signed-off-by: Sherry Yang Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index e12072b1d507..c2819a3d58a6 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -560,7 +560,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc, binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: merge free, buffer %pK do not share page with %pK or %pK\n", alloc->pid, buffer->data, - prev->data, next->data); + prev->data, next ? next->data : NULL); binder_update_page_range(alloc, 0, buffer_start_page(buffer), buffer_start_page(buffer) + PAGE_SIZE, NULL); -- cgit v1.2.3 From 65e665e68d097edfe667372f13d54f3e4edcb69c Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Thu, 19 Oct 2017 18:23:53 +0300 Subject: net: aquantia: Reset nic statistics on interface up/down Internal statistics system on chip never gets reset until hardware reboot. This is quite inconvenient in terms of ethtool statistics usage. This patch implements incremental statistics update inside of service callback. Upon nic initialization, first request is done to fetch initial stat data, current collected stat data gets cleared. Internal statistics mailbox readout is improved to save space and increase readability Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 2 + drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 3 + .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 1 + .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 1 + .../aquantia/atlantic/hw_atl/hw_atl_utils.c | 69 +++++++++++++++++----- .../aquantia/atlantic/hw_atl/hw_atl_utils.h | 16 ++++- 6 files changed, 75 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index bf9b3f020e10..3a8baaef053c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -163,6 +163,8 @@ struct aq_hw_ops { int (*hw_get_regs)(struct aq_hw_s *self, struct aq_hw_caps_s *aq_hw_caps, u32 *regs_buff); + int (*hw_update_stats)(struct aq_hw_s *self); + int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data, unsigned int *p_count); diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 0a5bb4114eb4..6b49dd658012 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -167,6 +167,9 @@ static void aq_nic_service_timer_cb(unsigned long param) self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, self->aq_nic_cfg.is_interrupt_moderation); + if (self->aq_hw_ops.hw_update_stats) + self->aq_hw_ops.hw_update_stats(self->aq_hw); + memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); for (i = AQ_DIMOF(self->aq_vec); i--;) { diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c index c5a02df7a48b..b0747b2486b2 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c @@ -885,6 +885,7 @@ static struct aq_hw_ops hw_atl_ops_ = { .hw_rss_set = hw_atl_a0_hw_rss_set, .hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set, .hw_get_regs = hw_atl_utils_hw_get_regs, + .hw_update_stats = hw_atl_utils_update_stats, .hw_get_hw_stats = hw_atl_utils_get_hw_stats, .hw_get_fw_version = hw_atl_utils_get_fw_version, }; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 21784cc39dab..6f6e70aa1047 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -939,6 +939,7 @@ static struct aq_hw_ops hw_atl_ops_ = { .hw_rss_set = hw_atl_b0_hw_rss_set, .hw_rss_hash_set = hw_atl_b0_hw_rss_hash_set, .hw_get_regs = hw_atl_utils_hw_get_regs, + .hw_update_stats = hw_atl_utils_update_stats, .hw_get_hw_stats = hw_atl_utils_get_hw_stats, .hw_get_fw_version = hw_atl_utils_get_fw_version, }; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c index bf734b32e44b..1fe016fc4bc7 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c @@ -255,6 +255,15 @@ err_exit: return err; } +int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self, + struct hw_aq_atl_utils_mbox_header *pmbox) +{ + return hw_atl_utils_fw_downld_dwords(self, + PHAL_ATLANTIC->mbox_addr, + (u32 *)(void *)pmbox, + sizeof(*pmbox) / sizeof(u32)); +} + void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, struct hw_aq_atl_utils_mbox *pmbox) { @@ -267,9 +276,6 @@ void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, if (err < 0) goto err_exit; - if (pmbox != &PHAL_ATLANTIC->mbox) - memcpy(pmbox, &PHAL_ATLANTIC->mbox, sizeof(*pmbox)); - if (IS_CHIP_FEATURE(REVISION_A0)) { unsigned int mtu = self->aq_nic_cfg ? self->aq_nic_cfg->mtu : 1514U; @@ -299,17 +305,17 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self, { int err = 0; u32 transaction_id = 0; + struct hw_aq_atl_utils_mbox_header mbox; if (state == MPI_RESET) { - hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox); + hw_atl_utils_mpi_read_mbox(self, &mbox); - transaction_id = PHAL_ATLANTIC->mbox.transaction_id; + transaction_id = mbox.transaction_id; AQ_HW_WAIT_FOR(transaction_id != - (hw_atl_utils_mpi_read_stats - (self, &PHAL_ATLANTIC->mbox), - PHAL_ATLANTIC->mbox.transaction_id), - 1000U, 100U); + (hw_atl_utils_mpi_read_mbox(self, &mbox), + mbox.transaction_id), + 1000U, 100U); if (err < 0) goto err_exit; } @@ -492,16 +498,51 @@ int hw_atl_utils_hw_set_power(struct aq_hw_s *self, return 0; } +int hw_atl_utils_update_stats(struct aq_hw_s *self) +{ + struct hw_atl_s *hw_self = PHAL_ATLANTIC; + struct hw_aq_atl_utils_mbox mbox; + + if (!self->aq_link_status.mbps) + return 0; + + hw_atl_utils_mpi_read_stats(self, &mbox); + +#define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \ + mbox.stats._N_ - hw_self->last_stats._N_) + + AQ_SDELTA(uprc); + AQ_SDELTA(mprc); + AQ_SDELTA(bprc); + AQ_SDELTA(erpt); + + AQ_SDELTA(uptc); + AQ_SDELTA(mptc); + AQ_SDELTA(bptc); + AQ_SDELTA(erpr); + + AQ_SDELTA(ubrc); + AQ_SDELTA(ubtc); + AQ_SDELTA(mbrc); + AQ_SDELTA(mbtc); + AQ_SDELTA(bbrc); + AQ_SDELTA(bbtc); + AQ_SDELTA(dpc); + +#undef AQ_SDELTA + + memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats)); + + return 0; +} + int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, u64 *data, unsigned int *p_count) { - struct hw_atl_stats_s *stats = NULL; + struct hw_atl_s *hw_self = PHAL_ATLANTIC; + struct hw_atl_stats_s *stats = &hw_self->curr_stats; int i = 0; - hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox); - - stats = &PHAL_ATLANTIC->mbox.stats; - data[i] = stats->uprc + stats->mprc + stats->bprc; data[++i] = stats->uprc; data[++i] = stats->mprc; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h index e0360a6b2202..2218bdb605a7 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h @@ -115,16 +115,21 @@ struct __packed hw_aq_atl_utils_fw_rpc { }; }; -struct __packed hw_aq_atl_utils_mbox { +struct __packed hw_aq_atl_utils_mbox_header { u32 version; u32 transaction_id; - int error; + u32 error; +}; + +struct __packed hw_aq_atl_utils_mbox { + struct hw_aq_atl_utils_mbox_header header; struct hw_atl_stats_s stats; }; struct __packed hw_atl_s { struct aq_hw_s base; - struct hw_aq_atl_utils_mbox mbox; + struct hw_atl_stats_s last_stats; + struct hw_atl_stats_s curr_stats; u64 speed; u32 itr_tx; u32 itr_rx; @@ -170,6 +175,9 @@ enum hal_atl_utils_fw_state_e { void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p); +int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self, + struct hw_aq_atl_utils_mbox_header *pmbox); + void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, struct hw_aq_atl_utils_mbox *pmbox); @@ -199,6 +207,8 @@ int hw_atl_utils_hw_deinit(struct aq_hw_s *self); int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version); +int hw_atl_utils_update_stats(struct aq_hw_s *self); + int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, u64 *data, unsigned int *p_count); -- cgit v1.2.3 From 5d8d84e91d7432cd206b27ad791a11220689ac53 Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Thu, 19 Oct 2017 18:23:54 +0300 Subject: net: aquantia: Add queue restarts stats counter Queue stat strings are cleaned up, duplicate stat name strings removed, queue restarts counter added Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- .../net/ethernet/aquantia/atlantic/aq_ethtool.c | 92 ++++++++-------------- drivers/net/ethernet/aquantia/atlantic/aq_vec.c | 3 + 2 files changed, 37 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c index a761e91471df..3eab4089e91a 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c @@ -56,10 +56,6 @@ aq_ethtool_set_link_ksettings(struct net_device *ndev, return aq_nic_set_link_ksettings(aq_nic, cmd); } -/* there "5U" is number of queue[#] stats lines (InPackets+...+InErrors) */ -static const unsigned int aq_ethtool_stat_queue_lines = 5U; -static const unsigned int aq_ethtool_stat_queue_chars = - 5U * ETH_GSTRING_LEN; static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { "InPackets", "InUCast", @@ -83,56 +79,26 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { "InOctetsDma", "OutOctetsDma", "InDroppedDma", - "Queue[0] InPackets", - "Queue[0] OutPackets", - "Queue[0] InJumboPackets", - "Queue[0] InLroPackets", - "Queue[0] InErrors", - "Queue[1] InPackets", - "Queue[1] OutPackets", - "Queue[1] InJumboPackets", - "Queue[1] InLroPackets", - "Queue[1] InErrors", - "Queue[2] InPackets", - "Queue[2] OutPackets", - "Queue[2] InJumboPackets", - "Queue[2] InLroPackets", - "Queue[2] InErrors", - "Queue[3] InPackets", - "Queue[3] OutPackets", - "Queue[3] InJumboPackets", - "Queue[3] InLroPackets", - "Queue[3] InErrors", - "Queue[4] InPackets", - "Queue[4] OutPackets", - "Queue[4] InJumboPackets", - "Queue[4] InLroPackets", - "Queue[4] InErrors", - "Queue[5] InPackets", - "Queue[5] OutPackets", - "Queue[5] InJumboPackets", - "Queue[5] InLroPackets", - "Queue[5] InErrors", - "Queue[6] InPackets", - "Queue[6] OutPackets", - "Queue[6] InJumboPackets", - "Queue[6] InLroPackets", - "Queue[6] InErrors", - "Queue[7] InPackets", - "Queue[7] OutPackets", - "Queue[7] InJumboPackets", - "Queue[7] InLroPackets", - "Queue[7] InErrors", +}; + +static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = { + "Queue[%d] InPackets", + "Queue[%d] OutPackets", + "Queue[%d] Restarts", + "Queue[%d] InJumboPackets", + "Queue[%d] InLroPackets", + "Queue[%d] InErrors", }; static void aq_ethtool_stats(struct net_device *ndev, struct ethtool_stats *stats, u64 *data) { struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); -/* ASSERT: Need add lines to aq_ethtool_stat_names if AQ_CFG_VECS_MAX > 8 */ - BUILD_BUG_ON(AQ_CFG_VECS_MAX > 8); - memset(data, 0, ARRAY_SIZE(aq_ethtool_stat_names) * sizeof(u64)); + memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) + + ARRAY_SIZE(aq_ethtool_queue_stat_names) * + cfg->vecs) * sizeof(u64)); aq_nic_get_stats(aq_nic, data); } @@ -154,8 +120,8 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev, strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "", sizeof(drvinfo->bus_info)); - drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) - - (AQ_CFG_VECS_MAX - cfg->vecs) * aq_ethtool_stat_queue_lines; + drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) + + cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); drvinfo->testinfo_len = 0; drvinfo->regdump_len = regs_count; drvinfo->eedump_len = 0; @@ -164,14 +130,25 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev, static void aq_ethtool_get_strings(struct net_device *ndev, u32 stringset, u8 *data) { + int i, si; struct aq_nic_s *aq_nic = netdev_priv(ndev); struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); - - if (stringset == ETH_SS_STATS) - memcpy(data, *aq_ethtool_stat_names, - sizeof(aq_ethtool_stat_names) - - (AQ_CFG_VECS_MAX - cfg->vecs) * - aq_ethtool_stat_queue_chars); + u8 *p = data; + + if (stringset == ETH_SS_STATS) { + memcpy(p, *aq_ethtool_stat_names, + sizeof(aq_ethtool_stat_names)); + p = p + sizeof(aq_ethtool_stat_names); + for (i = 0; i < cfg->vecs; i++) { + for (si = 0; + si < ARRAY_SIZE(aq_ethtool_queue_stat_names); + si++) { + snprintf(p, ETH_GSTRING_LEN, + aq_ethtool_queue_stat_names[si], i); + p += ETH_GSTRING_LEN; + } + } + } } static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset) @@ -182,9 +159,8 @@ static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset) switch (stringset) { case ETH_SS_STATS: - ret = ARRAY_SIZE(aq_ethtool_stat_names) - - (AQ_CFG_VECS_MAX - cfg->vecs) * - aq_ethtool_stat_queue_lines; + ret = ARRAY_SIZE(aq_ethtool_stat_names) + + cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); break; default: ret = -EOPNOTSUPP; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c index 305ff8ffac2c..5fecc9a099ef 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c @@ -373,8 +373,11 @@ int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count) memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); aq_vec_add_stats(self, &stats_rx, &stats_tx); + /* This data should mimic aq_ethtool_queue_stat_names structure + */ data[count] += stats_rx.packets; data[++count] += stats_tx.packets; + data[++count] += stats_tx.queue_restarts; data[++count] += stats_rx.jumbo_packets; data[++count] += stats_rx.lro_packets; data[++count] += stats_rx.errors; -- cgit v1.2.3 From 93d87b8fbe6cf17f0ad9552a934b5a6623ccd7d1 Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Thu, 19 Oct 2017 18:23:55 +0300 Subject: net: aquantia: Fixed transient link up/down/up notification When doing ifconfig down/up, driver did not reported carrier_off neither in nic_stop nor in nic_start. That caused link to be visible as "up" during couple of seconds immediately after "ifconfig up". Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 6b49dd658012..9378b4877783 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -337,6 +337,7 @@ struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev) } if (netif_running(ndev)) netif_tx_disable(ndev); + netif_carrier_off(self->ndev); for (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs; self->aq_vecs++) { @@ -902,6 +903,7 @@ int aq_nic_stop(struct aq_nic_s *self) unsigned int i = 0U; netif_tx_disable(self->ndev); + netif_carrier_off(self->ndev); del_timer_sync(&self->service_timer); -- cgit v1.2.3 From 4c8bb609d304df72858aa2e5e74abab5246bd24b Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Thu, 19 Oct 2017 18:23:56 +0300 Subject: net: aquantia: Limit number of MSIX irqs to the number of cpus There is no much practical use from having MSIX vectors more that number of cpus, thus cap this first with preconfigured limit, then with number of cpus online. Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index 4c6c882c6a1c..727f0a446ef1 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@ -85,6 +85,7 @@ int aq_pci_func_init(struct aq_pci_func_s *self) int err = 0; unsigned int bar = 0U; unsigned int port = 0U; + unsigned int numvecs = 0U; err = pci_enable_device(self->pdev); if (err < 0) @@ -142,10 +143,12 @@ int aq_pci_func_init(struct aq_pci_func_s *self) } } - /*enable interrupts */ + numvecs = min((u8)AQ_CFG_VECS_DEF, self->aq_hw_caps.msix_irqs); + numvecs = min(numvecs, num_online_cpus()); + + /* enable interrupts */ #if !AQ_CFG_FORCE_LEGACY_INT - err = pci_alloc_irq_vectors(self->pdev, self->aq_hw_caps.msix_irqs, - self->aq_hw_caps.msix_irqs, PCI_IRQ_MSIX); + err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs, PCI_IRQ_MSIX); if (err < 0) { err = pci_alloc_irq_vectors(self->pdev, 1, 1, @@ -153,7 +156,7 @@ int aq_pci_func_init(struct aq_pci_func_s *self) if (err < 0) goto err_exit; } -#endif +#endif /* AQ_CFG_FORCE_LEGACY_INT */ /* net device init */ for (port = 0; port < self->ports; ++port) { -- cgit v1.2.3 From 6849540adc0bcc8c648d7c11be169d2ca267fbca Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Thu, 19 Oct 2017 18:23:57 +0300 Subject: net: aquantia: mmio unmap was not performed on driver removal That may lead to mmio resource leakage. Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index 727f0a446ef1..cadaa646c89f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@ -268,6 +268,9 @@ void aq_pci_func_free(struct aq_pci_func_s *self) aq_nic_ndev_free(self->port[port]); } + if (self->mmio) + iounmap(self->mmio); + kfree(self); err_exit:; -- cgit v1.2.3 From b82ee71a86b0ea66da79a91959d800ffb696a5cb Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Thu, 19 Oct 2017 18:23:58 +0300 Subject: net: aquantia: Enable coalescing management via ethtool interface Aquantia NIC allows both TX and RX interrupt throttle rate (ITR) management, but this was used in a very limited way via predefined values. This patch allows to setup ITR default values via module command line arguments and via standard ethtool coalescing settings. Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_cfg.h | 8 ++- .../net/ethernet/aquantia/atlantic/aq_ethtool.c | 65 ++++++++++++++++++ drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 3 +- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 36 +++++++--- drivers/net/ethernet/aquantia/atlantic/aq_nic.h | 4 +- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 20 +++--- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 76 ++++++++++++---------- .../aquantia/atlantic/hw_atl/hw_atl_b0_internal.h | 3 + .../aquantia/atlantic/hw_atl/hw_atl_utils.h | 2 - 9 files changed, 155 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h index 0fdaaa643073..57e796870595 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h @@ -22,8 +22,12 @@ #define AQ_CFG_FORCE_LEGACY_INT 0U -#define AQ_CFG_IS_INTERRUPT_MODERATION_DEF 1U -#define AQ_CFG_INTERRUPT_MODERATION_RATE_DEF 0xFFFFU +#define AQ_CFG_INTERRUPT_MODERATION_OFF 0 +#define AQ_CFG_INTERRUPT_MODERATION_ON 1 +#define AQ_CFG_INTERRUPT_MODERATION_AUTO 0xFFFFU + +#define AQ_CFG_INTERRUPT_MODERATION_USEC_MAX (0x1FF * 2) + #define AQ_CFG_IRQ_MASK 0x1FFU #define AQ_CFG_VECS_MAX 8U diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c index 3eab4089e91a..d5e99b468870 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c @@ -221,6 +221,69 @@ static int aq_ethtool_get_rxnfc(struct net_device *ndev, return err; } +int aq_ethtool_get_coalesce(struct net_device *ndev, + struct ethtool_coalesce *coal) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + + if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON || + cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) { + coal->rx_coalesce_usecs = cfg->rx_itr; + coal->tx_coalesce_usecs = cfg->tx_itr; + coal->rx_max_coalesced_frames = 0; + coal->tx_max_coalesced_frames = 0; + } else { + coal->rx_coalesce_usecs = 0; + coal->tx_coalesce_usecs = 0; + coal->rx_max_coalesced_frames = 1; + coal->tx_max_coalesced_frames = 1; + } + return 0; +} + +int aq_ethtool_set_coalesce(struct net_device *ndev, + struct ethtool_coalesce *coal) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); + + /* This is not yet supported + */ + if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce) + return -EOPNOTSUPP; + + /* Atlantic only supports timing based coalescing + */ + if (coal->rx_max_coalesced_frames > 1 || + coal->rx_coalesce_usecs_irq || + coal->rx_max_coalesced_frames_irq) + return -EOPNOTSUPP; + + if (coal->tx_max_coalesced_frames > 1 || + coal->tx_coalesce_usecs_irq || + coal->tx_max_coalesced_frames_irq) + return -EOPNOTSUPP; + + /* We do not support frame counting. Check this + */ + if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs)) + return -EOPNOTSUPP; + if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs)) + return -EOPNOTSUPP; + + if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX || + coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX) + return -EINVAL; + + cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON; + + cfg->rx_itr = coal->rx_coalesce_usecs; + cfg->tx_itr = coal->tx_coalesce_usecs; + + return aq_nic_update_interrupt_moderation_settings(aq_nic); +} + const struct ethtool_ops aq_ethtool_ops = { .get_link = aq_ethtool_get_link, .get_regs_len = aq_ethtool_get_regs_len, @@ -235,4 +298,6 @@ const struct ethtool_ops aq_ethtool_ops = { .get_ethtool_stats = aq_ethtool_stats, .get_link_ksettings = aq_ethtool_get_link_ksettings, .set_link_ksettings = aq_ethtool_set_link_ksettings, + .get_coalesce = aq_ethtool_get_coalesce, + .set_coalesce = aq_ethtool_set_coalesce, }; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index 3a8baaef053c..0207927dc8a6 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -151,8 +151,7 @@ struct aq_hw_ops { [ETH_ALEN], u32 count); - int (*hw_interrupt_moderation_set)(struct aq_hw_s *self, - bool itr_enabled); + int (*hw_interrupt_moderation_set)(struct aq_hw_s *self); int (*hw_rss_set)(struct aq_hw_s *self, struct aq_rss_parameters *rss_params); diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 9378b4877783..483e97691eea 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -16,6 +16,7 @@ #include "aq_pci_func.h" #include "aq_nic_internal.h" +#include #include #include #include @@ -24,6 +25,18 @@ #include #include +static unsigned int aq_itr = AQ_CFG_INTERRUPT_MODERATION_AUTO; +module_param_named(aq_itr, aq_itr, uint, 0644); +MODULE_PARM_DESC(aq_itr, "Interrupt throttling mode"); + +static unsigned int aq_itr_tx; +module_param_named(aq_itr_tx, aq_itr_tx, uint, 0644); +MODULE_PARM_DESC(aq_itr_tx, "TX interrupt throttle rate"); + +static unsigned int aq_itr_rx; +module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644); +MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate"); + static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues) { struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; @@ -61,9 +74,9 @@ static void aq_nic_cfg_init_defaults(struct aq_nic_s *self) cfg->is_polling = AQ_CFG_IS_POLLING_DEF; - cfg->is_interrupt_moderation = AQ_CFG_IS_INTERRUPT_MODERATION_DEF; - cfg->itr = cfg->is_interrupt_moderation ? - AQ_CFG_INTERRUPT_MODERATION_RATE_DEF : 0U; + cfg->itr = aq_itr; + cfg->tx_itr = aq_itr_tx; + cfg->rx_itr = aq_itr_rx; cfg->is_rss = AQ_CFG_IS_RSS_DEF; cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF; @@ -126,10 +139,12 @@ static int aq_nic_update_link_status(struct aq_nic_s *self) if (err) return err; - if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) + if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) { pr_info("%s: link change old %d new %d\n", AQ_CFG_DRV_NAME, self->link_status.mbps, self->aq_hw->aq_link_status.mbps); + aq_nic_update_interrupt_moderation_settings(self); + } self->link_status = self->aq_hw->aq_link_status; if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) { @@ -164,9 +179,6 @@ static void aq_nic_service_timer_cb(unsigned long param) if (err) goto err_exit; - self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, - self->aq_nic_cfg.is_interrupt_moderation); - if (self->aq_hw_ops.hw_update_stats) self->aq_hw_ops.hw_update_stats(self->aq_hw); @@ -425,9 +437,8 @@ int aq_nic_start(struct aq_nic_s *self) if (err < 0) goto err_exit; - err = self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, - self->aq_nic_cfg.is_interrupt_moderation); - if (err < 0) + err = aq_nic_update_interrupt_moderation_settings(self); + if (err) goto err_exit; setup_timer(&self->service_timer, &aq_nic_service_timer_cb, (unsigned long)self); @@ -649,6 +660,11 @@ err_exit: return err; } +int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self) +{ + return self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw); +} + int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags) { int err = 0; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h index 0ddd556ff901..4309983acdd6 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h @@ -40,6 +40,8 @@ struct aq_nic_cfg_s { u32 vecs; /* vecs==allocated irqs */ u32 irq_type; u32 itr; + u16 rx_itr; + u16 tx_itr; u32 num_rss_queues; u32 mtu; u32 ucp_0x364; @@ -49,7 +51,6 @@ struct aq_nic_cfg_s { u16 is_mc_list_enabled; u16 mc_list_count; bool is_autoneg; - bool is_interrupt_moderation; bool is_polling; bool is_rss; bool is_lro; @@ -104,5 +105,6 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self, struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self); u32 aq_nic_get_fw_version(struct aq_nic_s *self); int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg); +int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self); #endif /* AQ_NIC_H */ diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c index b0747b2486b2..07b3c49a16a4 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c @@ -765,24 +765,23 @@ err_exit: return err; } -static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self, - bool itr_enabled) +static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self) { unsigned int i = 0U; + u32 itr_rx; - if (itr_enabled && self->aq_nic_cfg->itr) { - if (self->aq_nic_cfg->itr != 0xFFFFU) { + if (self->aq_nic_cfg->itr) { + if (self->aq_nic_cfg->itr != AQ_CFG_INTERRUPT_MODERATION_AUTO) { u32 itr_ = (self->aq_nic_cfg->itr >> 1); itr_ = min(AQ_CFG_IRQ_MASK, itr_); - PHAL_ATLANTIC_A0->itr_rx = 0x80000000U | - (itr_ << 0x10); + itr_rx = 0x80000000U | (itr_ << 0x10); } else { u32 n = 0xFFFFU & aq_hw_read_reg(self, 0x00002A00U); if (n < self->aq_link_status.mbps) { - PHAL_ATLANTIC_A0->itr_rx = 0U; + itr_rx = 0U; } else { static unsigned int hw_timers_tbl_[] = { 0x01CU, /* 10Gbit */ @@ -797,8 +796,7 @@ static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self, hw_atl_utils_mbps_2_speed_index( self->aq_link_status.mbps); - PHAL_ATLANTIC_A0->itr_rx = - 0x80000000U | + itr_rx = 0x80000000U | (hw_timers_tbl_[speed_index] << 0x10U); } @@ -806,11 +804,11 @@ static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self, aq_hw_write_reg(self, 0x00002A00U, 0x8D000000U); } } else { - PHAL_ATLANTIC_A0->itr_rx = 0U; + itr_rx = 0U; } for (i = HW_ATL_A0_RINGS_MAX; i--;) - reg_irq_thr_set(self, PHAL_ATLANTIC_A0->itr_rx, i); + reg_irq_thr_set(self, itr_rx, i); return aq_hw_err_from_flags(self); } diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 6f6e70aa1047..11f7e71bf448 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -788,31 +788,37 @@ err_exit: return err; } -static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self, - bool itr_enabled) +static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) { unsigned int i = 0U; + u32 itr_tx = 2U; + u32 itr_rx = 2U; - if (itr_enabled && self->aq_nic_cfg->itr) { + switch (self->aq_nic_cfg->itr) { + case AQ_CFG_INTERRUPT_MODERATION_ON: + case AQ_CFG_INTERRUPT_MODERATION_AUTO: tdm_tx_desc_wr_wb_irq_en_set(self, 0U); tdm_tdm_intr_moder_en_set(self, 1U); rdm_rx_desc_wr_wb_irq_en_set(self, 0U); rdm_rdm_intr_moder_en_set(self, 1U); - PHAL_ATLANTIC_B0->itr_tx = 2U; - PHAL_ATLANTIC_B0->itr_rx = 2U; + if (self->aq_nic_cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON) { + /* HW timers are in 2us units */ + int tx_max_timer = self->aq_nic_cfg->tx_itr / 2; + int tx_min_timer = tx_max_timer / 2; - if (self->aq_nic_cfg->itr != 0xFFFFU) { - unsigned int max_timer = self->aq_nic_cfg->itr / 2U; - unsigned int min_timer = self->aq_nic_cfg->itr / 32U; + int rx_max_timer = self->aq_nic_cfg->rx_itr / 2; + int rx_min_timer = rx_max_timer / 2; - max_timer = min(0x1FFU, max_timer); - min_timer = min(0xFFU, min_timer); + tx_max_timer = min(HW_ATL_INTR_MODER_MAX, tx_max_timer); + tx_min_timer = min(HW_ATL_INTR_MODER_MIN, tx_min_timer); + rx_max_timer = min(HW_ATL_INTR_MODER_MAX, rx_max_timer); + rx_min_timer = min(HW_ATL_INTR_MODER_MIN, rx_min_timer); - PHAL_ATLANTIC_B0->itr_tx |= min_timer << 0x8U; - PHAL_ATLANTIC_B0->itr_tx |= max_timer << 0x10U; - PHAL_ATLANTIC_B0->itr_rx |= min_timer << 0x8U; - PHAL_ATLANTIC_B0->itr_rx |= max_timer << 0x10U; + itr_tx |= tx_min_timer << 0x8U; + itr_tx |= tx_max_timer << 0x10U; + itr_rx |= rx_min_timer << 0x8U; + itr_rx |= rx_max_timer << 0x10U; } else { static unsigned int hw_atl_b0_timers_table_tx_[][2] = { {0xffU, 0xffU}, /* 10Gbit */ @@ -836,34 +842,36 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self, hw_atl_utils_mbps_2_speed_index( self->aq_link_status.mbps); - PHAL_ATLANTIC_B0->itr_tx |= - hw_atl_b0_timers_table_tx_[speed_index] - [0] << 0x8U; /* set min timer value */ - PHAL_ATLANTIC_B0->itr_tx |= - hw_atl_b0_timers_table_tx_[speed_index] - [1] << 0x10U; /* set max timer value */ - - PHAL_ATLANTIC_B0->itr_rx |= - hw_atl_b0_timers_table_rx_[speed_index] - [0] << 0x8U; /* set min timer value */ - PHAL_ATLANTIC_B0->itr_rx |= - hw_atl_b0_timers_table_rx_[speed_index] - [1] << 0x10U; /* set max timer value */ + /* Update user visible ITR settings */ + self->aq_nic_cfg->tx_itr = hw_atl_b0_timers_table_tx_ + [speed_index][1] * 2; + self->aq_nic_cfg->rx_itr = hw_atl_b0_timers_table_rx_ + [speed_index][1] * 2; + + itr_tx |= hw_atl_b0_timers_table_tx_ + [speed_index][0] << 0x8U; + itr_tx |= hw_atl_b0_timers_table_tx_ + [speed_index][1] << 0x10U; + + itr_rx |= hw_atl_b0_timers_table_rx_ + [speed_index][0] << 0x8U; + itr_rx |= hw_atl_b0_timers_table_rx_ + [speed_index][1] << 0x10U; } - } else { + break; + case AQ_CFG_INTERRUPT_MODERATION_OFF: tdm_tx_desc_wr_wb_irq_en_set(self, 1U); tdm_tdm_intr_moder_en_set(self, 0U); rdm_rx_desc_wr_wb_irq_en_set(self, 1U); rdm_rdm_intr_moder_en_set(self, 0U); - PHAL_ATLANTIC_B0->itr_tx = 0U; - PHAL_ATLANTIC_B0->itr_rx = 0U; + itr_tx = 0U; + itr_rx = 0U; + break; } for (i = HW_ATL_B0_RINGS_MAX; i--;) { - reg_tx_intr_moder_ctrl_set(self, - PHAL_ATLANTIC_B0->itr_tx, i); - reg_rx_intr_moder_ctrl_set(self, - PHAL_ATLANTIC_B0->itr_rx, i); + reg_tx_intr_moder_ctrl_set(self, itr_tx, i); + reg_rx_intr_moder_ctrl_set(self, itr_rx, i); } return aq_hw_err_from_flags(self); diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h index fcf89e25a773..9aa2c6edfca2 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h @@ -139,6 +139,9 @@ #define HW_ATL_B0_FW_VER_EXPECTED 0x01050006U +#define HW_ATL_INTR_MODER_MAX 0x1FF +#define HW_ATL_INTR_MODER_MIN 0xFF + /* Hardware tx descriptor */ struct __packed hw_atl_txd_s { u64 buf_addr; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h index 2218bdb605a7..c99cc690e425 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h @@ -131,8 +131,6 @@ struct __packed hw_atl_s { struct hw_atl_stats_s last_stats; struct hw_atl_stats_s curr_stats; u64 speed; - u32 itr_tx; - u32 itr_rx; unsigned int chip_features; u32 fw_ver_actual; atomic_t dpc; -- cgit v1.2.3 From 417a3ae4b14909439bb49790f90201f450399845 Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Thu, 19 Oct 2017 18:23:59 +0300 Subject: net: aquantia: Bad udp rate on default interrupt coalescing Default Tx rates cause very long ISR delays on Tx. 0xff is 510us delay, giving only ~ 2000 interrupts per seconds for Tx rings cleanup. With these settings udp tx rate was never higher than ~800Mbps on a single stream. Changing min delay to 0xF makes it way better with ~6Gbps TCP stream performance is almost unaffected by this change, since LSO optimizations play important role. CPU load is affected insignificantly by this change. Signed-off-by: Pavel Belous Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 11f7e71bf448..ec68c20efcbd 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -821,12 +821,12 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) itr_rx |= rx_max_timer << 0x10U; } else { static unsigned int hw_atl_b0_timers_table_tx_[][2] = { - {0xffU, 0xffU}, /* 10Gbit */ - {0xffU, 0x1ffU}, /* 5Gbit */ - {0xffU, 0x1ffU}, /* 5Gbit 5GS */ - {0xffU, 0x1ffU}, /* 2.5Gbit */ - {0xffU, 0x1ffU}, /* 1Gbit */ - {0xffU, 0x1ffU}, /* 100Mbit */ + {0xfU, 0xffU}, /* 10Gbit */ + {0xfU, 0x1ffU}, /* 5Gbit */ + {0xfU, 0x1ffU}, /* 5Gbit 5GS */ + {0xfU, 0x1ffU}, /* 2.5Gbit */ + {0xfU, 0x1ffU}, /* 1Gbit */ + {0xfU, 0x1ffU}, /* 100Mbit */ }; static unsigned int hw_atl_b0_timers_table_rx_[][2] = { -- cgit v1.2.3 From b16918a5fd87983d421a7e2241a1314e877c4ea2 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 19 Oct 2017 16:51:44 +0100 Subject: hwmon: (da9052) Increase sample rate when using TSI The TSI channel, which is usually used for touchscreen support, but can be used as 4 general purpose ADCs. When used as a touchscreen interface the touchscreen driver switches the device into 1ms sampling mode (rather than the default 10ms economy mode) as recommended by the manufacturer. When using the TSI channels as a general purpose ADC we are currently not doing this and testing suggests that this can result in ADC timeouts: [ 5827.198289] da9052 spi2.0: timeout waiting for ADC conversion interrupt [ 5827.728293] da9052 spi2.0: timeout waiting for ADC conversion interrupt [ 5993.808335] da9052 spi2.0: timeout waiting for ADC conversion interrupt [ 5994.328441] da9052 spi2.0: timeout waiting for ADC conversion interrupt [ 5994.848291] da9052 spi2.0: timeout waiting for ADC conversion interrupt Switching to the 1ms timing resolves this issue. Fixes: 4f16cab19a3d5 ("hwmon: da9052: Add support for TSI channel") Signed-off-by: Martyn Welch Acked-by: Steve Twiss Signed-off-by: Guenter Roeck --- drivers/hwmon/da9052-hwmon.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c index 97a62f5b9ea4..a973eb6a2890 100644 --- a/drivers/hwmon/da9052-hwmon.c +++ b/drivers/hwmon/da9052-hwmon.c @@ -477,6 +477,11 @@ static int da9052_hwmon_probe(struct platform_device *pdev) /* disable touchscreen features */ da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_A_REG, 0x00); + /* Sample every 1ms */ + da9052_reg_update(hwmon->da9052, DA9052_ADC_CONT_REG, + DA9052_ADCCONT_ADCMODE, + DA9052_ADCCONT_ADCMODE); + err = da9052_request_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, "tsiready-irq", da9052_tsi_datardy_irq, hwmon); -- cgit v1.2.3 From 8b95f4f730cba02ef6febbdc4ca7e55ca045b00e Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 20 Oct 2017 15:07:41 +0800 Subject: drm/amd/powerplay: fix uninitialized variable refresh_rate was not initialized when program display gap. this patch can fix vce ring test failed when do S3 on Polaris10. bug: https://bugs.freedesktop.org/show_bug.cgi?id=103102 bug: https://bugzilla.kernel.org/show_bug.cgi?id=196615 Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index c2743233ba10..b526f49be65d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -830,7 +830,7 @@ uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr) { uint32_t reference_clock, tmp; struct cgs_display_info info = {0}; - struct cgs_mode_info mode_info; + struct cgs_mode_info mode_info = {0}; info.mode_info = &mode_info; @@ -3948,10 +3948,9 @@ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr) uint32_t ref_clock; uint32_t refresh_rate = 0; struct cgs_display_info info = {0}; - struct cgs_mode_info mode_info; + struct cgs_mode_info mode_info = {0}; info.mode_info = &mode_info; - cgs_get_active_displays_info(hwmgr->device, &info); num_active_displays = info.display_count; @@ -3967,6 +3966,7 @@ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr) frame_time_in_us = 1000000 / refresh_rate; pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us; + data->frame_time_x2 = frame_time_in_us * 2 / 100; display_gap2 = pre_vbi_time_in_us * (ref_clock / 100); -- cgit v1.2.3 From 14aefd9011f14ecf1f821fcd1754f009f4ab3df9 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Fri, 20 Oct 2017 09:16:15 +0200 Subject: mlxsw: reg: Add Tunneling IPinIP General Configuration Register The TIGCR register is used for setting up the IPinIP Tunnel configuration. Fixes: ee954d1a91b2 ("mlxsw: spectrum_router: Support GRE tunnels") Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index cc27c5de5a1d..4afc8486eb9a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -6401,6 +6401,36 @@ static inline void mlxsw_reg_mgpc_pack(char *payload, u32 counter_index, mlxsw_reg_mgpc_opcode_set(payload, opcode); } +/* TIGCR - Tunneling IPinIP General Configuration Register + * ------------------------------------------------------- + * The TIGCR register is used for setting up the IPinIP Tunnel configuration. + */ +#define MLXSW_REG_TIGCR_ID 0xA801 +#define MLXSW_REG_TIGCR_LEN 0x10 + +MLXSW_REG_DEFINE(tigcr, MLXSW_REG_TIGCR_ID, MLXSW_REG_TIGCR_LEN); + +/* reg_tigcr_ipip_ttlc + * For IPinIP Tunnel encapsulation: whether to copy the ttl from the packet + * header. + * Access: RW + */ +MLXSW_ITEM32(reg, tigcr, ttlc, 0x04, 8, 1); + +/* reg_tigcr_ipip_ttl_uc + * The TTL for IPinIP Tunnel encapsulation of unicast packets if + * reg_tigcr_ipip_ttlc is unset. + * Access: RW + */ +MLXSW_ITEM32(reg, tigcr, ttl_uc, 0x04, 0, 8); + +static inline void mlxsw_reg_tigcr_pack(char *payload, bool ttlc, u8 ttl_uc) +{ + MLXSW_REG_ZERO(tigcr, payload); + mlxsw_reg_tigcr_ttlc_set(payload, ttlc); + mlxsw_reg_tigcr_ttl_uc_set(payload, ttl_uc); +} + /* SBPR - Shared Buffer Pools Register * ----------------------------------- * The SBPR configures and retrieves the shared buffer pools and configuration. @@ -6881,6 +6911,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { MLXSW_REG(mcc), MLXSW_REG(mcda), MLXSW_REG(mgpc), + MLXSW_REG(tigcr), MLXSW_REG(sbpr), MLXSW_REG(sbcm), MLXSW_REG(sbpm), -- cgit v1.2.3 From dcbda2820ff91a692338fed2c99bb9b1af37a05a Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Fri, 20 Oct 2017 09:16:16 +0200 Subject: mlxsw: spectrum_router: Configure TIGCR on init Spectrum tunnels do not default to ttl of "inherit" like the Linux ones do. Configure TIGCR on router init so that the TTL of tunnel packets is copied from the overlay packets. Fixes: ee954d1a91b2 ("mlxsw: spectrum_router: Support GRE tunnels") Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index c16718d296d3..5189022a1c8c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -5896,11 +5896,20 @@ static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp) kfree(mlxsw_sp->router->rifs); } +static int +mlxsw_sp_ipip_config_tigcr(struct mlxsw_sp *mlxsw_sp) +{ + char tigcr_pl[MLXSW_REG_TIGCR_LEN]; + + mlxsw_reg_tigcr_pack(tigcr_pl, true, 0); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tigcr), tigcr_pl); +} + static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp) { mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr; INIT_LIST_HEAD(&mlxsw_sp->router->ipip_list); - return 0; + return mlxsw_sp_ipip_config_tigcr(mlxsw_sp); } static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp) -- cgit v1.2.3 From 9c8080d068b861a80d430ba0b42d8c9b07366b66 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Fri, 20 Oct 2017 14:37:34 +0100 Subject: net: stmmac: Add missing call to dev_kfree_skb() When RX HW timestamp is enabled and a frame is discarded we are not freeing the skb but instead only setting to NULL the entry. Add a call to dev_kfree_skb_any() so that skb entry is correctly freed. Signed-off-by: Jose Abreu Cc: David S. Miller Cc: Joao Pinto Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 1763e48c84e2..d67638c7078e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3333,6 +3333,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) * them in stmmac_rx_refill() function so that * device can reuse it. */ + dev_kfree_skb_any(rx_q->rx_skbuff[entry]); rx_q->rx_skbuff[entry] = NULL; dma_unmap_single(priv->device, rx_q->rx_skbuff_dma[entry], -- cgit v1.2.3 From 98870943a561c64aca22d10820a881aa4fa728e4 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Fri, 20 Oct 2017 14:37:35 +0100 Subject: net: stmmac: Fix stmmac_get_rx_hwtstamp() When using GMAC4 the valid timestamp is from CTX next desc but we are passing the previous desc to get_rx_timestamp_status() callback. Fix this and while at it rework a little bit the function logic. Signed-off-by: Jose Abreu Cc: David S. Miller Cc: Joao Pinto Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d67638c7078e..284c10720daf 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -473,19 +473,18 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, struct dma_desc *np, struct sk_buff *skb) { struct skb_shared_hwtstamps *shhwtstamp = NULL; + struct dma_desc *desc = p; u64 ns; if (!priv->hwts_rx_en) return; + /* For GMAC4, the valid timestamp is from CTX next desc. */ + if (priv->plat->has_gmac4) + desc = np; /* Check if timestamp is available */ - if (priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) { - /* For GMAC4, the valid timestamp is from CTX next desc. */ - if (priv->plat->has_gmac4) - ns = priv->hw->desc->get_timestamp(np, priv->adv_ts); - else - ns = priv->hw->desc->get_timestamp(p, priv->adv_ts); - + if (priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) { + ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); shhwtstamp = skb_hwtstamps(skb); memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); -- cgit v1.2.3 From 9454360dec1c96800576693955b92a2792b74def Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Fri, 20 Oct 2017 14:37:36 +0100 Subject: net: stmmac: Prevent infinite loop in get_rx_timestamp_status() Prevent infinite loop by correctly setting the loop condition to break when i == 10. Signed-off-by: Jose Abreu Cc: David S. Miller Cc: Joao Pinto Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index e0ef02f9503b..4b286e27c4ca 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -275,7 +275,7 @@ static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) goto exit; i++; - } while ((ret == 1) || (i < 10)); + } while ((ret == 1) && (i < 10)); if (i == 10) ret = -EBUSY; -- cgit v1.2.3 From 66bdede495c71da9c5ce18542976fae53642880b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 18 Oct 2017 13:54:03 +0200 Subject: of_mdio: Fix broken PHY IRQ in case of probe deferral If an Ethernet PHY is initialized before the interrupt controller it is connected to, a message like the following is printed: irq: no irq domain found for /interrupt-controller@e61c0000 ! However, the actual error is ignored, leading to a non-functional (POLL) PHY interrupt later: Micrel KSZ8041RNLI ee700000.ethernet-ffffffff:01: attached PHY driver [Micrel KSZ8041RNLI] (mii_bus:phy_addr=ee700000.ethernet-ffffffff:01, irq=POLL) Depending on whether the PHY driver will fall back to polling, Ethernet may or may not work. To fix this: 1. Switch of_mdiobus_register_phy() from irq_of_parse_and_map() to of_irq_get(). Unlike the former, the latter returns -EPROBE_DEFER if the interrupt controller is not yet available, so this condition can be detected. Other errors are handled the same as before, i.e. use the passed mdio->irq[addr] as interrupt. 2. Propagate and handle errors from of_mdiobus_register_phy() and of_mdiobus_register_device(). Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/of/of_mdio.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index d94dd8b77abd..98258583abb0 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -44,7 +44,7 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id) return -EINVAL; } -static void of_mdiobus_register_phy(struct mii_bus *mdio, +static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *child, u32 addr) { struct phy_device *phy; @@ -60,9 +60,13 @@ static void of_mdiobus_register_phy(struct mii_bus *mdio, else phy = get_phy_device(mdio, addr, is_c45); if (IS_ERR(phy)) - return; + return PTR_ERR(phy); - rc = irq_of_parse_and_map(child, 0); + rc = of_irq_get(child, 0); + if (rc == -EPROBE_DEFER) { + phy_device_free(phy); + return rc; + } if (rc > 0) { phy->irq = rc; mdio->irq[addr] = rc; @@ -84,22 +88,23 @@ static void of_mdiobus_register_phy(struct mii_bus *mdio, if (rc) { phy_device_free(phy); of_node_put(child); - return; + return rc; } dev_dbg(&mdio->dev, "registered phy %s at address %i\n", child->name, addr); + return 0; } -static void of_mdiobus_register_device(struct mii_bus *mdio, - struct device_node *child, u32 addr) +static int of_mdiobus_register_device(struct mii_bus *mdio, + struct device_node *child, u32 addr) { struct mdio_device *mdiodev; int rc; mdiodev = mdio_device_create(mdio, addr); if (IS_ERR(mdiodev)) - return; + return PTR_ERR(mdiodev); /* Associate the OF node with the device structure so it * can be looked up later. @@ -112,11 +117,12 @@ static void of_mdiobus_register_device(struct mii_bus *mdio, if (rc) { mdio_device_free(mdiodev); of_node_put(child); - return; + return rc; } dev_dbg(&mdio->dev, "registered mdio device %s at address %i\n", child->name, addr); + return 0; } /* The following is a list of PHY compatible strings which appear in @@ -219,9 +225,11 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) } if (of_mdiobus_child_is_phy(child)) - of_mdiobus_register_phy(mdio, child, addr); + rc = of_mdiobus_register_phy(mdio, child, addr); else - of_mdiobus_register_device(mdio, child, addr); + rc = of_mdiobus_register_device(mdio, child, addr); + if (rc) + goto unregister; } if (!scanphys) @@ -242,12 +250,19 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) dev_info(&mdio->dev, "scan phy %s at address %i\n", child->name, addr); - if (of_mdiobus_child_is_phy(child)) - of_mdiobus_register_phy(mdio, child, addr); + if (of_mdiobus_child_is_phy(child)) { + rc = of_mdiobus_register_phy(mdio, child, addr); + if (rc) + goto unregister; + } } } return 0; + +unregister: + mdiobus_unregister(mdio); + return rc; } EXPORT_SYMBOL(of_mdiobus_register); -- cgit v1.2.3 From 8d5f4b07174976c55a5f5d6967777373c6826944 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Sat, 21 Oct 2017 06:51:30 +0000 Subject: stmmac: Don't access tx_q->dirty_tx before netif_tx_lock This is the possible reason for different hard to reproduce problems on my ARMv7-SMP test system. The symptoms are in recent kernels imprecise external aborts, and in older kernels various kinds of network stalls and unexpected page allocation failures. My testing indicates that the trouble started between v4.5 and v4.6 and prevails up to v4.14. Using the dirty_tx before acquiring the spin lock is clearly wrong and was first introduced with v4.6. Fixes: e3ad57c96715 ("stmmac: review RX/TX ring management") Signed-off-by: Bernd Edlinger Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 284c10720daf..16bd50929084 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1799,12 +1799,13 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) { struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; unsigned int bytes_compl = 0, pkts_compl = 0; - unsigned int entry = tx_q->dirty_tx; + unsigned int entry; netif_tx_lock(priv->dev); priv->xstats.tx_clean++; + entry = tx_q->dirty_tx; while (entry != tx_q->cur_tx) { struct sk_buff *skb = tx_q->tx_skbuff[entry]; struct dma_desc *p; -- cgit v1.2.3 From 988c3b385974be4c587ca228e577793eb19a95ff Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 20 Oct 2017 17:40:34 +0200 Subject: Revert "drm/etnaviv: submit supports performance monitor requests" The performance monitoring feature isn't stable enough yet, so don't advertise it to userspace yet. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 3fadb8d45e51..8721dc23312f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -550,7 +550,7 @@ static struct drm_driver etnaviv_drm_driver = { .desc = "etnaviv DRM", .date = "20151214", .major = 1, - .minor = 2, + .minor = 1, }; /* -- cgit v1.2.3 From 330b52bd9bba1d66028772dfe08c053a34c5069a Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 20 Oct 2017 17:46:55 +0200 Subject: drm/etnaviv: short-circuit perfmon ioctls The feature implementation isn't stable yet. Reject any attempt to use the IOCTLs for now. This keeps most of the code in place, so we can stabilize it in-tree, but keeps userspace from using the feature for now. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 8721dc23312f..491eddf9b150 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -459,6 +459,9 @@ static int etnaviv_ioctl_pm_query_dom(struct drm_device *dev, void *data, struct drm_etnaviv_pm_domain *args = data; struct etnaviv_gpu *gpu; + /* reject as long as the feature isn't stable */ + return -EINVAL; + if (args->pipe >= ETNA_MAX_PIPES) return -EINVAL; @@ -476,6 +479,9 @@ static int etnaviv_ioctl_pm_query_sig(struct drm_device *dev, void *data, struct drm_etnaviv_pm_signal *args = data; struct etnaviv_gpu *gpu; + /* reject as long as the feature isn't stable */ + return -EINVAL; + if (args->pipe >= ETNA_MAX_PIPES) return -EINVAL; -- cgit v1.2.3 From 3064abfa932bd09faf8da01741d171d476cf7193 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 29 Jun 2017 22:49:31 -0700 Subject: drm: Add CRTC_GET_SEQUENCE and CRTC_QUEUE_SEQUENCE ioctls [v3] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These provide crtc-id based functions instead of pipe-number, while also offering higher resolution time (ns) and wider frame count (64) as required by the Vulkan API. v2: * Check for DRIVER_MODESET in new crtc-based vblank ioctls Failing to check this will oops the driver. * Ensure vblank interupt is running in crtc_get_sequence ioctl The sequence and timing values are not correct while the interrupt is off, so make sure it's running before asking for them. * Short-circuit get_sequence if the counter is enabled and accurate Steal the idea from the code in wait_vblank to avoid the expense of drm_vblank_get/put * Return active state of crtc in crtc_get_sequence ioctl Might be useful for applications that aren't in charge of modesetting? * Use drm_crtc_vblank_get/put in new crtc-based vblank sequence ioctls Daniel Vetter prefers these over the old drm_vblank_put/get APIs. * Return s64 ns instead of u64 in new sequence event Suggested-by: Daniel Vetter Suggested-by: Ville Syrjälä v3: * Removed FIRST_PIXEL_OUT_FLAG * Document that the timestamp in the query and event are that of the first pixel leaving the display engine for the display (using the same wording as the Vulkan spec). Suggested-by: Michel Dänzer Acked-by: Dave Airlie [airlied: left->leaves (Michel)] Signed-off-by: Keith Packard Reviewed-by: Sean Paul Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_internal.h | 6 ++ drivers/gpu/drm/drm_ioctl.c | 2 + drivers/gpu/drm/drm_vblank.c | 168 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_vblank.h | 1 + include/uapi/drm/drm.h | 36 +++++++++ 5 files changed, 213 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index edd921adcf33..c9d5a6cd4d41 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -70,6 +70,12 @@ int drm_legacy_modeset_ctl_ioctl(struct drm_device *dev, void *data, int drm_legacy_irq_control(struct drm_device *dev, void *data, struct drm_file *file_priv); +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); + +int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); + /* drm_auth.c */ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index a78f03155466..9c435a4c0c82 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -663,6 +663,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 27b6db073a5c..13722c373a6a 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -819,6 +819,11 @@ static void send_vblank_event(struct drm_device *dev, e->event.vbl.tv_sec = tv.tv_sec; e->event.vbl.tv_usec = tv.tv_nsec / 1000; break; + case DRM_EVENT_CRTC_SEQUENCE: + if (seq) + e->event.seq.sequence = seq; + e->event.seq.time_ns = ktime_to_ns(now); + break; } trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq); drm_send_event_locked(dev, &e->base); @@ -1650,3 +1655,166 @@ bool drm_crtc_handle_vblank(struct drm_crtc *crtc) return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc)); } EXPORT_SYMBOL(drm_crtc_handle_vblank); + +/* + * Get crtc VBLANK count. + * + * \param dev DRM device + * \param data user arguement, pointing to a drm_crtc_get_sequence structure. + * \param file_priv drm file private for the user's open file descriptor + */ + +int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_crtc *crtc; + struct drm_vblank_crtc *vblank; + int pipe; + struct drm_crtc_get_sequence *get_seq = data; + ktime_t now; + bool vblank_enabled; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + if (!dev->irq_enabled) + return -EINVAL; + + crtc = drm_crtc_find(dev, file_priv, get_seq->crtc_id); + if (!crtc) + return -ENOENT; + + pipe = drm_crtc_index(crtc); + + vblank = &dev->vblank[pipe]; + vblank_enabled = dev->vblank_disable_immediate && READ_ONCE(vblank->enabled); + + if (!vblank_enabled) { + ret = drm_crtc_vblank_get(crtc); + if (ret) { + DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); + return ret; + } + } + drm_modeset_lock(&crtc->mutex, NULL); + if (crtc->state) + get_seq->active = crtc->state->enable; + else + get_seq->active = crtc->enabled; + drm_modeset_unlock(&crtc->mutex); + get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now); + get_seq->sequence_ns = ktime_to_ns(now); + if (!vblank_enabled) + drm_crtc_vblank_put(crtc); + return 0; +} + +/* + * Queue a event for VBLANK sequence + * + * \param dev DRM device + * \param data user arguement, pointing to a drm_crtc_queue_sequence structure. + * \param file_priv drm file private for the user's open file descriptor + */ + +int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_crtc *crtc; + struct drm_vblank_crtc *vblank; + int pipe; + struct drm_crtc_queue_sequence *queue_seq = data; + ktime_t now; + struct drm_pending_vblank_event *e; + u32 flags; + u64 seq; + u64 req_seq; + int ret; + unsigned long spin_flags; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + if (!dev->irq_enabled) + return -EINVAL; + + crtc = drm_crtc_find(dev, file_priv, queue_seq->crtc_id); + if (!crtc) + return -ENOENT; + + flags = queue_seq->flags; + /* Check valid flag bits */ + if (flags & ~(DRM_CRTC_SEQUENCE_RELATIVE| + DRM_CRTC_SEQUENCE_NEXT_ON_MISS)) + return -EINVAL; + + pipe = drm_crtc_index(crtc); + + vblank = &dev->vblank[pipe]; + + e = kzalloc(sizeof(*e), GFP_KERNEL); + if (e == NULL) + return -ENOMEM; + + ret = drm_crtc_vblank_get(crtc); + if (ret) { + DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); + goto err_free; + } + + seq = drm_vblank_count_and_time(dev, pipe, &now); + req_seq = queue_seq->sequence; + + if (flags & DRM_CRTC_SEQUENCE_RELATIVE) + req_seq += seq; + + if ((flags & DRM_CRTC_SEQUENCE_NEXT_ON_MISS) && vblank_passed(seq, req_seq)) + req_seq = seq + 1; + + e->pipe = pipe; + e->event.base.type = DRM_EVENT_CRTC_SEQUENCE; + e->event.base.length = sizeof(e->event.seq); + e->event.seq.user_data = queue_seq->user_data; + + spin_lock_irqsave(&dev->event_lock, spin_flags); + + /* + * drm_crtc_vblank_off() might have been called after we called + * drm_crtc_vblank_get(). drm_crtc_vblank_off() holds event_lock around the + * vblank disable, so no need for further locking. The reference from + * drm_crtc_vblank_get() protects against vblank disable from another source. + */ + if (!READ_ONCE(vblank->enabled)) { + ret = -EINVAL; + goto err_unlock; + } + + ret = drm_event_reserve_init_locked(dev, file_priv, &e->base, + &e->event.base); + + if (ret) + goto err_unlock; + + e->sequence = req_seq; + + if (vblank_passed(seq, req_seq)) { + drm_crtc_vblank_put(crtc); + send_vblank_event(dev, e, seq, now); + queue_seq->sequence = seq; + } else { + /* drm_handle_vblank_events will call drm_vblank_put */ + list_add_tail(&e->base.link, &dev->vblank_event_list); + queue_seq->sequence = req_seq; + } + + spin_unlock_irqrestore(&dev->event_lock, spin_flags); + return 0; + +err_unlock: + spin_unlock_irqrestore(&dev->event_lock, spin_flags); + drm_crtc_vblank_put(crtc); +err_free: + kfree(e); + return ret; +} diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index bf8e07035a0a..848b463a0af5 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -57,6 +57,7 @@ struct drm_pending_vblank_event { union { struct drm_event base; struct drm_event_vblank vbl; + struct drm_event_crtc_sequence seq; } event; }; diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 97677cd6964d..91d83c1747c0 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -737,6 +737,28 @@ struct drm_syncobj_array { __u32 pad; }; +/* Query current scanout sequence number */ +struct drm_crtc_get_sequence { + __u32 crtc_id; /* requested crtc_id */ + __u32 active; /* return: crtc output is active */ + __u64 sequence; /* return: most recent vblank sequence */ + __s64 sequence_ns; /* return: most recent time of first pixel out */ +}; + +/* Queue event to be delivered at specified sequence. Time stamp marks + * when the first pixel of the refresh cycle leaves the display engine + * for the display + */ +#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */ +#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */ + +struct drm_crtc_queue_sequence { + __u32 crtc_id; + __u32 flags; + __u64 sequence; /* on input, target sequence. on output, actual sequence */ + __u64 user_data; /* user data passed to event */ +}; + #if defined(__cplusplus) } #endif @@ -819,6 +841,9 @@ extern "C" { #define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) +#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence) +#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence) + #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) #define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) @@ -893,6 +918,7 @@ struct drm_event { #define DRM_EVENT_VBLANK 0x01 #define DRM_EVENT_FLIP_COMPLETE 0x02 +#define DRM_EVENT_CRTC_SEQUENCE 0x03 struct drm_event_vblank { struct drm_event base; @@ -903,6 +929,16 @@ struct drm_event_vblank { __u32 crtc_id; /* 0 on older kernels that do not support this */ }; +/* Event delivered at sequence. Time stamp marks when the first pixel + * of the refresh cycle leaves the display engine for the display + */ +struct drm_event_crtc_sequence { + struct drm_event base; + __u64 user_data; + __s64 time_ns; + __u64 sequence; +}; + /* typedef area */ #ifndef __KERNEL__ typedef struct drm_clip_rect drm_clip_rect_t; -- cgit v1.2.3 From 56cbcb6c41932b19ef0d838f1ff25a662a2e403d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 19 Oct 2017 08:21:49 +0200 Subject: drm/qxl: replace QXL_INFO with DRM_DEBUG_DRIVER Signed-off-by: Gerd Hoffmann Reviewed-by: Dave Airlie Link: http://patchwork.freedesktop.org/patch/msgid/20171019062150.28090-2-kraxel@redhat.com --- drivers/gpu/drm/qxl/qxl_cmd.c | 16 +++++++--------- drivers/gpu/drm/qxl/qxl_drv.h | 26 +------------------------- drivers/gpu/drm/qxl/qxl_fb.c | 13 +++++-------- drivers/gpu/drm/qxl/qxl_release.c | 5 ++--- drivers/gpu/drm/qxl/qxl_ttm.c | 4 ++-- 5 files changed, 17 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 74fc9362ecf9..8ec53d5abd62 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -219,7 +219,7 @@ int qxl_garbage_collect(struct qxl_device *qdev) union qxl_release_info *info; while (qxl_ring_pop(qdev->release_ring, &id)) { - QXL_INFO(qdev, "popped %lld\n", id); + DRM_DEBUG_DRIVER("popped %lld\n", id); while (id) { release = qxl_release_from_id_locked(qdev, id); if (release == NULL) @@ -229,8 +229,8 @@ int qxl_garbage_collect(struct qxl_device *qdev) next_id = info->next; qxl_release_unmap(qdev, release, info); - QXL_INFO(qdev, "popped %lld, next %lld\n", id, - next_id); + DRM_DEBUG_DRIVER("popped %lld, next %lld\n", id, + next_id); switch (release->type) { case QXL_RELEASE_DRAWABLE: @@ -248,7 +248,7 @@ int qxl_garbage_collect(struct qxl_device *qdev) } } - QXL_INFO(qdev, "%s: %d\n", __func__, i); + DRM_DEBUG_DRIVER("%d\n", i); return i; } @@ -381,8 +381,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, { struct qxl_surface_create *create; - QXL_INFO(qdev, "%s: qdev %p, ram_header %p\n", __func__, qdev, - qdev->ram_header); + DRM_DEBUG_DRIVER("qdev %p, ram_header %p\n", qdev, qdev->ram_header); create = &qdev->ram_header->create_surface; create->format = bo->surf.format; create->width = bo->surf.width; @@ -390,8 +389,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, create->stride = bo->surf.stride; create->mem = qxl_bo_physical_address(qdev, bo, offset); - QXL_INFO(qdev, "%s: mem = %llx, from %p\n", __func__, create->mem, - bo->kptr); + DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr); create->flags = QXL_SURF_FLAG_KEEP_DATA; create->type = QXL_SURF_TYPE_PRIMARY; @@ -401,7 +399,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id) { - QXL_INFO(qdev, "qxl_memslot_add %d\n", id); + DRM_DEBUG_DRIVER("qxl_memslot_add %d\n", id); wait_for_io_cmd(qdev, id, QXL_IO_MEMSLOT_ADD_ASYNC); } diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 3397a1907336..d707b351875c 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -62,33 +62,9 @@ #define QXL_DEBUGFS_MAX_COMPONENTS 32 -extern int qxl_log_level; extern int qxl_num_crtc; extern int qxl_max_ioctls; -enum { - QXL_INFO_LEVEL = 1, - QXL_DEBUG_LEVEL = 2, -}; - -#define QXL_INFO(qdev, fmt, ...) do { \ - if (qxl_log_level >= QXL_INFO_LEVEL) { \ - qxl_io_log(qdev, fmt, __VA_ARGS__); \ - } \ - } while (0) -#define QXL_DEBUG(qdev, fmt, ...) do { \ - if (qxl_log_level >= QXL_DEBUG_LEVEL) { \ - qxl_io_log(qdev, fmt, __VA_ARGS__); \ - } \ - } while (0) -#define QXL_INFO_ONCE(qdev, fmt, ...) do { \ - static int done; \ - if (!done) { \ - done = 1; \ - QXL_INFO(qdev, fmt, __VA_ARGS__); \ - } \ - } while (0) - #define DRM_FILE_OFFSET 0x100000000ULL #define DRM_FILE_PAGE_OFFSET (DRM_FILE_OFFSET >> PAGE_SHIFT) @@ -351,7 +327,7 @@ int qxl_check_idle(struct qxl_ring *ring); static inline void * qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical) { - QXL_INFO(qdev, "not implemented (%lu)\n", physical); + DRM_DEBUG_DRIVER("not implemented (%lu)\n", physical); return 0; } diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 844c4a31ca13..23af3e352673 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -240,18 +240,15 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, return ret; qbo = gem_to_qxl_bo(gobj); - QXL_INFO(qdev, "%s: %dx%d %d\n", __func__, mode_cmd.width, - mode_cmd.height, mode_cmd.pitches[0]); + DRM_DEBUG_DRIVER("%dx%d %d\n", mode_cmd.width, + mode_cmd.height, mode_cmd.pitches[0]); shadow = vmalloc(mode_cmd.pitches[0] * mode_cmd.height); /* TODO: what's the usual response to memory allocation errors? */ BUG_ON(!shadow); - QXL_INFO(qdev, - "surface0 at gpu offset %lld, mmap_offset %lld (virt %p, shadow %p)\n", - qxl_bo_gpu_offset(qbo), - qxl_bo_mmap_offset(qbo), - qbo->kptr, - shadow); + DRM_DEBUG_DRIVER("surface0 at gpu offset %lld, mmap_offset %lld (virt %p, shadow %p)\n", + qxl_bo_gpu_offset(qbo), qxl_bo_mmap_offset(qbo), + qbo->kptr, shadow); size = mode_cmd.pitches[0] * mode_cmd.height; info = drm_fb_helper_alloc_fbi(&qfbdev->helper); diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index e6ec845b5be0..a6da6fa6ad58 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -154,7 +154,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type, return handle; } *ret = release; - QXL_INFO(qdev, "allocated release %d\n", handle); + DRM_DEBUG_DRIVER("allocated release %d\n", handle); release->id = handle; return handle; } @@ -179,8 +179,7 @@ void qxl_release_free(struct qxl_device *qdev, struct qxl_release *release) { - QXL_INFO(qdev, "release %d, type %d\n", release->id, - release->type); + DRM_DEBUG_DRIVER("release %d, type %d\n", release->id, release->type); if (release->surface_release_id) qxl_surface_id_dealloc(qdev, release->surface_release_id); diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 7ecf8a4b9fe6..ab4823875311 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -136,8 +136,8 @@ int qxl_mmap(struct file *filp, struct vm_area_struct *vma) "filp->private_data->minor->dev->dev_private == NULL\n"); return -EINVAL; } - QXL_INFO(qdev, "%s: filp->private_data = 0x%p, vma->vm_pgoff = %lx\n", - __func__, filp->private_data, vma->vm_pgoff); + DRM_DEBUG_DRIVER("filp->private_data = 0x%p, vma->vm_pgoff = %lx\n", + filp->private_data, vma->vm_pgoff); r = ttm_bo_mmap(filp, vma, &qdev->mman.bdev); if (unlikely(r != 0)) -- cgit v1.2.3 From 62676d10b483a2ff6e8b08c5e7c7d63a831343f5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 19 Oct 2017 08:21:50 +0200 Subject: qxl: alloc & use shadow for dumb buffers This patch changes the way the primary surface is used for dumb framebuffers. Instead of configuring the bo itself as primary surface a shadow bo is created and used instead. Framebuffers can share the shadow bo in case they have the same format and resolution. On atomic plane updates we don't have to update the primary surface in case we pageflip from one framebuffer to another framebuffer which shares the same shadow. This in turn avoids the flicker caused by the primary-destroy + primary-create cycle, which is very annonying when running wayland on qxl. The qxl driver never actually writes to the shadow bo. It sends qxl blit commands which update it though, and the spice server might actually execute them (and thereby write to the shadow) in case the local rendering is kicked for some reason. This happens for example in case qemu is asked to write out a dump of the guest display (screendump monitor command). Signed-off-by: Gerd Hoffmann Reviewed-by: Dave Airlie Link: http://patchwork.freedesktop.org/patch/msgid/20171019062150.28090-3-kraxel@redhat.com --- drivers/gpu/drm/qxl/qxl_cmd.c | 6 ++++- drivers/gpu/drm/qxl/qxl_display.c | 49 ++++++++++++++++++++++++++++++++++++--- drivers/gpu/drm/qxl/qxl_drv.h | 2 ++ drivers/gpu/drm/qxl/qxl_dumb.c | 1 + 4 files changed, 54 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 8ec53d5abd62..c0fb52c6d4ca 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -387,7 +387,11 @@ void qxl_io_create_primary(struct qxl_device *qdev, create->width = bo->surf.width; create->height = bo->surf.height; create->stride = bo->surf.stride; - create->mem = qxl_bo_physical_address(qdev, bo, offset); + if (bo->shadow) { + create->mem = qxl_bo_physical_address(qdev, bo->shadow, offset); + } else { + create->mem = qxl_bo_physical_address(qdev, bo, offset); + } DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index afbf50d0c08f..4756b3c9bf2c 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -305,7 +305,9 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = { void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb); + struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj); + WARN_ON(bo->shadow); drm_gem_object_unreference_unlocked(qxl_fb->obj); drm_framebuffer_cleanup(fb); kfree(qxl_fb); @@ -508,6 +510,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, .x2 = qfb->base.width, .y2 = qfb->base.height }; + bool same_shadow = false; if (old_state->fb) { qfb_old = to_qxl_framebuffer(old_state->fb); @@ -519,15 +522,23 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, if (bo == bo_old) return; + if (bo_old && bo_old->shadow && bo->shadow && + bo_old->shadow == bo->shadow) { + same_shadow = true; + } + if (bo_old && bo_old->is_primary) { - qxl_io_destroy_primary(qdev); + if (!same_shadow) + qxl_io_destroy_primary(qdev); bo_old->is_primary = false; } if (!bo->is_primary) { - qxl_io_create_primary(qdev, 0, bo); + if (!same_shadow) + qxl_io_create_primary(qdev, 0, bo); bo->is_primary = true; } + qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1); } @@ -679,8 +690,9 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane, static int qxl_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { + struct qxl_device *qdev = plane->dev->dev_private; struct drm_gem_object *obj; - struct qxl_bo *user_bo; + struct qxl_bo *user_bo, *old_bo = NULL; int ret; if (!new_state->fb) @@ -689,6 +701,32 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, obj = to_qxl_framebuffer(new_state->fb)->obj; user_bo = gem_to_qxl_bo(obj); + if (plane->type == DRM_PLANE_TYPE_PRIMARY && + user_bo->is_dumb && !user_bo->shadow) { + if (plane->state->fb) { + obj = to_qxl_framebuffer(plane->state->fb)->obj; + old_bo = gem_to_qxl_bo(obj); + } + if (old_bo && old_bo->shadow && + user_bo->gem_base.size == old_bo->gem_base.size && + plane->state->crtc == new_state->crtc && + plane->state->crtc_w == new_state->crtc_w && + plane->state->crtc_h == new_state->crtc_h && + plane->state->src_x == new_state->src_x && + plane->state->src_y == new_state->src_y && + plane->state->src_w == new_state->src_w && + plane->state->src_h == new_state->src_h && + plane->state->rotation == new_state->rotation && + plane->state->zpos == new_state->zpos) { + drm_gem_object_get(&old_bo->shadow->gem_base); + user_bo->shadow = old_bo->shadow; + } else { + qxl_bo_create(qdev, user_bo->gem_base.size, + true, true, QXL_GEM_DOMAIN_VRAM, NULL, + &user_bo->shadow); + } + } + ret = qxl_bo_pin(user_bo, QXL_GEM_DOMAIN_CPU, NULL); if (ret) return ret; @@ -713,6 +751,11 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane, obj = to_qxl_framebuffer(old_state->fb)->obj; user_bo = gem_to_qxl_bo(obj); qxl_bo_unpin(user_bo); + + if (user_bo->shadow && !user_bo->is_primary) { + drm_gem_object_put_unlocked(&user_bo->shadow->gem_base); + user_bo->shadow = NULL; + } } static const uint32_t qxl_cursor_plane_formats[] = { diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index d707b351875c..08752c0ffb35 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -89,6 +89,8 @@ struct qxl_bo { /* Constant after initialization */ struct drm_gem_object gem_base; bool is_primary; /* is this now a primary surface */ + bool is_dumb; + struct qxl_bo *shadow; bool hw_surf_alloc; struct qxl_surface surf; uint32_t surface_id; diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index 5e65d5d2d937..11085ab01374 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c @@ -63,6 +63,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, &handle); if (r) return r; + qobj->is_dumb = true; args->pitch = pitch; args->handle = handle; return 0; -- cgit v1.2.3 From 8fe8ffb12c81b36877984274db184953c337db73 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 20 Oct 2017 11:46:45 -0700 Subject: scsi: Suppress a kernel warning in case the prep function returns BLKPREP_DEFER The legacy block layer handles requests as follows: - If the prep function returns BLKPREP_OK, let blk_peek_request() return the pointer to that request. - If the prep function returns BLKPREP_DEFER, keep the RQF_STARTED flag and retry calling the prep function later. - If the prep function returns BLKPREP_KILL or BLKPREP_INVALID, end the request. In none of these cases it is correct to clear the SCMD_INITIALIZED flag from inside scsi_prep_fn(). Since scsi_prep_fn() already guarantees that scsi_init_command() will be called once even if scsi_prep_fn() is called multiple times, remove the code that clears SCMD_INITIALIZED from scsi_prep_fn(). The scsi-mq code handles requests as follows: - If scsi_mq_prep_fn() returns BLKPREP_OK, set the RQF_DONTPREP flag and submit the request to the SCSI LLD. - If scsi_mq_prep_fn() returns BLKPREP_DEFER, call blk_mq_delay_run_hw_queue() and return BLK_STS_RESOURCE. - If the prep function returns BLKPREP_KILL or BLKPREP_INVALID, call scsi_mq_uninit_cmd() and let the blk-mq core end the request. In none of these cases scsi_mq_prep_fn() should clear the SCMD_INITIALIZED flag. Hence remove the code from scsi_mq_prep_fn() function that clears that flag. This patch avoids that the following warning is triggered when using the legacy block layer: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 4198 at drivers/scsi/scsi_lib.c:654 scsi_end_request+0x1de/0x220 CPU: 1 PID: 4198 Comm: mkfs.f2fs Not tainted 4.14.0-rc5+ #1 task: ffff91c147a4b800 task.stack: ffffb282c37b8000 RIP: 0010:scsi_end_request+0x1de/0x220 Call Trace: scsi_io_completion+0x204/0x5e0 scsi_finish_command+0xce/0xe0 scsi_softirq_done+0x126/0x130 blk_done_softirq+0x6e/0x80 __do_softirq+0xcf/0x2a8 irq_exit+0xab/0xb0 do_IRQ+0x7b/0xc0 common_interrupt+0x90/0x90 RIP: 0010:_raw_spin_unlock_irqrestore+0x9/0x10 __test_set_page_writeback+0xc7/0x2c0 __block_write_full_page+0x158/0x3b0 block_write_full_page+0xc4/0xd0 blkdev_writepage+0x13/0x20 __writepage+0x12/0x40 write_cache_pages+0x204/0x500 generic_writepages+0x48/0x70 blkdev_writepages+0x9/0x10 do_writepages+0x34/0xc0 __filemap_fdatawrite_range+0x6c/0x90 file_write_and_wait_range+0x31/0x90 blkdev_fsync+0x16/0x40 vfs_fsync_range+0x44/0xa0 do_fsync+0x38/0x60 SyS_fsync+0xb/0x10 entry_SYSCALL_64_fastpath+0x13/0x94 ---[ end trace 86e8ef85a4a6c1d1 ]--- Fixes: commit 64104f703212 ("scsi: Call scsi_initialize_rq() for filesystem requests") Signed-off-by: Bart Van Assche Cc: Damien Le Moal Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Johannes Thumshirn Reviewed-by: Damien Le Moal Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9cf6a80fe297..ad3ea24f0885 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1379,8 +1379,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ret = scsi_setup_cmnd(sdev, req); out: - if (ret != BLKPREP_OK) - cmd->flags &= ~SCMD_INITIALIZED; return scsi_prep_return(q, req, ret); } @@ -1900,7 +1898,6 @@ static int scsi_mq_prep_fn(struct request *req) struct scsi_device *sdev = req->q->queuedata; struct Scsi_Host *shost = sdev->host; struct scatterlist *sg; - int ret; scsi_init_command(sdev, cmd); @@ -1934,10 +1931,7 @@ static int scsi_mq_prep_fn(struct request *req) blk_mq_start_request(req); - ret = scsi_setup_cmnd(sdev, req); - if (ret != BLK_STS_OK) - cmd->flags &= ~SCMD_INITIALIZED; - return ret; + return scsi_setup_cmnd(sdev, req); } static void scsi_mq_done(struct scsi_cmnd *cmd) -- cgit v1.2.3 From cdc1cdca2d91c477ce33d5c02dc6be0d2b939247 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Oct 2017 11:55:13 +0300 Subject: drm/i915: Update DRIVER_DATE to 20171023 Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9bcf1d15485e..54b5d4c582b6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -80,8 +80,8 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20171012" -#define DRIVER_TIMESTAMP 1507831511 +#define DRIVER_DATE "20171023" +#define DRIVER_TIMESTAMP 1508748913 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions -- cgit v1.2.3 From 83beee5c88a6c71ded70e2eef5ca7406a02605cc Mon Sep 17 00:00:00 2001 From: Kuppuswamy Sathyanarayanan Date: Mon, 4 Sep 2017 22:37:21 -0700 Subject: platform/x86: intel_pmc_ipc: Use devm_* calls in driver probe function This patch cleans up unnecessary free/alloc calls in ipc_plat_probe(), ipc_pci_probe() and ipc_plat_get_res() functions by using devm_* calls. This patch also adds proper error handling for failure cases in ipc_pci_probe() function. Signed-off-by: Kuppuswamy Sathyanarayanan [andy: fixed style issues, missed devm_free_irq(), removed unnecessary log message] Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_pmc_ipc.c | 94 +++++++++++------------------------- 1 file changed, 28 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index bb792a52248b..751b1212d01c 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -480,52 +480,39 @@ static irqreturn_t ioc(int irq, void *dev_id) static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - resource_size_t pci_resource; + struct intel_pmc_ipc_dev *pmc = &ipcdev; int ret; - int len; - ipcdev.dev = &pci_dev_get(pdev)->dev; - ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ; + /* Only one PMC is supported */ + if (pmc->dev) + return -EBUSY; - ret = pci_enable_device(pdev); + pmc->irq_mode = IPC_TRIGGER_MODE_IRQ; + + ret = pcim_enable_device(pdev); if (ret) return ret; - ret = pci_request_regions(pdev, "intel_pmc_ipc"); + ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); if (ret) return ret; - pci_resource = pci_resource_start(pdev, 0); - len = pci_resource_len(pdev, 0); - if (!pci_resource || !len) { - dev_err(&pdev->dev, "Failed to get resource\n"); - return -ENOMEM; - } + init_completion(&pmc->cmd_complete); - init_completion(&ipcdev.cmd_complete); + pmc->ipc_base = pcim_iomap_table(pdev)[0]; - if (request_irq(pdev->irq, ioc, 0, "intel_pmc_ipc", &ipcdev)) { + ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc", + pmc); + if (ret) { dev_err(&pdev->dev, "Failed to request irq\n"); - return -EBUSY; + return ret; } - ipcdev.ipc_base = ioremap_nocache(pci_resource, len); - if (!ipcdev.ipc_base) { - dev_err(&pdev->dev, "Failed to ioremap ipc base\n"); - free_irq(pdev->irq, &ipcdev); - ret = -ENOMEM; - } + pmc->dev = &pdev->dev; - return ret; -} + pci_set_drvdata(pdev, pmc); -static void ipc_pci_remove(struct pci_dev *pdev) -{ - free_irq(pdev->irq, &ipcdev); - pci_release_regions(pdev); - pci_dev_put(pdev); - iounmap(ipcdev.ipc_base); - ipcdev.dev = NULL; + return 0; } static const struct pci_device_id ipc_pci_ids[] = { @@ -540,7 +527,6 @@ static struct pci_driver ipc_pci_driver = { .name = "intel_pmc_ipc", .id_table = ipc_pci_ids, .probe = ipc_pci_probe, - .remove = ipc_pci_remove, }; static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev, @@ -850,17 +836,12 @@ static int ipc_plat_get_res(struct platform_device *pdev) return -ENXIO; } size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE; + res->end = res->start + size - 1; + + addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(addr)) + return PTR_ERR(addr); - if (!request_mem_region(res->start, size, pdev->name)) { - dev_err(&pdev->dev, "Failed to request ipc resource\n"); - return -EBUSY; - } - addr = ioremap_nocache(res->start, size); - if (!addr) { - dev_err(&pdev->dev, "I/O memory remapping failed\n"); - release_mem_region(res->start, size); - return -ENOMEM; - } ipcdev.ipc_base = addr; ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; @@ -917,7 +898,6 @@ MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids); static int ipc_plat_probe(struct platform_device *pdev) { - struct resource *res; int ret; ipcdev.dev = &pdev->dev; @@ -939,11 +919,11 @@ static int ipc_plat_probe(struct platform_device *pdev) ret = ipc_create_pmc_devices(); if (ret) { dev_err(&pdev->dev, "Failed to create pmc devices\n"); - goto err_device; + return ret; } - if (request_irq(ipcdev.irq, ioc, IRQF_NO_SUSPEND, - "intel_pmc_ipc", &ipcdev)) { + if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND, + "intel_pmc_ipc", &ipcdev)) { dev_err(&pdev->dev, "Failed to request irq\n"); ret = -EBUSY; goto err_irq; @@ -960,40 +940,22 @@ static int ipc_plat_probe(struct platform_device *pdev) return 0; err_sys: - free_irq(ipcdev.irq, &ipcdev); + devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); err_irq: platform_device_unregister(ipcdev.tco_dev); platform_device_unregister(ipcdev.punit_dev); platform_device_unregister(ipcdev.telemetry_dev); -err_device: - iounmap(ipcdev.ipc_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, - PLAT_RESOURCE_IPC_INDEX); - if (res) { - release_mem_region(res->start, - PLAT_RESOURCE_IPC_SIZE + - PLAT_RESOURCE_GCR_SIZE); - } + return ret; } static int ipc_plat_remove(struct platform_device *pdev) { - struct resource *res; - sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group); - free_irq(ipcdev.irq, &ipcdev); + devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); platform_device_unregister(ipcdev.tco_dev); platform_device_unregister(ipcdev.punit_dev); platform_device_unregister(ipcdev.telemetry_dev); - iounmap(ipcdev.ipc_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, - PLAT_RESOURCE_IPC_INDEX); - if (res) { - release_mem_region(res->start, - PLAT_RESOURCE_IPC_SIZE + - PLAT_RESOURCE_GCR_SIZE); - } ipcdev.dev = NULL; return 0; } -- cgit v1.2.3 From 6687aeb9cd3d40904d1f9e884d2145603c23adfa Mon Sep 17 00:00:00 2001 From: Kuppuswamy Sathyanarayanan Date: Sat, 7 Oct 2017 15:19:51 -0700 Subject: platform/x86: intel_pmc_ipc: Use spin_lock to protect GCR updates Currently, update_no_reboot_bit() function implemented in this driver uses mutex_lock() to protect its register updates. But this function is called with in atomic context in iTCO_wdt_start() and iTCO_wdt_stop() functions in iTCO_wdt.c driver, which in turn causes "sleeping into atomic context" issue. This patch fixes this issue by replacing the mutex_lock() with spin_lock() to protect the GCR read/write/update APIs. Fixes: 9d855d4 ("platform/x86: intel_pmc_ipc: Fix iTCO_wdt GCS memory mapping failure") Signed-off-by: Kuppuswamy Sathyanarayanan Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_pmc_ipc.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index 751b1212d01c..e03fa31446ca 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -131,6 +132,7 @@ static struct intel_pmc_ipc_dev { /* gcr */ void __iomem *gcr_mem_base; bool has_gcr_regs; + spinlock_t gcr_lock; /* punit */ struct platform_device *punit_dev; @@ -225,17 +227,17 @@ int intel_pmc_gcr_read(u32 offset, u32 *data) { int ret; - mutex_lock(&ipclock); + spin_lock(&ipcdev.gcr_lock); ret = is_gcr_valid(offset); if (ret < 0) { - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return ret; } *data = readl(ipcdev.gcr_mem_base + offset); - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return 0; } @@ -255,17 +257,17 @@ int intel_pmc_gcr_write(u32 offset, u32 data) { int ret; - mutex_lock(&ipclock); + spin_lock(&ipcdev.gcr_lock); ret = is_gcr_valid(offset); if (ret < 0) { - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return ret; } writel(data, ipcdev.gcr_mem_base + offset); - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return 0; } @@ -287,7 +289,7 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val) u32 new_val; int ret = 0; - mutex_lock(&ipclock); + spin_lock(&ipcdev.gcr_lock); ret = is_gcr_valid(offset); if (ret < 0) @@ -309,7 +311,7 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val) } gcr_ipc_unlock: - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return ret; } EXPORT_SYMBOL_GPL(intel_pmc_gcr_update); @@ -489,6 +491,8 @@ static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) pmc->irq_mode = IPC_TRIGGER_MODE_IRQ; + spin_lock_init(&ipcdev.gcr_lock); + ret = pcim_enable_device(pdev); if (ret) return ret; @@ -903,6 +907,7 @@ static int ipc_plat_probe(struct platform_device *pdev) ipcdev.dev = &pdev->dev; ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ; init_completion(&ipcdev.cmd_complete); + spin_lock_init(&ipcdev.gcr_lock); ipcdev.irq = platform_get_irq(pdev, 0); if (ipcdev.irq < 0) { -- cgit v1.2.3 From 9d11b06638f6aa30d099090e6b8a540c558295ac Mon Sep 17 00:00:00 2001 From: Ran Wang Date: Mon, 23 Oct 2017 18:10:23 +0800 Subject: drivers/net/usb: add device id for TP-LINK UE300 USB 3.0 Ethernet This product is named 'TP-LINK USB 3.0 Gigabit Ethernet Network Adapter (Model No.is UE300)'. It uses chip RTL8153 and works with driver drivers/net/usb/r8152.c Signed-off-by: Ran Wang Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 8 ++++++++ drivers/net/usb/r8152.c | 2 ++ 2 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 52ea80bcd639..5529bd136624 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -561,6 +561,7 @@ static const struct driver_info wwan_info = { #define HP_VENDOR_ID 0x03f0 #define MICROSOFT_VENDOR_ID 0x045e #define UBLOX_VENDOR_ID 0x1546 +#define TPLINK_VENDOR_ID 0x2357 static const struct usb_device_id products[] = { /* BLACKLIST !! @@ -813,6 +814,13 @@ static const struct usb_device_id products[] = { .driver_info = 0, }, + /* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* WHITELIST!!! * * CDC Ether uses two interfaces, not necessarily consecutive. diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 941ece08ba78..d51d9abf7986 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -615,6 +615,7 @@ enum rtl8152_flags { #define VENDOR_ID_LENOVO 0x17ef #define VENDOR_ID_LINKSYS 0x13b1 #define VENDOR_ID_NVIDIA 0x0955 +#define VENDOR_ID_TPLINK 0x2357 #define MCU_TYPE_PLA 0x0100 #define MCU_TYPE_USB 0x0000 @@ -5319,6 +5320,7 @@ static const struct usb_device_id rtl8152_table[] = { {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, + {REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601)}, {} }; -- cgit v1.2.3 From 07f37efdaa3fa327ecbfd519110bc6bd0c2582cc Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 23 Oct 2017 17:16:41 +0200 Subject: cdc_ether: flag the Huawei ME906/ME909 as WWAN The Huawei ME906 (12d1:15c1) comes with a standard ECM interface that requires management via AT commands sent over one of the control TTYs (e.g. connected with AT^NDISDUP). Signed-off-by: Aleksander Morgado Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 5529bd136624..3e7a3ac3a362 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -871,6 +871,12 @@ static const struct usb_device_id products[] = { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x81ba, USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (kernel_ulong_t)&wwan_info, +}, { + /* Huawei ME906 and ME909 */ + USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x15c1, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&wwan_info, }, { /* ZTE modules */ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, USB_CLASS_COMM, -- cgit v1.2.3 From 822eaf7cfb7c4783375bceadbc7651137346ac00 Mon Sep 17 00:00:00 2001 From: Yan Markman Date: Mon, 23 Oct 2017 15:24:29 +0200 Subject: net: mvpp2: fix TSO headers allocation and management TSO headers are managed with txq index and therefore should be aligned with the txq size, not with the aggregated txq size. Fixes: 186cd4d4e414 ("net: mvpp2: software tso support") Reported-by: Marc Zyngier Signed-off-by: Yan Markman Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 9c86cb7cb988..72e43d848034 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -5609,7 +5609,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port, txq_pcpu->tso_headers = dma_alloc_coherent(port->dev->dev.parent, - MVPP2_AGGR_TXQ_SIZE * TSO_HEADER_SIZE, + txq_pcpu->size * TSO_HEADER_SIZE, &txq_pcpu->tso_headers_dma, GFP_KERNEL); if (!txq_pcpu->tso_headers) @@ -5623,7 +5623,7 @@ cleanup: kfree(txq_pcpu->buffs); dma_free_coherent(port->dev->dev.parent, - MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE, + txq_pcpu->size * TSO_HEADER_SIZE, txq_pcpu->tso_headers, txq_pcpu->tso_headers_dma); } @@ -5647,7 +5647,7 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port, kfree(txq_pcpu->buffs); dma_free_coherent(port->dev->dev.parent, - MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE, + txq_pcpu->size * TSO_HEADER_SIZE, txq_pcpu->tso_headers, txq_pcpu->tso_headers_dma); } -- cgit v1.2.3 From 20920267885218fda08dc12c7d3814938ab15b54 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 23 Oct 2017 15:24:30 +0200 Subject: net: mvpp2: do not unmap TSO headers buffers The TSO header buffers are coming from a per cpu pool and should not be unmapped as they are reused. The PPv2 driver was unmapping all descriptors buffers unconditionally. This patch fixes this by checking the buffers dma addresses before unmapping them, and by not unmapping those who are located in the TSO header pool. Fixes: 186cd4d4e414 ("net: mvpp2: software tso support") Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 72e43d848034..3de05a8c468a 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -1167,6 +1167,11 @@ struct mvpp2_bm_pool { u32 port_map; }; +#define IS_TSO_HEADER(txq_pcpu, addr) \ + ((addr) >= (txq_pcpu)->tso_headers_dma && \ + (addr) < (txq_pcpu)->tso_headers_dma + \ + (txq_pcpu)->size * TSO_HEADER_SIZE) + /* Queue modes */ #define MVPP2_QDIST_SINGLE_MODE 0 #define MVPP2_QDIST_MULTI_MODE 1 @@ -5321,8 +5326,9 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port, struct mvpp2_txq_pcpu_buf *tx_buf = txq_pcpu->buffs + txq_pcpu->txq_get_index; - dma_unmap_single(port->dev->dev.parent, tx_buf->dma, - tx_buf->size, DMA_TO_DEVICE); + if (!IS_TSO_HEADER(txq_pcpu, tx_buf->dma)) + dma_unmap_single(port->dev->dev.parent, tx_buf->dma, + tx_buf->size, DMA_TO_DEVICE); if (tx_buf->skb) dev_kfree_skb_any(tx_buf->skb); @@ -6212,12 +6218,15 @@ static inline void tx_desc_unmap_put(struct mvpp2_port *port, struct mvpp2_tx_queue *txq, struct mvpp2_tx_desc *desc) { + struct mvpp2_txq_pcpu *txq_pcpu = this_cpu_ptr(txq->pcpu); + dma_addr_t buf_dma_addr = mvpp2_txdesc_dma_addr_get(port, desc); size_t buf_sz = mvpp2_txdesc_size_get(port, desc); - dma_unmap_single(port->dev->dev.parent, buf_dma_addr, - buf_sz, DMA_TO_DEVICE); + if (!IS_TSO_HEADER(txq_pcpu, buf_dma_addr)) + dma_unmap_single(port->dev->dev.parent, buf_dma_addr, + buf_sz, DMA_TO_DEVICE); mvpp2_txq_desc_put(txq); } -- cgit v1.2.3 From 082297e61480c4d72ed75b31077e74aca0e7c799 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 23 Oct 2017 15:24:31 +0200 Subject: net: mvpp2: do not call txq_done from the Tx path when Tx irqs are used When Tx IRQs are used, txq_bufs_free() can be called from both the Tx path and from NAPI poll(). This led to CPU stalls as if these two tasks (Tx and Poll) are scheduled on two CPUs at the same time, DMA unmapping operations are done on the same txq buffers. This patch adds a check not to call txq_done() from the Tx path if Tx interrupts are used as it does not make sense to do so. Fixes: edc660fa09e2 ("net: mvpp2: replace TX coalescing interrupts with hrtimer") Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 3de05a8c468a..28c6e8a5e118 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -6499,7 +6499,7 @@ out: } /* Finalize TX processing */ - if (txq_pcpu->count >= txq->done_pkts_coal) + if (!port->has_tx_irqs && txq_pcpu->count >= txq->done_pkts_coal) mvpp2_txq_done(port, txq, txq_pcpu); /* Set the timer in case not all frags were processed */ -- cgit v1.2.3 From 3a379f5b36ae039dfeb6f73316e47ab1af4945df Mon Sep 17 00:00:00 2001 From: Gerhard Bertelsmann Date: Thu, 17 Aug 2017 15:59:49 +0200 Subject: can: sun4i: fix loopback mode Fix loopback mode by setting the right flag and remove presume mode. Signed-off-by: Gerhard Bertelsmann Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sun4i_can.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index 68ef0a4cd821..b0c80859f746 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -342,7 +342,7 @@ static int sun4i_can_start(struct net_device *dev) /* enter the selected mode */ mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR); - if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK) + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) mod_reg_val |= SUN4I_MSEL_LOOPBACK_MODE; else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) mod_reg_val |= SUN4I_MSEL_LISTEN_ONLY_MODE; @@ -811,7 +811,6 @@ static int sun4ican_probe(struct platform_device *pdev) priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_LOOPBACK | - CAN_CTRLMODE_PRESUME_ACK | CAN_CTRLMODE_3_SAMPLES; priv->base = addr; priv->clk = clk; -- cgit v1.2.3 From 8f65a923e6b628e187d5e791cf49393dd5e8c2f9 Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Tue, 24 Oct 2017 12:23:28 +0200 Subject: can: kvaser_usb: Correct return value in printout If the return value from kvaser_usb_send_simple_msg() was non-zero, the return value from kvaser_usb_flush_queue() was printed in the kernel warning. Signed-off-by: Jimmy Assarsson Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 18cc529fb807..861e90efab86 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1609,7 +1609,8 @@ static int kvaser_usb_close(struct net_device *netdev) if (err) netdev_warn(netdev, "Cannot flush queue, error %d\n", err); - if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel)) + err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel); + if (err) netdev_warn(netdev, "Cannot reset card, error %d\n", err); err = kvaser_usb_stop_chip(priv); -- cgit v1.2.3 From e1d2d1329a5722dbecc9c278303fcc4aa01f8790 Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Tue, 24 Oct 2017 12:23:29 +0200 Subject: can: kvaser_usb: Ignore CMD_FLUSH_QUEUE_REPLY messages To avoid kernel warning "Unhandled message (68)", ignore the CMD_FLUSH_QUEUE_REPLY message for now. As of Leaf v2 firmware version v4.1.844 (2017-02-15), flush tx queue is synchronous. There is a capability bit indicating whether flushing tx queue is synchronous or asynchronous. A proper solution would be to query the device for capabilities. If the synchronous tx flush capability bit is set, we should wait for CMD_FLUSH_QUEUE_REPLY message, while flushing the tx queue. Signed-off-by: Jimmy Assarsson Cc: linux-stable Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 861e90efab86..9b18d96ef526 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -137,6 +137,7 @@ static inline bool kvaser_is_usbcan(const struct usb_device_id *id) #define CMD_RESET_ERROR_COUNTER 49 #define CMD_TX_ACKNOWLEDGE 50 #define CMD_CAN_ERROR_EVENT 51 +#define CMD_FLUSH_QUEUE_REPLY 68 #define CMD_LEAF_USB_THROTTLE 77 #define CMD_LEAF_LOG_MESSAGE 106 @@ -1301,6 +1302,11 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev, goto warn; break; + case CMD_FLUSH_QUEUE_REPLY: + if (dev->family != KVASER_LEAF) + goto warn; + break; + default: warn: dev_warn(dev->udev->dev.parent, "Unhandled message (%d)\n", msg->id); -- cgit v1.2.3 From d0725439354a58f2b13b9f5234420641b662b9c4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 23 Oct 2017 17:36:03 -0700 Subject: hwmon: (tmp102) Fix first temperature reading Commit 3d8f7a89a197 ("hwmon: (tmp102) Improve handling of initial read delay") reduced the initial temperature read delay and made it dependent on the chip's shutdown mode. If the chip was not in shutdown mode at probe, the read delay no longer applies. This ignores the fact that the chip initialization changes the temperature sensor resolution, and that the temperature register values change when the resolution is changed. As a result, the reported temperature is twice as high as the real temperature until the first temperature conversion after the configuration change is complete. This can result in unexpected behavior and, worst case, in a system shutdown. To fix the problem, let's just always wait for a conversion to complete before reporting a temperature. Fixes: 3d8f7a89a197 ("hwmon: (tmp102) Improve handling of initial read delay") Link: https://bugzilla.kernel.org/show_bug.cgi?id=197167 Reported-by: Ralf Goebel Cc: Ralf Goebel Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/tmp102.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 5eafbaada795..dfc40c740d07 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -268,14 +268,11 @@ static int tmp102_probe(struct i2c_client *client, return err; } - tmp102->ready_time = jiffies; - if (tmp102->config_orig & TMP102_CONF_SD) { - /* - * Mark that we are not ready with data until the first - * conversion is complete - */ - tmp102->ready_time += msecs_to_jiffies(CONVERSION_TIME_MS); - } + /* + * Mark that we are not ready with data until the first + * conversion is complete + */ + tmp102->ready_time = jiffies + msecs_to_jiffies(CONVERSION_TIME_MS); hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, tmp102, -- cgit v1.2.3 From 0cc2b4e5a020fc7f4d1795741c116c983e9467d7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 24 Oct 2017 15:20:45 +0200 Subject: PM / QoS: Fix device resume latency PM QoS The special value of 0 for device resume latency PM QoS means "no restriction", but there are two problems with that. First, device resume latency PM QoS requests with 0 as the value are always put in front of requests with positive values in the priority lists used internally by the PM QoS framework, causing 0 to be chosen as an effective constraint value. However, that 0 is then interpreted as "no restriction" effectively overriding the other requests with specific restrictions which is incorrect. Second, the users of device resume latency PM QoS have no way to specify that *any* resume latency at all should be avoided, which is an artificial limitation in general. To address these issues, modify device resume latency PM QoS to use S32_MAX as the "no constraint" value and 0 as the "no latency at all" one and rework its users (the cpuidle menu governor, the genpd QoS governor and the runtime PM framework) to follow these changes. Also add a special "n/a" value to the corresponding user space I/F to allow user space to indicate that it cannot accept any resume latencies at all for the given device. Fixes: 85dc0b8a4019 (PM / QoS: Make it possible to expose PM QoS latency constraints) Link: https://bugzilla.kernel.org/show_bug.cgi?id=197323 Reported-by: Reinette Chatre Tested-by: Reinette Chatre Signed-off-by: Rafael J. Wysocki Acked-by: Alex Shi Cc: All applicable --- Documentation/ABI/testing/sysfs-devices-power | 4 +- drivers/base/cpu.c | 3 +- drivers/base/power/domain_governor.c | 53 +++++++++++++++------------ drivers/base/power/qos.c | 2 +- drivers/base/power/runtime.c | 2 +- drivers/base/power/sysfs.c | 25 +++++++++++-- drivers/cpuidle/governors/menu.c | 4 +- include/linux/pm_qos.h | 5 ++- 8 files changed, 63 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power index 676fdf5f2a99..5cbb6f038615 100644 --- a/Documentation/ABI/testing/sysfs-devices-power +++ b/Documentation/ABI/testing/sysfs-devices-power @@ -211,7 +211,9 @@ Description: device, after it has been suspended at run time, from a resume request to the moment the device will be ready to process I/O, in microseconds. If it is equal to 0, however, this means that - the PM QoS resume latency may be arbitrary. + the PM QoS resume latency may be arbitrary and the special value + "n/a" means that user space cannot accept any resume latency at + all for the given device. Not all drivers support this attribute. If it isn't supported, it is not present. diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 321cd7b4d817..227bac5f1191 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -377,7 +377,8 @@ int register_cpu(struct cpu *cpu, int num) per_cpu(cpu_sys_devices, num) = &cpu->dev; register_cpu_under_node(num, cpu_to_node(num)); - dev_pm_qos_expose_latency_limit(&cpu->dev, 0); + dev_pm_qos_expose_latency_limit(&cpu->dev, + PM_QOS_RESUME_LATENCY_NO_CONSTRAINT); return 0; } diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 281f949c5ffe..51751cc8c9e6 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c @@ -14,23 +14,20 @@ static int dev_update_qos_constraint(struct device *dev, void *data) { s64 *constraint_ns_p = data; - s32 constraint_ns = -1; + s64 constraint_ns = -1; if (dev->power.subsys_data && dev->power.subsys_data->domain_data) constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns; - if (constraint_ns < 0) { + if (constraint_ns < 0) constraint_ns = dev_pm_qos_read_value(dev); - constraint_ns *= NSEC_PER_USEC; - } - if (constraint_ns == 0) + + if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) return 0; - /* - * constraint_ns cannot be negative here, because the device has been - * suspended. - */ - if (constraint_ns < *constraint_ns_p || *constraint_ns_p == 0) + constraint_ns *= NSEC_PER_USEC; + + if (constraint_ns < *constraint_ns_p || *constraint_ns_p < 0) *constraint_ns_p = constraint_ns; return 0; @@ -63,10 +60,14 @@ static bool default_suspend_ok(struct device *dev) spin_unlock_irqrestore(&dev->power.lock, flags); - if (constraint_ns < 0) + if (constraint_ns == 0) return false; - constraint_ns *= NSEC_PER_USEC; + if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) + constraint_ns = -1; + else + constraint_ns *= NSEC_PER_USEC; + /* * We can walk the children without any additional locking, because * they all have been suspended at this point and their @@ -76,14 +77,19 @@ static bool default_suspend_ok(struct device *dev) device_for_each_child(dev, &constraint_ns, dev_update_qos_constraint); - if (constraint_ns > 0) { - constraint_ns -= td->suspend_latency_ns + - td->resume_latency_ns; - if (constraint_ns == 0) - return false; + if (constraint_ns < 0) { + /* The children have no constraints. */ + td->effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; + td->cached_suspend_ok = true; + } else { + constraint_ns -= td->suspend_latency_ns + td->resume_latency_ns; + if (constraint_ns > 0) { + td->effective_constraint_ns = constraint_ns; + td->cached_suspend_ok = true; + } else { + td->effective_constraint_ns = 0; + } } - td->effective_constraint_ns = constraint_ns; - td->cached_suspend_ok = constraint_ns >= 0; /* * The children have been suspended already, so we don't need to take @@ -145,13 +151,14 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, td = &to_gpd_data(pdd)->td; constraint_ns = td->effective_constraint_ns; /* default_suspend_ok() need not be called before us. */ - if (constraint_ns < 0) { + if (constraint_ns < 0) constraint_ns = dev_pm_qos_read_value(pdd->dev); - constraint_ns *= NSEC_PER_USEC; - } - if (constraint_ns == 0) + + if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) continue; + constraint_ns *= NSEC_PER_USEC; + /* * constraint_ns cannot be negative here, because the device has * been suspended. diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 277d43a83f53..7d29286d9313 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -189,7 +189,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) plist_head_init(&c->list); c->target_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->default_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; - c->no_constraint_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; + c->no_constraint_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; c->type = PM_QOS_MIN; c->notifiers = n; diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 7bcf80fa9ada..13e015905543 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -253,7 +253,7 @@ static int rpm_check_suspend_allowed(struct device *dev) || (dev->power.request_pending && dev->power.request == RPM_REQ_RESUME)) retval = -EAGAIN; - else if (__dev_pm_qos_read_value(dev) < 0) + else if (__dev_pm_qos_read_value(dev) == 0) retval = -EPERM; else if (dev->power.runtime_status == RPM_SUSPENDED) retval = 1; diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 156ab57bca77..632077f05c57 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -218,7 +218,14 @@ static ssize_t pm_qos_resume_latency_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", dev_pm_qos_requested_resume_latency(dev)); + s32 value = dev_pm_qos_requested_resume_latency(dev); + + if (value == 0) + return sprintf(buf, "n/a\n"); + else if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) + value = 0; + + return sprintf(buf, "%d\n", value); } static ssize_t pm_qos_resume_latency_store(struct device *dev, @@ -228,11 +235,21 @@ static ssize_t pm_qos_resume_latency_store(struct device *dev, s32 value; int ret; - if (kstrtos32(buf, 0, &value)) - return -EINVAL; + if (!kstrtos32(buf, 0, &value)) { + /* + * Prevent users from writing negative or "no constraint" values + * directly. + */ + if (value < 0 || value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) + return -EINVAL; - if (value < 0) + if (value == 0) + value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; + } else if (!strcmp(buf, "n/a") || !strcmp(buf, "n/a\n")) { + value = 0; + } else { return -EINVAL; + } ret = dev_pm_qos_update_request(dev->power.qos->resume_latency_req, value); diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 48eaf2879228..aa390404e85f 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -298,8 +298,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) data->needs_update = 0; } - /* resume_latency is 0 means no restriction */ - if (resume_latency && resume_latency < latency_req) + if (resume_latency < latency_req && + resume_latency != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) latency_req = resume_latency; /* Special case when user has set very strict latency requirement */ diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 032b55909145..6737a8c9e8c6 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -27,16 +27,17 @@ enum pm_qos_flags_status { PM_QOS_FLAGS_ALL, }; -#define PM_QOS_DEFAULT_VALUE -1 +#define PM_QOS_DEFAULT_VALUE (-1) +#define PM_QOS_LATENCY_ANY S32_MAX #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 #define PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE 0 #define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE 0 +#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) -#define PM_QOS_LATENCY_ANY ((s32)(~(__u32)0 >> 1)) #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) #define PM_QOS_FLAG_REMOTE_WAKEUP (1 << 1) -- cgit v1.2.3 From 57a95b41869b8f0d1949c24df2a9dac1ca7082ee Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 24 Oct 2017 11:08:18 -0700 Subject: Input: elan_i2c - add ELAN0611 to the ACPI table ELAN0611 touchpad uses elan_i2c as its driver. It can be found on Lenovo ideapad 320-15IKB. So add it to ACPI table to enable the touchpad. [Ido Adiv reports that the same ACPI ID is used for Elan touchpad in ideapad 520]. BugLink: https://bugs.launchpad.net/bugs/1723736 Signed-off-by: Kai-Heng Feng Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elan_i2c_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 0e761d079dc4..6d6b092e2da9 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1258,6 +1258,7 @@ static const struct acpi_device_id elan_acpi_id[] = { { "ELAN0605", 0 }, { "ELAN0609", 0 }, { "ELAN060B", 0 }, + { "ELAN0611", 0 }, { "ELAN1000", 0 }, { } }; -- cgit v1.2.3 From 32e67a3a06b88904155170560b7a63d372b320bd Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 24 Oct 2017 15:57:18 -0400 Subject: nbd: handle interrupted sendmsg with a sndtimeo set If you do not set sk_sndtimeo you will get -ERESTARTSYS if there is a pending signal when you enter sendmsg, which we handle properly. However if you set a timeout for your commands we'll set sk_sndtimeo to that timeout, which means that sendmsg will start returning -EINTR instead of -ERESTARTSYS. Fix this by checking either cases and doing the correct thing. Cc: stable@vger.kernel.org Fixes: dc88e34d69d8 ("nbd: set sk->sk_sndtimeo for our sockets") Reported-and-tested-by: Daniel Xu Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index baebbdfd74d5..9adfb5445f8d 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -386,6 +386,15 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, return result; } +/* + * Different settings for sk->sk_sndtimeo can result in different return values + * if there is a signal pending when we enter sendmsg, because reasons? + */ +static inline int was_interrupted(int result) +{ + return result == -ERESTARTSYS || result == -EINTR; +} + /* always call with the tx_lock held */ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) { @@ -458,7 +467,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) result = sock_xmit(nbd, index, 1, &from, (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent); if (result <= 0) { - if (result == -ERESTARTSYS) { + if (was_interrupted(result)) { /* If we havne't sent anything we can just return BUSY, * however if we have sent something we need to make * sure we only allow this req to be sent until we are @@ -502,7 +511,7 @@ send_pages: } result = sock_xmit(nbd, index, 1, &from, flags, &sent); if (result <= 0) { - if (result == -ERESTARTSYS) { + if (was_interrupted(result)) { /* We've already sent the header, we * have no choice but to set pending and * return BUSY. -- cgit v1.2.3 From e7646f84ad4f654e1ee503b03a12e520d947884f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Mar 2017 15:33:22 -0700 Subject: drm: Add new LEASE debug level Separate out lease debugging from the core. Signed-off-by: Keith Packard Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 3 ++- include/drm/drmP.h | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index c0292e5d7281..a934fd5e7e55 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -57,7 +57,8 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat "\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n" "\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n" "\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n" -"\t\tBit 5 (0x20) will enable VBL messages (vblank code)"); +"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n" +"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)"); module_param_named(debug, drm_debug, int, 0600); static DEFINE_SPINLOCK(drm_minor_lock); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 7277783a4ff0..59be1232d005 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -136,6 +136,7 @@ struct pci_controller; #define DRM_UT_ATOMIC 0x10 #define DRM_UT_VBL 0x20 #define DRM_UT_STATE 0x40 +#define DRM_UT_LEASE 0x80 /***********************************************************************/ /** \name DRM template customization defaults */ @@ -250,6 +251,9 @@ struct pci_controller; #define DRM_DEBUG_VBL(fmt, ...) \ drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__) +#define DRM_DEBUG_LEASE(fmt, ...) \ + drm_printk(KERN_DEBUG, DRM_UT_LEASE, fmt, ##__VA_ARGS__) + #define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \ ({ \ static DEFINE_RATELIMIT_STATE(_rs, \ -- cgit v1.2.3 From 2ed077e467eedb033032bc4b6e349365517662d6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 Mar 2017 22:26:41 -0700 Subject: drm: Add drm_object lease infrastructure [v5] This provides new data structures to hold "lease" information about drm mode setting objects, and provides for creating new drm_masters which have access to a subset of the available drm resources. An 'owner' is a drm_master which is not leasing the objects from another drm_master, and hence 'owns' them. A 'lessee' is a drm_master which is leasing objects from some other drm_master. Each lessee holds the set of objects which it is leasing from the lessor. A 'lessor' is a drm_master which is leasing objects to another drm_master. This is the same as the owner in the current code. The set of objects any drm_master 'controls' is limited to the set of objects it leases (for lessees) or all objects (for owners). Objects not controlled by a drm_master cannot be modified through the various state manipulating ioctls, and any state reported back to user space will be edited to make them appear idle and/or unusable. For instance, connectors always report 'disconnected', while encoders report no possible crtcs or clones. The full list of lessees leasing objects from an owner (either directly, or indirectly through another lessee), can be searched from an idr in the drm_master of the owner. Changes for v2 as suggested by Daniel Vetter : * Sub-leasing has been disabled. * BUG_ON for lock checking replaced with lockdep_assert_held * 'change' ioctl has been removed. * Leased objects can always be controlled by the lessor; the 'mask_lease' flag has been removed * Checking for leased status has been simplified, replacing the drm_lease_check function with drm_lease_held. Changes in v3, some suggested by Dave Airlie * Add revocation. This allows leases to be effectively revoked by removing all of the objects they have access to. The lease itself hangs around as it's hanging off a file. * Free the leases IDR when the master is destroyed * _drm_lease_held should look at lessees, not lessor * Allow non-master files to check for lease status Changes in v4, suggested by Dave Airlie * Formatting and whitespace changes Changes in v5 (airlied) * check DRIVER_MODESET before lease destroy call * check DRIVER_MODESET for lease revoke (Chris) * Use idr_mutex uniformly for all lease elements of struct drm_master. (Keith) Signed-off-by: Keith Packard --- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_auth.c | 30 +++- drivers/gpu/drm/drm_lease.c | 355 ++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_auth.h | 21 +++ include/drm/drm_lease.h | 36 +++++ include/drm/drm_mode_object.h | 1 + 6 files changed, 443 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/drm_lease.c create mode 100644 include/drm/drm_lease.h (limited to 'drivers') diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index a3fdc5a68dff..81ff79336623 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -17,7 +17,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_encoder.o drm_mode_object.o drm_property.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ - drm_syncobj.o + drm_syncobj.o drm_lease.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 7ff697389d74..4f0e274f4111 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -31,6 +31,7 @@ #include #include "drm_internal.h" #include "drm_legacy.h" +#include /** * DOC: master and authentication @@ -93,7 +94,7 @@ int drm_authmagic(struct drm_device *dev, void *data, return file ? 0 : -EINVAL; } -static struct drm_master *drm_master_create(struct drm_device *dev) +struct drm_master *drm_master_create(struct drm_device *dev) { struct drm_master *master; @@ -107,6 +108,14 @@ static struct drm_master *drm_master_create(struct drm_device *dev) idr_init(&master->magic_map); master->dev = dev; + /* initialize the tree of output resource lessees */ + master->lessor = NULL; + master->lessee_id = 0; + INIT_LIST_HEAD(&master->lessees); + INIT_LIST_HEAD(&master->lessee_list); + idr_init(&master->leases); + idr_init(&master->lessee_idr); + return master; } @@ -189,6 +198,12 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, goto out_unlock; } + if (file_priv->master->lessor != NULL) { + DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id); + ret = -EINVAL; + goto out_unlock; + } + ret = drm_set_master(dev, file_priv, false); out_unlock: mutex_unlock(&dev->master_mutex); @@ -270,6 +285,13 @@ void drm_master_release(struct drm_file *file_priv) if (dev->master == file_priv->master) drm_drop_master(dev, file_priv); out: + if (drm_core_check_feature(dev, DRIVER_MODESET) && file_priv->is_master) { + /* Revoke any leases held by this or lessees, but only if + * this is the "real" master + */ + drm_lease_revoke(master); + } + /* drop the master reference held by the file priv */ if (file_priv->master) drm_master_put(&file_priv->master); @@ -310,12 +332,18 @@ static void drm_master_destroy(struct kref *kref) struct drm_master *master = container_of(kref, struct drm_master, refcount); struct drm_device *dev = master->dev; + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_lease_destroy(master); + if (dev->driver->master_destroy) dev->driver->master_destroy(dev, master); drm_legacy_master_rmmaps(dev, master); idr_destroy(&master->magic_map); + idr_destroy(&master->leases); + idr_destroy(&master->lessee_idr); + kfree(master->unique); kfree(master); } diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c new file mode 100644 index 000000000000..030db1170570 --- /dev/null +++ b/drivers/gpu/drm/drm_lease.c @@ -0,0 +1,355 @@ +/* + * Copyright © 2017 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include "drm_internal.h" +#include "drm_legacy.h" +#include "drm_crtc_internal.h" +#include +#include +#include + +#define drm_for_each_lessee(lessee, lessor) \ + list_for_each_entry((lessee), &(lessor)->lessees, lessee_list) + +/** + * drm_lease_owner - return ancestor owner drm_master + * @master: drm_master somewhere within tree of lessees and lessors + * + * RETURN: + * + * drm_master at the top of the tree (i.e, with lessor NULL + */ +struct drm_master *drm_lease_owner(struct drm_master *master) +{ + while (master->lessor != NULL) + master = master->lessor; + return master; +} +EXPORT_SYMBOL(drm_lease_owner); + +/** + * _drm_find_lessee - find lessee by id (idr_mutex held) + * @master: drm_master of lessor + * @id: lessee_id + * + * RETURN: + * + * drm_master of the lessee if valid, NULL otherwise + */ + +static struct drm_master* +_drm_find_lessee(struct drm_master *master, int lessee_id) +{ + lockdep_assert_held(&master->dev->mode_config.idr_mutex); + return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id); +} + +/** + * _drm_lease_held_master - check to see if an object is leased (or owned) by master (idr_mutex held) + * @master: the master to check the lease status of + * @id: the id to check + * + * Checks if the specified master holds a lease on the object. Return + * value: + * + * true 'master' holds a lease on (or owns) the object + * false 'master' does not hold a lease. + */ +static int _drm_lease_held_master(struct drm_master *master, int id) +{ + lockdep_assert_held(&master->dev->mode_config.idr_mutex); + if (master->lessor) + return idr_find(&master->leases, id) != NULL; + return true; +} + +/** + * _drm_has_leased - check to see if an object has been leased (idr_mutex held) + * @master: the master to check the lease status of + * @id: the id to check + * + * Checks if any lessee of 'master' holds a lease on 'id'. Return + * value: + * + * true Some lessee holds a lease on the object. + * false No lessee has a lease on the object. + */ +static bool _drm_has_leased(struct drm_master *master, int id) +{ + struct drm_master *lessee; + + lockdep_assert_held(&master->dev->mode_config.idr_mutex); + drm_for_each_lessee(lessee, master) + if (_drm_lease_held_master(lessee, id)) + return true; + return false; +} + +/** + * _drm_lease_held - check drm_mode_object lease status (idr_mutex held) + * @master: the drm_master + * @id: the object id + * + * Checks if the specified master holds a lease on the object. Return + * value: + * + * true 'master' holds a lease on (or owns) the object + * false 'master' does not hold a lease. + */ +bool _drm_lease_held(struct drm_file *file_priv, int id) +{ + if (file_priv == NULL || file_priv->master == NULL) + return true; + + return _drm_lease_held_master(file_priv->master, id); +} +EXPORT_SYMBOL(_drm_lease_held); + +/** + * drm_lease_held - check drm_mode_object lease status (idr_mutex not held) + * @master: the drm_master + * @id: the object id + * + * Checks if the specified master holds a lease on the object. Return + * value: + * + * true 'master' holds a lease on (or owns) the object + * false 'master' does not hold a lease. + */ +bool drm_lease_held(struct drm_file *file_priv, int id) +{ + struct drm_master *master; + bool ret; + + if (file_priv == NULL || file_priv->master == NULL) + return true; + + master = file_priv->master; + mutex_lock(&master->dev->mode_config.idr_mutex); + ret = _drm_lease_held_master(master, id); + mutex_unlock(&master->dev->mode_config.idr_mutex); + return ret; +} +EXPORT_SYMBOL(drm_lease_held); + +/** + * drm_lease_filter_crtcs - restricted crtc set to leased values (idr_mutex not held) + * @file_priv: requestor file + * @crtcs: bitmask of crtcs to check + * + * Reconstructs a crtc mask based on the crtcs which are visible + * through the specified file. + */ +uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in) +{ + struct drm_master *master; + struct drm_device *dev; + struct drm_crtc *crtc; + int count_in, count_out; + uint32_t crtcs_out = 0; + + if (file_priv == NULL || file_priv->master == NULL) + return crtcs_in; + + master = file_priv->master; + dev = master->dev; + + count_in = count_out = 0; + mutex_lock(&master->dev->mode_config.idr_mutex); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (_drm_lease_held_master(master, crtc->base.id)) { + uint32_t mask_in = 1ul << count_in; + if ((crtcs_in & mask_in) != 0) { + uint32_t mask_out = 1ul << count_out; + crtcs_out |= mask_out; + } + count_out++; + } + count_in++; + } + mutex_unlock(&master->dev->mode_config.idr_mutex); + return crtcs_out; +} +EXPORT_SYMBOL(drm_lease_filter_crtcs); + +/* + * drm_lease_create - create a new drm_master with leased objects (idr_mutex not held) + * @lessor: lease holder (or owner) of objects + * @leases: objects to lease to the new drm_master + * + * Uses drm_master_create to allocate a new drm_master, then checks to + * make sure all of the desired objects can be leased, atomically + * leasing them to the new drmmaster. + * + * ERR_PTR(-EACCESS) some other master holds the title to any object + * ERR_PTR(-ENOENT) some object is not a valid DRM object for this device + * ERR_PTR(-EBUSY) some other lessee holds title to this object + * ERR_PTR(-EEXIST) same object specified more than once in the provided list + * ERR_PTR(-ENOMEM) allocation failed + */ +static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases) +{ + struct drm_device *dev = lessor->dev; + int error; + struct drm_master *lessee; + int object; + int id; + void *entry; + + DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id); + + lessee = drm_master_create(lessor->dev); + if (!lessee) { + DRM_DEBUG_LEASE("drm_master_create failed\n"); + return ERR_PTR(-ENOMEM); + } + + mutex_lock(&dev->mode_config.idr_mutex); + + /* Insert the new lessee into the tree */ + id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL); + if (id < 0) { + error = id; + goto out_lessee; + } + + lessee->lessee_id = id; + lessee->lessor = drm_master_get(lessor); + list_add_tail(&lessee->lessee_list, &lessor->lessees); + + idr_for_each_entry(leases, entry, object) { + error = 0; + if (!idr_find(&dev->mode_config.crtc_idr, object)) + error = -ENOENT; + else if (!_drm_lease_held_master(lessor, object)) + error = -EACCES; + else if (_drm_has_leased(lessor, object)) + error = -EBUSY; + + if (error != 0) { + DRM_DEBUG_LEASE("object %d failed %d\n", object, error); + goto out_lessee; + } + } + + /* Move the leases over */ + lessee->leases = *leases; + DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor); + + mutex_unlock(&dev->mode_config.idr_mutex); + return lessee; + +out_lessee: + drm_master_put(&lessee); + + mutex_unlock(&dev->mode_config.idr_mutex); + + return ERR_PTR(error); +} + +/** + * drm_lease_destroy - a master is going away (idr_mutex not held) + * @master: the drm_master being destroyed + * + * All lessees will have been destroyed as they + * hold a reference on their lessor. Notify any + * lessor for this master so that it can check + * the list of lessees. + */ +void drm_lease_destroy(struct drm_master *master) +{ + struct drm_device *dev = master->dev; + + mutex_lock(&dev->mode_config.idr_mutex); + + DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id); + + /* This master is referenced by all lessees, hence it cannot be destroyed + * until all of them have been + */ + WARN_ON(!list_empty(&master->lessees)); + + /* Remove this master from the lessee idr in the owner */ + if (master->lessee_id != 0) { + DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id); + idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id); + } + + /* Remove this master from any lessee list it may be on */ + list_del(&master->lessee_list); + + mutex_unlock(&dev->mode_config.idr_mutex); + + if (master->lessor) { + /* Tell the master to check the lessee list */ + drm_sysfs_hotplug_event(dev); + drm_master_put(&master->lessor); + } + + DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id); +} + +/** + * _drm_lease_revoke - revoke access to all leased objects (idr_mutex held) + * @master: the master losing its lease + */ +static void _drm_lease_revoke(struct drm_master *top) +{ + int object; + void *entry; + struct drm_master *master = top; + + lockdep_assert_held(&top->dev->mode_config.idr_mutex); + + /* + * Walk the tree starting at 'top' emptying all leases. Because + * the tree is fully connected, we can do this without recursing + */ + for (;;) { + DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id); + + /* Evacuate the lease */ + idr_for_each_entry(&master->leases, entry, object) + idr_remove(&master->leases, object); + + /* Depth-first list walk */ + + /* Down */ + if (!list_empty(&master->lessees)) { + master = list_first_entry(&master->lessees, struct drm_master, lessee_list); + } else { + /* Up */ + while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list)) + master = master->lessor; + + if (master == top) + break; + + /* Over */ + master = list_entry(master->lessee_list.next, struct drm_master, lessee_list); + } + } +} + +/** + * drm_lease_revoke - revoke access to all leased objects (idr_mutex not held) + * @top: the master losing its lease + */ +void drm_lease_revoke(struct drm_master *top) +{ + mutex_lock(&top->dev->mode_config.idr_mutex); + _drm_lease_revoke(top); + mutex_unlock(&top->dev->mode_config.idr_mutex); +} diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h index 81a40c2a9a3e..86bff9841b54 100644 --- a/include/drm/drm_auth.h +++ b/include/drm/drm_auth.h @@ -52,6 +52,12 @@ struct drm_lock_data { * @dev: Link back to the DRM device * @lock: DRI1 lock information. * @driver_priv: Pointer to driver-private information. + * @lessor: Lease holder + * @lessee_id: id for lessees. Owners always have id 0 + * @lessee_list: other lessees of the same master + * @lessees: drm_masters leasing from this one + * @leases: Objects leased to this drm_master. + * @lessee_idr: All lessees under this owner (only used where lessor == NULL) * * Note that master structures are only relevant for the legacy/primary device * nodes, hence there can only be one per device, not one per drm_minor. @@ -76,10 +82,25 @@ struct drm_master { struct idr magic_map; struct drm_lock_data lock; void *driver_priv; + + /* Tree of display resource leases, each of which is a drm_master struct + * All of these get activated simultaneously, so drm_device master points + * at the top of the tree (for which lessor is NULL). Protected by + * &drm_device.mode_config.idr_mutex. + */ + + struct drm_master *lessor; + int lessee_id; + struct list_head lessee_list; + struct list_head lessees; + struct idr leases; + struct idr lessee_idr; }; struct drm_master *drm_master_get(struct drm_master *master); void drm_master_put(struct drm_master **master); bool drm_is_current_master(struct drm_file *fpriv); +struct drm_master *drm_master_create(struct drm_device *dev); + #endif diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h new file mode 100644 index 000000000000..890018976a3c --- /dev/null +++ b/include/drm/drm_lease.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2017 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef _DRM_LEASE_H_ +#define _DRM_LEASE_H_ + +struct drm_file; +struct drm_device; +struct drm_master; + +struct drm_master *drm_lease_owner(struct drm_master *master); + +void drm_lease_destroy(struct drm_master *lessee); + +bool drm_lease_held(struct drm_file *file_priv, int id); + +bool _drm_lease_held(struct drm_file *file_priv, int id); + +void drm_lease_revoke(struct drm_master *master); + +uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs); + +uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders); + +#endif /* _DRM_LEASE_H_ */ diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index b2f920b518e3..c8155cb5a932 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -24,6 +24,7 @@ #define __DRM_MODESET_H__ #include +#include struct drm_object_properties; struct drm_property; struct drm_device; -- cgit v1.2.3 From 7de440db20d4531e4b740bf17b56afc426c54377 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 9 Apr 2017 22:35:34 -0600 Subject: drm: Check mode object lease status in all master ioctl paths [v4] Attempts to modify un-leased objects are rejected with an error. Information returned about unleased objects is modified to make them appear unusable and/or disconnected. Changes for v2 as suggested by Daniel Vetter : * With the change in the __drm_mode_object_find API to pass the file_priv along, we can now centralize most of the lease-based access checks in that function. * A few places skip that API and require in-line checks. Changes for v3 provided by Dave Airlie * remove support for leasing encoders. * add support for leasing planes. Changes for v4 * Only call drm_lease_held if DRIVER_MODESET. Signed-off-by: Keith Packard Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_auth.c | 2 +- drivers/gpu/drm/drm_encoder.c | 5 +++-- drivers/gpu/drm/drm_mode_config.c | 22 +++++++++++++--------- drivers/gpu/drm/drm_mode_object.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/drm_plane.c | 18 +++++++++++------- drivers/gpu/drm/drm_vblank.c | 22 ++++++++++++++++++++-- include/drm/drm_lease.h | 2 -- 7 files changed, 70 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 4f0e274f4111..aad468d170a7 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -310,7 +310,7 @@ out: */ bool drm_is_current_master(struct drm_file *fpriv) { - return fpriv->is_master && fpriv->master == fpriv->minor->dev->master; + return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master; } EXPORT_SYMBOL(drm_is_current_master); diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index 43f644844b83..59e0ebe733f8 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -226,7 +226,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); crtc = drm_encoder_get_crtc(encoder); - if (crtc) + if (crtc && drm_lease_held(file_priv, crtc->base.id)) enc_resp->crtc_id = crtc->base.id; else enc_resp->crtc_id = 0; @@ -234,7 +234,8 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, enc_resp->encoder_type = encoder->encoder_type; enc_resp->encoder_id = encoder->base.id; - enc_resp->possible_crtcs = encoder->possible_crtcs; + enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv, + encoder->possible_crtcs); enc_resp->possible_clones = encoder->possible_clones; return 0; diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 919e78d45ab0..cda8bfab6d3b 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -122,10 +122,12 @@ int drm_mode_getresources(struct drm_device *dev, void *data, count = 0; crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr); drm_for_each_crtc(crtc, dev) { - if (count < card_res->count_crtcs && - put_user(crtc->base.id, crtc_id + count)) - return -EFAULT; - count++; + if (drm_lease_held(file_priv, crtc->base.id)) { + if (count < card_res->count_crtcs && + put_user(crtc->base.id, crtc_id + count)) + return -EFAULT; + count++; + } } card_res->count_crtcs = count; @@ -143,12 +145,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data, count = 0; connector_id = u64_to_user_ptr(card_res->connector_id_ptr); drm_for_each_connector_iter(connector, &conn_iter) { - if (count < card_res->count_connectors && - put_user(connector->base.id, connector_id + count)) { - drm_connector_list_iter_end(&conn_iter); - return -EFAULT; + if (drm_lease_held(file_priv, connector->base.id)) { + if (count < card_res->count_connectors && + put_user(connector->base.id, connector_id + count)) { + drm_connector_list_iter_end(&conn_iter); + return -EFAULT; + } + count++; } - count++; } card_res->count_connectors = count; drm_connector_list_iter_end(&conn_iter); diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 240a05d91a53..d1599f36b605 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -104,6 +104,25 @@ void drm_mode_object_unregister(struct drm_device *dev, mutex_unlock(&dev->mode_config.idr_mutex); } +/** + * drm_lease_required - check types which must be leased to be used + * @type: type of object + * + * Returns whether the provided type of drm_mode_object must + * be owned or leased to be used by a process. + */ +static bool drm_lease_required(uint32_t type) +{ + switch(type) { + case DRM_MODE_OBJECT_CRTC: + case DRM_MODE_OBJECT_CONNECTOR: + case DRM_MODE_OBJECT_PLANE: + return true; + default: + return false; + } +} + struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, struct drm_file *file_priv, uint32_t id, uint32_t type) @@ -117,6 +136,9 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, if (obj && obj->id != id) obj = NULL; + if (obj && drm_lease_required(obj->type) && !_drm_lease_held(file_priv, obj->id)) + obj = NULL; + if (obj && obj->free_cb) { if (!kref_get_unless_zero(&obj->refcount)) obj = NULL; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 8d9824804b0c..19404e34cd59 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -479,10 +479,12 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, !file_priv->universal_planes) continue; - if (count < plane_resp->count_planes && - put_user(plane->base.id, plane_ptr + count)) - return -EFAULT; - count++; + if (drm_lease_held(file_priv, plane->base.id)) { + if (count < plane_resp->count_planes && + put_user(plane->base.id, plane_ptr + count)) + return -EFAULT; + count++; + } } plane_resp->count_planes = count; @@ -504,9 +506,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data, return -ENOENT; drm_modeset_lock(&plane->mutex, NULL); - if (plane->state && plane->state->crtc) + if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id)) plane_resp->crtc_id = plane->state->crtc->base.id; - else if (!plane->state && plane->crtc) + else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id)) plane_resp->crtc_id = plane->crtc->base.id; else plane_resp->crtc_id = 0; @@ -520,7 +522,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data, drm_modeset_unlock(&plane->mutex); plane_resp->plane_id = plane->base.id; - plane_resp->possible_crtcs = plane->possible_crtcs; + plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv, + plane->possible_crtcs); + plane_resp->gamma_size = 0; /* diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 13722c373a6a..57cc6e37c810 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1447,10 +1447,12 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe, int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_crtc *crtc; struct drm_vblank_crtc *vblank; union drm_wait_vblank *vblwait = data; int ret; u64 req_seq, seq; + unsigned int pipe_index; unsigned int flags, pipe, high_pipe; if (!dev->irq_enabled) @@ -1472,9 +1474,25 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); if (high_pipe) - pipe = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT; + pipe_index = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT; else - pipe = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; + pipe_index = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; + + /* Convert lease-relative crtc index into global crtc index */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + pipe = 0; + drm_for_each_crtc(crtc, dev) { + if (drm_lease_held(file_priv, crtc->base.id)) { + if (pipe_index == 0) + break; + pipe_index--; + } + pipe++; + } + } else { + pipe = pipe_index; + } + if (pipe >= dev->num_crtcs) return -EINVAL; diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h index 890018976a3c..6149e56ddbf3 100644 --- a/include/drm/drm_lease.h +++ b/include/drm/drm_lease.h @@ -31,6 +31,4 @@ void drm_lease_revoke(struct drm_master *master); uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs); -uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders); - #endif /* _DRM_LEASE_H_ */ -- cgit v1.2.3 From 62884cd386b876638720ef88374b31a84ca7ee5f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 Mar 2017 17:56:28 -0700 Subject: drm: Add four ioctls for managing drm mode object leases [v7] drm_mode_create_lease Creates a lease for a list of drm mode objects, returning an fd for the new drm_master and a 64-bit identifier for the lessee drm_mode_list_lesees List the identifiers of the lessees for a master file drm_mode_get_lease List the leased objects for a master file drm_mode_revoke_lease Erase the set of objects managed by a lease. This should suffice to at least create and query leases. Changes for v2 as suggested by Daniel Vetter : * query ioctls only query the master associated with the provided file. * 'mask_lease' value has been removed * change ioctl has been removed. Changes for v3 suggested in part by Dave Airlie * Add revoke ioctl. Changes for v4 suggested by Dave Airlie * Expand on the comment about the magic use of &drm_lease_idr_object * Pad lease ioctl structures to align on 64-bit boundaries Changes for v5 suggested by Dave Airlie * Check for non-negative object_id in create_lease to avoid debug output from the kernel. Changes for v6 provided by Dave Airlie * For non-universal planes add primary/cursor planes to lease If we aren't exposing universal planes to this userspace client, and it requests a lease on a crtc, we should implicitly export the primary and cursor planes for the crtc. If the lessee doesn't request universal planes, it will just see the crtc, but if it does request them it will then see the plane objects as well. This also moves the object look ups earlier as a side effect, so we'd exit the ioctl quicker for non-existant objects. * Restrict leases to crtc/connector/planes. This only allows leasing for objects we wish to allow. Changes for v7 provided by Dave Airlie * Check pad args are 0 * Check create flags and object count are valid. * Check return from fd allocation * Refactor lease idr setup and add some simple validation * Use idr_mutex uniformly (Keith) Signed-off-by: Keith Packard Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_ioctl.c | 4 + drivers/gpu/drm/drm_lease.c | 412 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_mode_object.c | 5 +- include/drm/drm_lease.h | 12 ++ include/drm/drm_mode_object.h | 2 + include/uapi/drm/drm.h | 5 + include/uapi/drm/drm_mode.h | 66 ++++++ 7 files changed, 504 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 9c435a4c0c82..4aafe4802099 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -665,6 +665,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 030db1170570..d1eb56a1eff4 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -23,6 +23,8 @@ #define drm_for_each_lessee(lessee, lessor) \ list_for_each_entry((lessee), &(lessor)->lessees, lessee_list) +static uint64_t drm_lease_idr_object; + /** * drm_lease_owner - return ancestor owner drm_master * @master: drm_master somewhere within tree of lessees and lessors @@ -353,3 +355,413 @@ void drm_lease_revoke(struct drm_master *top) _drm_lease_revoke(top); mutex_unlock(&top->dev->mode_config.idr_mutex); } + +static int validate_lease(struct drm_device *dev, + struct drm_file *lessor_priv, + int object_count, + struct drm_mode_object **objects) +{ + int o; + int has_crtc = -1; + int has_connector = -1; + int has_plane = -1; + + /* we want to confirm that there is at least one crtc, plane + connector object. */ + + for (o = 0; o < object_count; o++) { + if (objects[o]->type == DRM_MODE_OBJECT_CRTC && has_crtc == -1) { + has_crtc = o; + } + if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1) + has_connector = o; + + if (lessor_priv->universal_planes) { + if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1) + has_plane = o; + } + } + if (has_crtc == -1 || has_connector == -1) + return -EINVAL; + if (lessor_priv->universal_planes && has_plane == -1) + return -EINVAL; + return 0; +} + +static int fill_object_idr(struct drm_device *dev, + struct drm_file *lessor_priv, + struct idr *leases, + int object_count, + u32 *object_ids) +{ + struct drm_mode_object **objects; + u32 o; + int ret; + objects = kcalloc(object_count, sizeof(struct drm_mode_object *), + GFP_KERNEL); + if (!objects) + return -ENOMEM; + + /* step one - get references to all the mode objects + and check for validity. */ + for (o = 0; o < object_count; o++) { + if ((int) object_ids[o] < 0) { + ret = -EINVAL; + goto out_free_objects; + } + + objects[o] = drm_mode_object_find(dev, lessor_priv, + object_ids[o], + DRM_MODE_OBJECT_ANY); + if (!objects[o]) { + ret = -ENOENT; + goto out_free_objects; + } + + if (!drm_mode_object_lease_required(objects[o]->type)) { + ret = -EINVAL; + goto out_free_objects; + } + } + + ret = validate_lease(dev, lessor_priv, object_count, objects); + if (ret) + goto out_free_objects; + + /* add their IDs to the lease request - taking into account + universal planes */ + for (o = 0; o < object_count; o++) { + struct drm_mode_object *obj = objects[o]; + u32 object_id = objects[o]->id; + DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id); + + /* + * We're using an IDR to hold the set of leased + * objects, but we don't need to point at the object's + * data structure from the lease as the main crtc_idr + * will be used to actually find that. Instead, all we + * really want is a 'leased/not-leased' result, for + * which any non-NULL pointer will work fine. + */ + ret = idr_alloc(leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL); + if (ret < 0) { + DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n", + object_id, ret); + goto out_free_objects; + } + if (obj->type == DRM_MODE_OBJECT_CRTC && !lessor_priv->universal_planes) { + struct drm_crtc *crtc = obj_to_crtc(obj); + ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL); + if (ret < 0) { + DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n", + object_id, ret); + goto out_free_objects; + } + if (crtc->cursor) { + ret = idr_alloc(leases, &drm_lease_idr_object, crtc->cursor->base.id, crtc->cursor->base.id + 1, GFP_KERNEL); + if (ret < 0) { + DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n", + object_id, ret); + goto out_free_objects; + } + } + } + } + + ret = 0; +out_free_objects: + for (o = 0; o < object_count; o++) { + if (objects[o]) + drm_mode_object_put(objects[o]); + } + kfree(objects); + return ret; +} + +/** + * drm_mode_create_lease_ioctl - create a new lease + * @dev: the drm device + * @data: pointer to struct drm_mode_create_lease + * @file_priv: the file being manipulated + * + * The master associated with the specified file will have a lease + * created containing the objects specified in the ioctl structure. + * A file descriptor will be allocated for that and returned to the + * application. + */ +int drm_mode_create_lease_ioctl(struct drm_device *dev, + void *data, struct drm_file *lessor_priv) +{ + struct drm_mode_create_lease *cl = data; + size_t object_count; + int ret = 0; + struct idr leases; + struct drm_master *lessor = lessor_priv->master; + struct drm_master *lessee = NULL; + struct file *lessee_file = NULL; + struct file *lessor_file = lessor_priv->filp; + struct drm_file *lessee_priv; + int fd = -1; + uint32_t *object_ids; + + /* Can't lease without MODESET */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + /* Do not allow sub-leases */ + if (lessor->lessor) + return -EINVAL; + + /* need some objects */ + if (cl->object_count == 0) + return -EINVAL; + + if (cl->flags && (cl->flags & ~(O_CLOEXEC | O_NONBLOCK))) + return -EINVAL; + + object_count = cl->object_count; + + object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), object_count * sizeof(__u32)); + if (IS_ERR(object_ids)) + return PTR_ERR(object_ids); + + idr_init(&leases); + + /* fill and validate the object idr */ + ret = fill_object_idr(dev, lessor_priv, &leases, + object_count, object_ids); + kfree(object_ids); + if (ret) { + idr_destroy(&leases); + return ret; + } + + /* Allocate a file descriptor for the lease */ + fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK)); + if (fd < 0) { + idr_destroy(&leases); + return fd; + } + + DRM_DEBUG_LEASE("Creating lease\n"); + lessee = drm_lease_create(lessor, &leases); + + if (IS_ERR(lessee)) { + ret = PTR_ERR(lessee); + goto out_leases; + } + + /* Clone the lessor file to create a new file for us */ + DRM_DEBUG_LEASE("Allocating lease file\n"); + path_get(&lessor_file->f_path); + lessee_file = alloc_file(&lessor_file->f_path, + lessor_file->f_mode, + fops_get(lessor_file->f_inode->i_fop)); + + if (IS_ERR(lessee_file)) { + ret = PTR_ERR(lessee_file); + goto out_lessee; + } + + /* Initialize the new file for DRM */ + DRM_DEBUG_LEASE("Initializing the file with %p\n", lessee_file->f_op->open); + ret = lessee_file->f_op->open(lessee_file->f_inode, lessee_file); + if (ret) + goto out_lessee_file; + + lessee_priv = lessee_file->private_data; + + /* Change the file to a master one */ + drm_master_put(&lessee_priv->master); + lessee_priv->master = lessee; + lessee_priv->is_master = 1; + lessee_priv->authenticated = 1; + + /* Hook up the fd */ + fd_install(fd, lessee_file); + + /* Pass fd back to userspace */ + DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id); + cl->fd = fd; + cl->lessee_id = lessee->lessee_id; + + DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n"); + return 0; + +out_lessee_file: + fput(lessee_file); + +out_lessee: + drm_master_put(&lessee); + +out_leases: + put_unused_fd(fd); + idr_destroy(&leases); + + DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret); + return ret; +} + +/** + * drm_mode_list_lessees_ioctl - list lessee ids + * @dev: the drm device + * @data: pointer to struct drm_mode_list_lessees + * @lessor_priv: the file being manipulated + * + * Starting from the master associated with the specified file, + * the master with the provided lessee_id is found, and then + * an array of lessee ids associated with leases from that master + * are returned. + */ + +int drm_mode_list_lessees_ioctl(struct drm_device *dev, + void *data, struct drm_file *lessor_priv) +{ + struct drm_mode_list_lessees *arg = data; + __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr); + __u32 count_lessees = arg->count_lessees; + struct drm_master *lessor = lessor_priv->master, *lessee; + int count; + int ret = 0; + + if (arg->pad) + return -EINVAL; + + /* Can't lease without MODESET */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id); + + mutex_lock(&dev->mode_config.idr_mutex); + + count = 0; + drm_for_each_lessee(lessee, lessor) { + /* Only list un-revoked leases */ + if (!idr_is_empty(&lessee->leases)) { + if (count_lessees > count) { + DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id); + ret = put_user(lessee->lessee_id, lessee_ids + count); + if (ret) + break; + } + count++; + } + } + + DRM_DEBUG_LEASE("Lessor leases to %d\n", count); + if (ret == 0) + arg->count_lessees = count; + + mutex_unlock(&dev->mode_config.idr_mutex); + + return ret; +} + +/** + * drm_mode_get_lease_ioctl - list leased objects + * @dev: the drm device + * @data: pointer to struct drm_mode_get_lease + * @file_priv: the file being manipulated + * + * Return the list of leased objects for the specified lessee + */ + +int drm_mode_get_lease_ioctl(struct drm_device *dev, + void *data, struct drm_file *lessee_priv) +{ + struct drm_mode_get_lease *arg = data; + __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr); + __u32 count_objects = arg->count_objects; + struct drm_master *lessee = lessee_priv->master; + struct idr *object_idr; + int count; + void *entry; + int object; + int ret = 0; + + if (arg->pad) + return -EINVAL; + + /* Can't lease without MODESET */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id); + + mutex_lock(&dev->mode_config.idr_mutex); + + if (lessee->lessor == NULL) + /* owner can use all objects */ + object_idr = &lessee->dev->mode_config.crtc_idr; + else + /* lessee can only use allowed object */ + object_idr = &lessee->leases; + + count = 0; + idr_for_each_entry(object_idr, entry, object) { + if (count_objects > count) { + DRM_DEBUG_LEASE("adding object %d\n", object); + ret = put_user(object, object_ids + count); + if (ret) + break; + } + count++; + } + + DRM_DEBUG("lease holds %d objects\n", count); + if (ret == 0) + arg->count_objects = count; + + mutex_unlock(&dev->mode_config.idr_mutex); + + return ret; +} + +/** + * drm_mode_revoke_lease_ioctl - revoke lease + * @dev: the drm device + * @data: pointer to struct drm_mode_revoke_lease + * @file_priv: the file being manipulated + * + * This removes all of the objects from the lease without + * actually getting rid of the lease itself; that way all + * references to it still work correctly + */ +int drm_mode_revoke_lease_ioctl(struct drm_device *dev, + void *data, struct drm_file *lessor_priv) +{ + struct drm_mode_revoke_lease *arg = data; + struct drm_master *lessor = lessor_priv->master; + struct drm_master *lessee; + int ret = 0; + + DRM_DEBUG_LEASE("revoke lease for %d\n", arg->lessee_id); + + /* Can't lease without MODESET */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + mutex_lock(&dev->mode_config.idr_mutex); + + lessee = _drm_find_lessee(lessor, arg->lessee_id); + + /* No such lessee */ + if (!lessee) { + ret = -ENOENT; + goto fail; + } + + /* Lease is not held by lessor */ + if (lessee->lessor != lessor) { + ret = -EACCES; + goto fail; + } + + _drm_lease_revoke(lessee); + +fail: + mutex_unlock(&dev->mode_config.idr_mutex); + + return ret; +} diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index d1599f36b605..7c8b2698c6a7 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -111,7 +111,7 @@ void drm_mode_object_unregister(struct drm_device *dev, * Returns whether the provided type of drm_mode_object must * be owned or leased to be used by a process. */ -static bool drm_lease_required(uint32_t type) +bool drm_mode_object_lease_required(uint32_t type) { switch(type) { case DRM_MODE_OBJECT_CRTC: @@ -136,7 +136,8 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, if (obj && obj->id != id) obj = NULL; - if (obj && drm_lease_required(obj->type) && !_drm_lease_held(file_priv, obj->id)) + if (obj && drm_mode_object_lease_required(obj->type) && + !_drm_lease_held(file_priv, obj->id)) obj = NULL; if (obj && obj->free_cb) { diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h index 6149e56ddbf3..fbc0ab54855b 100644 --- a/include/drm/drm_lease.h +++ b/include/drm/drm_lease.h @@ -31,4 +31,16 @@ void drm_lease_revoke(struct drm_master *master); uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs); +int drm_mode_create_lease_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); + +int drm_mode_list_lessees_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); + +int drm_mode_get_lease_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); + +int drm_mode_revoke_lease_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); + #endif /* _DRM_LEASE_H_ */ diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index c8155cb5a932..7ba3913f30b5 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -154,4 +154,6 @@ int drm_object_property_get_value(struct drm_mode_object *obj, void drm_object_attach_property(struct drm_mode_object *obj, struct drm_property *property, uint64_t init_val); + +bool drm_mode_object_lease_required(uint32_t type); #endif diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 91d83c1747c0..6fdff5945c8a 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -888,6 +888,11 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array) #define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array) +#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease) +#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees) +#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease) +#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease) + /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 34b6bb34b002..5597a87154e5 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -782,6 +782,72 @@ struct drm_mode_destroy_blob { __u32 blob_id; }; +/** + * Lease mode resources, creating another drm_master. + */ +struct drm_mode_create_lease { + /** Pointer to array of object ids (__u32) */ + __u64 object_ids; + /** Number of object ids */ + __u32 object_count; + /** flags for new FD (O_CLOEXEC, etc) */ + __u32 flags; + + /** Return: unique identifier for lessee. */ + __u32 lessee_id; + /** Return: file descriptor to new drm_master file */ + __u32 fd; +}; + +/** + * List lesses from a drm_master + */ +struct drm_mode_list_lessees { + /** Number of lessees. + * On input, provides length of the array. + * On output, provides total number. No + * more than the input number will be written + * back, so two calls can be used to get + * the size and then the data. + */ + __u32 count_lessees; + __u32 pad; + + /** Pointer to lessees. + * pointer to __u64 array of lessee ids + */ + __u64 lessees_ptr; +}; + +/** + * Get leased objects + */ +struct drm_mode_get_lease { + /** Number of leased objects. + * On input, provides length of the array. + * On output, provides total number. No + * more than the input number will be written + * back, so two calls can be used to get + * the size and then the data. + */ + __u32 count_objects; + __u32 pad; + + /** Pointer to objects. + * pointer to __u32 array of object ids + */ + __u64 objects_ptr; +}; + +/** + * Revoke lease + */ +struct drm_mode_revoke_lease { + /** Unique ID of lessee + */ + __u32 lessee_id; +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From 092e72c9edab16d4d6ad10c683a95047d53b6db4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 25 Oct 2017 11:04:47 +0100 Subject: efi/efi_test: Prevent an Oops in efi_runtime_query_capsulecaps() If "qcaps.capsule_count" is ULONG_MAX then "qcaps.capsule_count + 1" will overflow to zero and kcalloc() will return the ZERO_SIZE_PTR. We try to dereference it inside the loop and crash. Signed-off-by: Dan Carpenter Signed-off-by: Matt Fleming Signed-off-by: Ard Biesheuvel Acked-by: Ivan Hu Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Fixes: ff6301dabc3c ("efi: Add efi_test driver for exporting UEFI runtime service interfaces") Link: http://lkml.kernel.org/r/20171025100448.26056-2-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/test/efi_test.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/efi/test/efi_test.c b/drivers/firmware/efi/test/efi_test.c index 08129b7b80ab..41c48a1e8baa 100644 --- a/drivers/firmware/efi/test/efi_test.c +++ b/drivers/firmware/efi/test/efi_test.c @@ -593,6 +593,9 @@ static long efi_runtime_query_capsulecaps(unsigned long arg) if (copy_from_user(&qcaps, qcaps_user, sizeof(qcaps))) return -EFAULT; + if (qcaps.capsule_count == ULONG_MAX) + return -EINVAL; + capsules = kcalloc(qcaps.capsule_count + 1, sizeof(efi_capsule_header_t), GFP_KERNEL); if (!capsules) -- cgit v1.2.3 From 38fb6652229c2149e8694d57db442878fdf8a1bd Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 25 Oct 2017 11:04:48 +0100 Subject: efi/libstub/arm: Don't randomize runtime regions when CONFIG_HIBERNATION=y Commit: e69176d68d26 ("ef/libstub/arm/arm64: Randomize the base of the UEFI rt services region") implemented randomization of the virtual mapping that the OS chooses for the UEFI runtime services. This was motivated by the fact that UEFI usually does not bother to specify any permission restrictions for those regions, making them prime real estate for exploitation now that the OS is getting more and more careful not to leave any R+W+X mapped regions lying around. However, this randomization breaks assumptions in the resume from hibernation code, which expects all memory regions populated by UEFI to remain in the same place, including their virtual mapping into the OS memory space. While this assumption may not be entirely reasonable in the first place, breaking it deliberately does not make a lot of sense either. So let's refrain from this randomization pass if CONFIG_HIBERNATION=y. Signed-off-by: Ard Biesheuvel Cc: James Morse Cc: Linus Torvalds Cc: Matt Fleming Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20171025100448.26056-3-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/libstub/arm-stub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index 1cb2d1c070c3..a94601d5939e 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -238,7 +238,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, efi_random_get_seed(sys_table); - if (!nokaslr()) { + /* hibernation expects the runtime regions to stay in the same place */ + if (!IS_ENABLED(CONFIG_HIBERNATION) && !nokaslr()) { /* * Randomize the base of the UEFI runtime services region. * Preserve the 2 MB alignment of the region by taking a -- cgit v1.2.3 From d3daa2c7865cbfa830651b11c8ad1df23465b46e Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 23 Oct 2017 11:27:35 -0400 Subject: drm/amd/amdgpu: Remove workaround check for UVD6 on APUs On APUs the uvd6 driver was skipping proper suspend/resume routines resulting in a broken state upon resume. Signed-off-by: Tom St Denis Acked-by: Alex Deucher Reviewed-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 31db356476f8..430a6b4dfac9 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -225,11 +225,7 @@ static int uvd_v6_0_suspend(void *handle) if (r) return r; - /* Skip this for APU for now */ - if (!(adev->flags & AMD_IS_APU)) - r = amdgpu_uvd_suspend(adev); - - return r; + return amdgpu_uvd_suspend(adev); } static int uvd_v6_0_resume(void *handle) @@ -237,12 +233,10 @@ static int uvd_v6_0_resume(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - /* Skip this for APU for now */ - if (!(adev->flags & AMD_IS_APU)) { - r = amdgpu_uvd_resume(adev); - if (r) - return r; - } + r = amdgpu_uvd_resume(adev); + if (r) + return r; + return uvd_v6_0_hw_init(adev); } -- cgit v1.2.3 From 7277f755048da562eb2489becacd38d0d05e1e06 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 24 Oct 2017 16:27:28 +0100 Subject: drm/i915/perf: fix perf enable/disable ioctls with 32bits userspace The compat callback was missing and triggered failures in 32bits userspace when enabling/disable the perf stream. We don't require any particular processing here as these ioctls don't take any argument. Signed-off-by: Lionel Landwerlin Fixes: eec688e1420 ("drm/i915: Add i915 perf infrastructure") Cc: linux-stable Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20171024152728.4873-1-lionel.g.landwerlin@intel.com (cherry picked from commit 191f896085cf3b5d85920d58a759da4eea141721) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_perf.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 94185d610673..370b9d248fed 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -2537,6 +2537,10 @@ static const struct file_operations fops = { .poll = i915_perf_poll, .read = i915_perf_read, .unlocked_ioctl = i915_perf_ioctl, + /* Our ioctl have no arguments, so it's safe to use the same function + * to handle 32bits compatibility. + */ + .compat_ioctl = i915_perf_ioctl, }; -- cgit v1.2.3 From 298d275d4d9bea3524ff4bc76678c140611d8a8d Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Wed, 25 Oct 2017 17:08:07 +0200 Subject: xen/gntdev: avoid out of bounds access in case of partial gntdev_mmap() In case gntdev_mmap() succeeds only partially in mapping grant pages it will leave some vital information uninitialized needed later for cleanup. This will lead to an out of bounds array access when unmapping the already mapped pages. So just initialize the data needed for unmapping the pages a little bit earlier. Cc: Reported-by: Arthur Borsboom Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Signed-off-by: Boris Ostrovsky --- drivers/xen/gntdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 82360594fa8e..57efbd3b053b 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -1024,6 +1024,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) mutex_unlock(&priv->lock); if (use_ptemod) { + map->pages_vm_start = vma->vm_start; err = apply_to_page_range(vma->vm_mm, vma->vm_start, vma->vm_end - vma->vm_start, find_grant_ptes, map); @@ -1061,7 +1062,6 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) set_grant_ptes_as_special, NULL); } #endif - map->pages_vm_start = vma->vm_start; } return 0; -- cgit v1.2.3 From b4d91aeb6e120b7e2f207021c31b914895c69bc4 Mon Sep 17 00:00:00 2001 From: "Michael J. Ruhl" Date: Tue, 24 Oct 2017 08:41:01 -0400 Subject: RDMA/netlink: OOPs in rdma_nl_rcv_msg() from misinterpreted flag rdma_nl_rcv_msg() checks to see if it should use the .dump() callback or the .doit() callback. The check is done with this check: if (flags & NLM_F_DUMP) ... The NLM_F_DUMP flag is two bits (NLM_F_ROOT | NLM_F_MATCH). When an RDMA_NL_LS message (response) is received, the bit used for indicating an error is the same bit as NLM_F_ROOT. NLM_F_ROOT == (0x100) == RDMA_NL_LS_F_ERR. ibacm sends a response with the RDMA_NL_LS_F_ERR bit set if an error occurs in the service. The current code then misinterprets the NLM_F_DUMP bit and trys to call the .dump() callback. If the .dump() callback for the specified request is not available (which is true for the RDMA_NL_LS messages) the following Oops occurs: [ 4555.960256] BUG: unable to handle kernel NULL pointer dereference at (null) [ 4555.969046] IP: (null) [ 4555.972664] PGD 10543f1067 P4D 10543f1067 PUD 1033f93067 PMD 0 [ 4555.979287] Oops: 0010 [#1] SMP [ 4555.982809] Modules linked in: rpcrdma ib_isert iscsi_target_mod target_core_mod ib_iser libiscsi scsi_transport_iscsi ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm dm_mirror dm_region_hash dm_log dm_mod dax sb_edac x86_pkg_temp_thermal intel_powerclamp coretemp kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel crypto_simd glue_helper cryptd hfi1 rdmavt iTCO_wdt iTCO_vendor_support ib_core mei_me lpc_ich pcspkr mei ioatdma sg shpchp i2c_i801 mfd_core wmi ipmi_si ipmi_devintf ipmi_msghandler acpi_power_meter acpi_pad nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables ext4 mbcache jbd2 sd_mod mgag200 drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm igb ahci crc32c_intel ptp libahci pps_core drm dca libata i2c_algo_bit i2c_core [ 4556.061190] CPU: 54 PID: 9841 Comm: ibacm Tainted: G I 4.14.0-rc2+ #6 [ 4556.069667] Hardware name: Intel Corporation S2600WT2/S2600WT2, BIOS SE5C610.86B.01.01.0008.021120151325 02/11/2015 [ 4556.081339] task: ffff880855f42d00 task.stack: ffffc900246b4000 [ 4556.087967] RIP: 0010: (null) [ 4556.092166] RSP: 0018:ffffc900246b7bc8 EFLAGS: 00010246 [ 4556.098018] RAX: ffffffff81dbe9e0 RBX: ffff881058bb1000 RCX: 0000000000000000 [ 4556.105997] RDX: 0000000000001100 RSI: ffff881058bb1320 RDI: ffff881056362000 [ 4556.113984] RBP: ffffc900246b7bf8 R08: 0000000000000ec0 R09: 0000000000001100 [ 4556.121971] R10: ffff8810573a5000 R11: 0000000000000000 R12: ffff881056362000 [ 4556.129957] R13: 0000000000000ec0 R14: ffff881058bb1320 R15: 0000000000000ec0 [ 4556.137945] FS: 00007fe0ba5a38c0(0000) GS:ffff88105f080000(0000) knlGS:0000000000000000 [ 4556.147000] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 4556.153433] CR2: 0000000000000000 CR3: 0000001056f5d003 CR4: 00000000001606e0 [ 4556.161419] Call Trace: [ 4556.164167] ? netlink_dump+0x12c/0x290 [ 4556.168468] __netlink_dump_start+0x186/0x1f0 [ 4556.173357] rdma_nl_rcv_msg+0x193/0x1b0 [ib_core] [ 4556.178724] rdma_nl_rcv+0xdc/0x130 [ib_core] [ 4556.183604] netlink_unicast+0x181/0x240 [ 4556.187998] netlink_sendmsg+0x2c2/0x3b0 [ 4556.192392] sock_sendmsg+0x38/0x50 [ 4556.196299] SYSC_sendto+0x102/0x190 [ 4556.200308] ? __audit_syscall_entry+0xaf/0x100 [ 4556.205387] ? syscall_trace_enter+0x1d0/0x2b0 [ 4556.210366] ? __audit_syscall_exit+0x209/0x290 [ 4556.215442] SyS_sendto+0xe/0x10 [ 4556.219060] do_syscall_64+0x67/0x1b0 [ 4556.223165] entry_SYSCALL64_slow_path+0x25/0x25 [ 4556.228328] RIP: 0033:0x7fe0b9db2a63 [ 4556.232333] RSP: 002b:00007ffc55edc260 EFLAGS: 00000293 ORIG_RAX: 000000000000002c [ 4556.240808] RAX: ffffffffffffffda RBX: 0000000000000010 RCX: 00007fe0b9db2a63 [ 4556.248796] RDX: 0000000000000010 RSI: 00007ffc55edc280 RDI: 000000000000000d [ 4556.256782] RBP: 00007ffc55edc670 R08: 00007ffc55edc270 R09: 000000000000000c [ 4556.265321] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc55edc280 [ 4556.273846] R13: 000000000260b400 R14: 000000000000000d R15: 0000000000000001 [ 4556.282368] Code: Bad RIP value. [ 4556.286629] RIP: (null) RSP: ffffc900246b7bc8 [ 4556.293013] CR2: 0000000000000000 [ 4556.297292] ---[ end trace 8d67abcfd10ec209 ]--- [ 4556.305465] Kernel panic - not syncing: Fatal exception [ 4556.313786] Kernel Offset: disabled [ 4556.321563] ---[ end Kernel panic - not syncing: Fatal exception [ 4556.328960] ------------[ cut here ]------------ Special case RDMA_NL_LS response messages to call the appropriate callback. Additionally, make sure that the .dump() callback is not NULL before calling it. Fixes: 647c75ac59a48a54 ("RDMA/netlink: Convert LS to doit callback") Reviewed-by: Mike Marciniszyn Reviewed-by: Kaike Wan Reviewed-by: Alex Estrin Signed-off-by: Michael J. Ruhl Reviewed-by: Shiraz Saleem Signed-off-by: Doug Ledford --- drivers/infiniband/core/netlink.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index b12e58787c3d..1fb72c356e36 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -175,13 +175,24 @@ static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, !netlink_capable(skb, CAP_NET_ADMIN)) return -EPERM; + /* + * LS responses overload the 0x100 (NLM_F_ROOT) flag. Don't + * mistakenly call the .dump() function. + */ + if (index == RDMA_NL_LS) { + if (cb_table[op].doit) + return cb_table[op].doit(skb, nlh, extack); + return -EINVAL; + } /* FIXME: Convert IWCM to properly handle doit callbacks */ if ((nlh->nlmsg_flags & NLM_F_DUMP) || index == RDMA_NL_RDMA_CM || index == RDMA_NL_IWCM) { struct netlink_dump_control c = { .dump = cb_table[op].dump, }; - return netlink_dump_start(nls, skb, nlh, &c); + if (c.dump) + return netlink_dump_start(nls, skb, nlh, &c); + return -EINVAL; } if (cb_table[op].doit) -- cgit v1.2.3 From 7265d50ea20f0dfe7e6d077a2feb50369773c090 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Oct 2017 12:44:18 +0300 Subject: drm/amd/powerplay: fix amd_powerplay_reset() We accidentally inverted an if statement and turned amd_powerplay_reset() into a no-op. Fixes: ae97988fc89e ("drm/amd/powerplay: tidy up ret checks in amd_powerplay.c (v3)") Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 3c8ef4bfc205..0f8b6dc853a5 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1184,7 +1184,7 @@ int amd_powerplay_reset(void *handle) int ret; ret = pp_check(instance); - if (!ret) + if (ret) return ret; ret = pp_hw_fini(instance); -- cgit v1.2.3 From 521d98a36fd0d5fe8df46fd2c3da9503e1262513 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:32 +0200 Subject: drm/exynos/mixer: abstract out output mode setup code Mode setup code is called from video plane update and mixer plane update. Let's group it together in mixer_commit function like in case of other Exynos CRTCs. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 002755415e00..499ebdca4fed 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -473,6 +473,22 @@ static void mixer_stop(struct mixer_context *ctx) usleep_range(10000, 12000); } +static void mixer_commit(struct mixer_context *ctx) +{ + struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode; + + /* setup display size */ + if (ctx->mxr_ver == MXR_VER_128_0_0_184) { + u32 val = MXR_MXR_RES_HEIGHT(mode->vdisplay) + | MXR_MXR_RES_WIDTH(mode->hdisplay); + mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION, val); + } + + mixer_cfg_scan(ctx, mode->vdisplay); + mixer_cfg_rgb_fmt(ctx, mode->vdisplay); + mixer_run(ctx); +} + static void vp_video_buffer(struct mixer_context *ctx, struct exynos_drm_plane *plane) { @@ -553,11 +569,9 @@ static void vp_video_buffer(struct mixer_context *ctx, vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); - mixer_cfg_scan(ctx, mode->vdisplay); - mixer_cfg_rgb_fmt(ctx, mode->vdisplay); mixer_cfg_layer(ctx, plane->index, priority, true); mixer_cfg_vp_blend(ctx); - mixer_run(ctx); + mixer_commit(ctx); spin_unlock_irqrestore(&res->reg_slock, flags); @@ -638,14 +652,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), fb->pitches[0] / fb->format->cpp[0]); - /* setup display size */ - if (ctx->mxr_ver == MXR_VER_128_0_0_184 && - win == DEFAULT_WIN) { - val = MXR_MXR_RES_HEIGHT(mode->vdisplay); - val |= MXR_MXR_RES_WIDTH(mode->hdisplay); - mixer_reg_write(res, MXR_RESOLUTION, val); - } - val = MXR_GRP_WH_WIDTH(state->src.w); val |= MXR_GRP_WH_HEIGHT(state->src.h); val |= MXR_GRP_WH_H_SCALE(x_ratio); @@ -660,18 +666,15 @@ static void mixer_graph_buffer(struct mixer_context *ctx, /* set buffer address to mixer */ mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); - mixer_cfg_scan(ctx, mode->vdisplay); - mixer_cfg_rgb_fmt(ctx, mode->vdisplay); mixer_cfg_layer(ctx, win, priority, true); mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format)); + mixer_commit(ctx); /* layer update mandatory for mixer 16.0.33.0 */ if (ctx->mxr_ver == MXR_VER_16_0_33_0 || ctx->mxr_ver == MXR_VER_128_0_0_184) mixer_layer_update(ctx); - mixer_run(ctx); - spin_unlock_irqrestore(&res->reg_slock, flags); mixer_regs_dump(ctx); -- cgit v1.2.3 From 71469944dea0e7c5d9426171a7a5fb3609b9d15f Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:33 +0200 Subject: drm/exynos/mixer: move mode commit to enable callback Mode commit should not be called for every plane separately. It is enough to call it once in enable callback. The change also requires that the interlace check is moved to mixer_commit. It should be done in the same patch to avoid regression. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 499ebdca4fed..ae89e53186ee 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -477,6 +477,11 @@ static void mixer_commit(struct mixer_context *ctx) { struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + __set_bit(MXR_BIT_INTERLACE, &ctx->flags); + else + __clear_bit(MXR_BIT_INTERLACE, &ctx->flags); + /* setup display size */ if (ctx->mxr_ver == MXR_VER_128_0_0_184) { u32 val = MXR_MXR_RES_HEIGHT(mode->vdisplay) @@ -494,7 +499,6 @@ static void vp_video_buffer(struct mixer_context *ctx, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode; struct mixer_resources *res = &ctx->mixer_res; struct drm_framebuffer *fb = state->base.fb; unsigned int priority = state->base.normalized_zpos + 1; @@ -509,8 +513,7 @@ static void vp_video_buffer(struct mixer_context *ctx, luma_addr[0] = exynos_drm_fb_dma_addr(fb, 0); chroma_addr[0] = exynos_drm_fb_dma_addr(fb, 1); - if (mode->flags & DRM_MODE_FLAG_INTERLACE) { - __set_bit(MXR_BIT_INTERLACE, &ctx->flags); + if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { if (is_tiled) { luma_addr[1] = luma_addr[0] + 0x40; chroma_addr[1] = chroma_addr[0] + 0x40; @@ -519,7 +522,6 @@ static void vp_video_buffer(struct mixer_context *ctx, chroma_addr[1] = chroma_addr[0] + fb->pitches[0]; } } else { - __clear_bit(MXR_BIT_INTERLACE, &ctx->flags); luma_addr[1] = 0; chroma_addr[1] = 0; } @@ -571,7 +573,6 @@ static void vp_video_buffer(struct mixer_context *ctx, mixer_cfg_layer(ctx, plane->index, priority, true); mixer_cfg_vp_blend(ctx); - mixer_commit(ctx); spin_unlock_irqrestore(&res->reg_slock, flags); @@ -591,7 +592,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode; struct mixer_resources *res = &ctx->mixer_res; struct drm_framebuffer *fb = state->base.fb; unsigned int priority = state->base.normalized_zpos + 1; @@ -637,11 +637,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, + (state->src.x * fb->format->cpp[0]) + (state->src.y * fb->pitches[0]); - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - __set_bit(MXR_BIT_INTERLACE, &ctx->flags); - else - __clear_bit(MXR_BIT_INTERLACE, &ctx->flags); - spin_lock_irqsave(&res->reg_slock, flags); /* setup format */ @@ -668,7 +663,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, mixer_cfg_layer(ctx, win, priority, true); mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format)); - mixer_commit(ctx); /* layer update mandatory for mixer 16.0.33.0 */ if (ctx->mxr_ver == MXR_VER_16_0_33_0 || @@ -1021,6 +1015,8 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) } mixer_win_reset(ctx); + mixer_commit(ctx); + mixer_vsync_set_update(ctx, true); set_bit(MXR_BIT_POWERED, &ctx->flags); -- cgit v1.2.3 From 3fc40ca9695c6a10c528f80306b1731128eca8c1 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:34 +0200 Subject: drm/exynos/mixer: move resolution configuration to single function Screen resolution configuration depends on HW version, let's put it into single function to make it consistent and simplify the code. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index ae89e53186ee..a87f60bbf2c2 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -367,7 +367,7 @@ static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) VP_SHADOW_UPDATE_ENABLE : 0); } -static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height) +static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height) { struct mixer_resources *res = &ctx->mixer_res; u32 val; @@ -376,7 +376,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height) val = test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? MXR_CFG_SCAN_INTERLACE : MXR_CFG_SCAN_PROGRESSIVE; - if (ctx->mxr_ver != MXR_VER_128_0_0_184) { + /* setup display size */ + if (ctx->mxr_ver == MXR_VER_128_0_0_184) { + mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION, + MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width)); + } else { /* choosing between proper HD and SD mode */ if (height <= 480) val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD; @@ -482,14 +486,7 @@ static void mixer_commit(struct mixer_context *ctx) else __clear_bit(MXR_BIT_INTERLACE, &ctx->flags); - /* setup display size */ - if (ctx->mxr_ver == MXR_VER_128_0_0_184) { - u32 val = MXR_MXR_RES_HEIGHT(mode->vdisplay) - | MXR_MXR_RES_WIDTH(mode->hdisplay); - mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION, val); - } - - mixer_cfg_scan(ctx, mode->vdisplay); + mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay); mixer_cfg_rgb_fmt(ctx, mode->vdisplay); mixer_run(ctx); } -- cgit v1.2.3 From 6ace38a52783705038e312220eb5d31237866fec Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:35 +0200 Subject: drm/exynos/mixer: fix mode validation code Mode limitation checked in mixer driver affects only older HW. Mixer in Exynos542x has no such limitations. While at it patch changes validation callback to recently introduced mode_valid which is more suitable for the check. Additionally little cleanup is performed. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index a87f60bbf2c2..fba120346189 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1040,26 +1040,24 @@ static void mixer_disable(struct exynos_drm_crtc *crtc) clear_bit(MXR_BIT_POWERED, &ctx->flags); } -/* Only valid for Mixer version 16.0.33.0 */ -static int mixer_atomic_check(struct exynos_drm_crtc *crtc, - struct drm_crtc_state *state) +static int mixer_mode_valid(struct exynos_drm_crtc *crtc, + const struct drm_display_mode *mode) { - struct drm_display_mode *mode = &state->adjusted_mode; - u32 w, h; + struct mixer_context *ctx = crtc->ctx; + u32 w = mode->hdisplay, h = mode->vdisplay; - w = mode->hdisplay; - h = mode->vdisplay; + DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n", w, h, + mode->vrefresh, !!(mode->flags & DRM_MODE_FLAG_INTERLACE)); - DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n", - mode->hdisplay, mode->vdisplay, mode->vrefresh, - (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0); + if (ctx->mxr_ver == MXR_VER_128_0_0_184) + return MODE_OK; if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) || - (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) || - (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) - return 0; + (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) || + (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) + return MODE_OK; - return -EINVAL; + return MODE_BAD; } static const struct exynos_drm_crtc_ops mixer_crtc_ops = { @@ -1071,7 +1069,7 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = { .update_plane = mixer_update_plane, .disable_plane = mixer_disable_plane, .atomic_flush = mixer_atomic_flush, - .atomic_check = mixer_atomic_check, + .mode_valid = mixer_mode_valid, }; static const struct mixer_drv_data exynos5420_mxr_drv_data = { -- cgit v1.2.3 From 524c59f1b79885154c2424aac00ed66f6a6eac29 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:36 +0200 Subject: drm/exynos/mixer: remove mixer_resources sub-structure mixer_resources adds only unnecessary redirection, removing it makes the code shorter and cleaner. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 324 ++++++++++++++++------------------ 1 file changed, 148 insertions(+), 176 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index fba120346189..c0e92021748b 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -67,19 +67,6 @@ #define MXR_FORMAT_ARGB4444 6 #define MXR_FORMAT_ARGB8888 7 -struct mixer_resources { - int irq; - void __iomem *mixer_regs; - void __iomem *vp_regs; - spinlock_t reg_slock; - struct clk *mixer; - struct clk *vp; - struct clk *hdmi; - struct clk *sclk_mixer; - struct clk *sclk_hdmi; - struct clk *mout_mixer; -}; - enum mixer_version_id { MXR_VER_0_0_0_16, MXR_VER_16_0_33_0, @@ -117,7 +104,16 @@ struct mixer_context { struct exynos_drm_plane planes[MIXER_WIN_NR]; unsigned long flags; - struct mixer_resources mixer_res; + int irq; + void __iomem *mixer_regs; + void __iomem *vp_regs; + spinlock_t reg_slock; + struct clk *mixer; + struct clk *vp; + struct clk *hdmi; + struct clk *sclk_mixer; + struct clk *sclk_hdmi; + struct clk *mout_mixer; enum mixer_version_id mxr_ver; }; @@ -194,44 +190,44 @@ static inline bool is_alpha_format(unsigned int pixel_format) } } -static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id) +static inline u32 vp_reg_read(struct mixer_context *ctx, u32 reg_id) { - return readl(res->vp_regs + reg_id); + return readl(ctx->vp_regs + reg_id); } -static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id, +static inline void vp_reg_write(struct mixer_context *ctx, u32 reg_id, u32 val) { - writel(val, res->vp_regs + reg_id); + writel(val, ctx->vp_regs + reg_id); } -static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id, +static inline void vp_reg_writemask(struct mixer_context *ctx, u32 reg_id, u32 val, u32 mask) { - u32 old = vp_reg_read(res, reg_id); + u32 old = vp_reg_read(ctx, reg_id); val = (val & mask) | (old & ~mask); - writel(val, res->vp_regs + reg_id); + writel(val, ctx->vp_regs + reg_id); } -static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id) +static inline u32 mixer_reg_read(struct mixer_context *ctx, u32 reg_id) { - return readl(res->mixer_regs + reg_id); + return readl(ctx->mixer_regs + reg_id); } -static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id, +static inline void mixer_reg_write(struct mixer_context *ctx, u32 reg_id, u32 val) { - writel(val, res->mixer_regs + reg_id); + writel(val, ctx->mixer_regs + reg_id); } -static inline void mixer_reg_writemask(struct mixer_resources *res, +static inline void mixer_reg_writemask(struct mixer_context *ctx, u32 reg_id, u32 val, u32 mask) { - u32 old = mixer_reg_read(res, reg_id); + u32 old = mixer_reg_read(ctx, reg_id); val = (val & mask) | (old & ~mask); - writel(val, res->mixer_regs + reg_id); + writel(val, ctx->mixer_regs + reg_id); } static void mixer_regs_dump(struct mixer_context *ctx) @@ -239,7 +235,7 @@ static void mixer_regs_dump(struct mixer_context *ctx) #define DUMPREG(reg_id) \ do { \ DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \ + (u32)readl(ctx->mixer_regs + reg_id)); \ } while (0) DUMPREG(MXR_STATUS); @@ -271,7 +267,7 @@ static void vp_regs_dump(struct mixer_context *ctx) #define DUMPREG(reg_id) \ do { \ DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \ + (u32) readl(ctx->vp_regs + reg_id)); \ } while (0) DUMPREG(VP_ENABLE); @@ -301,7 +297,7 @@ do { \ #undef DUMPREG } -static inline void vp_filter_set(struct mixer_resources *res, +static inline void vp_filter_set(struct mixer_context *ctx, int reg_id, const u8 *data, unsigned int size) { /* assure 4-byte align */ @@ -309,24 +305,23 @@ static inline void vp_filter_set(struct mixer_resources *res, for (; size; size -= 4, reg_id += 4, data += 4) { u32 val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; - vp_reg_write(res, reg_id, val); + vp_reg_write(ctx, reg_id, val); } } -static void vp_default_filter(struct mixer_resources *res) +static void vp_default_filter(struct mixer_context *ctx) { - vp_filter_set(res, VP_POLY8_Y0_LL, + vp_filter_set(ctx, VP_POLY8_Y0_LL, filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8)); - vp_filter_set(res, VP_POLY4_Y0_LL, + vp_filter_set(ctx, VP_POLY4_Y0_LL, filter_y_vert_tap4, sizeof(filter_y_vert_tap4)); - vp_filter_set(res, VP_POLY4_C0_LL, + vp_filter_set(ctx, VP_POLY4_C0_LL, filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4)); } static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win, bool alpha) { - struct mixer_resources *res = &ctx->mixer_res; u32 val; val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ @@ -335,13 +330,12 @@ static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win, val |= MXR_GRP_CFG_BLEND_PRE_MUL; val |= MXR_GRP_CFG_PIXEL_BLEND_EN; } - mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), + mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win), val, MXR_GRP_CFG_MISC_MASK); } static void mixer_cfg_vp_blend(struct mixer_context *ctx) { - struct mixer_resources *res = &ctx->mixer_res; u32 val; /* @@ -351,25 +345,22 @@ static void mixer_cfg_vp_blend(struct mixer_context *ctx) * support blending of the video layer through this. */ val = 0; - mixer_reg_write(res, MXR_VIDEO_CFG, val); + mixer_reg_write(ctx, MXR_VIDEO_CFG, val); } static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) { - struct mixer_resources *res = &ctx->mixer_res; - /* block update on vsync */ - mixer_reg_writemask(res, MXR_STATUS, enable ? + mixer_reg_writemask(ctx, MXR_STATUS, enable ? MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE); if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) - vp_reg_write(res, VP_SHADOW_UPDATE, enable ? + vp_reg_write(ctx, VP_SHADOW_UPDATE, enable ? VP_SHADOW_UPDATE_ENABLE : 0); } static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height) { - struct mixer_resources *res = &ctx->mixer_res; u32 val; /* choosing between interlace and progressive mode */ @@ -378,7 +369,7 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height) /* setup display size */ if (ctx->mxr_ver == MXR_VER_128_0_0_184) { - mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION, + mixer_reg_write(ctx, MXR_RESOLUTION, MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width)); } else { /* choosing between proper HD and SD mode */ @@ -394,12 +385,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height) val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; } - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK); + mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK); } static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) { - struct mixer_resources *res = &ctx->mixer_res; u32 val; switch (height) { @@ -412,45 +402,44 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) default: val = MXR_CFG_RGB709_16_235; /* Configure the BT.709 CSC matrix for full range RGB. */ - mixer_reg_write(res, MXR_CM_COEFF_Y, + mixer_reg_write(ctx, MXR_CM_COEFF_Y, MXR_CSC_CT( 0.184, 0.614, 0.063) | MXR_CM_COEFF_RGB_FULL); - mixer_reg_write(res, MXR_CM_COEFF_CB, + mixer_reg_write(ctx, MXR_CM_COEFF_CB, MXR_CSC_CT(-0.102, -0.338, 0.440)); - mixer_reg_write(res, MXR_CM_COEFF_CR, + mixer_reg_write(ctx, MXR_CM_COEFF_CR, MXR_CSC_CT( 0.440, -0.399, -0.040)); break; } - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK); + mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK); } static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win, unsigned int priority, bool enable) { - struct mixer_resources *res = &ctx->mixer_res; u32 val = enable ? ~0 : 0; switch (win) { case 0: - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE); - mixer_reg_writemask(res, MXR_LAYER_CFG, + mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP0_ENABLE); + mixer_reg_writemask(ctx, MXR_LAYER_CFG, MXR_LAYER_CFG_GRP0_VAL(priority), MXR_LAYER_CFG_GRP0_MASK); break; case 1: - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); - mixer_reg_writemask(res, MXR_LAYER_CFG, + mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); + mixer_reg_writemask(ctx, MXR_LAYER_CFG, MXR_LAYER_CFG_GRP1_VAL(priority), MXR_LAYER_CFG_GRP1_MASK); break; case VP_DEFAULT_WIN: if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) { - vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); - mixer_reg_writemask(res, MXR_CFG, val, + vp_reg_writemask(ctx, VP_ENABLE, val, VP_ENABLE_ON); + mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_VP_ENABLE); - mixer_reg_writemask(res, MXR_LAYER_CFG, + mixer_reg_writemask(ctx, MXR_LAYER_CFG, MXR_LAYER_CFG_VP_VAL(priority), MXR_LAYER_CFG_VP_MASK); } @@ -460,19 +449,16 @@ static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win, static void mixer_run(struct mixer_context *ctx) { - struct mixer_resources *res = &ctx->mixer_res; - - mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN); + mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_REG_RUN); } static void mixer_stop(struct mixer_context *ctx) { - struct mixer_resources *res = &ctx->mixer_res; int timeout = 20; - mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN); + mixer_reg_writemask(ctx, MXR_STATUS, 0, MXR_STATUS_REG_RUN); - while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) && + while (!(mixer_reg_read(ctx, MXR_STATUS) & MXR_STATUS_REG_IDLE) && --timeout) usleep_range(10000, 12000); } @@ -496,7 +482,6 @@ static void vp_video_buffer(struct mixer_context *ctx, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct mixer_resources *res = &ctx->mixer_res; struct drm_framebuffer *fb = state->base.fb; unsigned int priority = state->base.normalized_zpos + 1; unsigned long flags; @@ -523,55 +508,55 @@ static void vp_video_buffer(struct mixer_context *ctx, chroma_addr[1] = 0; } - spin_lock_irqsave(&res->reg_slock, flags); + spin_lock_irqsave(&ctx->reg_slock, flags); /* interlace or progressive scan mode */ val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0); - vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP); + vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP); /* setup format */ val = (is_nv21 ? VP_MODE_NV21 : VP_MODE_NV12); val |= (is_tiled ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR); - vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); + vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_FMT_MASK); /* setting size of input image */ - vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) | + vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) | VP_IMG_VSIZE(fb->height)); /* chroma plane for NV12/NV21 is half the height of the luma plane */ - vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) | + vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) | VP_IMG_VSIZE(fb->height / 2)); - vp_reg_write(res, VP_SRC_WIDTH, state->src.w); - vp_reg_write(res, VP_SRC_HEIGHT, state->src.h); - vp_reg_write(res, VP_SRC_H_POSITION, + vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w); + vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h); + vp_reg_write(ctx, VP_SRC_H_POSITION, VP_SRC_H_POSITION_VAL(state->src.x)); - vp_reg_write(res, VP_SRC_V_POSITION, state->src.y); + vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y); - vp_reg_write(res, VP_DST_WIDTH, state->crtc.w); - vp_reg_write(res, VP_DST_H_POSITION, state->crtc.x); + vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w); + vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x); if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { - vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h / 2); - vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y / 2); + vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2); + vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2); } else { - vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h); - vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y); + vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h); + vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y); } - vp_reg_write(res, VP_H_RATIO, state->h_ratio); - vp_reg_write(res, VP_V_RATIO, state->v_ratio); + vp_reg_write(ctx, VP_H_RATIO, state->h_ratio); + vp_reg_write(ctx, VP_V_RATIO, state->v_ratio); - vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); + vp_reg_write(ctx, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); /* set buffer address to vp */ - vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]); - vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]); - vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); - vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); + vp_reg_write(ctx, VP_TOP_Y_PTR, luma_addr[0]); + vp_reg_write(ctx, VP_BOT_Y_PTR, luma_addr[1]); + vp_reg_write(ctx, VP_TOP_C_PTR, chroma_addr[0]); + vp_reg_write(ctx, VP_BOT_C_PTR, chroma_addr[1]); mixer_cfg_layer(ctx, plane->index, priority, true); mixer_cfg_vp_blend(ctx); - spin_unlock_irqrestore(&res->reg_slock, flags); + spin_unlock_irqrestore(&ctx->reg_slock, flags); mixer_regs_dump(ctx); vp_regs_dump(ctx); @@ -579,9 +564,7 @@ static void vp_video_buffer(struct mixer_context *ctx, static void mixer_layer_update(struct mixer_context *ctx) { - struct mixer_resources *res = &ctx->mixer_res; - - mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); + mixer_reg_writemask(ctx, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); } static void mixer_graph_buffer(struct mixer_context *ctx, @@ -589,7 +572,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct mixer_resources *res = &ctx->mixer_res; struct drm_framebuffer *fb = state->base.fb; unsigned int priority = state->base.normalized_zpos + 1; unsigned long flags; @@ -634,29 +616,29 @@ static void mixer_graph_buffer(struct mixer_context *ctx, + (state->src.x * fb->format->cpp[0]) + (state->src.y * fb->pitches[0]); - spin_lock_irqsave(&res->reg_slock, flags); + spin_lock_irqsave(&ctx->reg_slock, flags); /* setup format */ - mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), + mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win), MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK); /* setup geometry */ - mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), + mixer_reg_write(ctx, MXR_GRAPHIC_SPAN(win), fb->pitches[0] / fb->format->cpp[0]); val = MXR_GRP_WH_WIDTH(state->src.w); val |= MXR_GRP_WH_HEIGHT(state->src.h); val |= MXR_GRP_WH_H_SCALE(x_ratio); val |= MXR_GRP_WH_V_SCALE(y_ratio); - mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); + mixer_reg_write(ctx, MXR_GRAPHIC_WH(win), val); /* setup offsets in display image */ val = MXR_GRP_DXY_DX(dst_x_offset); val |= MXR_GRP_DXY_DY(dst_y_offset); - mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val); + mixer_reg_write(ctx, MXR_GRAPHIC_DXY(win), val); /* set buffer address to mixer */ - mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); + mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr); mixer_cfg_layer(ctx, win, priority, true); mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format)); @@ -666,20 +648,19 @@ static void mixer_graph_buffer(struct mixer_context *ctx, ctx->mxr_ver == MXR_VER_128_0_0_184) mixer_layer_update(ctx); - spin_unlock_irqrestore(&res->reg_slock, flags); + spin_unlock_irqrestore(&ctx->reg_slock, flags); mixer_regs_dump(ctx); } static void vp_win_reset(struct mixer_context *ctx) { - struct mixer_resources *res = &ctx->mixer_res; unsigned int tries = 100; - vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING); + vp_reg_write(ctx, VP_SRESET, VP_SRESET_PROCESSING); while (--tries) { /* waiting until VP_SRESET_PROCESSING is 0 */ - if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING) + if (~vp_reg_read(ctx, VP_SRESET) & VP_SRESET_PROCESSING) break; mdelay(10); } @@ -688,57 +669,55 @@ static void vp_win_reset(struct mixer_context *ctx) static void mixer_win_reset(struct mixer_context *ctx) { - struct mixer_resources *res = &ctx->mixer_res; unsigned long flags; - spin_lock_irqsave(&res->reg_slock, flags); + spin_lock_irqsave(&ctx->reg_slock, flags); - mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); + mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); /* set output in RGB888 mode */ - mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK); + mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK); /* 16 beat burst in DMA */ - mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, + mixer_reg_writemask(ctx, MXR_STATUS, MXR_STATUS_16_BURST, MXR_STATUS_BURST_MASK); /* reset default layer priority */ - mixer_reg_write(res, MXR_LAYER_CFG, 0); + mixer_reg_write(ctx, MXR_LAYER_CFG, 0); /* set all background colors to RGB (0,0,0) */ - mixer_reg_write(res, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128)); - mixer_reg_write(res, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128)); - mixer_reg_write(res, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128)); + mixer_reg_write(ctx, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128)); + mixer_reg_write(ctx, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128)); + mixer_reg_write(ctx, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128)); if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) { /* configuration of Video Processor Registers */ vp_win_reset(ctx); - vp_default_filter(res); + vp_default_filter(ctx); } /* disable all layers */ - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); + mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); + mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); + mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_VP_ENABLE); /* set all source image offsets to zero */ - mixer_reg_write(res, MXR_GRAPHIC_SXY(0), 0); - mixer_reg_write(res, MXR_GRAPHIC_SXY(1), 0); + mixer_reg_write(ctx, MXR_GRAPHIC_SXY(0), 0); + mixer_reg_write(ctx, MXR_GRAPHIC_SXY(1), 0); - spin_unlock_irqrestore(&res->reg_slock, flags); + spin_unlock_irqrestore(&ctx->reg_slock, flags); } static irqreturn_t mixer_irq_handler(int irq, void *arg) { struct mixer_context *ctx = arg; - struct mixer_resources *res = &ctx->mixer_res; u32 val, base, shadow; - spin_lock(&res->reg_slock); + spin_lock(&ctx->reg_slock); /* read interrupt status for handling and clearing flags for VSYNC */ - val = mixer_reg_read(res, MXR_INT_STATUS); + val = mixer_reg_read(ctx, MXR_INT_STATUS); /* handling VSYNC */ if (val & MXR_INT_STATUS_VSYNC) { @@ -748,13 +727,13 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) /* interlace scan need to check shadow register */ if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { - base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0)); - shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0)); + base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); + shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); if (base != shadow) goto out; - base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1)); - shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1)); + base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(1)); + shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(1)); if (base != shadow) goto out; } @@ -764,9 +743,9 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) out: /* clear interrupts */ - mixer_reg_write(res, MXR_INT_STATUS, val); + mixer_reg_write(ctx, MXR_INT_STATUS, val); - spin_unlock(&res->reg_slock); + spin_unlock(&ctx->reg_slock); return IRQ_HANDLED; } @@ -774,26 +753,25 @@ out: static int mixer_resources_init(struct mixer_context *mixer_ctx) { struct device *dev = &mixer_ctx->pdev->dev; - struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; struct resource *res; int ret; - spin_lock_init(&mixer_res->reg_slock); + spin_lock_init(&mixer_ctx->reg_slock); - mixer_res->mixer = devm_clk_get(dev, "mixer"); - if (IS_ERR(mixer_res->mixer)) { + mixer_ctx->mixer = devm_clk_get(dev, "mixer"); + if (IS_ERR(mixer_ctx->mixer)) { dev_err(dev, "failed to get clock 'mixer'\n"); return -ENODEV; } - mixer_res->hdmi = devm_clk_get(dev, "hdmi"); - if (IS_ERR(mixer_res->hdmi)) { + mixer_ctx->hdmi = devm_clk_get(dev, "hdmi"); + if (IS_ERR(mixer_ctx->hdmi)) { dev_err(dev, "failed to get clock 'hdmi'\n"); - return PTR_ERR(mixer_res->hdmi); + return PTR_ERR(mixer_ctx->hdmi); } - mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); - if (IS_ERR(mixer_res->sclk_hdmi)) { + mixer_ctx->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); + if (IS_ERR(mixer_ctx->sclk_hdmi)) { dev_err(dev, "failed to get clock 'sclk_hdmi'\n"); return -ENODEV; } @@ -803,9 +781,9 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx) return -ENXIO; } - mixer_res->mixer_regs = devm_ioremap(dev, res->start, + mixer_ctx->mixer_regs = devm_ioremap(dev, res->start, resource_size(res)); - if (mixer_res->mixer_regs == NULL) { + if (mixer_ctx->mixer_regs == NULL) { dev_err(dev, "register mapping failed.\n"); return -ENXIO; } @@ -822,7 +800,7 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx) dev_err(dev, "request interrupt failed.\n"); return ret; } - mixer_res->irq = res->start; + mixer_ctx->irq = res->start; return 0; } @@ -830,30 +808,29 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx) static int vp_resources_init(struct mixer_context *mixer_ctx) { struct device *dev = &mixer_ctx->pdev->dev; - struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; struct resource *res; - mixer_res->vp = devm_clk_get(dev, "vp"); - if (IS_ERR(mixer_res->vp)) { + mixer_ctx->vp = devm_clk_get(dev, "vp"); + if (IS_ERR(mixer_ctx->vp)) { dev_err(dev, "failed to get clock 'vp'\n"); return -ENODEV; } if (test_bit(MXR_BIT_HAS_SCLK, &mixer_ctx->flags)) { - mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer"); - if (IS_ERR(mixer_res->sclk_mixer)) { + mixer_ctx->sclk_mixer = devm_clk_get(dev, "sclk_mixer"); + if (IS_ERR(mixer_ctx->sclk_mixer)) { dev_err(dev, "failed to get clock 'sclk_mixer'\n"); return -ENODEV; } - mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer"); - if (IS_ERR(mixer_res->mout_mixer)) { + mixer_ctx->mout_mixer = devm_clk_get(dev, "mout_mixer"); + if (IS_ERR(mixer_ctx->mout_mixer)) { dev_err(dev, "failed to get clock 'mout_mixer'\n"); return -ENODEV; } - if (mixer_res->sclk_hdmi && mixer_res->mout_mixer) - clk_set_parent(mixer_res->mout_mixer, - mixer_res->sclk_hdmi); + if (mixer_ctx->sclk_hdmi && mixer_ctx->mout_mixer) + clk_set_parent(mixer_ctx->mout_mixer, + mixer_ctx->sclk_hdmi); } res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1); @@ -862,9 +839,9 @@ static int vp_resources_init(struct mixer_context *mixer_ctx) return -ENXIO; } - mixer_res->vp_regs = devm_ioremap(dev, res->start, + mixer_ctx->vp_regs = devm_ioremap(dev, res->start, resource_size(res)); - if (mixer_res->vp_regs == NULL) { + if (mixer_ctx->vp_regs == NULL) { dev_err(dev, "register mapping failed.\n"); return -ENXIO; } @@ -908,15 +885,14 @@ static void mixer_ctx_remove(struct mixer_context *mixer_ctx) static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) { struct mixer_context *mixer_ctx = crtc->ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; __set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags); if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) return 0; /* enable vsync interrupt */ - mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); - mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC); + mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); + mixer_reg_writemask(mixer_ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC); return 0; } @@ -924,7 +900,6 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) { struct mixer_context *mixer_ctx = crtc->ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; __clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags); @@ -932,8 +907,8 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) return; /* disable vsync interrupt */ - mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); - mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); + mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); + mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); } static void mixer_atomic_begin(struct exynos_drm_crtc *crtc) @@ -966,7 +941,6 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { struct mixer_context *mixer_ctx = crtc->ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; unsigned long flags; DRM_DEBUG_KMS("win: %d\n", plane->index); @@ -974,9 +948,9 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc, if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) return; - spin_lock_irqsave(&res->reg_slock, flags); + spin_lock_irqsave(&mixer_ctx->reg_slock, flags); mixer_cfg_layer(mixer_ctx, plane->index, 0, false); - spin_unlock_irqrestore(&res->reg_slock, flags); + spin_unlock_irqrestore(&mixer_ctx->reg_slock, flags); } static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) @@ -993,7 +967,6 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) static void mixer_enable(struct exynos_drm_crtc *crtc) { struct mixer_context *ctx = crtc->ctx; - struct mixer_resources *res = &ctx->mixer_res; if (test_bit(MXR_BIT_POWERED, &ctx->flags)) return; @@ -1004,11 +977,12 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) mixer_vsync_set_update(ctx, false); - mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); + mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) { - mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); - mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC); + mixer_reg_writemask(ctx, MXR_INT_STATUS, ~0, + MXR_INT_CLEAR_VSYNC); + mixer_reg_writemask(ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC); } mixer_win_reset(ctx); @@ -1211,14 +1185,13 @@ static int mixer_remove(struct platform_device *pdev) static int __maybe_unused exynos_mixer_suspend(struct device *dev) { struct mixer_context *ctx = dev_get_drvdata(dev); - struct mixer_resources *res = &ctx->mixer_res; - clk_disable_unprepare(res->hdmi); - clk_disable_unprepare(res->mixer); + clk_disable_unprepare(ctx->hdmi); + clk_disable_unprepare(ctx->mixer); if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) { - clk_disable_unprepare(res->vp); + clk_disable_unprepare(ctx->vp); if (test_bit(MXR_BIT_HAS_SCLK, &ctx->flags)) - clk_disable_unprepare(res->sclk_mixer); + clk_disable_unprepare(ctx->sclk_mixer); } return 0; @@ -1227,28 +1200,27 @@ static int __maybe_unused exynos_mixer_suspend(struct device *dev) static int __maybe_unused exynos_mixer_resume(struct device *dev) { struct mixer_context *ctx = dev_get_drvdata(dev); - struct mixer_resources *res = &ctx->mixer_res; int ret; - ret = clk_prepare_enable(res->mixer); + ret = clk_prepare_enable(ctx->mixer); if (ret < 0) { DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret); return ret; } - ret = clk_prepare_enable(res->hdmi); + ret = clk_prepare_enable(ctx->hdmi); if (ret < 0) { DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); return ret; } if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) { - ret = clk_prepare_enable(res->vp); + ret = clk_prepare_enable(ctx->vp); if (ret < 0) { DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n", ret); return ret; } if (test_bit(MXR_BIT_HAS_SCLK, &ctx->flags)) { - ret = clk_prepare_enable(res->sclk_mixer); + ret = clk_prepare_enable(ctx->sclk_mixer); if (ret < 0) { DRM_ERROR("Failed to prepare_enable the " \ "sclk_mixer clk [%d]\n", -- cgit v1.2.3 From 991ea04e2cf4a9705462ec2fe878e385feb48d73 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:37 +0200 Subject: drm/exynos/hdmi: remove redundant mode field Display mode is preserved in CRTC state, there is no need to keep local copy of it. Moreover since HDMI should configure registers according to requested mode, use it instead of adjusted_mode, which should contain mode produced by CRTC - functionally it does not change anything, but subsequent patches will make the difference. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_hdmi.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 0109ff40b1db..0d37d6928623 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -119,7 +119,6 @@ struct hdmi_context { bool powered; bool dvi_mode; struct delayed_work hotplug_work; - struct drm_display_mode current_mode; struct cec_notifier *notifier; const struct hdmi_driver_data *drv_data; @@ -770,6 +769,7 @@ static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy) static void hdmi_reg_infoframes(struct hdmi_context *hdata) { + struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; union hdmi_infoframe frm; u8 buf[25]; int ret; @@ -783,8 +783,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata) return; } - ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, - &hdata->current_mode, false); + ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, m, false); if (!ret) ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf)); if (ret > 0) { @@ -794,8 +793,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata) DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret); } - ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi, - &hdata->current_mode); + ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi, m); if (!ret) ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf, sizeof(buf)); @@ -1096,9 +1094,10 @@ static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff) static void hdmi_start(struct hdmi_context *hdata, bool start) { + struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; u32 val = start ? HDMI_TG_EN : 0; - if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE) + if (m->flags & DRM_MODE_FLAG_INTERLACE) val |= HDMI_FIELD_EN; hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN); @@ -1168,7 +1167,7 @@ static void hdmiphy_wait_for_pll(struct hdmi_context *hdata) static void hdmi_v13_mode_apply(struct hdmi_context *hdata) { - struct drm_display_mode *m = &hdata->current_mode; + struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; unsigned int val; hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay); @@ -1247,7 +1246,7 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata) static void hdmi_v14_mode_apply(struct hdmi_context *hdata) { - struct drm_display_mode *m = &hdata->current_mode; + struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay); hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal); @@ -1380,10 +1379,11 @@ static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable) static void hdmiphy_conf_apply(struct hdmi_context *hdata) { + struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; int ret; const u8 *phy_conf; - ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000); + ret = hdmi_find_phy_conf(hdata, m->clock * 1000); if (ret < 0) { DRM_ERROR("failed to find hdmiphy conf\n"); return; @@ -1415,21 +1415,6 @@ static void hdmi_conf_apply(struct hdmi_context *hdata) hdmi_audio_control(hdata, true); } -static void hdmi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct hdmi_context *hdata = encoder_to_hdmi(encoder); - struct drm_display_mode *m = adjusted_mode; - - DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n", - m->hdisplay, m->vdisplay, - m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ? - "INTERLACED" : "PROGRESSIVE"); - - drm_mode_copy(&hdata->current_mode, m); -} - static void hdmi_set_refclk(struct hdmi_context *hdata, bool on) { if (!hdata->sysreg) @@ -1512,7 +1497,6 @@ static void hdmi_disable(struct drm_encoder *encoder) static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = { .mode_fixup = hdmi_mode_fixup, - .mode_set = hdmi_mode_set, .enable = hdmi_enable, .disable = hdmi_disable, }; -- cgit v1.2.3 From 2466db97e39d5479bb44a09a56ca85043d3d3997 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:38 +0200 Subject: drm/exynos: add mode_fixup callback to exynos_drm_crtc_ops crtc::mode_fixup callback is required by crtcs which internally use a different mode than requested by user - case of Exynos Mixer. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 15 +++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_drv.h | 3 +++ 2 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 6ce0821590df..dc01342e759a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -95,8 +95,23 @@ static enum drm_mode_status exynos_crtc_mode_valid(struct drm_crtc *crtc, return MODE_OK; } +static bool exynos_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); + + if (exynos_crtc->ops->mode_fixup) + return exynos_crtc->ops->mode_fixup(exynos_crtc, mode, + adjusted_mode); + + return true; +} + + static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { .mode_valid = exynos_crtc_mode_valid, + .mode_fixup = exynos_crtc_mode_fixup, .atomic_check = exynos_crtc_atomic_check, .atomic_begin = exynos_crtc_atomic_begin, .atomic_flush = exynos_crtc_atomic_flush, diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index f8bae4cb4823..c6847fa708fa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -136,6 +136,9 @@ struct exynos_drm_crtc_ops { u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc); enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc, const struct drm_display_mode *mode); + bool (*mode_fixup)(struct exynos_drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); int (*atomic_check)(struct exynos_drm_crtc *crtc, struct drm_crtc_state *state); void (*atomic_begin)(struct exynos_drm_crtc *crtc); -- cgit v1.2.3 From acc8bf040c39499139e6d26e72c642d42ffa5016 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:39 +0200 Subject: drm/exynos/mixer: pass actual mode on MIXER to encoder MIXER in SoCs prior to Exynos5420 supports only 4 video modes: 720x480, 720x576, 1280x720, 1920x1080. Support for other modes can be enabled by manipulating timings of HDMI. To allow it MIXER must pass actual video mode to HDMI, the proper way to do it is to modify adjusted_mode property in crtc::mode_fixup callback. Adding such callback allows also to simplify mixer_cfg_scan code - choosing mode is performed already in crtc::mode_fixup. mode_fixup is also better place to check interlace flag. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 71 +++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index c0e92021748b..e9122db95cb2 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -115,6 +115,7 @@ struct mixer_context { struct clk *sclk_hdmi; struct clk *mout_mixer; enum mixer_version_id mxr_ver; + int scan_value; }; struct mixer_drv_data { @@ -367,23 +368,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height) val = test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? MXR_CFG_SCAN_INTERLACE : MXR_CFG_SCAN_PROGRESSIVE; - /* setup display size */ - if (ctx->mxr_ver == MXR_VER_128_0_0_184) { + if (ctx->mxr_ver == MXR_VER_128_0_0_184) mixer_reg_write(ctx, MXR_RESOLUTION, MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width)); - } else { - /* choosing between proper HD and SD mode */ - if (height <= 480) - val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD; - else if (height <= 576) - val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD; - else if (height <= 720) - val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; - else if (height <= 1080) - val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD; - else - val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; - } + else + val |= ctx->scan_value; mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK); } @@ -467,11 +456,6 @@ static void mixer_commit(struct mixer_context *ctx) { struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - __set_bit(MXR_BIT_INTERLACE, &ctx->flags); - else - __clear_bit(MXR_BIT_INTERLACE, &ctx->flags); - mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay); mixer_cfg_rgb_fmt(ctx, mode->vdisplay); mixer_run(ctx); @@ -1034,6 +1018,52 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc, return MODE_BAD; } +static bool mixer_mode_fixup(struct exynos_drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct mixer_context *ctx = crtc->ctx; + int width = mode->hdisplay, height = mode->vdisplay, i; + + struct { + int hdisplay, vdisplay, htotal, vtotal, scan_val; + } static const modes[] = { + { 720, 480, 858, 525, MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD }, + { 720, 576, 864, 625, MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD }, + { 1280, 720, 1650, 750, MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD }, + { 1920, 1080, 2200, 1125, MXR_CFG_SCAN_HD_1080 | + MXR_CFG_SCAN_HD } + }; + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + __set_bit(MXR_BIT_INTERLACE, &ctx->flags); + else + __clear_bit(MXR_BIT_INTERLACE, &ctx->flags); + + if (ctx->mxr_ver == MXR_VER_128_0_0_184) + return true; + + for (i = 0; i < ARRAY_SIZE(modes); ++i) + if (width <= modes[i].hdisplay && height <= modes[i].vdisplay) { + ctx->scan_value = modes[i].scan_val; + if (width < modes[i].hdisplay || + height < modes[i].vdisplay) { + adjusted_mode->hdisplay = modes[i].hdisplay; + adjusted_mode->hsync_start = modes[i].hdisplay; + adjusted_mode->hsync_end = modes[i].htotal; + adjusted_mode->htotal = modes[i].htotal; + adjusted_mode->vdisplay = modes[i].vdisplay; + adjusted_mode->vsync_start = modes[i].vdisplay; + adjusted_mode->vsync_end = modes[i].vtotal; + adjusted_mode->vtotal = modes[i].vtotal; + } + + return true; + } + + return false; +} + static const struct exynos_drm_crtc_ops mixer_crtc_ops = { .enable = mixer_enable, .disable = mixer_disable, @@ -1044,6 +1074,7 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = { .disable_plane = mixer_disable_plane, .atomic_flush = mixer_atomic_flush, .mode_valid = mixer_mode_valid, + .mode_fixup = mixer_mode_fixup, }; static const struct mixer_drv_data exynos5420_mxr_drv_data = { -- cgit v1.2.3 From 36fd887acbd1ce349eba8283d9e8a9d7932a24ca Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:40 +0200 Subject: drm/exynos/hdmi: quirk for support mode timings conversion MIXER in SoCs prior to Exynos5420 supports only 4 video modes: 720x480, 720x576, 1280x720, 1920x1080. Support for other modes can be enabled by manipulating timings of HDMI. To do it adjusted_mode should contain actual mode set on crtc. With this patch it is possible to enable 1024x768 and 1280x1024 modes in MIXER. Suggested-by: Daniel Drake Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_hdmi.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 0d37d6928623..218914339cac 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1247,6 +1247,18 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata) static void hdmi_v14_mode_apply(struct hdmi_context *hdata) { struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; + struct drm_display_mode *am = + &hdata->encoder.crtc->state->adjusted_mode; + int hquirk = 0; + + /* + * In case video mode coming from CRTC differs from requested one HDMI + * sometimes is able to almost properly perform conversion - only + * first line is distorted. + */ + if ((m->vdisplay != am->vdisplay) && + (m->hdisplay == 1280 || m->hdisplay == 1024)) + hquirk = 258; hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay); hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal); @@ -1340,8 +1352,9 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata) hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff); hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal); - hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay); - hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay); + hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, + m->htotal - m->hdisplay - hquirk); + hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk); hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal); if (hdata->drv_data == &exynos5433_hdmi_driver_data) hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1); -- cgit v1.2.3 From 0900673e366190328796903a72cf17a9d082c327 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 29 Sep 2017 12:05:41 +0200 Subject: drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes Since HDMI can handle these modes despite of MIXER limitations let's enable them. Signed-off-by: Andrzej Hajda Reviewed-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index e9122db95cb2..714d72fd3bc5 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1015,6 +1015,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc, (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) return MODE_OK; + if ((w == 1024 && h == 768) || (w == 1280 && h == 1024)) + return MODE_OK; + return MODE_BAD; } -- cgit v1.2.3 From ae58c03e0ee13e37f8f56c0158d55f504ad889d2 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Fri, 29 Sep 2017 12:05:42 +0200 Subject: drm/exynos/hdmi: add 85.5MHz pixel clock for v14 HDMI PHY Configuration details from Samsung. This enables 1366x768@60Hz, which also needs the 256px timing hack to work around a mixer limitation. Signed-off-by: Daniel Drake Signed-off-by: Tobias Jakobi [a.hajda@samsung.com: rebased onto proposed patchset] Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_hdmi.c | 11 ++++++++++- drivers/gpu/drm/exynos/exynos_mixer.c | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 218914339cac..1309b1c9e074 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -296,6 +296,15 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = { 0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, }, }, + { + .pixel_clock = 85500000, + .conf = { + 0x01, 0xd1, 0x24, 0x11, 0x40, 0x40, 0xd0, 0x08, + 0x84, 0xa0, 0xd6, 0xd8, 0x45, 0xa0, 0xac, 0x80, + 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, + 0x54, 0x90, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, + }, + }, { .pixel_clock = 106500000, .conf = { @@ -1257,7 +1266,7 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata) * first line is distorted. */ if ((m->vdisplay != am->vdisplay) && - (m->hdisplay == 1280 || m->hdisplay == 1024)) + (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366)) hquirk = 258; hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay); diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 714d72fd3bc5..dc5d79465f9b 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1015,7 +1015,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc, (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) return MODE_OK; - if ((w == 1024 && h == 768) || (w == 1280 && h == 1024)) + if ((w == 1024 && h == 768) || + (w == 1366 && h == 768) || + (w == 1280 && h == 1024)) return MODE_OK; return MODE_BAD; -- cgit v1.2.3 From 691da76f9c90fa618682b88f386b6a1ef304666e Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 23 Oct 2017 14:49:34 +0200 Subject: drm: exynos: Add driver for HDMI audio interface The hdmi-codec interface added in this patch is required to properly support HDMI audio. Currently the audio part of the SoC internal HDMI transmitter is configured with fixed values, which makes HDMI audio working by chance, only on boards having an external audio codec connected in parallel with the HDMI audio transmitter's input I2S interface. Signed-off-by: Sylwester Nawrocki Reviewed-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/Kconfig | 1 + drivers/gpu/drm/exynos/exynos_hdmi.c | 250 ++++++++++++++++++++++++++--------- drivers/gpu/drm/exynos/regs-hdmi.h | 8 +- 3 files changed, 194 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 305dc3d4ff77..5a7c9d8abd6b 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -3,6 +3,7 @@ config DRM_EXYNOS depends on OF && DRM && (ARCH_S3C64XX || ARCH_EXYNOS || ARCH_MULTIPLATFORM) select DRM_KMS_HELPER select VIDEOMODE_HELPERS + select SND_SOC_HDMI_CODEC if SND_SOC help Choose this option if you have a Samsung SoC EXYNOS chipset. If M is selected the module will be called exynosdrm. diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 1309b1c9e074..82d1b7e2febe 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -40,7 +40,7 @@ #include #include #include - +#include #include #include @@ -111,12 +111,18 @@ struct hdmi_driver_data { struct string_array_spec clk_muxes; }; +struct hdmi_audio { + struct platform_device *pdev; + struct hdmi_audio_infoframe infoframe; + struct hdmi_codec_params params; + bool mute; +}; + struct hdmi_context { struct drm_encoder encoder; struct device *dev; struct drm_device *drm_dev; struct drm_connector connector; - bool powered; bool dvi_mode; struct delayed_work hotplug_work; struct cec_notifier *notifier; @@ -136,6 +142,11 @@ struct hdmi_context { struct regulator *reg_hdmi_en; struct exynos_drm_clk phy_clk; struct drm_bridge *bridge; + + /* mutex protecting subsequent fields below */ + struct mutex mutex; + struct hdmi_audio audio; + bool powered; }; static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e) @@ -776,6 +787,22 @@ static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy) return ret; } +static int hdmi_audio_infoframe_apply(struct hdmi_context *hdata) +{ + struct hdmi_audio_infoframe *infoframe = &hdata->audio.infoframe; + u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)]; + int len; + + len = hdmi_audio_infoframe_pack(infoframe, buf, sizeof(buf)); + if (len < 0) + return len; + + hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC); + hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, len); + + return 0; +} + static void hdmi_reg_infoframes(struct hdmi_context *hdata) { struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; @@ -812,15 +839,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata) hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3); } - ret = hdmi_audio_infoframe_init(&frm.audio); - if (!ret) { - frm.audio.channels = 2; - ret = hdmi_audio_infoframe_pack(&frm.audio, buf, sizeof(buf)); - } - if (ret > 0) { - hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC); - hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, ret); - } + hdmi_audio_infoframe_apply(hdata); } static enum drm_connector_status hdmi_detect(struct drm_connector *connector, @@ -1010,23 +1029,18 @@ static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq) hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4); } -static void hdmi_audio_init(struct hdmi_context *hdata) +static void hdmi_audio_config(struct hdmi_context *hdata) { - u32 sample_rate, bits_per_sample; - u32 data_num, bit_ch, sample_frq; - u32 val; - - sample_rate = 44100; - bits_per_sample = 16; + u32 bit_ch = 1; + u32 data_num, val; + int i; - switch (bits_per_sample) { + switch (hdata->audio.params.sample_width) { case 20: data_num = 2; - bit_ch = 1; break; case 24: data_num = 3; - bit_ch = 1; break; default: data_num = 1; @@ -1034,7 +1048,7 @@ static void hdmi_audio_init(struct hdmi_context *hdata) break; } - hdmi_reg_acr(hdata, sample_rate); + hdmi_reg_acr(hdata, hdata->audio.params.sample_rate); hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE @@ -1044,12 +1058,6 @@ static void hdmi_audio_init(struct hdmi_context *hdata) | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN); hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN); - - sample_frq = (sample_rate == 44100) ? 0 : - (sample_rate == 48000) ? 2 : - (sample_rate == 32000) ? 3 : - (sample_rate == 96000) ? 0xa : 0x0; - hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS); hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN); @@ -1073,31 +1081,24 @@ static void hdmi_audio_init(struct hdmi_context *hdata) | HDMI_I2S_SET_SDATA_BIT(data_num) | HDMI_I2S_BASIC_FORMAT); - /* Configure register related to CUV information */ - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0 - | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH - | HDMI_I2S_COPYRIGHT - | HDMI_I2S_LINEAR_PCM - | HDMI_I2S_CONSUMER_FORMAT); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0)); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2 - | HDMI_I2S_SET_SMP_FREQ(sample_frq)); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4, - HDMI_I2S_ORG_SMP_FREQ_44_1 - | HDMI_I2S_WORD_LEN_MAX24_24BITS - | HDMI_I2S_WORD_LEN_MAX_24BITS); + /* Configuration of the audio channel status registers */ + for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++) + hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i), + hdata->audio.params.iec.status[i]); hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD); } -static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff) +static void hdmi_audio_control(struct hdmi_context *hdata) { + bool enable = !hdata->audio.mute; + if (hdata->dvi_mode) return; - hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0); - hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ? + hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ? + HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN); + hdmi_reg_writemask(hdata, HDMI_CON_0, enable ? HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK); } @@ -1428,13 +1429,14 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) hdmiphy_wait_for_pll(hdata); } +/* Should be called with hdata->mutex mutex held */ static void hdmi_conf_apply(struct hdmi_context *hdata) { hdmi_start(hdata, false); hdmi_conf_init(hdata); - hdmi_audio_init(hdata); + hdmi_audio_config(hdata); hdmi_mode_apply(hdata); - hdmi_audio_control(hdata, true); + hdmi_audio_control(hdata); } static void hdmi_set_refclk(struct hdmi_context *hdata, bool on) @@ -1446,6 +1448,7 @@ static void hdmi_set_refclk(struct hdmi_context *hdata, bool on) SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0); } +/* Should be called with hdata->mutex mutex held. */ static void hdmiphy_enable(struct hdmi_context *hdata) { if (hdata->powered) @@ -1468,6 +1471,7 @@ static void hdmiphy_enable(struct hdmi_context *hdata) hdata->powered = true; } +/* Should be called with hdata->mutex mutex held. */ static void hdmiphy_disable(struct hdmi_context *hdata) { if (!hdata->powered) @@ -1493,28 +1497,38 @@ static void hdmi_enable(struct drm_encoder *encoder) { struct hdmi_context *hdata = encoder_to_hdmi(encoder); + mutex_lock(&hdata->mutex); + hdmiphy_enable(hdata); hdmi_conf_apply(hdata); + + mutex_unlock(&hdata->mutex); } static void hdmi_disable(struct drm_encoder *encoder) { struct hdmi_context *hdata = encoder_to_hdmi(encoder); - if (!hdata->powered) + mutex_lock(&hdata->mutex); + + if (hdata->powered) { + /* + * The SFRs of VP and Mixer are updated by Vertical Sync of + * Timing generator which is a part of HDMI so the sequence + * to disable TV Subsystem should be as following, + * VP -> Mixer -> HDMI + * + * To achieve such sequence HDMI is disabled together with + * HDMI PHY, via pipe clock callback. + */ + mutex_unlock(&hdata->mutex); + cancel_delayed_work(&hdata->hotplug_work); + cec_notifier_set_phys_addr(hdata->notifier, + CEC_PHYS_ADDR_INVALID); return; + } - /* - * The SFRs of VP and Mixer are updated by Vertical Sync of - * Timing generator which is a part of HDMI so the sequence - * to disable TV Subsystem should be as following, - * VP -> Mixer -> HDMI - * - * To achieve such sequence HDMI is disabled together with HDMI PHY, via - * pipe clock callback. - */ - cancel_delayed_work(&hdata->hotplug_work); - cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID); + mutex_unlock(&hdata->mutex); } static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = { @@ -1527,6 +1541,99 @@ static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = { .destroy = drm_encoder_cleanup, }; +static void hdmi_audio_shutdown(struct device *dev, void *data) +{ + struct hdmi_context *hdata = dev_get_drvdata(dev); + + mutex_lock(&hdata->mutex); + + hdata->audio.mute = true; + + if (hdata->powered) + hdmi_audio_control(hdata); + + mutex_unlock(&hdata->mutex); +} + +static int hdmi_audio_hw_params(struct device *dev, void *data, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) +{ + struct hdmi_context *hdata = dev_get_drvdata(dev); + + if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv || + daifmt->frame_clk_inv || daifmt->bit_clk_master || + daifmt->frame_clk_master) { + dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, + daifmt->bit_clk_inv, daifmt->frame_clk_inv, + daifmt->bit_clk_master, + daifmt->frame_clk_master); + return -EINVAL; + } + + mutex_lock(&hdata->mutex); + + hdata->audio.params = *params; + + if (hdata->powered) { + hdmi_audio_config(hdata); + hdmi_audio_infoframe_apply(hdata); + } + + mutex_unlock(&hdata->mutex); + + return 0; +} + +static int hdmi_audio_digital_mute(struct device *dev, void *data, bool mute) +{ + struct hdmi_context *hdata = dev_get_drvdata(dev); + + mutex_lock(&hdata->mutex); + + hdata->audio.mute = mute; + + if (hdata->powered) + hdmi_audio_control(hdata); + + mutex_unlock(&hdata->mutex); + + return 0; +} + +static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, + size_t len) +{ + struct hdmi_context *hdata = dev_get_drvdata(dev); + struct drm_connector *connector = &hdata->connector; + + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); + + return 0; +} + +static const struct hdmi_codec_ops audio_codec_ops = { + .hw_params = hdmi_audio_hw_params, + .audio_shutdown = hdmi_audio_shutdown, + .digital_mute = hdmi_audio_digital_mute, + .get_eld = hdmi_audio_get_eld, +}; + +static int hdmi_register_audio_device(struct hdmi_context *hdata) +{ + struct hdmi_codec_pdata codec_data = { + .ops = &audio_codec_ops, + .max_i2s_channels = 6, + .i2s = 1, + }; + + hdata->audio.pdev = platform_device_register_data( + hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, + &codec_data, sizeof(codec_data)); + + return PTR_ERR_OR_ZERO(hdata->audio.pdev); +} + static void hdmi_hotplug_work_func(struct work_struct *work) { struct hdmi_context *hdata; @@ -1602,11 +1709,14 @@ static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable) { struct hdmi_context *hdata = container_of(clk, struct hdmi_context, phy_clk); + mutex_lock(&hdata->mutex); if (enable) hdmiphy_enable(hdata); else hdmiphy_disable(hdata); + + mutex_unlock(&hdata->mutex); } static int hdmi_bridge_init(struct hdmi_context *hdata) @@ -1817,6 +1927,7 @@ out: static int hdmi_probe(struct platform_device *pdev) { + struct hdmi_audio_infoframe *audio_infoframe; struct device *dev = &pdev->dev; struct hdmi_context *hdata; struct resource *res; @@ -1832,6 +1943,8 @@ static int hdmi_probe(struct platform_device *pdev) hdata->dev = dev; + mutex_init(&hdata->mutex); + ret = hdmi_resources_init(hdata); if (ret) { if (ret != -EPROBE_DEFER) @@ -1891,12 +2004,26 @@ static int hdmi_probe(struct platform_device *pdev) pm_runtime_enable(dev); - ret = component_add(&pdev->dev, &hdmi_component_ops); + audio_infoframe = &hdata->audio.infoframe; + hdmi_audio_infoframe_init(audio_infoframe); + audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; + audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; + audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; + audio_infoframe->channels = 2; + + ret = hdmi_register_audio_device(hdata); if (ret) goto err_notifier_put; + ret = component_add(&pdev->dev, &hdmi_component_ops); + if (ret) + goto err_unregister_audio; + return ret; +err_unregister_audio: + platform_device_unregister(hdata->audio.pdev); + err_notifier_put: cec_notifier_put(hdata->notifier); pm_runtime_disable(dev); @@ -1920,6 +2047,7 @@ static int hdmi_remove(struct platform_device *pdev) cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID); component_del(&pdev->dev, &hdmi_component_ops); + platform_device_unregister(hdata->audio.pdev); cec_notifier_put(hdata->notifier); pm_runtime_disable(&pdev->dev); @@ -1935,6 +2063,8 @@ static int hdmi_remove(struct platform_device *pdev) put_device(&hdata->ddc_adpt->dev); + mutex_destroy(&hdata->mutex); + return 0; } diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h index a0507dc18d9e..04be0f7e8193 100644 --- a/drivers/gpu/drm/exynos/regs-hdmi.h +++ b/drivers/gpu/drm/exynos/regs-hdmi.h @@ -419,11 +419,9 @@ #define HDMI_I2S_DSD_CON HDMI_I2S_BASE(0x01c) #define HDMI_I2S_MUX_CON HDMI_I2S_BASE(0x020) #define HDMI_I2S_CH_ST_CON HDMI_I2S_BASE(0x024) -#define HDMI_I2S_CH_ST_0 HDMI_I2S_BASE(0x028) -#define HDMI_I2S_CH_ST_1 HDMI_I2S_BASE(0x02c) -#define HDMI_I2S_CH_ST_2 HDMI_I2S_BASE(0x030) -#define HDMI_I2S_CH_ST_3 HDMI_I2S_BASE(0x034) -#define HDMI_I2S_CH_ST_4 HDMI_I2S_BASE(0x038) +/* n must be within range 0...(HDMI_I2S_CH_ST_MAXNUM - 1) */ +#define HDMI_I2S_CH_ST_MAXNUM 5 +#define HDMI_I2S_CH_ST(n) HDMI_I2S_BASE(0x028 + 4 * (n)) #define HDMI_I2S_CH_ST_SH_0 HDMI_I2S_BASE(0x03c) #define HDMI_I2S_CH_ST_SH_1 HDMI_I2S_BASE(0x040) #define HDMI_I2S_CH_ST_SH_2 HDMI_I2S_BASE(0x044) -- cgit v1.2.3 From d309ae5c6a00648198d1932e6db483d612c2e260 Mon Sep 17 00:00:00 2001 From: Pieter Jansen van Vuuren Date: Wed, 25 Oct 2017 11:47:05 -0700 Subject: nfp: refuse offloading filters that redirects to upper devices Previously we did not ensure that a netdev is a representative netdev before dereferencing its private data. This can occur when an upper netdev is created on a representative netdev. This patch corrects this by first ensuring that the netdev is a representative netdev before using it. Checking only switchdev_port_same_parent_id is not sufficient to ensure that we can safely use the netdev. Failing to check that the netdev is also a representative netdev would result in incorrect dereferencing. Fixes: 1a1e586f54bf ("nfp: add basic action capabilities to flower offloads") Signed-off-by: Jakub Kicinski Signed-off-by: Pieter Jansen van Vuuren Signed-off-by: David S. Miller --- drivers/net/ethernet/netronome/nfp/flower/action.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index db9750695dc7..8ea9320014ee 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c @@ -110,6 +110,8 @@ nfp_fl_output(struct nfp_fl_output *output, const struct tc_action *action, */ if (!switchdev_port_same_parent_id(in_dev, out_dev)) return -EOPNOTSUPP; + if (!nfp_netdev_is_nfp_repr(out_dev)) + return -EOPNOTSUPP; output->port = cpu_to_be32(nfp_repr_get_port_id(out_dev)); if (!output->port) -- cgit v1.2.3 From 5c25f65fd1e42685f7ccd80e0621829c105785d9 Mon Sep 17 00:00:00 2001 From: Julien Gomes Date: Wed, 25 Oct 2017 11:50:50 -0700 Subject: tun: allow positive return values on dev_get_valid_name() call If the name argument of dev_get_valid_name() contains "%d", it will try to assign it a unit number in __dev__alloc_name() and return either the unit number (>= 0) or an error code (< 0). Considering positive values as error values prevent tun device creations relying this mechanism, therefor we should only consider negative values as errors here. Signed-off-by: Julien Gomes Acked-by: Cong Wang Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index e21bf90b819f..b9973fb868b7 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2028,7 +2028,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (!dev) return -ENOMEM; err = dev_get_valid_name(net, dev, name); - if (err) + if (err < 0) goto err_free_dev; dev_net_set(dev, net); -- cgit v1.2.3 From 75e500865fca102e4663cff2f02d67a62625ceb9 Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Thu, 19 Oct 2017 14:44:36 -0400 Subject: drm/amd/powerplay: add one smc message for Vega10 This is used to fix performance drop caused by updated SMU FW. Signed-off-by: Eric Huang Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h index d06ece4ac47d..247c97397a27 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h +++ b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h @@ -131,7 +131,8 @@ typedef uint16_t PPSMC_Result; #define PPSMC_MSG_RunAcgInOpenLoop 0x5E #define PPSMC_MSG_InitializeAcg 0x5F #define PPSMC_MSG_GetCurrPkgPwr 0x61 -#define PPSMC_Message_Count 0x62 +#define PPSMC_MSG_UpdatePkgPwrPidAlpha 0x68 +#define PPSMC_Message_Count 0x69 typedef int PPSMC_Msg; -- cgit v1.2.3 From b87079ec7b4d38efee015367315958ce5495ba93 Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Thu, 19 Oct 2017 14:55:18 -0400 Subject: drm/amd/powerplay: fix performance drop on Vega10 Setting package power PID to 1 fixes performance drop caused by updated SMU FW, before DPM is enabled. Signed-off-by: Eric Huang Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 0519338e0e5e..203ef10cafdc 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -2879,6 +2879,15 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) "DPM is already running right , skipping re-enablement!", return 0); + if ((data->smu_version == 0x001c2c00) || + (data->smu_version == 0x001c2d00)) { + tmp_result = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_UpdatePkgPwrPidAlpha, 1); + PP_ASSERT_WITH_CODE(!tmp_result, + "Failed to set package power PID!", + return tmp_result); + } + tmp_result = vega10_construct_voltage_tables(hwmgr); PP_ASSERT_WITH_CODE(!tmp_result, "Failed to contruct voltage tables!", -- cgit v1.2.3 From 0722382dcc4fd4e53c12db2c2eda9c5c9c903432 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Fri, 20 Oct 2017 15:42:34 +0800 Subject: drm/amd/powerplay: retrieve the real-time coreClock values - Currently, the coreClock value for min/max performance level on raven is hard-coded. Use the real-time value retrieved by GetGfxMinFreqLimit and GetGfxMaxFreqLimit PPSMC messages Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | 28 ++++++-------------------- 1 file changed, 6 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c index 938010842c7d..3e0b267c74a8 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c @@ -672,36 +672,20 @@ static int rv_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_p PHM_PerformanceLevelDesignation designation, uint32_t index, PHM_PerformanceLevel *level) { - const struct rv_power_state *ps; struct rv_hwmgr *data; - uint32_t level_index; - uint32_t i; - uint32_t vol_dep_record_index = 0; if (level == NULL || hwmgr == NULL || state == NULL) return -EINVAL; data = (struct rv_hwmgr *)(hwmgr->backend); - ps = cast_const_rv_ps(state); - - level_index = index > ps->level - 1 ? ps->level - 1 : index; - level->coreClock = 30000; - if (designation == PHM_PerformanceLevelDesignation_PowerContainment) { - for (i = 1; i < ps->level; i++) { - if (ps->levels[i].engine_clock > data->dce_slow_sclk_threshold) { - level->coreClock = 30000; - break; - } - } - } - - if (level_index == 0) { - vol_dep_record_index = data->clock_vol_info.vdd_dep_on_fclk->count - 1; - level->memory_clock = - data->clock_vol_info.vdd_dep_on_fclk->entries[vol_dep_record_index].clk; - } else { + if (index == 0) { level->memory_clock = data->clock_vol_info.vdd_dep_on_fclk->entries[0].clk; + level->coreClock = data->gfx_min_freq_limit; + } else { + level->memory_clock = data->clock_vol_info.vdd_dep_on_fclk->entries[ + data->clock_vol_info.vdd_dep_on_fclk->count - 1].clk; + level->coreClock = data->gfx_max_freq_limit; } level->nonLocalMemoryFreq = 0; -- cgit v1.2.3 From 4694257e7d4757fedaa8dcd18bb5ff52e76a2765 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 16 Oct 2017 16:51:28 +0800 Subject: drm/amdgpu/psp: prevent page fault by checking write_frame address(v4) - Prevent a possible buffer overflow when updating the ring buffer by bounds checking the command frame against the available space in the ring buffer. v2: update the ring_buffer_end address v3: update the commit log v4: squash in print fix (Michel) Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 14 ++++++++++++-- drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c index dea7c909ca5f..4e20d91d5d50 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c @@ -257,6 +257,9 @@ int psp_v10_0_cmd_submit(struct psp_context *psp, unsigned int psp_write_ptr_reg = 0; struct psp_gfx_rb_frame * write_frame = psp->km_ring.ring_mem; struct psp_ring *ring = &psp->km_ring; + struct psp_gfx_rb_frame *ring_buffer_start = ring->ring_mem; + struct psp_gfx_rb_frame *ring_buffer_end = ring_buffer_start + + ring->ring_size / sizeof(struct psp_gfx_rb_frame) - 1; struct amdgpu_device *adev = psp->adev; uint32_t ring_size_dw = ring->ring_size / 4; uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; @@ -266,9 +269,16 @@ int psp_v10_0_cmd_submit(struct psp_context *psp, /* Update KM RB frame pointer to new frame */ if ((psp_write_ptr_reg % ring_size_dw) == 0) - write_frame = ring->ring_mem; + write_frame = ring_buffer_start; else - write_frame = ring->ring_mem + (psp_write_ptr_reg / rb_frame_size_dw); + write_frame = ring_buffer_start + (psp_write_ptr_reg / rb_frame_size_dw); + /* Check invalid write_frame ptr address */ + if ((write_frame < ring_buffer_start) || (ring_buffer_end < write_frame)) { + DRM_ERROR("ring_buffer_start = %p; ring_buffer_end = %p; write_frame = %p\n", + ring_buffer_start, ring_buffer_end, write_frame); + DRM_ERROR("write_frame is pointing to address out of bounds\n"); + return -EINVAL; + } /* Initialize KM RB frame */ memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame)); diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index cee5c396b277..c7bcfe8e286c 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c @@ -367,6 +367,9 @@ int psp_v3_1_cmd_submit(struct psp_context *psp, unsigned int psp_write_ptr_reg = 0; struct psp_gfx_rb_frame * write_frame = psp->km_ring.ring_mem; struct psp_ring *ring = &psp->km_ring; + struct psp_gfx_rb_frame *ring_buffer_start = ring->ring_mem; + struct psp_gfx_rb_frame *ring_buffer_end = ring_buffer_start + + ring->ring_size / sizeof(struct psp_gfx_rb_frame) - 1; struct amdgpu_device *adev = psp->adev; uint32_t ring_size_dw = ring->ring_size / 4; uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; @@ -378,9 +381,16 @@ int psp_v3_1_cmd_submit(struct psp_context *psp, /* write_frame ptr increments by size of rb_frame in bytes */ /* psp_write_ptr_reg increments by size of rb_frame in DWORDs */ if ((psp_write_ptr_reg % ring_size_dw) == 0) - write_frame = ring->ring_mem; + write_frame = ring_buffer_start; else - write_frame = ring->ring_mem + (psp_write_ptr_reg / rb_frame_size_dw); + write_frame = ring_buffer_start + (psp_write_ptr_reg / rb_frame_size_dw); + /* Check invalid write_frame ptr address */ + if ((write_frame < ring_buffer_start) || (ring_buffer_end < write_frame)) { + DRM_ERROR("ring_buffer_start = %p; ring_buffer_end = %p; write_frame = %p\n", + ring_buffer_start, ring_buffer_end, write_frame); + DRM_ERROR("write_frame is pointing to address out of bounds\n"); + return -EINVAL; + } /* Initialize KM RB frame */ memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame)); -- cgit v1.2.3 From ec8c9f8be875c48c391a1355255867a2d70d1ee2 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 16 Oct 2017 13:47:15 +0200 Subject: drm/amdgpu: minor cleanup for amdgpu_ttm_bind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filter the placement mask before using it. In theory it could be that we have other flags set here as well. Signed-off-by: Christian König Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 51eacefadea1..b577b717caa0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -909,7 +909,8 @@ int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem) placement.busy_placement = &placements; placements.fpfn = 0; placements.lpfn = adev->mc.gart_size >> PAGE_SHIFT; - placements.flags = bo->mem.placement | TTM_PL_FLAG_TT; + placements.flags = (bo->mem.placement & ~TTM_PL_MASK_MEM) | + TTM_PL_FLAG_TT; r = ttm_bo_mem_space(bo, &placement, &tmp, true, false); if (unlikely(r)) -- cgit v1.2.3 From fa2cd036925ffea8ef4f2826734ccfa1b0528141 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 16 Oct 2017 17:37:06 +0200 Subject: drm/amdgpu: don't flush the TLB before initializing GART MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No point in doing this. Signed-off-by: Christian König Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index f4370081f6e6..fe818501c520 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -332,12 +332,13 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset, adev->gart.pages[p] = pagelist[i]; #endif - if (adev->gart.ptr) { - r = amdgpu_gart_map(adev, offset, pages, dma_addr, flags, - adev->gart.ptr); - if (r) - return r; - } + if (!adev->gart.ptr) + return 0; + + r = amdgpu_gart_map(adev, offset, pages, dma_addr, flags, + adev->gart.ptr); + if (r) + return r; mb(); amdgpu_gart_flush_gpu_tlb(adev, 0); -- cgit v1.2.3 From 4a0144bfc6df1f7a89a04a3e8662f1f4375eb1fe Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 24 Oct 2017 12:07:12 -0400 Subject: drm/amd/amdgpu: Remove workaround for suspend/resume in uvd7 The workaround is not required anymor and would result in hangs during suspend/resume cycles if the uvd block were busy. Signed-off-by: Tom St Denis Acked-by: Leo Liu Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index b8ed8faf2003..6634545060fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -592,11 +592,7 @@ static int uvd_v7_0_suspend(void *handle) if (r) return r; - /* Skip this for APU for now */ - if (!(adev->flags & AMD_IS_APU)) - r = amdgpu_uvd_suspend(adev); - - return r; + return amdgpu_uvd_suspend(adev); } static int uvd_v7_0_resume(void *handle) @@ -604,12 +600,10 @@ static int uvd_v7_0_resume(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - /* Skip this for APU for now */ - if (!(adev->flags & AMD_IS_APU)) { - r = amdgpu_uvd_resume(adev); - if (r) - return r; - } + r = amdgpu_uvd_resume(adev); + if (r) + return r; + return uvd_v7_0_hw_init(adev); } -- cgit v1.2.3 From 6377ed0bbae6fa28853e1679d068a9106c8a8908 Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Thu, 19 Oct 2017 14:14:29 +0300 Subject: net/mlx5: Fix health work queue spin lock to IRQ safe spin_lock/unlock of health->wq_lock should be IRQ safe. It was changed to spin_lock_irqsave since adding commit 0179720d6be2 ("net/mlx5: Introduce trigger_health_work function") which uses spin_lock from asynchronous event (IRQ) context. Thus, all spin_lock/unlock of health->wq_lock should have been moved to IRQ safe mode. However, one occurrence on new code using this lock missed that change, resulting in possible deadlock: kernel: Possible unsafe locking scenario: kernel: CPU0 kernel: ---- kernel: lock(&(&health->wq_lock)->rlock); kernel: kernel: lock(&(&health->wq_lock)->rlock); kernel: #012 *** DEADLOCK *** Fixes: 2a0165a034ac ("net/mlx5: Cancel delayed recovery work when unloading the driver") Signed-off-by: Moshe Shemesh Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/health.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c index 8aea0a065e56..db86e1506c8b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c @@ -356,10 +356,11 @@ void mlx5_drain_health_wq(struct mlx5_core_dev *dev) void mlx5_drain_health_recovery(struct mlx5_core_dev *dev) { struct mlx5_core_health *health = &dev->priv.health; + unsigned long flags; - spin_lock(&health->wq_lock); + spin_lock_irqsave(&health->wq_lock, flags); set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags); - spin_unlock(&health->wq_lock); + spin_unlock_irqrestore(&health->wq_lock, flags); cancel_delayed_work_sync(&dev->priv.health.recover_work); } -- cgit v1.2.3 From 4ca637a20a524cd8ddbca696f12bfa92111c96e3 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Wed, 4 Oct 2017 17:58:21 -0500 Subject: net/mlx5: Delay events till mlx5 interface's add complete for pci resume mlx5_ib_add is called during mlx5_pci_resume after a pci error. Before mlx5_ib_add completes, there are multiple events which trigger function mlx5_ib_event. This cause kernel panic because mlx5_ib_event accesses unitialized resources. The fix is to extend Erez Shitrit's patch <97834eba7c19> ("net/mlx5: Delay events till ib registration ends") to cover the pci resume code path. Trace: mlx5_core 0001:01:00.6: mlx5_pci_resume was called mlx5_core 0001:01:00.6: firmware version: 16.20.1011 mlx5_core 0001:01:00.6: mlx5_attach_interface:164:(pid 779): mlx5_ib_event:2996:(pid 34777): warning: event on port 1 mlx5_ib_event:2996:(pid 34782): warning: event on port 1 Unable to handle kernel paging request for data at address 0x0001c104 Faulting instruction address: 0xd000000008f411fc Oops: Kernel access of bad area, sig: 11 [#1] ... ... Call Trace: [c000000fff77bb70] [d000000008f4119c] mlx5_ib_event+0x64/0x470 [mlx5_ib] (unreliable) [c000000fff77bc60] [d000000008e67130] mlx5_core_event+0xb8/0x210 [mlx5_core] [c000000fff77bd10] [d000000008e4bd00] mlx5_eq_int+0x528/0x860[mlx5_core] Fixes: 97834eba7c19 ("net/mlx5: Delay events till ib registration ends") Signed-off-by: Huy Nguyen Reviewed-by: Saeed Mahameed Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 70 ++++++++++++++++----------- 1 file changed, 41 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c index ff60cf7342ca..fc281712869b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c @@ -77,35 +77,41 @@ static void add_delayed_event(struct mlx5_priv *priv, list_add_tail(&delayed_event->list, &priv->waiting_events_list); } -static void fire_delayed_event_locked(struct mlx5_device_context *dev_ctx, - struct mlx5_core_dev *dev, - struct mlx5_priv *priv) +static void delayed_event_release(struct mlx5_device_context *dev_ctx, + struct mlx5_priv *priv) { + struct mlx5_core_dev *dev = container_of(priv, struct mlx5_core_dev, priv); struct mlx5_delayed_event *de; struct mlx5_delayed_event *n; + struct list_head temp; - /* stop delaying events */ - priv->is_accum_events = false; + INIT_LIST_HEAD(&temp); + + spin_lock_irq(&priv->ctx_lock); - /* fire all accumulated events before new event comes */ - list_for_each_entry_safe(de, n, &priv->waiting_events_list, list) { + priv->is_accum_events = false; + list_splice_init(&priv->waiting_events_list, &temp); + if (!dev_ctx->context) + goto out; + list_for_each_entry_safe(de, n, &priv->waiting_events_list, list) dev_ctx->intf->event(dev, dev_ctx->context, de->event, de->param); + +out: + spin_unlock_irq(&priv->ctx_lock); + + list_for_each_entry_safe(de, n, &temp, list) { list_del(&de->list); kfree(de); } } -static void cleanup_delayed_evets(struct mlx5_priv *priv) +/* accumulating events that can come after mlx5_ib calls to + * ib_register_device, till adding that interface to the events list. + */ +static void delayed_event_start(struct mlx5_priv *priv) { - struct mlx5_delayed_event *de; - struct mlx5_delayed_event *n; - spin_lock_irq(&priv->ctx_lock); - priv->is_accum_events = false; - list_for_each_entry_safe(de, n, &priv->waiting_events_list, list) { - list_del(&de->list); - kfree(de); - } + priv->is_accum_events = true; spin_unlock_irq(&priv->ctx_lock); } @@ -122,11 +128,8 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv) return; dev_ctx->intf = intf; - /* accumulating events that can come after mlx5_ib calls to - * ib_register_device, till adding that interface to the events list. - */ - priv->is_accum_events = true; + delayed_event_start(priv); dev_ctx->context = intf->add(dev); set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state); @@ -137,8 +140,6 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv) spin_lock_irq(&priv->ctx_lock); list_add_tail(&dev_ctx->list, &priv->ctx_list); - fire_delayed_event_locked(dev_ctx, dev, priv); - #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING if (dev_ctx->intf->pfault) { if (priv->pfault) { @@ -150,11 +151,12 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv) } #endif spin_unlock_irq(&priv->ctx_lock); - } else { - kfree(dev_ctx); - /* delete all accumulated events */ - cleanup_delayed_evets(priv); } + + delayed_event_release(dev_ctx, priv); + + if (!dev_ctx->context) + kfree(dev_ctx); } static struct mlx5_device_context *mlx5_get_device(struct mlx5_interface *intf, @@ -205,17 +207,21 @@ static void mlx5_attach_interface(struct mlx5_interface *intf, struct mlx5_priv if (!dev_ctx) return; + delayed_event_start(priv); if (intf->attach) { if (test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state)) - return; + goto out; intf->attach(dev, dev_ctx->context); set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state); } else { if (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state)) - return; + goto out; dev_ctx->context = intf->add(dev); set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state); } + +out: + delayed_event_release(dev_ctx, priv); } void mlx5_attach_device(struct mlx5_core_dev *dev) @@ -414,8 +420,14 @@ void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event, if (priv->is_accum_events) add_delayed_event(priv, dev, event, param); + /* After mlx5_detach_device, the dev_ctx->intf is still set and dev_ctx is + * still in priv->ctx_list. In this case, only notify the dev_ctx if its + * ADDED or ATTACHED bit are set. + */ list_for_each_entry(dev_ctx, &priv->ctx_list, list) - if (dev_ctx->intf->event) + if (dev_ctx->intf->event && + (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state) || + test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state))) dev_ctx->intf->event(dev, dev_ctx->context, event, param); spin_unlock_irqrestore(&priv->ctx_lock, flags); -- cgit v1.2.3 From 3c37745ec614ff048d5dce38f976804b05d307ee Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Tue, 17 Oct 2017 12:33:43 +0200 Subject: net/mlx5e: Properly deal with encap flows add/del under neigh update Currently, the encap action offload is handled in the actions parse function and not in mlx5e_tc_add_fdb_flow() where we deal with all the other aspects of offloading actions (vlan, modify header) and the rule itself. When the neigh update code (mlx5e_tc_encap_flows_add()) recreates the encap entry and offloads the related flows, we wrongly call again into mlx5e_tc_add_fdb_flow(), this for itself would cause us to handle again the offloading of vlans and header re-write which puts things in non consistent state and step on freed memory (e.g the modify header parse buffer which is already freed). Since on error, mlx5e_tc_add_fdb_flow() detaches and may release the encap entry, it causes a corruption at the neigh update code which goes over the list of flows associated with this encap entry, or double free when the tc flow is later deleted by user-space. When neigh update (mlx5e_tc_encap_flows_del()) unoffloads the flows related to an encap entry which is now invalid, we do a partial repeat of the eswitch flow removal code which is wrong too. To fix things up we do the following: (1) handle the encap action offload in the eswitch flow add function mlx5e_tc_add_fdb_flow() as done for the other actions and the rule itself. (2) modify the neigh update code (mlx5e_tc_encap_flows_add/del) to only deal with the encap entry and rules delete/add and not with any of the other offloaded actions. Fixes: 232c001398ae ('net/mlx5e: Add support to neighbour update flow') Signed-off-by: Or Gerlitz Reviewed-by: Paul Blakey Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 89 +++++++++++++++---------- 1 file changed, 54 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 1aa2028ed995..9ba1f72060aa 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -78,9 +78,11 @@ struct mlx5e_tc_flow { }; struct mlx5e_tc_flow_parse_attr { + struct ip_tunnel_info tun_info; struct mlx5_flow_spec spec; int num_mod_hdr_actions; void *mod_hdr_actions; + int mirred_ifindex; }; enum { @@ -322,6 +324,12 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv, static void mlx5e_detach_encap(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow); +static int mlx5e_attach_encap(struct mlx5e_priv *priv, + struct ip_tunnel_info *tun_info, + struct net_device *mirred_dev, + struct net_device **encap_dev, + struct mlx5e_tc_flow *flow); + static struct mlx5_flow_handle * mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, struct mlx5e_tc_flow_parse_attr *parse_attr, @@ -329,9 +337,27 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_esw_flow_attr *attr = flow->esw_attr; - struct mlx5_flow_handle *rule; + struct net_device *out_dev, *encap_dev = NULL; + struct mlx5_flow_handle *rule = NULL; + struct mlx5e_rep_priv *rpriv; + struct mlx5e_priv *out_priv; int err; + if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) { + out_dev = __dev_get_by_index(dev_net(priv->netdev), + attr->parse_attr->mirred_ifindex); + err = mlx5e_attach_encap(priv, &parse_attr->tun_info, + out_dev, &encap_dev, flow); + if (err) { + rule = ERR_PTR(err); + if (err != -EAGAIN) + goto err_attach_encap; + } + out_priv = netdev_priv(encap_dev); + rpriv = out_priv->ppriv; + attr->out_rep = rpriv->rep; + } + err = mlx5_eswitch_add_vlan_action(esw, attr); if (err) { rule = ERR_PTR(err); @@ -347,10 +373,14 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, } } - rule = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr); - if (IS_ERR(rule)) - goto err_add_rule; - + /* we get here if (1) there's no error (rule being null) or when + * (2) there's an encap action and we're on -EAGAIN (no valid neigh) + */ + if (rule != ERR_PTR(-EAGAIN)) { + rule = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr); + if (IS_ERR(rule)) + goto err_add_rule; + } return rule; err_add_rule: @@ -361,6 +391,7 @@ err_mod_hdr: err_add_vlan: if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) mlx5e_detach_encap(priv, flow); +err_attach_encap: return rule; } @@ -389,6 +420,8 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, struct mlx5e_encap_entry *e) { + struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; + struct mlx5_esw_flow_attr *esw_attr; struct mlx5e_tc_flow *flow; int err; @@ -404,10 +437,9 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, mlx5e_rep_queue_neigh_stats_work(priv); list_for_each_entry(flow, &e->flows, encap) { - flow->esw_attr->encap_id = e->encap_id; - flow->rule = mlx5e_tc_add_fdb_flow(priv, - flow->esw_attr->parse_attr, - flow); + esw_attr = flow->esw_attr; + esw_attr->encap_id = e->encap_id; + flow->rule = mlx5_eswitch_add_offloaded_rule(esw, &esw_attr->parse_attr->spec, esw_attr); if (IS_ERR(flow->rule)) { err = PTR_ERR(flow->rule); mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n", @@ -421,15 +453,13 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv, struct mlx5e_encap_entry *e) { + struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5e_tc_flow *flow; - struct mlx5_fc *counter; list_for_each_entry(flow, &e->flows, encap) { if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) { flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED; - counter = mlx5_flow_rule_counter(flow->rule); - mlx5_del_flow_rules(flow->rule); - mlx5_fc_destroy(priv->mdev, counter); + mlx5_eswitch_del_offloaded_rule(esw, flow->rule, flow->esw_attr); } } @@ -1942,7 +1972,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, if (is_tcf_mirred_egress_redirect(a)) { int ifindex = tcf_mirred_ifindex(a); - struct net_device *out_dev, *encap_dev = NULL; + struct net_device *out_dev; struct mlx5e_priv *out_priv; out_dev = __dev_get_by_index(dev_net(priv->netdev), ifindex); @@ -1955,17 +1985,13 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, rpriv = out_priv->ppriv; attr->out_rep = rpriv->rep; } else if (encap) { - err = mlx5e_attach_encap(priv, info, - out_dev, &encap_dev, flow); - if (err && err != -EAGAIN) - return err; + parse_attr->mirred_ifindex = ifindex; + parse_attr->tun_info = *info; + attr->parse_attr = parse_attr; attr->action |= MLX5_FLOW_CONTEXT_ACTION_ENCAP | MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_COUNT; - out_priv = netdev_priv(encap_dev); - rpriv = out_priv->ppriv; - attr->out_rep = rpriv->rep; - attr->parse_attr = parse_attr; + /* attr->out_rep is resolved when we handle encap */ } else { pr_err("devices %s %s not on same switch HW, can't offload forwarding\n", priv->netdev->name, out_dev->name); @@ -2047,7 +2073,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, if (flow->flags & MLX5E_TC_FLOW_ESWITCH) { err = parse_tc_fdb_actions(priv, f->exts, parse_attr, flow); if (err < 0) - goto err_handle_encap_flow; + goto err_free; flow->rule = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow); } else { err = parse_tc_nic_actions(priv, f->exts, parse_attr, flow); @@ -2058,10 +2084,13 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, if (IS_ERR(flow->rule)) { err = PTR_ERR(flow->rule); - goto err_free; + if (err != -EAGAIN) + goto err_free; } - flow->flags |= MLX5E_TC_FLOW_OFFLOADED; + if (err != -EAGAIN) + flow->flags |= MLX5E_TC_FLOW_OFFLOADED; + err = rhashtable_insert_fast(&tc->ht, &flow->node, tc->ht_params); if (err) @@ -2075,16 +2104,6 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, err_del_rule: mlx5e_tc_del_flow(priv, flow); -err_handle_encap_flow: - if (err == -EAGAIN) { - err = rhashtable_insert_fast(&tc->ht, &flow->node, - tc->ht_params); - if (err) - mlx5e_tc_del_flow(priv, flow); - else - return 0; - } - err_free: kvfree(parse_attr); kfree(flow); -- cgit v1.2.3 From be0f161ef141e4df368aa3f417a1c2ab9c362e75 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Thu, 28 Sep 2017 15:33:50 -0500 Subject: net/mlx5e: DCBNL, Implement tc with ets type and zero bandwidth Previously, tc with ets type and zero bandwidth is not accepted by driver. This behavior does not follow the IEEE802.1qaz spec. If there are tcs with ets type and zero bandwidth, these tcs are assigned to the lowest priority tc_group #0. We equally distribute 100% bw of the tc_group #0 to these zero bandwidth ets tcs. Also, the non zero bandwidth ets tcs are assigned to tc_group #1. If there is no zero bandwidth ets tc, the non zero bandwidth ets tcs are assigned to tc_group #0. Fixes: cdcf11212b22 ("net/mlx5e: Validate BW weight values of ETS") Signed-off-by: Huy Nguyen Reviewed-by: Parav Pandit Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 113 +++++++++++++++------ drivers/net/ethernet/mellanox/mlx5/core/port.c | 21 ++++ include/linux/mlx5/port.h | 2 + 3 files changed, 106 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index c1d384fca4dc..51c4cc00a186 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -41,6 +41,11 @@ #define MLX5E_CEE_STATE_UP 1 #define MLX5E_CEE_STATE_DOWN 0 +enum { + MLX5E_VENDOR_TC_GROUP_NUM = 7, + MLX5E_LOWEST_PRIO_GROUP = 0, +}; + /* If dcbx mode is non-host set the dcbx mode to host. */ static int mlx5e_dcbnl_set_dcbx_mode(struct mlx5e_priv *priv, @@ -85,6 +90,9 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev, { struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5_core_dev *mdev = priv->mdev; + u8 tc_group[IEEE_8021QAZ_MAX_TCS]; + bool is_tc_group_6_exist = false; + bool is_zero_bw_ets_tc = false; int err = 0; int i; @@ -96,37 +104,64 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev, err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]); if (err) return err; - } - for (i = 0; i < ets->ets_cap; i++) { + err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]); + if (err) + return err; + err = mlx5_query_port_tc_bw_alloc(mdev, i, &ets->tc_tx_bw[i]); if (err) return err; + + if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC && + tc_group[i] == (MLX5E_LOWEST_PRIO_GROUP + 1)) + is_zero_bw_ets_tc = true; + + if (tc_group[i] == (MLX5E_VENDOR_TC_GROUP_NUM - 1)) + is_tc_group_6_exist = true; + } + + /* Report 0% ets tc if exits*/ + if (is_zero_bw_ets_tc) { + for (i = 0; i < ets->ets_cap; i++) + if (tc_group[i] == MLX5E_LOWEST_PRIO_GROUP) + ets->tc_tx_bw[i] = 0; + } + + /* Update tc_tsa based on fw setting*/ + for (i = 0; i < ets->ets_cap; i++) { if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC) priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS; + else if (tc_group[i] == MLX5E_VENDOR_TC_GROUP_NUM && + !is_tc_group_6_exist) + priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR; } - memcpy(ets->tc_tsa, priv->dcbx.tc_tsa, sizeof(ets->tc_tsa)); return err; } -enum { - MLX5E_VENDOR_TC_GROUP_NUM = 7, - MLX5E_ETS_TC_GROUP_NUM = 0, -}; - static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc) { bool any_tc_mapped_to_ets = false; + bool ets_zero_bw = false; int strict_group; int i; - for (i = 0; i <= max_tc; i++) - if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) + for (i = 0; i <= max_tc; i++) { + if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { any_tc_mapped_to_ets = true; + if (!ets->tc_tx_bw[i]) + ets_zero_bw = true; + } + } - strict_group = any_tc_mapped_to_ets ? 1 : 0; + /* strict group has higher priority than ets group */ + strict_group = MLX5E_LOWEST_PRIO_GROUP; + if (any_tc_mapped_to_ets) + strict_group++; + if (ets_zero_bw) + strict_group++; for (i = 0; i <= max_tc; i++) { switch (ets->tc_tsa[i]) { @@ -137,7 +172,9 @@ static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc) tc_group[i] = strict_group++; break; case IEEE_8021QAZ_TSA_ETS: - tc_group[i] = MLX5E_ETS_TC_GROUP_NUM; + tc_group[i] = MLX5E_LOWEST_PRIO_GROUP; + if (ets->tc_tx_bw[i] && ets_zero_bw) + tc_group[i] = MLX5E_LOWEST_PRIO_GROUP + 1; break; } } @@ -146,8 +183,22 @@ static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc) static void mlx5e_build_tc_tx_bw(struct ieee_ets *ets, u8 *tc_tx_bw, u8 *tc_group, int max_tc) { + int bw_for_ets_zero_bw_tc = 0; + int last_ets_zero_bw_tc = -1; + int num_ets_zero_bw = 0; int i; + for (i = 0; i <= max_tc; i++) { + if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS && + !ets->tc_tx_bw[i]) { + num_ets_zero_bw++; + last_ets_zero_bw_tc = i; + } + } + + if (num_ets_zero_bw) + bw_for_ets_zero_bw_tc = MLX5E_MAX_BW_ALLOC / num_ets_zero_bw; + for (i = 0; i <= max_tc; i++) { switch (ets->tc_tsa[i]) { case IEEE_8021QAZ_TSA_VENDOR: @@ -157,12 +208,26 @@ static void mlx5e_build_tc_tx_bw(struct ieee_ets *ets, u8 *tc_tx_bw, tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC; break; case IEEE_8021QAZ_TSA_ETS: - tc_tx_bw[i] = ets->tc_tx_bw[i]; + tc_tx_bw[i] = ets->tc_tx_bw[i] ? + ets->tc_tx_bw[i] : + bw_for_ets_zero_bw_tc; break; } } + + /* Make sure the total bw for ets zero bw group is 100% */ + if (last_ets_zero_bw_tc != -1) + tc_tx_bw[last_ets_zero_bw_tc] += + MLX5E_MAX_BW_ALLOC % num_ets_zero_bw; } +/* If there are ETS BW 0, + * Set ETS group # to 1 for all ETS non zero BW tcs. Their sum must be 100%. + * Set group #0 to all the ETS BW 0 tcs and + * equally splits the 100% BW between them + * Report both group #0 and #1 as ETS type. + * All the tcs in group #0 will be reported with 0% BW. + */ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) { struct mlx5_core_dev *mdev = priv->mdev; @@ -188,7 +253,6 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets) return err; memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa)); - return err; } @@ -209,17 +273,9 @@ static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, } /* Validate Bandwidth Sum */ - for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { - if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { - if (!ets->tc_tx_bw[i]) { - netdev_err(netdev, - "Failed to validate ETS: BW 0 is illegal\n"); - return -EINVAL; - } - + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) + if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) bw_sum += ets->tc_tx_bw[i]; - } - } if (bw_sum != 0 && bw_sum != 100) { netdev_err(netdev, @@ -533,8 +589,7 @@ static void mlx5e_dcbnl_getpgtccfgtx(struct net_device *netdev, static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev, int pgid, u8 *bw_pct) { - struct mlx5e_priv *priv = netdev_priv(netdev); - struct mlx5_core_dev *mdev = priv->mdev; + struct ieee_ets ets; if (pgid >= CEE_DCBX_MAX_PGS) { netdev_err(netdev, @@ -542,8 +597,8 @@ static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev, return; } - if (mlx5_query_port_tc_bw_alloc(mdev, pgid, bw_pct)) - *bw_pct = 0; + mlx5e_dcbnl_ieee_getets(netdev, &ets); + *bw_pct = ets.tc_tx_bw[pgid]; } static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev, @@ -739,8 +794,6 @@ static void mlx5e_ets_init(struct mlx5e_priv *priv) ets.prio_tc[i] = i; } - memcpy(priv->dcbx.tc_tsa, ets.tc_tsa, sizeof(ets.tc_tsa)); - /* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */ ets.prio_tc[0] = 1; ets.prio_tc[1] = 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index 1975d4388d4f..e07061f565d6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -677,6 +677,27 @@ int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group) } EXPORT_SYMBOL_GPL(mlx5_set_port_tc_group); +int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev, + u8 tc, u8 *tc_group) +{ + u32 out[MLX5_ST_SZ_DW(qetc_reg)]; + void *ets_tcn_conf; + int err; + + err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out)); + if (err) + return err; + + ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out, + tc_configuration[tc]); + + *tc_group = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf, + group); + + return 0; +} +EXPORT_SYMBOL_GPL(mlx5_query_port_tc_group); + int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw) { u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {0}; diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h index c57d4b7de3a8..c59af8ab753a 100644 --- a/include/linux/mlx5/port.h +++ b/include/linux/mlx5/port.h @@ -157,6 +157,8 @@ int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc); int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev, u8 prio, u8 *tc); int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group); +int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev, + u8 tc, u8 *tc_group); int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw); int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 tc, u8 *bw_pct); -- cgit v1.2.3 From ef4816f0ee576d4a27ed35cd1090904121391cb9 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 24 Oct 2017 11:41:26 +0200 Subject: net: mvpp2: fix typo in the tcam setup This patch fixes a typo in the mvpp2_prs_tcam_data_cmp() function, as the shift value is inverted with the data. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 28c6e8a5e118..0b2017170d5b 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -1539,7 +1539,7 @@ static bool mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *pe, int offs, int off = MVPP2_PRS_TCAM_DATA_BYTE(offs); u16 tcam_data; - tcam_data = (8 << pe->tcam.byte[off + 1]) | pe->tcam.byte[off]; + tcam_data = (pe->tcam.byte[off + 1] << 8) | pe->tcam.byte[off]; if (tcam_data != data) return false; return true; -- cgit v1.2.3 From 20746d717ea390ac6ac3aa531f27ac156bf2e747 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 24 Oct 2017 11:41:27 +0200 Subject: net: mvpp2: fix invalid parameters order when calling the tcam init When calling mvpp2_prs_mac_multi_set() from mvpp2_prs_mac_init(), two parameters (the port index and the table index) are inverted. Fixes this. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 0b2017170d5b..c8ce652a4dd7 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -2614,8 +2614,8 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv) /* place holders only - no ports */ mvpp2_prs_mac_drop_all_set(priv, 0, false); mvpp2_prs_mac_promisc_set(priv, 0, false); - mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_ALL, 0, false); - mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_IP6, 0, false); + mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_ALL, false); + mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_IP6, false); } /* Set default entries for various types of dsa packets */ -- cgit v1.2.3 From 239dd4ee4838523419ad16e05b16a2003b71d317 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 24 Oct 2017 11:41:28 +0200 Subject: net: mvpp2: do not sleep in set_rx_mode This patch replaces GFP_KERNEL by GFP_ATOMIC to avoid sleeping in the ndo_set_rx_mode() call which is called with BH disabled. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index c8ce652a4dd7..a37af5813f33 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -3396,7 +3396,7 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da, struct mvpp2_prs_entry *pe; int tid; - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc(sizeof(*pe), GFP_ATOMIC); if (!pe) return NULL; mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); @@ -3458,7 +3458,7 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port, if (tid < 0) return tid; - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc(sizeof(*pe), GFP_ATOMIC); if (!pe) return -ENOMEM; mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); -- cgit v1.2.3 From 78e0ea6791d7baafb8a0ca82b1bd0c7b3453c919 Mon Sep 17 00:00:00 2001 From: Girish Moodalbail Date: Wed, 25 Oct 2017 00:23:04 -0700 Subject: tap: double-free in error path in tap_open() Double free of skb_array in tap module is causing kernel panic. When tap_set_queue() fails we free skb_array right away by calling skb_array_cleanup(). However, later on skb_array_cleanup() is called again by tap_sock_destruct through sock_put(). This patch fixes that issue. Fixes: 362899b8725b35e3 (macvtap: switch to use skb array) Signed-off-by: Girish Moodalbail Acked-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/tap.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 21b71ae947fd..98ee6cc2875d 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -517,6 +517,10 @@ static int tap_open(struct inode *inode, struct file *file) &tap_proto, 0); if (!q) goto err; + if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) { + sk_free(&q->sk); + goto err; + } RCU_INIT_POINTER(q->sock.wq, &q->wq); init_waitqueue_head(&q->wq.wait); @@ -540,22 +544,18 @@ static int tap_open(struct inode *inode, struct file *file) if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG)) sock_set_flag(&q->sk, SOCK_ZEROCOPY); - err = -ENOMEM; - if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) - goto err_array; - err = tap_set_queue(tap, file, q); - if (err) - goto err_queue; + if (err) { + /* tap_sock_destruct() will take care of freeing skb_array */ + goto err_put; + } dev_put(tap->dev); rtnl_unlock(); return err; -err_queue: - skb_array_cleanup(&q->skb_array); -err_array: +err_put: sock_put(&q->sk); err: if (tap) -- cgit v1.2.3 From 5266b8e4445cc836c46689d80a9ff539fa3bfbda Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 26 Oct 2017 11:50:56 +0200 Subject: xen: fix booting ballooned down hvm guest Commit 96edd61dcf44362d3ef0bed1a5361e0ac7886a63 ("xen/balloon: don't online new memory initially") introduced a regression when booting a HVM domain with memory less than mem-max: instead of ballooning down immediately the system would try to use the memory up to mem-max resulting in Xen crashing the domain. For HVM domains the current size will be reflected in Xenstore node memory/static-max instead of memory/target. Additionally we have to trigger the ballooning process at once. Cc: # 4.13 Fixes: 96edd61dcf44362d3ef0bed1a5361e0ac7886a63 ("xen/balloon: don't online new memory initially") Reported-by: Simon Gaiser Suggested-by: Boris Ostrovsky Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Signed-off-by: Boris Ostrovsky --- drivers/xen/xen-balloon.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index e89136ab851e..b437fccd4e62 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c @@ -57,7 +57,7 @@ static int register_balloon(struct device *dev); static void watch_target(struct xenbus_watch *watch, const char *path, const char *token) { - unsigned long long new_target; + unsigned long long new_target, static_max; int err; static bool watch_fired; static long target_diff; @@ -72,13 +72,20 @@ static void watch_target(struct xenbus_watch *watch, * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. */ new_target >>= PAGE_SHIFT - 10; - if (watch_fired) { - balloon_set_new_target(new_target - target_diff); - return; + + if (!watch_fired) { + watch_fired = true; + err = xenbus_scanf(XBT_NIL, "memory", "static-max", "%llu", + &static_max); + if (err != 1) + static_max = new_target; + else + static_max >>= PAGE_SHIFT - 10; + target_diff = xen_pv_domain() ? 0 + : static_max - balloon_stats.target_pages; } - watch_fired = true; - target_diff = new_target - balloon_stats.target_pages; + balloon_set_new_target(new_target - target_diff); } static struct xenbus_watch target_watch = { .node = "memory/target", -- cgit v1.2.3 From 44c445c3d1b4eacff23141fa7977c3b2ec3a45c9 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Sat, 16 Sep 2017 18:00:00 +0200 Subject: e1000: fix race condition between e1000_down() and e1000_watchdog This patch fixes a race condition that can result into the interface being up and carrier on, but with transmits disabled in the hardware. The bug may show up by repeatedly IFF_DOWN+IFF_UP the interface, which allows e1000_watchdog() interleave with e1000_down(). CPU x CPU y -------------------------------------------------------------------- e1000_down(): netif_carrier_off() e1000_watchdog(): if (carrier == off) { netif_carrier_on(); enable_hw_transmit(); } disable_hw_transmit(); e1000_watchdog(): /* carrier on, do nothing */ Signed-off-by: Vincenzo Maffione Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 98375e1e1185..1982f7917a8d 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -520,8 +520,6 @@ void e1000_down(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; u32 rctl, tctl; - netif_carrier_off(netdev); - /* disable receives in the hardware */ rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); @@ -537,6 +535,15 @@ void e1000_down(struct e1000_adapter *adapter) E1000_WRITE_FLUSH(); msleep(10); + /* Set the carrier off after transmits have been disabled in the + * hardware, to avoid race conditions with e1000_watchdog() (which + * may be running concurrently to us, checking for the carrier + * bit to decide whether it should enable transmits again). Such + * a race condition would result into transmission being disabled + * in the hardware until the next IFF_DOWN+IFF_UP cycle. + */ + netif_carrier_off(netdev); + napi_disable(&adapter->napi); e1000_irq_disable(adapter); -- cgit v1.2.3 From 5983587c8c5ef00d6886477544ad67d495bc5479 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 22 Sep 2017 18:13:48 +0100 Subject: e1000: avoid null pointer dereference on invalid stat type Currently if the stat type is invalid then data[i] is being set either by dereferencing a null pointer p, or it is reading from an incorrect previous location if we had a valid stat type previously. Fix this by skipping over the read of p on an invalid stat type. Detected by CoverityScan, CID#113385 ("Explicit null dereferenced") Signed-off-by: Colin Ian King Reviewed-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index ec8aa4562cc9..3b3983a1ffbb 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -1824,11 +1824,12 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); int i; - char *p = NULL; const struct e1000_stats *stat = e1000_gstrings_stats; e1000_update_stats(adapter); - for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { + for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++, stat++) { + char *p; + switch (stat->type) { case NETDEV_STATS: p = (char *)netdev + stat->stat_offset; @@ -1839,15 +1840,13 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, default: WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n", stat->type, i); - break; + continue; } if (stat->sizeof_stat == sizeof(u64)) data[i] = *(u64 *)p; else data[i] = *(u32 *)p; - - stat++; } /* BUG_ON(i != E1000_STATS_LEN); */ } -- cgit v1.2.3 From 104ba83363d1d42af62abb247f1426c09a80fced Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Thu, 19 Oct 2017 20:07:36 +0100 Subject: igb: Fix TX map failure path When the driver cannot map a TX buffer, instead of rolling back gracefully and retrying later, we currently get a panic: [ 159.885994] igb 0000:00:00.0: TX DMA map failed [ 159.886588] Unable to handle kernel paging request at virtual address ffff00000a08c7a8 ... [ 159.897031] PC is at igb_xmit_frame_ring+0x9c8/0xcb8 Fix the erroneous test that leads to this situation. Signed-off-by: Jean-Philippe Brucker Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index fd4a46b03cc8..ea69af267d63 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -5326,7 +5326,7 @@ dma_error: DMA_TO_DEVICE); dma_unmap_len_set(tx_buffer, len, 0); - if (i--) + if (i-- == 0) i += tx_ring->count; tx_buffer = &tx_ring->tx_buffer_info[i]; } -- cgit v1.2.3 From 069db9cd0bbde92d3aa947ed86a09cbd4ceb5f67 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Oct 2017 17:07:13 -0400 Subject: ixgbe: Fix Tx map failure path This patch is a partial revert of "ixgbe: Don't bother clearing buffer memory for descriptor rings". Specifically I messed up the exception handling path a bit and this resulted in us incorrectly adding the count back in when we didn't need to. In order to make this simpler I am reverting most of the exception handling path change and instead just replacing the bit that was handled by the unmap_and_free call. Fixes: ffed21bcee7a ("ixgbe: Don't bother clearing buffer memory for descriptor rings") Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 4d76afd13868..6d5f31e94358 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -8020,29 +8020,23 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring, return 0; dma_error: dev_err(tx_ring->dev, "TX DMA map failed\n"); - tx_buffer = &tx_ring->tx_buffer_info[i]; /* clear dma mappings for failed tx_buffer_info map */ - while (tx_buffer != first) { + for (;;) { + tx_buffer = &tx_ring->tx_buffer_info[i]; if (dma_unmap_len(tx_buffer, len)) dma_unmap_page(tx_ring->dev, dma_unmap_addr(tx_buffer, dma), dma_unmap_len(tx_buffer, len), DMA_TO_DEVICE); dma_unmap_len_set(tx_buffer, len, 0); - - if (i--) + if (tx_buffer == first) + break; + if (i == 0) i += tx_ring->count; - tx_buffer = &tx_ring->tx_buffer_info[i]; + i--; } - if (dma_unmap_len(tx_buffer, len)) - dma_unmap_single(tx_ring->dev, - dma_unmap_addr(tx_buffer, dma), - dma_unmap_len(tx_buffer, len), - DMA_TO_DEVICE); - dma_unmap_len_set(tx_buffer, len, 0); - dev_kfree_skb_any(first->skb); first->skb = NULL; -- cgit v1.2.3 From 10781348cadebbd5291c8fb193e850365c914da8 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 20 Oct 2017 13:59:20 -0700 Subject: i40e: Fix incorrect use of tx_itr_setting when checking for Rx ITR setup It looks like there was either a copy/paste error or just a typo that resulted in the Tx ITR setting being used to determine if we were using adaptive Rx interrupt moderation or not. This patch fixes the typo. Fixes: 65e87c0398f5 ("i40evf: support queue-specific settings for interrupt moderation") Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 2756131495f0..ab142e05e196 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2269,7 +2269,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi, goto enable_int; } - if (ITR_IS_DYNAMIC(tx_itr_setting)) { + if (ITR_IS_DYNAMIC(rx_itr_setting)) { rx = i40e_set_new_dynamic_itr(&q_vector->rx); rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr); } -- cgit v1.2.3 From 62b4c6694dfd3821bd5ea5bed48238bbabd5fe8b Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 21 Oct 2017 18:12:29 -0700 Subject: i40e: Add programming descriptors to cleaned_count This patch updates the i40e driver to include programming descriptors in the cleaned_count. Without this change it becomes possible for us to leak memory as we don't trigger a large enough allocation when the time comes to allocate new buffers and we end up overwriting a number of rx_buffers equal to the number of programming descriptors we encountered. Fixes: 0e626ff7ccbf ("i40e: Fix support for flow director programming status") Signed-off-by: Alexander Duyck Tested-by: Anders K. Pedersen Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index ab142e05e196..120c68f78951 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2102,6 +2102,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) if (unlikely(i40e_rx_is_programming_status(qword))) { i40e_clean_programming_status(rx_ring, rx_desc, qword); + cleaned_count++; continue; } size = (qword & I40E_RXD_QW1_LENGTH_PBUF_MASK) >> -- cgit v1.2.3 From 8f63fc2bc64716c16e269ab951130eeda78fe37a Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 19 Oct 2017 13:54:06 +0800 Subject: drm/i915/gvt: properly check per_ctx bb valid state Need to check valid state for per_ctx bb and bypass batch buffer combine for scan if necessary. Otherwise adding invalid MI batch buffer start cmd for per_ctx bb will cause scan failure, which is taken as -EFAULT now so vGPU would be put in failsafe. This trys to fix that by checking per_ctx bb valid state. Also remove old invalid WARNING that indirect ctx bb shouldn't depend on valid per_ctx bb. Signed-off-by: Zhenyu Wang Signed-off-by: Zhi Wang --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 3 +++ drivers/gpu/drm/i915/gvt/execlist.c | 3 +-- drivers/gpu/drm/i915/gvt/scheduler.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 21c36e256884..d4726a3358a4 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -2723,6 +2723,9 @@ static int combine_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) uint32_t per_ctx_start[CACHELINE_DWORDS] = {0}; unsigned char *bb_start_sva; + if (!wa_ctx->per_ctx.valid) + return 0; + per_ctx_start[0] = 0x18800001; per_ctx_start[1] = wa_ctx->per_ctx.guest_gma; diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index 91b4300f3b39..e5320b4eb698 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -701,8 +701,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id, CACHELINE_BYTES; workload->wa_ctx.per_ctx.guest_gma = per_ctx & PER_CTX_ADDR_MASK; - - WARN_ON(workload->wa_ctx.indirect_ctx.size && !(per_ctx & 0x1)); + workload->wa_ctx.per_ctx.valid = per_ctx & 1; } if (emulate_schedule_in) diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h index 0d431a968a32..93a49eb0209e 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.h +++ b/drivers/gpu/drm/i915/gvt/scheduler.h @@ -68,6 +68,7 @@ struct shadow_indirect_ctx { struct shadow_per_ctx { unsigned long guest_gma; unsigned long shadow_gma; + unsigned valid; }; struct intel_shadow_wa_ctx { -- cgit v1.2.3 From edee7ecdb4d7311f351feaeb53e269f416bb1b57 Mon Sep 17 00:00:00 2001 From: Zhi Wang Date: Sat, 30 Sep 2017 17:32:16 +0800 Subject: drm/i915/gvt: Refine MMIO_RING_F() Inspect if the host has VCS2 ring by host i915 macro in MMIO_RING_F(). Also this helps on reducing some LOCs. Signed-off-by: Zhi Wang --- drivers/gpu/drm/i915/gvt/handlers.c | 44 ++----------------------------------- drivers/gpu/drm/i915/gvt/reg.h | 3 --- 2 files changed, 2 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 2294466dd415..812f411d1c7d 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1589,6 +1589,8 @@ static int ring_reset_ctl_write(struct intel_vgpu *vgpu, MMIO_F(prefix(BLT_RING_BASE), s, f, am, rm, d, r, w); \ MMIO_F(prefix(GEN6_BSD_RING_BASE), s, f, am, rm, d, r, w); \ MMIO_F(prefix(VEBOX_RING_BASE), s, f, am, rm, d, r, w); \ + if (HAS_BSD2(dev_priv)) \ + MMIO_F(prefix(GEN8_BSD2_RING_BASE), s, f, am, rm, d, r, w); \ } while (0) #define MMIO_RING_D(prefix, d) \ @@ -1636,7 +1638,6 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) #define RING_REG(base) (base + 0x6c) MMIO_RING_DFH(RING_REG, D_ALL, 0, instdone_mmio_read, NULL); - MMIO_DH(RING_REG(GEN8_BSD2_RING_BASE), D_ALL, instdone_mmio_read, NULL); #undef RING_REG MMIO_DH(GEN7_SC_INSTDONE, D_BDW_PLUS, instdone_mmio_read, NULL); @@ -2411,9 +2412,6 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt) struct drm_i915_private *dev_priv = gvt->dev_priv; int ret; - MMIO_DFH(RING_IMR(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS, NULL, - intel_vgpu_reg_imr_handler); - MMIO_DH(GEN8_GT_IMR(0), D_BDW_PLUS, NULL, intel_vgpu_reg_imr_handler); MMIO_DH(GEN8_GT_IER(0), D_BDW_PLUS, NULL, intel_vgpu_reg_ier_handler); MMIO_DH(GEN8_GT_IIR(0), D_BDW_PLUS, NULL, intel_vgpu_reg_iir_handler); @@ -2476,68 +2474,33 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt) MMIO_DH(GEN8_MASTER_IRQ, D_BDW_PLUS, NULL, intel_vgpu_reg_master_irq_handler); - MMIO_DFH(RING_HWSTAM(GEN8_BSD2_RING_BASE), D_BDW_PLUS, - F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(0x1c134, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); - - MMIO_DFH(RING_TAIL(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS, - NULL, NULL); - MMIO_DFH(RING_HEAD(GEN8_BSD2_RING_BASE), D_BDW_PLUS, - F_CMD_ACCESS, NULL, NULL); - MMIO_GM_RDR(RING_START(GEN8_BSD2_RING_BASE), D_BDW_PLUS, NULL, NULL); - MMIO_DFH(RING_CTL(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS, - NULL, NULL); - MMIO_DFH(RING_ACTHD(GEN8_BSD2_RING_BASE), D_BDW_PLUS, - F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(RING_ACTHD_UDW(GEN8_BSD2_RING_BASE), D_BDW_PLUS, - F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(0x1c29c, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, - ring_mode_mmio_write); - MMIO_DFH(RING_MI_MODE(GEN8_BSD2_RING_BASE), D_BDW_PLUS, - F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(RING_INSTPM(GEN8_BSD2_RING_BASE), D_BDW_PLUS, - F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(RING_TIMESTAMP(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS, - ring_timestamp_mmio_read, NULL); - MMIO_RING_DFH(RING_ACTHD_UDW, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); #define RING_REG(base) (base + 0xd0) MMIO_RING_F(RING_REG, 4, F_RO, 0, ~_MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET), D_BDW_PLUS, NULL, ring_reset_ctl_write); - MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 4, F_RO, 0, - ~_MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET), D_BDW_PLUS, NULL, - ring_reset_ctl_write); #undef RING_REG #define RING_REG(base) (base + 0x230) MMIO_RING_DFH(RING_REG, D_BDW_PLUS, 0, NULL, elsp_mmio_write); - MMIO_DH(RING_REG(GEN8_BSD2_RING_BASE), D_BDW_PLUS, NULL, elsp_mmio_write); #undef RING_REG #define RING_REG(base) (base + 0x234) MMIO_RING_F(RING_REG, 8, F_RO | F_CMD_ACCESS, 0, ~0, D_BDW_PLUS, NULL, NULL); - MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 4, F_RO | F_CMD_ACCESS, 0, - ~0LL, D_BDW_PLUS, NULL, NULL); #undef RING_REG #define RING_REG(base) (base + 0x244) MMIO_RING_DFH(RING_REG, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(RING_REG(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS, - NULL, NULL); #undef RING_REG #define RING_REG(base) (base + 0x370) MMIO_RING_F(RING_REG, 48, F_RO, 0, ~0, D_BDW_PLUS, NULL, NULL); - MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 48, F_RO, 0, ~0, D_BDW_PLUS, - NULL, NULL); #undef RING_REG #define RING_REG(base) (base + 0x3a0) MMIO_RING_DFH(RING_REG, D_BDW_PLUS, F_MODE_MASK, NULL, NULL); - MMIO_DFH(RING_REG(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_MODE_MASK, NULL, NULL); #undef RING_REG MMIO_D(PIPEMISC(PIPE_A), D_BDW_PLUS); @@ -2557,11 +2520,9 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt) #define RING_REG(base) (base + 0x270) MMIO_RING_F(RING_REG, 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL); - MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL); #undef RING_REG MMIO_RING_GM_RDR(RING_HWS_PGA, D_BDW_PLUS, NULL, NULL); - MMIO_GM_RDR(RING_HWS_PGA(GEN8_BSD2_RING_BASE), D_BDW_PLUS, NULL, NULL); MMIO_DFH(HDC_CHICKEN0, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); @@ -2849,7 +2810,6 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_D(0x65f08, D_SKL | D_KBL); MMIO_D(0x320f0, D_SKL | D_KBL); - MMIO_DFH(_REG_VCS2_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); MMIO_D(0x70034, D_SKL_PLUS); MMIO_D(0x71034, D_SKL_PLUS); MMIO_D(0x72034, D_SKL_PLUS); diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h index fbd023a16f18..7d01c77a0f7a 100644 --- a/drivers/gpu/drm/i915/gvt/reg.h +++ b/drivers/gpu/drm/i915/gvt/reg.h @@ -54,9 +54,6 @@ #define VGT_SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B) -#define _REG_VECS_EXCC 0x1A028 -#define _REG_VCS2_EXCC 0x1c028 - #define _REG_701C0(pipe, plane) (0x701c0 + pipe * 0x1000 + (plane - 1) * 0x100) #define _REG_701C4(pipe, plane) (0x701c4 + pipe * 0x1000 + (plane - 1) * 0x100) -- cgit v1.2.3 From 20a2bcdec5071f78bebe48c5eecdb89de6e96acb Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Sat, 14 Oct 2017 06:34:46 +0800 Subject: drm/i915/gvt: Extract mmio_read_from_hw() common function The mmio read handler for ring timestmap / instdone register are same as reading hw value directly. Extract it as common function to reduce code duplications. Signed-off-by: Xiong Zhang Signed-off-by: Zhi Wang --- drivers/gpu/drm/i915/gvt/handlers.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 812f411d1c7d..c24341f174d3 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1429,18 +1429,7 @@ static int skl_lcpll_write(struct intel_vgpu *vgpu, unsigned int offset, return 0; } -static int ring_timestamp_mmio_read(struct intel_vgpu *vgpu, - unsigned int offset, void *p_data, unsigned int bytes) -{ - struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; - - mmio_hw_access_pre(dev_priv); - vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset)); - mmio_hw_access_post(dev_priv); - return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); -} - -static int instdone_mmio_read(struct intel_vgpu *vgpu, +static int mmio_read_from_hw(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; @@ -1637,9 +1626,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) #undef RING_REG #define RING_REG(base) (base + 0x6c) - MMIO_RING_DFH(RING_REG, D_ALL, 0, instdone_mmio_read, NULL); + MMIO_RING_DFH(RING_REG, D_ALL, 0, mmio_read_from_hw, NULL); #undef RING_REG - MMIO_DH(GEN7_SC_INSTDONE, D_BDW_PLUS, instdone_mmio_read, NULL); + MMIO_DH(GEN7_SC_INSTDONE, D_BDW_PLUS, mmio_read_from_hw, NULL); MMIO_GM_RDR(0x2148, D_ALL, NULL, NULL); MMIO_GM_RDR(CCID, D_ALL, NULL, NULL); @@ -1663,9 +1652,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_RING_DFH(RING_INSTPM, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); MMIO_RING_DFH(RING_TIMESTAMP, D_ALL, F_CMD_ACCESS, - ring_timestamp_mmio_read, NULL); + mmio_read_from_hw, NULL); MMIO_RING_DFH(RING_TIMESTAMP_UDW, D_ALL, F_CMD_ACCESS, - ring_timestamp_mmio_read, NULL); + mmio_read_from_hw, NULL); MMIO_DFH(GEN7_GT_MODE, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); MMIO_DFH(CACHE_MODE_0_GEN7, D_ALL, F_MODE_MASK | F_CMD_ACCESS, -- cgit v1.2.3 From 894e287b3dcc8bfc8d974f883dab3b5c66344089 Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Sat, 14 Oct 2017 06:34:47 +0800 Subject: drm/i915/gvt: Adding ACTHD mmio read handler When a workload is too heavy to finish it in gpu hang check timer intervals(1.5), gpu hang check function will check ACTHD register value to decide whether gpu is real dead or not. On real hw, ACTHD is updated by HW when workload is running, then host kernel won't think it is gpu hang. while guest kernel always read a constant ACTHD value as GVT doesn't supply ACTHD emulate handler, then guest kernel detects a fake gpu hang. To remove such guest fake gpu hang, this patch supply ACTHD mmio read handler which read real HW ACTHD register directly. Signed-off-by: Xiong Zhang Signed-off-by: Zhi Wang Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/b4c9a097-3e62-124e-6856-b0c37764df7b@intel.com --- drivers/gpu/drm/i915/gvt/handlers.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index c24341f174d3..a5bed2e71b92 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1638,7 +1638,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_RING_DFH(RING_TAIL, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_RING_DFH(RING_HEAD, D_ALL, F_CMD_ACCESS, NULL, NULL); MMIO_RING_DFH(RING_CTL, D_ALL, F_CMD_ACCESS, NULL, NULL); - MMIO_RING_DFH(RING_ACTHD, D_ALL, F_CMD_ACCESS, NULL, NULL); + MMIO_RING_DFH(RING_ACTHD, D_ALL, F_CMD_ACCESS, mmio_read_from_hw, NULL); MMIO_RING_GM_RDR(RING_START, D_ALL, NULL, NULL); /* RING MODE */ @@ -2463,7 +2463,8 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt) MMIO_DH(GEN8_MASTER_IRQ, D_BDW_PLUS, NULL, intel_vgpu_reg_master_irq_handler); - MMIO_RING_DFH(RING_ACTHD_UDW, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL); + MMIO_RING_DFH(RING_ACTHD_UDW, D_BDW_PLUS, F_CMD_ACCESS, + mmio_read_from_hw, NULL); #define RING_REG(base) (base + 0xd0) MMIO_RING_F(RING_REG, 4, F_RO, 0, -- cgit v1.2.3 From 4894ac6b6c25b2693dc21c611621dc9fd21f4090 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Thu, 26 Oct 2017 09:51:33 +0100 Subject: net: stmmac: dwc-qos-eth: Fix typo in DT bindings parsing According to DT bindings documentation we are expecting a property called "snps,read-requests" but we are parsing instead a property called "read,read-requests". This is clearly a typo. Fix it. Signed-off-by: Jose Abreu Cc: Joao Pinto Cc: David S. Miller Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c index 5efef8001edf..3256e5cbad27 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c @@ -74,7 +74,7 @@ static int dwc_eth_dwmac_config_dt(struct platform_device *pdev, plat_dat->axi->axi_wr_osr_lmt--; } - if (of_property_read_u32(np, "read,read-requests", + if (of_property_read_u32(np, "snps,read-requests", &plat_dat->axi->axi_rd_osr_lmt)) { /** * Since the register has a reset value of 1, if property -- cgit v1.2.3 From 6d9f0790af8d33476f936ac84a07cac42f808f6c Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Thu, 26 Oct 2017 10:07:12 +0100 Subject: net: stmmac: First Queue must always be in DCB mode According to DWMAC databook the first queue operating mode must always be in DCB. As MTL_QUEUE_DCB = 1, we need to always set the first queue operating mode to DCB otherwise driver will think that queue is in AVB mode (because MTL_QUEUE_AVB = 0). Signed-off-by: Jose Abreu Cc: Joao Pinto Cc: David S. Miller Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 8a280b48e3a9..6383695004a5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -150,6 +150,13 @@ static void stmmac_mtl_setup(struct platform_device *pdev, plat->rx_queues_to_use = 1; plat->tx_queues_to_use = 1; + /* First Queue must always be in DCB mode. As MTL_QUEUE_DCB = 1 we need + * to always set this, otherwise Queue will be classified as AVB + * (because MTL_QUEUE_AVB = 0). + */ + plat->rx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB; + plat->tx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB; + rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0); if (!rx_node) return; -- cgit v1.2.3 From b73b6e8094523d8440a48a15feb7684141e4b140 Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Fri, 27 Oct 2017 15:24:38 -0400 Subject: drm/amd/powerplay: change ASIC temperature reading on Vega10 ASIC temperature reading from HOTSPOT to ASIC edge which makes things consistent with previous asics. Signed-off-by: Eric Huang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c index 1feefac49ea9..dc3761bcb9b6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c @@ -365,8 +365,8 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr) temp = cgs_read_register(hwmgr->device, reg); - temp = (temp & CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK) >> - CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP__SHIFT; + temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >> + CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT; temp = temp & 0x1ff; -- cgit v1.2.3 From a50829479f58416a013a4ccca791336af3c584c7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 23 Oct 2017 16:46:00 -0700 Subject: Input: gtco - fix potential out-of-bound access parse_hid_report_descriptor() has a while (i < length) loop, which only guarantees that there's at least 1 byte in the buffer, but the loop body can read multiple bytes which causes out-of-bounds access. Reported-by: Andrey Konovalov Reviewed-by: Andrey Konovalov Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/gtco.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index b796e891e2ee..4b8b9d7aa75e 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c @@ -230,13 +230,17 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, /* Walk this report and pull out the info we need */ while (i < length) { - prefix = report[i]; - - /* Skip over prefix */ - i++; + prefix = report[i++]; /* Determine data size and save the data in the proper variable */ - size = PREF_SIZE(prefix); + size = (1U << PREF_SIZE(prefix)) >> 1; + if (i + size > length) { + dev_err(ddev, + "Not enough data (need %d, have %d)\n", + i + size, length); + break; + } + switch (size) { case 1: data = report[i]; @@ -244,8 +248,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, case 2: data16 = get_unaligned_le16(&report[i]); break; - case 3: - size = 4; + case 4: data32 = get_unaligned_le32(&report[i]); break; } -- cgit v1.2.3 From 3e64fcbdbd10e46dede502d507dbcc104837cd59 Mon Sep 17 00:00:00 2001 From: Andrew Duggan Date: Wed, 25 Oct 2017 09:30:16 -0700 Subject: Input: synaptics-rmi4 - limit the range of what GPIOs are buttons By convention the first 6 bits of F30 Ctrl 2 and 3 are used to signify GPIOs which are connected to buttons. Additional GPIOs may be used as input GPIOs to signal the touch controller of some event (ie disable touchpad). These additional GPIOs may meet the criteria of a button in rmi_f30_is_valid_button() but should not be considered buttons. This patch limits the GPIOs which are mapped to buttons to just the first 6. Signed-off-by: Andrew Duggan Reported-by: Daniel Martin Tested-by: Daniel Martin Acked-By: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f30.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c index 34dfee555b20..82e0f0d43d55 100644 --- a/drivers/input/rmi4/rmi_f30.c +++ b/drivers/input/rmi4/rmi_f30.c @@ -232,9 +232,10 @@ static int rmi_f30_map_gpios(struct rmi_function *fn, unsigned int trackstick_button = BTN_LEFT; bool button_mapped = false; int i; + int button_count = min_t(u8, f30->gpioled_count, TRACKSTICK_RANGE_END); f30->gpioled_key_map = devm_kcalloc(&fn->dev, - f30->gpioled_count, + button_count, sizeof(f30->gpioled_key_map[0]), GFP_KERNEL); if (!f30->gpioled_key_map) { @@ -242,7 +243,7 @@ static int rmi_f30_map_gpios(struct rmi_function *fn, return -ENOMEM; } - for (i = 0; i < f30->gpioled_count; i++) { + for (i = 0; i < button_count; i++) { if (!rmi_f30_is_valid_button(i, f30->ctrl)) continue; -- cgit v1.2.3 From 66b783b4465de05ce6b370b1ae97e95b0fc14a34 Mon Sep 17 00:00:00 2001 From: Besar Wicaksono Date: Fri, 27 Oct 2017 19:35:18 -0400 Subject: drm/amdkfd: Add SDMA trap src id to the KFD isr wanted list This enables SDMA signalling with event interrupt. Signed-off-by: Besar Wicaksono Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c | 3 +++ drivers/gpu/drm/amd/amdkfd/cik_int.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c index 211fc48697fa..66164aa67c66 100644 --- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c @@ -36,6 +36,7 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev, /* Do not process in ISR, just request it to be forwarded to WQ. */ return (pasid != 0) && (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE || + ihre->source_id == CIK_INTSRC_SDMA_TRAP || ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG || ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE); } @@ -54,6 +55,8 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev, if (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE) kfd_signal_event_interrupt(pasid, 0, 0); + else if (ihre->source_id == CIK_INTSRC_SDMA_TRAP) + kfd_signal_event_interrupt(pasid, 0, 0); else if (ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG) kfd_signal_event_interrupt(pasid, ihre->data & 0xFF, 8); else if (ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE) diff --git a/drivers/gpu/drm/amd/amdkfd/cik_int.h b/drivers/gpu/drm/amd/amdkfd/cik_int.h index 79a16d24c1b8..109298b9d507 100644 --- a/drivers/gpu/drm/amd/amdkfd/cik_int.h +++ b/drivers/gpu/drm/amd/amdkfd/cik_int.h @@ -32,9 +32,10 @@ struct cik_ih_ring_entry { uint32_t reserved; }; -#define CIK_INTSRC_DEQUEUE_COMPLETE 0xC6 #define CIK_INTSRC_CP_END_OF_PIPE 0xB5 #define CIK_INTSRC_CP_BAD_OPCODE 0xB7 +#define CIK_INTSRC_DEQUEUE_COMPLETE 0xC6 +#define CIK_INTSRC_SDMA_TRAP 0xE0 #define CIK_INTSRC_SQ_INTERRUPT_MSG 0xEF #endif -- cgit v1.2.3 From 9b56bb115460cee92a80bf85232b4b7da2f080e6 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:19 -0400 Subject: drm/amdkfd: Don't dereference kfd_process.mm The kfd_process doesn't own a reference to the mm_struct, so it can disappear without warning even while the kfd_process still exists. Therefore, avoid dereferencing the kfd_process.mm pointer and make it opaque. Use get_task_mm to get a temporary reference to the mm when it's needed. v2: removed unnecessary WARN_ON Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 19 +++++++++++++++---- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 7 ++++++- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 1 - 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 944abfad39c1..61ce5476c055 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include #include #include #include "kfd_priv.h" @@ -904,14 +904,24 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, unsigned int pasid, * running so the lookup function returns a locked process. */ struct kfd_process *p = kfd_lookup_process_by_pasid(pasid); + struct mm_struct *mm; if (!p) return; /* Presumably process exited. */ + /* Take a safe reference to the mm_struct, which may otherwise + * disappear even while the kfd_process is still referenced. + */ + mm = get_task_mm(p->lead_thread); + if (!mm) { + mutex_unlock(&p->mutex); + return; /* Process is exiting */ + } + memset(&memory_exception_data, 0, sizeof(memory_exception_data)); - down_read(&p->mm->mmap_sem); - vma = find_vma(p->mm, address); + down_read(&mm->mmap_sem); + vma = find_vma(mm, address); memory_exception_data.gpu_id = dev->id; memory_exception_data.va = address; @@ -937,7 +947,8 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, unsigned int pasid, } } - up_read(&p->mm->mmap_sem); + up_read(&mm->mmap_sem); + mmput(mm); mutex_lock(&p->event_mutex); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 7d86ec9790d3..1a483a7ecd4e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -494,7 +494,12 @@ struct kfd_process { */ struct hlist_node kfd_processes; - struct mm_struct *mm; + /* + * Opaque pointer to mm_struct. We don't hold a reference to + * it so it should never be dereferenced from here. This is + * only used for looking up processes by their mm. + */ + void *mm; struct mutex mutex; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 3ccb3b53216e..695fa2ae8e5b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -200,7 +200,6 @@ static void kfd_process_destroy_delayed(struct rcu_head *rcu) struct kfd_process *p; p = container_of(rcu, struct kfd_process, rcu); - WARN_ON(atomic_read(&p->mm->mm_count) <= 0); mmdrop(p->mm); -- cgit v1.2.3 From 1f9d09becb9aa6ddc67a44391f05cb96bfab80df Mon Sep 17 00:00:00 2001 From: Sean Keely Date: Fri, 27 Oct 2017 19:35:20 -0400 Subject: drm/amdkfd: Short cut for kfd_wait_on_events without waiting If kfd_wait_on_events can return immediately, we don't need to populate the wait list and don't need to enter the sleep-loop. Signed-off-by: Sean Keely Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 43 ++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 61ce5476c055..f3d88c833135 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -617,7 +617,7 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events) return event_waiters; } -static int init_event_waiter(struct kfd_process *p, +static int init_event_waiter_get_status(struct kfd_process *p, struct kfd_event_waiter *waiter, uint32_t event_id, uint32_t input_index) @@ -632,11 +632,20 @@ static int init_event_waiter(struct kfd_process *p, waiter->activated = ev->signaled; ev->signaled = ev->signaled && !ev->auto_reset; - list_add(&waiter->waiters, &ev->waiters); - return 0; } +static void init_event_waiter_add_to_waitlist(struct kfd_event_waiter *waiter) +{ + struct kfd_event *ev = waiter->event; + + /* Only add to the wait list if we actually need to + * wait on this event. + */ + if (!waiter->activated) + list_add(&waiter->waiters, &ev->waiters); +} + static bool test_event_condition(bool all, uint32_t num_events, struct kfd_event_waiter *event_waiters) { @@ -724,11 +733,17 @@ int kfd_wait_on_events(struct kfd_process *p, (struct kfd_event_data __user *) data; uint32_t i; int ret = 0; + struct kfd_event_waiter *event_waiters = NULL; long timeout = user_timeout_to_jiffies(user_timeout_ms); mutex_lock(&p->event_mutex); + /* Set to something unreasonable - this is really + * just a bool for now. + */ + *wait_result = KFD_WAIT_TIMEOUT; + event_waiters = alloc_event_waiters(num_events); if (!event_waiters) { ret = -ENOMEM; @@ -744,14 +759,34 @@ int kfd_wait_on_events(struct kfd_process *p, goto fail; } - ret = init_event_waiter(p, &event_waiters[i], + ret = init_event_waiter_get_status(p, &event_waiters[i], event_data.event_id, i); if (ret) goto fail; } + /* Check condition once. */ + if (test_event_condition(all, num_events, event_waiters)) { + if (copy_signaled_event_data(num_events, + event_waiters, events)) + *wait_result = KFD_WAIT_COMPLETE; + else + *wait_result = KFD_WAIT_ERROR; + free_waiters(num_events, event_waiters); + } else { + /* Add to wait lists if we need to wait. */ + for (i = 0; i < num_events; i++) + init_event_waiter_add_to_waitlist(&event_waiters[i]); + } + mutex_unlock(&p->event_mutex); + /* Return if all waits were already satisfied. */ + if (*wait_result != KFD_WAIT_TIMEOUT) { + __set_current_state(TASK_RUNNING); + return ret; + } + while (true) { if (fatal_signal_pending(current)) { ret = -EINTR; -- cgit v1.2.3 From d9aeec4cbb58599008e6dd4cc23f5bfbdbd0f4ff Mon Sep 17 00:00:00 2001 From: Sean Keely Date: Fri, 27 Oct 2017 19:35:21 -0400 Subject: drm/amdkfd: Fix scheduler race in kfd_wait_on_events sleep loop Signed-off-by: Sean Keely Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index f3d88c833135..1efd6a8c2a40 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -806,6 +806,17 @@ int kfd_wait_on_events(struct kfd_process *p, break; } + /* Set task state to interruptible sleep before + * checking wake-up conditions. A concurrent wake-up + * will put the task back into runnable state. In that + * case schedule_timeout will not put the task to + * sleep and we'll get a chance to re-check the + * updated conditions almost immediately. Otherwise, + * this race condition would lead to a soft hang or a + * very long sleep. + */ + set_current_state(TASK_INTERRUPTIBLE); + if (test_event_condition(all, num_events, event_waiters)) { if (copy_signaled_event_data(num_events, event_waiters, events)) @@ -820,7 +831,7 @@ int kfd_wait_on_events(struct kfd_process *p, break; } - timeout = schedule_timeout_interruptible(timeout); + timeout = schedule_timeout(timeout); } __set_current_state(TASK_RUNNING); -- cgit v1.2.3 From fdf0c8332a0309ac619e22e82b6014c77b2a3518 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:22 -0400 Subject: drm/amdkfd: Clean up kfd_wait_on_events Cleaned up the code while resolving some potential bugs and inconsistencies in the process. Clean-ups: * Remove enum kfd_event_wait_result, which duplicates KFD_IOC_EVENT_RESULT definitions * alloc_event_waiters can be called without holding p->event_mutex * Return an error code from copy_signaled_event_data instead of bool * Clean up error handling code paths to minimize duplication in kfd_wait_on_events Fixes: * Consistently return an error code from kfd_wait_on_events and set wait_result to KFD_IOC_WAIT_RESULT_FAIL in all failure cases. * Always call free_waiters while holding p->event_mutex * copy_signaled_event_data might sleep. Don't call it while the task state is TASK_INTERRUPTIBLE. Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 5 +-- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 71 ++++++++++++++------------------ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 8 +--- 3 files changed, 32 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 0ef82b229754..a25321ff448f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -835,15 +835,12 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p, void *data) { struct kfd_ioctl_wait_events_args *args = data; - enum kfd_event_wait_result wait_result; int err; err = kfd_wait_on_events(p, args->num_events, (void __user *)args->events_ptr, (args->wait_for_all != 0), - args->timeout, &wait_result); - - args->wait_result = wait_result; + args->timeout, &args->wait_result); return err; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 1efd6a8c2a40..33cafbb96520 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -668,7 +668,7 @@ static bool test_event_condition(bool all, uint32_t num_events, * Copy event specific data, if defined. * Currently only memory exception events have additional data to copy to user */ -static bool copy_signaled_event_data(uint32_t num_events, +static int copy_signaled_event_data(uint32_t num_events, struct kfd_event_waiter *event_waiters, struct kfd_event_data __user *data) { @@ -686,11 +686,11 @@ static bool copy_signaled_event_data(uint32_t num_events, src = &event->memory_exception_data; if (copy_to_user(dst, src, sizeof(struct kfd_hsa_memory_exception_data))) - return false; + return -EFAULT; } } - return true; + return 0; } @@ -727,7 +727,7 @@ static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters) int kfd_wait_on_events(struct kfd_process *p, uint32_t num_events, void __user *data, bool all, uint32_t user_timeout_ms, - enum kfd_event_wait_result *wait_result) + uint32_t *wait_result) { struct kfd_event_data __user *events = (struct kfd_event_data __user *) data; @@ -737,18 +737,18 @@ int kfd_wait_on_events(struct kfd_process *p, struct kfd_event_waiter *event_waiters = NULL; long timeout = user_timeout_to_jiffies(user_timeout_ms); + event_waiters = alloc_event_waiters(num_events); + if (!event_waiters) { + ret = -ENOMEM; + goto out; + } + mutex_lock(&p->event_mutex); /* Set to something unreasonable - this is really * just a bool for now. */ - *wait_result = KFD_WAIT_TIMEOUT; - - event_waiters = alloc_event_waiters(num_events); - if (!event_waiters) { - ret = -ENOMEM; - goto fail; - } + *wait_result = KFD_IOC_WAIT_RESULT_TIMEOUT; for (i = 0; i < num_events; i++) { struct kfd_event_data event_data; @@ -756,23 +756,21 @@ int kfd_wait_on_events(struct kfd_process *p, if (copy_from_user(&event_data, &events[i], sizeof(struct kfd_event_data))) { ret = -EFAULT; - goto fail; + goto out_unlock; } ret = init_event_waiter_get_status(p, &event_waiters[i], event_data.event_id, i); if (ret) - goto fail; + goto out_unlock; } /* Check condition once. */ if (test_event_condition(all, num_events, event_waiters)) { - if (copy_signaled_event_data(num_events, - event_waiters, events)) - *wait_result = KFD_WAIT_COMPLETE; - else - *wait_result = KFD_WAIT_ERROR; - free_waiters(num_events, event_waiters); + *wait_result = KFD_IOC_WAIT_RESULT_COMPLETE; + ret = copy_signaled_event_data(num_events, + event_waiters, events); + goto out_unlock; } else { /* Add to wait lists if we need to wait. */ for (i = 0; i < num_events; i++) @@ -781,12 +779,6 @@ int kfd_wait_on_events(struct kfd_process *p, mutex_unlock(&p->event_mutex); - /* Return if all waits were already satisfied. */ - if (*wait_result != KFD_WAIT_TIMEOUT) { - __set_current_state(TASK_RUNNING); - return ret; - } - while (true) { if (fatal_signal_pending(current)) { ret = -EINTR; @@ -818,16 +810,12 @@ int kfd_wait_on_events(struct kfd_process *p, set_current_state(TASK_INTERRUPTIBLE); if (test_event_condition(all, num_events, event_waiters)) { - if (copy_signaled_event_data(num_events, - event_waiters, events)) - *wait_result = KFD_WAIT_COMPLETE; - else - *wait_result = KFD_WAIT_ERROR; + *wait_result = KFD_IOC_WAIT_RESULT_COMPLETE; break; } if (timeout <= 0) { - *wait_result = KFD_WAIT_TIMEOUT; + *wait_result = KFD_IOC_WAIT_RESULT_TIMEOUT; break; } @@ -835,19 +823,20 @@ int kfd_wait_on_events(struct kfd_process *p, } __set_current_state(TASK_RUNNING); + /* copy_signaled_event_data may sleep. So this has to happen + * after the task state is set back to RUNNING. + */ + if (!ret && *wait_result == KFD_IOC_WAIT_RESULT_COMPLETE) + ret = copy_signaled_event_data(num_events, + event_waiters, events); + mutex_lock(&p->event_mutex); +out_unlock: free_waiters(num_events, event_waiters); mutex_unlock(&p->event_mutex); - - return ret; - -fail: - if (event_waiters) - free_waiters(num_events, event_waiters); - - mutex_unlock(&p->event_mutex); - - *wait_result = KFD_WAIT_ERROR; +out: + if (ret) + *wait_result = KFD_IOC_WAIT_RESULT_FAIL; return ret; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 1a483a7ecd4e..d3cf53a50ced 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -726,19 +726,13 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd); extern const struct kfd_event_interrupt_class event_interrupt_class_cik; extern const struct kfd_device_global_init_class device_global_init_class_cik; -enum kfd_event_wait_result { - KFD_WAIT_COMPLETE, - KFD_WAIT_TIMEOUT, - KFD_WAIT_ERROR -}; - void kfd_event_init_process(struct kfd_process *p); void kfd_event_free_process(struct kfd_process *p); int kfd_event_mmap(struct kfd_process *process, struct vm_area_struct *vma); int kfd_wait_on_events(struct kfd_process *p, uint32_t num_events, void __user *data, bool all, uint32_t user_timeout_ms, - enum kfd_event_wait_result *wait_result); + uint32_t *wait_result); void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, uint32_t valid_id_bits); void kfd_signal_iommu_event(struct kfd_dev *dev, -- cgit v1.2.3 From fe528c13acc764965929b7fcb5fadf2c15b57373 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:23 -0400 Subject: drm/amdkfd: Fix event destruction with pending waiters When an event with pending waiters is destroyed, those waiters may end up sleeping forever unless they are notified and woken up. Implement the notification by clearing the waiter->event pointer, which becomes invalid anyway, when the event is freed, and waking up the waiting tasks. Waiters on an event that's destroyed return failure. Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 72 +++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 33cafbb96520..2f0fe124ce08 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -345,18 +345,24 @@ void kfd_event_init_process(struct kfd_process *p) static void destroy_event(struct kfd_process *p, struct kfd_event *ev) { + /* Wake up pending waiters. They will return failure */ + while (!list_empty(&ev->waiters)) { + struct kfd_event_waiter *waiter = + list_first_entry(&ev->waiters, struct kfd_event_waiter, + waiters); + + waiter->event = NULL; + /* _init because free_waiters will call list_del */ + list_del_init(&waiter->waiters); + wake_up_process(waiter->sleeping_task); + } + if (ev->signal_page) { release_event_notification_slot(ev->signal_page, ev->signal_slot_index); p->signal_event_count--; } - /* - * Abandon the list of waiters. Individual waiting threads will - * clean up their own data. - */ - list_del(&ev->waiters); - hash_del(&ev->events); kfree(ev); } @@ -646,22 +652,36 @@ static void init_event_waiter_add_to_waitlist(struct kfd_event_waiter *waiter) list_add(&waiter->waiters, &ev->waiters); } -static bool test_event_condition(bool all, uint32_t num_events, +/* test_event_condition - Test condition of events being waited for + * @all: Return completion only if all events have signaled + * @num_events: Number of events to wait for + * @event_waiters: Array of event waiters, one per event + * + * Returns KFD_IOC_WAIT_RESULT_COMPLETE if all (or one) event(s) have + * signaled. Returns KFD_IOC_WAIT_RESULT_TIMEOUT if no (or not all) + * events have signaled. Returns KFD_IOC_WAIT_RESULT_FAIL if any of + * the events have been destroyed. + */ +static uint32_t test_event_condition(bool all, uint32_t num_events, struct kfd_event_waiter *event_waiters) { uint32_t i; uint32_t activated_count = 0; for (i = 0; i < num_events; i++) { + if (!event_waiters[i].event) + return KFD_IOC_WAIT_RESULT_FAIL; + if (event_waiters[i].activated) { if (!all) - return true; + return KFD_IOC_WAIT_RESULT_COMPLETE; activated_count++; } } - return activated_count == num_events; + return activated_count == num_events ? + KFD_IOC_WAIT_RESULT_COMPLETE : KFD_IOC_WAIT_RESULT_TIMEOUT; } /* @@ -745,11 +765,6 @@ int kfd_wait_on_events(struct kfd_process *p, mutex_lock(&p->event_mutex); - /* Set to something unreasonable - this is really - * just a bool for now. - */ - *wait_result = KFD_IOC_WAIT_RESULT_TIMEOUT; - for (i = 0; i < num_events; i++) { struct kfd_event_data event_data; @@ -766,17 +781,22 @@ int kfd_wait_on_events(struct kfd_process *p, } /* Check condition once. */ - if (test_event_condition(all, num_events, event_waiters)) { - *wait_result = KFD_IOC_WAIT_RESULT_COMPLETE; + *wait_result = test_event_condition(all, num_events, event_waiters); + if (*wait_result == KFD_IOC_WAIT_RESULT_COMPLETE) { ret = copy_signaled_event_data(num_events, event_waiters, events); goto out_unlock; - } else { - /* Add to wait lists if we need to wait. */ - for (i = 0; i < num_events; i++) - init_event_waiter_add_to_waitlist(&event_waiters[i]); + } else if (WARN_ON(*wait_result == KFD_IOC_WAIT_RESULT_FAIL)) { + /* This should not happen. Events shouldn't be + * destroyed while we're holding the event_mutex + */ + goto out_unlock; } + /* Add to wait lists if we need to wait. */ + for (i = 0; i < num_events; i++) + init_event_waiter_add_to_waitlist(&event_waiters[i]); + mutex_unlock(&p->event_mutex); while (true) { @@ -809,15 +829,13 @@ int kfd_wait_on_events(struct kfd_process *p, */ set_current_state(TASK_INTERRUPTIBLE); - if (test_event_condition(all, num_events, event_waiters)) { - *wait_result = KFD_IOC_WAIT_RESULT_COMPLETE; + *wait_result = test_event_condition(all, num_events, + event_waiters); + if (*wait_result != KFD_IOC_WAIT_RESULT_TIMEOUT) break; - } - if (timeout <= 0) { - *wait_result = KFD_IOC_WAIT_RESULT_TIMEOUT; + if (timeout <= 0) break; - } timeout = schedule_timeout(timeout); } @@ -837,6 +855,8 @@ out_unlock: out: if (ret) *wait_result = KFD_IOC_WAIT_RESULT_FAIL; + else if (*wait_result == KFD_IOC_WAIT_RESULT_FAIL) + ret = -EIO; return ret; } -- cgit v1.2.3 From ebf947fe93dd3627774f6bb4daa57b4e2897929d Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:24 -0400 Subject: drm/amdkfd: remove redundant kfd_event_waiter.input_index This always identical with the index of the event_waiter in the array. No need to store it in the waiter record. Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 2f0fe124ce08..b4cda9256225 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -49,7 +49,6 @@ struct kfd_event_waiter { /* Event */ struct kfd_event *event; - uint32_t input_index; }; /* @@ -625,8 +624,7 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events) static int init_event_waiter_get_status(struct kfd_process *p, struct kfd_event_waiter *waiter, - uint32_t event_id, - uint32_t input_index) + uint32_t event_id) { struct kfd_event *ev = lookup_event_by_id(p, event_id); @@ -634,7 +632,6 @@ static int init_event_waiter_get_status(struct kfd_process *p, return -EINVAL; waiter->event = ev; - waiter->input_index = input_index; waiter->activated = ev->signaled; ev->signaled = ev->signaled && !ev->auto_reset; @@ -702,7 +699,7 @@ static int copy_signaled_event_data(uint32_t num_events, waiter = &event_waiters[i]; event = waiter->event; if (waiter->activated && event->type == KFD_EVENT_TYPE_MEMORY) { - dst = &data[waiter->input_index].memory_exception_data; + dst = &data[i].memory_exception_data; src = &event->memory_exception_data; if (copy_to_user(dst, src, sizeof(struct kfd_hsa_memory_exception_data))) @@ -775,7 +772,7 @@ int kfd_wait_on_events(struct kfd_process *p, } ret = init_event_waiter_get_status(p, &event_waiters[i], - event_data.event_id, i); + event_data.event_id); if (ret) goto out_unlock; } -- cgit v1.2.3 From 74e4071665da243e0ff1b7a0e1b8ac7d89cdb3ca Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:25 -0400 Subject: drm/amdkfd: Use wait_queue_t to implement event waiting Use standard wait queues for waiting and waking up waiting threads instead of inventing our own. We still have our own wait loop because the HSA event semantics require the ability to have one thread waiting on multiple wait queues (events) at the same time. Signed-off-by: Kent Russell Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 59 ++++++++++++--------------------- drivers/gpu/drm/amd/amdkfd/kfd_events.h | 3 +- 2 files changed, 24 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index b4cda9256225..7dae26f0e11a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -33,22 +33,12 @@ #include /* - * A task can only be on a single wait_queue at a time, but we need to support - * waiting on multiple events (any/all). - * Instead of each event simply having a wait_queue with sleeping tasks, it - * has a singly-linked list of tasks. - * A thread that wants to sleep creates an array of these, one for each event - * and adds one to each event's waiter chain. + * Wrapper around wait_queue_entry_t */ struct kfd_event_waiter { - struct list_head waiters; - struct task_struct *sleeping_task; - - /* Transitions to true when the event this belongs to is signaled. */ - bool activated; - - /* Event */ - struct kfd_event *event; + wait_queue_entry_t wait; + struct kfd_event *event; /* Event to wait for */ + bool activated; /* Becomes true when event is signaled */ }; /* @@ -344,17 +334,12 @@ void kfd_event_init_process(struct kfd_process *p) static void destroy_event(struct kfd_process *p, struct kfd_event *ev) { - /* Wake up pending waiters. They will return failure */ - while (!list_empty(&ev->waiters)) { - struct kfd_event_waiter *waiter = - list_first_entry(&ev->waiters, struct kfd_event_waiter, - waiters); + struct kfd_event_waiter *waiter; + /* Wake up pending waiters. They will return failure */ + list_for_each_entry(waiter, &ev->wq.head, wait.entry) waiter->event = NULL; - /* _init because free_waiters will call list_del */ - list_del_init(&waiter->waiters); - wake_up_process(waiter->sleeping_task); - } + wake_up_all(&ev->wq); if (ev->signal_page) { release_event_notification_slot(ev->signal_page, @@ -424,7 +409,7 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p, ev->auto_reset = auto_reset; ev->signaled = false; - INIT_LIST_HEAD(&ev->waiters); + init_waitqueue_head(&ev->wq); *event_page_offset = 0; @@ -482,19 +467,18 @@ int kfd_event_destroy(struct kfd_process *p, uint32_t event_id) static void set_event(struct kfd_event *ev) { struct kfd_event_waiter *waiter; - struct kfd_event_waiter *next; - /* Auto reset if the list is non-empty and we're waking someone. */ - ev->signaled = !ev->auto_reset || list_empty(&ev->waiters); + /* Auto reset if the list is non-empty and we're waking + * someone. waitqueue_active is safe here because we're + * protected by the p->event_mutex, which is also held when + * updating the wait queues in kfd_wait_on_events. + */ + ev->signaled = !ev->auto_reset || !waitqueue_active(&ev->wq); - list_for_each_entry_safe(waiter, next, &ev->waiters, waiters) { + list_for_each_entry(waiter, &ev->wq.head, wait.entry) waiter->activated = true; - /* _init because free_waiters will call list_del */ - list_del_init(&waiter->waiters); - - wake_up_process(waiter->sleeping_task); - } + wake_up_all(&ev->wq); } /* Assumes that p is current. */ @@ -614,8 +598,7 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events) GFP_KERNEL); for (i = 0; (event_waiters) && (i < num_events) ; i++) { - INIT_LIST_HEAD(&event_waiters[i].waiters); - event_waiters[i].sleeping_task = current; + init_wait(&event_waiters[i].wait); event_waiters[i].activated = false; } @@ -646,7 +629,7 @@ static void init_event_waiter_add_to_waitlist(struct kfd_event_waiter *waiter) * wait on this event. */ if (!waiter->activated) - list_add(&waiter->waiters, &ev->waiters); + add_wait_queue(&ev->wq, &waiter->wait); } /* test_event_condition - Test condition of events being waited for @@ -736,7 +719,9 @@ static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters) uint32_t i; for (i = 0; i < num_events; i++) - list_del(&waiters[i].waiters); + if (waiters[i].event) + remove_wait_queue(&waiters[i].event->wq, + &waiters[i].wait); kfree(waiters); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.h b/drivers/gpu/drm/amd/amdkfd/kfd_events.h index 28f6838b1f4c..96f9122805fa 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.h @@ -27,6 +27,7 @@ #include #include #include +#include #include "kfd_priv.h" #include @@ -56,7 +57,7 @@ struct kfd_event { int type; - struct list_head waiters; /* List of kfd_event_waiter by waiters. */ + wait_queue_head_t wq; /* List of event waiters. */ /* Only for signal events. */ struct signal_page *signal_page; -- cgit v1.2.3 From 50cb7dd94cb43a6204813376e1be1d21780b71fb Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:26 -0400 Subject: drm/amdkfd: Simplify events page allocator The first event page is always big enough to handle all events. Handling of multiple events pages is not supported by user mode, and not necessary. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 197 +++++++++++--------------------- drivers/gpu/drm/amd/amdkfd/kfd_events.h | 1 - drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 4 +- 3 files changed, 70 insertions(+), 132 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 7dae26f0e11a..7cc17107f448 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -41,6 +41,9 @@ struct kfd_event_waiter { bool activated; /* Becomes true when event is signaled */ }; +#define SLOTS_PER_PAGE KFD_SIGNAL_EVENT_LIMIT +#define SLOT_BITMAP_LONGS BITS_TO_LONGS(SLOTS_PER_PAGE) + /* * Over-complicated pooled allocator for event notification slots. * @@ -51,132 +54,98 @@ struct kfd_event_waiter { * Individual signal events are then allocated a slot in a page. */ -struct signal_page { - struct list_head event_pages; /* kfd_process.signal_event_pages */ +struct kfd_signal_page { uint64_t *kernel_address; uint64_t __user *user_address; - uint32_t page_index; /* Index into the mmap aperture. */ unsigned int free_slots; - unsigned long used_slot_bitmap[0]; + unsigned long used_slot_bitmap[SLOT_BITMAP_LONGS]; }; -#define SLOTS_PER_PAGE KFD_SIGNAL_EVENT_LIMIT -#define SLOT_BITMAP_SIZE BITS_TO_LONGS(SLOTS_PER_PAGE) -#define BITS_PER_PAGE (ilog2(SLOTS_PER_PAGE)+1) -#define SIGNAL_PAGE_SIZE (sizeof(struct signal_page) + \ - SLOT_BITMAP_SIZE * sizeof(long)) - /* * For signal events, the event ID is used as the interrupt user data. * For SQ s_sendmsg interrupts, this is limited to 8 bits. */ #define INTERRUPT_DATA_BITS 8 -#define SIGNAL_EVENT_ID_SLOT_SHIFT 0 -static uint64_t *page_slots(struct signal_page *page) +static uint64_t *page_slots(struct kfd_signal_page *page) { return page->kernel_address; } static bool allocate_free_slot(struct kfd_process *process, - struct signal_page **out_page, - unsigned int *out_slot_index) + unsigned int *out_slot_index) { - struct signal_page *page; + struct kfd_signal_page *page = process->signal_page; + unsigned int slot; - list_for_each_entry(page, &process->signal_event_pages, event_pages) { - if (page->free_slots > 0) { - unsigned int slot = - find_first_zero_bit(page->used_slot_bitmap, - SLOTS_PER_PAGE); + if (!page || page->free_slots == 0) { + pr_debug("No free event signal slots were found for process %p\n", + process); - __set_bit(slot, page->used_slot_bitmap); - page->free_slots--; + return false; + } - page_slots(page)[slot] = UNSIGNALED_EVENT_SLOT; + slot = find_first_zero_bit(page->used_slot_bitmap, SLOTS_PER_PAGE); - *out_page = page; - *out_slot_index = slot; + __set_bit(slot, page->used_slot_bitmap); + page->free_slots--; - pr_debug("Allocated event signal slot in page %p, slot %d\n", - page, slot); + page_slots(page)[slot] = UNSIGNALED_EVENT_SLOT; - return true; - } - } + *out_slot_index = slot; - pr_debug("No free event signal slots were found for process %p\n", - process); + pr_debug("Allocated event signal slot in page %p, slot %d\n", + page, slot); - return false; + return true; } -#define list_tail_entry(head, type, member) \ - list_entry((head)->prev, type, member) - -static bool allocate_signal_page(struct file *devkfd, struct kfd_process *p) +static struct kfd_signal_page *allocate_signal_page(struct kfd_process *p) { void *backing_store; - struct signal_page *page; + struct kfd_signal_page *page; - page = kzalloc(SIGNAL_PAGE_SIZE, GFP_KERNEL); + page = kzalloc(sizeof(*page), GFP_KERNEL); if (!page) - goto fail_alloc_signal_page; + return NULL; page->free_slots = SLOTS_PER_PAGE; - backing_store = (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, + backing_store = (void *) __get_free_pages(GFP_KERNEL, get_order(KFD_SIGNAL_EVENT_LIMIT * 8)); if (!backing_store) goto fail_alloc_signal_store; - /* prevent user-mode info leaks */ + /* Initialize all events to unsignaled */ memset(backing_store, (uint8_t) UNSIGNALED_EVENT_SLOT, - KFD_SIGNAL_EVENT_LIMIT * 8); + KFD_SIGNAL_EVENT_LIMIT * 8); page->kernel_address = backing_store; - - if (list_empty(&p->signal_event_pages)) - page->page_index = 0; - else - page->page_index = list_tail_entry(&p->signal_event_pages, - struct signal_page, - event_pages)->page_index + 1; - pr_debug("Allocated new event signal page at %p, for process %p\n", page, p); - pr_debug("Page index is %d\n", page->page_index); - - list_add(&page->event_pages, &p->signal_event_pages); - return true; + return page; fail_alloc_signal_store: kfree(page); -fail_alloc_signal_page: - return false; + return NULL; } -static bool allocate_event_notification_slot(struct file *devkfd, - struct kfd_process *p, - struct signal_page **page, - unsigned int *signal_slot_index) +static bool allocate_event_notification_slot(struct kfd_process *p, + unsigned int *signal_slot_index) { - bool ret; - - ret = allocate_free_slot(p, page, signal_slot_index); - if (!ret) { - ret = allocate_signal_page(devkfd, p); - if (ret) - ret = allocate_free_slot(p, page, signal_slot_index); + if (!p->signal_page) { + p->signal_page = allocate_signal_page(p); + if (!p->signal_page) + return false; } - return ret; + return allocate_free_slot(p, signal_slot_index); } /* Assumes that the process's event_mutex is locked. */ -static void release_event_notification_slot(struct signal_page *page, +static void release_event_notification_slot(struct kfd_signal_page *page, size_t slot_index) { __clear_bit(slot_index, page->used_slot_bitmap); @@ -187,22 +156,6 @@ static void release_event_notification_slot(struct signal_page *page, */ } -static struct signal_page *lookup_signal_page_by_index(struct kfd_process *p, - unsigned int page_index) -{ - struct signal_page *page; - - /* - * This is safe because we don't delete signal pages until the - * process exits. - */ - list_for_each_entry(page, &p->signal_event_pages, event_pages) - if (page->page_index == page_index) - return page; - - return NULL; -} - /* * Assumes that p->event_mutex is held and of course that p is not going * away (current or locked). @@ -218,13 +171,6 @@ static struct kfd_event *lookup_event_by_id(struct kfd_process *p, uint32_t id) return NULL; } -static u32 make_signal_event_id(struct signal_page *page, - unsigned int signal_slot_index) -{ - return page->page_index | - (signal_slot_index << SIGNAL_EVENT_ID_SLOT_SHIFT); -} - /* * Produce a kfd event id for a nonsignal event. * These are arbitrary numbers, so we do a sequential search through @@ -270,10 +216,9 @@ static u32 make_nonsignal_event_id(struct kfd_process *p) } static struct kfd_event *lookup_event_by_page_slot(struct kfd_process *p, - struct signal_page *page, unsigned int signal_slot) { - return lookup_event_by_id(p, make_signal_event_id(page, signal_slot)); + return lookup_event_by_id(p, signal_slot); } static int create_signal_event(struct file *devkfd, @@ -288,8 +233,7 @@ static int create_signal_event(struct file *devkfd, return -ENOMEM; } - if (!allocate_event_notification_slot(devkfd, p, &ev->signal_page, - &ev->signal_slot_index)) { + if (!allocate_event_notification_slot(p, &ev->signal_slot_index)) { pr_warn("Signal event wasn't created because out of kernel memory\n"); return -ENOMEM; } @@ -297,10 +241,9 @@ static int create_signal_event(struct file *devkfd, p->signal_event_count++; ev->user_signal_address = - &ev->signal_page->user_address[ev->signal_slot_index]; + &p->signal_page->user_address[ev->signal_slot_index]; - ev->event_id = make_signal_event_id(ev->signal_page, - ev->signal_slot_index); + ev->event_id = ev->signal_slot_index; pr_debug("Signal event number %zu created with id %d, address %p\n", p->signal_event_count, ev->event_id, @@ -327,7 +270,7 @@ void kfd_event_init_process(struct kfd_process *p) { mutex_init(&p->event_mutex); hash_init(p->events); - INIT_LIST_HEAD(&p->signal_event_pages); + p->signal_page = NULL; p->next_nonsignal_event_id = KFD_FIRST_NONSIGNAL_EVENT_ID; p->signal_event_count = 0; } @@ -341,8 +284,9 @@ static void destroy_event(struct kfd_process *p, struct kfd_event *ev) waiter->event = NULL; wake_up_all(&ev->wq); - if (ev->signal_page) { - release_event_notification_slot(ev->signal_page, + if ((ev->type == KFD_EVENT_TYPE_SIGNAL || + ev->type == KFD_EVENT_TYPE_DEBUG) && p->signal_page) { + release_event_notification_slot(p->signal_page, ev->signal_slot_index); p->signal_event_count--; } @@ -365,12 +309,11 @@ static void destroy_events(struct kfd_process *p) * We assume that the process is being destroyed and there is no need to * unmap the pages or keep bookkeeping data in order. */ -static void shutdown_signal_pages(struct kfd_process *p) +static void shutdown_signal_page(struct kfd_process *p) { - struct signal_page *page, *tmp; + struct kfd_signal_page *page = p->signal_page; - list_for_each_entry_safe(page, tmp, &p->signal_event_pages, - event_pages) { + if (page) { free_pages((unsigned long)page->kernel_address, get_order(KFD_SIGNAL_EVENT_LIMIT * 8)); kfree(page); @@ -380,7 +323,7 @@ static void shutdown_signal_pages(struct kfd_process *p) void kfd_event_free_process(struct kfd_process *p) { destroy_events(p); - shutdown_signal_pages(p); + shutdown_signal_page(p); } static bool event_can_be_gpu_signaled(const struct kfd_event *ev) @@ -420,8 +363,7 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p, case KFD_EVENT_TYPE_DEBUG: ret = create_signal_event(devkfd, p, ev); if (!ret) { - *event_page_offset = (ev->signal_page->page_index | - KFD_MMAP_EVENTS_MASK); + *event_page_offset = KFD_MMAP_EVENTS_MASK; *event_page_offset <<= PAGE_SHIFT; *event_slot_index = ev->signal_slot_index; } @@ -527,13 +469,17 @@ int kfd_reset_event(struct kfd_process *p, uint32_t event_id) static void acknowledge_signal(struct kfd_process *p, struct kfd_event *ev) { - page_slots(ev->signal_page)[ev->signal_slot_index] = + page_slots(p->signal_page)[ev->signal_slot_index] = UNSIGNALED_EVENT_SLOT; } -static bool is_slot_signaled(struct signal_page *page, unsigned int index) +static bool is_slot_signaled(struct kfd_process *p, unsigned int index) { - return page_slots(page)[index] != UNSIGNALED_EVENT_SLOT; + if (!p->signal_page) + return false; + else + return page_slots(p->signal_page)[index] != + UNSIGNALED_EVENT_SLOT; } static void set_event_from_interrupt(struct kfd_process *p, @@ -566,22 +512,19 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, /* Partial ID is a full ID. */ ev = lookup_event_by_id(p, partial_id); set_event_from_interrupt(p, ev); - } else { + } else if (p->signal_page) { /* * Partial ID is in fact partial. For now we completely * ignore it, but we could use any bits we did receive to * search faster. */ - struct signal_page *page; unsigned int i; - list_for_each_entry(page, &p->signal_event_pages, event_pages) - for (i = 0; i < SLOTS_PER_PAGE; i++) - if (is_slot_signaled(page, i)) { - ev = lookup_event_by_page_slot(p, - page, i); - set_event_from_interrupt(p, ev); - } + for (i = 0; i < SLOTS_PER_PAGE; i++) + if (is_slot_signaled(p, i)) { + ev = lookup_event_by_page_slot(p, i); + set_event_from_interrupt(p, ev); + } } mutex_unlock(&p->event_mutex); @@ -846,9 +789,8 @@ out: int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma) { - unsigned int page_index; unsigned long pfn; - struct signal_page *page; + struct kfd_signal_page *page; /* check required size is logical */ if (get_order(KFD_SIGNAL_EVENT_LIMIT * 8) != @@ -857,13 +799,10 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma) return -EINVAL; } - page_index = vma->vm_pgoff; - - page = lookup_signal_page_by_index(p, page_index); + page = p->signal_page; if (!page) { /* Probably KFD bug, but mmap is user-accessible. */ - pr_debug("Signal page could not be found for page_index %u\n", - page_index); + pr_debug("Signal page could not be found\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.h b/drivers/gpu/drm/amd/amdkfd/kfd_events.h index 96f9122805fa..f85fcee4414b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.h @@ -60,7 +60,6 @@ struct kfd_event { wait_queue_head_t wq; /* List of event waiters. */ /* Only for signal events. */ - struct signal_page *signal_page; unsigned int signal_slot_index; uint64_t __user *user_signal_address; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index d3cf53a50ced..c1b3ee22faed 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -540,8 +540,8 @@ struct kfd_process { struct mutex event_mutex; /* All events in process hashed by ID, linked on kfd_event.events. */ DECLARE_HASHTABLE(events, 4); - /* struct slot_page_header.event_pages */ - struct list_head signal_event_pages; + /* Event page */ + struct kfd_signal_page *signal_page; u32 next_nonsignal_event_id; size_t signal_event_count; bool signal_event_limit_reached; -- cgit v1.2.3 From 482f07775cf559c82cb3d086e3c4fad91582e4cb Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:27 -0400 Subject: drm/amdkfd: Simplify event ID and signal slot management Signal slots are identical to event IDs. Replace the used_slot_bitmap and events hash table with an IDR to allocate and lookup event IDs and signal slots more efficiently. Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 230 ++++++++++---------------------- drivers/gpu/drm/amd/amdkfd/kfd_events.h | 14 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 6 +- 3 files changed, 80 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 7cc17107f448..41580e0638f3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -41,24 +41,16 @@ struct kfd_event_waiter { bool activated; /* Becomes true when event is signaled */ }; -#define SLOTS_PER_PAGE KFD_SIGNAL_EVENT_LIMIT -#define SLOT_BITMAP_LONGS BITS_TO_LONGS(SLOTS_PER_PAGE) - /* - * Over-complicated pooled allocator for event notification slots. - * * Each signal event needs a 64-bit signal slot where the signaler will write - * a 1 before sending an interrupt.l (This is needed because some interrupts + * a 1 before sending an interrupt. (This is needed because some interrupts * do not contain enough spare data bits to identify an event.) - * We get whole pages from vmalloc and map them to the process VA. - * Individual signal events are then allocated a slot in a page. + * We get whole pages and map them to the process VA. + * Individual signal events use their event_id as slot index. */ - struct kfd_signal_page { uint64_t *kernel_address; uint64_t __user *user_address; - unsigned int free_slots; - unsigned long used_slot_bitmap[SLOT_BITMAP_LONGS]; }; /* @@ -73,34 +65,6 @@ static uint64_t *page_slots(struct kfd_signal_page *page) return page->kernel_address; } -static bool allocate_free_slot(struct kfd_process *process, - unsigned int *out_slot_index) -{ - struct kfd_signal_page *page = process->signal_page; - unsigned int slot; - - if (!page || page->free_slots == 0) { - pr_debug("No free event signal slots were found for process %p\n", - process); - - return false; - } - - slot = find_first_zero_bit(page->used_slot_bitmap, SLOTS_PER_PAGE); - - __set_bit(slot, page->used_slot_bitmap); - page->free_slots--; - - page_slots(page)[slot] = UNSIGNALED_EVENT_SLOT; - - *out_slot_index = slot; - - pr_debug("Allocated event signal slot in page %p, slot %d\n", - page, slot); - - return true; -} - static struct kfd_signal_page *allocate_signal_page(struct kfd_process *p) { void *backing_store; @@ -110,8 +74,6 @@ static struct kfd_signal_page *allocate_signal_page(struct kfd_process *p) if (!page) return NULL; - page->free_slots = SLOTS_PER_PAGE; - backing_store = (void *) __get_free_pages(GFP_KERNEL, get_order(KFD_SIGNAL_EVENT_LIMIT * 8)); if (!backing_store) @@ -132,28 +94,26 @@ fail_alloc_signal_store: return NULL; } -static bool allocate_event_notification_slot(struct kfd_process *p, - unsigned int *signal_slot_index) +static int allocate_event_notification_slot(struct kfd_process *p, + struct kfd_event *ev) { + int id; + if (!p->signal_page) { p->signal_page = allocate_signal_page(p); if (!p->signal_page) - return false; + return -ENOMEM; } - return allocate_free_slot(p, signal_slot_index); -} + id = idr_alloc(&p->event_idr, ev, 0, KFD_SIGNAL_EVENT_LIMIT, + GFP_KERNEL); + if (id < 0) + return id; -/* Assumes that the process's event_mutex is locked. */ -static void release_event_notification_slot(struct kfd_signal_page *page, - size_t slot_index) -{ - __clear_bit(slot_index, page->used_slot_bitmap); - page->free_slots++; + ev->event_id = id; + page_slots(p->signal_page)[id] = UNSIGNALED_EVENT_SLOT; - /* We don't free signal pages, they are retained by the process - * and reused until it exits. - */ + return 0; } /* @@ -162,89 +122,32 @@ static void release_event_notification_slot(struct kfd_signal_page *page, */ static struct kfd_event *lookup_event_by_id(struct kfd_process *p, uint32_t id) { - struct kfd_event *ev; - - hash_for_each_possible(p->events, ev, events, id) - if (ev->event_id == id) - return ev; - - return NULL; -} - -/* - * Produce a kfd event id for a nonsignal event. - * These are arbitrary numbers, so we do a sequential search through - * the hash table for an unused number. - */ -static u32 make_nonsignal_event_id(struct kfd_process *p) -{ - u32 id; - - for (id = p->next_nonsignal_event_id; - id < KFD_LAST_NONSIGNAL_EVENT_ID && - lookup_event_by_id(p, id); - id++) - ; - - if (id < KFD_LAST_NONSIGNAL_EVENT_ID) { - - /* - * What if id == LAST_NONSIGNAL_EVENT_ID - 1? - * Then next_nonsignal_event_id = LAST_NONSIGNAL_EVENT_ID so - * the first loop fails immediately and we proceed with the - * wraparound loop below. - */ - p->next_nonsignal_event_id = id + 1; - - return id; - } - - for (id = KFD_FIRST_NONSIGNAL_EVENT_ID; - id < KFD_LAST_NONSIGNAL_EVENT_ID && - lookup_event_by_id(p, id); - id++) - ; - - - if (id < KFD_LAST_NONSIGNAL_EVENT_ID) { - p->next_nonsignal_event_id = id + 1; - return id; - } - - p->next_nonsignal_event_id = KFD_FIRST_NONSIGNAL_EVENT_ID; - return 0; -} - -static struct kfd_event *lookup_event_by_page_slot(struct kfd_process *p, - unsigned int signal_slot) -{ - return lookup_event_by_id(p, signal_slot); + return idr_find(&p->event_idr, id); } static int create_signal_event(struct file *devkfd, struct kfd_process *p, struct kfd_event *ev) { + int ret; + if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) { if (!p->signal_event_limit_reached) { pr_warn("Signal event wasn't created because limit was reached\n"); p->signal_event_limit_reached = true; } - return -ENOMEM; + return -ENOSPC; } - if (!allocate_event_notification_slot(p, &ev->signal_slot_index)) { + ret = allocate_event_notification_slot(p, ev); + if (ret) { pr_warn("Signal event wasn't created because out of kernel memory\n"); - return -ENOMEM; + return ret; } p->signal_event_count++; - ev->user_signal_address = - &p->signal_page->user_address[ev->signal_slot_index]; - - ev->event_id = ev->signal_slot_index; - + ev->user_signal_address = &p->signal_page->user_address[ev->event_id]; pr_debug("Signal event number %zu created with id %d, address %p\n", p->signal_event_count, ev->event_id, ev->user_signal_address); @@ -252,16 +155,20 @@ static int create_signal_event(struct file *devkfd, return 0; } -/* - * No non-signal events are supported yet. - * We create them as events that never signal. - * Set event calls from user-mode are failed. - */ static int create_other_event(struct kfd_process *p, struct kfd_event *ev) { - ev->event_id = make_nonsignal_event_id(p); - if (ev->event_id == 0) - return -ENOMEM; + /* Cast KFD_LAST_NONSIGNAL_EVENT to uint32_t. This allows an + * intentional integer overflow to -1 without a compiler + * warning. idr_alloc treats a negative value as "maximum + * signed integer". + */ + int id = idr_alloc(&p->event_idr, ev, KFD_FIRST_NONSIGNAL_EVENT_ID, + (uint32_t)KFD_LAST_NONSIGNAL_EVENT_ID + 1, + GFP_KERNEL); + + if (id < 0) + return id; + ev->event_id = id; return 0; } @@ -269,9 +176,8 @@ static int create_other_event(struct kfd_process *p, struct kfd_event *ev) void kfd_event_init_process(struct kfd_process *p) { mutex_init(&p->event_mutex); - hash_init(p->events); + idr_init(&p->event_idr); p->signal_page = NULL; - p->next_nonsignal_event_id = KFD_FIRST_NONSIGNAL_EVENT_ID; p->signal_event_count = 0; } @@ -284,25 +190,22 @@ static void destroy_event(struct kfd_process *p, struct kfd_event *ev) waiter->event = NULL; wake_up_all(&ev->wq); - if ((ev->type == KFD_EVENT_TYPE_SIGNAL || - ev->type == KFD_EVENT_TYPE_DEBUG) && p->signal_page) { - release_event_notification_slot(p->signal_page, - ev->signal_slot_index); + if (ev->type == KFD_EVENT_TYPE_SIGNAL || + ev->type == KFD_EVENT_TYPE_DEBUG) p->signal_event_count--; - } - hash_del(&ev->events); + idr_remove(&p->event_idr, ev->event_id); kfree(ev); } static void destroy_events(struct kfd_process *p) { struct kfd_event *ev; - struct hlist_node *tmp; - unsigned int hash_bkt; + uint32_t id; - hash_for_each_safe(p->events, hash_bkt, tmp, ev, events) + idr_for_each_entry(&p->event_idr, ev, id) destroy_event(p, ev); + idr_destroy(&p->event_idr); } /* @@ -365,7 +268,7 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p, if (!ret) { *event_page_offset = KFD_MMAP_EVENTS_MASK; *event_page_offset <<= PAGE_SHIFT; - *event_slot_index = ev->signal_slot_index; + *event_slot_index = ev->event_id; } break; default: @@ -374,8 +277,6 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p, } if (!ret) { - hash_add(p->events, &ev->events, ev->event_id); - *event_id = ev->event_id; *event_trigger_data = ev->event_id; } else { @@ -469,17 +370,7 @@ int kfd_reset_event(struct kfd_process *p, uint32_t event_id) static void acknowledge_signal(struct kfd_process *p, struct kfd_event *ev) { - page_slots(p->signal_page)[ev->signal_slot_index] = - UNSIGNALED_EVENT_SLOT; -} - -static bool is_slot_signaled(struct kfd_process *p, unsigned int index) -{ - if (!p->signal_page) - return false; - else - return page_slots(p->signal_page)[index] != - UNSIGNALED_EVENT_SLOT; + page_slots(p->signal_page)[ev->event_id] = UNSIGNALED_EVENT_SLOT; } static void set_event_from_interrupt(struct kfd_process *p, @@ -518,13 +409,31 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, * ignore it, but we could use any bits we did receive to * search faster. */ - unsigned int i; + uint64_t *slots = page_slots(p->signal_page); + uint32_t id; + + if (p->signal_event_count < KFD_SIGNAL_EVENT_LIMIT/2) { + /* With relatively few events, it's faster to + * iterate over the event IDR + */ + idr_for_each_entry(&p->event_idr, ev, id) { + if (id >= KFD_SIGNAL_EVENT_LIMIT) + break; - for (i = 0; i < SLOTS_PER_PAGE; i++) - if (is_slot_signaled(p, i)) { - ev = lookup_event_by_page_slot(p, i); - set_event_from_interrupt(p, ev); + if (slots[id] != UNSIGNALED_EVENT_SLOT) + set_event_from_interrupt(p, ev); } + } else { + /* With relatively many events, it's faster to + * iterate over the signal slots and lookup + * only signaled events from the IDR. + */ + for (id = 0; id < KFD_SIGNAL_EVENT_LIMIT; id++) + if (slots[id] != UNSIGNALED_EVENT_SLOT) { + ev = lookup_event_by_id(p, id); + set_event_from_interrupt(p, ev); + } + } } mutex_unlock(&p->event_mutex); @@ -836,12 +745,13 @@ static void lookup_events_by_type_and_signal(struct kfd_process *p, { struct kfd_hsa_memory_exception_data *ev_data; struct kfd_event *ev; - int bkt; + uint32_t id; bool send_signal = true; ev_data = (struct kfd_hsa_memory_exception_data *) event_data; - hash_for_each(p->events, bkt, ev, events) + id = KFD_FIRST_NONSIGNAL_EVENT_ID; + idr_for_each_entry_continue(&p->event_idr, ev, id) if (ev->type == type) { send_signal = false; dev_dbg(kfd_device, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.h b/drivers/gpu/drm/amd/amdkfd/kfd_events.h index f85fcee4414b..abca5bfebbff 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.h @@ -31,9 +31,13 @@ #include "kfd_priv.h" #include -#define KFD_EVENT_ID_NONSIGNAL_MASK 0x80000000U -#define KFD_FIRST_NONSIGNAL_EVENT_ID KFD_EVENT_ID_NONSIGNAL_MASK -#define KFD_LAST_NONSIGNAL_EVENT_ID UINT_MAX +/* + * IDR supports non-negative integer IDs. Small IDs are used for + * signal events to match their signal slot. Use the upper half of the + * ID space for non-signal events. + */ +#define KFD_FIRST_NONSIGNAL_EVENT_ID ((INT_MAX >> 1) + 1) +#define KFD_LAST_NONSIGNAL_EVENT_ID INT_MAX /* * Written into kfd_signal_slot_t to indicate that the event is not signaled. @@ -47,9 +51,6 @@ struct kfd_event_waiter; struct signal_page; struct kfd_event { - /* All events in process, rooted at kfd_process.events. */ - struct hlist_node events; - u32 event_id; bool signaled; @@ -60,7 +61,6 @@ struct kfd_event { wait_queue_head_t wq; /* List of event waiters. */ /* Only for signal events. */ - unsigned int signal_slot_index; uint64_t __user *user_signal_address; /* type specific data */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index c1b3ee22faed..ebae8e1891d2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "amd_shared.h" @@ -538,11 +539,10 @@ struct kfd_process { /* Event-related data */ struct mutex event_mutex; - /* All events in process hashed by ID, linked on kfd_event.events. */ - DECLARE_HASHTABLE(events, 4); + /* Event ID allocator and lookup */ + struct idr event_idr; /* Event page */ struct kfd_signal_page *signal_page; - u32 next_nonsignal_event_id; size_t signal_event_count; bool signal_event_limit_reached; }; -- cgit v1.2.3 From 3f04f9614831b4d18dcaf228cff0617a20073f9d Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:28 -0400 Subject: drm/amdkfd: Use IH context ID for signal lookup This speeds up signal lookup when the IH ring entry includes a valid context ID or partial context ID. Only if the context ID is found to be invalid, fall back to an exhaustive search of all signaled events. Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c | 7 ++- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 73 +++++++++++++++++++----- 2 files changed, 64 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c index 66164aa67c66..3d5ccb3755d4 100644 --- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c @@ -47,6 +47,7 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev, unsigned int pasid; const struct cik_ih_ring_entry *ihre = (const struct cik_ih_ring_entry *)ih_ring_entry; + uint32_t context_id = ihre->data & 0xfffffff; pasid = (ihre->ring_id & 0xffff0000) >> 16; @@ -54,11 +55,11 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev, return; if (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE) - kfd_signal_event_interrupt(pasid, 0, 0); + kfd_signal_event_interrupt(pasid, context_id, 28); else if (ihre->source_id == CIK_INTSRC_SDMA_TRAP) - kfd_signal_event_interrupt(pasid, 0, 0); + kfd_signal_event_interrupt(pasid, context_id, 28); else if (ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG) - kfd_signal_event_interrupt(pasid, ihre->data & 0xFF, 8); + kfd_signal_event_interrupt(pasid, context_id & 0xff, 8); else if (ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE) kfd_signal_hw_exception_event(pasid); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 41580e0638f3..26e8045aa760 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -53,12 +53,6 @@ struct kfd_signal_page { uint64_t __user *user_address; }; -/* - * For signal events, the event ID is used as the interrupt user data. - * For SQ s_sendmsg interrupts, this is limited to 8 bits. - */ - -#define INTERRUPT_DATA_BITS 8 static uint64_t *page_slots(struct kfd_signal_page *page) { @@ -125,6 +119,54 @@ static struct kfd_event *lookup_event_by_id(struct kfd_process *p, uint32_t id) return idr_find(&p->event_idr, id); } +/** + * lookup_signaled_event_by_partial_id - Lookup signaled event from partial ID + * @p: Pointer to struct kfd_process + * @id: ID to look up + * @bits: Number of valid bits in @id + * + * Finds the first signaled event with a matching partial ID. If no + * matching signaled event is found, returns NULL. In that case the + * caller should assume that the partial ID is invalid and do an + * exhaustive search of all siglaned events. + * + * If multiple events with the same partial ID signal at the same + * time, they will be found one interrupt at a time, not necessarily + * in the same order the interrupts occurred. As long as the number of + * interrupts is correct, all signaled events will be seen by the + * driver. + */ +static struct kfd_event *lookup_signaled_event_by_partial_id( + struct kfd_process *p, uint32_t id, uint32_t bits) +{ + struct kfd_event *ev; + + if (!p->signal_page || id >= KFD_SIGNAL_EVENT_LIMIT) + return NULL; + + /* Fast path for the common case that @id is not a partial ID + * and we only need a single lookup. + */ + if (bits > 31 || (1U << bits) >= KFD_SIGNAL_EVENT_LIMIT) { + if (page_slots(p->signal_page)[id] == UNSIGNALED_EVENT_SLOT) + return NULL; + + return idr_find(&p->event_idr, id); + } + + /* General case for partial IDs: Iterate over all matching IDs + * and find the first one that has signaled. + */ + for (ev = NULL; id < KFD_SIGNAL_EVENT_LIMIT && !ev; id += 1U << bits) { + if (page_slots(p->signal_page)[id] == UNSIGNALED_EVENT_SLOT) + continue; + + ev = idr_find(&p->event_idr, id); + } + + return ev; +} + static int create_signal_event(struct file *devkfd, struct kfd_process *p, struct kfd_event *ev) @@ -385,7 +427,7 @@ static void set_event_from_interrupt(struct kfd_process *p, void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, uint32_t valid_id_bits) { - struct kfd_event *ev; + struct kfd_event *ev = NULL; /* * Because we are called from arbitrary context (workqueue) as opposed @@ -399,19 +441,24 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, mutex_lock(&p->event_mutex); - if (valid_id_bits >= INTERRUPT_DATA_BITS) { - /* Partial ID is a full ID. */ - ev = lookup_event_by_id(p, partial_id); + if (valid_id_bits) + ev = lookup_signaled_event_by_partial_id(p, partial_id, + valid_id_bits); + if (ev) { set_event_from_interrupt(p, ev); } else if (p->signal_page) { /* - * Partial ID is in fact partial. For now we completely - * ignore it, but we could use any bits we did receive to - * search faster. + * Partial ID lookup failed. Assume that the event ID + * in the interrupt payload was invalid and do an + * exhaustive search of signaled events. */ uint64_t *slots = page_slots(p->signal_page); uint32_t id; + if (valid_id_bits) + pr_debug_ratelimited("Partial ID invalid: %u (%u valid bits)\n", + partial_id, valid_id_bits); + if (p->signal_event_count < KFD_SIGNAL_EVENT_LIMIT/2) { /* With relatively few events, it's faster to * iterate over the event IDR -- cgit v1.2.3 From b9a5d0a5db802277c93667c6af93e699bb8c773e Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 27 Oct 2017 19:35:29 -0400 Subject: drm/amdkfd: Make event limit dependent on user mode mapping size This allows increasing the KFD_SIGNAL_EVENT_LIMIT in kfd_ioctl.h without breaking processes built with older kfd_ioctl.h versions. Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 25 +++++++++++++++++++------ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 + 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 26e8045aa760..cb92d4b72400 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -97,9 +97,17 @@ static int allocate_event_notification_slot(struct kfd_process *p, p->signal_page = allocate_signal_page(p); if (!p->signal_page) return -ENOMEM; + /* Oldest user mode expects 256 event slots */ + p->signal_mapped_size = 256*8; } - id = idr_alloc(&p->event_idr, ev, 0, KFD_SIGNAL_EVENT_LIMIT, + /* + * Compatibility with old user mode: Only use signal slots + * user mode has mapped, may be less than + * KFD_SIGNAL_EVENT_LIMIT. This also allows future increase + * of the event limit without breaking user mode. + */ + id = idr_alloc(&p->event_idr, ev, 0, p->signal_mapped_size / 8, GFP_KERNEL); if (id < 0) return id; @@ -173,7 +181,8 @@ static int create_signal_event(struct file *devkfd, { int ret; - if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) { + if (p->signal_mapped_size && + p->signal_event_count == p->signal_mapped_size / 8) { if (!p->signal_event_limit_reached) { pr_warn("Signal event wasn't created because limit was reached\n"); p->signal_event_limit_reached = true; @@ -744,12 +753,12 @@ out: int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma) { - unsigned long pfn; struct kfd_signal_page *page; + int ret; - /* check required size is logical */ - if (get_order(KFD_SIGNAL_EVENT_LIMIT * 8) != + /* check required size doesn't exceed the allocated size */ + if (get_order(KFD_SIGNAL_EVENT_LIMIT * 8) < get_order(vma->vm_end - vma->vm_start)) { pr_err("Event page mmap requested illegal size\n"); return -EINVAL; @@ -779,8 +788,12 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma) page->user_address = (uint64_t __user *)vma->vm_start; /* mapping the page to user process */ - return remap_pfn_range(vma, vma->vm_start, pfn, + ret = remap_pfn_range(vma, vma->vm_start, pfn, vma->vm_end - vma->vm_start, vma->vm_page_prot); + if (!ret) + p->signal_mapped_size = vma->vm_end - vma->vm_start; + + return ret; } /* diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index ebae8e1891d2..ba26da81d8ec 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -543,6 +543,7 @@ struct kfd_process { struct idr event_idr; /* Event page */ struct kfd_signal_page *signal_page; + size_t signal_mapped_size; size_t signal_event_count; bool signal_event_limit_reached; }; -- cgit v1.2.3 From 04ad47bd14a0f7a268124c4fc468e964e457a702 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 27 Oct 2017 19:35:31 -0400 Subject: drm/amdkfd: use standard kernel kfifo for IH Replace our implementation of a lockless ring buffer with the standard linux kernel kfifo. We shouldn't maintain our own version of a standard data structure. Signed-off-by: Andres Rodriguez Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 78 ++++++++++-------------------- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 6 +-- 2 files changed, 27 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c index 70b3a99cffc2..ffbb91aa9bbf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -42,25 +42,24 @@ #include #include +#include #include "kfd_priv.h" -#define KFD_INTERRUPT_RING_SIZE 1024 +#define KFD_IH_NUM_ENTRIES 1024 static void interrupt_wq(struct work_struct *); int kfd_interrupt_init(struct kfd_dev *kfd) { - void *interrupt_ring = kmalloc_array(KFD_INTERRUPT_RING_SIZE, - kfd->device_info->ih_ring_entry_size, - GFP_KERNEL); - if (!interrupt_ring) - return -ENOMEM; - - kfd->interrupt_ring = interrupt_ring; - kfd->interrupt_ring_size = - KFD_INTERRUPT_RING_SIZE * kfd->device_info->ih_ring_entry_size; - atomic_set(&kfd->interrupt_ring_wptr, 0); - atomic_set(&kfd->interrupt_ring_rptr, 0); + int r; + + r = kfifo_alloc(&kfd->ih_fifo, + KFD_IH_NUM_ENTRIES * kfd->device_info->ih_ring_entry_size, + GFP_KERNEL); + if (r) { + dev_err(kfd_chardev(), "Failed to allocate IH fifo\n"); + return r; + } spin_lock_init(&kfd->interrupt_lock); @@ -98,68 +97,41 @@ void kfd_interrupt_exit(struct kfd_dev *kfd) */ flush_scheduled_work(); - kfree(kfd->interrupt_ring); + kfifo_free(&kfd->ih_fifo); } /* - * This assumes that it can't be called concurrently with itself - * but only with dequeue_ih_ring_entry. + * Assumption: single reader/writer. This function is not re-entrant */ bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry) { - unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); - unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); + int count; - if ((rptr - wptr) % kfd->interrupt_ring_size == - kfd->device_info->ih_ring_entry_size) { - /* This is very bad, the system is likely to hang. */ + count = kfifo_in(&kfd->ih_fifo, ih_ring_entry, + kfd->device_info->ih_ring_entry_size); + if (count != kfd->device_info->ih_ring_entry_size) { dev_err_ratelimited(kfd_chardev(), - "Interrupt ring overflow, dropping interrupt.\n"); + "Interrupt ring overflow, dropping interrupt %d\n", + count); return false; } - memcpy(kfd->interrupt_ring + wptr, ih_ring_entry, - kfd->device_info->ih_ring_entry_size); - - wptr = (wptr + kfd->device_info->ih_ring_entry_size) % - kfd->interrupt_ring_size; - smp_wmb(); /* Ensure memcpy'd data is visible before wptr update. */ - atomic_set(&kfd->interrupt_ring_wptr, wptr); - return true; } /* - * This assumes that it can't be called concurrently with itself - * but only with enqueue_ih_ring_entry. + * Assumption: single reader/writer. This function is not re-entrant */ static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry) { - /* - * Assume that wait queues have an implicit barrier, i.e. anything that - * happened in the ISR before it queued work is visible. - */ - - unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); - unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); + int count; - if (rptr == wptr) - return false; - - memcpy(ih_ring_entry, kfd->interrupt_ring + rptr, - kfd->device_info->ih_ring_entry_size); - - rptr = (rptr + kfd->device_info->ih_ring_entry_size) % - kfd->interrupt_ring_size; + count = kfifo_out(&kfd->ih_fifo, ih_ring_entry, + kfd->device_info->ih_ring_entry_size); - /* - * Ensure the rptr write update is not visible until - * memcpy has finished reading. - */ - smp_mb(); - atomic_set(&kfd->interrupt_ring_rptr, rptr); + WARN_ON(count && count != kfd->device_info->ih_ring_entry_size); - return true; + return count == kfd->device_info->ih_ring_entry_size; } static void interrupt_wq(struct work_struct *work) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index ba26da81d8ec..0aec5ca8a964 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "amd_shared.h" @@ -182,10 +183,7 @@ struct kfd_dev { unsigned int gtt_sa_num_of_chunks; /* Interrupts */ - void *interrupt_ring; - size_t interrupt_ring_size; - atomic_t interrupt_ring_rptr; - atomic_t interrupt_ring_wptr; + struct kfifo ih_fifo; struct work_struct interrupt_work; spinlock_t interrupt_lock; -- cgit v1.2.3 From 27232055b12902073f3dbc17cdfa2def27f70d85 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 27 Oct 2017 19:35:32 -0400 Subject: drm/amdkfd: increase IH num entries to 8192 A larger buffer will let us accommodate applications with a large amount of semi-simultaneous event signals. Signed-off-by: Andres Rodriguez Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c index ffbb91aa9bbf..a1472691e028 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -45,7 +45,7 @@ #include #include "kfd_priv.h" -#define KFD_IH_NUM_ENTRIES 1024 +#define KFD_IH_NUM_ENTRIES 8192 static void interrupt_wq(struct work_struct *); -- cgit v1.2.3 From 0f875e3f3e422d28bb80757269837def75009778 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 27 Oct 2017 19:35:33 -0400 Subject: drm/amdkfd: wait only for IH work on IH exit We don't need to wait for all work to complete in the IH exit function. We only need to make sure the interrupt_work has finished executing to guarantee that ih_kfifo is no longer in use. Signed-off-by: Andres Rodriguez Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c index a1472691e028..9c08d4670b7f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -91,11 +91,11 @@ void kfd_interrupt_exit(struct kfd_dev *kfd) spin_unlock_irqrestore(&kfd->interrupt_lock, flags); /* - * Flush_scheduled_work ensures that there are no outstanding + * flush_work ensures that there are no outstanding * work-queue items that will access interrupt_ring. New work items * can't be created because we stopped interrupt handling above. */ - flush_scheduled_work(); + flush_work(&kfd->interrupt_work); kfifo_free(&kfd->ih_fifo); } -- cgit v1.2.3 From 48e876a20e79566f1736413d4f42dc66f3ab2f16 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Fri, 27 Oct 2017 19:35:34 -0400 Subject: drm/amdkfd: use a high priority workqueue for IH work In systems under heavy load the IH work may experience significant scheduling delays. Under load + system workqueue: Max Latency: 7.023695 ms Avg Latency: 0.263994 ms Under load + high priority workqueue: Max Latency: 1.162568 ms Avg Latency: 0.163213 ms Further work is required to measure the impact of per-cpu settings on IH performance. Signed-off-by: Andres Rodriguez Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 3 ++- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 46049f005b02..621a3b53a038 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -403,7 +403,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) if (kfd->interrupts_active && interrupt_is_wanted(kfd, ih_ring_entry) && enqueue_ih_ring_entry(kfd, ih_ring_entry)) - schedule_work(&kfd->interrupt_work); + queue_work(kfd->ih_wq, &kfd->interrupt_work); spin_unlock(&kfd->interrupt_lock); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c index 9c08d4670b7f..035c351f47c5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -61,6 +61,7 @@ int kfd_interrupt_init(struct kfd_dev *kfd) return r; } + kfd->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI, 1); spin_lock_init(&kfd->interrupt_lock); INIT_WORK(&kfd->interrupt_work, interrupt_wq); @@ -95,7 +96,7 @@ void kfd_interrupt_exit(struct kfd_dev *kfd) * work-queue items that will access interrupt_ring. New work items * can't be created because we stopped interrupt handling above. */ - flush_work(&kfd->interrupt_work); + flush_workqueue(kfd->ih_wq); kfifo_free(&kfd->ih_fifo); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 0aec5ca8a964..6a91a60c64cf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -184,6 +184,7 @@ struct kfd_dev { /* Interrupts */ struct kfifo ih_fifo; + struct workqueue_struct *ih_wq; struct work_struct interrupt_work; spinlock_t interrupt_lock; -- cgit v1.2.3 From 63b9ab65bd76e5de6479bb14b4014b64aa1a317a Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 27 Oct 2017 11:05:44 +0800 Subject: tuntap: properly align skb->head before building skb An unaligned alloc_frag->offset caused by previous allocation will result an unaligned skb->head. This will lead unaligned skb_shared_info and then unaligned dataref which requires to be aligned for accessing on some architecture. Fix this by aligning alloc_frag->offset before the frag refilling. Fixes: 0bbd7dad34f8 ("tun: make tun_build_skb() thread safe") Cc: Eric Dumazet Cc: Willem de Bruijn Cc: Wei Wei Cc: Dmitry Vyukov Cc: Mark Rutland Reported-by: Wei Wei Signed-off-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/tun.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index b9973fb868b7..5550f56cb895 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1286,6 +1286,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, buflen += SKB_DATA_ALIGN(len + pad); rcu_read_unlock(); + alloc_frag->offset = ALIGN((u64)alloc_frag->offset, SMP_CACHE_BYTES); if (unlikely(!skb_page_frag_refill(buflen, alloc_frag, GFP_KERNEL))) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From dea6e19f4ef746aa18b4c33d1a7fed54356796ed Mon Sep 17 00:00:00 2001 From: Girish Moodalbail Date: Fri, 27 Oct 2017 00:00:16 -0700 Subject: tap: reference to KVA of an unloaded module causes kernel panic The commit 9a393b5d5988 ("tap: tap as an independent module") created a separate tap module that implements tap functionality and exports interfaces that will be used by macvtap and ipvtap modules to create create respective tap devices. However, that patch introduced a regression wherein the modules macvtap and ipvtap can be removed (through modprobe -r) while there are applications using the respective /dev/tapX devices. These applications cause kernel to hold reference to /dev/tapX through 'struct cdev macvtap_cdev' and 'struct cdev ipvtap_dev' defined in macvtap and ipvtap modules respectively. So, when the application is later closed the kernel panics because we are referencing KVA that is present in the unloaded modules. ----------8<------- Example ----------8<---------- $ sudo ip li add name mv0 link enp7s0 type macvtap $ sudo ip li show mv0 |grep mv0| awk -e '{print $1 $2}' 14:mv0@enp7s0: $ cat /dev/tap14 & $ lsmod |egrep -i 'tap|vlan' macvtap 16384 0 macvlan 24576 1 macvtap tap 24576 3 macvtap $ sudo modprobe -r macvtap $ fg cat /dev/tap14 ^C <...system panics...> BUG: unable to handle kernel paging request at ffffffffa038c500 IP: cdev_put+0xf/0x30 ----------8<-----------------8<---------- The fix is to set cdev.owner to the module that creates the tap device (either macvtap or ipvtap). With this set, the operations (in fs/char_dev.c) on char device holds and releases the module through cdev_get() and cdev_put() and will not allow the module to unload prematurely. Fixes: 9a393b5d5988ea4e (tap: tap as an independent module) Signed-off-by: Girish Moodalbail Signed-off-by: David S. Miller --- drivers/net/ipvlan/ipvtap.c | 4 ++-- drivers/net/macvtap.c | 4 ++-- drivers/net/tap.c | 5 +++-- include/linux/if_tap.h | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c index 5dea2063dbc8..0bcc07f346c3 100644 --- a/drivers/net/ipvlan/ipvtap.c +++ b/drivers/net/ipvlan/ipvtap.c @@ -197,8 +197,8 @@ static int ipvtap_init(void) { int err; - err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap"); - + err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap", + THIS_MODULE); if (err) goto out1; diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index c2d0ea2fb019..cba5cb3b849a 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -204,8 +204,8 @@ static int macvtap_init(void) { int err; - err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap"); - + err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap", + THIS_MODULE); if (err) goto out1; diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 98ee6cc2875d..1b10fcc6a58d 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -1249,8 +1249,8 @@ static int tap_list_add(dev_t major, const char *device_name) return 0; } -int tap_create_cdev(struct cdev *tap_cdev, - dev_t *tap_major, const char *device_name) +int tap_create_cdev(struct cdev *tap_cdev, dev_t *tap_major, + const char *device_name, struct module *module) { int err; @@ -1259,6 +1259,7 @@ int tap_create_cdev(struct cdev *tap_cdev, goto out1; cdev_init(tap_cdev, &tap_fops); + tap_cdev->owner = module; err = cdev_add(tap_cdev, *tap_major, TAP_NUM_DEVS); if (err) goto out2; diff --git a/include/linux/if_tap.h b/include/linux/if_tap.h index 4837157da0dc..9ae41cdd0d4c 100644 --- a/include/linux/if_tap.h +++ b/include/linux/if_tap.h @@ -73,8 +73,8 @@ void tap_del_queues(struct tap_dev *tap); int tap_get_minor(dev_t major, struct tap_dev *tap); void tap_free_minor(dev_t major, struct tap_dev *tap); int tap_queue_resize(struct tap_dev *tap); -int tap_create_cdev(struct cdev *tap_cdev, - dev_t *tap_major, const char *device_name); +int tap_create_cdev(struct cdev *tap_cdev, dev_t *tap_major, + const char *device_name, struct module *module); void tap_destroy_cdev(dev_t major, struct cdev *tap_cdev); #endif /*_LINUX_IF_TAP_H_*/ -- cgit v1.2.3 From ad5149c4f65f7cb984ab85b366c6e7b573eaf48f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 12 Sep 2017 14:23:05 -0400 Subject: drm/msm: fix _NO_IMPLICIT fencing case We need to call reservation_object_reserve_shared() in both cases, but this wasn't happening in the _NO_IMPLICIT submit case. Fixes: f0a42bb ("drm/msm: submit support for in-fences") Reported-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 11 ----------- drivers/gpu/drm/msm/msm_gem_submit.c | 24 ++++++++++++++++++------ 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index f15821a0d900..a0ab6040c484 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -610,17 +610,6 @@ int msm_gem_sync_object(struct drm_gem_object *obj, struct dma_fence *fence; int i, ret; - if (!exclusive) { - /* NOTE: _reserve_shared() must happen before _add_shared_fence(), - * which makes this a slightly strange place to call it. OTOH this - * is a convenient can-fail point to hook it in. (And similar to - * how etnaviv and nouveau handle this.) - */ - ret = reservation_object_reserve_shared(msm_obj->resv); - if (ret) - return ret; - } - fobj = reservation_object_get_list(msm_obj->resv); if (!fobj || (fobj->shared_count == 0)) { fence = reservation_object_get_excl(msm_obj->resv); diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 5d0a75d4b249..93535cac0676 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -221,7 +221,7 @@ fail: return ret; } -static int submit_fence_sync(struct msm_gem_submit *submit) +static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit) { int i, ret = 0; @@ -229,6 +229,20 @@ static int submit_fence_sync(struct msm_gem_submit *submit) struct msm_gem_object *msm_obj = submit->bos[i].obj; bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE; + if (!write) { + /* NOTE: _reserve_shared() must happen before + * _add_shared_fence(), which makes this a slightly + * strange place to call it. OTOH this is a + * convenient can-fail point to hook it in. + */ + ret = reservation_object_reserve_shared(msm_obj->resv); + if (ret) + return ret; + } + + if (no_implicit) + continue; + ret = msm_gem_sync_object(&msm_obj->base, submit->gpu->fctx, write); if (ret) break; @@ -451,11 +465,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (ret) goto out; - if (!(args->flags & MSM_SUBMIT_NO_IMPLICIT)) { - ret = submit_fence_sync(submit); - if (ret) - goto out; - } + ret = submit_fence_sync(submit, !!(args->flags & MSM_SUBMIT_NO_IMPLICIT)); + if (ret) + goto out; ret = submit_pin_objects(submit); if (ret) -- cgit v1.2.3 From aacd9e6bdb7f7e66e779ca0316257cce667d3431 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 14 Jun 2017 13:36:10 +0530 Subject: drm/msm/hdmi: Remove mmagic_iface_clk from the 8x96 PHY clocks This was used as a placeholder. It was never really input to the MDSS/HDMI clocks. Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c index 1fb7645cc721..4d580a86c2e2 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c @@ -758,7 +758,6 @@ static const char * const hdmi_phy_8996_reg_names[] = { }; static const char * const hdmi_phy_8996_clk_names[] = { - "mmagic_iface_clk", "iface_clk", "ref_clk", }; -- cgit v1.2.3 From eec874ce5ff1fe1742317513904a2292af749c7d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 16 Oct 2017 09:22:38 -0400 Subject: drm/msm/adreno: load gpu at probe/bind time Previously, in an effort to defer initializing the gpu until firmware was available (ie. rootfs mounted), the gpu was not loaded at when the subdevice was bound. Which resulted that clks/etc were requested in a place that devm couldn't really help unwind if something failed. Instead move request_firmware() to gpu->hw_init() and construct the gpu earlier in adreno_bind(). To avoid the rest of the driver needing to be aware of a gpu that hasn't managed to load firmware and hw_init() yet, stash the gpu ptr in the adreno device's drvdata, and don't set priv->gpu() until hw_init() succeeds. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 5 +- drivers/gpu/drm/msm/adreno/adreno_device.c | 78 +++++++++++++++--------------- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 45 +++++++++++------ drivers/gpu/drm/msm/msm_drv.c | 10 ---- 4 files changed, 73 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 17c59d839e6f..f44ca0ef4ae9 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -536,13 +536,12 @@ static int a5xx_hw_init(struct msm_gpu *gpu) REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x00000000); gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000); - /* Load the GPMU firmware before starting the HW init */ - a5xx_gpmu_ucode_init(gpu); - ret = adreno_hw_init(gpu); if (ret) return ret; + a5xx_gpmu_ucode_init(gpu); + ret = a5xx_ucode_init(gpu); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index c75c4df4bc39..05022ea2a007 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -125,51 +125,24 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; - struct adreno_platform_config *config; - struct adreno_rev rev; - const struct adreno_info *info; - struct msm_gpu *gpu = NULL; + struct msm_gpu *gpu = platform_get_drvdata(priv->gpu_pdev); + int ret; - if (!pdev) { + if (!gpu) { dev_err(dev->dev, "no adreno device\n"); return NULL; } - config = pdev->dev.platform_data; - rev = config->rev; - info = adreno_info(config->rev); - - if (!info) { - dev_warn(dev->dev, "Unknown GPU revision: %u.%u.%u.%u\n", - rev.core, rev.major, rev.minor, rev.patchid); + pm_runtime_get_sync(&pdev->dev); + mutex_lock(&dev->struct_mutex); + ret = msm_gpu_hw_init(gpu); + mutex_unlock(&dev->struct_mutex); + pm_runtime_put_sync(&pdev->dev); + if (ret) { + dev_err(dev->dev, "gpu hw init failed: %d\n", ret); return NULL; } - DBG("Found GPU: %u.%u.%u.%u", rev.core, rev.major, - rev.minor, rev.patchid); - - gpu = info->init(dev); - if (IS_ERR(gpu)) { - dev_warn(dev->dev, "failed to load adreno gpu\n"); - gpu = NULL; - /* not fatal */ - } - - if (gpu) { - int ret; - - pm_runtime_get_sync(&pdev->dev); - mutex_lock(&dev->struct_mutex); - ret = msm_gpu_hw_init(gpu); - mutex_unlock(&dev->struct_mutex); - pm_runtime_put_sync(&pdev->dev); - if (ret) { - dev_err(dev->dev, "gpu hw init failed: %d\n", ret); - gpu->funcs->destroy(gpu); - gpu = NULL; - } - } - return gpu; } @@ -282,6 +255,9 @@ static int adreno_get_pwrlevels(struct device *dev, static int adreno_bind(struct device *dev, struct device *master, void *data) { static struct adreno_platform_config config = {}; + const struct adreno_info *info; + struct drm_device *drm = dev_get_drvdata(master); + struct msm_gpu *gpu; u32 val; int ret; @@ -302,13 +278,39 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) return ret; dev->platform_data = &config; - set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev)); + set_gpu_pdev(drm, to_platform_device(dev)); + + info = adreno_info(config.rev); + + if (!info) { + dev_warn(drm->dev, "Unknown GPU revision: %u.%u.%u.%u\n", + config.rev.core, config.rev.major, + config.rev.minor, config.rev.patchid); + return -ENXIO; + } + + DBG("Found GPU: %u.%u.%u.%u", config.rev.core, config.rev.major, + config.rev.minor, config.rev.patchid); + + gpu = info->init(drm); + if (IS_ERR(gpu)) { + dev_warn(drm->dev, "failed to load adreno gpu\n"); + return PTR_ERR(gpu); + } + + dev_set_drvdata(dev, gpu); + return 0; } static void adreno_unbind(struct device *dev, struct device *master, void *data) { + struct msm_gpu *gpu = dev_get_drvdata(dev); + + gpu->funcs->pm_suspend(gpu); + gpu->funcs->destroy(gpu); + set_gpu_pdev(dev_get_drvdata(master), NULL); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index c8b4ac254bb5..8caa7f1f012d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -64,6 +64,33 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) } } +static int adreno_load_fw(struct adreno_gpu *adreno_gpu) +{ + struct drm_device *drm = adreno_gpu->base.dev; + int ret; + + if (adreno_gpu->pm4) + return 0; + + ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); + if (ret) { + dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", + adreno_gpu->info->pm4fw, ret); + return ret; + } + + ret = request_firmware(&adreno_gpu->pfp, adreno_gpu->info->pfpfw, drm->dev); + if (ret) { + dev_err(drm->dev, "failed to load %s PFP firmware: %d\n", + adreno_gpu->info->pfpfw, ret); + release_firmware(adreno_gpu->pm4); + adreno_gpu->pm4 = NULL; + return ret; + } + + return 0; +} + int adreno_hw_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -71,6 +98,10 @@ int adreno_hw_init(struct msm_gpu *gpu) DBG("%s", gpu->name); + ret = adreno_load_fw(adreno_gpu); + if (ret) + return ret; + ret = msm_gem_get_iova(gpu->rb->bo, gpu->aspace, &gpu->rb_iova); if (ret) { gpu->rb_iova = 0; @@ -377,20 +408,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, if (ret) return ret; - ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); - if (ret) { - dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", - adreno_gpu->info->pm4fw, ret); - return ret; - } - - ret = request_firmware(&adreno_gpu->pfp, adreno_gpu->info->pfpfw, drm->dev); - if (ret) { - dev_err(drm->dev, "failed to load %s PFP firmware: %d\n", - adreno_gpu->info->pfpfw, ret); - return ret; - } - adreno_gpu->memptrs = msm_gem_kernel_new(drm, sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED, gpu->aspace, &adreno_gpu->memptrs_bo, &adreno_gpu->memptrs_iova); diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 606df7bea97b..d4d4146b3425 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -211,7 +211,6 @@ static int msm_drm_uninit(struct device *dev) struct drm_device *ddev = platform_get_drvdata(pdev); struct msm_drm_private *priv = ddev->dev_private; struct msm_kms *kms = priv->kms; - struct msm_gpu *gpu = priv->gpu; struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl; struct vblank_event *vbl_ev, *tmp; @@ -253,15 +252,6 @@ static int msm_drm_uninit(struct device *dev) if (kms && kms->funcs) kms->funcs->destroy(kms); - if (gpu) { - mutex_lock(&ddev->struct_mutex); - // XXX what do we do here? - //pm_runtime_enable(&pdev->dev); - gpu->funcs->pm_suspend(gpu); - mutex_unlock(&ddev->struct_mutex); - gpu->funcs->destroy(gpu); - } - if (priv->vram.paddr) { unsigned long attrs = DMA_ATTR_NO_KERNEL_MAPPING; drm_mm_takedown(&priv->vram.mm); -- cgit v1.2.3 From e8f3de96a9d36813beba892fec18b05a1e39a122 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 16 Oct 2017 10:13:15 -0400 Subject: drm/msm/adreno: split out helper to load fw Prep work for the next patch. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 11 +++++----- drivers/gpu/drm/msm/adreno/a5xx_power.c | 3 ++- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 36 ++++++++++++++++++++++----------- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 2 ++ 4 files changed, 34 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index f44ca0ef4ae9..4854c659927c 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -26,8 +26,9 @@ static void a5xx_dump(struct msm_gpu *gpu); #define GPU_PAS_ID 13 -static int zap_shader_load_mdt(struct device *dev, const char *fwname) +static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname) { + struct device *dev = &gpu->pdev->dev; const struct firmware *fw; struct device_node *np; struct resource r; @@ -55,10 +56,10 @@ static int zap_shader_load_mdt(struct device *dev, const char *fwname) mem_size = resource_size(&r); /* Request the MDT file for the firmware */ - ret = request_firmware(&fw, fwname, dev); - if (ret) { + fw = adreno_request_fw(to_adreno_gpu(gpu), fwname); + if (IS_ERR(fw)) { DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname); - return ret; + return PTR_ERR(fw); } /* Figure out how much memory we need */ @@ -381,7 +382,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu) return -ENODEV; } - ret = zap_shader_load_mdt(&pdev->dev, adreno_gpu->info->zapfw); + ret = zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw); loaded = !ret; diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index 04aab1dcae2b..b5de2be67732 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -264,7 +264,8 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) return; /* Get the firmware */ - if (request_firmware(&fw, adreno_gpu->info->gpmufw, drm->dev)) { + fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->gpmufw); + if (IS_ERR(fw)) { DRM_ERROR("%s: Could not get GPMU firmware. GPMU will not be active\n", gpu->name); return; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 8caa7f1f012d..54f77045ff60 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -64,29 +64,41 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) } } -static int adreno_load_fw(struct adreno_gpu *adreno_gpu) +const struct firmware * +adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname) { struct drm_device *drm = adreno_gpu->base.dev; + const struct firmware *fw = NULL; int ret; + ret = request_firmware(&fw, fwname, drm->dev); + if (ret) { + dev_err(drm->dev, "failed to load %s: %d\n", fwname, ret); + return ERR_PTR(ret); + } + + return fw; +} + +static int adreno_load_fw(struct adreno_gpu *adreno_gpu) +{ + const struct firmware *fw; + if (adreno_gpu->pm4) return 0; - ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); - if (ret) { - dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", - adreno_gpu->info->pm4fw, ret); - return ret; - } + fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pm4fw); + if (IS_ERR(fw)) + return PTR_ERR(fw); + adreno_gpu->pm4 = fw; - ret = request_firmware(&adreno_gpu->pfp, adreno_gpu->info->pfpfw, drm->dev); - if (ret) { - dev_err(drm->dev, "failed to load %s PFP firmware: %d\n", - adreno_gpu->info->pfpfw, ret); + fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->pfpfw); + if (IS_ERR(fw)) { release_firmware(adreno_gpu->pm4); adreno_gpu->pm4 = NULL; - return ret; + return PTR_ERR(fw); } + adreno_gpu->pfp = fw; return 0; } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 4d9165f29f43..3eda98af546e 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -196,6 +196,8 @@ static inline int adreno_is_a530(struct adreno_gpu *gpu) } int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value); +const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu, + const char *fwname); int adreno_hw_init(struct msm_gpu *gpu); uint32_t adreno_last_fence(struct msm_gpu *gpu); void adreno_recover(struct msm_gpu *gpu); -- cgit v1.2.3 From 2c41ef1b6f7d791f61a09bbabbb4f8fc4736d508 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 16 Oct 2017 10:46:23 -0400 Subject: drm/msm/adreno: deal with linux-firmware fw paths When firmware was added to linux-firmware, it was put in a qcom sub- directory, unlike what we'd been using before. For a300_pfp.fw and a300_pm4.fw symlinks were created, but we'd prefer not to have to do this in the future. So add support to look in both places when loading firmware. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 23 +++++++++-- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 67 ++++++++++++++++++++++++++++++--- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 21 +++++++++++ 3 files changed, 103 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 4854c659927c..9fa905434590 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -76,9 +76,26 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname) goto out; } - /* Load the rest of the MDT */ - ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID, mem_region, mem_phys, - mem_size); + /* + * Load the rest of the MDT + * + * Note that we could be dealing with two different paths, since + * with upstream linux-firmware it would be in a qcom/ subdir.. + * adreno_request_fw() handles this, but qcom_mdt_load() does + * not. But since we've already gotten thru adreno_request_fw() + * we know which of the two cases it is: + */ + if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) { + ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID, + mem_region, mem_phys, mem_size); + } else { + char newname[strlen("qcom/") + strlen(fwname) + 1]; + + sprintf(newname, "qcom/%s", fwname); + + ret = qcom_mdt_load(dev, fw, newname, GPU_PAS_ID, + mem_region, mem_phys, mem_size); + } if (ret) goto out; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 54f77045ff60..76416b5238ad 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -69,15 +69,72 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname) { struct drm_device *drm = adreno_gpu->base.dev; const struct firmware *fw = NULL; + char newname[strlen("qcom/") + strlen(fwname) + 1]; int ret; - ret = request_firmware(&fw, fwname, drm->dev); - if (ret) { - dev_err(drm->dev, "failed to load %s: %d\n", fwname, ret); - return ERR_PTR(ret); + sprintf(newname, "qcom/%s", fwname); + + /* + * Try first to load from qcom/$fwfile using a direct load (to avoid + * a potential timeout waiting for usermode helper) + */ + if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) || + (adreno_gpu->fwloc == FW_LOCATION_NEW)) { + + ret = request_firmware_direct(&fw, newname, drm->dev); + if (!ret) { + dev_info(drm->dev, "loaded %s from new location\n", + newname); + adreno_gpu->fwloc = FW_LOCATION_NEW; + return fw; + } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { + dev_err(drm->dev, "failed to load %s: %d\n", + newname, ret); + return ERR_PTR(ret); + } + } + + /* + * Then try the legacy location without qcom/ prefix + */ + if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) || + (adreno_gpu->fwloc == FW_LOCATION_LEGACY)) { + + ret = request_firmware_direct(&fw, fwname, drm->dev); + if (!ret) { + dev_info(drm->dev, "loaded %s from legacy location\n", + newname); + adreno_gpu->fwloc = FW_LOCATION_LEGACY; + return fw; + } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { + dev_err(drm->dev, "failed to load %s: %d\n", + fwname, ret); + return ERR_PTR(ret); + } + } + + /* + * Finally fall back to request_firmware() for cases where the + * usermode helper is needed (I think mainly android) + */ + if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) || + (adreno_gpu->fwloc == FW_LOCATION_HELPER)) { + + ret = request_firmware(&fw, newname, drm->dev); + if (!ret) { + dev_info(drm->dev, "loaded %s with helper\n", + newname); + adreno_gpu->fwloc = FW_LOCATION_HELPER; + return fw; + } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { + dev_err(drm->dev, "failed to load %s: %d\n", + newname, ret); + return ERR_PTR(ret); + } } - return fw; + dev_err(drm->dev, "failed to load %s\n", fwname); + return ERR_PTR(-ENOENT); } static int adreno_load_fw(struct adreno_gpu *adreno_gpu) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 3eda98af546e..b8c22658929d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -101,6 +101,27 @@ struct adreno_gpu { /* interesting register offsets to dump: */ const unsigned int *registers; + /* + * Are we loading fw from legacy path? Prior to addition + * of gpu firmware to linux-firmware, the fw files were + * placed in toplevel firmware directory, following qcom's + * android kernel. But linux-firmware preferred they be + * placed in a 'qcom' subdirectory. + * + * For backwards compatibility, we try first to load from + * the new path, using request_firmware_direct() to avoid + * any potential timeout waiting for usermode helper, then + * fall back to the old path (with direct load). And + * finally fall back to request_firmware() with the new + * path to allow the usermode helper. + */ + enum { + FW_LOCATION_UNKNOWN = 0, + FW_LOCATION_NEW, /* /lib/firmware/qcom/$fwfile */ + FW_LOCATION_LEGACY, /* /lib/firmware/$fwfile */ + FW_LOCATION_HELPER, + } fwloc; + /* firmware: */ const struct firmware *pm4, *pfp; -- cgit v1.2.3 From e9acce2bb94c1db47fd0463c8d16ba9794111ca5 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 16 Oct 2017 12:52:48 -0400 Subject: drm/msm/mdp5: always print mdp5 version This is useful to see in the log, without requiring drm.debug. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 7e829a8d1cb1..494b2936502d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -501,7 +501,7 @@ static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms, *major = FIELD(version, MDP5_HW_VERSION_MAJOR); *minor = FIELD(version, MDP5_HW_VERSION_MINOR); - DBG("MDP5 version v%d.%d", *major, *minor); + dev_info(dev, "MDP5 version v%d.%d", *major, *minor); } static int get_clk(struct platform_device *pdev, struct clk **clkp, -- cgit v1.2.3 From db9a3750eb6fec2381b4090b4f10e56fafe512fe Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 16 Oct 2017 13:35:57 -0400 Subject: drm/msm/dsi: convert to msm_clk_get() We already have, as a result of upstreaming the gpu bindings, msm_clk_get() which will try to get the clock both without and with a "_clk" suffix. Use this in DSI code so we can drop the "_clk" suffix in bindings while maintaing backwards compatibility. Signed-off-by: Rob Clark Reviewed-by: Sean Paul --- drivers/gpu/drm/msm/dsi/dsi_cfg.c | 8 ++++---- drivers/gpu/drm/msm/dsi/dsi_host.c | 30 +++++++++++++++--------------- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index a5d75c9b3a73..65c1dfbbe019 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -14,7 +14,7 @@ #include "dsi_cfg.h" static const char * const dsi_v2_bus_clk_names[] = { - "core_mmss_clk", "iface_clk", "bus_clk", + "core_mmss", "iface", "bus", }; static const struct msm_dsi_config apq8064_dsi_cfg = { @@ -34,7 +34,7 @@ static const struct msm_dsi_config apq8064_dsi_cfg = { }; static const char * const dsi_6g_bus_clk_names[] = { - "mdp_core_clk", "iface_clk", "bus_clk", "core_mmss_clk", + "mdp_core", "iface", "bus", "core_mmss", }; static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = { @@ -55,7 +55,7 @@ static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = { }; static const char * const dsi_8916_bus_clk_names[] = { - "mdp_core_clk", "iface_clk", "bus_clk", + "mdp_core", "iface", "bus", }; static const struct msm_dsi_config msm8916_dsi_cfg = { @@ -99,7 +99,7 @@ static const struct msm_dsi_config msm8994_dsi_cfg = { * without it too. Figure out why it doesn't enable and uncomment below */ static const char * const dsi_8996_bus_clk_names[] = { - "mdp_core_clk", "iface_clk", "bus_clk", /* "core_mmss_clk", */ + "mdp_core", "iface", "bus", /* "core_mmss", */ }; static const struct msm_dsi_config msm8996_dsi_cfg = { diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index dbb31a014419..50d437568d43 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -334,46 +334,46 @@ static int dsi_regulator_init(struct msm_dsi_host *msm_host) static int dsi_clk_init(struct msm_dsi_host *msm_host) { - struct device *dev = &msm_host->pdev->dev; + struct platform_device *pdev = msm_host->pdev; const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; const struct msm_dsi_config *cfg = cfg_hnd->cfg; int i, ret = 0; /* get bus clocks */ for (i = 0; i < cfg->num_bus_clks; i++) { - msm_host->bus_clks[i] = devm_clk_get(dev, + msm_host->bus_clks[i] = msm_clk_get(pdev, cfg->bus_clk_names[i]); if (IS_ERR(msm_host->bus_clks[i])) { ret = PTR_ERR(msm_host->bus_clks[i]); - pr_err("%s: Unable to get %s, ret = %d\n", + pr_err("%s: Unable to get %s clock, ret = %d\n", __func__, cfg->bus_clk_names[i], ret); goto exit; } } /* get link and source clocks */ - msm_host->byte_clk = devm_clk_get(dev, "byte_clk"); + msm_host->byte_clk = msm_clk_get(pdev, "byte"); if (IS_ERR(msm_host->byte_clk)) { ret = PTR_ERR(msm_host->byte_clk); - pr_err("%s: can't find dsi_byte_clk. ret=%d\n", + pr_err("%s: can't find dsi_byte clock. ret=%d\n", __func__, ret); msm_host->byte_clk = NULL; goto exit; } - msm_host->pixel_clk = devm_clk_get(dev, "pixel_clk"); + msm_host->pixel_clk = msm_clk_get(pdev, "pixel"); if (IS_ERR(msm_host->pixel_clk)) { ret = PTR_ERR(msm_host->pixel_clk); - pr_err("%s: can't find dsi_pixel_clk. ret=%d\n", + pr_err("%s: can't find dsi_pixel clock. ret=%d\n", __func__, ret); msm_host->pixel_clk = NULL; goto exit; } - msm_host->esc_clk = devm_clk_get(dev, "core_clk"); + msm_host->esc_clk = msm_clk_get(pdev, "core"); if (IS_ERR(msm_host->esc_clk)) { ret = PTR_ERR(msm_host->esc_clk); - pr_err("%s: can't find dsi_esc_clk. ret=%d\n", + pr_err("%s: can't find dsi_esc clock. ret=%d\n", __func__, ret); msm_host->esc_clk = NULL; goto exit; @@ -382,22 +382,22 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host) msm_host->byte_clk_src = clk_get_parent(msm_host->byte_clk); if (!msm_host->byte_clk_src) { ret = -ENODEV; - pr_err("%s: can't find byte_clk_src. ret=%d\n", __func__, ret); + pr_err("%s: can't find byte_clk clock. ret=%d\n", __func__, ret); goto exit; } msm_host->pixel_clk_src = clk_get_parent(msm_host->pixel_clk); if (!msm_host->pixel_clk_src) { ret = -ENODEV; - pr_err("%s: can't find pixel_clk_src. ret=%d\n", __func__, ret); + pr_err("%s: can't find pixel_clk clock. ret=%d\n", __func__, ret); goto exit; } if (cfg_hnd->major == MSM_DSI_VER_MAJOR_V2) { - msm_host->src_clk = devm_clk_get(dev, "src_clk"); + msm_host->src_clk = msm_clk_get(pdev, "src"); if (IS_ERR(msm_host->src_clk)) { ret = PTR_ERR(msm_host->src_clk); - pr_err("%s: can't find dsi_src_clk. ret=%d\n", + pr_err("%s: can't find src clock. ret=%d\n", __func__, ret); msm_host->src_clk = NULL; goto exit; @@ -406,7 +406,7 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host) msm_host->esc_clk_src = clk_get_parent(msm_host->esc_clk); if (!msm_host->esc_clk_src) { ret = -ENODEV; - pr_err("%s: can't get esc_clk_src. ret=%d\n", + pr_err("%s: can't get esc clock parent. ret=%d\n", __func__, ret); goto exit; } @@ -414,7 +414,7 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host) msm_host->dsi_clk_src = clk_get_parent(msm_host->src_clk); if (!msm_host->dsi_clk_src) { ret = -ENODEV; - pr_err("%s: can't get dsi_clk_src. ret=%d\n", + pr_err("%s: can't get src clock parent. ret=%d\n", __func__, ret); } } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 7c9bf91bc22b..790ca280cbfd 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -482,7 +482,7 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) goto fail; } - phy->ahb_clk = devm_clk_get(dev, "iface_clk"); + phy->ahb_clk = msm_clk_get(pdev, "iface"); if (IS_ERR(phy->ahb_clk)) { dev_err(dev, "%s: Unable to get ahb clk\n", __func__); ret = PTR_ERR(phy->ahb_clk); -- cgit v1.2.3 From cf52ec24b2c64fab3146991071d410f389a0bc9c Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 16 Oct 2017 16:39:59 -0400 Subject: drm/msm/edp: convert to msm_clk_get() We already have, as a result of upstreaming the gpu bindings, msm_clk_get() which will try to get the clock both without and with a "_clk" suffix. Use this in eDP code so we can drop the "_clk" suffix in bindings while maintaing backwards compatibility. Signed-off-by: Rob Clark Reviewed-by: Sean Paul --- drivers/gpu/drm/msm/edp/edp_ctrl.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c b/drivers/gpu/drm/msm/edp/edp_ctrl.c index e32a4a4f3797..7c72264101ff 100644 --- a/drivers/gpu/drm/msm/edp/edp_ctrl.c +++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c @@ -150,46 +150,46 @@ static const struct edp_pixel_clk_div clk_divs[2][EDP_PIXEL_CLK_NUM] = { static int edp_clk_init(struct edp_ctrl *ctrl) { - struct device *dev = &ctrl->pdev->dev; + struct platform_device *pdev = ctrl->pdev; int ret; - ctrl->aux_clk = devm_clk_get(dev, "core_clk"); + ctrl->aux_clk = msm_clk_get(pdev, "core"); if (IS_ERR(ctrl->aux_clk)) { ret = PTR_ERR(ctrl->aux_clk); - pr_err("%s: Can't find aux_clk, %d\n", __func__, ret); + pr_err("%s: Can't find core clock, %d\n", __func__, ret); ctrl->aux_clk = NULL; return ret; } - ctrl->pixel_clk = devm_clk_get(dev, "pixel_clk"); + ctrl->pixel_clk = msm_clk_get(pdev, "pixel"); if (IS_ERR(ctrl->pixel_clk)) { ret = PTR_ERR(ctrl->pixel_clk); - pr_err("%s: Can't find pixel_clk, %d\n", __func__, ret); + pr_err("%s: Can't find pixel clock, %d\n", __func__, ret); ctrl->pixel_clk = NULL; return ret; } - ctrl->ahb_clk = devm_clk_get(dev, "iface_clk"); + ctrl->ahb_clk = msm_clk_get(pdev, "iface"); if (IS_ERR(ctrl->ahb_clk)) { ret = PTR_ERR(ctrl->ahb_clk); - pr_err("%s: Can't find ahb_clk, %d\n", __func__, ret); + pr_err("%s: Can't find iface clock, %d\n", __func__, ret); ctrl->ahb_clk = NULL; return ret; } - ctrl->link_clk = devm_clk_get(dev, "link_clk"); + ctrl->link_clk = msm_clk_get(pdev, "link"); if (IS_ERR(ctrl->link_clk)) { ret = PTR_ERR(ctrl->link_clk); - pr_err("%s: Can't find link_clk, %d\n", __func__, ret); + pr_err("%s: Can't find link clock, %d\n", __func__, ret); ctrl->link_clk = NULL; return ret; } /* need mdp core clock to receive irq */ - ctrl->mdp_core_clk = devm_clk_get(dev, "mdp_core_clk"); + ctrl->mdp_core_clk = msm_clk_get(pdev, "mdp_core"); if (IS_ERR(ctrl->mdp_core_clk)) { ret = PTR_ERR(ctrl->mdp_core_clk); - pr_err("%s: Can't find mdp_core_clk, %d\n", __func__, ret); + pr_err("%s: Can't find mdp_core clock, %d\n", __func__, ret); ctrl->mdp_core_clk = NULL; return ret; } -- cgit v1.2.3 From aede1e9ee4ec3d7a7b996d260ce7297a6b4dc4ca Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 16 Oct 2017 16:56:28 -0400 Subject: drm/msm/hdmi: convert to msm_clk_get() We already have, as a result of upstreaming the gpu bindings, msm_clk_get() which will try to get the clock both without and with a "_clk" suffix. Use this in HDMI code so we can drop the "_clk" suffix in bindings while maintaing backwards compatibility. Signed-off-by: Rob Clark Reviewed-by: Sean Paul --- drivers/gpu/drm/msm/hdmi/hdmi.c | 10 +++++----- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 2 +- drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | 2 +- drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 3 +-- drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c | 3 +-- 5 files changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 17e069a133a4..e63dc0fb55f8 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -208,7 +208,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) for (i = 0; i < config->hpd_clk_cnt; i++) { struct clk *clk; - clk = devm_clk_get(&pdev->dev, config->hpd_clk_names[i]); + clk = msm_clk_get(pdev, config->hpd_clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(&pdev->dev, "failed to get hpd clk: %s (%d)\n", @@ -228,7 +228,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) for (i = 0; i < config->pwr_clk_cnt; i++) { struct clk *clk; - clk = devm_clk_get(&pdev->dev, config->pwr_clk_names[i]); + clk = msm_clk_get(pdev, config->pwr_clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(&pdev->dev, "failed to get pwr clk: %s (%d)\n", @@ -361,7 +361,7 @@ static const char *hpd_reg_names_none[] = {}; static struct hdmi_platform_config hdmi_tx_8660_config; static const char *hpd_reg_names_8960[] = {"core-vdda", "hdmi-mux"}; -static const char *hpd_clk_names_8960[] = {"core_clk", "master_iface_clk", "slave_iface_clk"}; +static const char *hpd_clk_names_8960[] = {"core", "master_iface", "slave_iface"}; static struct hdmi_platform_config hdmi_tx_8960_config = { HDMI_CFG(hpd_reg, 8960), @@ -370,8 +370,8 @@ static struct hdmi_platform_config hdmi_tx_8960_config = { static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"}; static const char *hpd_reg_names_8x74[] = {"hpd-gdsc", "hpd-5v"}; -static const char *pwr_clk_names_8x74[] = {"extp_clk", "alt_iface_clk"}; -static const char *hpd_clk_names_8x74[] = {"iface_clk", "core_clk", "mdp_core_clk"}; +static const char *pwr_clk_names_8x74[] = {"extp", "alt_iface"}; +static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core"}; static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0}; static struct hdmi_platform_config hdmi_tx_8974_config = { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 534ce5b49781..5e631392dc85 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -48,7 +48,7 @@ static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy) for (i = 0; i < cfg->num_clks; i++) { struct clk *clk; - clk = devm_clk_get(dev, cfg->clk_names[i]); + clk = msm_clk_get(phy->pdev, cfg->clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(dev, "failed to get phy clock: %s (%d)\n", diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c index e6ee6b745ab7..0980da8ec966 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c @@ -48,7 +48,7 @@ static const char * const hdmi_phy_8960_reg_names[] = { }; static const char * const hdmi_phy_8960_clk_names[] = { - "slave_iface_clk", + "slave_iface", }; const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg = { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c index 4d580a86c2e2..0df504c61833 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c @@ -758,8 +758,7 @@ static const char * const hdmi_phy_8996_reg_names[] = { }; static const char * const hdmi_phy_8996_clk_names[] = { - "iface_clk", - "ref_clk", + "iface", "ref", }; const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c index c4a61e537851..4a8b8468586a 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c @@ -41,8 +41,7 @@ static const char * const hdmi_phy_8x74_reg_names[] = { }; static const char * const hdmi_phy_8x74_clk_names[] = { - "iface_clk", - "alt_iface_clk" + "iface", "alt_iface" }; const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg = { -- cgit v1.2.3 From cae923e6bf2168d1e332977e1de224ee5da1a32c Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 17 Oct 2017 09:39:39 -0400 Subject: drm/msm/mdp4: disable vblanks when crtc is off Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 47fa2aba1983..14bd3bd3e040 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -290,6 +290,9 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, if (WARN_ON(!mdp4_crtc->enabled)) return; + /* Disable/save vblank irq handling before power is disabled */ + drm_crtc_vblank_off(crtc); + mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); mdp4_disable(mdp4_kms); @@ -308,6 +311,10 @@ static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc, return; mdp4_enable(mdp4_kms); + + /* Restore vblank irq handling after power is enabled */ + drm_crtc_vblank_on(crtc); + mdp_irq_register(&mdp4_kms->base, &mdp4_crtc->err); crtc_flush(crtc); -- cgit v1.2.3 From 0033e1b523f6d6a60ff7beaaa923cd7656a72959 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 17 Oct 2017 09:39:53 -0400 Subject: drm/msm/mdp5: disable vblanks when crtc is off Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 6fcb58ab718c..436bf628ef9c 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -422,6 +422,9 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, if (WARN_ON(!mdp5_crtc->enabled)) return; + /* Disable/save vblank irq handling before power is disabled */ + drm_crtc_vblank_off(crtc); + if (mdp5_cstate->cmd_mode) mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done); @@ -446,6 +449,9 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, pm_runtime_get_sync(dev); + /* Restore vblank irq handling after power is enabled */ + drm_crtc_vblank_on(crtc); + mdp5_crtc_mode_set_nofb(crtc); mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); -- cgit v1.2.3 From f7de15450e906ed6586b29bde609a5686cd0d034 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:06:55 -0600 Subject: drm/msm: Add per-instance submit queues Currently the behavior of a command stream is provided by the user application during submission and the application is expected to internally maintain the settings for each 'context' or 'rendering queue' and specify the correct ones. This works okay for simple cases but as applications become more complex we will want to set context specific flags and do various permission checks to allow certain contexts to enable additional privileges. Add kernel-side submit queues to be analogous to 'contexts' or 'rendering queues' on the application side. Each file descriptor instance will maintain its own list of queues. Queues cannot be shared between file descriptors. For backwards compatibility context id '0' is defined as a default context specifying no priority and no special flags. This is intended to be the usual configuration for 99% of applications so that a garden variety application can function correctly without creating a queue. Only those applications requiring the specific benefit of different queues need create one. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/msm_drv.c | 56 ++++++++++++-- drivers/gpu/drm/msm/msm_drv.h | 20 +++-- drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++- drivers/gpu/drm/msm/msm_gpu.h | 15 ++++ drivers/gpu/drm/msm/msm_submitqueue.c | 135 ++++++++++++++++++++++++++++++++++ include/uapi/drm/msm_drm.h | 22 ++++++ 8 files changed, 250 insertions(+), 16 deletions(-) create mode 100644 drivers/gpu/drm/msm/msm_submitqueue.c (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 33008fa1be9b..3c234e7b4742 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -57,7 +57,8 @@ msm-y := \ msm_iommu.o \ msm_perf.o \ msm_rd.o \ - msm_ringbuffer.o + msm_ringbuffer.o \ + msm_submitqueue.o msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index d4d4146b3425..2585bebfcf3e 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -29,9 +29,12 @@ * - 1.0.0 - initial interface * - 1.1.0 - adds madvise, and support for submits with > 4 cmd buffers * - 1.2.0 - adds explicit fence support for submit ioctl + * - 1.3.0 - adds GMEM_BASE + NR_RINGS params, SUBMITQUEUE_NEW + + * SUBMITQUEUE_CLOSE ioctls, and MSM_INFO_IOVA flag for + * MSM_GEM_INFO ioctl. */ #define MSM_VERSION_MAJOR 1 -#define MSM_VERSION_MINOR 2 +#define MSM_VERSION_MINOR 3 #define MSM_VERSION_PATCHLEVEL 0 static void msm_fb_output_poll_changed(struct drm_device *dev) @@ -504,24 +507,37 @@ static void load_gpu(struct drm_device *dev) mutex_unlock(&init_lock); } -static int msm_open(struct drm_device *dev, struct drm_file *file) +static int context_init(struct drm_file *file) { struct msm_file_private *ctx; - /* For now, load gpu on open.. to avoid the requirement of having - * firmware in the initrd. - */ - load_gpu(dev); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + msm_submitqueue_init(ctx); + file->driver_priv = ctx; return 0; } +static int msm_open(struct drm_device *dev, struct drm_file *file) +{ + /* For now, load gpu on open.. to avoid the requirement of having + * firmware in the initrd. + */ + load_gpu(dev); + + return context_init(file); +} + +static void context_close(struct msm_file_private *ctx) +{ + msm_submitqueue_close(ctx); + kfree(ctx); +} + static void msm_postclose(struct drm_device *dev, struct drm_file *file) { struct msm_drm_private *priv = dev->dev_private; @@ -532,7 +548,7 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file) priv->lastctx = NULL; mutex_unlock(&dev->struct_mutex); - kfree(ctx); + context_close(ctx); } static void msm_lastclose(struct drm_device *dev) @@ -777,6 +793,28 @@ unlock: return ret; } + +static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_msm_submitqueue *args = data; + + if (args->flags & ~MSM_SUBMITQUEUE_FLAGS) + return -EINVAL; + + return msm_submitqueue_create(file->driver_priv, args->prio, + args->flags, &args->id); +} + + +static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data, + struct drm_file *file) +{ + u32 id = *(u32 *) data; + + return msm_submitqueue_remove(file->driver_priv, id); +} + static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_GET_PARAM, msm_ioctl_get_param, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_AUTH|DRM_RENDER_ALLOW), @@ -786,6 +824,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT, msm_ioctl_gem_submit, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE, msm_ioctl_wait_fence, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_GEM_MADVISE, msm_ioctl_gem_madvise, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW, msm_ioctl_submitqueue_new, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_AUTH|DRM_RENDER_ALLOW), }; static const struct vm_operations_struct vm_ops = { diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 5e8109c07560..b3b8f20f58db 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -56,11 +56,9 @@ struct msm_gem_address_space; struct msm_gem_vma; struct msm_file_private { - /* currently we don't do anything useful with this.. but when - * per-context address spaces are supported we'd keep track of - * the context's page-tables here. - */ - int dummy; + rwlock_t queuelock; + struct list_head submitqueues; + int queueid; }; enum msm_mdp_plane_property { @@ -319,6 +317,18 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, void msm_writel(u32 data, void __iomem *addr); u32 msm_readl(const void __iomem *addr); +struct msm_gpu_submitqueue; +int msm_submitqueue_init(struct msm_file_private *ctx); +struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx, + u32 id); +int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio, + u32 flags, u32 *id); +int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id); +void msm_submitqueue_close(struct msm_file_private *ctx); + +void msm_submitqueue_destroy(struct kref *kref); + + #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__) #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__) diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 91c210d2359c..17f8a6c23464 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -142,6 +142,7 @@ struct msm_gem_submit { struct list_head bo_list; struct ww_acquire_ctx ticket; struct dma_fence *fence; + struct msm_gpu_submitqueue *queue; struct pid *pid; /* submitting process */ bool valid; /* true if no cmdstream patching needed */ unsigned int nr_cmds; diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 93535cac0676..c196cc615e77 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -31,7 +31,8 @@ #define BO_PINNED 0x2000 static struct msm_gem_submit *submit_create(struct drm_device *dev, - struct msm_gpu *gpu, uint32_t nr_bos, uint32_t nr_cmds) + struct msm_gpu *gpu, struct msm_gpu_submitqueue *queue, + uint32_t nr_bos, uint32_t nr_cmds) { struct msm_gem_submit *submit; uint64_t sz = sizeof(*submit) + ((u64)nr_bos * sizeof(submit->bos[0])) + @@ -49,6 +50,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, submit->fence = NULL; submit->pid = get_pid(task_pid(current)); submit->cmd = (void *)&submit->bos[nr_bos]; + submit->queue = queue; /* initially, until copy_from_user() and bo lookup succeeds: */ submit->nr_bos = 0; @@ -66,6 +68,8 @@ void msm_gem_submit_free(struct msm_gem_submit *submit) dma_fence_put(submit->fence); list_del(&submit->node); put_pid(submit->pid); + msm_submitqueue_put(submit->queue); + kfree(submit); } @@ -405,6 +409,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct msm_gpu *gpu = priv->gpu; struct dma_fence *in_fence = NULL; struct sync_file *sync_file = NULL; + struct msm_gpu_submitqueue *queue; int out_fence_fd = -1; unsigned i; int ret; @@ -421,6 +426,10 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS) return -EINVAL; + queue = msm_submitqueue_get(ctx, args->queueid); + if (!queue) + return -ENOENT; + if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { in_fence = sync_file_get_fence(args->fence_fd); @@ -451,7 +460,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, } priv->struct_mutex_task = current; - submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); + submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds); if (!submit) { ret = -ENOMEM; goto out_unlock; @@ -535,6 +544,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, submit->nr_cmds = i; submit->fence = msm_fence_alloc(gpu->fctx); + if (IS_ERR(submit->fence)) { ret = PTR_ERR(submit->fence); submit->fence = NULL; diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index df4e2771fb85..a890176c27ce 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -150,6 +150,15 @@ struct msm_gpu_perfcntr { const char *name; }; +struct msm_gpu_submitqueue { + int id; + u32 flags; + u32 prio; + int faults; + struct list_head node; + struct kref ref; +}; + static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data) { msm_writel(data, gpu->mmio + (reg << 2)); @@ -223,4 +232,10 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev); void __init adreno_register(void); void __exit adreno_unregister(void); +static inline void msm_submitqueue_put(struct msm_gpu_submitqueue *queue) +{ + if (queue) + kref_put(&queue->ref, msm_submitqueue_destroy); +} + #endif /* __MSM_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c new file mode 100644 index 000000000000..593c3b5f44cd --- /dev/null +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -0,0 +1,135 @@ +/* Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "msm_gpu.h" + +void msm_submitqueue_destroy(struct kref *kref) +{ + struct msm_gpu_submitqueue *queue = container_of(kref, + struct msm_gpu_submitqueue, ref); + + kfree(queue); +} + +struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx, + u32 id) +{ + struct msm_gpu_submitqueue *entry; + + if (!ctx) + return NULL; + + read_lock(&ctx->queuelock); + + list_for_each_entry(entry, &ctx->submitqueues, node) { + if (entry->id == id) { + kref_get(&entry->ref); + read_unlock(&ctx->queuelock); + + return entry; + } + } + + read_unlock(&ctx->queuelock); + return NULL; +} + +void msm_submitqueue_close(struct msm_file_private *ctx) +{ + struct msm_gpu_submitqueue *entry, *tmp; + + if (!ctx) + return; + + /* + * No lock needed in close and there won't + * be any more user ioctls coming our way + */ + list_for_each_entry_safe(entry, tmp, &ctx->submitqueues, node) + msm_submitqueue_put(entry); +} + +int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio, u32 flags, + u32 *id) +{ + struct msm_gpu_submitqueue *queue; + + if (!ctx) + return -ENODEV; + + queue = kzalloc(sizeof(*queue), GFP_KERNEL); + + if (!queue) + return -ENOMEM; + + kref_init(&queue->ref); + queue->flags = flags; + queue->prio = prio; + + write_lock(&ctx->queuelock); + + queue->id = ctx->queueid++; + + if (id) + *id = queue->id; + + list_add_tail(&queue->node, &ctx->submitqueues); + + write_unlock(&ctx->queuelock); + + return 0; +} + +int msm_submitqueue_init(struct msm_file_private *ctx) +{ + if (!ctx) + return 0; + + INIT_LIST_HEAD(&ctx->submitqueues); + + rwlock_init(&ctx->queuelock); + + return msm_submitqueue_create(ctx, 2, 0, NULL); +} + +int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id) +{ + struct msm_gpu_submitqueue *entry; + + if (!ctx) + return 0; + + /* + * id 0 is the "default" queue and can't be destroyed + * by the user + */ + if (!id) + return -ENOENT; + + write_lock(&ctx->queuelock); + + list_for_each_entry(entry, &ctx->submitqueues, node) { + if (entry->id == id) { + list_del(&entry->node); + write_unlock(&ctx->queuelock); + + msm_submitqueue_put(entry); + return 0; + } + } + + write_unlock(&ctx->queuelock); + return -ENOENT; +} + diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index ad4eb2863e70..fee44322a69c 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -218,6 +218,7 @@ struct drm_msm_gem_submit { __u64 bos; /* in, ptr to array of submit_bo's */ __u64 cmds; /* in, ptr to array of submit_cmd's */ __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */ + __u32 queueid; /* in, submitqueue id */ }; /* The normal way to synchronize with the GPU is just to CPU_PREP on @@ -254,6 +255,20 @@ struct drm_msm_gem_madvise { __u32 retained; /* out, whether backing store still exists */ }; +/* + * Draw queues allow the user to set specific submission parameter. Command + * submissions specify a specific submitqueue to use. ID 0 is reserved for + * backwards compatibility as a "default" submitqueue + */ + +#define MSM_SUBMITQUEUE_FLAGS (0) + +struct drm_msm_submitqueue { + __u32 flags; /* in, MSM_SUBMITQUEUE_x */ + __u32 prio; /* in, Priority level */ + __u32 id; /* out, identifier */ +}; + #define DRM_MSM_GET_PARAM 0x00 /* placeholder: #define DRM_MSM_SET_PARAM 0x01 @@ -265,6 +280,11 @@ struct drm_msm_gem_madvise { #define DRM_MSM_GEM_SUBMIT 0x06 #define DRM_MSM_WAIT_FENCE 0x07 #define DRM_MSM_GEM_MADVISE 0x08 +/* placeholder: +#define DRM_MSM_GEM_SVM_NEW 0x09 + */ +#define DRM_MSM_SUBMITQUEUE_NEW 0x0A +#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) @@ -274,6 +294,8 @@ struct drm_msm_gem_madvise { #define DRM_IOCTL_MSM_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit) #define DRM_IOCTL_MSM_WAIT_FENCE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence) #define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise) +#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue) +#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32) #if defined(__cplusplus) } -- cgit v1.2.3 From cd414f3d931687eb1ebeb87533d85537e315f195 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:06:56 -0600 Subject: drm/msm: Move memptrs to msm_gpu When we move to multiple ringbuffers we're going to store the data in the memptrs on a per-ring basis. In order to prepare for that move the current memptrs from the adreno namespace into msm_gpu. This is way cleaner and immediately lets us kill off some sub functions so there is much less cost later when we do move to per-ring structs. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 1 - drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 1 - drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 ++--- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 55 +++++++-------------------------- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 16 ---------- drivers/gpu/drm/msm/msm_gpu.c | 32 ++++++++++++++++--- drivers/gpu/drm/msm/msm_gpu.h | 17 ++++++++-- 7 files changed, 58 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 7791313405b5..789f7fb86cba 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -444,7 +444,6 @@ static const struct adreno_gpu_funcs funcs = { .pm_suspend = msm_gpu_pm_suspend, .pm_resume = msm_gpu_pm_resume, .recover = a3xx_recover, - .last_fence = adreno_last_fence, .submit = adreno_submit, .flush = adreno_flush, .irq = a3xx_irq, diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 58341ef6f15b..f87c43124099 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -532,7 +532,6 @@ static const struct adreno_gpu_funcs funcs = { .pm_suspend = a4xx_pm_suspend, .pm_resume = a4xx_pm_resume, .recover = a4xx_recover, - .last_fence = adreno_last_fence, .submit = adreno_submit, .flush = adreno_flush, .irq = a4xx_irq, diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 9fa905434590..e34835c3b55d 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -116,7 +116,6 @@ out: static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { - struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct msm_drm_private *priv = gpu->dev->dev_private; struct msm_ringbuffer *ring = gpu->rb; unsigned int i, ibs = 0; @@ -143,8 +142,8 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, OUT_PKT7(ring, CP_EVENT_WRITE, 4); OUT_RING(ring, CACHE_FLUSH_TS | (1 << 31)); - OUT_RING(ring, lower_32_bits(rbmemptr(adreno_gpu, fence))); - OUT_RING(ring, upper_32_bits(rbmemptr(adreno_gpu, fence))); + OUT_RING(ring, lower_32_bits(rbmemptr(gpu, fence))); + OUT_RING(ring, upper_32_bits(rbmemptr(gpu, fence))); OUT_RING(ring, submit->fence->seqno); gpu->funcs->flush(gpu); @@ -821,7 +820,7 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu) struct msm_drm_private *priv = dev->dev_private; dev_err(dev->dev, "gpu fault fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", - gpu->funcs->last_fence(gpu), + gpu->memptrs->fence, gpu_read(gpu, REG_A5XX_RBBM_STATUS), gpu_read(gpu, REG_A5XX_CP_RB_RPTR), gpu_read(gpu, REG_A5XX_CP_RB_WPTR), @@ -1009,7 +1008,6 @@ static const struct adreno_gpu_funcs funcs = { .pm_suspend = a5xx_pm_suspend, .pm_resume = a5xx_pm_resume, .recover = a5xx_recover, - .last_fence = adreno_last_fence, .submit = a5xx_submit, .flush = adreno_flush, .irq = a5xx_irq, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 76416b5238ad..5f2501c2cd3f 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -182,8 +182,8 @@ int adreno_hw_init(struct msm_gpu *gpu) gpu->rb->cur = gpu->rb->start; /* reset completed fence seqno: */ - adreno_gpu->memptrs->fence = gpu->fctx->completed_fence; - adreno_gpu->memptrs->rptr = 0; + gpu->memptrs->fence = gpu->fctx->completed_fence; + gpu->memptrs->rptr = 0; /* Setup REG_CP_RB_CNTL: */ adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL, @@ -198,8 +198,7 @@ int adreno_hw_init(struct msm_gpu *gpu) if (!adreno_is_a430(adreno_gpu)) { adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR, - REG_ADRENO_CP_RB_RPTR_ADDR_HI, - rbmemptr(adreno_gpu, rptr)); + REG_ADRENO_CP_RB_RPTR_ADDR_HI, rbmemptr(gpu, rptr)); } return 0; @@ -213,17 +212,13 @@ static uint32_t get_wptr(struct msm_ringbuffer *ring) /* Use this helper to read rptr, since a430 doesn't update rptr in memory */ static uint32_t get_rptr(struct adreno_gpu *adreno_gpu) { + struct msm_gpu *gpu = &adreno_gpu->base; + if (adreno_is_a430(adreno_gpu)) - return adreno_gpu->memptrs->rptr = adreno_gpu_read( + return gpu->memptrs->rptr = adreno_gpu_read( adreno_gpu, REG_ADRENO_CP_RB_RPTR); else - return adreno_gpu->memptrs->rptr; -} - -uint32_t adreno_last_fence(struct msm_gpu *gpu) -{ - struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - return adreno_gpu->memptrs->fence; + return gpu->memptrs->rptr; } void adreno_recover(struct msm_gpu *gpu) @@ -288,7 +283,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, OUT_PKT3(ring, CP_EVENT_WRITE, 3); OUT_RING(ring, CACHE_FLUSH_TS); - OUT_RING(ring, rbmemptr(adreno_gpu, fence)); + OUT_RING(ring, rbmemptr(gpu, fence)); OUT_RING(ring, submit->fence->seqno); /* we could maybe be clever and only CP_COND_EXEC the interrupt: */ @@ -361,7 +356,7 @@ void adreno_show(struct msm_gpu *gpu, struct seq_file *m) adreno_gpu->rev.major, adreno_gpu->rev.minor, adreno_gpu->rev.patchid); - seq_printf(m, "fence: %d/%d\n", adreno_gpu->memptrs->fence, + seq_printf(m, "fence: %d/%d\n", gpu->memptrs->fence, gpu->fctx->last_fence); seq_printf(m, "rptr: %d\n", get_rptr(adreno_gpu)); seq_printf(m, "rb wptr: %d\n", get_wptr(gpu->rb)); @@ -396,7 +391,7 @@ void adreno_dump_info(struct msm_gpu *gpu) adreno_gpu->rev.major, adreno_gpu->rev.minor, adreno_gpu->rev.patchid); - printk("fence: %d/%d\n", adreno_gpu->memptrs->fence, + printk("fence: %d/%d\n", gpu->memptrs->fence, gpu->fctx->last_fence); printk("rptr: %d\n", get_rptr(adreno_gpu)); printk("rb wptr: %d\n", get_wptr(gpu->rb)); @@ -443,7 +438,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_platform_config *config = pdev->dev.platform_data; struct msm_gpu_config adreno_gpu_config = { 0 }; struct msm_gpu *gpu = &adreno_gpu->base; - int ret; adreno_gpu->funcs = funcs; adreno_gpu->info = adreno_info(config->rev); @@ -472,39 +466,14 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); - ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, + return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config); - if (ret) - return ret; - - adreno_gpu->memptrs = msm_gem_kernel_new(drm, - sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED, gpu->aspace, - &adreno_gpu->memptrs_bo, &adreno_gpu->memptrs_iova); - - if (IS_ERR(adreno_gpu->memptrs)) { - ret = PTR_ERR(adreno_gpu->memptrs); - adreno_gpu->memptrs = NULL; - dev_err(drm->dev, "could not allocate memptrs: %d\n", ret); - } - - return ret; } void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) { - struct msm_gpu *gpu = &adreno_gpu->base; - - if (adreno_gpu->memptrs_bo) { - if (adreno_gpu->memptrs) - msm_gem_put_vaddr(adreno_gpu->memptrs_bo); - - if (adreno_gpu->memptrs_iova) - msm_gem_put_iova(adreno_gpu->memptrs_bo, gpu->aspace); - - drm_gem_object_unreference_unlocked(adreno_gpu->memptrs_bo); - } release_firmware(adreno_gpu->pm4); release_firmware(adreno_gpu->pfp); - msm_gpu_cleanup(gpu); + msm_gpu_cleanup(&adreno_gpu->base); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index b8c22658929d..1676282948d5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -82,14 +82,6 @@ struct adreno_info { const struct adreno_info *adreno_info(struct adreno_rev rev); -#define rbmemptr(adreno_gpu, member) \ - ((adreno_gpu)->memptrs_iova + offsetof(struct adreno_rbmemptrs, member)) - -struct adreno_rbmemptrs { - volatile uint32_t rptr; - volatile uint32_t fence; -}; - struct adreno_gpu { struct msm_gpu base; struct adreno_rev rev; @@ -125,13 +117,6 @@ struct adreno_gpu { /* firmware: */ const struct firmware *pm4, *pfp; - /* ringbuffer rptr/wptr: */ - // TODO should this be in msm_ringbuffer? I think it would be - // different for z180.. - struct adreno_rbmemptrs *memptrs; - struct drm_gem_object *memptrs_bo; - uint64_t memptrs_iova; - /* * Register offsets are different between some GPUs. * GPU specific offsets will be exported by GPU specific @@ -220,7 +205,6 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value); const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname); int adreno_hw_init(struct msm_gpu *gpu); -uint32_t adreno_last_fence(struct msm_gpu *gpu); void adreno_recover(struct msm_gpu *gpu); void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx); diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index ffbff27600e0..0744837ed70f 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -228,7 +228,7 @@ static void recover_worker(struct work_struct *work) struct msm_gpu *gpu = container_of(work, struct msm_gpu, recover_work); struct drm_device *dev = gpu->dev; struct msm_gem_submit *submit; - uint32_t fence = gpu->funcs->last_fence(gpu); + uint32_t fence = gpu->memptrs->fence; msm_update_fence(gpu->fctx, fence + 1); @@ -281,7 +281,7 @@ static void hangcheck_handler(unsigned long data) struct msm_gpu *gpu = (struct msm_gpu *)data; struct drm_device *dev = gpu->dev; struct msm_drm_private *priv = dev->dev_private; - uint32_t fence = gpu->funcs->last_fence(gpu); + uint32_t fence = gpu->memptrs->fence; if (fence != gpu->hangcheck_fence) { /* some progress has been made.. ya! */ @@ -449,7 +449,7 @@ static void retire_worker(struct work_struct *work) { struct msm_gpu *gpu = container_of(work, struct msm_gpu, retire_work); struct drm_device *dev = gpu->dev; - uint32_t fence = gpu->funcs->last_fence(gpu); + uint32_t fence = gpu->memptrs->fence; msm_update_fence(gpu->fctx, fence); @@ -689,6 +689,17 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } + gpu->memptrs = msm_gem_kernel_new(drm, sizeof(*gpu->memptrs_bo), + MSM_BO_UNCACHED, gpu->aspace, &gpu->memptrs_bo, + &gpu->memptrs_iova); + + if (IS_ERR(gpu->memptrs)) { + ret = PTR_ERR(gpu->memptrs); + gpu->memptrs = NULL; + dev_err(drm->dev, "could not allocate memptrs: %d\n", ret); + goto fail; + } + /* Create ringbuffer: */ gpu->rb = msm_ringbuffer_new(gpu, config->ringsz); if (IS_ERR(gpu->rb)) { @@ -701,6 +712,12 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, return 0; fail: + if (gpu->memptrs_bo) { + msm_gem_put_vaddr(gpu->memptrs_bo); + msm_gem_put_iova(gpu->memptrs_bo, gpu->aspace); + drm_gem_object_unreference_unlocked(gpu->memptrs_bo); + } + platform_set_drvdata(pdev, NULL); return ret; } @@ -718,7 +735,14 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) msm_gem_put_iova(gpu->rb->bo, gpu->aspace); msm_ringbuffer_destroy(gpu->rb); } - if (gpu->aspace) { + + if (gpu->memptrs_bo) { + msm_gem_put_vaddr(gpu->memptrs_bo); + msm_gem_put_iova(gpu->memptrs_bo, gpu->aspace); + drm_gem_object_unreference_unlocked(gpu->memptrs_bo); + } + + if (!IS_ERR_OR_NULL(gpu->aspace)) { gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu, NULL, 0); msm_gem_address_space_put(gpu->aspace); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index a890176c27ce..8ddda059de34 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -59,7 +59,6 @@ struct msm_gpu_funcs { struct msm_file_private *ctx); void (*flush)(struct msm_gpu *gpu); irqreturn_t (*irq)(struct msm_gpu *irq); - uint32_t (*last_fence)(struct msm_gpu *gpu); void (*recover)(struct msm_gpu *gpu); void (*destroy)(struct msm_gpu *gpu); #ifdef CONFIG_DEBUG_FS @@ -68,6 +67,14 @@ struct msm_gpu_funcs { #endif }; +#define rbmemptr(gpu, member) \ + ((gpu)->memptrs_iova + offsetof(struct msm_rbmemptrs, member)) + +struct msm_rbmemptrs { + volatile uint32_t rptr; + volatile uint32_t fence; +}; + struct msm_gpu { const char *name; struct drm_device *dev; @@ -130,11 +137,17 @@ struct msm_gpu { struct work_struct recover_work; struct list_head submit_list; + + struct msm_rbmemptrs *memptrs; + struct drm_gem_object *memptrs_bo; + uint64_t memptrs_iova; + + }; static inline bool msm_gpu_active(struct msm_gpu *gpu) { - return gpu->fctx->last_fence > gpu->funcs->last_fence(gpu); + return gpu->fctx->last_fence > gpu->memptrs->fence; } /* Perf-Counters: -- cgit v1.2.3 From f97decac5f4c2d862e5b848694e3ffb29fc8acdd Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:06:57 -0600 Subject: drm/msm: Support multiple ringbuffers Add the infrastructure to support the idea of multiple ringbuffers. Assign each ringbuffer an id and use that as an index for the various ring specific operations. The biggest delta is to support legacy fences. Each fence gets its own sequence number but the legacy functions expect to use a unique integer. To handle this we return a unique identifier for each submission but map it to a specific ring/sequence under the covers. Newer users use a dma_fence pointer anyway so they don't care about the actual sequence ID or ring. The actual mechanics for multiple ringbuffers are very target specific so this code just allows for the possibility but still only defines one ringbuffer for each target family. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 9 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 9 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 54 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 2 +- drivers/gpu/drm/msm/adreno/a5xx_power.c | 6 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 136 +++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 20 +- drivers/gpu/drm/msm/msm_drv.c | 23 +- drivers/gpu/drm/msm/msm_drv.h | 8 +- drivers/gpu/drm/msm/msm_fence.c | 2 +- drivers/gpu/drm/msm/msm_fence.h | 2 +- drivers/gpu/drm/msm/msm_gem.h | 4 +- drivers/gpu/drm/msm/msm_gem_submit.c | 12 +- drivers/gpu/drm/msm/msm_gpu.c | 163 ++++-- drivers/gpu/drm/msm/msm_gpu.h | 42 +- drivers/gpu/drm/msm/msm_ringbuffer.c | 34 +- drivers/gpu/drm/msm/msm_ringbuffer.h | 20 +- drivers/gpu/drm/msm/msm_submitqueue.c | 27 +- include/dt-bindings/msm/msm-bus-ids.h | 887 ++++++++++++++++++++++++++++++++ include/uapi/drm/msm_drm.h | 1 + 20 files changed, 1251 insertions(+), 210 deletions(-) create mode 100644 include/dt-bindings/msm/msm-bus-ids.h (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 789f7fb86cba..4baef2738178 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -44,7 +44,7 @@ static bool a3xx_idle(struct msm_gpu *gpu); static bool a3xx_me_init(struct msm_gpu *gpu) { - struct msm_ringbuffer *ring = gpu->rb; + struct msm_ringbuffer *ring = gpu->rb[0]; OUT_PKT3(ring, CP_ME_INIT, 17); OUT_RING(ring, 0x000003f7); @@ -65,7 +65,7 @@ static bool a3xx_me_init(struct msm_gpu *gpu) OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); - gpu->funcs->flush(gpu); + gpu->funcs->flush(gpu, ring); return a3xx_idle(gpu); } @@ -339,7 +339,7 @@ static void a3xx_destroy(struct msm_gpu *gpu) static bool a3xx_idle(struct msm_gpu *gpu) { /* wait for ringbuffer to drain: */ - if (!adreno_idle(gpu)) + if (!adreno_idle(gpu, gpu->rb[0])) return false; /* then wait for GPU to finish: */ @@ -446,6 +446,7 @@ static const struct adreno_gpu_funcs funcs = { .recover = a3xx_recover, .submit = adreno_submit, .flush = adreno_flush, + .active_ring = adreno_active_ring, .irq = a3xx_irq, .destroy = a3xx_destroy, #ifdef CONFIG_DEBUG_FS @@ -491,7 +492,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = a3xx_registers; adreno_gpu->reg_offsets = a3xx_register_offsets; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index f87c43124099..8199a4b9f2fa 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -116,7 +116,7 @@ static void a4xx_enable_hwcg(struct msm_gpu *gpu) static bool a4xx_me_init(struct msm_gpu *gpu) { - struct msm_ringbuffer *ring = gpu->rb; + struct msm_ringbuffer *ring = gpu->rb[0]; OUT_PKT3(ring, CP_ME_INIT, 17); OUT_RING(ring, 0x000003f7); @@ -137,7 +137,7 @@ static bool a4xx_me_init(struct msm_gpu *gpu) OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); - gpu->funcs->flush(gpu); + gpu->funcs->flush(gpu, ring); return a4xx_idle(gpu); } @@ -337,7 +337,7 @@ static void a4xx_destroy(struct msm_gpu *gpu) static bool a4xx_idle(struct msm_gpu *gpu) { /* wait for ringbuffer to drain: */ - if (!adreno_idle(gpu)) + if (!adreno_idle(gpu, gpu->rb[0])) return false; /* then wait for GPU to finish: */ @@ -534,6 +534,7 @@ static const struct adreno_gpu_funcs funcs = { .recover = a4xx_recover, .submit = adreno_submit, .flush = adreno_flush, + .active_ring = adreno_active_ring, .irq = a4xx_irq, .destroy = a4xx_destroy, #ifdef CONFIG_DEBUG_FS @@ -573,7 +574,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = a4xx_registers; adreno_gpu->reg_offsets = a4xx_register_offsets; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index e34835c3b55d..32252f8ac30c 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -117,7 +117,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { struct msm_drm_private *priv = gpu->dev->dev_private; - struct msm_ringbuffer *ring = gpu->rb; + struct msm_ringbuffer *ring = submit->ring; unsigned int i, ibs = 0; for (i = 0; i < submit->nr_cmds; i++) { @@ -138,15 +138,15 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, } OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1); - OUT_RING(ring, submit->fence->seqno); + OUT_RING(ring, submit->seqno); OUT_PKT7(ring, CP_EVENT_WRITE, 4); OUT_RING(ring, CACHE_FLUSH_TS | (1 << 31)); - OUT_RING(ring, lower_32_bits(rbmemptr(gpu, fence))); - OUT_RING(ring, upper_32_bits(rbmemptr(gpu, fence))); - OUT_RING(ring, submit->fence->seqno); + OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence))); + OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence))); + OUT_RING(ring, submit->seqno); - gpu->funcs->flush(gpu); + gpu->funcs->flush(gpu, ring); } static const struct { @@ -262,7 +262,7 @@ void a5xx_set_hwcg(struct msm_gpu *gpu, bool state) static int a5xx_me_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - struct msm_ringbuffer *ring = gpu->rb; + struct msm_ringbuffer *ring = gpu->rb[0]; OUT_PKT7(ring, CP_ME_INIT, 8); @@ -293,9 +293,8 @@ static int a5xx_me_init(struct msm_gpu *gpu) OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); - gpu->funcs->flush(gpu); - - return a5xx_idle(gpu) ? 0 : -EINVAL; + gpu->funcs->flush(gpu, ring); + return a5xx_idle(gpu, ring) ? 0 : -EINVAL; } static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu, @@ -581,11 +580,11 @@ static int a5xx_hw_init(struct msm_gpu *gpu) * ticking correctly */ if (adreno_is_a530(adreno_gpu)) { - OUT_PKT7(gpu->rb, CP_EVENT_WRITE, 1); - OUT_RING(gpu->rb, 0x0F); + OUT_PKT7(gpu->rb[0], CP_EVENT_WRITE, 1); + OUT_RING(gpu->rb[0], 0x0F); - gpu->funcs->flush(gpu); - if (!a5xx_idle(gpu)) + gpu->funcs->flush(gpu, gpu->rb[0]); + if (!a5xx_idle(gpu, gpu->rb[0])) return -EINVAL; } @@ -598,11 +597,11 @@ static int a5xx_hw_init(struct msm_gpu *gpu) */ ret = a5xx_zap_shader_init(gpu); if (!ret) { - OUT_PKT7(gpu->rb, CP_SET_SECURE_MODE, 1); - OUT_RING(gpu->rb, 0x00000000); + OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1); + OUT_RING(gpu->rb[0], 0x00000000); - gpu->funcs->flush(gpu); - if (!a5xx_idle(gpu)) + gpu->funcs->flush(gpu, gpu->rb[0]); + if (!a5xx_idle(gpu, gpu->rb[0])) return -EINVAL; } else { /* Print a warning so if we die, we know why */ @@ -676,18 +675,19 @@ static inline bool _a5xx_check_idle(struct msm_gpu *gpu) A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT); } -bool a5xx_idle(struct msm_gpu *gpu) +bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring) { /* wait for CP to drain ringbuffer: */ - if (!adreno_idle(gpu)) + if (!adreno_idle(gpu, ring)) return false; if (spin_until(_a5xx_check_idle(gpu))) { - DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X\n", + DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X rptr/wptr %d/%d\n", gpu->name, __builtin_return_address(0), gpu_read(gpu, REG_A5XX_RBBM_STATUS), - gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS)); - + gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS), + gpu_read(gpu, REG_A5XX_CP_RB_RPTR), + gpu_read(gpu, REG_A5XX_CP_RB_WPTR)); return false; } @@ -818,9 +818,10 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu) { struct drm_device *dev = gpu->dev; struct msm_drm_private *priv = dev->dev_private; + struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu); - dev_err(dev->dev, "gpu fault fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", - gpu->memptrs->fence, + dev_err(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", + ring ? ring->id : -1, ring ? ring->seqno : 0, gpu_read(gpu, REG_A5XX_RBBM_STATUS), gpu_read(gpu, REG_A5XX_CP_RB_RPTR), gpu_read(gpu, REG_A5XX_CP_RB_WPTR), @@ -1010,6 +1011,7 @@ static const struct adreno_gpu_funcs funcs = { .recover = a5xx_recover, .submit = a5xx_submit, .flush = adreno_flush, + .active_ring = adreno_active_ring, .irq = a5xx_irq, .destroy = a5xx_destroy, #ifdef CONFIG_DEBUG_FS @@ -1045,7 +1047,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h index e94451685bf8..44db48d86202 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h @@ -55,7 +55,7 @@ static inline int spin_usecs(struct msm_gpu *gpu, uint32_t usecs, return -ETIMEDOUT; } -bool a5xx_idle(struct msm_gpu *gpu); +bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring); void a5xx_set_hwcg(struct msm_gpu *gpu, bool state); #endif /* __A5XX_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index b5de2be67732..e5700bbf09dd 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -173,7 +173,7 @@ static int a5xx_gpmu_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); - struct msm_ringbuffer *ring = gpu->rb; + struct msm_ringbuffer *ring = gpu->rb[0]; if (!a5xx_gpu->gpmu_dwords) return 0; @@ -192,9 +192,9 @@ static int a5xx_gpmu_init(struct msm_gpu *gpu) OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); OUT_RING(ring, 1); - gpu->funcs->flush(gpu); + gpu->funcs->flush(gpu, ring); - if (!a5xx_idle(gpu)) { + if (!a5xx_idle(gpu, ring)) { DRM_ERROR("%s: Unable to load GPMU firmware. GPMU will not be active\n", gpu->name); return -EINVAL; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 5f2501c2cd3f..fd0fb0568dd3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -21,7 +21,6 @@ #include "msm_gem.h" #include "msm_mmu.h" -#define RB_SIZE SZ_32K #define RB_BLKSIZE 32 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) @@ -163,7 +162,7 @@ static int adreno_load_fw(struct adreno_gpu *adreno_gpu) int adreno_hw_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - int ret; + int ret, i; DBG("%s", gpu->name); @@ -171,34 +170,42 @@ int adreno_hw_init(struct msm_gpu *gpu) if (ret) return ret; - ret = msm_gem_get_iova(gpu->rb->bo, gpu->aspace, &gpu->rb_iova); - if (ret) { - gpu->rb_iova = 0; - dev_err(gpu->dev->dev, "could not map ringbuffer: %d\n", ret); - return ret; - } + for (i = 0; i < gpu->nr_rings; i++) { + struct msm_ringbuffer *ring = gpu->rb[i]; - /* reset ringbuffer: */ - gpu->rb->cur = gpu->rb->start; + if (!ring) + continue; - /* reset completed fence seqno: */ - gpu->memptrs->fence = gpu->fctx->completed_fence; - gpu->memptrs->rptr = 0; + ret = msm_gem_get_iova(ring->bo, gpu->aspace, &ring->iova); + if (ret) { + ring->iova = 0; + dev_err(gpu->dev->dev, + "could not map ringbuffer %d: %d\n", i, ret); + return ret; + } + + ring->cur = ring->start; + + /* reset completed fence seqno: */ + ring->memptrs->fence = ring->seqno; + ring->memptrs->rptr = 0; + } /* Setup REG_CP_RB_CNTL: */ adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL, - /* size is log2(quad-words): */ - AXXX_CP_RB_CNTL_BUFSZ(ilog2(gpu->rb->size / 8)) | - AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8)) | - (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0)); + /* size is log2(quad-words): */ + AXXX_CP_RB_CNTL_BUFSZ(ilog2(MSM_GPU_RINGBUFFER_SZ / 8)) | + AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8)) | + (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0)); - /* Setup ringbuffer address: */ + /* Setup ringbuffer address - use ringbuffer[0] for GPU init */ adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_BASE, - REG_ADRENO_CP_RB_BASE_HI, gpu->rb_iova); + REG_ADRENO_CP_RB_BASE_HI, gpu->rb[0]->iova); if (!adreno_is_a430(adreno_gpu)) { adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR, - REG_ADRENO_CP_RB_RPTR_ADDR_HI, rbmemptr(gpu, rptr)); + REG_ADRENO_CP_RB_RPTR_ADDR_HI, + rbmemptr(gpu->rb[0], rptr)); } return 0; @@ -210,15 +217,19 @@ static uint32_t get_wptr(struct msm_ringbuffer *ring) } /* Use this helper to read rptr, since a430 doesn't update rptr in memory */ -static uint32_t get_rptr(struct adreno_gpu *adreno_gpu) +static uint32_t get_rptr(struct adreno_gpu *adreno_gpu, + struct msm_ringbuffer *ring) { - struct msm_gpu *gpu = &adreno_gpu->base; - if (adreno_is_a430(adreno_gpu)) - return gpu->memptrs->rptr = adreno_gpu_read( + return ring->memptrs->rptr = adreno_gpu_read( adreno_gpu, REG_ADRENO_CP_RB_RPTR); else - return gpu->memptrs->rptr; + return ring->memptrs->rptr; +} + +struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu) +{ + return gpu->rb[0]; } void adreno_recover(struct msm_gpu *gpu) @@ -244,7 +255,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct msm_drm_private *priv = gpu->dev->dev_private; - struct msm_ringbuffer *ring = gpu->rb; + struct msm_ringbuffer *ring = submit->ring; unsigned i; for (i = 0; i < submit->nr_cmds; i++) { @@ -267,7 +278,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, } OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1); - OUT_RING(ring, submit->fence->seqno); + OUT_RING(ring, submit->seqno); if (adreno_is_a3xx(adreno_gpu) || adreno_is_a4xx(adreno_gpu)) { /* Flush HLSQ lazy updates to make sure there is nothing @@ -283,8 +294,8 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, OUT_PKT3(ring, CP_EVENT_WRITE, 3); OUT_RING(ring, CACHE_FLUSH_TS); - OUT_RING(ring, rbmemptr(gpu, fence)); - OUT_RING(ring, submit->fence->seqno); + OUT_RING(ring, rbmemptr(ring, fence)); + OUT_RING(ring, submit->seqno); /* we could maybe be clever and only CP_COND_EXEC the interrupt: */ OUT_PKT3(ring, CP_INTERRUPT, 1); @@ -310,10 +321,10 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, } #endif - gpu->funcs->flush(gpu); + gpu->funcs->flush(gpu, ring); } -void adreno_flush(struct msm_gpu *gpu) +void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); uint32_t wptr; @@ -323,7 +334,7 @@ void adreno_flush(struct msm_gpu *gpu) * to account for the possibility that the last command fit exactly into * the ringbuffer and rb->next hasn't wrapped to zero yet */ - wptr = get_wptr(gpu->rb) & ((gpu->rb->size / 4) - 1); + wptr = get_wptr(ring) % (MSM_GPU_RINGBUFFER_SZ >> 2); /* ensure writes to ringbuffer have hit system memory: */ mb(); @@ -331,17 +342,18 @@ void adreno_flush(struct msm_gpu *gpu) adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_WPTR, wptr); } -bool adreno_idle(struct msm_gpu *gpu) +bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - uint32_t wptr = get_wptr(gpu->rb); + uint32_t wptr = get_wptr(ring); /* wait for CP to drain ringbuffer: */ - if (!spin_until(get_rptr(adreno_gpu) == wptr)) + if (!spin_until(get_rptr(adreno_gpu, ring) == wptr)) return true; /* TODO maybe we need to reset GPU here to recover from hang? */ - DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name); + DRM_ERROR("%s: timeout waiting to drain ringbuffer %d!\n", gpu->name, + ring->id); return false; } @@ -356,10 +368,16 @@ void adreno_show(struct msm_gpu *gpu, struct seq_file *m) adreno_gpu->rev.major, adreno_gpu->rev.minor, adreno_gpu->rev.patchid); - seq_printf(m, "fence: %d/%d\n", gpu->memptrs->fence, - gpu->fctx->last_fence); - seq_printf(m, "rptr: %d\n", get_rptr(adreno_gpu)); - seq_printf(m, "rb wptr: %d\n", get_wptr(gpu->rb)); + for (i = 0; i < gpu->nr_rings; i++) { + struct msm_ringbuffer *ring = gpu->rb[i]; + + seq_printf(m, "rb %d: fence: %d/%d\n", i, + ring->memptrs->fence, ring->seqno); + + seq_printf(m, " rptr: %d\n", + get_rptr(adreno_gpu, ring)); + seq_printf(m, "rb wptr: %d\n", get_wptr(ring)); + } /* dump these out in a form that can be parsed by demsm: */ seq_printf(m, "IO:region %s 00000000 00020000\n", gpu->name); @@ -385,16 +403,23 @@ void adreno_show(struct msm_gpu *gpu, struct seq_file *m) void adreno_dump_info(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + int i; printk("revision: %d (%d.%d.%d.%d)\n", adreno_gpu->info->revn, adreno_gpu->rev.core, adreno_gpu->rev.major, adreno_gpu->rev.minor, adreno_gpu->rev.patchid); - printk("fence: %d/%d\n", gpu->memptrs->fence, - gpu->fctx->last_fence); - printk("rptr: %d\n", get_rptr(adreno_gpu)); - printk("rb wptr: %d\n", get_wptr(gpu->rb)); + for (i = 0; i < gpu->nr_rings; i++) { + struct msm_ringbuffer *ring = gpu->rb[i]; + + printk("rb %d: fence: %d/%d\n", i, + ring->memptrs->fence, + ring->seqno); + + printk("rptr: %d\n", get_rptr(adreno_gpu, ring)); + printk("rb wptr: %d\n", get_wptr(ring)); + } } /* would be nice to not have to duplicate the _show() stuff with printk(): */ @@ -417,23 +442,26 @@ void adreno_dump(struct msm_gpu *gpu) } } -static uint32_t ring_freewords(struct msm_gpu *gpu) +static uint32_t ring_freewords(struct msm_ringbuffer *ring) { - struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - uint32_t size = gpu->rb->size / 4; - uint32_t wptr = get_wptr(gpu->rb); - uint32_t rptr = get_rptr(adreno_gpu); + struct adreno_gpu *adreno_gpu = to_adreno_gpu(ring->gpu); + uint32_t size = MSM_GPU_RINGBUFFER_SZ >> 2; + uint32_t wptr = get_wptr(ring); + uint32_t rptr = get_rptr(adreno_gpu, ring); return (rptr + (size - 1) - wptr) % size; } -void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords) +void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords) { - if (spin_until(ring_freewords(gpu) >= ndwords)) - DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name); + if (spin_until(ring_freewords(ring) >= ndwords)) + DRM_DEV_ERROR(ring->gpu->dev->dev, + "timeout waiting for space in ringubffer %d\n", + ring->id); } int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, - struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs) + struct adreno_gpu *adreno_gpu, + const struct adreno_gpu_funcs *funcs, int nr_rings) { struct adreno_platform_config *config = pdev->dev.platform_data; struct msm_gpu_config adreno_gpu_config = { 0 }; @@ -460,7 +488,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, adreno_gpu_config.va_start = SZ_16M; adreno_gpu_config.va_end = 0xffffffff; - adreno_gpu_config.ringsz = RB_SIZE; + adreno_gpu_config.nr_rings = nr_rings; pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD); pm_runtime_use_autosuspend(&pdev->dev); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 1676282948d5..3e9a1743f476 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -208,17 +208,19 @@ int adreno_hw_init(struct msm_gpu *gpu); void adreno_recover(struct msm_gpu *gpu); void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx); -void adreno_flush(struct msm_gpu *gpu); -bool adreno_idle(struct msm_gpu *gpu); +void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring); +bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring); #ifdef CONFIG_DEBUG_FS void adreno_show(struct msm_gpu *gpu, struct seq_file *m); #endif void adreno_dump_info(struct msm_gpu *gpu); void adreno_dump(struct msm_gpu *gpu); -void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords); +void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords); +struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu); int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, - struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs); + struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs, + int nr_rings); void adreno_gpu_cleanup(struct adreno_gpu *gpu); @@ -227,7 +229,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu); static inline void OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt) { - adreno_wait_ring(ring->gpu, cnt+1); + adreno_wait_ring(ring, cnt+1); OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF)); } @@ -235,14 +237,14 @@ OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt) static inline void OUT_PKT2(struct msm_ringbuffer *ring) { - adreno_wait_ring(ring->gpu, 1); + adreno_wait_ring(ring, 1); OUT_RING(ring, CP_TYPE2_PKT); } static inline void OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) { - adreno_wait_ring(ring->gpu, cnt+1); + adreno_wait_ring(ring, cnt+1); OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8)); } @@ -264,14 +266,14 @@ static inline u32 PM4_PARITY(u32 val) static inline void OUT_PKT4(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt) { - adreno_wait_ring(ring->gpu, cnt + 1); + adreno_wait_ring(ring, cnt + 1); OUT_RING(ring, PKT4(regindx, cnt)); } static inline void OUT_PKT7(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) { - adreno_wait_ring(ring->gpu, cnt + 1); + adreno_wait_ring(ring, cnt + 1); OUT_RING(ring, CP_TYPE7_PKT | (cnt << 0) | (PM4_PARITY(cnt) << 15) | ((opcode & 0x7F) << 16) | (PM4_PARITY(opcode) << 23)); } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 2585bebfcf3e..bfb8c7cf800a 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -507,7 +507,7 @@ static void load_gpu(struct drm_device *dev) mutex_unlock(&init_lock); } -static int context_init(struct drm_file *file) +static int context_init(struct drm_device *dev, struct drm_file *file) { struct msm_file_private *ctx; @@ -515,7 +515,7 @@ static int context_init(struct drm_file *file) if (!ctx) return -ENOMEM; - msm_submitqueue_init(ctx); + msm_submitqueue_init(dev, ctx); file->driver_priv = ctx; @@ -529,7 +529,7 @@ static int msm_open(struct drm_device *dev, struct drm_file *file) */ load_gpu(dev); - return context_init(file); + return context_init(dev, file); } static void context_close(struct msm_file_private *ctx) @@ -743,16 +743,27 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, struct msm_drm_private *priv = dev->dev_private; struct drm_msm_wait_fence *args = data; ktime_t timeout = to_ktime(args->timeout); + struct msm_gpu_submitqueue *queue; + struct msm_gpu *gpu = priv->gpu; + int ret; if (args->pad) { DRM_ERROR("invalid pad: %08x\n", args->pad); return -EINVAL; } - if (!priv->gpu) + if (!gpu) return 0; - return msm_wait_fence(priv->gpu->fctx, args->fence, &timeout, true); + queue = msm_submitqueue_get(file->driver_priv, args->queueid); + if (!queue) + return -ENOENT; + + ret = msm_wait_fence(gpu->rb[queue->prio]->fctx, args->fence, &timeout, + true); + + msm_submitqueue_put(queue); + return ret; } static int msm_ioctl_gem_madvise(struct drm_device *dev, void *data, @@ -802,7 +813,7 @@ static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data, if (args->flags & ~MSM_SUBMITQUEUE_FLAGS) return -EINVAL; - return msm_submitqueue_create(file->driver_priv, args->prio, + return msm_submitqueue_create(dev, file->driver_priv, args->prio, args->flags, &args->id); } diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index b3b8f20f58db..2821f572ecd8 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -74,6 +74,8 @@ struct msm_vblank_ctrl { spinlock_t lock; }; +#define MSM_GPU_MAX_RINGS 1 + struct msm_drm_private { struct drm_device *dev; @@ -318,11 +320,11 @@ void msm_writel(u32 data, void __iomem *addr); u32 msm_readl(const void __iomem *addr); struct msm_gpu_submitqueue; -int msm_submitqueue_init(struct msm_file_private *ctx); +int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx); struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx, u32 id); -int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio, - u32 flags, u32 *id); +int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx, + u32 prio, u32 flags, u32 *id); int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id); void msm_submitqueue_close(struct msm_file_private *ctx); diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index a2f89bac9c16..349c12f670eb 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -31,7 +31,7 @@ msm_fence_context_alloc(struct drm_device *dev, const char *name) return ERR_PTR(-ENOMEM); fctx->dev = dev; - fctx->name = name; + strncpy(fctx->name, name, sizeof(fctx->name)); fctx->context = dma_fence_context_alloc(1); init_waitqueue_head(&fctx->event); spin_lock_init(&fctx->spinlock); diff --git a/drivers/gpu/drm/msm/msm_fence.h b/drivers/gpu/drm/msm/msm_fence.h index 56061aa1959d..1aa6a4c6530c 100644 --- a/drivers/gpu/drm/msm/msm_fence.h +++ b/drivers/gpu/drm/msm/msm_fence.h @@ -22,7 +22,7 @@ struct msm_fence_context { struct drm_device *dev; - const char *name; + char name[32]; unsigned context; /* last_fence == completed_fence --> no pending work */ uint32_t last_fence; /* last assigned fence */ diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 17f8a6c23464..9320e184b48d 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -138,13 +138,15 @@ void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass); struct msm_gem_submit { struct drm_device *dev; struct msm_gpu *gpu; - struct list_head node; /* node in gpu submit_list */ + struct list_head node; /* node in ring submit list */ struct list_head bo_list; struct ww_acquire_ctx ticket; + uint32_t seqno; /* Sequence number of the submit on the ring */ struct dma_fence *fence; struct msm_gpu_submitqueue *queue; struct pid *pid; /* submitting process */ bool valid; /* true if no cmdstream patching needed */ + struct msm_ringbuffer *ring; unsigned int nr_cmds; unsigned int nr_bos; struct { diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index c196cc615e77..d3551aa130fb 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -51,6 +51,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, submit->pid = get_pid(task_pid(current)); submit->cmd = (void *)&submit->bos[nr_bos]; submit->queue = queue; + submit->ring = gpu->rb[queue->prio]; /* initially, until copy_from_user() and bo lookup succeeds: */ submit->nr_bos = 0; @@ -247,7 +248,8 @@ static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit) if (no_implicit) continue; - ret = msm_gem_sync_object(&msm_obj->base, submit->gpu->fctx, write); + ret = msm_gem_sync_object(&msm_obj->base, submit->ring->fctx, + write); if (ret) break; } @@ -410,6 +412,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct dma_fence *in_fence = NULL; struct sync_file *sync_file = NULL; struct msm_gpu_submitqueue *queue; + struct msm_ringbuffer *ring; int out_fence_fd = -1; unsigned i; int ret; @@ -430,6 +433,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (!queue) return -ENOENT; + ring = gpu->rb[queue->prio]; + if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { in_fence = sync_file_get_fence(args->fence_fd); @@ -440,7 +445,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, * Wait if the fence is from a foreign context, or if the fence * array contains any fence from a foreign context. */ - if (!dma_fence_match_context(in_fence, gpu->fctx->context)) { + if (!dma_fence_match_context(in_fence, ring->fctx->context)) { ret = dma_fence_wait(in_fence, true); if (ret) return ret; @@ -543,8 +548,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, submit->nr_cmds = i; - submit->fence = msm_fence_alloc(gpu->fctx); - + submit->fence = msm_fence_alloc(ring->fctx); if (IS_ERR(submit->fence)) { ret = PTR_ERR(submit->fence); submit->fence = NULL; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 0744837ed70f..ec28c99ee36e 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -221,6 +221,20 @@ int msm_gpu_hw_init(struct msm_gpu *gpu) * Hangcheck detection for locked gpu: */ +static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring, + uint32_t fence) +{ + struct msm_gem_submit *submit; + + list_for_each_entry(submit, &ring->submits, node) { + if (submit->seqno > fence) + break; + + msm_update_fence(submit->ring->fctx, + submit->fence->seqno); + } +} + static void retire_submits(struct msm_gpu *gpu); static void recover_worker(struct work_struct *work) @@ -228,15 +242,34 @@ static void recover_worker(struct work_struct *work) struct msm_gpu *gpu = container_of(work, struct msm_gpu, recover_work); struct drm_device *dev = gpu->dev; struct msm_gem_submit *submit; - uint32_t fence = gpu->memptrs->fence; + struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu); + uint64_t fence; + int i; + + /* Update all the rings with the latest and greatest fence */ + for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) { + struct msm_ringbuffer *ring = gpu->rb[i]; - msm_update_fence(gpu->fctx, fence + 1); + fence = ring->memptrs->fence; + + /* + * For the current (faulting?) ring/submit advance the fence by + * one more to clear the faulting submit + */ + if (ring == cur_ring) + fence = fence + 1; + + update_fences(gpu, ring, fence); + } mutex_lock(&dev->struct_mutex); + dev_err(dev->dev, "%s: hangcheck recover!\n", gpu->name); - list_for_each_entry(submit, &gpu->submit_list, node) { - if (submit->fence->seqno == (fence + 1)) { + fence = cur_ring->memptrs->fence + 1; + + list_for_each_entry(submit, &cur_ring->submits, node) { + if (submit->seqno == fence) { struct task_struct *task; rcu_read_lock(); @@ -258,9 +291,16 @@ static void recover_worker(struct work_struct *work) gpu->funcs->recover(gpu); pm_runtime_put_sync(&gpu->pdev->dev); - /* replay the remaining submits after the one that hung: */ - list_for_each_entry(submit, &gpu->submit_list, node) { - gpu->funcs->submit(gpu, submit, NULL); + /* + * Replay all remaining submits starting with highest priority + * ring + */ + + for (i = gpu->nr_rings - 1; i >= 0; i--) { + struct msm_ringbuffer *ring = gpu->rb[i]; + + list_for_each_entry(submit, &ring->submits, node) + gpu->funcs->submit(gpu, submit, NULL); } } @@ -281,25 +321,27 @@ static void hangcheck_handler(unsigned long data) struct msm_gpu *gpu = (struct msm_gpu *)data; struct drm_device *dev = gpu->dev; struct msm_drm_private *priv = dev->dev_private; - uint32_t fence = gpu->memptrs->fence; + struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu); + uint32_t fence = ring->memptrs->fence; - if (fence != gpu->hangcheck_fence) { + if (fence != ring->hangcheck_fence) { /* some progress has been made.. ya! */ - gpu->hangcheck_fence = fence; - } else if (fence < gpu->fctx->last_fence) { + ring->hangcheck_fence = fence; + } else if (fence < ring->seqno) { /* no progress and not done.. hung! */ - gpu->hangcheck_fence = fence; - dev_err(dev->dev, "%s: hangcheck detected gpu lockup!\n", - gpu->name); + ring->hangcheck_fence = fence; + dev_err(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n", + gpu->name, ring->id); dev_err(dev->dev, "%s: completed fence: %u\n", gpu->name, fence); dev_err(dev->dev, "%s: submitted fence: %u\n", - gpu->name, gpu->fctx->last_fence); + gpu->name, ring->seqno); + queue_work(priv->wq, &gpu->recover_work); } /* if still more pending work, reset the hangcheck timer: */ - if (gpu->fctx->last_fence > gpu->hangcheck_fence) + if (ring->seqno > ring->hangcheck_fence) hangcheck_timer_reset(gpu); /* workaround for missing irq: */ @@ -428,19 +470,18 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) static void retire_submits(struct msm_gpu *gpu) { struct drm_device *dev = gpu->dev; + struct msm_gem_submit *submit, *tmp; + int i; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - while (!list_empty(&gpu->submit_list)) { - struct msm_gem_submit *submit; - - submit = list_first_entry(&gpu->submit_list, - struct msm_gem_submit, node); + /* Retire the commits starting with highest priority */ + for (i = gpu->nr_rings - 1; i >= 0; i--) { + struct msm_ringbuffer *ring = gpu->rb[i]; - if (dma_fence_is_signaled(submit->fence)) { - retire_submit(gpu, submit); - } else { - break; + list_for_each_entry_safe(submit, tmp, &ring->submits, node) { + if (dma_fence_is_signaled(submit->fence)) + retire_submit(gpu, submit); } } } @@ -449,9 +490,10 @@ static void retire_worker(struct work_struct *work) { struct msm_gpu *gpu = container_of(work, struct msm_gpu, retire_work); struct drm_device *dev = gpu->dev; - uint32_t fence = gpu->memptrs->fence; + int i; - msm_update_fence(gpu->fctx, fence); + for (i = 0; i < gpu->nr_rings; i++) + update_fences(gpu, gpu->rb[i], gpu->rb[i]->memptrs->fence); mutex_lock(&dev->struct_mutex); retire_submits(gpu); @@ -472,6 +514,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, { struct drm_device *dev = gpu->dev; struct msm_drm_private *priv = dev->dev_private; + struct msm_ringbuffer *ring = submit->ring; int i; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -480,7 +523,9 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, msm_gpu_hw_init(gpu); - list_add_tail(&submit->node, &gpu->submit_list); + submit->seqno = ++ring->seqno; + + list_add_tail(&submit->node, &ring->submits); msm_rd_dump_submit(submit); @@ -605,7 +650,9 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, const char *name, struct msm_gpu_config *config) { - int ret; + int i, ret, nr_rings = config->nr_rings; + void *memptrs; + uint64_t memptrs_iova; if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs))) gpu->num_perfcntrs = ARRAY_SIZE(gpu->last_cntrs); @@ -613,18 +660,11 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->dev = drm; gpu->funcs = funcs; gpu->name = name; - gpu->fctx = msm_fence_context_alloc(drm, name); - if (IS_ERR(gpu->fctx)) { - ret = PTR_ERR(gpu->fctx); - gpu->fctx = NULL; - goto fail; - } INIT_LIST_HEAD(&gpu->active_list); INIT_WORK(&gpu->retire_work, retire_worker); INIT_WORK(&gpu->recover_work, recover_worker); - INIT_LIST_HEAD(&gpu->submit_list); setup_timer(&gpu->hangcheck_timer, hangcheck_handler, (unsigned long)gpu); @@ -689,29 +729,47 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } - gpu->memptrs = msm_gem_kernel_new(drm, sizeof(*gpu->memptrs_bo), + memptrs = msm_gem_kernel_new(drm, sizeof(*gpu->memptrs_bo), MSM_BO_UNCACHED, gpu->aspace, &gpu->memptrs_bo, - &gpu->memptrs_iova); + &memptrs_iova); - if (IS_ERR(gpu->memptrs)) { - ret = PTR_ERR(gpu->memptrs); - gpu->memptrs = NULL; + if (IS_ERR(memptrs)) { + ret = PTR_ERR(memptrs); dev_err(drm->dev, "could not allocate memptrs: %d\n", ret); goto fail; } - /* Create ringbuffer: */ - gpu->rb = msm_ringbuffer_new(gpu, config->ringsz); - if (IS_ERR(gpu->rb)) { - ret = PTR_ERR(gpu->rb); - gpu->rb = NULL; - dev_err(drm->dev, "could not create ringbuffer: %d\n", ret); - goto fail; + if (nr_rings > ARRAY_SIZE(gpu->rb)) { + DRM_DEV_INFO_ONCE(drm->dev, "Only creating %lu ringbuffers\n", + ARRAY_SIZE(gpu->rb)); + nr_rings = ARRAY_SIZE(gpu->rb); } + /* Create ringbuffer(s): */ + for (i = 0; i < nr_rings; i++) { + gpu->rb[i] = msm_ringbuffer_new(gpu, i, memptrs, memptrs_iova); + + if (IS_ERR(gpu->rb[i])) { + ret = PTR_ERR(gpu->rb[i]); + dev_err(drm->dev, + "could not create ringbuffer %d: %d\n", i, ret); + goto fail; + } + + memptrs += sizeof(struct msm_rbmemptrs); + memptrs_iova += sizeof(struct msm_rbmemptrs); + } + + gpu->nr_rings = nr_rings; + return 0; fail: + for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) { + msm_ringbuffer_destroy(gpu->rb[i]); + gpu->rb[i] = NULL; + } + if (gpu->memptrs_bo) { msm_gem_put_vaddr(gpu->memptrs_bo); msm_gem_put_iova(gpu->memptrs_bo, gpu->aspace); @@ -724,16 +782,17 @@ fail: void msm_gpu_cleanup(struct msm_gpu *gpu) { + int i; + DBG("%s", gpu->name); WARN_ON(!list_empty(&gpu->active_list)); bs_fini(gpu); - if (gpu->rb) { - if (gpu->rb_iova) - msm_gem_put_iova(gpu->rb->bo, gpu->aspace); - msm_ringbuffer_destroy(gpu->rb); + for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) { + msm_ringbuffer_destroy(gpu->rb[i]); + gpu->rb[i] = NULL; } if (gpu->memptrs_bo) { diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 8ddda059de34..1be0317bb2c0 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -33,7 +33,7 @@ struct msm_gpu_config { const char *irqname; uint64_t va_start; uint64_t va_end; - unsigned int ringsz; + unsigned int nr_rings; }; /* So far, with hardware that I've seen to date, we can have: @@ -57,8 +57,9 @@ struct msm_gpu_funcs { int (*pm_resume)(struct msm_gpu *gpu); void (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx); - void (*flush)(struct msm_gpu *gpu); + void (*flush)(struct msm_gpu *gpu, struct msm_ringbuffer *ring); irqreturn_t (*irq)(struct msm_gpu *irq); + struct msm_ringbuffer *(*active_ring)(struct msm_gpu *gpu); void (*recover)(struct msm_gpu *gpu); void (*destroy)(struct msm_gpu *gpu); #ifdef CONFIG_DEBUG_FS @@ -67,14 +68,6 @@ struct msm_gpu_funcs { #endif }; -#define rbmemptr(gpu, member) \ - ((gpu)->memptrs_iova + offsetof(struct msm_rbmemptrs, member)) - -struct msm_rbmemptrs { - volatile uint32_t rptr; - volatile uint32_t fence; -}; - struct msm_gpu { const char *name; struct drm_device *dev; @@ -93,16 +86,12 @@ struct msm_gpu { const struct msm_gpu_perfcntr *perfcntrs; uint32_t num_perfcntrs; - /* ringbuffer: */ - struct msm_ringbuffer *rb; - uint64_t rb_iova; + struct msm_ringbuffer *rb[MSM_GPU_MAX_RINGS]; + int nr_rings; /* list of GEM active objects: */ struct list_head active_list; - /* fencing: */ - struct msm_fence_context *fctx; - /* does gpu need hw_init? */ bool needs_hw_init; @@ -133,21 +122,26 @@ struct msm_gpu { #define DRM_MSM_HANGCHECK_PERIOD 500 /* in ms */ #define DRM_MSM_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_MSM_HANGCHECK_PERIOD) struct timer_list hangcheck_timer; - uint32_t hangcheck_fence; struct work_struct recover_work; - struct list_head submit_list; - - struct msm_rbmemptrs *memptrs; struct drm_gem_object *memptrs_bo; - uint64_t memptrs_iova; - - }; +/* It turns out that all targets use the same ringbuffer size */ +#define MSM_GPU_RINGBUFFER_SZ SZ_32K + static inline bool msm_gpu_active(struct msm_gpu *gpu) { - return gpu->fctx->last_fence > gpu->memptrs->fence; + int i; + + for (i = 0; i < gpu->nr_rings; i++) { + struct msm_ringbuffer *ring = gpu->rb[i]; + + if (ring->seqno > ring->memptrs->fence) + return true; + } + + return false; } /* Perf-Counters: diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index bf065a540130..4db6ca719706 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -18,13 +18,15 @@ #include "msm_ringbuffer.h" #include "msm_gpu.h" -struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) +struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, + void *memptrs, uint64_t memptrs_iova) { struct msm_ringbuffer *ring; + char name[32]; int ret; - if (WARN_ON(!is_power_of_2(size))) - return ERR_PTR(-EINVAL); + /* We assume everwhere that MSM_GPU_RINGBUFFER_SZ is a power of 2 */ + BUILD_BUG_ON(!is_power_of_2(MSM_GPU_RINGBUFFER_SZ)); ring = kzalloc(sizeof(*ring), GFP_KERNEL); if (!ring) { @@ -33,32 +35,44 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) } ring->gpu = gpu; - + ring->id = id; /* Pass NULL for the iova pointer - we will map it later */ - ring->start = msm_gem_kernel_new(gpu->dev, size, MSM_BO_WC, - gpu->aspace, &ring->bo, NULL); + ring->start = msm_gem_kernel_new(gpu->dev, MSM_GPU_RINGBUFFER_SZ, + MSM_BO_WC, gpu->aspace, &ring->bo, NULL); if (IS_ERR(ring->start)) { ret = PTR_ERR(ring->start); ring->start = 0; goto fail; } - ring->end = ring->start + (size / 4); + ring->end = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2); ring->cur = ring->start; - ring->size = size; + ring->memptrs = memptrs; + ring->memptrs_iova = memptrs_iova; + + INIT_LIST_HEAD(&ring->submits); + + snprintf(name, sizeof(name), "gpu-ring-%d", ring->id); + + ring->fctx = msm_fence_context_alloc(gpu->dev, name); return ring; fail: - if (ring) - msm_ringbuffer_destroy(ring); + msm_ringbuffer_destroy(ring); return ERR_PTR(ret); } void msm_ringbuffer_destroy(struct msm_ringbuffer *ring) { + if (IS_ERR_OR_NULL(ring)) + return; + + msm_fence_context_free(ring->fctx); + if (ring->bo) { + msm_gem_put_iova(ring->bo, ring->gpu->aspace); msm_gem_put_vaddr(ring->bo); drm_gem_object_unreference_unlocked(ring->bo); } diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index 6e0e1049fa4f..ec44251ef9f2 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -20,14 +20,30 @@ #include "msm_drv.h" +#define rbmemptr(ring, member) \ + ((ring)->memptrs_iova + offsetof(struct msm_rbmemptrs, member)) + +struct msm_rbmemptrs { + volatile uint32_t rptr; + volatile uint32_t fence; +}; + struct msm_ringbuffer { struct msm_gpu *gpu; - int size; + int id; struct drm_gem_object *bo; uint32_t *start, *end, *cur; + struct list_head submits; + uint64_t iova; + uint32_t seqno; + uint32_t hangcheck_fence; + struct msm_rbmemptrs *memptrs; + uint64_t memptrs_iova; + struct msm_fence_context *fctx; }; -struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size); +struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, + void *memptrs, uint64_t memptrs_iova); void msm_ringbuffer_destroy(struct msm_ringbuffer *ring); /* ringbuffer helpers (the parts that are same for a3xx/a2xx/z180..) */ diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c index 593c3b5f44cd..5115f75b5b7f 100644 --- a/drivers/gpu/drm/msm/msm_submitqueue.c +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -60,9 +60,10 @@ void msm_submitqueue_close(struct msm_file_private *ctx) msm_submitqueue_put(entry); } -int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio, u32 flags, - u32 *id) +int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx, + u32 prio, u32 flags, u32 *id) { + struct msm_drm_private *priv = drm->dev_private; struct msm_gpu_submitqueue *queue; if (!ctx) @@ -75,7 +76,13 @@ int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio, u32 flags, kref_init(&queue->ref); queue->flags = flags; - queue->prio = prio; + + if (priv->gpu) { + if (prio >= priv->gpu->nr_rings) + return -EINVAL; + + queue->prio = prio; + } write_lock(&ctx->queuelock); @@ -91,16 +98,26 @@ int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio, u32 flags, return 0; } -int msm_submitqueue_init(struct msm_file_private *ctx) +int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx) { + struct msm_drm_private *priv = drm->dev_private; + int default_prio; + if (!ctx) return 0; + /* + * Select priority 2 as the "default priority" unless nr_rings is less + * than 2 and then pick the lowest pirority + */ + default_prio = priv->gpu ? + clamp_t(uint32_t, 2, 0, priv->gpu->nr_rings - 1) : 0; + INIT_LIST_HEAD(&ctx->submitqueues); rwlock_init(&ctx->queuelock); - return msm_submitqueue_create(ctx, 2, 0, NULL); + return msm_submitqueue_create(drm, ctx, default_prio, 0, NULL); } int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id) diff --git a/include/dt-bindings/msm/msm-bus-ids.h b/include/dt-bindings/msm/msm-bus-ids.h new file mode 100644 index 000000000000..a75d304473d5 --- /dev/null +++ b/include/dt-bindings/msm/msm-bus-ids.h @@ -0,0 +1,887 @@ +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MSM_BUS_IDS_H +#define __MSM_BUS_IDS_H + +/* Aggregation types */ +#define AGG_SCHEME_NONE 0 +#define AGG_SCHEME_LEG 1 +#define AGG_SCHEME_1 2 + +/* Topology related enums */ +#define MSM_BUS_FAB_DEFAULT 0 +#define MSM_BUS_FAB_APPSS 0 +#define MSM_BUS_FAB_SYSTEM 1024 +#define MSM_BUS_FAB_MMSS 2048 +#define MSM_BUS_FAB_SYSTEM_FPB 3072 +#define MSM_BUS_FAB_CPSS_FPB 4096 + +#define MSM_BUS_FAB_BIMC 0 +#define MSM_BUS_FAB_SYS_NOC 1024 +#define MSM_BUS_FAB_MMSS_NOC 2048 +#define MSM_BUS_FAB_OCMEM_NOC 3072 +#define MSM_BUS_FAB_PERIPH_NOC 4096 +#define MSM_BUS_FAB_CONFIG_NOC 5120 +#define MSM_BUS_FAB_OCMEM_VNOC 6144 +#define MSM_BUS_FAB_MMSS_AHB 2049 +#define MSM_BUS_FAB_A0_NOC 6145 +#define MSM_BUS_FAB_A1_NOC 6146 +#define MSM_BUS_FAB_A2_NOC 6147 +#define MSM_BUS_FAB_GNOC 6148 +#define MSM_BUS_FAB_CR_VIRT 6149 + +#define MSM_BUS_MASTER_FIRST 1 +#define MSM_BUS_MASTER_AMPSS_M0 1 +#define MSM_BUS_MASTER_AMPSS_M1 2 +#define MSM_BUS_APPSS_MASTER_FAB_MMSS 3 +#define MSM_BUS_APPSS_MASTER_FAB_SYSTEM 4 +#define MSM_BUS_SYSTEM_MASTER_FAB_APPSS 5 +#define MSM_BUS_MASTER_SPS 6 +#define MSM_BUS_MASTER_ADM_PORT0 7 +#define MSM_BUS_MASTER_ADM_PORT1 8 +#define MSM_BUS_SYSTEM_MASTER_ADM1_PORT0 9 +#define MSM_BUS_MASTER_ADM1_PORT1 10 +#define MSM_BUS_MASTER_LPASS_PROC 11 +#define MSM_BUS_MASTER_MSS_PROCI 12 +#define MSM_BUS_MASTER_MSS_PROCD 13 +#define MSM_BUS_MASTER_MSS_MDM_PORT0 14 +#define MSM_BUS_MASTER_LPASS 15 +#define MSM_BUS_SYSTEM_MASTER_CPSS_FPB 16 +#define MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB 17 +#define MSM_BUS_SYSTEM_MASTER_MMSS_FPB 18 +#define MSM_BUS_MASTER_ADM1_CI 19 +#define MSM_BUS_MASTER_ADM0_CI 20 +#define MSM_BUS_MASTER_MSS_MDM_PORT1 21 +#define MSM_BUS_MASTER_MDP_PORT0 22 +#define MSM_BUS_MASTER_MDP_PORT1 23 +#define MSM_BUS_MMSS_MASTER_ADM1_PORT0 24 +#define MSM_BUS_MASTER_ROTATOR 25 +#define MSM_BUS_MASTER_GRAPHICS_3D 26 +#define MSM_BUS_MASTER_JPEG_DEC 27 +#define MSM_BUS_MASTER_GRAPHICS_2D_CORE0 28 +#define MSM_BUS_MASTER_VFE 29 +#define MSM_BUS_MASTER_VFE0 MSM_BUS_MASTER_VFE +#define MSM_BUS_MASTER_VPE 30 +#define MSM_BUS_MASTER_JPEG_ENC 31 +#define MSM_BUS_MASTER_GRAPHICS_2D_CORE1 32 +#define MSM_BUS_MMSS_MASTER_APPS_FAB 33 +#define MSM_BUS_MASTER_HD_CODEC_PORT0 34 +#define MSM_BUS_MASTER_HD_CODEC_PORT1 35 +#define MSM_BUS_MASTER_SPDM 36 +#define MSM_BUS_MASTER_RPM 37 +#define MSM_BUS_MASTER_MSS 38 +#define MSM_BUS_MASTER_RIVA 39 +#define MSM_BUS_MASTER_SNOC_VMEM 40 +#define MSM_BUS_MASTER_MSS_SW_PROC 41 +#define MSM_BUS_MASTER_MSS_FW_PROC 42 +#define MSM_BUS_MASTER_HMSS 43 +#define MSM_BUS_MASTER_GSS_NAV 44 +#define MSM_BUS_MASTER_PCIE 45 +#define MSM_BUS_MASTER_SATA 46 +#define MSM_BUS_MASTER_CRYPTO 47 +#define MSM_BUS_MASTER_VIDEO_CAP 48 +#define MSM_BUS_MASTER_GRAPHICS_3D_PORT1 49 +#define MSM_BUS_MASTER_VIDEO_ENC 50 +#define MSM_BUS_MASTER_VIDEO_DEC 51 +#define MSM_BUS_MASTER_LPASS_AHB 52 +#define MSM_BUS_MASTER_QDSS_BAM 53 +#define MSM_BUS_MASTER_SNOC_CFG 54 +#define MSM_BUS_MASTER_CRYPTO_CORE0 55 +#define MSM_BUS_MASTER_CRYPTO_CORE1 56 +#define MSM_BUS_MASTER_MSS_NAV 57 +#define MSM_BUS_MASTER_OCMEM_DMA 58 +#define MSM_BUS_MASTER_WCSS 59 +#define MSM_BUS_MASTER_QDSS_ETR 60 +#define MSM_BUS_MASTER_USB3 61 +#define MSM_BUS_MASTER_JPEG 62 +#define MSM_BUS_MASTER_VIDEO_P0 63 +#define MSM_BUS_MASTER_VIDEO_P1 64 +#define MSM_BUS_MASTER_MSS_PROC 65 +#define MSM_BUS_MASTER_JPEG_OCMEM 66 +#define MSM_BUS_MASTER_MDP_OCMEM 67 +#define MSM_BUS_MASTER_VIDEO_P0_OCMEM 68 +#define MSM_BUS_MASTER_VIDEO_P1_OCMEM 69 +#define MSM_BUS_MASTER_VFE_OCMEM 70 +#define MSM_BUS_MASTER_CNOC_ONOC_CFG 71 +#define MSM_BUS_MASTER_RPM_INST 72 +#define MSM_BUS_MASTER_RPM_DATA 73 +#define MSM_BUS_MASTER_RPM_SYS 74 +#define MSM_BUS_MASTER_DEHR 75 +#define MSM_BUS_MASTER_QDSS_DAP 76 +#define MSM_BUS_MASTER_TIC 77 +#define MSM_BUS_MASTER_SDCC_1 78 +#define MSM_BUS_MASTER_SDCC_3 79 +#define MSM_BUS_MASTER_SDCC_4 80 +#define MSM_BUS_MASTER_SDCC_2 81 +#define MSM_BUS_MASTER_TSIF 82 +#define MSM_BUS_MASTER_BAM_DMA 83 +#define MSM_BUS_MASTER_BLSP_2 84 +#define MSM_BUS_MASTER_USB_HSIC 85 +#define MSM_BUS_MASTER_BLSP_1 86 +#define MSM_BUS_MASTER_USB_HS 87 +#define MSM_BUS_MASTER_PNOC_CFG 88 +#define MSM_BUS_MASTER_V_OCMEM_GFX3D 89 +#define MSM_BUS_MASTER_IPA 90 +#define MSM_BUS_MASTER_QPIC 91 +#define MSM_BUS_MASTER_MDPE 92 +#define MSM_BUS_MASTER_USB_HS2 93 +#define MSM_BUS_MASTER_VPU 94 +#define MSM_BUS_MASTER_UFS 95 +#define MSM_BUS_MASTER_BCAST 96 +#define MSM_BUS_MASTER_CRYPTO_CORE2 97 +#define MSM_BUS_MASTER_EMAC 98 +#define MSM_BUS_MASTER_VPU_1 99 +#define MSM_BUS_MASTER_PCIE_1 100 +#define MSM_BUS_MASTER_USB3_1 101 +#define MSM_BUS_MASTER_CNOC_MNOC_MMSS_CFG 102 +#define MSM_BUS_MASTER_CNOC_MNOC_CFG 103 +#define MSM_BUS_MASTER_TCU_0 104 +#define MSM_BUS_MASTER_TCU_1 105 +#define MSM_BUS_MASTER_CPP 106 +#define MSM_BUS_MASTER_AUDIO 107 +#define MSM_BUS_MASTER_PCIE_2 108 +#define MSM_BUS_MASTER_VFE1 109 +#define MSM_BUS_MASTER_XM_USB_HS1 110 +#define MSM_BUS_MASTER_PCNOC_BIMC_1 111 +#define MSM_BUS_MASTER_BIMC_PCNOC 112 +#define MSM_BUS_MASTER_XI_USB_HSIC 113 +#define MSM_BUS_MASTER_SGMII 114 +#define MSM_BUS_SPMI_FETCHER 115 +#define MSM_BUS_MASTER_GNOC_BIMC 116 +#define MSM_BUS_MASTER_CRVIRT_A2NOC 117 +#define MSM_BUS_MASTER_CNOC_A2NOC 118 +#define MSM_BUS_MASTER_WLAN 119 +#define MSM_BUS_MASTER_MSS_CE 120 +#define MSM_BUS_MASTER_CDSP_PROC 121 +#define MSM_BUS_MASTER_GNOC_SNOC 122 +#define MSM_BUS_MASTER_PIMEM 123 +#define MSM_BUS_MASTER_MASTER_LAST 124 + +#define MSM_BUS_SYSTEM_FPB_MASTER_SYSTEM MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB +#define MSM_BUS_CPSS_FPB_MASTER_SYSTEM MSM_BUS_SYSTEM_MASTER_CPSS_FPB + +#define MSM_BUS_SNOC_MM_INT_0 10000 +#define MSM_BUS_SNOC_MM_INT_1 10001 +#define MSM_BUS_SNOC_MM_INT_2 10002 +#define MSM_BUS_SNOC_MM_INT_BIMC 10003 +#define MSM_BUS_SNOC_INT_0 10004 +#define MSM_BUS_SNOC_INT_1 10005 +#define MSM_BUS_SNOC_INT_BIMC 10006 +#define MSM_BUS_SNOC_BIMC_0_MAS 10007 +#define MSM_BUS_SNOC_BIMC_1_MAS 10008 +#define MSM_BUS_SNOC_QDSS_INT 10009 +#define MSM_BUS_PNOC_SNOC_MAS 10010 +#define MSM_BUS_PNOC_SNOC_SLV 10011 +#define MSM_BUS_PNOC_INT_0 10012 +#define MSM_BUS_PNOC_INT_1 10013 +#define MSM_BUS_PNOC_M_0 10014 +#define MSM_BUS_PNOC_M_1 10015 +#define MSM_BUS_BIMC_SNOC_MAS 10016 +#define MSM_BUS_BIMC_SNOC_SLV 10017 +#define MSM_BUS_PNOC_SLV_0 10018 +#define MSM_BUS_PNOC_SLV_1 10019 +#define MSM_BUS_PNOC_SLV_2 10020 +#define MSM_BUS_PNOC_SLV_3 10021 +#define MSM_BUS_PNOC_SLV_4 10022 +#define MSM_BUS_PNOC_SLV_8 10023 +#define MSM_BUS_PNOC_SLV_9 10024 +#define MSM_BUS_SNOC_BIMC_0_SLV 10025 +#define MSM_BUS_SNOC_BIMC_1_SLV 10026 +#define MSM_BUS_MNOC_BIMC_MAS 10027 +#define MSM_BUS_MNOC_BIMC_SLV 10028 +#define MSM_BUS_BIMC_MNOC_MAS 10029 +#define MSM_BUS_BIMC_MNOC_SLV 10030 +#define MSM_BUS_SNOC_BIMC_MAS 10031 +#define MSM_BUS_SNOC_BIMC_SLV 10032 +#define MSM_BUS_CNOC_SNOC_MAS 10033 +#define MSM_BUS_CNOC_SNOC_SLV 10034 +#define MSM_BUS_SNOC_CNOC_MAS 10035 +#define MSM_BUS_SNOC_CNOC_SLV 10036 +#define MSM_BUS_OVNOC_SNOC_MAS 10037 +#define MSM_BUS_OVNOC_SNOC_SLV 10038 +#define MSM_BUS_SNOC_OVNOC_MAS 10039 +#define MSM_BUS_SNOC_OVNOC_SLV 10040 +#define MSM_BUS_SNOC_PNOC_MAS 10041 +#define MSM_BUS_SNOC_PNOC_SLV 10042 +#define MSM_BUS_BIMC_INT_APPS_EBI 10043 +#define MSM_BUS_BIMC_INT_APPS_SNOC 10044 +#define MSM_BUS_SNOC_BIMC_2_MAS 10045 +#define MSM_BUS_SNOC_BIMC_2_SLV 10046 +#define MSM_BUS_PNOC_SLV_5 10047 +#define MSM_BUS_PNOC_SLV_7 10048 +#define MSM_BUS_PNOC_INT_2 10049 +#define MSM_BUS_PNOC_INT_3 10050 +#define MSM_BUS_PNOC_INT_4 10051 +#define MSM_BUS_PNOC_INT_5 10052 +#define MSM_BUS_PNOC_INT_6 10053 +#define MSM_BUS_PNOC_INT_7 10054 +#define MSM_BUS_BIMC_SNOC_1_MAS 10055 +#define MSM_BUS_BIMC_SNOC_1_SLV 10056 +#define MSM_BUS_PNOC_A1NOC_MAS 10057 +#define MSM_BUS_PNOC_A1NOC_SLV 10058 +#define MSM_BUS_CNOC_A1NOC_MAS 10059 +#define MSM_BUS_A0NOC_SNOC_MAS 10060 +#define MSM_BUS_A0NOC_SNOC_SLV 10061 +#define MSM_BUS_A1NOC_SNOC_SLV 10062 +#define MSM_BUS_A1NOC_SNOC_MAS 10063 +#define MSM_BUS_A2NOC_SNOC_MAS 10064 +#define MSM_BUS_A2NOC_SNOC_SLV 10065 +#define MSM_BUS_SNOC_INT_2 10066 +#define MSM_BUS_A0NOC_QDSS_INT 10067 +#define MSM_BUS_INT_LAST 10068 + +#define MSM_BUS_INT_TEST_ID 20000 +#define MSM_BUS_INT_TEST_LAST 20050 + +#define MSM_BUS_SLAVE_FIRST 512 +#define MSM_BUS_SLAVE_EBI_CH0 512 +#define MSM_BUS_SLAVE_EBI_CH1 513 +#define MSM_BUS_SLAVE_AMPSS_L2 514 +#define MSM_BUS_APPSS_SLAVE_FAB_MMSS 515 +#define MSM_BUS_APPSS_SLAVE_FAB_SYSTEM 516 +#define MSM_BUS_SYSTEM_SLAVE_FAB_APPS 517 +#define MSM_BUS_SLAVE_SPS 518 +#define MSM_BUS_SLAVE_SYSTEM_IMEM 519 +#define MSM_BUS_SLAVE_AMPSS 520 +#define MSM_BUS_SLAVE_MSS 521 +#define MSM_BUS_SLAVE_LPASS 522 +#define MSM_BUS_SYSTEM_SLAVE_CPSS_FPB 523 +#define MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB 524 +#define MSM_BUS_SYSTEM_SLAVE_MMSS_FPB 525 +#define MSM_BUS_SLAVE_CORESIGHT 526 +#define MSM_BUS_SLAVE_RIVA 527 +#define MSM_BUS_SLAVE_SMI 528 +#define MSM_BUS_MMSS_SLAVE_FAB_APPS 529 +#define MSM_BUS_MMSS_SLAVE_FAB_APPS_1 530 +#define MSM_BUS_SLAVE_MM_IMEM 531 +#define MSM_BUS_SLAVE_CRYPTO 532 +#define MSM_BUS_SLAVE_SPDM 533 +#define MSM_BUS_SLAVE_RPM 534 +#define MSM_BUS_SLAVE_RPM_MSG_RAM 535 +#define MSM_BUS_SLAVE_MPM 536 +#define MSM_BUS_SLAVE_PMIC1_SSBI1_A 537 +#define MSM_BUS_SLAVE_PMIC1_SSBI1_B 538 +#define MSM_BUS_SLAVE_PMIC1_SSBI1_C 539 +#define MSM_BUS_SLAVE_PMIC2_SSBI2_A 540 +#define MSM_BUS_SLAVE_PMIC2_SSBI2_B 541 +#define MSM_BUS_SLAVE_GSBI1_UART 542 +#define MSM_BUS_SLAVE_GSBI2_UART 543 +#define MSM_BUS_SLAVE_GSBI3_UART 544 +#define MSM_BUS_SLAVE_GSBI4_UART 545 +#define MSM_BUS_SLAVE_GSBI5_UART 546 +#define MSM_BUS_SLAVE_GSBI6_UART 547 +#define MSM_BUS_SLAVE_GSBI7_UART 548 +#define MSM_BUS_SLAVE_GSBI8_UART 549 +#define MSM_BUS_SLAVE_GSBI9_UART 550 +#define MSM_BUS_SLAVE_GSBI10_UART 551 +#define MSM_BUS_SLAVE_GSBI11_UART 552 +#define MSM_BUS_SLAVE_GSBI12_UART 553 +#define MSM_BUS_SLAVE_GSBI1_QUP 554 +#define MSM_BUS_SLAVE_GSBI2_QUP 555 +#define MSM_BUS_SLAVE_GSBI3_QUP 556 +#define MSM_BUS_SLAVE_GSBI4_QUP 557 +#define MSM_BUS_SLAVE_GSBI5_QUP 558 +#define MSM_BUS_SLAVE_GSBI6_QUP 559 +#define MSM_BUS_SLAVE_GSBI7_QUP 560 +#define MSM_BUS_SLAVE_GSBI8_QUP 561 +#define MSM_BUS_SLAVE_GSBI9_QUP 562 +#define MSM_BUS_SLAVE_GSBI10_QUP 563 +#define MSM_BUS_SLAVE_GSBI11_QUP 564 +#define MSM_BUS_SLAVE_GSBI12_QUP 565 +#define MSM_BUS_SLAVE_EBI2_NAND 566 +#define MSM_BUS_SLAVE_EBI2_CS0 567 +#define MSM_BUS_SLAVE_EBI2_CS1 568 +#define MSM_BUS_SLAVE_EBI2_CS2 569 +#define MSM_BUS_SLAVE_EBI2_CS3 570 +#define MSM_BUS_SLAVE_EBI2_CS4 571 +#define MSM_BUS_SLAVE_EBI2_CS5 572 +#define MSM_BUS_SLAVE_USB_FS1 573 +#define MSM_BUS_SLAVE_USB_FS2 574 +#define MSM_BUS_SLAVE_TSIF 575 +#define MSM_BUS_SLAVE_MSM_TSSC 576 +#define MSM_BUS_SLAVE_MSM_PDM 577 +#define MSM_BUS_SLAVE_MSM_DIMEM 578 +#define MSM_BUS_SLAVE_MSM_TCSR 579 +#define MSM_BUS_SLAVE_MSM_PRNG 580 +#define MSM_BUS_SLAVE_GSS 581 +#define MSM_BUS_SLAVE_SATA 582 +#define MSM_BUS_SLAVE_USB3 583 +#define MSM_BUS_SLAVE_WCSS 584 +#define MSM_BUS_SLAVE_OCIMEM 585 +#define MSM_BUS_SLAVE_SNOC_OCMEM 586 +#define MSM_BUS_SLAVE_SERVICE_SNOC 587 +#define MSM_BUS_SLAVE_QDSS_STM 588 +#define MSM_BUS_SLAVE_CAMERA_CFG 589 +#define MSM_BUS_SLAVE_DISPLAY_CFG 590 +#define MSM_BUS_SLAVE_OCMEM_CFG 591 +#define MSM_BUS_SLAVE_CPR_CFG 592 +#define MSM_BUS_SLAVE_CPR_XPU_CFG 593 +#define MSM_BUS_SLAVE_MISC_CFG 594 +#define MSM_BUS_SLAVE_MISC_XPU_CFG 595 +#define MSM_BUS_SLAVE_VENUS_CFG 596 +#define MSM_BUS_SLAVE_MISC_VENUS_CFG 597 +#define MSM_BUS_SLAVE_GRAPHICS_3D_CFG 598 +#define MSM_BUS_SLAVE_MMSS_CLK_CFG 599 +#define MSM_BUS_SLAVE_MMSS_CLK_XPU_CFG 600 +#define MSM_BUS_SLAVE_MNOC_MPU_CFG 601 +#define MSM_BUS_SLAVE_ONOC_MPU_CFG 602 +#define MSM_BUS_SLAVE_SERVICE_MNOC 603 +#define MSM_BUS_SLAVE_OCMEM 604 +#define MSM_BUS_SLAVE_SERVICE_ONOC 605 +#define MSM_BUS_SLAVE_SDCC_1 606 +#define MSM_BUS_SLAVE_SDCC_3 607 +#define MSM_BUS_SLAVE_SDCC_2 608 +#define MSM_BUS_SLAVE_SDCC_4 609 +#define MSM_BUS_SLAVE_BAM_DMA 610 +#define MSM_BUS_SLAVE_BLSP_2 611 +#define MSM_BUS_SLAVE_USB_HSIC 612 +#define MSM_BUS_SLAVE_BLSP_1 613 +#define MSM_BUS_SLAVE_USB_HS 614 +#define MSM_BUS_SLAVE_PDM 615 +#define MSM_BUS_SLAVE_PERIPH_APU_CFG 616 +#define MSM_BUS_SLAVE_PNOC_MPU_CFG 617 +#define MSM_BUS_SLAVE_PRNG 618 +#define MSM_BUS_SLAVE_SERVICE_PNOC 619 +#define MSM_BUS_SLAVE_CLK_CTL 620 +#define MSM_BUS_SLAVE_CNOC_MSS 621 +#define MSM_BUS_SLAVE_SECURITY 622 +#define MSM_BUS_SLAVE_TCSR 623 +#define MSM_BUS_SLAVE_TLMM 624 +#define MSM_BUS_SLAVE_CRYPTO_0_CFG 625 +#define MSM_BUS_SLAVE_CRYPTO_1_CFG 626 +#define MSM_BUS_SLAVE_IMEM_CFG 627 +#define MSM_BUS_SLAVE_MESSAGE_RAM 628 +#define MSM_BUS_SLAVE_BIMC_CFG 629 +#define MSM_BUS_SLAVE_BOOT_ROM 630 +#define MSM_BUS_SLAVE_CNOC_MNOC_MMSS_CFG 631 +#define MSM_BUS_SLAVE_PMIC_ARB 632 +#define MSM_BUS_SLAVE_SPDM_WRAPPER 633 +#define MSM_BUS_SLAVE_DEHR_CFG 634 +#define MSM_BUS_SLAVE_QDSS_CFG 635 +#define MSM_BUS_SLAVE_RBCPR_CFG 636 +#define MSM_BUS_SLAVE_RBCPR_QDSS_APU_CFG 637 +#define MSM_BUS_SLAVE_SNOC_MPU_CFG 638 +#define MSM_BUS_SLAVE_CNOC_ONOC_CFG 639 +#define MSM_BUS_SLAVE_CNOC_MNOC_CFG 640 +#define MSM_BUS_SLAVE_PNOC_CFG 641 +#define MSM_BUS_SLAVE_SNOC_CFG 642 +#define MSM_BUS_SLAVE_EBI1_DLL_CFG 643 +#define MSM_BUS_SLAVE_PHY_APU_CFG 644 +#define MSM_BUS_SLAVE_EBI1_PHY_CFG 645 +#define MSM_BUS_SLAVE_SERVICE_CNOC 646 +#define MSM_BUS_SLAVE_IPS_CFG 647 +#define MSM_BUS_SLAVE_QPIC 648 +#define MSM_BUS_SLAVE_DSI_CFG 649 +#define MSM_BUS_SLAVE_UFS_CFG 650 +#define MSM_BUS_SLAVE_RBCPR_CX_CFG 651 +#define MSM_BUS_SLAVE_RBCPR_MX_CFG 652 +#define MSM_BUS_SLAVE_PCIE_CFG 653 +#define MSM_BUS_SLAVE_USB_PHYS_CFG 654 +#define MSM_BUS_SLAVE_VIDEO_CAP_CFG 655 +#define MSM_BUS_SLAVE_AVSYNC_CFG 656 +#define MSM_BUS_SLAVE_CRYPTO_2_CFG 657 +#define MSM_BUS_SLAVE_VPU_CFG 658 +#define MSM_BUS_SLAVE_BCAST_CFG 659 +#define MSM_BUS_SLAVE_KLM_CFG 660 +#define MSM_BUS_SLAVE_GENI_IR_CFG 661 +#define MSM_BUS_SLAVE_OCMEM_GFX 662 +#define MSM_BUS_SLAVE_CATS_128 663 +#define MSM_BUS_SLAVE_OCMEM_64 664 +#define MSM_BUS_SLAVE_PCIE_0 665 +#define MSM_BUS_SLAVE_PCIE_1 666 +#define MSM_BUS_SLAVE_PCIE_0_CFG 667 +#define MSM_BUS_SLAVE_PCIE_1_CFG 668 +#define MSM_BUS_SLAVE_SRVC_MNOC 669 +#define MSM_BUS_SLAVE_USB_HS2 670 +#define MSM_BUS_SLAVE_AUDIO 671 +#define MSM_BUS_SLAVE_TCU 672 +#define MSM_BUS_SLAVE_APPSS 673 +#define MSM_BUS_SLAVE_PCIE_PARF 674 +#define MSM_BUS_SLAVE_USB3_PHY_CFG 675 +#define MSM_BUS_SLAVE_IPA_CFG 676 +#define MSM_BUS_SLAVE_A0NOC_SNOC 677 +#define MSM_BUS_SLAVE_A1NOC_SNOC 678 +#define MSM_BUS_SLAVE_A2NOC_SNOC 679 +#define MSM_BUS_SLAVE_HMSS_L3 680 +#define MSM_BUS_SLAVE_PIMEM_CFG 681 +#define MSM_BUS_SLAVE_DCC_CFG 682 +#define MSM_BUS_SLAVE_QDSS_RBCPR_APU_CFG 683 +#define MSM_BUS_SLAVE_PCIE_2_CFG 684 +#define MSM_BUS_SLAVE_PCIE20_AHB2PHY 685 +#define MSM_BUS_SLAVE_A0NOC_CFG 686 +#define MSM_BUS_SLAVE_A1NOC_CFG 687 +#define MSM_BUS_SLAVE_A2NOC_CFG 688 +#define MSM_BUS_SLAVE_A1NOC_MPU_CFG 689 +#define MSM_BUS_SLAVE_A2NOC_MPU_CFG 690 +#define MSM_BUS_SLAVE_A0NOC_SMMU_CFG 691 +#define MSM_BUS_SLAVE_A1NOC_SMMU_CFG 692 +#define MSM_BUS_SLAVE_A2NOC_SMMU_CFG 693 +#define MSM_BUS_SLAVE_LPASS_SMMU_CFG 694 +#define MSM_BUS_SLAVE_MMAGIC_CFG 695 +#define MSM_BUS_SLAVE_VENUS_THROTTLE_CFG 696 +#define MSM_BUS_SLAVE_SSC_CFG 697 +#define MSM_BUS_SLAVE_DSA_CFG 698 +#define MSM_BUS_SLAVE_DSA_MPU_CFG 699 +#define MSM_BUS_SLAVE_DISPLAY_THROTTLE_CFG 700 +#define MSM_BUS_SLAVE_SMMU_CPP_CFG 701 +#define MSM_BUS_SLAVE_SMMU_JPEG_CFG 702 +#define MSM_BUS_SLAVE_SMMU_MDP_CFG 703 +#define MSM_BUS_SLAVE_SMMU_ROTATOR_CFG 704 +#define MSM_BUS_SLAVE_SMMU_VENUS_CFG 705 +#define MSM_BUS_SLAVE_SMMU_VFE_CFG 706 +#define MSM_BUS_SLAVE_A0NOC_MPU_CFG 707 +#define MSM_BUS_SLAVE_VMEM_CFG 708 +#define MSM_BUS_SLAVE_CAMERA_THROTTLE_CFG 709 +#define MSM_BUS_SLAVE_VMEM 710 +#define MSM_BUS_SLAVE_AHB2PHY 711 +#define MSM_BUS_SLAVE_PIMEM 712 +#define MSM_BUS_SLAVE_SNOC_VMEM 713 +#define MSM_BUS_SLAVE_PCIE_2 714 +#define MSM_BUS_SLAVE_RBCPR_MX 715 +#define MSM_BUS_SLAVE_RBCPR_CX 716 +#define MSM_BUS_SLAVE_BIMC_PCNOC 717 +#define MSM_BUS_SLAVE_PCNOC_BIMC_1 718 +#define MSM_BUS_SLAVE_SGMII 719 +#define MSM_BUS_SLAVE_SPMI_FETCHER 720 +#define MSM_BUS_PNOC_SLV_6 721 +#define MSM_BUS_SLAVE_MMSS_SMMU_CFG 722 +#define MSM_BUS_SLAVE_WLAN 723 +#define MSM_BUS_SLAVE_CRVIRT_A2NOC 724 +#define MSM_BUS_SLAVE_CNOC_A2NOC 725 +#define MSM_BUS_SLAVE_GLM 726 +#define MSM_BUS_SLAVE_GNOC_BIMC 727 +#define MSM_BUS_SLAVE_GNOC_SNOC 728 +#define MSM_BUS_SLAVE_QM_CFG 729 +#define MSM_BUS_SLAVE_TLMM_EAST 730 +#define MSM_BUS_SLAVE_TLMM_NORTH 731 +#define MSM_BUS_SLAVE_TLMM_WEST 732 +#define MSM_BUS_SLAVE_SKL 733 +#define MSM_BUS_SLAVE_LPASS_TCM 734 +#define MSM_BUS_SLAVE_TLMM_SOUTH 735 +#define MSM_BUS_SLAVE_TLMM_CENTER 736 +#define MSM_BUS_MSS_NAV_CE_MPU_CFG 737 +#define MSM_BUS_SLAVE_A2NOC_THROTTLE_CFG 738 +#define MSM_BUS_SLAVE_CDSP 739 +#define MSM_BUS_SLAVE_CDSP_SMMU_CFG 740 +#define MSM_BUS_SLAVE_LPASS_MPU_CFG 741 +#define MSM_BUS_SLAVE_CSI_PHY_CFG 742 +#define MSM_BUS_SLAVE_LAST 743 + +#define MSM_BUS_SYSTEM_FPB_SLAVE_SYSTEM MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB +#define MSM_BUS_CPSS_FPB_SLAVE_SYSTEM MSM_BUS_SYSTEM_SLAVE_CPSS_FPB + +/* + * ID's used in RPM messages + */ +#define ICBID_MASTER_APPSS_PROC 0 +#define ICBID_MASTER_MSS_PROC 1 +#define ICBID_MASTER_MNOC_BIMC 2 +#define ICBID_MASTER_SNOC_BIMC 3 +#define ICBID_MASTER_SNOC_BIMC_0 ICBID_MASTER_SNOC_BIMC +#define ICBID_MASTER_CNOC_MNOC_MMSS_CFG 4 +#define ICBID_MASTER_CNOC_MNOC_CFG 5 +#define ICBID_MASTER_GFX3D 6 +#define ICBID_MASTER_JPEG 7 +#define ICBID_MASTER_MDP 8 +#define ICBID_MASTER_MDP0 ICBID_MASTER_MDP +#define ICBID_MASTER_MDPS ICBID_MASTER_MDP +#define ICBID_MASTER_VIDEO 9 +#define ICBID_MASTER_VIDEO_P0 ICBID_MASTER_VIDEO +#define ICBID_MASTER_VIDEO_P1 10 +#define ICBID_MASTER_VFE 11 +#define ICBID_MASTER_VFE0 ICBID_MASTER_VFE +#define ICBID_MASTER_CNOC_ONOC_CFG 12 +#define ICBID_MASTER_JPEG_OCMEM 13 +#define ICBID_MASTER_MDP_OCMEM 14 +#define ICBID_MASTER_VIDEO_P0_OCMEM 15 +#define ICBID_MASTER_VIDEO_P1_OCMEM 16 +#define ICBID_MASTER_VFE_OCMEM 17 +#define ICBID_MASTER_LPASS_AHB 18 +#define ICBID_MASTER_QDSS_BAM 19 +#define ICBID_MASTER_SNOC_CFG 20 +#define ICBID_MASTER_BIMC_SNOC 21 +#define ICBID_MASTER_BIMC_SNOC_0 ICBID_MASTER_BIMC_SNOC +#define ICBID_MASTER_CNOC_SNOC 22 +#define ICBID_MASTER_CRYPTO 23 +#define ICBID_MASTER_CRYPTO_CORE0 ICBID_MASTER_CRYPTO +#define ICBID_MASTER_CRYPTO_CORE1 24 +#define ICBID_MASTER_LPASS_PROC 25 +#define ICBID_MASTER_MSS 26 +#define ICBID_MASTER_MSS_NAV 27 +#define ICBID_MASTER_OCMEM_DMA 28 +#define ICBID_MASTER_PNOC_SNOC 29 +#define ICBID_MASTER_WCSS 30 +#define ICBID_MASTER_QDSS_ETR 31 +#define ICBID_MASTER_USB3 32 +#define ICBID_MASTER_USB3_0 ICBID_MASTER_USB3 +#define ICBID_MASTER_SDCC_1 33 +#define ICBID_MASTER_SDCC_3 34 +#define ICBID_MASTER_SDCC_2 35 +#define ICBID_MASTER_SDCC_4 36 +#define ICBID_MASTER_TSIF 37 +#define ICBID_MASTER_BAM_DMA 38 +#define ICBID_MASTER_BLSP_2 39 +#define ICBID_MASTER_USB_HSIC 40 +#define ICBID_MASTER_BLSP_1 41 +#define ICBID_MASTER_USB_HS 42 +#define ICBID_MASTER_USB_HS1 ICBID_MASTER_USB_HS +#define ICBID_MASTER_PNOC_CFG 43 +#define ICBID_MASTER_SNOC_PNOC 44 +#define ICBID_MASTER_RPM_INST 45 +#define ICBID_MASTER_RPM_DATA 46 +#define ICBID_MASTER_RPM_SYS 47 +#define ICBID_MASTER_DEHR 48 +#define ICBID_MASTER_QDSS_DAP 49 +#define ICBID_MASTER_SPDM 50 +#define ICBID_MASTER_TIC 51 +#define ICBID_MASTER_SNOC_CNOC 52 +#define ICBID_MASTER_GFX3D_OCMEM 53 +#define ICBID_MASTER_GFX3D_GMEM ICBID_MASTER_GFX3D_OCMEM +#define ICBID_MASTER_OVIRT_SNOC 54 +#define ICBID_MASTER_SNOC_OVIRT 55 +#define ICBID_MASTER_SNOC_GVIRT ICBID_MASTER_SNOC_OVIRT +#define ICBID_MASTER_ONOC_OVIRT 56 +#define ICBID_MASTER_USB_HS2 57 +#define ICBID_MASTER_QPIC 58 +#define ICBID_MASTER_IPA 59 +#define ICBID_MASTER_DSI 60 +#define ICBID_MASTER_MDP1 61 +#define ICBID_MASTER_MDPE ICBID_MASTER_MDP1 +#define ICBID_MASTER_VPU_PROC 62 +#define ICBID_MASTER_VPU 63 +#define ICBID_MASTER_VPU0 ICBID_MASTER_VPU +#define ICBID_MASTER_CRYPTO_CORE2 64 +#define ICBID_MASTER_PCIE_0 65 +#define ICBID_MASTER_PCIE_1 66 +#define ICBID_MASTER_SATA 67 +#define ICBID_MASTER_UFS 68 +#define ICBID_MASTER_USB3_1 69 +#define ICBID_MASTER_VIDEO_OCMEM 70 +#define ICBID_MASTER_VPU1 71 +#define ICBID_MASTER_VCAP 72 +#define ICBID_MASTER_EMAC 73 +#define ICBID_MASTER_BCAST 74 +#define ICBID_MASTER_MMSS_PROC 75 +#define ICBID_MASTER_SNOC_BIMC_1 76 +#define ICBID_MASTER_SNOC_PCNOC 77 +#define ICBID_MASTER_AUDIO 78 +#define ICBID_MASTER_MM_INT_0 79 +#define ICBID_MASTER_MM_INT_1 80 +#define ICBID_MASTER_MM_INT_2 81 +#define ICBID_MASTER_MM_INT_BIMC 82 +#define ICBID_MASTER_MSS_INT 83 +#define ICBID_MASTER_PCNOC_CFG 84 +#define ICBID_MASTER_PCNOC_INT_0 85 +#define ICBID_MASTER_PCNOC_INT_1 86 +#define ICBID_MASTER_PCNOC_M_0 87 +#define ICBID_MASTER_PCNOC_M_1 88 +#define ICBID_MASTER_PCNOC_S_0 89 +#define ICBID_MASTER_PCNOC_S_1 90 +#define ICBID_MASTER_PCNOC_S_2 91 +#define ICBID_MASTER_PCNOC_S_3 92 +#define ICBID_MASTER_PCNOC_S_4 93 +#define ICBID_MASTER_PCNOC_S_6 94 +#define ICBID_MASTER_PCNOC_S_7 95 +#define ICBID_MASTER_PCNOC_S_8 96 +#define ICBID_MASTER_PCNOC_S_9 97 +#define ICBID_MASTER_QDSS_INT 98 +#define ICBID_MASTER_SNOC_INT_0 99 +#define ICBID_MASTER_SNOC_INT_1 100 +#define ICBID_MASTER_SNOC_INT_BIMC 101 +#define ICBID_MASTER_TCU_0 102 +#define ICBID_MASTER_TCU_1 103 +#define ICBID_MASTER_BIMC_INT_0 104 +#define ICBID_MASTER_BIMC_INT_1 105 +#define ICBID_MASTER_CAMERA 106 +#define ICBID_MASTER_RICA 107 +#define ICBID_MASTER_SNOC_BIMC_2 108 +#define ICBID_MASTER_BIMC_SNOC_1 109 +#define ICBID_MASTER_A0NOC_SNOC 110 +#define ICBID_MASTER_A1NOC_SNOC 111 +#define ICBID_MASTER_A2NOC_SNOC 112 +#define ICBID_MASTER_PIMEM 113 +#define ICBID_MASTER_SNOC_VMEM 114 +#define ICBID_MASTER_CPP 115 +#define ICBID_MASTER_CNOC_A1NOC 116 +#define ICBID_MASTER_PNOC_A1NOC 117 +#define ICBID_MASTER_HMSS 118 +#define ICBID_MASTER_PCIE_2 119 +#define ICBID_MASTER_ROTATOR 120 +#define ICBID_MASTER_VENUS_VMEM 121 +#define ICBID_MASTER_DCC 122 +#define ICBID_MASTER_MCDMA 123 +#define ICBID_MASTER_PCNOC_INT_2 124 +#define ICBID_MASTER_PCNOC_INT_3 125 +#define ICBID_MASTER_PCNOC_INT_4 126 +#define ICBID_MASTER_PCNOC_INT_5 127 +#define ICBID_MASTER_PCNOC_INT_6 128 +#define ICBID_MASTER_PCNOC_S_5 129 +#define ICBID_MASTER_SENSORS_AHB 130 +#define ICBID_MASTER_SENSORS_PROC 131 +#define ICBID_MASTER_QSPI 132 +#define ICBID_MASTER_VFE1 133 +#define ICBID_MASTER_SNOC_INT_2 134 +#define ICBID_MASTER_SMMNOC_BIMC 135 +#define ICBID_MASTER_CRVIRT_A1NOC 136 +#define ICBID_MASTER_XM_USB_HS1 137 +#define ICBID_MASTER_XI_USB_HS1 138 +#define ICBID_MASTER_PCNOC_BIMC_1 139 +#define ICBID_MASTER_BIMC_PCNOC 140 +#define ICBID_MASTER_XI_HSIC 141 +#define ICBID_MASTER_SGMII 142 +#define ICBID_MASTER_SPMI_FETCHER 143 +#define ICBID_MASTER_GNOC_BIMC 144 +#define ICBID_MASTER_CRVIRT_A2NOC 145 +#define ICBID_MASTER_CNOC_A2NOC 146 +#define ICBID_MASTER_WLAN 147 +#define ICBID_MASTER_MSS_CE 148 +#define ICBID_MASTER_CDSP_PROC 149 +#define ICBID_MASTER_GNOC_SNOC 150 + +#define ICBID_SLAVE_EBI1 0 +#define ICBID_SLAVE_APPSS_L2 1 +#define ICBID_SLAVE_BIMC_SNOC 2 +#define ICBID_SLAVE_BIMC_SNOC_0 ICBID_SLAVE_BIMC_SNOC +#define ICBID_SLAVE_CAMERA_CFG 3 +#define ICBID_SLAVE_DISPLAY_CFG 4 +#define ICBID_SLAVE_OCMEM_CFG 5 +#define ICBID_SLAVE_CPR_CFG 6 +#define ICBID_SLAVE_CPR_XPU_CFG 7 +#define ICBID_SLAVE_MISC_CFG 8 +#define ICBID_SLAVE_MISC_XPU_CFG 9 +#define ICBID_SLAVE_VENUS_CFG 10 +#define ICBID_SLAVE_GFX3D_CFG 11 +#define ICBID_SLAVE_MMSS_CLK_CFG 12 +#define ICBID_SLAVE_MMSS_CLK_XPU_CFG 13 +#define ICBID_SLAVE_MNOC_MPU_CFG 14 +#define ICBID_SLAVE_ONOC_MPU_CFG 15 +#define ICBID_SLAVE_MNOC_BIMC 16 +#define ICBID_SLAVE_SERVICE_MNOC 17 +#define ICBID_SLAVE_OCMEM 18 +#define ICBID_SLAVE_GMEM ICBID_SLAVE_OCMEM +#define ICBID_SLAVE_SERVICE_ONOC 19 +#define ICBID_SLAVE_APPSS 20 +#define ICBID_SLAVE_LPASS 21 +#define ICBID_SLAVE_USB3 22 +#define ICBID_SLAVE_USB3_0 ICBID_SLAVE_USB3 +#define ICBID_SLAVE_WCSS 23 +#define ICBID_SLAVE_SNOC_BIMC 24 +#define ICBID_SLAVE_SNOC_BIMC_0 ICBID_SLAVE_SNOC_BIMC +#define ICBID_SLAVE_SNOC_CNOC 25 +#define ICBID_SLAVE_IMEM 26 +#define ICBID_SLAVE_OCIMEM ICBID_SLAVE_IMEM +#define ICBID_SLAVE_SNOC_OVIRT 27 +#define ICBID_SLAVE_SNOC_GVIRT ICBID_SLAVE_SNOC_OVIRT +#define ICBID_SLAVE_SNOC_PNOC 28 +#define ICBID_SLAVE_SNOC_PCNOC ICBID_SLAVE_SNOC_PNOC +#define ICBID_SLAVE_SERVICE_SNOC 29 +#define ICBID_SLAVE_QDSS_STM 30 +#define ICBID_SLAVE_SDCC_1 31 +#define ICBID_SLAVE_SDCC_3 32 +#define ICBID_SLAVE_SDCC_2 33 +#define ICBID_SLAVE_SDCC_4 34 +#define ICBID_SLAVE_TSIF 35 +#define ICBID_SLAVE_BAM_DMA 36 +#define ICBID_SLAVE_BLSP_2 37 +#define ICBID_SLAVE_USB_HSIC 38 +#define ICBID_SLAVE_BLSP_1 39 +#define ICBID_SLAVE_USB_HS 40 +#define ICBID_SLAVE_USB_HS1 ICBID_SLAVE_USB_HS +#define ICBID_SLAVE_PDM 41 +#define ICBID_SLAVE_PERIPH_APU_CFG 42 +#define ICBID_SLAVE_PNOC_MPU_CFG 43 +#define ICBID_SLAVE_PRNG 44 +#define ICBID_SLAVE_PNOC_SNOC 45 +#define ICBID_SLAVE_PCNOC_SNOC ICBID_SLAVE_PNOC_SNOC +#define ICBID_SLAVE_SERVICE_PNOC 46 +#define ICBID_SLAVE_CLK_CTL 47 +#define ICBID_SLAVE_CNOC_MSS 48 +#define ICBID_SLAVE_PCNOC_MSS ICBID_SLAVE_CNOC_MSS +#define ICBID_SLAVE_SECURITY 49 +#define ICBID_SLAVE_TCSR 50 +#define ICBID_SLAVE_TLMM 51 +#define ICBID_SLAVE_CRYPTO_0_CFG 52 +#define ICBID_SLAVE_CRYPTO_1_CFG 53 +#define ICBID_SLAVE_IMEM_CFG 54 +#define ICBID_SLAVE_MESSAGE_RAM 55 +#define ICBID_SLAVE_BIMC_CFG 56 +#define ICBID_SLAVE_BOOT_ROM 57 +#define ICBID_SLAVE_CNOC_MNOC_MMSS_CFG 58 +#define ICBID_SLAVE_PMIC_ARB 59 +#define ICBID_SLAVE_SPDM_WRAPPER 60 +#define ICBID_SLAVE_DEHR_CFG 61 +#define ICBID_SLAVE_MPM 62 +#define ICBID_SLAVE_QDSS_CFG 63 +#define ICBID_SLAVE_RBCPR_CFG 64 +#define ICBID_SLAVE_RBCPR_CX_CFG ICBID_SLAVE_RBCPR_CFG +#define ICBID_SLAVE_RBCPR_QDSS_APU_CFG 65 +#define ICBID_SLAVE_CNOC_MNOC_CFG 66 +#define ICBID_SLAVE_SNOC_MPU_CFG 67 +#define ICBID_SLAVE_CNOC_ONOC_CFG 68 +#define ICBID_SLAVE_PNOC_CFG 69 +#define ICBID_SLAVE_SNOC_CFG 70 +#define ICBID_SLAVE_EBI1_DLL_CFG 71 +#define ICBID_SLAVE_PHY_APU_CFG 72 +#define ICBID_SLAVE_EBI1_PHY_CFG 73 +#define ICBID_SLAVE_RPM 74 +#define ICBID_SLAVE_CNOC_SNOC 75 +#define ICBID_SLAVE_SERVICE_CNOC 76 +#define ICBID_SLAVE_OVIRT_SNOC 77 +#define ICBID_SLAVE_OVIRT_OCMEM 78 +#define ICBID_SLAVE_USB_HS2 79 +#define ICBID_SLAVE_QPIC 80 +#define ICBID_SLAVE_IPS_CFG 81 +#define ICBID_SLAVE_DSI_CFG 82 +#define ICBID_SLAVE_USB3_1 83 +#define ICBID_SLAVE_PCIE_0 84 +#define ICBID_SLAVE_PCIE_1 85 +#define ICBID_SLAVE_PSS_SMMU_CFG 86 +#define ICBID_SLAVE_CRYPTO_2_CFG 87 +#define ICBID_SLAVE_PCIE_0_CFG 88 +#define ICBID_SLAVE_PCIE_1_CFG 89 +#define ICBID_SLAVE_SATA_CFG 90 +#define ICBID_SLAVE_SPSS_GENI_IR 91 +#define ICBID_SLAVE_UFS_CFG 92 +#define ICBID_SLAVE_AVSYNC_CFG 93 +#define ICBID_SLAVE_VPU_CFG 94 +#define ICBID_SLAVE_USB_PHY_CFG 95 +#define ICBID_SLAVE_RBCPR_MX_CFG 96 +#define ICBID_SLAVE_PCIE_PARF 97 +#define ICBID_SLAVE_VCAP_CFG 98 +#define ICBID_SLAVE_EMAC_CFG 99 +#define ICBID_SLAVE_BCAST_CFG 100 +#define ICBID_SLAVE_KLM_CFG 101 +#define ICBID_SLAVE_DISPLAY_PWM 102 +#define ICBID_SLAVE_GENI 103 +#define ICBID_SLAVE_SNOC_BIMC_1 104 +#define ICBID_SLAVE_AUDIO 105 +#define ICBID_SLAVE_CATS_0 106 +#define ICBID_SLAVE_CATS_1 107 +#define ICBID_SLAVE_MM_INT_0 108 +#define ICBID_SLAVE_MM_INT_1 109 +#define ICBID_SLAVE_MM_INT_2 110 +#define ICBID_SLAVE_MM_INT_BIMC 111 +#define ICBID_SLAVE_MMU_MODEM_XPU_CFG 112 +#define ICBID_SLAVE_MSS_INT 113 +#define ICBID_SLAVE_PCNOC_INT_0 114 +#define ICBID_SLAVE_PCNOC_INT_1 115 +#define ICBID_SLAVE_PCNOC_M_0 116 +#define ICBID_SLAVE_PCNOC_M_1 117 +#define ICBID_SLAVE_PCNOC_S_0 118 +#define ICBID_SLAVE_PCNOC_S_1 119 +#define ICBID_SLAVE_PCNOC_S_2 120 +#define ICBID_SLAVE_PCNOC_S_3 121 +#define ICBID_SLAVE_PCNOC_S_4 122 +#define ICBID_SLAVE_PCNOC_S_6 123 +#define ICBID_SLAVE_PCNOC_S_7 124 +#define ICBID_SLAVE_PCNOC_S_8 125 +#define ICBID_SLAVE_PCNOC_S_9 126 +#define ICBID_SLAVE_PRNG_XPU_CFG 127 +#define ICBID_SLAVE_QDSS_INT 128 +#define ICBID_SLAVE_RPM_XPU_CFG 129 +#define ICBID_SLAVE_SNOC_INT_0 130 +#define ICBID_SLAVE_SNOC_INT_1 131 +#define ICBID_SLAVE_SNOC_INT_BIMC 132 +#define ICBID_SLAVE_TCU 133 +#define ICBID_SLAVE_BIMC_INT_0 134 +#define ICBID_SLAVE_BIMC_INT_1 135 +#define ICBID_SLAVE_RICA_CFG 136 +#define ICBID_SLAVE_SNOC_BIMC_2 137 +#define ICBID_SLAVE_BIMC_SNOC_1 138 +#define ICBID_SLAVE_PNOC_A1NOC 139 +#define ICBID_SLAVE_SNOC_VMEM 140 +#define ICBID_SLAVE_A0NOC_SNOC 141 +#define ICBID_SLAVE_A1NOC_SNOC 142 +#define ICBID_SLAVE_A2NOC_SNOC 143 +#define ICBID_SLAVE_A0NOC_CFG 144 +#define ICBID_SLAVE_A0NOC_MPU_CFG 145 +#define ICBID_SLAVE_A0NOC_SMMU_CFG 146 +#define ICBID_SLAVE_A1NOC_CFG 147 +#define ICBID_SLAVE_A1NOC_MPU_CFG 148 +#define ICBID_SLAVE_A1NOC_SMMU_CFG 149 +#define ICBID_SLAVE_A2NOC_CFG 150 +#define ICBID_SLAVE_A2NOC_MPU_CFG 151 +#define ICBID_SLAVE_A2NOC_SMMU_CFG 152 +#define ICBID_SLAVE_AHB2PHY 153 +#define ICBID_SLAVE_CAMERA_THROTTLE_CFG 154 +#define ICBID_SLAVE_DCC_CFG 155 +#define ICBID_SLAVE_DISPLAY_THROTTLE_CFG 156 +#define ICBID_SLAVE_DSA_CFG 157 +#define ICBID_SLAVE_DSA_MPU_CFG 158 +#define ICBID_SLAVE_SSC_MPU_CFG 159 +#define ICBID_SLAVE_HMSS_L3 160 +#define ICBID_SLAVE_LPASS_SMMU_CFG 161 +#define ICBID_SLAVE_MMAGIC_CFG 162 +#define ICBID_SLAVE_PCIE20_AHB2PHY 163 +#define ICBID_SLAVE_PCIE_2 164 +#define ICBID_SLAVE_PCIE_2_CFG 165 +#define ICBID_SLAVE_PIMEM 166 +#define ICBID_SLAVE_PIMEM_CFG 167 +#define ICBID_SLAVE_QDSS_RBCPR_APU_CFG 168 +#define ICBID_SLAVE_RBCPR_CX 169 +#define ICBID_SLAVE_RBCPR_MX 170 +#define ICBID_SLAVE_SMMU_CPP_CFG 171 +#define ICBID_SLAVE_SMMU_JPEG_CFG 172 +#define ICBID_SLAVE_SMMU_MDP_CFG 173 +#define ICBID_SLAVE_SMMU_ROTATOR_CFG 174 +#define ICBID_SLAVE_SMMU_VENUS_CFG 175 +#define ICBID_SLAVE_SMMU_VFE_CFG 176 +#define ICBID_SLAVE_SSC_CFG 177 +#define ICBID_SLAVE_VENUS_THROTTLE_CFG 178 +#define ICBID_SLAVE_VMEM 179 +#define ICBID_SLAVE_VMEM_CFG 180 +#define ICBID_SLAVE_QDSS_MPU_CFG 181 +#define ICBID_SLAVE_USB3_PHY_CFG 182 +#define ICBID_SLAVE_IPA_CFG 183 +#define ICBID_SLAVE_PCNOC_INT_2 184 +#define ICBID_SLAVE_PCNOC_INT_3 185 +#define ICBID_SLAVE_PCNOC_INT_4 186 +#define ICBID_SLAVE_PCNOC_INT_5 187 +#define ICBID_SLAVE_PCNOC_INT_6 188 +#define ICBID_SLAVE_PCNOC_S_5 189 +#define ICBID_SLAVE_QSPI 190 +#define ICBID_SLAVE_A1NOC_MS_MPU_CFG 191 +#define ICBID_SLAVE_A2NOC_MS_MPU_CFG 192 +#define ICBID_SLAVE_MODEM_Q6_SMMU_CFG 193 +#define ICBID_SLAVE_MSS_MPU_CFG 194 +#define ICBID_SLAVE_MSS_PROC_MS_MPU_CFG 195 +#define ICBID_SLAVE_SKL 196 +#define ICBID_SLAVE_SNOC_INT_2 197 +#define ICBID_SLAVE_SMMNOC_BIMC 198 +#define ICBID_SLAVE_CRVIRT_A1NOC 199 +#define ICBID_SLAVE_SGMII 200 +#define ICBID_SLAVE_QHS4_APPS 201 +#define ICBID_SLAVE_BIMC_PCNOC 202 +#define ICBID_SLAVE_PCNOC_BIMC_1 203 +#define ICBID_SLAVE_SPMI_FETCHER 204 +#define ICBID_SLAVE_MMSS_SMMU_CFG 205 +#define ICBID_SLAVE_WLAN 206 +#define ICBID_SLAVE_CRVIRT_A2NOC 207 +#define ICBID_SLAVE_CNOC_A2NOC 208 +#define ICBID_SLAVE_GLM 209 +#define ICBID_SLAVE_GNOC_BIMC 210 +#define ICBID_SLAVE_GNOC_SNOC 211 +#define ICBID_SLAVE_QM_CFG 212 +#define ICBID_SLAVE_TLMM_EAST 213 +#define ICBID_SLAVE_TLMM_NORTH 214 +#define ICBID_SLAVE_TLMM_WEST 215 +#define ICBID_SLAVE_LPASS_TCM 216 +#define ICBID_SLAVE_TLMM_SOUTH 217 +#define ICBID_SLAVE_TLMM_CENTER 218 +#define ICBID_SLAVE_MSS_NAV_CE_MPU_CFG 219 +#define ICBID_SLAVE_A2NOC_THROTTLE_CFG 220 +#define ICBID_SLAVE_CDSP 221 +#define ICBID_SLAVE_CDSP_SMMU_CFG 222 +#define ICBID_SLAVE_LPASS_MPU_CFG 223 +#define ICBID_SLAVE_CSI_PHY_CFG 224 +#endif diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index fee44322a69c..12d7619afa22 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -232,6 +232,7 @@ struct drm_msm_wait_fence { __u32 fence; /* in */ __u32 pad; struct drm_msm_timespec timeout; /* in */ + __u32 queueid; /* in, submitqueue id */ }; /* madvise provides a way to tell the kernel in case a buffers contents -- cgit v1.2.3 From a6e29a0eea3ccbf6fb8a908a3fc3e931f3ba2ae4 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:06:58 -0600 Subject: drm/msm: Add a parameter query for the number of ringbuffers In order to manage ringbuffer priority to its fullest userspace should know how many ringbuffers it has to work with. Add a parameter to return the number of active rings. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ include/uapi/drm/msm_drm.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index fd0fb0568dd3..4e9caf97b20f 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -57,6 +57,9 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) return ret; } return -EINVAL; + case MSM_PARAM_NR_RINGS: + *value = gpu->nr_rings; + return 0; default: DBG("%s: invalid param: %u", gpu->name, param); return -EINVAL; diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 12d7619afa22..bbbaffad772d 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -73,6 +73,7 @@ struct drm_msm_timespec { #define MSM_PARAM_MAX_FREQ 0x04 #define MSM_PARAM_TIMESTAMP 0x05 #define MSM_PARAM_GMEM_BASE 0x06 +#define MSM_PARAM_NR_RINGS 0x07 struct drm_msm_param { __u32 pipe; /* in, MSM_PIPE_x */ -- cgit v1.2.3 From 4c7085a5d581a547232086b4ac0f553024eb9cec Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:06:59 -0600 Subject: drm/msm: Shadow current pointer in the ring until command is complete Add a shadow pointer to track the current command being written into the ring. Don't commit it as 'cur' until the command is submitted. Because 'cur' is used to construct the software copy of the wptr this ensures that somebody peeking in on the ring doesn't assume that a command is inflight while it is being written. This isn't a huge deal with a single ring (though technically the hangcheck could assume the system is prematurely busy when it isn't) but it will be rather important for preemption where the decision to preempt is based on a non-empty ringbuffer. Without a shadow an aggressive preemption scheme could assume that the ringbuffer is non empty and switch to it before the CPU is done writing the command and boom. Even though preemption won't be supported for all targets because of the way the code is organized it is simpler to make this generic for all targets. The extra load for non-preemption targets should be minimal. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 9 +++++++-- drivers/gpu/drm/msm/msm_ringbuffer.c | 1 + drivers/gpu/drm/msm/msm_ringbuffer.h | 12 ++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 4e9caf97b20f..63d05a376700 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -188,6 +188,7 @@ int adreno_hw_init(struct msm_gpu *gpu) } ring->cur = ring->start; + ring->next = ring->start; /* reset completed fence seqno: */ ring->memptrs->fence = ring->seqno; @@ -332,12 +333,15 @@ void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); uint32_t wptr; + /* Copy the shadow to the actual register */ + ring->cur = ring->next; + /* * Mask wptr value that we calculate to fit in the HW range. This is * to account for the possibility that the last command fit exactly into * the ringbuffer and rb->next hasn't wrapped to zero yet */ - wptr = get_wptr(ring) % (MSM_GPU_RINGBUFFER_SZ >> 2); + wptr = (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2); /* ensure writes to ringbuffer have hit system memory: */ mb(); @@ -449,7 +453,8 @@ static uint32_t ring_freewords(struct msm_ringbuffer *ring) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(ring->gpu); uint32_t size = MSM_GPU_RINGBUFFER_SZ >> 2; - uint32_t wptr = get_wptr(ring); + /* Use ring->next to calculate free size */ + uint32_t wptr = ring->next - ring->start; uint32_t rptr = get_rptr(adreno_gpu, ring); return (rptr + (size - 1) - wptr) % size; } diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 4db6ca719706..e39c4e392854 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -46,6 +46,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, goto fail; } ring->end = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2); + ring->next = ring->start; ring->cur = ring->start; ring->memptrs = memptrs; diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index ec44251ef9f2..3749764a238e 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -32,7 +32,7 @@ struct msm_ringbuffer { struct msm_gpu *gpu; int id; struct drm_gem_object *bo; - uint32_t *start, *end, *cur; + uint32_t *start, *end, *cur, *next; struct list_head submits; uint64_t iova; uint32_t seqno; @@ -51,9 +51,13 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring); static inline void OUT_RING(struct msm_ringbuffer *ring, uint32_t data) { - if (ring->cur == ring->end) - ring->cur = ring->start; - *(ring->cur++) = data; + /* + * ring->next points to the current command being written - it won't be + * committed as ring->cur until the flush + */ + if (ring->next == ring->end) + ring->next = ring->start; + *(ring->next++) = data; } #endif /* __MSM_RINGBUFFER_H__ */ -- cgit v1.2.3 From 4d87fc32dfd20ad0d4ffd5204f6e5d41d281e128 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:07:00 -0600 Subject: drm/msm: Make the value of RB_CNTL (almost) generic We use a global ringbuffer size and block size for all targets and at least for 5XX preemption we need to know the value the RB_CNTL in several locations so it makes sense to calculate it once and use it everywhere. The only monkey wrench is that we need to disable the RPTR shadow for A430 targets but that only needs to be done once and doesn't affect A5XX so we can or in the value at init time. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 12 +++++++----- drivers/gpu/drm/msm/msm_gpu.h | 5 +++++ 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 63d05a376700..f3f81fd35452 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -21,7 +21,6 @@ #include "msm_gem.h" #include "msm_mmu.h" -#define RB_BLKSIZE 32 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) { @@ -195,11 +194,14 @@ int adreno_hw_init(struct msm_gpu *gpu) ring->memptrs->rptr = 0; } - /* Setup REG_CP_RB_CNTL: */ + /* + * Setup REG_CP_RB_CNTL. The same value is used across targets (with + * the excpetion of A430 that disables the RPTR shadow) - the cacluation + * for the ringbuffer size and block size is moved to msm_gpu.h for the + * pre-processor to deal with and the A430 variant is ORed in here + */ adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL, - /* size is log2(quad-words): */ - AXXX_CP_RB_CNTL_BUFSZ(ilog2(MSM_GPU_RINGBUFFER_SZ / 8)) | - AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8)) | + MSM_GPU_RB_CNTL_DEFAULT | (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0)); /* Setup ringbuffer address - use ringbuffer[0] for GPU init */ diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 1be0317bb2c0..e113d64574d3 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -129,6 +129,11 @@ struct msm_gpu { /* It turns out that all targets use the same ringbuffer size */ #define MSM_GPU_RINGBUFFER_SZ SZ_32K +#define MSM_GPU_RINGBUFFER_BLKSIZE 32 + +#define MSM_GPU_RB_CNTL_DEFAULT \ + (AXXX_CP_RB_CNTL_BUFSZ(ilog2(MSM_GPU_RINGBUFFER_SZ / 8)) | \ + AXXX_CP_RB_CNTL_BLKSZ(ilog2(MSM_GPU_RINGBUFFER_BLKSIZE / 8))) static inline bool msm_gpu_active(struct msm_gpu *gpu) { -- cgit v1.2.3 From b1fc2839d2f92d09da90d1e09156a73ddaba8a93 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:07:01 -0600 Subject: drm/msm: Implement preemption for A5XX targets Implement preemption for A5XX targets - this allows multiple ringbuffers for different priorities with automatic preemption of a lower priority ringbuffer if a higher one is ready. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 176 ++++++++++++++++- drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 107 ++++++++++- drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 305 ++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 14 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 7 +- drivers/gpu/drm/msm/msm_drv.h | 2 +- drivers/gpu/drm/msm/msm_gpu.c | 5 +- drivers/gpu/drm/msm/msm_ringbuffer.c | 1 + drivers/gpu/drm/msm/msm_ringbuffer.h | 1 + 10 files changed, 599 insertions(+), 20 deletions(-) create mode 100644 drivers/gpu/drm/msm/adreno/a5xx_preempt.c (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 3c234e7b4742..d0b26dd80076 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -8,6 +8,7 @@ msm-y := \ adreno/a4xx_gpu.o \ adreno/a5xx_gpu.o \ adreno/a5xx_power.o \ + adreno/a5xx_preempt.o \ hdmi/hdmi.o \ hdmi/hdmi_audio.o \ hdmi/hdmi_bridge.o \ diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 32252f8ac30c..a1f4eeeb73e2 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -113,13 +113,65 @@ out: return ret; } +static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + uint32_t wptr; + unsigned long flags; + + spin_lock_irqsave(&ring->lock, flags); + + /* Copy the shadow to the actual register */ + ring->cur = ring->next; + + /* Make sure to wrap wptr if we need to */ + wptr = get_wptr(ring); + + spin_unlock_irqrestore(&ring->lock, flags); + + /* Make sure everything is posted before making a decision */ + mb(); + + /* Update HW if this is the current ring and we are not in preempt */ + if (a5xx_gpu->cur_ring == ring && !a5xx_in_preempt(a5xx_gpu)) + gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr); +} + static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); struct msm_drm_private *priv = gpu->dev->dev_private; struct msm_ringbuffer *ring = submit->ring; unsigned int i, ibs = 0; + OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); + OUT_RING(ring, 0x02); + + /* Turn off protected mode to write to special registers */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 0); + + /* Set the save preemption record for the ring/command */ + OUT_PKT4(ring, REG_A5XX_CP_CONTEXT_SWITCH_SAVE_ADDR_LO, 2); + OUT_RING(ring, lower_32_bits(a5xx_gpu->preempt_iova[submit->ring->id])); + OUT_RING(ring, upper_32_bits(a5xx_gpu->preempt_iova[submit->ring->id])); + + /* Turn back on protected mode */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 1); + + /* Enable local preemption for finegrain preemption */ + OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); + OUT_RING(ring, 0x02); + + /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */ + OUT_PKT7(ring, CP_YIELD_ENABLE, 1); + OUT_RING(ring, 0x02); + + /* Submit the commands */ for (i = 0; i < submit->nr_cmds; i++) { switch (submit->cmd[i].type) { case MSM_SUBMIT_CMD_IB_TARGET_BUF: @@ -137,16 +189,54 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, } } + /* + * Write the render mode to NULL (0) to indicate to the CP that the IBs + * are done rendering - otherwise a lucky preemption would start + * replaying from the last checkpoint + */ + OUT_PKT7(ring, CP_SET_RENDER_MODE, 5); + OUT_RING(ring, 0); + OUT_RING(ring, 0); + OUT_RING(ring, 0); + OUT_RING(ring, 0); + OUT_RING(ring, 0); + + /* Turn off IB level preemptions */ + OUT_PKT7(ring, CP_YIELD_ENABLE, 1); + OUT_RING(ring, 0x01); + + /* Write the fence to the scratch register */ OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1); OUT_RING(ring, submit->seqno); + /* + * Execute a CACHE_FLUSH_TS event. This will ensure that the + * timestamp is written to the memory and then triggers the interrupt + */ OUT_PKT7(ring, CP_EVENT_WRITE, 4); OUT_RING(ring, CACHE_FLUSH_TS | (1 << 31)); OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence))); OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence))); OUT_RING(ring, submit->seqno); - gpu->funcs->flush(gpu, ring); + /* Yield the floor on command completion */ + OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4); + /* + * If dword[2:1] are non zero, they specify an address for the CP to + * write the value of dword[3] to on preemption complete. Write 0 to + * skip the write + */ + OUT_RING(ring, 0x00); + OUT_RING(ring, 0x00); + /* Data value - not used if the address above is 0 */ + OUT_RING(ring, 0x01); + /* Set bit 0 to trigger an interrupt on preempt complete */ + OUT_RING(ring, 0x01); + + a5xx_flush(gpu, ring); + + /* Check to see if we need to start preemption */ + a5xx_preempt_trigger(gpu); } static const struct { @@ -297,6 +387,50 @@ static int a5xx_me_init(struct msm_gpu *gpu) return a5xx_idle(gpu, ring) ? 0 : -EINVAL; } +static int a5xx_preempt_start(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + struct msm_ringbuffer *ring = gpu->rb[0]; + + if (gpu->nr_rings == 1) + return 0; + + /* Turn off protected mode to write to special registers */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 0); + + /* Set the save preemption record for the ring/command */ + OUT_PKT4(ring, REG_A5XX_CP_CONTEXT_SWITCH_SAVE_ADDR_LO, 2); + OUT_RING(ring, lower_32_bits(a5xx_gpu->preempt_iova[ring->id])); + OUT_RING(ring, upper_32_bits(a5xx_gpu->preempt_iova[ring->id])); + + /* Turn back on protected mode */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 1); + + OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); + OUT_RING(ring, 0x00); + + OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1); + OUT_RING(ring, 0x01); + + OUT_PKT7(ring, CP_YIELD_ENABLE, 1); + OUT_RING(ring, 0x01); + + /* Yield the floor on command completion */ + OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4); + OUT_RING(ring, 0x00); + OUT_RING(ring, 0x00); + OUT_RING(ring, 0x01); + OUT_RING(ring, 0x01); + + gpu->funcs->flush(gpu, ring); + + return a5xx_idle(gpu, ring) ? 0 : -EINVAL; +} + + static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu, const struct firmware *fw, u64 *iova) { @@ -412,6 +546,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu) A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \ A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \ A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT | \ + A5XX_RBBM_INT_0_MASK_CP_SW | \ A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \ A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \ A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP) @@ -556,6 +691,8 @@ static int a5xx_hw_init(struct msm_gpu *gpu) if (ret) return ret; + a5xx_preempt_hw_init(gpu); + a5xx_gpmu_ucode_init(gpu); ret = a5xx_ucode_init(gpu); @@ -610,6 +747,9 @@ static int a5xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0); } + /* Last step - yield the ringbuffer */ + a5xx_preempt_start(gpu); + return 0; } @@ -640,6 +780,8 @@ static void a5xx_destroy(struct msm_gpu *gpu) DBG("%s", gpu->name); + a5xx_preempt_fini(gpu); + if (a5xx_gpu->pm4_bo) { if (a5xx_gpu->pm4_iova) msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace); @@ -677,6 +819,14 @@ static inline bool _a5xx_check_idle(struct msm_gpu *gpu) bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring) { + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + + if (ring != a5xx_gpu->cur_ring) { + WARN(1, "Tried to idle a non-current ringbuffer\n"); + return false; + } + /* wait for CP to drain ringbuffer: */ if (!adreno_idle(gpu, ring)) return false; @@ -871,8 +1021,13 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu) if (status & A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP) a5xx_gpmu_err_irq(gpu); - if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) + if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) { + a5xx_preempt_trigger(gpu); msm_gpu_retire(gpu); + } + + if (status & A5XX_RBBM_INT_0_MASK_CP_SW) + a5xx_preempt_irq(gpu); return IRQ_HANDLED; } @@ -1002,6 +1157,14 @@ static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m) } #endif +static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + + return a5xx_gpu->cur_ring; +} + static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, @@ -1010,8 +1173,8 @@ static const struct adreno_gpu_funcs funcs = { .pm_resume = a5xx_pm_resume, .recover = a5xx_recover, .submit = a5xx_submit, - .flush = adreno_flush, - .active_ring = adreno_active_ring, + .flush = a5xx_flush, + .active_ring = a5xx_active_ring, .irq = a5xx_irq, .destroy = a5xx_destroy, #ifdef CONFIG_DEBUG_FS @@ -1047,7 +1210,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); return ERR_PTR(ret); @@ -1056,5 +1219,8 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) if (gpu->aspace) msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, a5xx_fault_handler); + /* Set up the preemption specific bits and pieces for each ringbuffer */ + a5xx_preempt_init(gpu); + return gpu; } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h index 44db48d86202..6fb8c2f9b9e4 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016 The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -35,10 +35,100 @@ struct a5xx_gpu { uint32_t gpmu_dwords; uint32_t lm_leakage; + + struct msm_ringbuffer *cur_ring; + struct msm_ringbuffer *next_ring; + + struct drm_gem_object *preempt_bo[MSM_GPU_MAX_RINGS]; + struct a5xx_preempt_record *preempt[MSM_GPU_MAX_RINGS]; + uint64_t preempt_iova[MSM_GPU_MAX_RINGS]; + + atomic_t preempt_state; + struct timer_list preempt_timer; }; #define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base) +/* + * In order to do lockless preemption we use a simple state machine to progress + * through the process. + * + * PREEMPT_NONE - no preemption in progress. Next state START. + * PREEMPT_START - The trigger is evaulating if preemption is possible. Next + * states: TRIGGERED, NONE + * PREEMPT_ABORT - An intermediate state before moving back to NONE. Next + * state: NONE. + * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. Next + * states: FAULTED, PENDING + * PREEMPT_FAULTED: A preemption timed out (never completed). This will trigger + * recovery. Next state: N/A + * PREEMPT_PENDING: Preemption complete interrupt fired - the callback is + * checking the success of the operation. Next state: FAULTED, NONE. + */ + +enum preempt_state { + PREEMPT_NONE = 0, + PREEMPT_START, + PREEMPT_ABORT, + PREEMPT_TRIGGERED, + PREEMPT_FAULTED, + PREEMPT_PENDING, +}; + +/* + * struct a5xx_preempt_record is a shared buffer between the microcode and the + * CPU to store the state for preemption. The record itself is much larger + * (64k) but most of that is used by the CP for storage. + * + * There is a preemption record assigned per ringbuffer. When the CPU triggers a + * preemption, it fills out the record with the useful information (wptr, ring + * base, etc) and the microcode uses that information to set up the CP following + * the preemption. When a ring is switched out, the CP will save the ringbuffer + * state back to the record. In this way, once the records are properly set up + * the CPU can quickly switch back and forth between ringbuffers by only + * updating a few registers (often only the wptr). + * + * These are the CPU aware registers in the record: + * @magic: Must always be 0x27C4BAFC + * @info: Type of the record - written 0 by the CPU, updated by the CP + * @data: Data field from SET_RENDER_MODE or a checkpoint. Written and used by + * the CP + * @cntl: Value of RB_CNTL written by CPU, save/restored by CP + * @rptr: Value of RB_RPTR written by CPU, save/restored by CP + * @wptr: Value of RB_WPTR written by CPU, save/restored by CP + * @rptr_addr: Value of RB_RPTR_ADDR written by CPU, save/restored by CP + * @rbase: Value of RB_BASE written by CPU, save/restored by CP + * @counter: GPU address of the storage area for the performance counters + */ +struct a5xx_preempt_record { + uint32_t magic; + uint32_t info; + uint32_t data; + uint32_t cntl; + uint32_t rptr; + uint32_t wptr; + uint64_t rptr_addr; + uint64_t rbase; + uint64_t counter; +}; + +/* Magic identifier for the preemption record */ +#define A5XX_PREEMPT_RECORD_MAGIC 0x27C4BAFCUL + +/* + * Even though the structure above is only a few bytes, we need a full 64k to + * store the entire preemption record from the CP + */ +#define A5XX_PREEMPT_RECORD_SIZE (64 * 1024) + +/* + * The preemption counter block is a storage area for the value of the + * preemption counters that are saved immediately before context switch. We + * append it on to the end of the allocation for the preemption record. + */ +#define A5XX_PREEMPT_COUNTER_SIZE (16 * 4) + + int a5xx_power_init(struct msm_gpu *gpu); void a5xx_gpmu_ucode_init(struct msm_gpu *gpu); @@ -58,4 +148,19 @@ static inline int spin_usecs(struct msm_gpu *gpu, uint32_t usecs, bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring); void a5xx_set_hwcg(struct msm_gpu *gpu, bool state); +void a5xx_preempt_init(struct msm_gpu *gpu); +void a5xx_preempt_hw_init(struct msm_gpu *gpu); +void a5xx_preempt_trigger(struct msm_gpu *gpu); +void a5xx_preempt_irq(struct msm_gpu *gpu); +void a5xx_preempt_fini(struct msm_gpu *gpu); + +/* Return true if we are in a preempt state */ +static inline bool a5xx_in_preempt(struct a5xx_gpu *a5xx_gpu) +{ + int preempt_state = atomic_read(&a5xx_gpu->preempt_state); + + return !(preempt_state == PREEMPT_NONE || + preempt_state == PREEMPT_ABORT); +} + #endif /* __A5XX_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c new file mode 100644 index 000000000000..40f4840ef98e --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -0,0 +1,305 @@ +/* Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "msm_gem.h" +#include "a5xx_gpu.h" + +/* + * Try to transition the preemption state from old to new. Return + * true on success or false if the original state wasn't 'old' + */ +static inline bool try_preempt_state(struct a5xx_gpu *a5xx_gpu, + enum preempt_state old, enum preempt_state new) +{ + enum preempt_state cur = atomic_cmpxchg(&a5xx_gpu->preempt_state, + old, new); + + return (cur == old); +} + +/* + * Force the preemption state to the specified state. This is used in cases + * where the current state is known and won't change + */ +static inline void set_preempt_state(struct a5xx_gpu *gpu, + enum preempt_state new) +{ + /* + * preempt_state may be read by other cores trying to trigger a + * preemption or in the interrupt handler so barriers are needed + * before... + */ + smp_mb__before_atomic(); + atomic_set(&gpu->preempt_state, new); + /* ... and after*/ + smp_mb__after_atomic(); +} + +/* Write the most recent wptr for the given ring into the hardware */ +static inline void update_wptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) +{ + unsigned long flags; + uint32_t wptr; + + if (!ring) + return; + + spin_lock_irqsave(&ring->lock, flags); + wptr = get_wptr(ring); + spin_unlock_irqrestore(&ring->lock, flags); + + gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr); +} + +/* Return the highest priority ringbuffer with something in it */ +static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu) +{ + unsigned long flags; + int i; + + for (i = 0; i < gpu->nr_rings; i++) { + bool empty; + struct msm_ringbuffer *ring = gpu->rb[i]; + + spin_lock_irqsave(&ring->lock, flags); + empty = (get_wptr(ring) == ring->memptrs->rptr); + spin_unlock_irqrestore(&ring->lock, flags); + + if (!empty) + return ring; + } + + return NULL; +} + +static void a5xx_preempt_timer(unsigned long data) +{ + struct a5xx_gpu *a5xx_gpu = (struct a5xx_gpu *) data; + struct msm_gpu *gpu = &a5xx_gpu->base.base; + struct drm_device *dev = gpu->dev; + struct msm_drm_private *priv = dev->dev_private; + + if (!try_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED, PREEMPT_FAULTED)) + return; + + dev_err(dev->dev, "%s: preemption timed out\n", gpu->name); + queue_work(priv->wq, &gpu->recover_work); +} + +/* Try to trigger a preemption switch */ +void a5xx_preempt_trigger(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + unsigned long flags; + struct msm_ringbuffer *ring; + + if (gpu->nr_rings == 1) + return; + + /* + * Try to start preemption by moving from NONE to START. If + * unsuccessful, a preemption is already in flight + */ + if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START)) + return; + + /* Get the next ring to preempt to */ + ring = get_next_ring(gpu); + + /* + * If no ring is populated or the highest priority ring is the current + * one do nothing except to update the wptr to the latest and greatest + */ + if (!ring || (a5xx_gpu->cur_ring == ring)) { + /* + * Its possible that while a preemption request is in progress + * from an irq context, a user context trying to submit might + * fail to update the write pointer, because it determines + * that the preempt state is not PREEMPT_NONE. + * + * Close the race by introducing an intermediate + * state PREEMPT_ABORT to let the submit path + * know that the ringbuffer is not going to change + * and can safely update the write pointer. + */ + + set_preempt_state(a5xx_gpu, PREEMPT_ABORT); + update_wptr(gpu, a5xx_gpu->cur_ring); + set_preempt_state(a5xx_gpu, PREEMPT_NONE); + return; + } + + /* Make sure the wptr doesn't update while we're in motion */ + spin_lock_irqsave(&ring->lock, flags); + a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring); + spin_unlock_irqrestore(&ring->lock, flags); + + /* Set the address of the incoming preemption record */ + gpu_write64(gpu, REG_A5XX_CP_CONTEXT_SWITCH_RESTORE_ADDR_LO, + REG_A5XX_CP_CONTEXT_SWITCH_RESTORE_ADDR_HI, + a5xx_gpu->preempt_iova[ring->id]); + + a5xx_gpu->next_ring = ring; + + /* Start a timer to catch a stuck preemption */ + mod_timer(&a5xx_gpu->preempt_timer, jiffies + msecs_to_jiffies(10000)); + + /* Set the preemption state to triggered */ + set_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED); + + /* Make sure everything is written before hitting the button */ + wmb(); + + /* And actually start the preemption */ + gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1); +} + +void a5xx_preempt_irq(struct msm_gpu *gpu) +{ + uint32_t status; + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + struct drm_device *dev = gpu->dev; + struct msm_drm_private *priv = dev->dev_private; + + if (!try_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED, PREEMPT_PENDING)) + return; + + /* Delete the preemption watchdog timer */ + del_timer(&a5xx_gpu->preempt_timer); + + /* + * The hardware should be setting CP_CONTEXT_SWITCH_CNTL to zero before + * firing the interrupt, but there is a non zero chance of a hardware + * condition or a software race that could set it again before we have a + * chance to finish. If that happens, log and go for recovery + */ + status = gpu_read(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL); + if (unlikely(status)) { + set_preempt_state(a5xx_gpu, PREEMPT_FAULTED); + dev_err(dev->dev, "%s: Preemption failed to complete\n", + gpu->name); + queue_work(priv->wq, &gpu->recover_work); + return; + } + + a5xx_gpu->cur_ring = a5xx_gpu->next_ring; + a5xx_gpu->next_ring = NULL; + + update_wptr(gpu, a5xx_gpu->cur_ring); + + set_preempt_state(a5xx_gpu, PREEMPT_NONE); +} + +void a5xx_preempt_hw_init(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + int i; + + for (i = 0; i < gpu->nr_rings; i++) { + a5xx_gpu->preempt[i]->wptr = 0; + a5xx_gpu->preempt[i]->rptr = 0; + a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova; + } + + /* Write a 0 to signal that we aren't switching pagetables */ + gpu_write64(gpu, REG_A5XX_CP_CONTEXT_SWITCH_SMMU_INFO_LO, + REG_A5XX_CP_CONTEXT_SWITCH_SMMU_INFO_HI, 0); + + /* Reset the preemption state */ + set_preempt_state(a5xx_gpu, PREEMPT_NONE); + + /* Always come up on rb 0 */ + a5xx_gpu->cur_ring = gpu->rb[0]; +} + +static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu, + struct msm_ringbuffer *ring) +{ + struct adreno_gpu *adreno_gpu = &a5xx_gpu->base; + struct msm_gpu *gpu = &adreno_gpu->base; + struct a5xx_preempt_record *ptr; + struct drm_gem_object *bo = NULL; + u64 iova = 0; + + ptr = msm_gem_kernel_new(gpu->dev, + A5XX_PREEMPT_RECORD_SIZE + A5XX_PREEMPT_COUNTER_SIZE, + MSM_BO_UNCACHED, gpu->aspace, &bo, &iova); + + if (IS_ERR(ptr)) + return PTR_ERR(ptr); + + a5xx_gpu->preempt_bo[ring->id] = bo; + a5xx_gpu->preempt_iova[ring->id] = iova; + a5xx_gpu->preempt[ring->id] = ptr; + + /* Set up the defaults on the preemption record */ + + ptr->magic = A5XX_PREEMPT_RECORD_MAGIC; + ptr->info = 0; + ptr->data = 0; + ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT; + ptr->rptr_addr = rbmemptr(ring, rptr); + ptr->counter = iova + A5XX_PREEMPT_RECORD_SIZE; + + return 0; +} + +void a5xx_preempt_fini(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + int i; + + for (i = 0; i < gpu->nr_rings; i++) { + if (!a5xx_gpu->preempt_bo[i]) + continue; + + msm_gem_put_vaddr(a5xx_gpu->preempt_bo[i]); + + if (a5xx_gpu->preempt_iova[i]) + msm_gem_put_iova(a5xx_gpu->preempt_bo[i], gpu->aspace); + + drm_gem_object_unreference(a5xx_gpu->preempt_bo[i]); + a5xx_gpu->preempt_bo[i] = NULL; + } +} + +void a5xx_preempt_init(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + int i; + + /* No preemption if we only have one ring */ + if (gpu->nr_rings <= 1) + return; + + for (i = 0; i < gpu->nr_rings; i++) { + if (preempt_init_ring(a5xx_gpu, gpu->rb[i])) { + /* + * On any failure our adventure is over. Clean up and + * set nr_rings to 1 to force preemption off + */ + a5xx_preempt_fini(gpu); + gpu->nr_rings = 1; + + return; + } + } + + setup_timer(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, + (unsigned long) a5xx_gpu); +} diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f3f81fd35452..e2ffecce59a3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -217,11 +217,6 @@ int adreno_hw_init(struct msm_gpu *gpu) return 0; } -static uint32_t get_wptr(struct msm_ringbuffer *ring) -{ - return ring->cur - ring->start; -} - /* Use this helper to read rptr, since a430 doesn't update rptr in memory */ static uint32_t get_rptr(struct adreno_gpu *adreno_gpu, struct msm_ringbuffer *ring) @@ -276,7 +271,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, case MSM_SUBMIT_CMD_BUF: OUT_PKT3(ring, adreno_is_a430(adreno_gpu) ? CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2); - OUT_RING(ring, submit->cmd[i].iova); + OUT_RING(ring, lower_32_bits(submit->cmd[i].iova)); OUT_RING(ring, submit->cmd[i].size); OUT_PKT2(ring); break; @@ -343,7 +338,7 @@ void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) * to account for the possibility that the last command fit exactly into * the ringbuffer and rb->next hasn't wrapped to zero yet */ - wptr = (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2); + wptr = get_wptr(ring); /* ensure writes to ringbuffer have hit system memory: */ mb(); @@ -361,8 +356,9 @@ bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring) return true; /* TODO maybe we need to reset GPU here to recover from hang? */ - DRM_ERROR("%s: timeout waiting to drain ringbuffer %d!\n", gpu->name, - ring->id); + DRM_ERROR("%s: timeout waiting to drain ringbuffer %d rptr/wptr = %X/%X\n", + gpu->name, ring->id, get_rptr(adreno_gpu, ring), wptr); + return false; } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 3e9a1743f476..28e3de6e5f94 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -2,7 +2,7 @@ * Copyright (C) 2013 Red Hat * Author: Rob Clark * - * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by @@ -332,6 +332,11 @@ static inline void adreno_gpu_write64(struct adreno_gpu *gpu, adreno_gpu_write(gpu, hi, upper_32_bits(data)); } +static inline uint32_t get_wptr(struct msm_ringbuffer *ring) +{ + return (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2); +} + /* * Given a register and a count, return a value to program into * REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 2821f572ecd8..9853e3e58042 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -74,7 +74,7 @@ struct msm_vblank_ctrl { spinlock_t lock; }; -#define MSM_GPU_MAX_RINGS 1 +#define MSM_GPU_MAX_RINGS 4 struct msm_drm_private { diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index ec28c99ee36e..a05aa119f22b 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -295,8 +295,7 @@ static void recover_worker(struct work_struct *work) * Replay all remaining submits starting with highest priority * ring */ - - for (i = gpu->nr_rings - 1; i >= 0; i--) { + for (i = 0; i < gpu->nr_rings; i++) { struct msm_ringbuffer *ring = gpu->rb[i]; list_for_each_entry(submit, &ring->submits, node) @@ -476,7 +475,7 @@ static void retire_submits(struct msm_gpu *gpu) WARN_ON(!mutex_is_locked(&dev->struct_mutex)); /* Retire the commits starting with highest priority */ - for (i = gpu->nr_rings - 1; i >= 0; i--) { + for (i = 0; i < gpu->nr_rings; i++) { struct msm_ringbuffer *ring = gpu->rb[i]; list_for_each_entry_safe(submit, tmp, &ring->submits, node) { diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index e39c4e392854..6ca98da35f63 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -53,6 +53,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, ring->memptrs_iova = memptrs_iova; INIT_LIST_HEAD(&ring->submits); + spin_lock_init(&ring->lock); snprintf(name, sizeof(name), "gpu-ring-%d", ring->id); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index 3749764a238e..cffce094aecb 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -40,6 +40,7 @@ struct msm_ringbuffer { struct msm_rbmemptrs *memptrs; uint64_t memptrs_iova; struct msm_fence_context *fctx; + spinlock_t lock; }; struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, -- cgit v1.2.3 From 3ceaa1411da4d0d5f3ea89e9ecd03af1b7bcd5eb Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:07:02 -0600 Subject: drm/msm: Removed unused struct_mutex_task Recent changes to locking have rendered struct_mutex_task unused. Unused since 0e08270a1f01. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 6 ------ drivers/gpu/drm/msm/msm_gem_submit.c | 2 -- 2 files changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 9853e3e58042..c46dc12dbbcc 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -154,12 +154,6 @@ struct msm_drm_private { struct shrinker shrinker; struct msm_vblank_ctrl vblank_ctrl; - - /* task holding struct_mutex.. currently only used in submit path - * to detect and reject faults from copy_from_user() for submit - * ioctl. - */ - struct task_struct *struct_mutex_task; }; struct msm_format { diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index d3551aa130fb..69868682f8f4 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -463,7 +463,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, goto out_unlock; } } - priv->struct_mutex_task = current; submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds); if (!submit) { @@ -581,7 +580,6 @@ out: out_unlock: if (ret && (out_fence_fd >= 0)) put_unused_fd(out_fence_fd); - priv->struct_mutex_task = NULL; mutex_unlock(&dev->struct_mutex); return ret; } -- cgit v1.2.3 From 78b8e5b847b4c80b731d2ad8a9ce1a377ea68ef2 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 20 Oct 2017 11:07:03 -0600 Subject: drm/msm: dump a rd GPUADDR header for all buffers in the command Currently the rd dump avoids any buffers marked as WRITE under the assumption that the contents are not interesting. While it is true that the contents are uninteresting we should still print the iova and size for all buffers so that any listening replay tools can correctly construct the submission. Print the header for all buffers but only dump the contents for buffers marked as READ. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_rd.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 0366b8092f97..4c858d860c79 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -268,10 +268,6 @@ static void snapshot_buf(struct msm_rd_state *rd, struct msm_gem_object *obj = submit->bos[idx].obj; const char *buf; - buf = msm_gem_get_vaddr(&obj->base); - if (IS_ERR(buf)) - return; - if (iova) { buf += iova - submit->bos[idx].iova; } else { @@ -279,8 +275,21 @@ static void snapshot_buf(struct msm_rd_state *rd, size = obj->base.size; } + /* + * Always write the GPUADDR header so can get a complete list of all the + * buffers in the cmd + */ rd_write_section(rd, RD_GPUADDR, (uint32_t[3]){ iova, size, iova >> 32 }, 12); + + /* But only dump the contents of buffers marked READ */ + if (!(submit->bos[idx].flags & MSM_SUBMIT_BO_READ)) + return; + + buf = msm_gem_get_vaddr(&obj->base); + if (IS_ERR(buf)) + return; + rd_write_section(rd, RD_BUFFER_CONTENTS, buf, size); msm_gem_put_vaddr(&obj->base); @@ -309,17 +318,8 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4)); - if (rd_full) { - for (i = 0; i < submit->nr_bos; i++) { - /* buffers that are written to probably don't start out - * with anything interesting: - */ - if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE) - continue; - - snapshot_buf(rd, submit, i, 0, 0); - } - } + for (i = 0; rd_full && i < submit->nr_bos; i++) + snapshot_buf(rd, submit, i, 0, 0); for (i = 0; i < submit->nr_cmds; i++) { uint64_t iova = submit->cmd[i].iova; -- cgit v1.2.3 From 18bb8a6c899d9e503a86198220f2a48814870bef Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 13 Sep 2017 10:17:18 -0400 Subject: drm/msm: show task cmdline in gpu recovery messages Now that freedreno gallium driver defaults to using submit_queue task (render reordering), just showing task->comm is not so useful (ie. it is always "flush_queue:0"), so also dump the cmdline. This should also be more useful for piglit/shader_runner. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 55 +++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index a05aa119f22b..8481014192d1 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -20,6 +20,8 @@ #include "msm_mmu.h" #include "msm_fence.h" +#include + /* * Power Management: @@ -235,6 +237,20 @@ static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring, } } +static struct msm_gem_submit * +find_submit(struct msm_ringbuffer *ring, uint32_t fence) +{ + struct msm_gem_submit *submit; + + WARN_ON(!mutex_is_locked(&ring->gpu->dev->struct_mutex)); + + list_for_each_entry(submit, &ring->submits, node) + if (submit->seqno == fence) + return submit; + + return NULL; +} + static void retire_submits(struct msm_gpu *gpu); static void recover_worker(struct work_struct *work) @@ -268,19 +284,34 @@ static void recover_worker(struct work_struct *work) dev_err(dev->dev, "%s: hangcheck recover!\n", gpu->name); fence = cur_ring->memptrs->fence + 1; - list_for_each_entry(submit, &cur_ring->submits, node) { - if (submit->seqno == fence) { - struct task_struct *task; - - rcu_read_lock(); - task = pid_task(submit->pid, PIDTYPE_PID); - if (task) { - dev_err(dev->dev, "%s: offending task: %s\n", - gpu->name, task->comm); - } - rcu_read_unlock(); - break; + submit = find_submit(cur_ring, fence); + if (submit) { + struct task_struct *task; + + rcu_read_lock(); + task = pid_task(submit->pid, PIDTYPE_PID); + if (task) { + char *cmd; + + /* + * So slightly annoying, in other paths like + * mmap'ing gem buffers, mmap_sem is acquired + * before struct_mutex, which means we can't + * hold struct_mutex across the call to + * get_cmdline(). But submits are retired + * from the same in-order workqueue, so we can + * safely drop the lock here without worrying + * about the submit going away. + */ + mutex_unlock(&dev->struct_mutex); + cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); + mutex_lock(&dev->struct_mutex); + + dev_err(dev->dev, "%s: offending task: %s (%s)\n", + gpu->name, task->comm, cmd); } + rcu_read_unlock(); + } if (msm_gpu_active(gpu)) { -- cgit v1.2.3 From fad33f4b1073a423a9ecd2a335de05e7a3ec1f37 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 15 Sep 2017 08:38:20 -0400 Subject: drm/msm: add special _get_vaddr_active() for cmdstream dumps Prep work for adding a debugfs file that dumps just submits which trigger hangs/faults. In this case the bo may already be in the MADV_DONTNEED state, but will be still on the active list (since the submit hasn't completed yet). So the normal check that the bo is in the WILLNEED state does not apply. (But of course the bo should definitely not be in the PURGED state!) Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 1 + drivers/gpu/drm/msm/msm_gem.c | 22 ++++++++++++++++++++-- drivers/gpu/drm/msm/msm_rd.c | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index c46dc12dbbcc..666fce66f9dd 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -213,6 +213,7 @@ struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev, int msm_gem_prime_pin(struct drm_gem_object *obj); void msm_gem_prime_unpin(struct drm_gem_object *obj); void *msm_gem_get_vaddr(struct drm_gem_object *obj); +void *msm_gem_get_vaddr_active(struct drm_gem_object *obj); void msm_gem_put_vaddr(struct drm_gem_object *obj); int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv); int msm_gem_sync_object(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index a0ab6040c484..0776160a6924 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -470,14 +470,16 @@ fail: return ret; } -void *msm_gem_get_vaddr(struct drm_gem_object *obj) +static void *get_vaddr(struct drm_gem_object *obj, unsigned madv) { struct msm_gem_object *msm_obj = to_msm_bo(obj); int ret = 0; mutex_lock(&msm_obj->lock); - if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) { + if (WARN_ON(msm_obj->madv > madv)) { + dev_err(obj->dev->dev, "Invalid madv state: %u vs %u\n", + msm_obj->madv, madv); mutex_unlock(&msm_obj->lock); return ERR_PTR(-EBUSY); } @@ -513,6 +515,22 @@ fail: return ERR_PTR(ret); } +void *msm_gem_get_vaddr(struct drm_gem_object *obj) +{ + return get_vaddr(obj, MSM_MADV_WILLNEED); +} + +/* + * Don't use this! It is for the very special case of dumping + * submits from GPU hangs or faults, were the bo may already + * be MSM_MADV_DONTNEED, but we know the buffer is still on the + * active list. + */ +void *msm_gem_get_vaddr_active(struct drm_gem_object *obj) +{ + return get_vaddr(obj, __MSM_MADV_PURGED); +} + void msm_gem_put_vaddr(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 4c858d860c79..47c0c78f2076 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -286,7 +286,7 @@ static void snapshot_buf(struct msm_rd_state *rd, if (!(submit->bos[idx].flags & MSM_SUBMIT_BO_READ)) return; - buf = msm_gem_get_vaddr(&obj->base); + buf = msm_gem_get_vaddr_active(&obj->base); if (IS_ERR(buf)) return; -- cgit v1.2.3 From 2165e2b9cba277a5088c2e771af477e95dcc37bf Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 15 Sep 2017 09:04:52 -0400 Subject: drm/msm: split rd debugfs file Split into two instances, the existing $debugfs/rd which continues to dump all submits, and $debugfs/hangrd which will be used to dump just submits that cause gpu hangs (and eventually faults, but that will require some iommu framework enhancements). Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 5 ++- drivers/gpu/drm/msm/msm_gpu.c | 2 +- drivers/gpu/drm/msm/msm_rd.c | 101 +++++++++++++++++++++++++++++++----------- 3 files changed, 79 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 666fce66f9dd..b01bd7fa9c2b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -108,7 +108,8 @@ struct msm_drm_private { struct drm_fb_helper *fbdev; - struct msm_rd_state *rd; + struct msm_rd_state *rd; /* debugfs to dump all submits */ + struct msm_rd_state *hangrd; /* debugfs to dump hanging submits */ struct msm_perf_state *perf; /* list of GEM objects: */ @@ -298,7 +299,7 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m); int msm_debugfs_late_init(struct drm_device *dev); int msm_rd_debugfs_init(struct drm_minor *minor); void msm_rd_debugfs_cleanup(struct msm_drm_private *priv); -void msm_rd_dump_submit(struct msm_gem_submit *submit); +void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit); int msm_perf_debugfs_init(struct drm_minor *minor); void msm_perf_debugfs_cleanup(struct msm_drm_private *priv); #else diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 8481014192d1..7fc6f68d6aec 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -557,7 +557,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, list_add_tail(&submit->node, &ring->submits); - msm_rd_dump_submit(submit); + msm_rd_dump_submit(priv->rd, submit); update_sw_cntrs(gpu); diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 47c0c78f2076..0fac6ea5f906 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -19,11 +19,17 @@ * * tail -f /sys/kernel/debug/dri//rd > logfile.rd * - * To log the cmdstream in a format that is understood by freedreno/cffdump + * to log the cmdstream in a format that is understood by freedreno/cffdump * utility. By comparing the last successfully completed fence #, to the * cmdstream for the next fence, you can narrow down which process and submit * caused the gpu crash/lockup. * + * Additionally: + * + * tail -f /sys/kernel/debug/dri//hangrd > logfile.rd + * + * will capture just the cmdstream from submits which triggered a GPU hang. + * * This bypasses drm_debugfs_create_files() mainly because we need to use * our own fops for a bit more control. In particular, we don't want to * do anything if userspace doesn't have the debugfs file open. @@ -212,53 +218,89 @@ static const struct file_operations rd_debugfs_fops = { .release = rd_release, }; -int msm_rd_debugfs_init(struct drm_minor *minor) + +static void rd_cleanup(struct msm_rd_state *rd) +{ + if (!rd) + return; + + mutex_destroy(&rd->read_lock); + kfree(rd); +} + +static struct msm_rd_state *rd_init(struct drm_minor *minor, const char *name) { - struct msm_drm_private *priv = minor->dev->dev_private; struct msm_rd_state *rd; struct dentry *ent; - - /* only create on first minor: */ - if (priv->rd) - return 0; + int ret = 0; rd = kzalloc(sizeof(*rd), GFP_KERNEL); if (!rd) - return -ENOMEM; + return ERR_PTR(-ENOMEM); rd->dev = minor->dev; rd->fifo.buf = rd->buf; mutex_init(&rd->read_lock); - priv->rd = rd; init_waitqueue_head(&rd->fifo_event); - ent = debugfs_create_file("rd", S_IFREG | S_IRUGO, + ent = debugfs_create_file(name, S_IFREG | S_IRUGO, minor->debugfs_root, rd, &rd_debugfs_fops); if (!ent) { - DRM_ERROR("Cannot create /sys/kernel/debug/dri/%pd/rd\n", - minor->debugfs_root); + DRM_ERROR("Cannot create /sys/kernel/debug/dri/%pd/%s\n", + minor->debugfs_root, name); + ret = -ENOMEM; goto fail; } + return rd; + +fail: + rd_cleanup(rd); + return ERR_PTR(ret); +} + +int msm_rd_debugfs_init(struct drm_minor *minor) +{ + struct msm_drm_private *priv = minor->dev->dev_private; + struct msm_rd_state *rd; + int ret; + + /* only create on first minor: */ + if (priv->rd) + return 0; + + rd = rd_init(minor, "rd"); + if (IS_ERR(rd)) { + ret = PTR_ERR(rd); + goto fail; + } + + priv->rd = rd; + + rd = rd_init(minor, "hangrd"); + if (IS_ERR(rd)) { + ret = PTR_ERR(rd); + goto fail; + } + + priv->hangrd = rd; + return 0; fail: msm_rd_debugfs_cleanup(priv); - return -1; + return ret; } void msm_rd_debugfs_cleanup(struct msm_drm_private *priv) { - struct msm_rd_state *rd = priv->rd; - - if (!rd) - return; - + rd_cleanup(priv->rd); priv->rd = NULL; - mutex_destroy(&rd->read_lock); - kfree(rd); + + rd_cleanup(priv->hangrd); + priv->hangrd = NULL; } static void snapshot_buf(struct msm_rd_state *rd, @@ -296,11 +338,10 @@ static void snapshot_buf(struct msm_rd_state *rd, } /* called under struct_mutex */ -void msm_rd_dump_submit(struct msm_gem_submit *submit) +void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit) { struct drm_device *dev = submit->dev; - struct msm_drm_private *priv = dev->dev_private; - struct msm_rd_state *rd = priv->rd; + struct task_struct *task; char msg[128]; int i, n; @@ -312,9 +353,17 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) */ WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - n = snprintf(msg, sizeof(msg), "%.*s/%d: fence=%u", - TASK_COMM_LEN, current->comm, task_pid_nr(current), - submit->fence->seqno); + rcu_read_lock(); + task = pid_task(submit->pid, PIDTYPE_PID); + if (task) { + n = snprintf(msg, sizeof(msg), "%.*s/%d: fence=%u", + TASK_COMM_LEN, task->comm, + pid_nr(submit->pid), submit->seqno); + } else { + n = snprintf(msg, sizeof(msg), "???/%d: fence=%u", + pid_nr(submit->pid), submit->seqno); + } + rcu_read_unlock(); rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4)); -- cgit v1.2.3 From 998b9a588314faa334dd0f94007e1c685bf664dd Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 15 Sep 2017 10:46:45 -0400 Subject: drm/msm/rd: allow adding addition msg to top of dump For faults or hangs, it is nice to be able to include a bit more information. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 3 ++- drivers/gpu/drm/msm/msm_gpu.c | 2 +- drivers/gpu/drm/msm/msm_rd.c | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index b01bd7fa9c2b..a007bbf4d94d 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -299,7 +299,8 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m); int msm_debugfs_late_init(struct drm_device *dev); int msm_rd_debugfs_init(struct drm_minor *minor); void msm_rd_debugfs_cleanup(struct msm_drm_private *priv); -void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit); +void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, + const char *fmt, ...); int msm_perf_debugfs_init(struct drm_minor *minor); void msm_perf_debugfs_cleanup(struct msm_drm_private *priv); #else diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 7fc6f68d6aec..4dd0c917e30c 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -557,7 +557,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, list_add_tail(&submit->node, &ring->submits); - msm_rd_dump_submit(priv->rd, submit); + msm_rd_dump_submit(priv->rd, submit, NULL); update_sw_cntrs(gpu); diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 0fac6ea5f906..96d678b582d9 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -338,11 +338,12 @@ static void snapshot_buf(struct msm_rd_state *rd, } /* called under struct_mutex */ -void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit) +void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, + const char *fmt, ...) { struct drm_device *dev = submit->dev; struct task_struct *task; - char msg[128]; + char msg[256]; int i, n; if (!rd->open) @@ -353,6 +354,16 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit) */ WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + if (fmt) { + va_list args; + + va_start(args, fmt); + n = vsnprintf(msg, sizeof(msg), fmt, args); + va_end(args); + + rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4)); + } + rcu_read_lock(); task = pid_task(submit->pid, PIDTYPE_PID); if (task) { -- cgit v1.2.3 From 544a32dbf05888ec012868db2e813233078bbdfb Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 15 Sep 2017 10:58:13 -0400 Subject: drm/msm: preserve IOVAs in submit's bo table We need this if we want to dump the submit after cleanup (ie. from hang or fault). But in the backoff/unpin case we want to clear them. So add a flag so we can skip clearing the IOVAs in at cleanup. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem_submit.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 69868682f8f4..b8dc8f96caf2 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -161,7 +161,8 @@ out: return ret; } -static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i) +static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, + int i, bool backoff) { struct msm_gem_object *msm_obj = submit->bos[i].obj; @@ -171,7 +172,7 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i) if (submit->bos[i].flags & BO_LOCKED) ww_mutex_unlock(&msm_obj->resv->lock); - if (!(submit->bos[i].flags & BO_VALID)) + if (backoff && !(submit->bos[i].flags & BO_VALID)) submit->bos[i].iova = 0; submit->bos[i].flags &= ~(BO_LOCKED | BO_PINNED); @@ -206,10 +207,10 @@ retry: fail: for (; i >= 0; i--) - submit_unlock_unpin_bo(submit, i); + submit_unlock_unpin_bo(submit, i, true); if (slow_locked > 0) - submit_unlock_unpin_bo(submit, slow_locked); + submit_unlock_unpin_bo(submit, slow_locked, true); if (ret == -EDEADLK) { struct msm_gem_object *msm_obj = submit->bos[contended].obj; @@ -393,7 +394,7 @@ static void submit_cleanup(struct msm_gem_submit *submit) for (i = 0; i < submit->nr_bos; i++) { struct msm_gem_object *msm_obj = submit->bos[i].obj; - submit_unlock_unpin_bo(submit, i); + submit_unlock_unpin_bo(submit, i, false); list_del_init(&msm_obj->submit_entry); drm_gem_object_unreference(&msm_obj->base); } -- cgit v1.2.3 From 96169f4e755a507a5c0b4fc12882d1d42abd5ab5 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 15 Sep 2017 11:04:44 -0400 Subject: drm/msm: dump submits which triggered gpu hang Note we need to move update_fences() to after msm_rd_dump_submit(), otherwise the bo's referenced by the submit may no longer be valid. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 47 +++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 4dd0c917e30c..06bf2cc9afa9 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -257,34 +257,16 @@ static void recover_worker(struct work_struct *work) { struct msm_gpu *gpu = container_of(work, struct msm_gpu, recover_work); struct drm_device *dev = gpu->dev; + struct msm_drm_private *priv = dev->dev_private; struct msm_gem_submit *submit; struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu); - uint64_t fence; int i; - /* Update all the rings with the latest and greatest fence */ - for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) { - struct msm_ringbuffer *ring = gpu->rb[i]; - - fence = ring->memptrs->fence; - - /* - * For the current (faulting?) ring/submit advance the fence by - * one more to clear the faulting submit - */ - if (ring == cur_ring) - fence = fence + 1; - - update_fences(gpu, ring, fence); - } - mutex_lock(&dev->struct_mutex); - dev_err(dev->dev, "%s: hangcheck recover!\n", gpu->name); - fence = cur_ring->memptrs->fence + 1; - submit = find_submit(cur_ring, fence); + submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1); if (submit) { struct task_struct *task; @@ -309,9 +291,34 @@ static void recover_worker(struct work_struct *work) dev_err(dev->dev, "%s: offending task: %s (%s)\n", gpu->name, task->comm, cmd); + + msm_rd_dump_submit(priv->hangrd, submit, + "offending task: %s (%s)", task->comm, cmd); + } else { + msm_rd_dump_submit(priv->hangrd, submit, NULL); } rcu_read_unlock(); + } + + + /* + * Update all the rings with the latest and greatest fence.. this + * needs to happen after msm_rd_dump_submit() to ensure that the + * bo's referenced by the offending submit are still around. + */ + for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) { + struct msm_ringbuffer *ring = gpu->rb[i]; + + uint32_t fence = ring->memptrs->fence; + /* + * For the current (faulting?) ring/submit advance the fence by + * one more to clear the faulting submit + */ + if (ring == cur_ring) + fence++; + + update_fences(gpu, ring, fence); } if (msm_gpu_active(gpu)) { -- cgit v1.2.3 From a055cf3a972e6a01933f9dfde564f5de944adde0 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 24 Oct 2017 10:19:42 -0400 Subject: drm/msm/mdp5: ignore planes that are not visible Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 436bf628ef9c..1a4aedb16b54 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -114,6 +114,8 @@ static u32 crtc_flush_all(struct drm_crtc *crtc) return 0; drm_atomic_crtc_for_each_plane(plane, crtc) { + if (!plane->state->visible) + continue; flush_mask |= mdp5_plane_get_flush(plane); } @@ -242,6 +244,9 @@ static void blend_setup(struct drm_crtc *crtc) drm_atomic_crtc_for_each_plane(plane, crtc) { enum mdp5_pipe right_pipe; + if (!plane->state->visible) + continue; + pstate = to_mdp5_plane_state(plane->state); pstates[pstate->stage] = pstate; stage[pstate->stage][PIPE_LEFT] = mdp5_plane_pipe(plane); @@ -586,6 +591,9 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, DBG("%s: check", crtc->name); drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { + if (!pstate->visible) + continue; + pstates[cnt].plane = plane; pstates[cnt].state = to_mdp5_plane_state(pstate); -- cgit v1.2.3 From 3c352b66905b29689bbf1c8e3722c26de65f086d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 20 Oct 2017 08:17:43 -0400 Subject: drm/msm/mdp5: don't use autosuspend It's only likely to paper over bugs. Unlike the gpu, where we want to keep things alive a bit longer in expectation of the next frame's submit, when the display is shut down we can power off immediately. Signed-off-by: Rob Clark Acked-by: Archit Taneja --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 6 +++--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 10 +++++----- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c index 60790df91bfa..1abc7f5c345c 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c @@ -224,7 +224,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, MDP5_SPLIT_DPL_LOWER_SMART_PANEL); mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); return 0; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 1a4aedb16b54..5ad722c83b3f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -434,7 +434,7 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done); mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); mdp5_crtc->enabled = false; } @@ -831,7 +831,7 @@ set_cursor: crtc_flush(crtc, flush_mask); end: - pm_runtime_put_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); if (old_bo) { drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo); /* enable vblank to complete cursor work: */ @@ -877,7 +877,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) crtc_flush(crtc, flush_mask); - pm_runtime_put_autosuspend(&mdp5_kms->pdev->dev); + pm_runtime_put_sync(&mdp5_kms->pdev->dev); return 0; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index 5b851380d3f2..36ad3cbe5f79 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c @@ -384,7 +384,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, mdp5_ctl_pair(mdp5_encoder->ctl, mdp5_slave_enc->ctl, true); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); return 0; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index bb5deb00c899..280e368bc9bb 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -54,7 +54,7 @@ void mdp5_irq_preinstall(struct msm_kms *kms) pm_runtime_get_sync(dev); mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff); mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); } int mdp5_irq_postinstall(struct msm_kms *kms) @@ -72,7 +72,7 @@ int mdp5_irq_postinstall(struct msm_kms *kms) pm_runtime_get_sync(dev); mdp_irq_register(mdp_kms, error_handler); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); return 0; } @@ -84,7 +84,7 @@ void mdp5_irq_uninstall(struct msm_kms *kms) pm_runtime_get_sync(dev); mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); } irqreturn_t mdp5_irq(struct msm_kms *kms) @@ -119,7 +119,7 @@ int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) pm_runtime_get_sync(dev); mdp_update_vblank_mask(to_mdp_kms(kms), mdp5_crtc_vblank(crtc), true); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); return 0; } @@ -132,5 +132,5 @@ void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) pm_runtime_get_sync(dev); mdp_update_vblank_mask(to_mdp_kms(kms), mdp5_crtc_vblank(crtc), false); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 494b2936502d..3e9bba4d6624 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -125,7 +125,7 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s if (mdp5_kms->smp) mdp5_smp_complete_commit(mdp5_kms->smp, &mdp5_kms->state->smp); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); } static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms, @@ -496,7 +496,7 @@ static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms, pm_runtime_get_sync(dev); version = mdp5_read(mdp5_kms, REG_MDP5_HW_VERSION); - pm_runtime_put_autosuspend(dev); + pm_runtime_put_sync(dev); *major = FIELD(version, MDP5_HW_VERSION_MAJOR); *minor = FIELD(version, MDP5_HW_VERSION_MINOR); @@ -683,7 +683,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) aspace = NULL;; } - pm_runtime_put_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); ret = modeset_init(mdp5_kms); if (ret) { -- cgit v1.2.3 From 9d9ea7a9c6005a42e9837da96ff138a6ddcd593c Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 19 Oct 2017 16:00:31 -0400 Subject: drm/msm/mdp5: restore cursor state when enabling crtc Since we enabled runtime PM, we cannot count on cursor registers to retain their values. This can result in situations where we think the cursor is enabled when we enable the CRTC but it is trying to scan out null (and the rest of cursor position/size is lost), resulting in faults and generally angering the hw when coming out of DPMS with a cursor enabled. stable backport note: reverting 774e39ee3572 is also a suitable fix Fixes: 774e39ee3572 drm/msm/mdp5: Set up runtime PM for MDSS Signed-off-by: Rob Clark Reviewed-by: Archit Taneja --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 100 +++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 5ad722c83b3f..95ba9edebf04 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -61,12 +61,15 @@ struct mdp5_crtc { /* current cursor being scanned out: */ struct drm_gem_object *scanout_bo; + uint64_t iova; uint32_t width, height; uint32_t x, y; } cursor; }; #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base) +static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc); + static struct mdp5_kms *get_kms(struct drm_crtc *crtc) { struct msm_drm_private *priv = crtc->dev->dev_private; @@ -454,6 +457,21 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, pm_runtime_get_sync(dev); + /* Restore cursor state, as it might have been lost with suspend: */ + if (mdp5_crtc->cursor.iova) { + unsigned long flags; + + spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); + mdp5_crtc_restore_cursor(crtc); + spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); + + mdp5_ctl_set_cursor(mdp5_cstate->ctl, + &mdp5_cstate->pipeline, 0, true); + } else { + mdp5_ctl_set_cursor(mdp5_cstate->ctl, + &mdp5_cstate->pipeline, 0, false); + } + /* Restore vblank irq handling after power is enabled */ drm_crtc_vblank_on(crtc); @@ -737,6 +755,50 @@ static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h) mdp5_crtc->cursor.y); } +static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc) +{ + struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + struct mdp5_kms *mdp5_kms = get_kms(crtc); + const enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL; + uint32_t blendcfg, stride; + uint32_t x, y, width, height; + uint32_t roi_w, roi_h; + int lm; + + assert_spin_locked(&mdp5_crtc->cursor.lock); + + lm = mdp5_cstate->pipeline.mixer->lm; + + x = mdp5_crtc->cursor.x; + y = mdp5_crtc->cursor.y; + width = mdp5_crtc->cursor.width; + height = mdp5_crtc->cursor.height; + + stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0); + + get_roi(crtc, &roi_w, &roi_h); + + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), + MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_IMG_SIZE(lm), + MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) | + MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width)); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), + MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) | + MDP5_LM_CURSOR_SIZE_ROI_W(roi_w)); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(lm), + MDP5_LM_CURSOR_START_XY_Y_START(y) | + MDP5_LM_CURSOR_START_XY_X_START(x)); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), + mdp5_crtc->cursor.iova); + + blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN; + blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha); + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg); +} + static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file, uint32_t handle, uint32_t width, uint32_t height) @@ -749,13 +811,9 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, struct platform_device *pdev = mdp5_kms->pdev; struct msm_kms *kms = &mdp5_kms->base.base; struct drm_gem_object *cursor_bo, *old_bo = NULL; - uint32_t blendcfg, stride; - uint64_t cursor_addr; struct mdp5_ctl *ctl; - int ret, lm; - enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL; + int ret; uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); - uint32_t roi_w, roi_h; bool cursor_enable = true; unsigned long flags; @@ -775,6 +833,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, if (!handle) { DBG("Cursor off"); cursor_enable = false; + mdp5_crtc->cursor.iova = 0; pm_runtime_get_sync(&pdev->dev); goto set_cursor; } @@ -783,13 +842,11 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, if (!cursor_bo) return -ENOENT; - ret = msm_gem_get_iova(cursor_bo, kms->aspace, &cursor_addr); + ret = msm_gem_get_iova(cursor_bo, kms->aspace, + &mdp5_crtc->cursor.iova); if (ret) return -EINVAL; - lm = mdp5_cstate->pipeline.mixer->lm; - stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0); - pm_runtime_get_sync(&pdev->dev); spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); @@ -799,22 +856,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, mdp5_crtc->cursor.width = width; mdp5_crtc->cursor.height = height; - get_roi(crtc, &roi_w, &roi_h); - - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), - MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_IMG_SIZE(lm), - MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) | - MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width)); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), - MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) | - MDP5_LM_CURSOR_SIZE_ROI_W(roi_w)); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr); - - blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN; - blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg); + mdp5_crtc_restore_cursor(crtc); spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); @@ -845,7 +887,6 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) struct mdp5_kms *mdp5_kms = get_kms(crtc); struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); - uint32_t lm = mdp5_cstate->pipeline.mixer->lm; uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); uint32_t roi_w; uint32_t roi_h; @@ -867,12 +908,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) pm_runtime_get_sync(&mdp5_kms->pdev->dev); spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), - MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) | - MDP5_LM_CURSOR_SIZE_ROI_W(roi_w)); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(lm), - MDP5_LM_CURSOR_START_XY_Y_START(y) | - MDP5_LM_CURSOR_START_XY_X_START(x)); + mdp5_crtc_restore_cursor(crtc); spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); crtc_flush(crtc, flush_mask); -- cgit v1.2.3 From 1f920175fff934b2bef0168cb70cf82b690f2d96 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 25 Oct 2017 12:30:51 -0400 Subject: drm/msm/atomic: switch to drm_atomic_helper_check Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_atomic.c | 29 ----------------------------- drivers/gpu/drm/msm/msm_drv.c | 2 +- drivers/gpu/drm/msm/msm_drv.h | 2 -- 3 files changed, 1 insertion(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 025d454163b0..ae07dd12b1c3 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -146,35 +146,6 @@ static void commit_worker(struct work_struct *work) complete_commit(container_of(work, struct msm_commit, work), true); } -/* - * this func is identical to the drm_atomic_helper_check, but we keep this - * because we might eventually need to have a more finegrained check - * sequence without using the atomic helpers. - * - * In the past, we first called drm_atomic_helper_check_planes, and then - * drm_atomic_helper_check_modeset. We needed this because the MDP5 plane's - * ->atomic_check could update ->mode_changed for pixel format changes. - * This, however isn't needed now because if there is a pixel format change, - * we just assign a new hwpipe for it with a new SMP allocation. We might - * eventually hit a condition where we would need to do a full modeset if - * we run out of planes. There, we'd probably need to set mode_changed. - */ -int msm_atomic_check(struct drm_device *dev, - struct drm_atomic_state *state) -{ - int ret; - - ret = drm_atomic_helper_check_modeset(dev, state); - if (ret) - return ret; - - ret = drm_atomic_helper_check_planes(dev, state); - if (ret) - return ret; - - return ret; -} - /** * drm_atomic_helper_commit - commit validated state object * @dev: DRM device diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index bfb8c7cf800a..0a3ea3034e39 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -47,7 +47,7 @@ static void msm_fb_output_poll_changed(struct drm_device *dev) static const struct drm_mode_config_funcs mode_config_funcs = { .fb_create = msm_framebuffer_create, .output_poll_changed = msm_fb_output_poll_changed, - .atomic_check = msm_atomic_check, + .atomic_check = drm_atomic_helper_check, .atomic_commit = msm_atomic_commit, .atomic_state_alloc = msm_atomic_state_alloc, .atomic_state_clear = msm_atomic_state_clear, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index a007bbf4d94d..c646843d8822 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -161,8 +161,6 @@ struct msm_format { uint32_t pixel_format; }; -int msm_atomic_check(struct drm_device *dev, - struct drm_atomic_state *state); int msm_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock); struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev); -- cgit v1.2.3 From 224a4c970987fc685bc04854c5fb2d94ef46b2ee Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 30 Jun 2017 15:03:20 -0300 Subject: drm/msm: update cursors asynchronously through atomic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support to async updates of cursors by using the new atomic interface for that. Basically what this commit does is do what mdp5_update_cursor_plane_legacy() did but through atomic. v5: call drm_atomic_helper_async_check() from the check hook v4: add missing atomic async commit call to msm_atomic_commit(Archit Taneja) v3: move size checks back to drivers (Ville Syrjälä) v2: move fb setting to core and use new state (Eric Anholt) Cc: Rob Clark Cc: Archit Taneja Signed-off-by: Gustavo Padovan Tested-by: Archit Taneja (v4) [added comment about not hitting async update path if hwpipes are re-assigned or global state is touched] Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 151 +++++++++++++----------------- drivers/gpu/drm/msm/msm_atomic.c | 12 +++ 2 files changed, 75 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 4b22ac3413a1..83200bbf91f8 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -31,15 +31,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_rect *src, struct drm_rect *dest); -static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h, - struct drm_modeset_acquire_ctx *ctx); - static struct mdp5_kms *get_kms(struct drm_plane *plane) { struct msm_drm_private *priv = plane->dev->dev_private; @@ -255,7 +246,7 @@ static const struct drm_plane_funcs mdp5_plane_funcs = { }; static const struct drm_plane_funcs mdp5_cursor_plane_funcs = { - .update_plane = mdp5_update_cursor_plane_legacy, + .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = mdp5_plane_destroy, .atomic_set_property = mdp5_plane_atomic_set_property, @@ -487,11 +478,73 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane, } } +static int mdp5_plane_atomic_async_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state); + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_existing_crtc_state(state->state, + state->crtc); + if (WARN_ON(!crtc_state)) + return -EINVAL; + + if (!crtc_state->active) + return -EINVAL; + + mdp5_state = to_mdp5_plane_state(state); + + /* don't use fast path if we don't have a hwpipe allocated yet */ + if (!mdp5_state->hwpipe) + return -EINVAL; + + /* only allow changing of position(crtc x/y or src x/y) in fast path */ + if (plane->state->crtc != state->crtc || + plane->state->src_w != state->src_w || + plane->state->src_h != state->src_h || + plane->state->crtc_w != state->crtc_w || + plane->state->crtc_h != state->crtc_h || + !plane->state->fb || + plane->state->fb != state->fb) + return -EINVAL; + + return 0; +} + +static void mdp5_plane_atomic_async_update(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ + plane->state->src_x = new_state->src_x; + plane->state->src_y = new_state->src_y; + plane->state->crtc_x = new_state->crtc_x; + plane->state->crtc_y = new_state->crtc_y; + + if (plane_enabled(new_state)) { + struct mdp5_ctl *ctl; + struct mdp5_pipeline *pipeline = + mdp5_crtc_get_pipeline(plane->crtc); + int ret; + + ret = mdp5_plane_mode_set(plane, new_state->crtc, new_state->fb, + &new_state->src, &new_state->dst); + WARN_ON(ret < 0); + + ctl = mdp5_crtc_get_ctl(new_state->crtc); + + mdp5_ctl_commit(ctl, pipeline, mdp5_plane_get_flush(plane)); + } + + *to_mdp5_plane_state(plane->state) = + *to_mdp5_plane_state(new_state); +} + static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = { .prepare_fb = mdp5_plane_prepare_fb, .cleanup_fb = mdp5_plane_cleanup_fb, .atomic_check = mdp5_plane_atomic_check, .atomic_update = mdp5_plane_atomic_update, + .atomic_async_check = mdp5_plane_atomic_async_check, + .atomic_async_update = mdp5_plane_atomic_async_update, }; static void set_scanout_locked(struct mdp5_kms *mdp5_kms, @@ -996,84 +1049,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, return ret; } -static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane, - struct drm_crtc *crtc, struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h, - struct drm_modeset_acquire_ctx *ctx) -{ - struct drm_plane_state *plane_state, *new_plane_state; - struct mdp5_plane_state *mdp5_pstate; - struct drm_crtc_state *crtc_state = crtc->state; - int ret; - - if (!crtc_state->active || drm_atomic_crtc_needs_modeset(crtc_state)) - goto slow; - - plane_state = plane->state; - mdp5_pstate = to_mdp5_plane_state(plane_state); - - /* don't use fast path if we don't have a hwpipe allocated yet */ - if (!mdp5_pstate->hwpipe) - goto slow; - - /* only allow changing of position(crtc x/y or src x/y) in fast path */ - if (plane_state->crtc != crtc || - plane_state->src_w != src_w || - plane_state->src_h != src_h || - plane_state->crtc_w != crtc_w || - plane_state->crtc_h != crtc_h || - !plane_state->fb || - plane_state->fb != fb) - goto slow; - - new_plane_state = mdp5_plane_duplicate_state(plane); - if (!new_plane_state) - return -ENOMEM; - - new_plane_state->src_x = src_x; - new_plane_state->src_y = src_y; - new_plane_state->src_w = src_w; - new_plane_state->src_h = src_h; - new_plane_state->crtc_x = crtc_x; - new_plane_state->crtc_y = crtc_y; - new_plane_state->crtc_w = crtc_w; - new_plane_state->crtc_h = crtc_h; - - ret = mdp5_plane_atomic_check_with_state(crtc_state, new_plane_state); - if (ret) - goto slow_free; - - if (new_plane_state->visible) { - struct mdp5_ctl *ctl; - struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(crtc); - - ret = mdp5_plane_mode_set(plane, crtc, fb, - &new_plane_state->src, - &new_plane_state->dst); - WARN_ON(ret < 0); - - ctl = mdp5_crtc_get_ctl(crtc); - - mdp5_ctl_commit(ctl, pipeline, mdp5_plane_get_flush(plane)); - } - - *to_mdp5_plane_state(plane_state) = - *to_mdp5_plane_state(new_plane_state); - - mdp5_plane_destroy_state(plane, new_plane_state); - - return 0; -slow_free: - mdp5_plane_destroy_state(plane, new_plane_state); -slow: - return drm_atomic_helper_update_plane(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h, ctx); -} - /* * Use this func and the one below only after the atomic state has been * successfully swapped diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index ae07dd12b1c3..bf5f8c39f34d 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -173,6 +173,18 @@ int msm_atomic_commit(struct drm_device *dev, if (ret) return ret; + /* + * Note that plane->atomic_async_check() should fail if we need + * to re-assign hwpipe or anything that touches global atomic + * state, so we'll never go down the async update path in those + * cases. + */ + if (state->async_update) { + drm_atomic_helper_async_commit(dev, state); + drm_atomic_helper_cleanup_planes(dev, state); + return 0; + } + c = commit_init(state); if (!c) { ret = -ENOMEM; -- cgit v1.2.3 From ba49f0623dfd7307eb55b9e184389b513f1b3a2b Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 30 Jun 2017 15:03:21 -0300 Subject: drm/msm: remove mdp5_cursor_plane_funcs After converting legacy cursor updates to atomic async commits mdp5_cursor_plane_funcs just duplicates mdp5_plane_funcs now. Cc: Rob Clark Cc: Archit Taneja Signed-off-by: Gustavo Padovan Tested-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 83200bbf91f8..56287219d134 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -245,18 +245,6 @@ static const struct drm_plane_funcs mdp5_plane_funcs = { .atomic_print_state = mdp5_plane_atomic_print_state, }; -static const struct drm_plane_funcs mdp5_cursor_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, - .destroy = mdp5_plane_destroy, - .atomic_set_property = mdp5_plane_atomic_set_property, - .atomic_get_property = mdp5_plane_atomic_get_property, - .reset = mdp5_plane_reset, - .atomic_duplicate_state = mdp5_plane_duplicate_state, - .atomic_destroy_state = mdp5_plane_destroy_state, - .atomic_print_state = mdp5_plane_atomic_print_state, -}; - static int mdp5_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { @@ -1108,16 +1096,9 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, mdp5_plane->nformats = mdp_get_formats(mdp5_plane->formats, ARRAY_SIZE(mdp5_plane->formats), false); - if (type == DRM_PLANE_TYPE_CURSOR) - ret = drm_universal_plane_init(dev, plane, 0xff, - &mdp5_cursor_plane_funcs, - mdp5_plane->formats, mdp5_plane->nformats, - NULL, type, NULL); - else - ret = drm_universal_plane_init(dev, plane, 0xff, - &mdp5_plane_funcs, - mdp5_plane->formats, mdp5_plane->nformats, - NULL, type, NULL); + ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, + mdp5_plane->formats, mdp5_plane->nformats, + NULL, type, NULL); if (ret) goto fail; -- cgit v1.2.3 From 9866601e67adc5589302d7dfe12d8325d5b894f8 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 27 Oct 2017 16:27:29 +0530 Subject: drm/msm/mdp5: Prepare mdp5_pipe_assign for some rework mdp5_pipe_assign currently returns the hwpipe pointer for the drm_plane. Return it indirectly by setting a pointer passed as an argument. This is needed because we want the func to find out the right hwpipe too. Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c | 32 +++++++++++++++---------------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h | 4 ++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 18 ++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c index 2bfac3712685..1ca9ecc46d91 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c @@ -17,19 +17,19 @@ #include "mdp5_kms.h" -struct mdp5_hw_pipe *mdp5_pipe_assign(struct drm_atomic_state *s, - struct drm_plane *plane, uint32_t caps, uint32_t blkcfg) +int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, + uint32_t caps, uint32_t blkcfg, + struct mdp5_hw_pipe **hwpipe) { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); struct mdp5_state *state; struct mdp5_hw_pipe_state *old_state, *new_state; - struct mdp5_hw_pipe *hwpipe = NULL; int i; state = mdp5_get_state(s); if (IS_ERR(state)) - return ERR_CAST(state); + return PTR_ERR(state); /* grab old_state after mdp5_get_state(), since now we hold lock: */ old_state = &mdp5_kms->state->hwpipe; @@ -64,31 +64,31 @@ struct mdp5_hw_pipe *mdp5_pipe_assign(struct drm_atomic_state *s, /* possible candidate, take the one with the * fewest unneeded caps bits set: */ - if (!hwpipe || (hweight_long(cur->caps & ~caps) < - hweight_long(hwpipe->caps & ~caps))) - hwpipe = cur; + if (!(*hwpipe) || (hweight_long(cur->caps & ~caps) < + hweight_long((*hwpipe)->caps & ~caps))) + *hwpipe = cur; } - if (!hwpipe) - return ERR_PTR(-ENOMEM); + if (!(*hwpipe)) + return -ENOMEM; if (mdp5_kms->smp) { int ret; - DBG("%s: alloc SMP blocks", hwpipe->name); + DBG("%s: alloc SMP blocks", (*hwpipe)->name); ret = mdp5_smp_assign(mdp5_kms->smp, &state->smp, - hwpipe->pipe, blkcfg); + (*hwpipe)->pipe, blkcfg); if (ret) - return ERR_PTR(-ENOMEM); + return -ENOMEM; - hwpipe->blkcfg = blkcfg; + (*hwpipe)->blkcfg = blkcfg; } DBG("%s: assign to plane %s for caps %x", - hwpipe->name, plane->name, caps); - new_state->hwpipe_to_plane[hwpipe->idx] = plane; + (*hwpipe)->name, plane->name, caps); + new_state->hwpipe_to_plane[(*hwpipe)->idx] = plane; - return hwpipe; + return 0; } void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h index 924c3e6f9517..aaa2bd4e9c32 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h @@ -44,9 +44,9 @@ struct mdp5_hw_pipe_state { struct drm_plane *hwpipe_to_plane[SSPP_MAX]; }; -struct mdp5_hw_pipe *__must_check +int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, - uint32_t caps, uint32_t blkcfg); + uint32_t caps, uint32_t blkcfg, struct mdp5_hw_pipe **hwpipe); void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 56287219d134..aec115e20053 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -394,21 +394,21 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, struct mdp5_hw_pipe *old_right_hwpipe = mdp5_state->r_hwpipe; - mdp5_state->hwpipe = mdp5_pipe_assign(state->state, - plane, caps, blkcfg); - if (IS_ERR(mdp5_state->hwpipe)) { + ret = mdp5_pipe_assign(state->state, plane, caps, + blkcfg, &mdp5_state->hwpipe); + if (ret) { DBG("%s: failed to assign hwpipe!", plane->name); - return PTR_ERR(mdp5_state->hwpipe); + return ret; } if (need_right_hwpipe) { - mdp5_state->r_hwpipe = - mdp5_pipe_assign(state->state, plane, - caps, blkcfg); - if (IS_ERR(mdp5_state->r_hwpipe)) { + ret = mdp5_pipe_assign(state->state, plane, + caps, blkcfg, + &mdp5_state->r_hwpipe); + if (ret) { DBG("%s: failed to assign right hwpipe", plane->name); - return PTR_ERR(mdp5_state->r_hwpipe); + return ret; } } else { /* -- cgit v1.2.3 From b14892801078085cb54dcbe3389057e12c1746a2 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 27 Oct 2017 16:27:30 +0530 Subject: drm/msm/mdp5: Update mdp5_pipe_assign to spit out both planes We currently call mdp5_pipe_assign() twice to assign the left and right hwpipes for our drm_plane. When merging 2 hwpipes, there are a few constraints that we need to keep in mind: - Only the same types of SSPPs are preferred. I.e, a RGB pipe should be paired with another RGB pipe, VIG with VIG etc. - The hwpipe staged on the left should have a higher priority than the hwpipe staged on the right. The priorities are as follows: VIG0 > VIG1 > VIG2 > VIG3 RGB0 > RGB1 > RGB2 > RGB3 DMA0 > DMA1 We can't apply these constraints easily if mdp5_pipe_assign() is called twice. Update mdp5_pipe_assign() to find both hwpipes in one go, and add the extra constraints needed. Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c | 45 ++++++++++++++++++++++++++++--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h | 7 ++--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 25 +++++++++-------- 3 files changed, 57 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c index 1ca9ecc46d91..ff52c49095f9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c @@ -19,13 +19,14 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, uint32_t caps, uint32_t blkcfg, - struct mdp5_hw_pipe **hwpipe) + struct mdp5_hw_pipe **hwpipe, + struct mdp5_hw_pipe **r_hwpipe) { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); struct mdp5_state *state; struct mdp5_hw_pipe_state *old_state, *new_state; - int i; + int i, j; state = mdp5_get_state(s); if (IS_ERR(state)) @@ -65,16 +66,46 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, * fewest unneeded caps bits set: */ if (!(*hwpipe) || (hweight_long(cur->caps & ~caps) < - hweight_long((*hwpipe)->caps & ~caps))) - *hwpipe = cur; + hweight_long((*hwpipe)->caps & ~caps))) { + bool r_found = false; + + if (r_hwpipe) { + for (j = i + 1; j < mdp5_kms->num_hwpipes; + j++) { + struct mdp5_hw_pipe *r_cur = + mdp5_kms->hwpipes[j]; + + /* reject different types of hwpipes */ + if (r_cur->caps != cur->caps) + continue; + + /* respect priority, eg. VIG0 > VIG1 */ + if (cur->pipe > r_cur->pipe) + continue; + + *r_hwpipe = r_cur; + r_found = true; + break; + } + } + + if (!r_hwpipe || r_found) + *hwpipe = cur; + } } if (!(*hwpipe)) return -ENOMEM; + if (r_hwpipe && !(*r_hwpipe)) + return -ENOMEM; + if (mdp5_kms->smp) { int ret; + /* We don't support SMP and 2 hwpipes/plane together */ + WARN_ON(r_hwpipe); + DBG("%s: alloc SMP blocks", (*hwpipe)->name); ret = mdp5_smp_assign(mdp5_kms->smp, &state->smp, (*hwpipe)->pipe, blkcfg); @@ -88,6 +119,12 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, (*hwpipe)->name, plane->name, caps); new_state->hwpipe_to_plane[(*hwpipe)->idx] = plane; + if (r_hwpipe) { + DBG("%s: assign to right of plane %s for caps %x", + (*r_hwpipe)->name, plane->name, caps); + new_state->hwpipe_to_plane[(*r_hwpipe)->idx] = plane; + } + return 0; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h index aaa2bd4e9c32..bb2b0ac7aa2b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.h @@ -44,9 +44,10 @@ struct mdp5_hw_pipe_state { struct drm_plane *hwpipe_to_plane[SSPP_MAX]; }; -int -mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, - uint32_t caps, uint32_t blkcfg, struct mdp5_hw_pipe **hwpipe); +int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, + uint32_t caps, uint32_t blkcfg, + struct mdp5_hw_pipe **hwpipe, + struct mdp5_hw_pipe **r_hwpipe); void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index aec115e20053..f1cf367e853d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -393,31 +393,30 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, struct mdp5_hw_pipe *old_hwpipe = mdp5_state->hwpipe; struct mdp5_hw_pipe *old_right_hwpipe = mdp5_state->r_hwpipe; + struct mdp5_hw_pipe *new_hwpipe = NULL; + struct mdp5_hw_pipe *new_right_hwpipe = NULL; ret = mdp5_pipe_assign(state->state, plane, caps, - blkcfg, &mdp5_state->hwpipe); + blkcfg, &new_hwpipe, + need_right_hwpipe ? + &new_right_hwpipe : NULL); if (ret) { - DBG("%s: failed to assign hwpipe!", plane->name); + DBG("%s: failed to assign hwpipe(s)!", + plane->name); return ret; } - if (need_right_hwpipe) { - ret = mdp5_pipe_assign(state->state, plane, - caps, blkcfg, - &mdp5_state->r_hwpipe); - if (ret) { - DBG("%s: failed to assign right hwpipe", - plane->name); - return ret; - } - } else { + mdp5_state->hwpipe = new_hwpipe; + if (need_right_hwpipe) + mdp5_state->r_hwpipe = new_right_hwpipe; + else /* * set it to NULL so that the driver knows we * don't have a right hwpipe when committing a * new state */ mdp5_state->r_hwpipe = NULL; - } + mdp5_pipe_release(state->state, old_hwpipe); mdp5_pipe_release(state->state, old_right_hwpipe); -- cgit v1.2.3 From aa649e875daf6919bae8d406f115d38a6f39e59c Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 27 Oct 2017 16:27:31 +0530 Subject: drm/msm/mdp5: mdp5_crtc: Restore cursor state only if LM cursors are enabled MDP5 on newer SoCs support cursor planes (i.e, cursor SSPPs). They are a separate entity unlike the cursors within LM. Do not try to restore the MDP5 LM cursor registers, or the corresponding CTL bits if we are not using LM cursors. Also, since we've introduced a new variable 'lm_cursor_enabled', we can now use it to avoid creating a different sets of crtc_funcs for CRTCs with LM cursors and CRTCs with cursor planes. Fixes: "drm/msm/mdp5: restore cursor state when enabling crtc" Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 66 ++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 95ba9edebf04..6f84796c5abc 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -55,6 +55,8 @@ struct mdp5_crtc { struct completion pp_completion; + bool lm_cursor_enabled; + struct { /* protect REG_MDP5_LM_CURSOR* registers and cursor scanout_bo*/ spinlock_t lock; @@ -457,19 +459,24 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, pm_runtime_get_sync(dev); - /* Restore cursor state, as it might have been lost with suspend: */ - if (mdp5_crtc->cursor.iova) { - unsigned long flags; - - spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); - mdp5_crtc_restore_cursor(crtc); - spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); - - mdp5_ctl_set_cursor(mdp5_cstate->ctl, - &mdp5_cstate->pipeline, 0, true); - } else { - mdp5_ctl_set_cursor(mdp5_cstate->ctl, - &mdp5_cstate->pipeline, 0, false); + if (mdp5_crtc->lm_cursor_enabled) { + /* + * Restore LM cursor state, as it might have been lost + * with suspend: + */ + if (mdp5_crtc->cursor.iova) { + unsigned long flags; + + spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); + mdp5_crtc_restore_cursor(crtc); + spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); + + mdp5_ctl_set_cursor(mdp5_cstate->ctl, + &mdp5_cstate->pipeline, 0, true); + } else { + mdp5_ctl_set_cursor(mdp5_cstate->ctl, + &mdp5_cstate->pipeline, 0, false); + } } /* Restore vblank irq handling after power is enabled */ @@ -817,6 +824,12 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, bool cursor_enable = true; unsigned long flags; + if (!mdp5_crtc->lm_cursor_enabled) { + dev_warn(dev->dev, + "cursor_set is deprecated with cursor planes\n"); + return -EINVAL; + } + if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height); return -EINVAL; @@ -888,10 +901,17 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); + struct drm_device *dev = crtc->dev; uint32_t roi_w; uint32_t roi_h; unsigned long flags; + if (!mdp5_crtc->lm_cursor_enabled) { + dev_warn(dev->dev, + "cursor_move is deprecated with cursor planes\n"); + return -EINVAL; + } + /* don't support LM cursors when we we have source split enabled */ if (mdp5_cstate->pipeline.r_mixer) return -EINVAL; @@ -993,16 +1013,6 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = { .atomic_print_state = mdp5_crtc_atomic_print_state, }; -static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = { - .set_config = drm_atomic_helper_set_config, - .destroy = mdp5_crtc_destroy, - .page_flip = drm_atomic_helper_page_flip, - .reset = mdp5_crtc_reset, - .atomic_duplicate_state = mdp5_crtc_duplicate_state, - .atomic_destroy_state = mdp5_crtc_destroy_state, - .atomic_print_state = mdp5_crtc_atomic_print_state, -}; - static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { .mode_set_nofb = mdp5_crtc_mode_set_nofb, .atomic_check = mdp5_crtc_atomic_check, @@ -1171,12 +1181,10 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, mdp5_crtc->err.irq = mdp5_crtc_err_irq; mdp5_crtc->pp_done.irq = mdp5_crtc_pp_done_irq; - if (cursor_plane) - drm_crtc_init_with_planes(dev, crtc, plane, cursor_plane, - &mdp5_crtc_no_lm_cursor_funcs, NULL); - else - drm_crtc_init_with_planes(dev, crtc, plane, NULL, - &mdp5_crtc_funcs, NULL); + mdp5_crtc->lm_cursor_enabled = cursor_plane ? false : true; + + drm_crtc_init_with_planes(dev, crtc, plane, cursor_plane, + &mdp5_crtc_funcs, NULL); drm_flip_work_init(&mdp5_crtc->unref_cursor_work, "unref cursor", unref_cursor_worker); -- cgit v1.2.3 From 18075d0d4849c670a09ec2056a4fecb994c6ee3e Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 27 Oct 2017 16:27:32 +0530 Subject: drm/msm/mdp5: Don't use async plane update path if plane visibility changes When a plane moves out of bounds (i.e, outside the crtc clip region), the plane state's "visible" parameter changes to false. When this happens, we (a) release the hwpipe resources away from it, and (b) unstage the corresponding hwpipe(s) from the Layer Mixers in the CRTC. (a) requires use to acquire the global atomic state and assign a new hwpipe. (b) requires us to re-configure the Layer Mixer, which is done in the CRTC. We don't want to do these things in the async plane update path, so return an error if the new state's "visible" isn't the same as the current state's "visible". Cc: Gustavo Padovan Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index f1cf367e853d..be50445f9901 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -470,6 +470,9 @@ static int mdp5_plane_atomic_async_check(struct drm_plane *plane, { struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state); struct drm_crtc_state *crtc_state; + struct drm_rect clip; + int min_scale, max_scale; + int ret; crtc_state = drm_atomic_get_existing_crtc_state(state->state, state->crtc); @@ -495,6 +498,28 @@ static int mdp5_plane_atomic_async_check(struct drm_plane *plane, plane->state->fb != state->fb) return -EINVAL; + clip.x1 = 0; + clip.y1 = 0; + clip.x2 = crtc_state->adjusted_mode.hdisplay; + clip.y2 = crtc_state->adjusted_mode.vdisplay; + min_scale = FRAC_16_16(1, 8); + max_scale = FRAC_16_16(8, 1); + + ret = drm_plane_helper_check_state(state, &clip, min_scale, + max_scale, true, true); + if (ret) + return ret; + + /* + * if the visibility of the plane changes (i.e, if the cursor is + * clipped out completely, we can't take the async path because + * we need to stage/unstage the plane from the Layer Mixer(s). We + * also assign/unassign the hwpipe(s) tied to the plane. We avoid + * taking the fast path for both these reasons. + */ + if (state->visible != plane->state->visible) + return -EINVAL; + return 0; } -- cgit v1.2.3 From f4fa88ab28ab61941a22f938eda3d93d1fe371af Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 30 Oct 2017 14:16:21 +0100 Subject: drm/radeon: deprecate and remove KFD interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To quote Felix: "For testing KV with current user mode stack, please use amdgpu. I don't expect this to work with radeon and I'm not planning to spend any effort on making radeon work with a current user mode stack." Only compile tested, but should be straight forward. Signed-off-by: Christian König Signed-off-by: Oded Gabbay --- MAINTAINERS | 2 - drivers/gpu/drm/amd/amdkfd/Kconfig | 2 +- drivers/gpu/drm/radeon/Makefile | 3 +- drivers/gpu/drm/radeon/cik.c | 14 +- drivers/gpu/drm/radeon/cikd.h | 2 - drivers/gpu/drm/radeon/radeon.h | 3 - drivers/gpu/drm/radeon/radeon_drv.c | 10 - drivers/gpu/drm/radeon/radeon_kfd.c | 901 ------------------------------------ drivers/gpu/drm/radeon/radeon_kfd.h | 47 -- drivers/gpu/drm/radeon/radeon_kms.c | 7 - 10 files changed, 4 insertions(+), 987 deletions(-) delete mode 100644 drivers/gpu/drm/radeon/radeon_kfd.c delete mode 100644 drivers/gpu/drm/radeon/radeon_kfd.h (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 0525701befd0..6e1f94b4ed26 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -759,8 +759,6 @@ F: drivers/gpu/drm/amd/amdkfd/ F: drivers/gpu/drm/amd/include/cik_structs.h F: drivers/gpu/drm/amd/include/kgd_kfd_interface.h F: drivers/gpu/drm/amd/include/vi_structs.h -F: drivers/gpu/drm/radeon/radeon_kfd.c -F: drivers/gpu/drm/radeon/radeon_kfd.h F: include/uapi/linux/kfd_ioctl.h AMD SEATTLE DEVICE TREE SUPPORT diff --git a/drivers/gpu/drm/amd/amdkfd/Kconfig b/drivers/gpu/drm/amd/amdkfd/Kconfig index e13c67c8d2c0..bc5a2945bd2b 100644 --- a/drivers/gpu/drm/amd/amdkfd/Kconfig +++ b/drivers/gpu/drm/amd/amdkfd/Kconfig @@ -4,6 +4,6 @@ config HSA_AMD tristate "HSA kernel driver for AMD GPU devices" - depends on (DRM_RADEON || DRM_AMDGPU) && AMD_IOMMU_V2 && X86_64 + depends on DRM_AMDGPU && AMD_IOMMU_V2 && X86_64 help Enable this if you want to use HSA features on AMD GPU devices. diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index be16c6390216..cf3e5985e3e7 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -102,8 +102,7 @@ radeon-y += \ radeon-y += \ radeon_vce.o \ vce_v1_0.o \ - vce_v2_0.o \ - radeon_kfd.o + vce_v2_0.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o radeon-$(CONFIG_ACPI) += radeon_acpi.o diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 3cb6c55b268d..898f9a078830 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -33,7 +33,6 @@ #include "cik_blit_shaders.h" #include "radeon_ucode.h" #include "clearstate_ci.h" -#include "radeon_kfd.h" #define SH_MEM_CONFIG_GFX_DEFAULT \ ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) @@ -5684,10 +5683,9 @@ int cik_vm_init(struct radeon_device *rdev) /* * number of VMs * VMID 0 is reserved for System - * radeon graphics/compute will use VMIDs 1-7 - * amdkfd will use VMIDs 8-15 + * radeon graphics/compute will use VMIDs 1-15 */ - rdev->vm_manager.nvm = RADEON_NUM_OF_VMIDS; + rdev->vm_manager.nvm = 16; /* base offset of vram pages */ if (rdev->flags & RADEON_IS_IGP) { u64 tmp = RREG32(MC_VM_FB_OFFSET); @@ -7589,9 +7587,6 @@ restart_ih: /* wptr/rptr are in bytes! */ ring_index = rptr / 4; - radeon_kfd_interrupt(rdev, - (const void *) &rdev->ih.ring[ring_index]); - src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff; @@ -8486,10 +8481,6 @@ static int cik_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_kfd_resume(rdev); - if (r) - return r; - return 0; } @@ -8538,7 +8529,6 @@ int cik_resume(struct radeon_device *rdev) */ int cik_suspend(struct radeon_device *rdev) { - radeon_kfd_suspend(rdev); radeon_pm_suspend(rdev); radeon_audio_fini(rdev); radeon_vm_manager_fini(rdev); diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index e21015475ed5..cda16fcd43bb 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -30,8 +30,6 @@ #define CIK_RB_BITMAP_WIDTH_PER_SH 2 #define HAWAII_RB_BITMAP_WIDTH_PER_SH 4 -#define RADEON_NUM_OF_VMIDS 8 - /* DIDT IND registers */ #define DIDT_SQ_CTRL0 0x0 # define DIDT_CTRL_EN (1 << 0) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 8cbaeec090c9..a8e546569858 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2456,9 +2456,6 @@ struct radeon_device { u64 vram_pin_size; u64 gart_pin_size; - /* amdkfd interface */ - struct kfd_dev *kfd; - struct mutex mn_lock; DECLARE_HASHTABLE(mn_hash, 7); }; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index f4becad0a78c..31dd04f6baa1 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -43,7 +43,6 @@ #include #include -#include "radeon_kfd.h" /* * KMS wrapper. @@ -338,14 +337,6 @@ static int radeon_pci_probe(struct pci_dev *pdev, { int ret; - /* - * Initialize amdkfd before starting radeon. If it was not loaded yet, - * defer radeon probing - */ - ret = radeon_kfd_init(); - if (ret == -EPROBE_DEFER) - return ret; - if (vga_switcheroo_client_probe_defer(pdev)) return -EPROBE_DEFER; @@ -645,7 +636,6 @@ static int __init radeon_init(void) static void __exit radeon_exit(void) { - radeon_kfd_fini(); pci_unregister_driver(pdriver); radeon_unregister_atpx_handler(); } diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c deleted file mode 100644 index 385b4d76956d..000000000000 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ /dev/null @@ -1,901 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include "radeon.h" -#include "cikd.h" -#include "cik_reg.h" -#include "radeon_kfd.h" -#include "radeon_ucode.h" -#include -#include "cik_structs.h" - -#define CIK_PIPE_PER_MEC (4) - -static const uint32_t watchRegs[MAX_WATCH_ADDRESSES * ADDRESS_WATCH_REG_MAX] = { - TCP_WATCH0_ADDR_H, TCP_WATCH0_ADDR_L, TCP_WATCH0_CNTL, - TCP_WATCH1_ADDR_H, TCP_WATCH1_ADDR_L, TCP_WATCH1_CNTL, - TCP_WATCH2_ADDR_H, TCP_WATCH2_ADDR_L, TCP_WATCH2_CNTL, - TCP_WATCH3_ADDR_H, TCP_WATCH3_ADDR_L, TCP_WATCH3_CNTL -}; - -struct kgd_mem { - struct radeon_bo *bo; - uint64_t gpu_addr; - void *cpu_ptr; -}; - - -static int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, - void **mem_obj, uint64_t *gpu_addr, - void **cpu_ptr); - -static void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj); - -static uint64_t get_vmem_size(struct kgd_dev *kgd); -static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd); - -static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd); - -static int alloc_pasid(unsigned int bits); -static void free_pasid(unsigned int pasid); - -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); - -/* - * Register access functions - */ - -static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, - uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, - uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases); - -static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, - unsigned int vmid); - -static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, - uint32_t hpd_size, uint64_t hpd_gpu_addr); -static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id); -static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, - uint32_t queue_id, uint32_t __user *wptr, - uint32_t wptr_shift, uint32_t wptr_mask, - struct mm_struct *mm); -static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd); -static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, - uint32_t pipe_id, uint32_t queue_id); - -static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, uint32_t reset_type, - unsigned int timeout, uint32_t pipe_id, - uint32_t queue_id); -static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); -static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, - unsigned int timeout); -static int kgd_address_watch_disable(struct kgd_dev *kgd); -static int kgd_address_watch_execute(struct kgd_dev *kgd, - unsigned int watch_point_id, - uint32_t cntl_val, - uint32_t addr_hi, - uint32_t addr_lo); -static int kgd_wave_control_execute(struct kgd_dev *kgd, - uint32_t gfx_index_val, - uint32_t sq_cmd); -static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, - unsigned int watch_point_id, - unsigned int reg_offset); - -static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid); -static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, - uint8_t vmid); -static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid); - -static const struct kfd2kgd_calls kfd2kgd = { - .init_gtt_mem_allocation = alloc_gtt_mem, - .free_gtt_mem = free_gtt_mem, - .get_vmem_size = get_vmem_size, - .get_gpu_clock_counter = get_gpu_clock_counter, - .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, - .alloc_pasid = alloc_pasid, - .free_pasid = free_pasid, - .program_sh_mem_settings = kgd_program_sh_mem_settings, - .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, - .init_pipeline = kgd_init_pipeline, - .init_interrupts = kgd_init_interrupts, - .hqd_load = kgd_hqd_load, - .hqd_sdma_load = kgd_hqd_sdma_load, - .hqd_is_occupied = kgd_hqd_is_occupied, - .hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied, - .hqd_destroy = kgd_hqd_destroy, - .hqd_sdma_destroy = kgd_hqd_sdma_destroy, - .address_watch_disable = kgd_address_watch_disable, - .address_watch_execute = kgd_address_watch_execute, - .wave_control_execute = kgd_wave_control_execute, - .address_watch_get_offset = kgd_address_watch_get_offset, - .get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid, - .get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid, - .write_vmid_invalidate_request = write_vmid_invalidate_request, - .get_fw_version = get_fw_version -}; - -static const struct kgd2kfd_calls *kgd2kfd; - -int radeon_kfd_init(void) -{ - int ret; - -#if defined(CONFIG_HSA_AMD_MODULE) - int (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); - - kgd2kfd_init_p = symbol_request(kgd2kfd_init); - - if (kgd2kfd_init_p == NULL) - return -ENOENT; - - ret = kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd); - if (ret) { - symbol_put(kgd2kfd_init); - kgd2kfd = NULL; - } - -#elif defined(CONFIG_HSA_AMD) - ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd); - if (ret) - kgd2kfd = NULL; - -#else - ret = -ENOENT; -#endif - - return ret; -} - -void radeon_kfd_fini(void) -{ - if (kgd2kfd) { - kgd2kfd->exit(); - symbol_put(kgd2kfd_init); - } -} - -void radeon_kfd_device_probe(struct radeon_device *rdev) -{ - if (kgd2kfd) - rdev->kfd = kgd2kfd->probe((struct kgd_dev *)rdev, - rdev->pdev, &kfd2kgd); -} - -void radeon_kfd_device_init(struct radeon_device *rdev) -{ - int i, queue, pipe, mec; - - if (rdev->kfd) { - struct kgd2kfd_shared_resources gpu_resources = { - .compute_vmid_bitmap = 0xFF00, - .num_pipe_per_mec = 4, - .num_queue_per_pipe = 8 - }; - - bitmap_zero(gpu_resources.queue_bitmap, KGD_MAX_QUEUES); - - for (i = 0; i < KGD_MAX_QUEUES; ++i) { - queue = i % gpu_resources.num_queue_per_pipe; - pipe = (i / gpu_resources.num_queue_per_pipe) - % gpu_resources.num_pipe_per_mec; - mec = (i / gpu_resources.num_queue_per_pipe) - / gpu_resources.num_pipe_per_mec; - - if (mec == 0 && pipe > 0) - set_bit(i, gpu_resources.queue_bitmap); - } - - radeon_doorbell_get_kfd_info(rdev, - &gpu_resources.doorbell_physical_address, - &gpu_resources.doorbell_aperture_size, - &gpu_resources.doorbell_start_offset); - - kgd2kfd->device_init(rdev->kfd, &gpu_resources); - } -} - -void radeon_kfd_device_fini(struct radeon_device *rdev) -{ - if (rdev->kfd) { - kgd2kfd->device_exit(rdev->kfd); - rdev->kfd = NULL; - } -} - -void radeon_kfd_interrupt(struct radeon_device *rdev, const void *ih_ring_entry) -{ - if (rdev->kfd) - kgd2kfd->interrupt(rdev->kfd, ih_ring_entry); -} - -void radeon_kfd_suspend(struct radeon_device *rdev) -{ - if (rdev->kfd) - kgd2kfd->suspend(rdev->kfd); -} - -int radeon_kfd_resume(struct radeon_device *rdev) -{ - int r = 0; - - if (rdev->kfd) - r = kgd2kfd->resume(rdev->kfd); - - return r; -} - -static int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, - void **mem_obj, uint64_t *gpu_addr, - void **cpu_ptr) -{ - struct radeon_device *rdev = (struct radeon_device *)kgd; - struct kgd_mem **mem = (struct kgd_mem **) mem_obj; - int r; - - BUG_ON(kgd == NULL); - BUG_ON(gpu_addr == NULL); - BUG_ON(cpu_ptr == NULL); - - *mem = kmalloc(sizeof(struct kgd_mem), GFP_KERNEL); - if ((*mem) == NULL) - return -ENOMEM; - - r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, - RADEON_GEM_GTT_WC, NULL, NULL, &(*mem)->bo); - if (r) { - dev_err(rdev->dev, - "failed to allocate BO for amdkfd (%d)\n", r); - return r; - } - - /* map the buffer */ - r = radeon_bo_reserve((*mem)->bo, true); - if (r) { - dev_err(rdev->dev, "(%d) failed to reserve bo for amdkfd\n", r); - goto allocate_mem_reserve_bo_failed; - } - - r = radeon_bo_pin((*mem)->bo, RADEON_GEM_DOMAIN_GTT, - &(*mem)->gpu_addr); - if (r) { - dev_err(rdev->dev, "(%d) failed to pin bo for amdkfd\n", r); - goto allocate_mem_pin_bo_failed; - } - *gpu_addr = (*mem)->gpu_addr; - - r = radeon_bo_kmap((*mem)->bo, &(*mem)->cpu_ptr); - if (r) { - dev_err(rdev->dev, - "(%d) failed to map bo to kernel for amdkfd\n", r); - goto allocate_mem_kmap_bo_failed; - } - *cpu_ptr = (*mem)->cpu_ptr; - - radeon_bo_unreserve((*mem)->bo); - - return 0; - -allocate_mem_kmap_bo_failed: - radeon_bo_unpin((*mem)->bo); -allocate_mem_pin_bo_failed: - radeon_bo_unreserve((*mem)->bo); -allocate_mem_reserve_bo_failed: - radeon_bo_unref(&(*mem)->bo); - - return r; -} - -static void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) -{ - struct kgd_mem *mem = (struct kgd_mem *) mem_obj; - - BUG_ON(mem == NULL); - - radeon_bo_reserve(mem->bo, true); - radeon_bo_kunmap(mem->bo); - radeon_bo_unpin(mem->bo); - radeon_bo_unreserve(mem->bo); - radeon_bo_unref(&(mem->bo)); - kfree(mem); -} - -static uint64_t get_vmem_size(struct kgd_dev *kgd) -{ - struct radeon_device *rdev = (struct radeon_device *)kgd; - - BUG_ON(kgd == NULL); - - return rdev->mc.real_vram_size; -} - -static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd) -{ - struct radeon_device *rdev = (struct radeon_device *)kgd; - - return rdev->asic->get_gpu_clock_counter(rdev); -} - -static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd) -{ - struct radeon_device *rdev = (struct radeon_device *)kgd; - - /* The sclk is in quantas of 10kHz */ - return rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk / 100; -} - -/* - * PASID manager - */ -static DEFINE_IDA(pasid_ida); - -static int alloc_pasid(unsigned int bits) -{ - int pasid = -EINVAL; - - for (bits = min(bits, 31U); bits > 0; bits--) { - pasid = ida_simple_get(&pasid_ida, - 1U << (bits - 1), 1U << bits, - GFP_KERNEL); - if (pasid != -ENOSPC) - break; - } - - return pasid; -} - -static void free_pasid(unsigned int pasid) -{ - ida_simple_remove(&pasid_ida, pasid); -} - -static inline struct radeon_device *get_radeon_device(struct kgd_dev *kgd) -{ - return (struct radeon_device *)kgd; -} - -static void write_register(struct kgd_dev *kgd, uint32_t offset, uint32_t value) -{ - struct radeon_device *rdev = get_radeon_device(kgd); - - writel(value, (void __iomem *)(rdev->rmmio + offset)); -} - -static uint32_t read_register(struct kgd_dev *kgd, uint32_t offset) -{ - struct radeon_device *rdev = get_radeon_device(kgd); - - return readl((void __iomem *)(rdev->rmmio + offset)); -} - -static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe, - uint32_t queue, uint32_t vmid) -{ - struct radeon_device *rdev = get_radeon_device(kgd); - uint32_t value = PIPEID(pipe) | MEID(mec) | VMID(vmid) | QUEUEID(queue); - - mutex_lock(&rdev->srbm_mutex); - write_register(kgd, SRBM_GFX_CNTL, value); -} - -static void unlock_srbm(struct kgd_dev *kgd) -{ - struct radeon_device *rdev = get_radeon_device(kgd); - - write_register(kgd, SRBM_GFX_CNTL, 0); - mutex_unlock(&rdev->srbm_mutex); -} - -static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, - uint32_t queue_id) -{ - uint32_t mec = (++pipe_id / CIK_PIPE_PER_MEC) + 1; - uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC); - - lock_srbm(kgd, mec, pipe, queue_id, 0); -} - -static void release_queue(struct kgd_dev *kgd) -{ - unlock_srbm(kgd); -} - -static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, - uint32_t sh_mem_config, - uint32_t sh_mem_ape1_base, - uint32_t sh_mem_ape1_limit, - uint32_t sh_mem_bases) -{ - lock_srbm(kgd, 0, 0, 0, vmid); - - write_register(kgd, SH_MEM_CONFIG, sh_mem_config); - write_register(kgd, SH_MEM_APE1_BASE, sh_mem_ape1_base); - write_register(kgd, SH_MEM_APE1_LIMIT, sh_mem_ape1_limit); - write_register(kgd, SH_MEM_BASES, sh_mem_bases); - - unlock_srbm(kgd); -} - -static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, - unsigned int vmid) -{ - /* - * We have to assume that there is no outstanding mapping. - * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 - * because a mapping is in progress or because a mapping finished and - * the SW cleared it. - * So the protocol is to always wait & clear. - */ - uint32_t pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid | - ATC_VMID_PASID_MAPPING_VALID_MASK; - - write_register(kgd, ATC_VMID0_PASID_MAPPING + vmid*sizeof(uint32_t), - pasid_mapping); - - while (!(read_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS) & - (1U << vmid))) - cpu_relax(); - write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); - - /* Mapping vmid to pasid also for IH block */ - write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t), - pasid_mapping); - - return 0; -} - -static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, - uint32_t hpd_size, uint64_t hpd_gpu_addr) -{ - /* nothing to do here */ - return 0; -} - -static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) -{ - uint32_t mec; - uint32_t pipe; - - mec = (pipe_id / CIK_PIPE_PER_MEC) + 1; - pipe = (pipe_id % CIK_PIPE_PER_MEC); - - lock_srbm(kgd, mec, pipe, 0, 0); - - write_register(kgd, CPC_INT_CNTL, - TIME_STAMP_INT_ENABLE | OPCODE_ERROR_INT_ENABLE); - - unlock_srbm(kgd); - - return 0; -} - -static inline uint32_t get_sdma_base_addr(struct cik_sdma_rlc_registers *m) -{ - uint32_t retval; - - retval = m->sdma_engine_id * SDMA1_REGISTER_OFFSET + - m->sdma_queue_id * KFD_CIK_SDMA_QUEUE_OFFSET; - - pr_debug("kfd: sdma base address: 0x%x\n", retval); - - return retval; -} - -static inline struct cik_mqd *get_mqd(void *mqd) -{ - return (struct cik_mqd *)mqd; -} - -static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd) -{ - return (struct cik_sdma_rlc_registers *)mqd; -} - -static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, - uint32_t queue_id, uint32_t __user *wptr, - uint32_t wptr_shift, uint32_t wptr_mask, - struct mm_struct *mm) -{ - uint32_t wptr_shadow, is_wptr_shadow_valid; - struct cik_mqd *m; - - m = get_mqd(mqd); - - is_wptr_shadow_valid = !get_user(wptr_shadow, wptr); - - acquire_queue(kgd, pipe_id, queue_id); - write_register(kgd, CP_MQD_BASE_ADDR, m->cp_mqd_base_addr_lo); - write_register(kgd, CP_MQD_BASE_ADDR_HI, m->cp_mqd_base_addr_hi); - write_register(kgd, CP_MQD_CONTROL, m->cp_mqd_control); - - write_register(kgd, CP_HQD_PQ_BASE, m->cp_hqd_pq_base_lo); - write_register(kgd, CP_HQD_PQ_BASE_HI, m->cp_hqd_pq_base_hi); - write_register(kgd, CP_HQD_PQ_CONTROL, m->cp_hqd_pq_control); - - write_register(kgd, CP_HQD_IB_CONTROL, m->cp_hqd_ib_control); - write_register(kgd, CP_HQD_IB_BASE_ADDR, m->cp_hqd_ib_base_addr_lo); - write_register(kgd, CP_HQD_IB_BASE_ADDR_HI, m->cp_hqd_ib_base_addr_hi); - - write_register(kgd, CP_HQD_IB_RPTR, m->cp_hqd_ib_rptr); - - write_register(kgd, CP_HQD_PERSISTENT_STATE, - m->cp_hqd_persistent_state); - write_register(kgd, CP_HQD_SEMA_CMD, m->cp_hqd_sema_cmd); - write_register(kgd, CP_HQD_MSG_TYPE, m->cp_hqd_msg_type); - - write_register(kgd, CP_HQD_ATOMIC0_PREOP_LO, - m->cp_hqd_atomic0_preop_lo); - - write_register(kgd, CP_HQD_ATOMIC0_PREOP_HI, - m->cp_hqd_atomic0_preop_hi); - - write_register(kgd, CP_HQD_ATOMIC1_PREOP_LO, - m->cp_hqd_atomic1_preop_lo); - - write_register(kgd, CP_HQD_ATOMIC1_PREOP_HI, - m->cp_hqd_atomic1_preop_hi); - - write_register(kgd, CP_HQD_PQ_RPTR_REPORT_ADDR, - m->cp_hqd_pq_rptr_report_addr_lo); - - write_register(kgd, CP_HQD_PQ_RPTR_REPORT_ADDR_HI, - m->cp_hqd_pq_rptr_report_addr_hi); - - write_register(kgd, CP_HQD_PQ_RPTR, m->cp_hqd_pq_rptr); - - write_register(kgd, CP_HQD_PQ_WPTR_POLL_ADDR, - m->cp_hqd_pq_wptr_poll_addr_lo); - - write_register(kgd, CP_HQD_PQ_WPTR_POLL_ADDR_HI, - m->cp_hqd_pq_wptr_poll_addr_hi); - - write_register(kgd, CP_HQD_PQ_DOORBELL_CONTROL, - m->cp_hqd_pq_doorbell_control); - - write_register(kgd, CP_HQD_VMID, m->cp_hqd_vmid); - - write_register(kgd, CP_HQD_QUANTUM, m->cp_hqd_quantum); - - write_register(kgd, CP_HQD_PIPE_PRIORITY, m->cp_hqd_pipe_priority); - write_register(kgd, CP_HQD_QUEUE_PRIORITY, m->cp_hqd_queue_priority); - - write_register(kgd, CP_HQD_IQ_RPTR, m->cp_hqd_iq_rptr); - - if (is_wptr_shadow_valid) - write_register(kgd, CP_HQD_PQ_WPTR, wptr_shadow); - - write_register(kgd, CP_HQD_ACTIVE, m->cp_hqd_active); - release_queue(kgd); - - return 0; -} - -static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd) -{ - struct cik_sdma_rlc_registers *m; - uint32_t sdma_base_addr; - - m = get_sdma_mqd(mqd); - sdma_base_addr = get_sdma_base_addr(m); - - write_register(kgd, - sdma_base_addr + SDMA0_RLC0_VIRTUAL_ADDR, - m->sdma_rlc_virtual_addr); - - write_register(kgd, - sdma_base_addr + SDMA0_RLC0_RB_BASE, - m->sdma_rlc_rb_base); - - write_register(kgd, - sdma_base_addr + SDMA0_RLC0_RB_BASE_HI, - m->sdma_rlc_rb_base_hi); - - write_register(kgd, - sdma_base_addr + SDMA0_RLC0_RB_RPTR_ADDR_LO, - m->sdma_rlc_rb_rptr_addr_lo); - - write_register(kgd, - sdma_base_addr + SDMA0_RLC0_RB_RPTR_ADDR_HI, - m->sdma_rlc_rb_rptr_addr_hi); - - write_register(kgd, - sdma_base_addr + SDMA0_RLC0_DOORBELL, - m->sdma_rlc_doorbell); - - write_register(kgd, - sdma_base_addr + SDMA0_RLC0_RB_CNTL, - m->sdma_rlc_rb_cntl); - - return 0; -} - -static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, - uint32_t pipe_id, uint32_t queue_id) -{ - uint32_t act; - bool retval = false; - uint32_t low, high; - - acquire_queue(kgd, pipe_id, queue_id); - act = read_register(kgd, CP_HQD_ACTIVE); - if (act) { - low = lower_32_bits(queue_address >> 8); - high = upper_32_bits(queue_address >> 8); - - if (low == read_register(kgd, CP_HQD_PQ_BASE) && - high == read_register(kgd, CP_HQD_PQ_BASE_HI)) - retval = true; - } - release_queue(kgd); - return retval; -} - -static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) -{ - struct cik_sdma_rlc_registers *m; - uint32_t sdma_base_addr; - uint32_t sdma_rlc_rb_cntl; - - m = get_sdma_mqd(mqd); - sdma_base_addr = get_sdma_base_addr(m); - - sdma_rlc_rb_cntl = read_register(kgd, - sdma_base_addr + SDMA0_RLC0_RB_CNTL); - - if (sdma_rlc_rb_cntl & SDMA_RB_ENABLE) - return true; - - return false; -} - -static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, uint32_t reset_type, - unsigned int timeout, uint32_t pipe_id, - uint32_t queue_id) -{ - uint32_t temp; - - acquire_queue(kgd, pipe_id, queue_id); - write_register(kgd, CP_HQD_PQ_DOORBELL_CONTROL, 0); - - write_register(kgd, CP_HQD_DEQUEUE_REQUEST, reset_type); - - while (true) { - temp = read_register(kgd, CP_HQD_ACTIVE); - if (temp & 0x1) - break; - if (timeout == 0) { - pr_err("kfd: cp queue preemption time out (%dms)\n", - temp); - release_queue(kgd); - return -ETIME; - } - msleep(20); - timeout -= 20; - } - - release_queue(kgd); - return 0; -} - -static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, - unsigned int timeout) -{ - struct cik_sdma_rlc_registers *m; - uint32_t sdma_base_addr; - uint32_t temp; - - m = get_sdma_mqd(mqd); - sdma_base_addr = get_sdma_base_addr(m); - - temp = read_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_CNTL); - temp = temp & ~SDMA_RB_ENABLE; - write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_CNTL, temp); - - while (true) { - temp = read_register(kgd, sdma_base_addr + - SDMA0_RLC0_CONTEXT_STATUS); - if (temp & SDMA_RLC_IDLE) - break; - if (timeout == 0) - return -ETIME; - msleep(20); - timeout -= 20; - } - - write_register(kgd, sdma_base_addr + SDMA0_RLC0_DOORBELL, 0); - write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_RPTR, 0); - write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_WPTR, 0); - write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_BASE, 0); - - return 0; -} - -static int kgd_address_watch_disable(struct kgd_dev *kgd) -{ - union TCP_WATCH_CNTL_BITS cntl; - unsigned int i; - - cntl.u32All = 0; - - cntl.bitfields.valid = 0; - cntl.bitfields.mask = ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK; - cntl.bitfields.atc = 1; - - /* Turning off this address until we set all the registers */ - for (i = 0; i < MAX_WATCH_ADDRESSES; i++) - write_register(kgd, - watchRegs[i * ADDRESS_WATCH_REG_MAX + - ADDRESS_WATCH_REG_CNTL], - cntl.u32All); - - return 0; -} - -static int kgd_address_watch_execute(struct kgd_dev *kgd, - unsigned int watch_point_id, - uint32_t cntl_val, - uint32_t addr_hi, - uint32_t addr_lo) -{ - union TCP_WATCH_CNTL_BITS cntl; - - cntl.u32All = cntl_val; - - /* Turning off this watch point until we set all the registers */ - cntl.bitfields.valid = 0; - write_register(kgd, - watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + - ADDRESS_WATCH_REG_CNTL], - cntl.u32All); - - write_register(kgd, - watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + - ADDRESS_WATCH_REG_ADDR_HI], - addr_hi); - - write_register(kgd, - watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + - ADDRESS_WATCH_REG_ADDR_LO], - addr_lo); - - /* Enable the watch point */ - cntl.bitfields.valid = 1; - - write_register(kgd, - watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + - ADDRESS_WATCH_REG_CNTL], - cntl.u32All); - - return 0; -} - -static int kgd_wave_control_execute(struct kgd_dev *kgd, - uint32_t gfx_index_val, - uint32_t sq_cmd) -{ - struct radeon_device *rdev = get_radeon_device(kgd); - uint32_t data; - - mutex_lock(&rdev->grbm_idx_mutex); - - write_register(kgd, GRBM_GFX_INDEX, gfx_index_val); - write_register(kgd, SQ_CMD, sq_cmd); - - /* Restore the GRBM_GFX_INDEX register */ - - data = INSTANCE_BROADCAST_WRITES | SH_BROADCAST_WRITES | - SE_BROADCAST_WRITES; - - write_register(kgd, GRBM_GFX_INDEX, data); - - mutex_unlock(&rdev->grbm_idx_mutex); - - return 0; -} - -static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, - unsigned int watch_point_id, - unsigned int reg_offset) -{ - return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset] - / 4; -} - -static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid) -{ - uint32_t reg; - struct radeon_device *rdev = (struct radeon_device *) kgd; - - reg = RREG32(ATC_VMID0_PASID_MAPPING + vmid*4); - return reg & ATC_VMID_PASID_MAPPING_VALID_MASK; -} - -static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, - uint8_t vmid) -{ - uint32_t reg; - struct radeon_device *rdev = (struct radeon_device *) kgd; - - reg = RREG32(ATC_VMID0_PASID_MAPPING + vmid*4); - return reg & ATC_VMID_PASID_MAPPING_PASID_MASK; -} - -static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid) -{ - struct radeon_device *rdev = (struct radeon_device *) kgd; - - return WREG32(VM_INVALIDATE_REQUEST, 1 << vmid); -} - -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) -{ - struct radeon_device *rdev = (struct radeon_device *) kgd; - const union radeon_firmware_header *hdr; - - BUG_ON(kgd == NULL || rdev->mec_fw == NULL); - - switch (type) { - case KGD_ENGINE_PFP: - hdr = (const union radeon_firmware_header *) rdev->pfp_fw->data; - break; - - case KGD_ENGINE_ME: - hdr = (const union radeon_firmware_header *) rdev->me_fw->data; - break; - - case KGD_ENGINE_CE: - hdr = (const union radeon_firmware_header *) rdev->ce_fw->data; - break; - - case KGD_ENGINE_MEC1: - hdr = (const union radeon_firmware_header *) rdev->mec_fw->data; - break; - - case KGD_ENGINE_MEC2: - hdr = (const union radeon_firmware_header *) - rdev->mec2_fw->data; - break; - - case KGD_ENGINE_RLC: - hdr = (const union radeon_firmware_header *) rdev->rlc_fw->data; - break; - - case KGD_ENGINE_SDMA1: - case KGD_ENGINE_SDMA2: - hdr = (const union radeon_firmware_header *) - rdev->sdma_fw->data; - break; - - default: - return 0; - } - - if (hdr == NULL) - return 0; - - /* Only 12 bit in use*/ - return hdr->common.ucode_version; -} diff --git a/drivers/gpu/drm/radeon/radeon_kfd.h b/drivers/gpu/drm/radeon/radeon_kfd.h deleted file mode 100644 index 9df1fea8e971..000000000000 --- a/drivers/gpu/drm/radeon/radeon_kfd.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - */ - -/* - * radeon_kfd.h defines the private interface between the - * AMD kernel graphics drivers and the AMD KFD. - */ - -#ifndef RADEON_KFD_H_INCLUDED -#define RADEON_KFD_H_INCLUDED - -#include -#include "kgd_kfd_interface.h" - -struct radeon_device; - -int radeon_kfd_init(void); -void radeon_kfd_fini(void); - -void radeon_kfd_suspend(struct radeon_device *rdev); -int radeon_kfd_resume(struct radeon_device *rdev); -void radeon_kfd_interrupt(struct radeon_device *rdev, - const void *ih_ring_entry); -void radeon_kfd_device_probe(struct radeon_device *rdev); -void radeon_kfd_device_init(struct radeon_device *rdev); -void radeon_kfd_device_fini(struct radeon_device *rdev); - -#endif /* RADEON_KFD_H_INCLUDED */ diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index dfee8f7d94ae..cde037f213d7 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -34,8 +34,6 @@ #include #include -#include "radeon_kfd.h" - #if defined(CONFIG_VGA_SWITCHEROO) bool radeon_has_atpx(void); #else @@ -68,8 +66,6 @@ void radeon_driver_unload_kms(struct drm_device *dev) pm_runtime_forbid(dev->dev); } - radeon_kfd_device_fini(rdev); - radeon_acpi_fini(rdev); radeon_modeset_fini(rdev); @@ -174,9 +170,6 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) "Error during ACPI methods call\n"); } - radeon_kfd_device_probe(rdev); - radeon_kfd_device_init(rdev); - if (radeon_is_px(dev)) { pm_runtime_use_autosuspend(dev->dev); pm_runtime_set_autosuspend_delay(dev->dev, 5000); -- cgit v1.2.3 From d18d1a5ac811d12f7ebc1129230312b5f2c50cb8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 31 Oct 2017 11:55:35 +0000 Subject: drm: Require __GFP_NOFAIL for the legacy drm_modeset_lock_all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To acquire all modeset locks requires a ww_ctx to be allocated. As this is the legacy path and the allocation small, to reduce the changes required (and complex untested error handling) to the legacy drivers, we simply assume that the allocation succeeds. At present, it relies on the too-small-to-fail rule, but syzbot found that by injecting a failure here we would hit the WARN. Document that this allocation must succeed with __GFP_NOFAIL. Signed-off-by: Chris Wilson Cc: Daniel Vetter Reported-by: syzbot Signed-off-by: Daniel Vetter Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171031115535.15166-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_modeset_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index e123497da0ca..963e23db0fe7 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -93,7 +93,7 @@ void drm_modeset_lock_all(struct drm_device *dev) struct drm_modeset_acquire_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL); if (WARN_ON(!ctx)) return; -- cgit v1.2.3 From 4d98e5ee6084f6d7bc578c5d5f86de7156aaa4cb Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 30 Oct 2017 14:57:43 +0100 Subject: drm/ttm: once more fix ttm_buffer_object_transfer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the mutex is locked just in the moment we copy it we end up with a warning that we release a locked mutex. Fix this by properly reinitializing the mutex. Signed-off-by: Christian König Reviewed-by: Alex Deucher CC: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo_util.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 78cb99be7146..e7a519f1849b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -474,6 +474,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, INIT_LIST_HEAD(&fbo->lru); INIT_LIST_HEAD(&fbo->swap); INIT_LIST_HEAD(&fbo->io_reserve_lru); + mutex_init(&fbo->wu_mutex); fbo->moving = NULL; drm_vma_node_reset(&fbo->vma_node); atomic_set(&fbo->cpu_writers, 0); -- cgit v1.2.3 From a695e43712242c354748e9bae5d137d4337a7694 Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 31 Oct 2017 09:36:13 +0100 Subject: drm/amdgpu: fix error handling in amdgpu_bo_do_create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bo structure is freed up in case of an error, so we can't do any accounting if that happens. Signed-off-by: Christian König Reviewed-by: Michel Dänzer CC: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 8b4ed8a98a18..ea25164e7f4b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -369,6 +369,9 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type, &bo->placement, page_align, !kernel, NULL, acc_size, sg, resv, &amdgpu_ttm_bo_destroy); + if (unlikely(r != 0)) + return r; + bytes_moved = atomic64_read(&adev->num_bytes_moved) - initial_bytes_moved; if (adev->mc.visible_vram_size < adev->mc.real_vram_size && @@ -378,9 +381,6 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, else amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0); - if (unlikely(r != 0)) - return r; - if (kernel) bo->tbo.priority = 1; -- cgit v1.2.3 From bbb4d8d9ee81714b98c25df39a1ed90fa075e90a Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Mon, 23 Oct 2017 10:30:57 +0800 Subject: drm/ttm:fix memory leak due to individualize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit after individualize we need manually call reservation_object_fini() if all fences on resv signaled during test, otherwise kmemory leak Signed-off-by: Monk Liu Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d79607a1187c..379ec41d2c69 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -457,8 +457,11 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) if (reservation_object_test_signaled_rcu(&bo->ttm_resv, true)) { ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); - if (bo->resv != &bo->ttm_resv) + if (bo->resv != &bo->ttm_resv) { reservation_object_unlock(&bo->ttm_resv); + reservation_object_fini(&bo->ttm_resv); + } + ttm_bo_cleanup_memtype_use(bo); return; } -- cgit v1.2.3 From 4f626a4ac8f57ddabf06d03870adab91e463217f Mon Sep 17 00:00:00 2001 From: Roman Kapl Date: Mon, 30 Oct 2017 11:56:13 +0100 Subject: drm/radeon: fix atombios on big endian The function for byteswapping the data send to/from atombios was buggy for num_bytes not divisible by four. The function must be aware of the fact that after byte-swapping the u32 units, valid bytes might end up after the num_bytes boundary. This patch was tested on kernel 3.12 and allowed us to sucesfully use DisplayPort on and Radeon SI card. Namely it fixed the link training and EDID readout. The function is patched both in radeon and amd drivers, since the functions and the fixes are identical. Signed-off-by: Roman Kapl Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 38 +++++++++++++--------------- drivers/gpu/drm/radeon/atombios_dp.c | 38 +++++++++++++--------------- 2 files changed, 36 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index f66d33e4baca..f450b69323fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -1766,34 +1766,32 @@ bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev) return true; } -/* Atom needs data in little endian format - * so swap as appropriate when copying data to - * or from atom. Note that atom operates on - * dw units. +/* Atom needs data in little endian format so swap as appropriate when copying + * data to or from atom. Note that atom operates on dw units. + * + * Use to_le=true when sending data to atom and provide at least + * ALIGN(num_bytes,4) bytes in the dst buffer. + * + * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4) + * byes in the src buffer. */ void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) { #ifdef __BIG_ENDIAN - u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ - u32 *dst32, *src32; + u32 src_tmp[5], dst_tmp[5]; int i; + u8 align_num_bytes = ALIGN(num_bytes, 4); - memcpy(src_tmp, src, num_bytes); - src32 = (u32 *)src_tmp; - dst32 = (u32 *)dst_tmp; if (to_le) { - for (i = 0; i < ((num_bytes + 3) / 4); i++) - dst32[i] = cpu_to_le32(src32[i]); - memcpy(dst, dst_tmp, num_bytes); + memcpy(src_tmp, src, num_bytes); + for (i = 0; i < align_num_bytes / 4; i++) + dst_tmp[i] = cpu_to_le32(src_tmp[i]); + memcpy(dst, dst_tmp, align_num_bytes); } else { - u8 dws = num_bytes & ~3; - for (i = 0; i < ((num_bytes + 3) / 4); i++) - dst32[i] = le32_to_cpu(src32[i]); - memcpy(dst, dst_tmp, dws); - if (num_bytes % 4) { - for (i = 0; i < (num_bytes % 4); i++) - dst[dws+i] = dst_tmp[dws+i]; - } + memcpy(src_tmp, src, align_num_bytes); + for (i = 0; i < align_num_bytes / 4; i++) + dst_tmp[i] = le32_to_cpu(src_tmp[i]); + memcpy(dst, dst_tmp, num_bytes); } #else memcpy(dst, src, num_bytes); diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index a904c80c30e6..3e798593e042 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -45,34 +45,32 @@ static char *pre_emph_names[] = { /***** radeon AUX functions *****/ -/* Atom needs data in little endian format - * so swap as appropriate when copying data to - * or from atom. Note that atom operates on - * dw units. +/* Atom needs data in little endian format so swap as appropriate when copying + * data to or from atom. Note that atom operates on dw units. + * + * Use to_le=true when sending data to atom and provide at least + * ALIGN(num_bytes,4) bytes in the dst buffer. + * + * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4) + * byes in the src buffer. */ void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) { #ifdef __BIG_ENDIAN - u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ - u32 *dst32, *src32; + u32 src_tmp[5], dst_tmp[5]; int i; + u8 align_num_bytes = ALIGN(num_bytes, 4); - memcpy(src_tmp, src, num_bytes); - src32 = (u32 *)src_tmp; - dst32 = (u32 *)dst_tmp; if (to_le) { - for (i = 0; i < ((num_bytes + 3) / 4); i++) - dst32[i] = cpu_to_le32(src32[i]); - memcpy(dst, dst_tmp, num_bytes); + memcpy(src_tmp, src, num_bytes); + for (i = 0; i < align_num_bytes / 4; i++) + dst_tmp[i] = cpu_to_le32(src_tmp[i]); + memcpy(dst, dst_tmp, align_num_bytes); } else { - u8 dws = num_bytes & ~3; - for (i = 0; i < ((num_bytes + 3) / 4); i++) - dst32[i] = le32_to_cpu(src32[i]); - memcpy(dst, dst_tmp, dws); - if (num_bytes % 4) { - for (i = 0; i < (num_bytes % 4); i++) - dst[dws+i] = dst_tmp[dws+i]; - } + memcpy(src_tmp, src, align_num_bytes); + for (i = 0; i < align_num_bytes / 4; i++) + dst_tmp[i] = le32_to_cpu(src_tmp[i]); + memcpy(dst, dst_tmp, num_bytes); } #else memcpy(dst, src, num_bytes); -- cgit v1.2.3 From a2f042430784d86eb2b7a6d2a869f552da30edba Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 15 Aug 2017 15:14:25 +0100 Subject: drm/hisilicon: Ensure LDI regs are properly configured. This patch fixes the following soft lockup: BUG: soft lockup - CPU#0 stuck for 23s! [weston:307] On weston idle-timeout the IP is powered down and reset asserted. On weston resume we get a massive vblank IRQ storm due to the LDI registers having lost some state. This state loss is caused by ade_crtc_atomic_begin() not calling ade_ldi_set_mode(). With this patch applied resuming from Weston idle-timeout works well. Signed-off-by: Peter Griffin Tested-by: John Stultz Cc: stable@vger.kernel.org Reviewed-by: Xinliang Liu Signed-off-by: Xinliang Liu --- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index 9823477b1855..2269be91f3e1 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -534,9 +534,12 @@ static void ade_crtc_atomic_begin(struct drm_crtc *crtc, { struct ade_crtc *acrtc = to_ade_crtc(crtc); struct ade_hw_ctx *ctx = acrtc->ctx; + struct drm_display_mode *mode = &crtc->state->mode; + struct drm_display_mode *adj_mode = &crtc->state->adjusted_mode; if (!ctx->power_on) (void)ade_power_up(ctx); + ade_ldi_set_mode(acrtc, mode, adj_mode); } static void ade_crtc_atomic_flush(struct drm_crtc *crtc, -- cgit v1.2.3 From 39ae0d3e561d360e41f2a3d1c427d5d9142468da Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 3 Aug 2017 13:50:48 +0200 Subject: drm/msm: use %z format modifier for printing size_t The return type of ARRAY_SIZE() is size_t, so we have to use %zu instead of %lu to avoid this warning: drivers/gpu/drm/msm/msm_gpu.c: In function 'msm_gpu_init': drivers/gpu/drm/msm/msm_gpu.c:742:31: error: format '%lu' expects argument of type 'long unsigned int', but argument 7 has type 'unsigned int' [-Werror=format=] The warning it otherwise harmless as size_t is always the same size as unsigned long in all supported architectures, but gcc doesn't know that. Fixes: c2fceabca6d5 ("drm/msm: Support multiple ringbuffers") Signed-off-by: Arnd Bergmann Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 06bf2cc9afa9..8d4477818ec2 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -777,7 +777,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, } if (nr_rings > ARRAY_SIZE(gpu->rb)) { - DRM_DEV_INFO_ONCE(drm->dev, "Only creating %lu ringbuffers\n", + DRM_DEV_INFO_ONCE(drm->dev, "Only creating %zu ringbuffers\n", ARRAY_SIZE(gpu->rb)); nr_rings = ARRAY_SIZE(gpu->rb); } -- cgit v1.2.3 From ab40cba30333cc264cf2731626565c3e1f29e4d1 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 1 Nov 2017 19:21:26 -0400 Subject: drm/amdkfd: Clean up the data structure in kfd_process A list of per-process queues is maintained in the kfd_process_queue_manager, so the queues array in kfd_process is redundant and in fact unused. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 6 ------ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 18 ------------------ 2 files changed, 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 6a91a60c64cf..78b5d61780cb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -527,12 +527,6 @@ struct kfd_process { struct process_queue_manager pqm; - /* The process's queues. */ - size_t queue_array_size; - - /* Size is queue_array_size, up to MAX_PROCESS_QUEUES. */ - struct kfd_queue **queues; - /*Is the user space process 32 bit?*/ bool is_32bit_user_mode; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 695fa2ae8e5b..946f4d68947f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -34,13 +34,6 @@ struct mm_struct; #include "kfd_priv.h" #include "kfd_dbgmgr.h" -/* - * Initial size for the array of queues. - * The allocated size is doubled each time - * it is exceeded up to MAX_PROCESS_QUEUES. - */ -#define INITIAL_QUEUE_ARRAY_SIZE 16 - /* * List of struct kfd_process (field kfd_process). * Unique/indexed by mm_struct* @@ -187,8 +180,6 @@ static void kfd_process_wq_release(struct work_struct *work) mutex_destroy(&p->mutex); - kfree(p->queues); - kfree(p); kfree(work); @@ -270,11 +261,6 @@ static struct kfd_process *create_process(const struct task_struct *thread) if (!process) goto err_alloc_process; - process->queues = kmalloc_array(INITIAL_QUEUE_ARRAY_SIZE, - sizeof(process->queues[0]), GFP_KERNEL); - if (!process->queues) - goto err_alloc_queues; - process->pasid = kfd_pasid_alloc(); if (process->pasid == 0) goto err_alloc_pasid; @@ -297,8 +283,6 @@ static struct kfd_process *create_process(const struct task_struct *thread) process->lead_thread = thread->group_leader; - process->queue_array_size = INITIAL_QUEUE_ARRAY_SIZE; - INIT_LIST_HEAD(&process->per_device_data); kfd_event_init_process(process); @@ -327,8 +311,6 @@ err_mmu_notifier: err_alloc_doorbells: kfd_pasid_free(process->pasid); err_alloc_pasid: - kfree(process->queues); -err_alloc_queues: kfree(process); err_alloc_process: return ERR_PTR(err); -- cgit v1.2.3 From bba9662db79cb21c532bff2e83843037a616ed86 Mon Sep 17 00:00:00 2001 From: Jay Cornwall Date: Wed, 1 Nov 2017 19:21:27 -0400 Subject: drm/amdkfd: Disable CP/SDMA ring/doorbell in MQD The MQD represents an inactive context and should not have ring or doorbell enable bits set. Doing so interferes with HWS which streams the MQD onto the HQD. If enable bits are set this activates the ring or doorbell before the HQD is fully configured. Signed-off-by: Jay Cornwall Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 34 +++++++----------------- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 7 ++--- 2 files changed, 11 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index 44ffd23348fc..4859d263fa2a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c @@ -189,12 +189,9 @@ static int update_mqd(struct mqd_manager *mm, void *mqd, if (q->format == KFD_QUEUE_FORMAT_AQL) m->cp_hqd_pq_control |= NO_UPDATE_RPTR; - q->is_active = false; - if (q->queue_size > 0 && + q->is_active = (q->queue_size > 0 && q->queue_address != 0 && - q->queue_percent > 0) { - q->is_active = true; - } + q->queue_percent > 0); return 0; } @@ -215,24 +212,17 @@ static int update_mqd_sdma(struct mqd_manager *mm, void *mqd, m->sdma_rlc_rb_base_hi = upper_32_bits(q->queue_address >> 8); m->sdma_rlc_rb_rptr_addr_lo = lower_32_bits((uint64_t)q->read_ptr); m->sdma_rlc_rb_rptr_addr_hi = upper_32_bits((uint64_t)q->read_ptr); - m->sdma_rlc_doorbell = q->doorbell_off << - SDMA0_RLC0_DOORBELL__OFFSET__SHIFT | - 1 << SDMA0_RLC0_DOORBELL__ENABLE__SHIFT; + m->sdma_rlc_doorbell = + q->doorbell_off << SDMA0_RLC0_DOORBELL__OFFSET__SHIFT; m->sdma_rlc_virtual_addr = q->sdma_vm_addr; m->sdma_engine_id = q->sdma_engine_id; m->sdma_queue_id = q->sdma_queue_id; - q->is_active = false; - if (q->queue_size > 0 && + q->is_active = (q->queue_size > 0 && q->queue_address != 0 && - q->queue_percent > 0) { - m->sdma_rlc_rb_cntl |= - 1 << SDMA0_RLC0_RB_CNTL__RB_ENABLE__SHIFT; - - q->is_active = true; - } + q->queue_percent > 0); return 0; } @@ -359,19 +349,13 @@ static int update_mqd_hiq(struct mqd_manager *mm, void *mqd, m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8); m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr); m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr); - m->cp_hqd_pq_doorbell_control = DOORBELL_EN | - DOORBELL_OFFSET(q->doorbell_off); + m->cp_hqd_pq_doorbell_control = DOORBELL_OFFSET(q->doorbell_off); m->cp_hqd_vmid = q->vmid; - m->cp_hqd_active = 0; - q->is_active = false; - if (q->queue_size > 0 && + q->is_active = (q->queue_size > 0 && q->queue_address != 0 && - q->queue_percent > 0) { - m->cp_hqd_active = 1; - q->is_active = true; - } + q->queue_percent > 0); return 0; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c index 73cbfe186dd2..4ea854f9007b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c @@ -163,12 +163,9 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd, 2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT; } - q->is_active = false; - if (q->queue_size > 0 && + q->is_active = (q->queue_size > 0 && q->queue_address != 0 && - q->queue_percent > 0) { - q->is_active = true; - } + q->queue_percent > 0); return 0; } -- cgit v1.2.3 From e2a8e99964ded3a156137c1a02832493ee727721 Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 1 Nov 2017 19:21:28 -0400 Subject: drm/amdkfd: Avoid calling amd_iommu_unbind_pasid() when suspending When kfd suspending on APU, we do not need to call amd_iommu_unbind_pasid(), because pasid will be unbound automatically when power goes off. On the other hand, calling amd_iommu_unbind_pasid() will trigger kfd_process_iommu_unbind_callback() if the process is not terminating. By design, kfd_process_iommu_unbind_callback() should only be called for process terminating. So we would rather not to call amd_iommu_unbind_pasid() when suspending. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 946f4d68947f..b81ad8164da6 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -423,29 +423,25 @@ int kfd_bind_processes_to_device(struct kfd_dev *dev) } /* - * Temporarily unbind currently bound processes from the device and - * mark them as PDD_BOUND_SUSPENDED. These processes will be restored - * to PDD_BOUND state in kfd_bind_processes_to_device. + * Mark currently bound processes as PDD_BOUND_SUSPENDED. These + * processes will be restored to PDD_BOUND state in + * kfd_bind_processes_to_device. */ void kfd_unbind_processes_from_device(struct kfd_dev *dev) { struct kfd_process_device *pdd; struct kfd_process *p; - unsigned int temp, temp_bound, temp_pasid; + unsigned int temp; int idx = srcu_read_lock(&kfd_processes_srcu); hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) { mutex_lock(&p->mutex); pdd = kfd_get_process_device_data(dev, p); - temp_bound = pdd->bound; - temp_pasid = p->pasid; + if (pdd->bound == PDD_BOUND) pdd->bound = PDD_BOUND_SUSPENDED; mutex_unlock(&p->mutex); - - if (temp_bound == PDD_BOUND) - amd_iommu_unbind_pasid(dev->pdev, temp_pasid); } srcu_read_unlock(&kfd_processes_srcu, idx); -- cgit v1.2.3 From 062c5672d5f66963f6c87249a38226d0e70b1c4b Mon Sep 17 00:00:00 2001 From: Yair Shachar Date: Wed, 1 Nov 2017 19:21:29 -0400 Subject: drm/amdkfd: Fix debug unregister procedure on process termination Take the dbgmgr lock and unregister before destroying the debug manager. Do this before destroying the queues. v2: Correct locking order in kfd_ioctl_dbg_register to ake sure the process mutex and dbgmgr mutex are always taken in the same order. Signed-off-by: Yair Shachar Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 4 ++-- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 37 +++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index a25321ff448f..505d39156acd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -450,8 +450,8 @@ static int kfd_ioctl_dbg_register(struct file *filep, return -EINVAL; } - mutex_lock(kfd_get_dbgmgr_mutex()); mutex_lock(&p->mutex); + mutex_lock(kfd_get_dbgmgr_mutex()); /* * make sure that we have pdd, if this the first queue created for @@ -479,8 +479,8 @@ static int kfd_ioctl_dbg_register(struct file *filep, } out: - mutex_unlock(&p->mutex); mutex_unlock(kfd_get_dbgmgr_mutex()); + mutex_unlock(&p->mutex); return status; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index b81ad8164da6..db08f8f53d4b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -224,17 +224,26 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, mutex_lock(&p->mutex); + /* Iterate over all process device data structures and if the + * pdd is in debug mode, we should first force unregistration, + * then we will be able to destroy the queues + */ + list_for_each_entry(pdd, &p->per_device_data, per_device_list) { + struct kfd_dev *dev = pdd->dev; + + mutex_lock(kfd_get_dbgmgr_mutex()); + if (dev && dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) { + if (!kfd_dbgmgr_unregister(dev->dbgmgr, p)) { + kfd_dbgmgr_destroy(dev->dbgmgr); + dev->dbgmgr = NULL; + } + } + mutex_unlock(kfd_get_dbgmgr_mutex()); + } + kfd_process_dequeue_from_all_devices(p); pqm_uninit(&p->pqm); - /* Iterate over all process device data structure and check - * if we should delete debug managers - */ - list_for_each_entry(pdd, &p->per_device_data, per_device_list) - if ((pdd->dev->dbgmgr) && - (pdd->dev->dbgmgr->pasid == p->pasid)) - kfd_dbgmgr_destroy(pdd->dev->dbgmgr); - mutex_unlock(&p->mutex); /* @@ -463,8 +472,16 @@ void kfd_process_iommu_unbind_callback(struct kfd_dev *dev, unsigned int pasid) pr_debug("Unbinding process %d from IOMMU\n", pasid); - if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) - kfd_dbgmgr_destroy(dev->dbgmgr); + mutex_lock(kfd_get_dbgmgr_mutex()); + + if (dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) { + if (!kfd_dbgmgr_unregister(dev->dbgmgr, p)) { + kfd_dbgmgr_destroy(dev->dbgmgr); + dev->dbgmgr = NULL; + } + } + + mutex_unlock(kfd_get_dbgmgr_mutex()); pdd = kfd_get_process_device_data(dev, p); if (pdd) -- cgit v1.2.3 From 5a29ad6b9e0899cd17988895fa64fd3e9408ab8e Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Wed, 1 Nov 2017 19:21:30 -0400 Subject: drm/amdkfd: Register/Deregister process on qpd resolution Process registration needs to happen on each device. So use per-device queue lists to determine when to register/deregister the process. Signed-off-by: Ben Goz Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 5129dc139219..2bec902fc939 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -177,7 +177,8 @@ int pqm_create_queue(struct process_queue_manager *pqm, if (retval != 0) return retval; - if (list_empty(&pqm->queues)) { + if (list_empty(&pdd->qpd.queues_list) && + list_empty(&pdd->qpd.priv_queue_list)) { pdd->qpd.pqm = pqm; dev->dqm->ops.register_process(dev->dqm, &pdd->qpd); } @@ -248,7 +249,8 @@ err_create_queue: err_allocate_pqn: /* check if queues list is empty unregister process from device */ clear_bit(*qid, pqm->queue_slot_bitmap); - if (list_empty(&pqm->queues)) + if (list_empty(&pdd->qpd.queues_list) && + list_empty(&pdd->qpd.priv_queue_list)) dev->dqm->ops.unregister_process(dev->dqm, &pdd->qpd); return retval; } @@ -302,7 +304,8 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid) kfree(pqn); clear_bit(qid, pqm->queue_slot_bitmap); - if (list_empty(&pqm->queues)) + if (list_empty(&pdd->qpd.queues_list) && + list_empty(&pdd->qpd.priv_queue_list)) dqm->ops.unregister_process(dqm, &pdd->qpd); return retval; -- cgit v1.2.3 From bfd5e378a98d0387b45a4864528a11b65d038f0c Mon Sep 17 00:00:00 2001 From: Yong Zhao Date: Wed, 1 Nov 2017 19:21:31 -0400 Subject: drm/amdkfd: Cleanup DQM ASIC-specific ops Remove empty initialize function. Rename register_process to update_qpd to avoid confusion with the non-ASIC-specific register_process. Shorten ops_asic_specific to asic_ops. Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 19 +++++++------------ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 11 ++++++----- .../drm/amd/amdkfd/kfd_device_queue_manager_cik.c | 20 +++++++------------- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c | 20 +++++++------------- 4 files changed, 27 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index da3b74315acf..45b98dd5b785 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -467,7 +467,7 @@ static int register_process(struct device_queue_manager *dqm, mutex_lock(&dqm->lock); list_add(&n->list, &dqm->queues); - retval = dqm->ops_asic_specific.register_process(dqm, qpd); + retval = dqm->asic_ops.update_qpd(dqm, qpd); dqm->processes_count++; @@ -629,7 +629,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id); pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id); - dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd); + dqm->asic_ops.init_sdma_vm(dqm, q, qpd); retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, &q->gart_mqd_addr, &q->properties); if (retval) @@ -696,8 +696,6 @@ static int set_sched_resources(struct device_queue_manager *dqm) static int initialize_cpsch(struct device_queue_manager *dqm) { - int retval; - pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm)); mutex_init(&dqm->lock); @@ -706,11 +704,8 @@ static int initialize_cpsch(struct device_queue_manager *dqm) dqm->sdma_queue_count = 0; dqm->active_runlist = false; dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1; - retval = dqm->ops_asic_specific.initialize(dqm); - if (retval) - mutex_destroy(&dqm->lock); - return retval; + return 0; } static int start_cpsch(struct device_queue_manager *dqm) @@ -850,7 +845,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, goto out; } - dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd); + dqm->asic_ops.init_sdma_vm(dqm, q, qpd); retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, &q->gart_mqd_addr, &q->properties); if (retval) @@ -1095,7 +1090,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm, qpd->sh_mem_ape1_limit = limit >> 16; } - retval = dqm->ops_asic_specific.set_cache_memory_policy( + retval = dqm->asic_ops.set_cache_memory_policy( dqm, qpd, default_policy, @@ -1270,11 +1265,11 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) switch (dev->device_info->asic_family) { case CHIP_CARRIZO: - device_queue_manager_init_vi(&dqm->ops_asic_specific); + device_queue_manager_init_vi(&dqm->asic_ops); break; case CHIP_KAVERI: - device_queue_manager_init_cik(&dqm->ops_asic_specific); + device_queue_manager_init_cik(&dqm->asic_ops); break; default: WARN(1, "Unexpected ASIC family %u", diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 31c2b1f9d320..5b77cb69f732 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -128,9 +128,8 @@ struct device_queue_manager_ops { }; struct device_queue_manager_asic_ops { - int (*register_process)(struct device_queue_manager *dqm, + int (*update_qpd)(struct device_queue_manager *dqm, struct qcm_process_device *qpd); - int (*initialize)(struct device_queue_manager *dqm); bool (*set_cache_memory_policy)(struct device_queue_manager *dqm, struct qcm_process_device *qpd, enum cache_policy default_policy, @@ -156,7 +155,7 @@ struct device_queue_manager_asic_ops { struct device_queue_manager { struct device_queue_manager_ops ops; - struct device_queue_manager_asic_ops ops_asic_specific; + struct device_queue_manager_asic_ops asic_ops; struct mqd_manager *mqds[KFD_MQD_TYPE_MAX]; struct packet_manager packets; @@ -179,8 +178,10 @@ struct device_queue_manager { bool active_runlist; }; -void device_queue_manager_init_cik(struct device_queue_manager_asic_ops *ops); -void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops); +void device_queue_manager_init_cik( + struct device_queue_manager_asic_ops *asic_ops); +void device_queue_manager_init_vi( + struct device_queue_manager_asic_ops *asic_ops); void program_sh_mem_settings(struct device_queue_manager *dqm, struct qcm_process_device *qpd); unsigned int get_queues_num(struct device_queue_manager *dqm); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c index 72c3cbabc0a7..28e48c90c596 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c @@ -32,18 +32,17 @@ static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm, enum cache_policy alternate_policy, void __user *alternate_aperture_base, uint64_t alternate_aperture_size); -static int register_process_cik(struct device_queue_manager *dqm, +static int update_qpd_cik(struct device_queue_manager *dqm, struct qcm_process_device *qpd); -static int initialize_cpsch_cik(struct device_queue_manager *dqm); static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q, struct qcm_process_device *qpd); -void device_queue_manager_init_cik(struct device_queue_manager_asic_ops *ops) +void device_queue_manager_init_cik( + struct device_queue_manager_asic_ops *asic_ops) { - ops->set_cache_memory_policy = set_cache_memory_policy_cik; - ops->register_process = register_process_cik; - ops->initialize = initialize_cpsch_cik; - ops->init_sdma_vm = init_sdma_vm; + asic_ops->set_cache_memory_policy = set_cache_memory_policy_cik; + asic_ops->update_qpd = update_qpd_cik; + asic_ops->init_sdma_vm = init_sdma_vm; } static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble) @@ -99,7 +98,7 @@ static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm, return true; } -static int register_process_cik(struct device_queue_manager *dqm, +static int update_qpd_cik(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { struct kfd_process_device *pdd; @@ -148,8 +147,3 @@ static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q, q->properties.sdma_vm_addr = value; } - -static int initialize_cpsch_cik(struct device_queue_manager *dqm) -{ - return 0; -} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c index 40e9ddd096cd..2fbce57a2f21 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c @@ -33,18 +33,17 @@ static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, enum cache_policy alternate_policy, void __user *alternate_aperture_base, uint64_t alternate_aperture_size); -static int register_process_vi(struct device_queue_manager *dqm, +static int update_qpd_vi(struct device_queue_manager *dqm, struct qcm_process_device *qpd); -static int initialize_cpsch_vi(struct device_queue_manager *dqm); static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q, struct qcm_process_device *qpd); -void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops) +void device_queue_manager_init_vi( + struct device_queue_manager_asic_ops *asic_ops) { - ops->set_cache_memory_policy = set_cache_memory_policy_vi; - ops->register_process = register_process_vi; - ops->initialize = initialize_cpsch_vi; - ops->init_sdma_vm = init_sdma_vm; + asic_ops->set_cache_memory_policy = set_cache_memory_policy_vi; + asic_ops->update_qpd = update_qpd_vi; + asic_ops->init_sdma_vm = init_sdma_vm; } static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble) @@ -104,7 +103,7 @@ static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, return true; } -static int register_process_vi(struct device_queue_manager *dqm, +static int update_qpd_vi(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { struct kfd_process_device *pdd; @@ -160,8 +159,3 @@ static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q, q->properties.sdma_vm_addr = value; } - -static int initialize_cpsch_vi(struct device_queue_manager *dqm) -{ - return 0; -} -- cgit v1.2.3 From 096d1a3efc8b0914a4cfb1203c147ed597907191 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 1 Nov 2017 19:21:32 -0400 Subject: drm/amdkfd: Update queue_count before mapping queues map_queues_cpsch uses the queue_count to decide whether to upload a new runlist. So update the counter before calling it. Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 45b98dd5b785..e2fc4c5d42cd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -408,6 +408,17 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) retval = mqd->update_mqd(mqd, q->mqd, &q->properties); + /* + * check active state vs. the previous state and modify + * counter accordingly. map_queues_cpsch uses the + * dqm->queue_count to determine whether a new runlist must be + * uploaded. + */ + if (q->properties.is_active && !prev_active) + dqm->queue_count++; + else if (!q->properties.is_active && prev_active) + dqm->queue_count--; + if (sched_policy != KFD_SCHED_POLICY_NO_HWS) retval = map_queues_cpsch(dqm); else if (sched_policy == KFD_SCHED_POLICY_NO_HWS && @@ -417,15 +428,6 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue, &q->properties, q->process->mm); - /* - * check active state vs. the previous state - * and modify counter accordingly - */ - if (q->properties.is_active && !prev_active) - dqm->queue_count++; - else if (!q->properties.is_active && prev_active) - dqm->queue_count--; - out_unlock: mutex_unlock(&dqm->lock); return retval; -- cgit v1.2.3 From 894a8293aaa702a5aef758bc069162a671ca7a07 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Wed, 1 Nov 2017 19:21:33 -0400 Subject: drm/amdkfd: Minor cleanups These were missed previously when rebasing changes for upstreaming. v2: Remove redundant sched_policy conditions Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 10 ++++------ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 ++ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index e2fc4c5d42cd..e202921c150e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -389,12 +389,11 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) if (sched_policy != KFD_SCHED_POLICY_NO_HWS) { retval = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); - if (retval != 0) { + if (retval) { pr_err("unmap queue failed\n"); goto out_unlock; } - } else if (sched_policy == KFD_SCHED_POLICY_NO_HWS && - prev_active && + } else if (prev_active && (q->properties.type == KFD_QUEUE_TYPE_COMPUTE || q->properties.type == KFD_QUEUE_TYPE_SDMA)) { retval = mqd->destroy_mqd(mqd, q->mqd, @@ -421,8 +420,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) if (sched_policy != KFD_SCHED_POLICY_NO_HWS) retval = map_queues_cpsch(dqm); - else if (sched_policy == KFD_SCHED_POLICY_NO_HWS && - q->properties.is_active && + else if (q->properties.is_active && (q->properties.type == KFD_QUEUE_TYPE_COMPUTE || q->properties.type == KFD_QUEUE_TYPE_SDMA)) retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue, @@ -832,7 +830,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { retval = allocate_sdma_queue(dqm, &q->sdma_id); - if (retval != 0) + if (retval) goto out; q->properties.sdma_queue_id = q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 78b5d61780cb..9e4134c5b481 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -507,6 +507,8 @@ struct kfd_process { * In any process, the thread that started main() is the lead * thread and outlives the rest. * It is here because amd_iommu_bind_pasid wants a task_struct. + * It can also be used for safely getting a reference to the + * mm_struct of the process. */ struct task_struct *lead_thread; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index db08f8f53d4b..1f5ccd28bd41 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -416,7 +416,7 @@ int kfd_bind_processes_to_device(struct kfd_dev *dev) err = amd_iommu_bind_pasid(dev->pdev, p->pasid, p->lead_thread); if (err < 0) { - pr_err("unexpected pasid %d binding failure\n", + pr_err("Unexpected pasid %d binding failure\n", p->pasid); mutex_unlock(&p->mutex); break; -- cgit v1.2.3 From 24738d7c8750784e5660bd200f0cc2643499417a Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Tue, 31 Oct 2017 19:45:11 +0800 Subject: drm/amdgpu:add fw-vram-usage for atomfirmware otherwise PF & VF exchange is broken Signed-off-by: Monk Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index f9ffe8ef0cd6..ff8efd0f8fd5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -71,19 +71,33 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) struct atom_context *ctx = adev->mode_info.atom_context; int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, vram_usagebyfirmware); + struct vram_usagebyfirmware_v2_1 * firmware_usage; + uint32_t start_addr, size; uint16_t data_offset; int usage_bytes = 0; if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { - struct vram_usagebyfirmware_v2_1 *firmware_usage = - (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); - + firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n", le32_to_cpu(firmware_usage->start_address_in_kb), le16_to_cpu(firmware_usage->used_by_firmware_in_kb), le16_to_cpu(firmware_usage->used_by_driver_in_kb)); - usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) * 1024; + start_addr = le32_to_cpu(firmware_usage->start_address_in_kb); + size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb); + + if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == + (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << + ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { + /* Firmware request VRAM reservation for SR-IOV */ + adev->fw_vram_usage.start_offset = (start_addr & + (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; + adev->fw_vram_usage.size = size << 10; + /* Use the default scratch size */ + usage_bytes = 0; + } else { + usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10; + } } ctx->scratch_size_bytes = 0; if (usage_bytes == 0) -- cgit v1.2.3 From 7b38a49d75fb5e90512e63038449222c2ef651ef Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Tue, 31 Oct 2017 17:35:28 -0400 Subject: drm/amd/powerplay: fix memory leak of hardcoded pptable Signed-off-by: Eric Huang Reviewed-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 0f8b6dc853a5..c7e34128cbde 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -78,6 +78,9 @@ static int amd_powerplay_destroy(void *handle) { struct pp_instance *instance = (struct pp_instance *)handle; + kfree(instance->hwmgr->hardcode_pp_table); + instance->hwmgr->hardcode_pp_table = NULL; + kfree(instance->hwmgr); instance->hwmgr = NULL; -- cgit v1.2.3 From 710931c2be5a784c0651111f54bd083e3681c309 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Wed, 1 Nov 2017 16:52:08 +0800 Subject: drm/amd/powerplay: wrong control mode cause the fan spins faster unnecessarily The fan control mode can either be FDO_PWM_MODE_STATIC or FDO_PWM_MODE_STATIC_RPM. Setting it as AMD_FAN_CTRL_AUTO will cause the fan spin faster wrongly. This can be reproduced by: '# cat /sys/class/hwmon/hwmon0/pwm1 38 '# cat /sys/class/hwmon/hwmon0/pwm1_enable 2 '# echo "2" > /sys/class/hwmon/hwmon0/pwm1_enable '# cat /sys/class/hwmon/hwmon0/pwm1 122 The fan speed get faster wrongly even with its original mode echo back. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 203ef10cafdc..4239b98cf6db 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -4234,7 +4234,7 @@ static void vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode) vega10_fan_ctrl_stop_smc_fan_control(hwmgr); break; case AMD_FAN_CTRL_AUTO: - if (!vega10_fan_ctrl_set_static_mode(hwmgr, mode)) + if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) vega10_fan_ctrl_start_smc_fan_control(hwmgr); break; default: -- cgit v1.2.3 From d32656373857839c82e3941a9e26cf228ca319b3 Mon Sep 17 00:00:00 2001 From: Rhys Kidd Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/therm/gp100: initial implementation of new gp1xx temperature sensor v2: - add nv138 and drop nv13b chipsets (Ilia Mirkin) - refactor out status variable and instead mask tsensor (Ilia Mirkin) - switch SHADOWed state message away from nvkm_error() (Ilia Mirkin) - rename internal temperature variable (Karol Herbst) v3: - use nvkm_trace() for SHADOWed state message (Ben Skeggs) Signed-off-by: Rhys Kidd Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/subdev/therm.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 6 +++ drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c | 3 +- drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c | 56 ++++++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h index 1bfd93b85575..9841f076da2e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h @@ -97,4 +97,5 @@ int gt215_therm_new(struct nvkm_device *, int, struct nvkm_therm **); int gf119_therm_new(struct nvkm_device *, int, struct nvkm_therm **); int gm107_therm_new(struct nvkm_device *, int, struct nvkm_therm **); int gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **); +int gp100_therm_new(struct nvkm_device *, int, struct nvkm_therm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index e096a5d9c292..28fd4fa98635 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2169,6 +2169,7 @@ nv130_chipset = { .ltc = gp100_ltc_new, .mc = gp100_mc_new, .mmu = gf100_mmu_new, + .therm = gp100_therm_new, .secboot = gm200_secboot_new, .pci = gp100_pci_new, .pmu = gp100_pmu_new, @@ -2203,6 +2204,7 @@ nv132_chipset = { .ltc = gp100_ltc_new, .mc = gp100_mc_new, .mmu = gf100_mmu_new, + .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, @@ -2237,6 +2239,7 @@ nv134_chipset = { .ltc = gp100_ltc_new, .mc = gp100_mc_new, .mmu = gf100_mmu_new, + .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, @@ -2271,6 +2274,7 @@ nv136_chipset = { .ltc = gp100_ltc_new, .mc = gp100_mc_new, .mmu = gf100_mmu_new, + .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, @@ -2305,6 +2309,7 @@ nv137_chipset = { .ltc = gp100_ltc_new, .mc = gp100_mc_new, .mmu = gf100_mmu_new, + .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, @@ -2339,6 +2344,7 @@ nv138_chipset = { .ltc = gp100_ltc_new, .mc = gp100_mc_new, .mmu = gf100_mmu_new, + .therm = gp100_therm_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, .timer = gk20a_timer_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild index 2bafcc1d1818..7ba56b12badd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild @@ -12,3 +12,4 @@ nvkm-y += nvkm/subdev/therm/gt215.o nvkm-y += nvkm/subdev/therm/gf119.o nvkm-y += nvkm/subdev/therm/gm107.o nvkm-y += nvkm/subdev/therm/gm200.o +nvkm-y += nvkm/subdev/therm/gp100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c index 952a7cb0a59a..f27fc6d0d4c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c @@ -341,7 +341,8 @@ nvkm_therm_init(struct nvkm_subdev *subdev) { struct nvkm_therm *therm = nvkm_therm(subdev); - therm->func->init(therm); + if (therm->func->init) + therm->func->init(therm); if (therm->suspend >= 0) { /* restore the pwm value only when on manual or auto mode */ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c new file mode 100644 index 000000000000..9f0dea3f61dc --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Rhys Kidd + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: Rhys Kidd + */ +#include "priv.h" + +static int +gp100_temp_get(struct nvkm_therm *therm) +{ + struct nvkm_device *device = therm->subdev.device; + struct nvkm_subdev *subdev = &therm->subdev; + u32 tsensor = nvkm_rd32(device, 0x020460); + u32 inttemp = (tsensor & 0x0001fff8); + + /* device SHADOWed */ + if (tsensor & 0x40000000) + nvkm_trace(subdev, "reading temperature from SHADOWed sensor\n"); + + /* device valid */ + if (tsensor & 0x20000000) + return (inttemp >> 8); + else + return -ENODEV; +} + +static const struct nvkm_therm_func +gp100_therm = { + .temp_get = gp100_temp_get, + .program_alarms = nvkm_therm_program_alarms_polling, +}; + +int +gp100_therm_new(struct nvkm_device *device, int index, + struct nvkm_therm **ptherm) +{ + return nvkm_therm_new_(&gp100_therm, device, index, ptherm); +} -- cgit v1.2.3 From 451b58d2d03d2033f00d346fb0b0335e536ae5ae Mon Sep 17 00:00:00 2001 From: Rhys Kidd Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: Document nouveau support for Tegra in DRIVER_DESC nouveau supports the Tegra K1 and higher after the SoC-based GPUs converged with the main GeForce GPU families. v2: - Qualify that support is Tegra K1+ (Martin Peres) Signed-off-by: Rhys Kidd Reviewed-by: Martin Peres Acked-by: Pierre Moreau Acked-by: Thierry Reding Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 822fe1d4d35e..ec60d52790e3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -5,7 +5,7 @@ #define DRIVER_EMAIL "nouveau@lists.freedesktop.org" #define DRIVER_NAME "nouveau" -#define DRIVER_DESC "nVidia Riva/TNT/GeForce/Quadro/Tesla" +#define DRIVER_DESC "nVidia Riva/TNT/GeForce/Quadro/Tesla/Tegra K1+" #define DRIVER_DATE "20120801" #define DRIVER_MAJOR 1 -- cgit v1.2.3 From f5a5b5232b899c06626960b601d1943cc2fb21d9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: remove some useless semicolons Reported-by: Dave Airlie Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 189ed80e21ff..30483c5d27c3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -216,7 +216,7 @@ nvkm_device_tegra_fini(struct nvkm_device *device, bool suspend) if (tdev->irq) { free_irq(tdev->irq, tdev); tdev->irq = 0; - }; + } } static int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c index 23caef8df17f..73e463ed55c3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c @@ -99,7 +99,7 @@ nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense) rail->extdev_id = nvbios_rd08(bios, entry + 0x1); res_start = 0x5; break; - }; + } if (nvbios_extdev_parse(bios, rail->extdev_id, &extdev)) continue; @@ -115,7 +115,7 @@ nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense) default: rail->resistor_count = 0; break; - }; + } for (r = 0; r < rail->resistor_count; ++r) { rail->resistors[r].mohm = nvbios_rd08(bios, entry + res_start + r * 2); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 455da298227f..f2b1a3e75f17 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -66,7 +66,7 @@ nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) delta += (u64)len << vma->node->type; } r = r->next; - }; + } mmu->func->flush(vm); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index a4cb82495cee..b1b1f3626b96 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -87,7 +87,7 @@ nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend) if (pci->irq >= 0) { free_irq(pci->irq, pci); pci->irq = -1; - }; + } if (pci->agp.bridge) nvkm_agp_fini(pci); -- cgit v1.2.3 From 73cef6cee71b7a1029e4951a97095c2e4fee4be7 Mon Sep 17 00:00:00 2001 From: Jérémy Lefaure Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bios/init: use ARRAY_SIZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the ARRAY_SIZE macro improves the readability of the code. Also, it is useless to re-invent it. Found with Coccinelle with the following semantic patch: @r depends on (org || report)@ type T; T[] E; position p; @@ ( (sizeof(E)@p /sizeof(*E)) | (sizeof(E)@p /sizeof(E[...])) | (sizeof(E)@p /sizeof(T)) ) Reviewed-by: Thierry Reding Signed-off-by: Jérémy Lefaure Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c index b58ee99f7bfc..9cc10e438b3d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c @@ -36,6 +36,8 @@ #include #include +#include + #define bioslog(lvl, fmt, args...) do { \ nvkm_printk(init->subdev, lvl, info, "0x%08x[%c]: "fmt, \ init->offset, init_exec(init) ? \ @@ -2271,8 +2273,6 @@ static struct nvbios_init_opcode { [0xaa] = { init_reserved }, }; -#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0])) - int nvbios_exec(struct nvbios_init *init) { @@ -2281,7 +2281,8 @@ nvbios_exec(struct nvbios_init *init) init->nested++; while (init->offset) { u8 opcode = nvbios_rd08(bios, init->offset); - if (opcode >= init_opcode_nr || !init_opcode[opcode].exec) { + if (opcode >= ARRAY_SIZE(init_opcode) || + !init_opcode[opcode].exec) { error("unknown opcode 0x%02x\n", opcode); return -EINVAL; } -- cgit v1.2.3 From 3a0bc8cb9b102229ad26ae3788cef8c6c5273be1 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/kms: add 8.1Gbps DP link rate This was already done in dcb.c inside nvkm, but the other parser did not get the update. Signed-off-by: Ilia Mirkin Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index dd6fba55ad5d..c4ef3a0a737e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -1478,9 +1478,13 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, case 1: entry->dpconf.link_bw = 270000; break; - default: + case 2: entry->dpconf.link_bw = 540000; break; + case 3: + default: + entry->dpconf.link_bw = 810000; + break; } switch ((conf & 0x0f000000) >> 24) { case 0xf: -- cgit v1.2.3 From 9551efcf7664b73d881de7eb88e4626c9561b624 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/kms/nv50: prevent oops in failure paths Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index e4751f92b342..9cd5a53f85fa 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -510,6 +510,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, int ret; mutex_init(&dmac->lock); + INIT_LIST_HEAD(&dmac->ctxdma); dmac->ptr = dma_alloc_coherent(nvxx_device(device)->dev, PAGE_SIZE, &dmac->handle, GFP_KERNEL); @@ -556,7 +557,6 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, if (ret) return ret; - INIT_LIST_HEAD(&dmac->ctxdma); return ret; } -- cgit v1.2.3 From bbb10e639819e6a14e487ce14b3d8575767573b8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: fix handling of GART OOM on pre-NV50 chipsets The correct thing to do on OOM is to return 0 and set mm_node to NULL, otherwise TTM will assume some other kind of error, and not attempt to evict other buffers to make space. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_ttm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index b0ad7fcefcf5..ffc3458c89de 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -243,6 +243,10 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, ret = nvkm_vm_get(man->priv, reg->num_pages << 12, node->page_shift, NV_MEM_ACCESS_RW, &node->vma[0]); if (ret) { + if (ret == -ENOSPC) { + reg->mm_node = NULL; + ret = 0; + } kfree(node); return ret; } -- cgit v1.2.3 From 1f474be9a89e7848649034c8854c55996bb29459 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/object: separate oclass data out into its own header Want to be able to include this from core/device.h without pulling in core/object.h. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/object.h | 28 +------------------ drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h | 31 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h index 96dda350ada3..5a092ffb5abf 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h @@ -1,10 +1,8 @@ #ifndef __NVKM_OBJECT_H__ #define __NVKM_OBJECT_H__ -#include -#include +#include struct nvkm_event; struct nvkm_gpuobj; -struct nvkm_oclass; struct nvkm_object { const struct nvkm_object_func *func; @@ -66,28 +64,4 @@ bool nvkm_object_insert(struct nvkm_object *); void nvkm_object_remove(struct nvkm_object *); struct nvkm_object *nvkm_object_search(struct nvkm_client *, u64 object, const struct nvkm_object_func *); - -struct nvkm_sclass { - int minver; - int maxver; - s32 oclass; - const struct nvkm_object_func *func; - int (*ctor)(const struct nvkm_oclass *, void *data, u32 size, - struct nvkm_object **); -}; - -struct nvkm_oclass { - int (*ctor)(const struct nvkm_oclass *, void *data, u32 size, - struct nvkm_object **); - struct nvkm_sclass base; - const void *priv; - const void *engn; - u32 handle; - u8 route; - u64 token; - u64 object; - struct nvkm_client *client; - struct nvkm_object *parent; - struct nvkm_engine *engine; -}; #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h b/drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h new file mode 100644 index 000000000000..8e1b945d38f3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/oclass.h @@ -0,0 +1,31 @@ +#ifndef __NVKM_OCLASS_H__ +#define __NVKM_OCLASS_H__ +#include +#include +struct nvkm_oclass; +struct nvkm_object; + +struct nvkm_sclass { + int minver; + int maxver; + s32 oclass; + const struct nvkm_object_func *func; + int (*ctor)(const struct nvkm_oclass *, void *data, u32 size, + struct nvkm_object **); +}; + +struct nvkm_oclass { + int (*ctor)(const struct nvkm_oclass *, void *data, u32 size, + struct nvkm_object **); + struct nvkm_sclass base; + const void *priv; + const void *engn; + u32 handle; + u8 route; + u64 token; + u64 object; + struct nvkm_client *client; + struct nvkm_object *parent; + struct nvkm_engine *engine; +}; +#endif -- cgit v1.2.3 From 01326050391ceee2cf1b6c91c108414a35f40861 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/object: allow arguments to be passed to map function MMU will be needing this to specify kind info on BAR mappings. We have no userspace currently using these interfaces, so break the ABI instead of supporting both. NVIF version bump so any future use can be guarded. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv04/disp.c | 2 +- drivers/gpu/drm/nouveau/include/nvif/ioctl.h | 10 ++- drivers/gpu/drm/nouveau/include/nvif/object.h | 7 +- drivers/gpu/drm/nouveau/include/nvkm/core/object.h | 11 ++- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 2 +- drivers/gpu/drm/nouveau/nvif/object.c | 87 +++++++++++++++------- drivers/gpu/drm/nouveau/nvkm/core/ioctl.c | 12 ++- drivers/gpu/drm/nouveau/nvkm/core/object.c | 5 +- drivers/gpu/drm/nouveau/nvkm/core/oproxy.c | 6 +- drivers/gpu/drm/nouveau/nvkm/engine/device/user.c | 4 +- .../gpu/drm/nouveau/nvkm/engine/disp/channv50.c | 4 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 4 +- 13 files changed, 108 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index 5b9d549aa791..501d2d290e9c 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -48,7 +48,7 @@ nv04_display_create(struct drm_device *dev) if (!disp) return -ENOMEM; - nvif_object_map(&drm->client.device.object); + nvif_object_map(&drm->client.device.object, NULL, 0); nouveau_display(dev)->priv = disp; nouveau_display(dev)->dtor = nv04_display_destroy; diff --git a/drivers/gpu/drm/nouveau/include/nvif/ioctl.h b/drivers/gpu/drm/nouveau/include/nvif/ioctl.h index c5f5eb83a594..1886366457f1 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/ioctl.h +++ b/drivers/gpu/drm/nouveau/include/nvif/ioctl.h @@ -1,7 +1,7 @@ #ifndef __NVIF_IOCTL_H__ #define __NVIF_IOCTL_H__ -#define NVIF_VERSION_LATEST 0x0000000000000000ULL +#define NVIF_VERSION_LATEST 0x0000000000000100ULL struct nvif_ioctl_v0 { __u8 version; @@ -83,9 +83,13 @@ struct nvif_ioctl_wr_v0 { struct nvif_ioctl_map_v0 { /* nvif_ioctl ... */ __u8 version; - __u8 pad01[3]; - __u32 length; +#define NVIF_IOCTL_MAP_V0_IO 0x00 +#define NVIF_IOCTL_MAP_V0_VA 0x01 + __u8 type; + __u8 pad02[6]; __u64 handle; + __u64 length; + __u8 data[]; }; struct nvif_ioctl_unmap { diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h index 9e58b305b020..0b54261bdefe 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/object.h +++ b/drivers/gpu/drm/nouveau/include/nvif/object.h @@ -16,7 +16,7 @@ struct nvif_object { void *priv; /*XXX: hack */ struct { void __iomem *ptr; - u32 size; + u64 size; } map; }; @@ -29,7 +29,10 @@ void nvif_object_sclass_put(struct nvif_sclass **); u32 nvif_object_rd(struct nvif_object *, int, u64); void nvif_object_wr(struct nvif_object *, int, u64, u32); int nvif_object_mthd(struct nvif_object *, u32, void *, u32); -int nvif_object_map(struct nvif_object *); +int nvif_object_map_handle(struct nvif_object *, void *, u32, + u64 *handle, u64 *length); +void nvif_object_unmap_handle(struct nvif_object *); +int nvif_object_map(struct nvif_object *, void *, u32); void nvif_object_unmap(struct nvif_object *); #define nvif_handle(a) (unsigned long)(void *)(a) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h index 5a092ffb5abf..4797577d52ce 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h @@ -19,13 +19,19 @@ struct nvkm_object { struct rb_node node; }; +enum nvkm_object_map { + NVKM_OBJECT_MAP_IO, + NVKM_OBJECT_MAP_VA +}; + struct nvkm_object_func { void *(*dtor)(struct nvkm_object *); int (*init)(struct nvkm_object *); int (*fini)(struct nvkm_object *, bool suspend); int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size); int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **); - int (*map)(struct nvkm_object *, u64 *addr, u32 *size); + int (*map)(struct nvkm_object *, void *argv, u32 argc, + enum nvkm_object_map *, u64 *addr, u64 *size); int (*rd08)(struct nvkm_object *, u64 addr, u8 *data); int (*rd16)(struct nvkm_object *, u64 addr, u16 *data); int (*rd32)(struct nvkm_object *, u64 addr, u32 *data); @@ -50,7 +56,8 @@ int nvkm_object_init(struct nvkm_object *); int nvkm_object_fini(struct nvkm_object *, bool suspend); int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size); int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **); -int nvkm_object_map(struct nvkm_object *, u64 *addr, u32 *size); +int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc, + enum nvkm_object_map *, u64 *addr, u64 *size); int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8 *data); int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data); int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data); diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index dbc41fa86ee8..4af09e9be930 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -318,7 +318,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) struct nv_dma_v0 args = {}; int ret, i; - nvif_object_map(&chan->user); + nvif_object_map(&chan->user, NULL, 0); if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) { ret = nvif_notify_init(&chan->user, nouveau_channel_killed, diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 9cd5a53f85fa..1f3872f438c9 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -318,7 +318,7 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, ret = nvif_object_init(disp, 0, oclass[0], data, size, &chan->user); if (ret == 0) - nvif_object_map(&chan->user); + nvif_object_map(&chan->user, NULL, 0); nvif_object_sclass_put(&sclass); return ret; } diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index c3fb6a20f567..40adfe9b334b 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -166,46 +166,77 @@ nvif_object_mthd(struct nvif_object *object, u32 mthd, void *data, u32 size) } void -nvif_object_unmap(struct nvif_object *object) +nvif_object_unmap_handle(struct nvif_object *object) +{ + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_unmap unmap; + } args = { + .ioctl.type = NVIF_IOCTL_V0_UNMAP, + }; + + nvif_object_ioctl(object, &args, sizeof(args), NULL); +} + +int +nvif_object_map_handle(struct nvif_object *object, void *argv, u32 argc, + u64 *handle, u64 *length) { - if (object->map.size) { - struct nvif_client *client = object->client; - struct { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_unmap unmap; - } args = { - .ioctl.type = NVIF_IOCTL_V0_UNMAP, - }; + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_map_v0 map; + } *args; + u32 argn = sizeof(*args) + argc; + int ret, maptype; + + if (!(args = kzalloc(argn, GFP_KERNEL))) + return -ENOMEM; + args->ioctl.type = NVIF_IOCTL_V0_MAP; + memcpy(args->map.data, argv, argc); - if (object->map.ptr) { + ret = nvif_object_ioctl(object, args, argn, NULL); + *handle = args->map.handle; + *length = args->map.length; + maptype = args->map.type; + kfree(args); + return ret ? ret : (maptype == NVIF_IOCTL_MAP_V0_IO); +} + +void +nvif_object_unmap(struct nvif_object *object) +{ + struct nvif_client *client = object->client; + if (object->map.ptr) { + if (object->map.size) { client->driver->unmap(client, object->map.ptr, object->map.size); - object->map.ptr = NULL; + object->map.size = 0; } - - nvif_object_ioctl(object, &args, sizeof(args), NULL); - object->map.size = 0; + object->map.ptr = NULL; + nvif_object_unmap_handle(object); } } int -nvif_object_map(struct nvif_object *object) +nvif_object_map(struct nvif_object *object, void *argv, u32 argc) { struct nvif_client *client = object->client; - struct { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_map_v0 map; - } args = { - .ioctl.type = NVIF_IOCTL_V0_MAP, - }; - int ret = nvif_object_ioctl(object, &args, sizeof(args), NULL); - if (ret == 0) { - object->map.size = args.map.length; - object->map.ptr = client->driver->map(client, args.map.handle, - object->map.size); - if (ret = -ENOMEM, object->map.ptr) + u64 handle, length; + int ret = nvif_object_map_handle(object, argv, argc, &handle, &length); + if (ret >= 0) { + if (ret) { + object->map.ptr = client->driver->map(client, + handle, + length); + if (ret = -ENOMEM, object->map.ptr) { + object->map.size = length; + return 0; + } + } else { + object->map.ptr = (void *)(unsigned long)handle; return 0; - nvif_object_unmap(object); + } + nvif_object_unmap_handle(object); } return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c index be19bbe56bba..bf2507f17baa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c @@ -257,13 +257,19 @@ nvkm_ioctl_map(struct nvkm_client *client, union { struct nvif_ioctl_map_v0 v0; } *args = data; + enum nvkm_object_map type; int ret = -ENOSYS; nvif_ioctl(object, "map size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) { nvif_ioctl(object, "map vers %d\n", args->v0.version); - ret = nvkm_object_map(object, &args->v0.handle, - &args->v0.length); + ret = nvkm_object_map(object, data, size, &type, + &args->v0.handle, + &args->v0.length); + if (type == NVKM_OBJECT_MAP_IO) + args->v0.type = NVIF_IOCTL_MAP_V0_IO; + else + args->v0.type = NVIF_IOCTL_MAP_V0_VA; } return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/object.c b/drivers/gpu/drm/nouveau/nvkm/core/object.c index acd76fd4f6d8..516e73a52665 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/object.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/object.c @@ -102,10 +102,11 @@ nvkm_object_ntfy(struct nvkm_object *object, u32 mthd, } int -nvkm_object_map(struct nvkm_object *object, u64 *addr, u32 *size) +nvkm_object_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) { if (likely(object->func->map)) - return object->func->map(object, addr, size); + return object->func->map(object, argv, argc, type, addr, size); return -ENODEV; } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c index e31a0479add0..e7dd15b97721 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c @@ -37,9 +37,11 @@ nvkm_oproxy_ntfy(struct nvkm_object *object, u32 mthd, } static int -nvkm_oproxy_map(struct nvkm_object *object, u64 *addr, u32 *size) +nvkm_oproxy_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) { - return nvkm_object_map(nvkm_oproxy(object)->object, addr, size); + struct nvkm_oproxy *oproxy = nvkm_oproxy(object); + return nvkm_object_map(oproxy->object, argv, argc, type, addr, size); } static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 513ee6b79553..e9b90e40f274 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -206,10 +206,12 @@ nvkm_udevice_wr32(struct nvkm_object *object, u64 addr, u32 data) } static int -nvkm_udevice_map(struct nvkm_object *object, u64 *addr, u32 *size) +nvkm_udevice_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) { struct nvkm_udevice *udev = nvkm_udevice(object); struct nvkm_device *device = udev->device; + *type = NVKM_OBJECT_MAP_IO; *addr = device->func->resource_addr(device, 0); *size = device->func->resource_size(device, 0); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 0c0310498afd..723dcbde2ac2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -191,11 +191,13 @@ nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type, } static int -nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size) +nv50_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) { struct nv50_disp_chan *chan = nv50_disp_chan(object); struct nv50_disp *disp = chan->root->disp; struct nvkm_device *device = disp->base.engine.subdev.device; + *type = NVKM_OBJECT_MAP_IO; *addr = device->func->resource_addr(device, 0) + 0x640000 + (chan->chid.user * 0x1000); *size = 0x001000; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index fab760ae922f..7aea0a8692ae 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -253,9 +253,11 @@ nvkm_fifo_chan_ntfy(struct nvkm_object *object, u32 type, } static int -nvkm_fifo_chan_map(struct nvkm_object *object, u64 *addr, u32 *size) +nvkm_fifo_chan_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) { struct nvkm_fifo_chan *chan = nvkm_fifo_chan(object); + *type = NVKM_OBJECT_MAP_IO; *addr = chan->addr; *size = chan->size; return 0; -- cgit v1.2.3 From 8e0042d505e86299544cf000e26408bdd252e36b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/object: plumb the unmap ioctl through MMU will be using this for BAR mappings. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/object.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/core/ioctl.c | 1 + drivers/gpu/drm/nouveau/nvkm/core/object.c | 9 +++++++++ drivers/gpu/drm/nouveau/nvkm/core/oproxy.c | 7 +++++++ 4 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h index 4797577d52ce..916a4b76d430 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h @@ -32,6 +32,7 @@ struct nvkm_object_func { int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **); int (*map)(struct nvkm_object *, void *argv, u32 argc, enum nvkm_object_map *, u64 *addr, u64 *size); + int (*unmap)(struct nvkm_object *); int (*rd08)(struct nvkm_object *, u64 addr, u8 *data); int (*rd16)(struct nvkm_object *, u64 addr, u16 *data); int (*rd32)(struct nvkm_object *, u64 addr, u32 *data); @@ -58,6 +59,7 @@ int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size); int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **); int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc, enum nvkm_object_map *, u64 *addr, u64 *size); +int nvkm_object_unmap(struct nvkm_object *); int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8 *data); int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data); int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c index bf2507f17baa..a28018ee5b19 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c @@ -287,6 +287,7 @@ nvkm_ioctl_unmap(struct nvkm_client *client, nvif_ioctl(object, "unmap size %d\n", size); if (!(ret = nvif_unvers(ret, &data, &size, args->none))) { nvif_ioctl(object, "unmap\n"); + ret = nvkm_object_unmap(object); } return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/object.c b/drivers/gpu/drm/nouveau/nvkm/core/object.c index 516e73a52665..301a5e5b5f7f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/object.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/object.c @@ -110,6 +110,14 @@ nvkm_object_map(struct nvkm_object *object, void *argv, u32 argc, return -ENODEV; } +int +nvkm_object_unmap(struct nvkm_object *object) +{ + if (likely(object->func->unmap)) + return object->func->unmap(object); + return -ENODEV; +} + int nvkm_object_rd08(struct nvkm_object *object, u64 addr, u8 *data) { @@ -260,6 +268,7 @@ nvkm_object_dtor(struct nvkm_object *object) } nvif_debug(object, "destroy running...\n"); + nvkm_object_unmap(object); if (object->func->dtor) data = object->func->dtor(object); nvkm_engine_unref(&object->engine); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c index e7dd15b97721..16299837a296 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c @@ -44,6 +44,12 @@ nvkm_oproxy_map(struct nvkm_object *object, void *argv, u32 argc, return nvkm_object_map(oproxy->object, argv, argc, type, addr, size); } +static int +nvkm_oproxy_unmap(struct nvkm_object *object) +{ + return nvkm_object_unmap(nvkm_oproxy(object)->object); +} + static int nvkm_oproxy_rd08(struct nvkm_object *object, u64 addr, u8 *data) { @@ -173,6 +179,7 @@ nvkm_oproxy_func = { .mthd = nvkm_oproxy_mthd, .ntfy = nvkm_oproxy_ntfy, .map = nvkm_oproxy_map, + .unmap = nvkm_oproxy_unmap, .rd08 = nvkm_oproxy_rd08, .rd16 = nvkm_oproxy_rd16, .rd32 = nvkm_oproxy_rd32, -- cgit v1.2.3 From 153b642fcb8ce912575e594f9af079d17757a6bd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/gpuobj: remove embedded struct nvkm_object nvkm_gpuobj hasn't subclassed nvkm_object in a long time. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h | 2 -- drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h index c23da4f05929..1d7ccde7cde8 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h @@ -1,6 +1,5 @@ #ifndef __NVKM_GPUOBJ_H__ #define __NVKM_GPUOBJ_H__ -#include #include #include struct nvkm_vma; @@ -10,7 +9,6 @@ struct nvkm_vm; #define NVOBJ_FLAG_HEAP 0x00000004 struct nvkm_gpuobj { - struct nvkm_object object; const struct nvkm_gpuobj_func *func; struct nvkm_gpuobj *parent; struct nvkm_memory *memory; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h index 5ee6298991e2..8a48ca67f60d 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h @@ -1,6 +1,7 @@ #ifndef __NVKM_RAMHT_H__ #define __NVKM_RAMHT_H__ #include +struct nvkm_object; struct nvkm_ramht_data { struct nvkm_gpuobj *inst; -- cgit v1.2.3 From 82be74ee3baafff58d6b1f40ac7687c32a74d93a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/subdev: compile out messages for unwanted debug levels Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h index ca9ed3d68f44..a6c21be7537f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h @@ -33,7 +33,7 @@ void nvkm_subdev_intr(struct nvkm_subdev *); /* subdev logging */ #define nvkm_printk_(s,l,p,f,a...) do { \ const struct nvkm_subdev *_subdev = (s); \ - if (_subdev->debug >= (l)) { \ + if (CONFIG_NOUVEAU_DEBUG >= (l) && _subdev->debug >= (l)) { \ dev_##p(_subdev->device->dev, "%s: "f, \ nvkm_subdev_name[_subdev->index], ##a); \ } \ -- cgit v1.2.3 From 4246b92cf9fb32da8d8b060c92d8302797c6fbea Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/device: remove object include to prevent unnecessary rebuilds nvkm_device hasn't subclassed nvkm_object in a long time. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 2 +- drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 +- drivers/gpu/drm/nouveau/nvkm/core/ramht.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/sw/chan.h | 4 +++- drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.h | 2 +- 17 files changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index bb4c214f1046..5046e1db99ac 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -1,7 +1,7 @@ #ifndef __NVKM_DEVICE_H__ #define __NVKM_DEVICE_H__ +#include #include -#include enum nvkm_devidx { NVKM_SUBDEV_PCI, diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h index d2a6532ce3b9..b672a3b07f55 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h @@ -1,6 +1,7 @@ #ifndef __NVKM_DMA_H__ #define __NVKM_DMA_H__ #include +#include struct nvkm_client; struct nvkm_dmaobj { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h index e1a854e2ade1..8f9d132fbedf 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h @@ -3,6 +3,7 @@ #define nvkm_falcon(p) container_of((p), struct nvkm_falcon, engine) #include struct nvkm_fifo_chan; +struct nvkm_gpuobj; enum nvkm_falcon_dmaidx { FALCON_DMAIDX_UCODE = 0, diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index f00527b36acc..0e65ad7e6eed 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -1,6 +1,7 @@ #ifndef __NVKM_FIFO_H__ #define __NVKM_FIFO_H__ #include +#include #include #define NVKM_FIFO_CHID_NR 4096 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index dcd3deff27a4..d333c7668c23 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -2,7 +2,7 @@ #define __NVKM_MMU_H__ #include #include -struct nvkm_device; +struct nvkm_gpuobj; struct nvkm_mem; struct nvkm_vm_pgt { diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c index 89da47234016..ccba4ae73cc5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c @@ -21,6 +21,7 @@ */ #include #include +#include static u32 nvkm_ramht_hash(struct nvkm_ramht *ramht, int chid, u32 handle) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.h index 20249d8e444d..2c3c3ee3c494 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.h @@ -1,7 +1,7 @@ #ifndef __NVKM_DEVICE_CTRL_H__ #define __NVKM_DEVICE_CTRL_H__ #define nvkm_control(p) container_of((p), struct nvkm_control, object) -#include +#include struct nvkm_control { struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index 737b38f6fbd2..9bb4ad5b0e57 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -1,6 +1,7 @@ #ifndef __NV50_DISP_CHAN_H__ #define __NV50_DISP_CHAN_H__ #define nv50_disp_chan(p) container_of((p), struct nv50_disp_chan, object) +#include #include "nv50.h" struct nv50_disp_chan { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index a36e45a4a635..290148816360 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -156,6 +156,7 @@ int gp100_gr_init(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); #define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object) +#include struct gf100_gr_chan { struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h index cdf4501e3798..d0cb2b8846ec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h @@ -19,6 +19,7 @@ void nv20_gr_tile(struct nvkm_gr *, int, struct nvkm_fb_tile *); int nv30_gr_init(struct nvkm_gr *); #define nv20_gr_chan(p) container_of((p), struct nv20_gr_chan, object) +#include struct nv20_gr_chan { struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h index 2812ed11f877..bee8ef2d5697 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h @@ -16,6 +16,7 @@ void nv40_gr_intr(struct nvkm_gr *); u64 nv40_gr_units(struct nvkm_gr *); #define nv40_gr_chan(p) container_of((p), struct nv40_gr_chan, object) +#include struct nv40_gr_chan { struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h index 45eec83a5969..1ab6ea436b70 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h @@ -19,6 +19,7 @@ u64 nv50_gr_units(struct nvkm_gr *); int g84_gr_tlb_flush(struct nvkm_gr *); #define nv50_gr_chan(p) container_of((p), struct nv50_gr_chan, object) +#include struct nv50_gr_chan { struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h index d3bb34fcdebf..f0d35beb58df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h @@ -18,6 +18,7 @@ struct nv31_mpeg_func { }; #define nv31_mpeg_chan(p) container_of((p), struct nv31_mpeg_chan, object) +#include struct nv31_mpeg_chan { struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c index 4e528851e9c0..6df880a39019 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c @@ -24,6 +24,7 @@ #include "priv.h" #include +#include #include #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h index d7b81cbf82b5..4ff0475e776c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h @@ -67,6 +67,7 @@ struct nvkm_specdom { }; #define nvkm_perfdom(p) container_of((p), struct nvkm_perfdom, object) +#include struct nvkm_perfdom { struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/chan.h b/drivers/gpu/drm/nouveau/nvkm/engine/sw/chan.h index 6608bf6c6842..b5be49f0ac56 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/chan.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/chan.h @@ -1,9 +1,11 @@ #ifndef __NVKM_SW_CHAN_H__ #define __NVKM_SW_CHAN_H__ #define nvkm_sw_chan(p) container_of((p), struct nvkm_sw_chan, object) -#include "priv.h" +#include #include +#include "priv.h" + struct nvkm_sw_chan { const struct nvkm_sw_chan_func *func; struct nvkm_object object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.h b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.h index 943ef4c10091..bcfff62131fe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.h @@ -1,7 +1,7 @@ #ifndef __NVKM_NVSW_H__ #define __NVKM_NVSW_H__ #define nvkm_nvsw(p) container_of((p), struct nvkm_nvsw, object) -#include "priv.h" +#include struct nvkm_nvsw { struct nvkm_object object; -- cgit v1.2.3 From 12973a37c47a33c275017c92327340ab61558d83 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/secboot: add missing newline in debug message Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c index ee989210725e..6f10b098676c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c @@ -183,7 +183,7 @@ acr_ls_sec2_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) break; ); if (reg & BIT(4)) { - nvkm_debug(subdev, "applying workaround for start bug..."); + nvkm_debug(subdev, "applying workaround for start bug...\n"); nvkm_falcon_start(sb->boot_falcon); nvkm_msec(subdev->device, 1, if ((reg = nvkm_rd32(subdev->device, -- cgit v1.2.3 From b5078d731fad979e7426e1ef55c44ea469a71191 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/disp: add missing newline in ior debug messages Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index a1e8bf48b778..c9e0a8f7b5d5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -147,7 +147,7 @@ void gf119_hda_eld(struct nvkm_ior *, u8 *, u8); #define IOR_MSG(i,l,f,a...) do { \ struct nvkm_ior *_ior = (i); \ - nvkm_##l(&_ior->disp->engine.subdev, "%s: "f, _ior->name, ##a); \ + nvkm_##l(&_ior->disp->engine.subdev, "%s: "f"\n", _ior->name, ##a); \ } while(0) #define IOR_WARN(i,f,a...) IOR_MSG((i), warn, f, ##a) #define IOR_DBG(i,f,a...) IOR_MSG((i), debug, f, ##a) -- cgit v1.2.3 From 5e721ad198a0518a6059003b1651fdb183e32dd5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fifo: perform reset from preinit RM appears to do this really early in its initialisation, before DEVINIT. We currently do this before BAR2 initialisation for some reason. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/engine.h | 1 + drivers/gpu/drm/nouveau/nvkm/core/engine.c | 10 ++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c | 8 ++++++++ 3 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h index d4cd2fbfde88..7730499bfd95 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h @@ -15,6 +15,7 @@ struct nvkm_engine { struct nvkm_engine_func { void *(*dtor)(struct nvkm_engine *); + void (*preinit)(struct nvkm_engine *); int (*oneinit)(struct nvkm_engine *); int (*init)(struct nvkm_engine *); int (*fini)(struct nvkm_engine *, bool suspend); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/engine.c b/drivers/gpu/drm/nouveau/nvkm/core/engine.c index b6c916954a10..657231c3c098 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/engine.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/engine.c @@ -126,6 +126,15 @@ nvkm_engine_init(struct nvkm_subdev *subdev) return ret; } +static int +nvkm_engine_preinit(struct nvkm_subdev *subdev) +{ + struct nvkm_engine *engine = nvkm_engine(subdev); + if (engine->func->preinit) + engine->func->preinit(engine); + return 0; +} + static void * nvkm_engine_dtor(struct nvkm_subdev *subdev) { @@ -138,6 +147,7 @@ nvkm_engine_dtor(struct nvkm_subdev *subdev) static const struct nvkm_subdev_func nvkm_engine_func = { .dtor = nvkm_engine_dtor, + .preinit = nvkm_engine_preinit, .init = nvkm_engine_init, .fini = nvkm_engine_fini, .intr = nvkm_engine_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 660ca7aa95ea..64f6b7654a08 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -278,6 +279,12 @@ nvkm_fifo_oneinit(struct nvkm_engine *engine) return 0; } +static void +nvkm_fifo_preinit(struct nvkm_engine *engine) +{ + nvkm_mc_reset(engine->subdev.device, NVKM_ENGINE_FIFO); +} + static int nvkm_fifo_init(struct nvkm_engine *engine) { @@ -302,6 +309,7 @@ nvkm_fifo_dtor(struct nvkm_engine *engine) static const struct nvkm_engine_func nvkm_fifo = { .dtor = nvkm_fifo_dtor, + .preinit = nvkm_fifo_preinit, .oneinit = nvkm_fifo_oneinit, .init = nvkm_fifo_init, .fini = nvkm_fifo_fini, -- cgit v1.2.3 From e69dae85c90b3e07ed5538a8ad8a7ee807fbbf64 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar/nv50,g84: drop mmu invalidate Will already be done by MMU as a result of the PT writes that occur during BAR2 bootstrapping. This is likely just a left-over from the days when it was hardcoded. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 4 +--- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 9 +-------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 2 +- 6 files changed, 7 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index c561d148cebc..2eab979e94df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -56,7 +56,8 @@ static int nvkm_bar_init(struct nvkm_subdev *subdev) { struct nvkm_bar *bar = nvkm_bar(subdev); - return bar->func->init(bar); + bar->func->init(bar); + return 0; } static void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 676c167c95b9..1befe4464155 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -117,7 +117,7 @@ gf100_bar_oneinit(struct nvkm_bar *base) return 0; } -int +void gf100_bar_init(struct nvkm_bar *base) { struct gf100_bar *bar = gf100_bar(base); @@ -136,8 +136,6 @@ gf100_bar_init(struct nvkm_bar *base) addr |= 0x40000000; nvkm_wr32(device, 0x001714, 0x80000000 | addr); } - - return 0; } void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index 20a5255362ba..9c5735f01acd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -19,6 +19,6 @@ int gf100_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, int, struct nvkm_bar **); void *gf100_bar_dtor(struct nvkm_bar *); int gf100_bar_oneinit(struct nvkm_bar *); -int gf100_bar_init(struct nvkm_bar *); +void gf100_bar_init(struct nvkm_bar *); int gf100_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 6eff637ac301..4bfe6db006ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -144,7 +144,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) return 0; } -int +void nv50_bar_init(struct nvkm_bar *base) { struct nv50_bar *bar = nv50_bar(base); @@ -153,12 +153,6 @@ nv50_bar_init(struct nvkm_bar *base) nvkm_mask(device, 0x000200, 0x00000100, 0x00000000); nvkm_mask(device, 0x000200, 0x00000100, 0x00000100); - nvkm_wr32(device, 0x100c80, 0x00060001); - if (nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x100c80) & 0x00000001)) - break; - ) < 0) - return -EBUSY; nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12); nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12); @@ -166,7 +160,6 @@ nv50_bar_init(struct nvkm_bar *base) nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar3->node->offset >> 4); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000); - return 0; } void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index 1eb764f22a49..da5e6be573c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -19,7 +19,7 @@ int nv50_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, int, u32 pgd_addr, struct nvkm_bar **); void *nv50_bar_dtor(struct nvkm_bar *); int nv50_bar_oneinit(struct nvkm_bar *); -int nv50_bar_init(struct nvkm_bar *); +void nv50_bar_init(struct nvkm_bar *); struct nvkm_vm *nv50_bar_kmap(struct nvkm_bar *); int nv50_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index d834ef20db5b..c017239b2a8e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -9,7 +9,7 @@ void nvkm_bar_ctor(const struct nvkm_bar_func *, struct nvkm_device *, struct nvkm_bar_func { void *(*dtor)(struct nvkm_bar *); int (*oneinit)(struct nvkm_bar *); - int (*init)(struct nvkm_bar *); + void (*init)(struct nvkm_bar *); struct nvkm_vm *(*kmap)(struct nvkm_bar *); int (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); void (*flush)(struct nvkm_bar *); -- cgit v1.2.3 From c9e70592963d1588da4a300209cd4913d12ae689 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: remove NV_PMC_ENABLE_PFIFO twiddling It's handled by FIFO preinit() now. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 3 --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 3 --- 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 1befe4464155..3a6b2e4c66ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -124,9 +124,6 @@ gf100_bar_init(struct nvkm_bar *base) struct nvkm_device *device = bar->base.subdev.device; u32 addr; - nvkm_mask(device, 0x000200, 0x00000100, 0x00000000); - nvkm_mask(device, 0x000200, 0x00000100, 0x00000100); - addr = nvkm_memory_addr(bar->bar[1].mem) >> 12; nvkm_wr32(device, 0x001704, 0x80000000 | addr); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 4bfe6db006ac..aca65506cbc8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -151,9 +151,6 @@ nv50_bar_init(struct nvkm_bar *base) struct nvkm_device *device = bar->base.subdev.device; int i; - nvkm_mask(device, 0x000200, 0x00000100, 0x00000000); - nvkm_mask(device, 0x000200, 0x00000100, 0x00000100); - nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12); nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12); nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); -- cgit v1.2.3 From 269fe32d3343b7b9e48ba533887f58eb877581c8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: swap oneinit/init ordering, and rename bar3 to bar2 NVIDIA call it BAR2, Linux APIs treat it as BAR3 due to BAR1 being a 64-bit BAR, which I presume take two slots or something. No actual code changes here, just to make future commits less messy. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 10 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 48 +++++++++--------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 4 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 66 ++++++++++++------------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h | 4 +- 5 files changed, 66 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index 2eab979e94df..f849db6ef541 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -46,18 +46,18 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma) } static int -nvkm_bar_oneinit(struct nvkm_subdev *subdev) +nvkm_bar_init(struct nvkm_subdev *subdev) { struct nvkm_bar *bar = nvkm_bar(subdev); - return bar->func->oneinit(bar); + bar->func->init(bar); + return 0; } static int -nvkm_bar_init(struct nvkm_subdev *subdev) +nvkm_bar_oneinit(struct nvkm_subdev *subdev) { struct nvkm_bar *bar = nvkm_bar(subdev); - bar->func->init(bar); - return 0; + return bar->func->oneinit(bar); } static void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 3a6b2e4c66ba..d2496cd736fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -41,9 +41,27 @@ gf100_bar_umap(struct nvkm_bar *base, u64 size, int type, struct nvkm_vma *vma) return nvkm_vm_get(bar->bar[1].vm, size, type, NV_MEM_ACCESS_RW, vma); } +void +gf100_bar_init(struct nvkm_bar *base) +{ + struct gf100_bar *bar = gf100_bar(base); + struct nvkm_device *device = bar->base.subdev.device; + u32 addr; + + addr = nvkm_memory_addr(bar->bar[1].mem) >> 12; + nvkm_wr32(device, 0x001704, 0x80000000 | addr); + + if (bar->bar[0].mem) { + addr = nvkm_memory_addr(bar->bar[0].mem) >> 12; + if (bar->bar2_halve) + addr |= 0x40000000; + nvkm_wr32(device, 0x001714, 0x80000000 | addr); + } +} + static int -gf100_bar_ctor_vm(struct gf100_bar *bar, struct gf100_bar_vm *bar_vm, - struct lock_class_key *key, int bar_nr) +gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, + struct lock_class_key *key, int bar_nr) { struct nvkm_device *device = bar->base.subdev.device; struct nvkm_vm *vm; @@ -98,43 +116,25 @@ int gf100_bar_oneinit(struct nvkm_bar *base) { static struct lock_class_key bar1_lock; - static struct lock_class_key bar3_lock; + static struct lock_class_key bar2_lock; struct gf100_bar *bar = gf100_bar(base); int ret; - /* BAR3 */ + /* BAR2 */ if (bar->base.func->kmap) { - ret = gf100_bar_ctor_vm(bar, &bar->bar[0], &bar3_lock, 3); + ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, 3); if (ret) return ret; } /* BAR1 */ - ret = gf100_bar_ctor_vm(bar, &bar->bar[1], &bar1_lock, 1); + ret = gf100_bar_oneinit_bar(bar, &bar->bar[1], &bar1_lock, 1); if (ret) return ret; return 0; } -void -gf100_bar_init(struct nvkm_bar *base) -{ - struct gf100_bar *bar = gf100_bar(base); - struct nvkm_device *device = bar->base.subdev.device; - u32 addr; - - addr = nvkm_memory_addr(bar->bar[1].mem) >> 12; - nvkm_wr32(device, 0x001704, 0x80000000 | addr); - - if (bar->bar[0].mem) { - addr = nvkm_memory_addr(bar->bar[0].mem) >> 12; - if (bar->bar2_halve) - addr |= 0x40000000; - nvkm_wr32(device, 0x001714, 0x80000000 | addr); - } -} - void * gf100_bar_dtor(struct nvkm_bar *base) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index 9c5735f01acd..ece98643bedd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -3,7 +3,7 @@ #define gf100_bar(p) container_of((p), struct gf100_bar, base) #include "priv.h" -struct gf100_bar_vm { +struct gf100_barN { struct nvkm_memory *mem; struct nvkm_gpuobj *pgd; struct nvkm_vm *vm; @@ -12,7 +12,7 @@ struct gf100_bar_vm { struct gf100_bar { struct nvkm_bar base; bool bar2_halve; - struct gf100_bar_vm bar[2]; + struct gf100_barN bar[2]; }; int gf100_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index aca65506cbc8..8a4c42f9a96a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -31,7 +31,7 @@ struct nvkm_vm * nv50_bar_kmap(struct nvkm_bar *base) { - return nv50_bar(base)->bar3_vm; + return nv50_bar(base)->bar2_vm; } int @@ -56,13 +56,28 @@ nv50_bar_flush(struct nvkm_bar *base) spin_unlock_irqrestore(&bar->base.lock, flags); } +void +nv50_bar_init(struct nvkm_bar *base) +{ + struct nv50_bar *bar = nv50_bar(base); + struct nvkm_device *device = bar->base.subdev.device; + int i; + + nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12); + nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12); + nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); + nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar2->node->offset >> 4); + for (i = 0; i < 8; i++) + nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000); +} + int nv50_bar_oneinit(struct nvkm_bar *base) { struct nv50_bar *bar = nv50_bar(base); struct nvkm_device *device = bar->base.subdev.device; static struct lock_class_key bar1_lock; - static struct lock_class_key bar3_lock; + static struct lock_class_key bar2_lock; struct nvkm_vm *vm; u64 start, limit; int ret; @@ -80,11 +95,11 @@ nv50_bar_oneinit(struct nvkm_bar *base) if (ret) return ret; - /* BAR3 */ + /* BAR2 */ start = 0x0100000000ULL; limit = start + device->func->resource_size(device, 3); - ret = nvkm_vm_new(device, start, limit - start, start, &bar3_lock, &vm); + ret = nvkm_vm_new(device, start, limit - start, start, &bar2_lock, &vm); if (ret) return ret; @@ -94,24 +109,24 @@ nv50_bar_oneinit(struct nvkm_bar *base) if (ret) return ret; - ret = nvkm_vm_ref(vm, &bar->bar3_vm, bar->pgd); + ret = nvkm_vm_ref(vm, &bar->bar2_vm, bar->pgd); nvkm_vm_ref(NULL, &vm, NULL); if (ret) return ret; - ret = nvkm_gpuobj_new(device, 24, 16, false, bar->mem, &bar->bar3); + ret = nvkm_gpuobj_new(device, 24, 16, false, bar->mem, &bar->bar2); if (ret) return ret; - nvkm_kmap(bar->bar3); - nvkm_wo32(bar->bar3, 0x00, 0x7fc00000); - nvkm_wo32(bar->bar3, 0x04, lower_32_bits(limit)); - nvkm_wo32(bar->bar3, 0x08, lower_32_bits(start)); - nvkm_wo32(bar->bar3, 0x0c, upper_32_bits(limit) << 24 | + nvkm_kmap(bar->bar2); + nvkm_wo32(bar->bar2, 0x00, 0x7fc00000); + nvkm_wo32(bar->bar2, 0x04, lower_32_bits(limit)); + nvkm_wo32(bar->bar2, 0x08, lower_32_bits(start)); + nvkm_wo32(bar->bar2, 0x0c, upper_32_bits(limit) << 24 | upper_32_bits(start)); - nvkm_wo32(bar->bar3, 0x10, 0x00000000); - nvkm_wo32(bar->bar3, 0x14, 0x00000000); - nvkm_done(bar->bar3); + nvkm_wo32(bar->bar2, 0x10, 0x00000000); + nvkm_wo32(bar->bar2, 0x14, 0x00000000); + nvkm_done(bar->bar2); /* BAR1 */ start = 0x0000000000ULL; @@ -144,31 +159,16 @@ nv50_bar_oneinit(struct nvkm_bar *base) return 0; } -void -nv50_bar_init(struct nvkm_bar *base) -{ - struct nv50_bar *bar = nv50_bar(base); - struct nvkm_device *device = bar->base.subdev.device; - int i; - - nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12); - nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12); - nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); - nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar3->node->offset >> 4); - for (i = 0; i < 8; i++) - nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000); -} - void * nv50_bar_dtor(struct nvkm_bar *base) { struct nv50_bar *bar = nv50_bar(base); nvkm_gpuobj_del(&bar->bar1); nvkm_vm_ref(NULL, &bar->bar1_vm, bar->pgd); - nvkm_gpuobj_del(&bar->bar3); - if (bar->bar3_vm) { - nvkm_memory_del(&bar->bar3_vm->pgt[0].mem[0]); - nvkm_vm_ref(NULL, &bar->bar3_vm, bar->pgd); + nvkm_gpuobj_del(&bar->bar2); + if (bar->bar2_vm) { + nvkm_memory_del(&bar->bar2_vm->pgt[0].mem[0]); + nvkm_vm_ref(NULL, &bar->bar2_vm, bar->pgd); } nvkm_gpuobj_del(&bar->pgd); nvkm_gpuobj_del(&bar->pad); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index da5e6be573c9..6ff3fdb4b4bd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -11,8 +11,8 @@ struct nv50_bar { struct nvkm_gpuobj *pgd; struct nvkm_vm *bar1_vm; struct nvkm_gpuobj *bar1; - struct nvkm_vm *bar3_vm; - struct nvkm_gpuobj *bar3; + struct nvkm_vm *bar2_vm; + struct nvkm_gpuobj *bar2; }; int nv50_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, -- cgit v1.2.3 From 7313cfa4f6e30384fa04083698d1e865cf812a6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: move bar1 initialisation into its own function BAR2 being done for practical reasons, this is just for consistency. Flushes have been added after the write to bind the instance block, as later commits will reveal the need for them. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 22 +++++++++++++++++++--- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 17 ++++++++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 6 ++++++ 8 files changed, 51 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index f849db6ef541..adaf91ee8326 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -49,6 +49,8 @@ static int nvkm_bar_init(struct nvkm_subdev *subdev) { struct nvkm_bar *bar = nvkm_bar(subdev); + bar->func->bar1.init(bar); + bar->func->bar1.wait(bar); bar->func->init(bar); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c index ef717136c838..dee1cd9987c2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c @@ -44,6 +44,8 @@ g84_bar_func = { .dtor = nv50_bar_dtor, .oneinit = nv50_bar_oneinit, .init = nv50_bar_init, + .bar1.init = nv50_bar_bar1_init, + .bar1.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, .flush = g84_bar_flush, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index d2496cd736fa..fc3d771cef50 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -41,6 +41,23 @@ gf100_bar_umap(struct nvkm_bar *base, u64 size, int type, struct nvkm_vma *vma) return nvkm_vm_get(bar->bar[1].vm, size, type, NV_MEM_ACCESS_RW, vma); } +void +gf100_bar_bar1_wait(struct nvkm_bar *base) +{ + /* NFI why it's twice. */ + nvkm_bar_flush(base); + nvkm_bar_flush(base); +} + +void +gf100_bar_bar1_init(struct nvkm_bar *base) +{ + struct nvkm_device *device = base->subdev.device; + struct gf100_bar *bar = gf100_bar(base); + const u32 addr = nvkm_memory_addr(bar->bar[1].mem) >> 12; + nvkm_wr32(device, 0x001704, 0x80000000 | addr); +} + void gf100_bar_init(struct nvkm_bar *base) { @@ -48,9 +65,6 @@ gf100_bar_init(struct nvkm_bar *base) struct nvkm_device *device = bar->base.subdev.device; u32 addr; - addr = nvkm_memory_addr(bar->bar[1].mem) >> 12; - nvkm_wr32(device, 0x001704, 0x80000000 | addr); - if (bar->bar[0].mem) { addr = nvkm_memory_addr(bar->bar[0].mem) >> 12; if (bar->bar2_halve) @@ -171,6 +185,8 @@ gf100_bar_func = { .dtor = gf100_bar_dtor, .oneinit = gf100_bar_oneinit, .init = gf100_bar_init, + .bar1.init = gf100_bar_bar1_init, + .bar1.wait = gf100_bar_bar1_wait, .kmap = gf100_bar_kmap, .umap = gf100_bar_umap, .flush = g84_bar_flush, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index ece98643bedd..9b994eaad1e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -20,5 +20,7 @@ int gf100_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, void *gf100_bar_dtor(struct nvkm_bar *); int gf100_bar_oneinit(struct nvkm_bar *); void gf100_bar_init(struct nvkm_bar *); +void gf100_bar_bar1_init(struct nvkm_bar *); +void gf100_bar_bar1_wait(struct nvkm_bar *); int gf100_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c index 9232fab4274c..86aca93e76e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c @@ -25,7 +25,8 @@ static const struct nvkm_bar_func gk20a_bar_func = { .dtor = gf100_bar_dtor, .oneinit = gf100_bar_oneinit, - .init = gf100_bar_init, + .bar1.init = gf100_bar_bar1_init, + .bar1.wait = gf100_bar_bar1_wait, .umap = gf100_bar_umap, .flush = g84_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 8a4c42f9a96a..8cb8e721a515 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -56,6 +56,20 @@ nv50_bar_flush(struct nvkm_bar *base) spin_unlock_irqrestore(&bar->base.lock, flags); } +void +nv50_bar_bar1_wait(struct nvkm_bar *base) +{ + nvkm_bar_flush(base); +} + +void +nv50_bar_bar1_init(struct nvkm_bar *base) +{ + struct nvkm_device *device = base->subdev.device; + struct nv50_bar *bar = nv50_bar(base); + nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); +} + void nv50_bar_init(struct nvkm_bar *base) { @@ -65,7 +79,6 @@ nv50_bar_init(struct nvkm_bar *base) nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12); nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12); - nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar2->node->offset >> 4); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000); @@ -194,6 +207,8 @@ nv50_bar_func = { .dtor = nv50_bar_dtor, .oneinit = nv50_bar_oneinit, .init = nv50_bar_init, + .bar1.init = nv50_bar_bar1_init, + .bar1.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, .flush = nv50_bar_flush, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index 6ff3fdb4b4bd..52971cfd119c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -20,6 +20,8 @@ int nv50_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, void *nv50_bar_dtor(struct nvkm_bar *); int nv50_bar_oneinit(struct nvkm_bar *); void nv50_bar_init(struct nvkm_bar *); +void nv50_bar_bar1_init(struct nvkm_bar *); +void nv50_bar_bar1_wait(struct nvkm_bar *); struct nvkm_vm *nv50_bar_kmap(struct nvkm_bar *); int nv50_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index c017239b2a8e..8b508373769f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -10,6 +10,12 @@ struct nvkm_bar_func { void *(*dtor)(struct nvkm_bar *); int (*oneinit)(struct nvkm_bar *); void (*init)(struct nvkm_bar *); + + struct { + void (*init)(struct nvkm_bar *); + void (*wait)(struct nvkm_bar *); + } bar1; + struct nvkm_vm *(*kmap)(struct nvkm_bar *); int (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); void (*flush)(struct nvkm_bar *); -- cgit v1.2.3 From bbb163e18960a90b0c5974fe448ad78a5df8e5d7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: implement bar1 teardown Will prevent spurious MMU fault interrupts if something decides to touch BAR1 after we've unloaded the driver. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 9 +++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 7 +++++++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 7 +++++++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 5 +++++ 6 files changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index adaf91ee8326..0fee5e0a090e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -45,6 +45,14 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma) return bar->func->umap(bar, size, type, vma); } +static int +nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend) +{ + struct nvkm_bar *bar = nvkm_bar(subdev); + bar->func->bar1.fini(bar); + return 0; +} + static int nvkm_bar_init(struct nvkm_subdev *subdev) { @@ -74,6 +82,7 @@ nvkm_bar = { .dtor = nvkm_bar_dtor, .oneinit = nvkm_bar_oneinit, .init = nvkm_bar_init, + .fini = nvkm_bar_fini, }; void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c index dee1cd9987c2..0b63f224fa26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c @@ -45,6 +45,7 @@ g84_bar_func = { .oneinit = nv50_bar_oneinit, .init = nv50_bar_init, .bar1.init = nv50_bar_bar1_init, + .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index fc3d771cef50..fb57c0175e57 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -49,6 +49,12 @@ gf100_bar_bar1_wait(struct nvkm_bar *base) nvkm_bar_flush(base); } +void +gf100_bar_bar1_fini(struct nvkm_bar *bar) +{ + nvkm_mask(bar->subdev.device, 0x001704, 0x80000000, 0x00000000); +} + void gf100_bar_bar1_init(struct nvkm_bar *base) { @@ -186,6 +192,7 @@ gf100_bar_func = { .oneinit = gf100_bar_oneinit, .init = gf100_bar_init, .bar1.init = gf100_bar_bar1_init, + .bar1.fini = gf100_bar_bar1_fini, .bar1.wait = gf100_bar_bar1_wait, .kmap = gf100_bar_kmap, .umap = gf100_bar_umap, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c index 86aca93e76e8..ab4664b4b2b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c @@ -26,6 +26,7 @@ gk20a_bar_func = { .dtor = gf100_bar_dtor, .oneinit = gf100_bar_oneinit, .bar1.init = gf100_bar_bar1_init, + .bar1.fini = gf100_bar_bar1_fini, .bar1.wait = gf100_bar_bar1_wait, .umap = gf100_bar_umap, .flush = g84_bar_flush, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 8cb8e721a515..c9776121a076 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -62,6 +62,12 @@ nv50_bar_bar1_wait(struct nvkm_bar *base) nvkm_bar_flush(base); } +void +nv50_bar_bar1_fini(struct nvkm_bar *bar) +{ + nvkm_wr32(bar->subdev.device, 0x001708, 0x00000000); +} + void nv50_bar_bar1_init(struct nvkm_bar *base) { @@ -208,6 +214,7 @@ nv50_bar_func = { .oneinit = nv50_bar_oneinit, .init = nv50_bar_init, .bar1.init = nv50_bar_bar1_init, + .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index 8b508373769f..d130aab01aca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -13,6 +13,7 @@ struct nvkm_bar_func { struct { void (*init)(struct nvkm_bar *); + void (*fini)(struct nvkm_bar *); void (*wait)(struct nvkm_bar *); } bar1; @@ -21,5 +22,9 @@ struct nvkm_bar_func { void (*flush)(struct nvkm_bar *); }; +void nv50_bar_bar1_fini(struct nvkm_bar *); + void g84_bar_flush(struct nvkm_bar *); + +void gf100_bar_bar1_fini(struct nvkm_bar *); #endif -- cgit v1.2.3 From 48fe02478a0ddb89930f3595f8217fa2dfd98796 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: expose interface to bar2 initialisation If we want to be able to hit the instmem fast-path in a few trickier cases, we need to be more flexible with when we can initialise BAR2 access. There's probably a decent case to be made for merging BAR/INSTMEM into BUS, but that's something to ponder another day. Flushes have been added after the write to bind the instance block, as later commits will reveal the need for them. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 16 +++++++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 19 ++++++++----------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 15 ++++++++++++--- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 2 +- 8 files changed, 42 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h index d3071b5a4f98..eb9ad379f9e1 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h @@ -8,11 +8,13 @@ struct nvkm_bar { struct nvkm_subdev subdev; spinlock_t lock; + bool bar2; /* whether the BAR supports to be ioremapped WC or should be uncached */ bool iomap_uncached; }; +void nvkm_bar_bar2_init(struct nvkm_device *); void nvkm_bar_flush(struct nvkm_bar *); struct nvkm_vm *nvkm_bar_kmap(struct nvkm_bar *); int nvkm_bar_umap(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index 0fee5e0a090e..b55ab7183cb9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -45,11 +45,23 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma) return bar->func->umap(bar, size, type, vma); } +void +nvkm_bar_bar2_init(struct nvkm_device *device) +{ + struct nvkm_bar *bar = device->bar; + if (bar && bar->subdev.oneinit && !bar->bar2 && bar->func->bar2.init) { + bar->func->bar2.init(bar); + bar->func->bar2.wait(bar); + bar->bar2 = true; + } +} + static int nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_bar *bar = nvkm_bar(subdev); bar->func->bar1.fini(bar); + bar->bar2 = false; return 0; } @@ -57,9 +69,11 @@ static int nvkm_bar_init(struct nvkm_subdev *subdev) { struct nvkm_bar *bar = nvkm_bar(subdev); + nvkm_bar_bar2_init(subdev->device); bar->func->bar1.init(bar); bar->func->bar1.wait(bar); - bar->func->init(bar); + if (bar->func->init) + bar->func->init(bar); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c index 0b63f224fa26..912c8194e1d9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c @@ -47,6 +47,8 @@ g84_bar_func = { .bar1.init = nv50_bar_bar1_init, .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, + .bar2.init = nv50_bar_bar2_init, + .bar2.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, .flush = g84_bar_flush, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index fb57c0175e57..7504450972fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -65,18 +65,14 @@ gf100_bar_bar1_init(struct nvkm_bar *base) } void -gf100_bar_init(struct nvkm_bar *base) +gf100_bar_bar2_init(struct nvkm_bar *base) { + struct nvkm_device *device = base->subdev.device; struct gf100_bar *bar = gf100_bar(base); - struct nvkm_device *device = bar->base.subdev.device; - u32 addr; - - if (bar->bar[0].mem) { - addr = nvkm_memory_addr(bar->bar[0].mem) >> 12; - if (bar->bar2_halve) - addr |= 0x40000000; - nvkm_wr32(device, 0x001714, 0x80000000 | addr); - } + u32 addr = nvkm_memory_addr(bar->bar[0].mem) >> 12; + if (bar->bar2_halve) + addr |= 0x40000000; + nvkm_wr32(device, 0x001714, 0x80000000 | addr); } static int @@ -190,10 +186,11 @@ static const struct nvkm_bar_func gf100_bar_func = { .dtor = gf100_bar_dtor, .oneinit = gf100_bar_oneinit, - .init = gf100_bar_init, .bar1.init = gf100_bar_bar1_init, .bar1.fini = gf100_bar_bar1_fini, .bar1.wait = gf100_bar_bar1_wait, + .bar2.init = gf100_bar_bar2_init, + .bar2.wait = gf100_bar_bar1_wait, .kmap = gf100_bar_kmap, .umap = gf100_bar_umap, .flush = g84_bar_flush, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index 9b994eaad1e5..393116a7398a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -19,8 +19,8 @@ int gf100_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, int, struct nvkm_bar **); void *gf100_bar_dtor(struct nvkm_bar *); int gf100_bar_oneinit(struct nvkm_bar *); -void gf100_bar_init(struct nvkm_bar *); void gf100_bar_bar1_init(struct nvkm_bar *); void gf100_bar_bar1_wait(struct nvkm_bar *); +void gf100_bar_bar2_init(struct nvkm_bar *); int gf100_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index c9776121a076..d6d9a1d09722 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -76,6 +76,16 @@ nv50_bar_bar1_init(struct nvkm_bar *base) nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); } +void +nv50_bar_bar2_init(struct nvkm_bar *base) +{ + struct nvkm_device *device = base->subdev.device; + struct nv50_bar *bar = nv50_bar(base); + nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12); + nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12); + nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar2->node->offset >> 4); +} + void nv50_bar_init(struct nvkm_bar *base) { @@ -83,9 +93,6 @@ nv50_bar_init(struct nvkm_bar *base) struct nvkm_device *device = bar->base.subdev.device; int i; - nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12); - nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12); - nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar2->node->offset >> 4); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000); } @@ -216,6 +223,8 @@ nv50_bar_func = { .bar1.init = nv50_bar_bar1_init, .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, + .bar2.init = nv50_bar_bar2_init, + .bar2.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, .flush = nv50_bar_flush, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index 52971cfd119c..0009ed4344f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -22,6 +22,7 @@ int nv50_bar_oneinit(struct nvkm_bar *); void nv50_bar_init(struct nvkm_bar *); void nv50_bar_bar1_init(struct nvkm_bar *); void nv50_bar_bar1_wait(struct nvkm_bar *); +void nv50_bar_bar2_init(struct nvkm_bar *); struct nvkm_vm *nv50_bar_kmap(struct nvkm_bar *); int nv50_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index d130aab01aca..8c9c897dec5d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -15,7 +15,7 @@ struct nvkm_bar_func { void (*init)(struct nvkm_bar *); void (*fini)(struct nvkm_bar *); void (*wait)(struct nvkm_bar *); - } bar1; + } bar1, bar2; struct nvkm_vm *(*kmap)(struct nvkm_bar *); int (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); -- cgit v1.2.3 From e988952eefd923a40cea1077bcb939025dafb0f1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: expose interface to bar2 teardown Will prevent spurious MMU fault interrupts if something decides to touch BAR1 after we've unloaded the driver. Exposed external to BAR so that INSTMEM can use it to better control the suspend/resume fast-path access. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 12 +++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 7 +++++++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 7 +++++++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 2 ++ 6 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h index eb9ad379f9e1..11427d3d6173 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h @@ -15,6 +15,7 @@ struct nvkm_bar { }; void nvkm_bar_bar2_init(struct nvkm_device *); +void nvkm_bar_bar2_fini(struct nvkm_device *); void nvkm_bar_flush(struct nvkm_bar *); struct nvkm_vm *nvkm_bar_kmap(struct nvkm_bar *); int nvkm_bar_umap(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index b55ab7183cb9..b495f7796fa3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -45,6 +45,16 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma) return bar->func->umap(bar, size, type, vma); } +void +nvkm_bar_bar2_fini(struct nvkm_device *device) +{ + struct nvkm_bar *bar = device->bar; + if (bar && bar->bar2) { + bar->func->bar2.fini(bar); + bar->bar2 = false; + } +} + void nvkm_bar_bar2_init(struct nvkm_device *device) { @@ -61,7 +71,7 @@ nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_bar *bar = nvkm_bar(subdev); bar->func->bar1.fini(bar); - bar->bar2 = false; + nvkm_bar_bar2_fini(subdev->device); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c index 912c8194e1d9..dce74e0d2591 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c @@ -48,6 +48,7 @@ g84_bar_func = { .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, .bar2.init = nv50_bar_bar2_init, + .bar2.fini = nv50_bar_bar2_fini, .bar2.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 7504450972fa..13d5a04f41df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -64,6 +64,12 @@ gf100_bar_bar1_init(struct nvkm_bar *base) nvkm_wr32(device, 0x001704, 0x80000000 | addr); } +void +gf100_bar_bar2_fini(struct nvkm_bar *bar) +{ + nvkm_mask(bar->subdev.device, 0x001714, 0x80000000, 0x00000000); +} + void gf100_bar_bar2_init(struct nvkm_bar *base) { @@ -190,6 +196,7 @@ gf100_bar_func = { .bar1.fini = gf100_bar_bar1_fini, .bar1.wait = gf100_bar_bar1_wait, .bar2.init = gf100_bar_bar2_init, + .bar2.fini = gf100_bar_bar2_fini, .bar2.wait = gf100_bar_bar1_wait, .kmap = gf100_bar_kmap, .umap = gf100_bar_umap, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index d6d9a1d09722..8d3f7ac42e02 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -76,6 +76,12 @@ nv50_bar_bar1_init(struct nvkm_bar *base) nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); } +void +nv50_bar_bar2_fini(struct nvkm_bar *bar) +{ + nvkm_wr32(bar->subdev.device, 0x00170c, 0x00000000); +} + void nv50_bar_bar2_init(struct nvkm_bar *base) { @@ -224,6 +230,7 @@ nv50_bar_func = { .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, .bar2.init = nv50_bar_bar2_init, + .bar2.fini = nv50_bar_bar2_fini, .bar2.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, .umap = nv50_bar_umap, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index 8c9c897dec5d..9b1c360d62ec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -23,8 +23,10 @@ struct nvkm_bar_func { }; void nv50_bar_bar1_fini(struct nvkm_bar *); +void nv50_bar_bar2_fini(struct nvkm_bar *); void g84_bar_flush(struct nvkm_bar *); void gf100_bar_bar1_fini(struct nvkm_bar *); +void gf100_bar_bar2_fini(struct nvkm_bar *); #endif -- cgit v1.2.3 From 570889dc5070e1f98b5898dce426f970c9b9329b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: modify interface to bar1 vmm mapping Upcoming changes will remove the nvkm_vmm pointer from nvkm_vma, instead requiring it to be explicitly specified on each operation. It's not currently possible to get this information for BAR1 mappings, so let's fix that ahead of time. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/os.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h | 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 5 ++++- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 6 ++++-- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 9 ++++----- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 15 +++++++-------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 2 +- 13 files changed, 32 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h index cd57e238ddd3..cfd9ed361c44 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h @@ -1,4 +1,5 @@ #ifndef __NVKM_OS_H__ #define __NVKM_OS_H__ #include +#define nvkm_vmm nvkm_vm #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h index 11427d3d6173..679027538b12 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h @@ -14,11 +14,11 @@ struct nvkm_bar { bool iomap_uncached; }; +struct nvkm_vmm *nvkm_bar_bar1_vmm(struct nvkm_device *); void nvkm_bar_bar2_init(struct nvkm_device *); void nvkm_bar_bar2_fini(struct nvkm_device *); void nvkm_bar_flush(struct nvkm_bar *); struct nvkm_vm *nvkm_bar_kmap(struct nvkm_bar *); -int nvkm_bar_umap(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); int nv50_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int g84_bar_new(struct nvkm_device *, int, struct nvkm_bar **); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index e427f80344c4..3da87932a21f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1362,13 +1362,13 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) reg->bus.base = device->func->resource_addr(device, 1); reg->bus.is_iomem = true; if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - struct nvkm_bar *bar = nvxx_bar(&drm->client.device); + struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); int page_shift = 12; if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) page_shift = mem->page_shift; - ret = nvkm_bar_umap(bar, mem->size << 12, page_shift, - &mem->bar_vma); + ret = nvkm_vm_get(bar, mem->size << 12, page_shift, + NV_MEM_ACCESS_RW, &mem->bar_vma); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index cd468ab1db12..b1ab34f1a0e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -559,6 +560,7 @@ gf100_fifo_oneinit(struct nvkm_fifo *base) struct gf100_fifo *fifo = gf100_fifo(base); struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; + struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); int ret; /* Determine number of PBDMAs by checking valid enable bits. */ @@ -584,7 +586,8 @@ gf100_fifo_oneinit(struct nvkm_fifo *base) if (ret) return ret; - ret = nvkm_bar_umap(device->bar, 128 * 0x1000, 12, &fifo->user.bar); + ret = nvkm_vm_get(bar, nvkm_memory_size(fifo->user.mem), 12, + NV_MEM_ACCESS_RW, &fifo->user.bar); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index a7e55c422501..cdadff59bb4c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -771,6 +772,7 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) struct gk104_fifo *fifo = gk104_fifo(base); struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; + struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); int engn, runl, pbid, ret, i, j; enum nvkm_devidx engidx; u32 *map; @@ -834,8 +836,8 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) if (ret) return ret; - ret = nvkm_bar_umap(device->bar, fifo->base.nr * 0x200, 12, - &fifo->user.bar); + ret = nvkm_vm_get(bar, nvkm_memory_size(fifo->user.mem), 12, + NV_MEM_ACCESS_RW, &fifo->user.bar); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index b495f7796fa3..5a80cf5f9eb0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -39,10 +39,10 @@ nvkm_bar_kmap(struct nvkm_bar *bar) return NULL; } -int -nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma) +struct nvkm_vmm * +nvkm_bar_bar1_vmm(struct nvkm_device *device) { - return bar->func->umap(bar, size, type, vma); + return device->bar->func->bar1.vmm(device->bar); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c index dce74e0d2591..f88f5d6e64b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c @@ -47,11 +47,11 @@ g84_bar_func = { .bar1.init = nv50_bar_bar1_init, .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, + .bar1.vmm = nv50_bar_bar1_vmm, .bar2.init = nv50_bar_bar2_init, .bar2.fini = nv50_bar_bar2_fini, .bar2.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, - .umap = nv50_bar_umap, .flush = g84_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 13d5a04f41df..379fa339dbaf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -34,11 +34,10 @@ gf100_bar_kmap(struct nvkm_bar *base) return gf100_bar(base)->bar[0].vm; } -int -gf100_bar_umap(struct nvkm_bar *base, u64 size, int type, struct nvkm_vma *vma) +struct nvkm_vmm * +gf100_bar_bar1_vmm(struct nvkm_bar *base) { - struct gf100_bar *bar = gf100_bar(base); - return nvkm_vm_get(bar->bar[1].vm, size, type, NV_MEM_ACCESS_RW, vma); + return gf100_bar(base)->bar[1].vm; } void @@ -195,11 +194,11 @@ gf100_bar_func = { .bar1.init = gf100_bar_bar1_init, .bar1.fini = gf100_bar_bar1_fini, .bar1.wait = gf100_bar_bar1_wait, + .bar1.vmm = gf100_bar_bar1_vmm, .bar2.init = gf100_bar_bar2_init, .bar2.fini = gf100_bar_bar2_fini, .bar2.wait = gf100_bar_bar1_wait, .kmap = gf100_bar_kmap, - .umap = gf100_bar_umap, .flush = g84_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index 393116a7398a..c56c8989b2a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -21,6 +21,6 @@ void *gf100_bar_dtor(struct nvkm_bar *); int gf100_bar_oneinit(struct nvkm_bar *); void gf100_bar_bar1_init(struct nvkm_bar *); void gf100_bar_bar1_wait(struct nvkm_bar *); +struct nvkm_vmm *gf100_bar_bar1_vmm(struct nvkm_bar *); void gf100_bar_bar2_init(struct nvkm_bar *); -int gf100_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c index ab4664b4b2b2..b10077d38839 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c @@ -28,7 +28,7 @@ gk20a_bar_func = { .bar1.init = gf100_bar_bar1_init, .bar1.fini = gf100_bar_bar1_fini, .bar1.wait = gf100_bar_bar1_wait, - .umap = gf100_bar_umap, + .bar1.vmm = gf100_bar_bar1_vmm, .flush = g84_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 8d3f7ac42e02..8020cc996d1a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -34,13 +34,6 @@ nv50_bar_kmap(struct nvkm_bar *base) return nv50_bar(base)->bar2_vm; } -int -nv50_bar_umap(struct nvkm_bar *base, u64 size, int type, struct nvkm_vma *vma) -{ - struct nv50_bar *bar = nv50_bar(base); - return nvkm_vm_get(bar->bar1_vm, size, type, NV_MEM_ACCESS_RW, vma); -} - static void nv50_bar_flush(struct nvkm_bar *base) { @@ -56,6 +49,12 @@ nv50_bar_flush(struct nvkm_bar *base) spin_unlock_irqrestore(&bar->base.lock, flags); } +struct nvkm_vmm * +nv50_bar_bar1_vmm(struct nvkm_bar *base) +{ + return nv50_bar(base)->bar1_vm; +} + void nv50_bar_bar1_wait(struct nvkm_bar *base) { @@ -229,11 +228,11 @@ nv50_bar_func = { .bar1.init = nv50_bar_bar1_init, .bar1.fini = nv50_bar_bar1_fini, .bar1.wait = nv50_bar_bar1_wait, + .bar1.vmm = nv50_bar_bar1_vmm, .bar2.init = nv50_bar_bar2_init, .bar2.fini = nv50_bar_bar2_fini, .bar2.wait = nv50_bar_bar1_wait, .kmap = nv50_bar_kmap, - .umap = nv50_bar_umap, .flush = nv50_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index 0009ed4344f0..24ca9a52cb42 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -22,8 +22,8 @@ int nv50_bar_oneinit(struct nvkm_bar *); void nv50_bar_init(struct nvkm_bar *); void nv50_bar_bar1_init(struct nvkm_bar *); void nv50_bar_bar1_wait(struct nvkm_bar *); +struct nvkm_vmm *nv50_bar_bar1_vmm(struct nvkm_bar *); void nv50_bar_bar2_init(struct nvkm_bar *); struct nvkm_vm *nv50_bar_kmap(struct nvkm_bar *); -int nv50_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index 9b1c360d62ec..5aa220e204ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -15,10 +15,10 @@ struct nvkm_bar_func { void (*init)(struct nvkm_bar *); void (*fini)(struct nvkm_bar *); void (*wait)(struct nvkm_bar *); + struct nvkm_vmm *(*vmm)(struct nvkm_bar *); } bar1, bar2; struct nvkm_vm *(*kmap)(struct nvkm_bar *); - int (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); void (*flush)(struct nvkm_bar *); }; -- cgit v1.2.3 From a78dbce9a161a3a985b837bd07afd8651d42cabd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: modify interface to bar2 vmm mapping Match API with the BAR1 version. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 19 +++++++++++-------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 16 ++++++++-------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 14 +++++++------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h | 3 +-- drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 3 +-- 9 files changed, 31 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h index 679027538b12..75ef15cd8b41 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h @@ -17,8 +17,8 @@ struct nvkm_bar { struct nvkm_vmm *nvkm_bar_bar1_vmm(struct nvkm_device *); void nvkm_bar_bar2_init(struct nvkm_device *); void nvkm_bar_bar2_fini(struct nvkm_device *); +struct nvkm_vmm *nvkm_bar_bar2_vmm(struct nvkm_device *); void nvkm_bar_flush(struct nvkm_bar *); -struct nvkm_vm *nvkm_bar_kmap(struct nvkm_bar *); int nv50_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int g84_bar_new(struct nvkm_device *, int, struct nvkm_bar **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index 5a80cf5f9eb0..d600aafae315 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -30,19 +30,22 @@ nvkm_bar_flush(struct nvkm_bar *bar) bar->func->flush(bar); } -struct nvkm_vm * -nvkm_bar_kmap(struct nvkm_bar *bar) +struct nvkm_vmm * +nvkm_bar_bar1_vmm(struct nvkm_device *device) { - /* disallow kmap() until after vm has been bootstrapped */ - if (bar && bar->func->kmap && bar->subdev.oneinit) - return bar->func->kmap(bar); - return NULL; + return device->bar->func->bar1.vmm(device->bar); } struct nvkm_vmm * -nvkm_bar_bar1_vmm(struct nvkm_device *device) +nvkm_bar_bar2_vmm(struct nvkm_device *device) { - return device->bar->func->bar1.vmm(device->bar); + /* Denies access to BAR2 when it's not initialised, used by INSTMEM + * to know when object access needs to go through the BAR0 window. + */ + struct nvkm_bar *bar = device->bar; + if (bar && bar->func->bar2.vmm && bar->subdev.oneinit) + return bar->func->bar2.vmm(bar); + return NULL; } void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c index f88f5d6e64b9..87f26f54b481 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c @@ -51,7 +51,7 @@ g84_bar_func = { .bar2.init = nv50_bar_bar2_init, .bar2.fini = nv50_bar_bar2_fini, .bar2.wait = nv50_bar_bar1_wait, - .kmap = nv50_bar_kmap, + .bar2.vmm = nv50_bar_bar2_vmm, .flush = g84_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 379fa339dbaf..c6317a0f04a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -28,12 +28,6 @@ #include #include -static struct nvkm_vm * -gf100_bar_kmap(struct nvkm_bar *base) -{ - return gf100_bar(base)->bar[0].vm; -} - struct nvkm_vmm * gf100_bar_bar1_vmm(struct nvkm_bar *base) { @@ -63,6 +57,12 @@ gf100_bar_bar1_init(struct nvkm_bar *base) nvkm_wr32(device, 0x001704, 0x80000000 | addr); } +struct nvkm_vmm * +gf100_bar_bar2_vmm(struct nvkm_bar *base) +{ + return gf100_bar(base)->bar[0].vm; +} + void gf100_bar_bar2_fini(struct nvkm_bar *bar) { @@ -142,7 +142,7 @@ gf100_bar_oneinit(struct nvkm_bar *base) int ret; /* BAR2 */ - if (bar->base.func->kmap) { + if (bar->base.func->bar2.init) { ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, 3); if (ret) return ret; @@ -198,7 +198,7 @@ gf100_bar_func = { .bar2.init = gf100_bar_bar2_init, .bar2.fini = gf100_bar_bar2_fini, .bar2.wait = gf100_bar_bar1_wait, - .kmap = gf100_bar_kmap, + .bar2.vmm = gf100_bar_bar2_vmm, .flush = g84_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index c56c8989b2a1..fc1a7bd975a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -23,4 +23,5 @@ void gf100_bar_bar1_init(struct nvkm_bar *); void gf100_bar_bar1_wait(struct nvkm_bar *); struct nvkm_vmm *gf100_bar_bar1_vmm(struct nvkm_bar *); void gf100_bar_bar2_init(struct nvkm_bar *); +struct nvkm_vmm *gf100_bar_bar2_vmm(struct nvkm_bar *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 8020cc996d1a..4b912c905551 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -28,12 +28,6 @@ #include #include -struct nvkm_vm * -nv50_bar_kmap(struct nvkm_bar *base) -{ - return nv50_bar(base)->bar2_vm; -} - static void nv50_bar_flush(struct nvkm_bar *base) { @@ -75,6 +69,12 @@ nv50_bar_bar1_init(struct nvkm_bar *base) nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); } +struct nvkm_vmm * +nv50_bar_bar2_vmm(struct nvkm_bar *base) +{ + return nv50_bar(base)->bar2_vm; +} + void nv50_bar_bar2_fini(struct nvkm_bar *bar) { @@ -232,7 +232,7 @@ nv50_bar_func = { .bar2.init = nv50_bar_bar2_init, .bar2.fini = nv50_bar_bar2_fini, .bar2.wait = nv50_bar_bar1_wait, - .kmap = nv50_bar_kmap, + .bar2.vmm = nv50_bar_bar2_vmm, .flush = nv50_bar_flush, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index 24ca9a52cb42..b5fe26aab118 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -24,6 +24,5 @@ void nv50_bar_bar1_init(struct nvkm_bar *); void nv50_bar_bar1_wait(struct nvkm_bar *); struct nvkm_vmm *nv50_bar_bar1_vmm(struct nvkm_bar *); void nv50_bar_bar2_init(struct nvkm_bar *); -struct nvkm_vm *nv50_bar_kmap(struct nvkm_bar *); -void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *); +struct nvkm_vmm *nv50_bar_bar2_vmm(struct nvkm_bar *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index 5aa220e204ee..f9a07b6d2860 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -18,7 +18,6 @@ struct nvkm_bar_func { struct nvkm_vmm *(*vmm)(struct nvkm_bar *); } bar1, bar2; - struct nvkm_vm *(*kmap)(struct nvkm_bar *); void (*flush)(struct nvkm_bar *); }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 6d512c062ae3..a3cd3e193d03 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -107,11 +107,10 @@ nv50_instobj_acquire(struct nvkm_memory *memory) { struct nv50_instobj *iobj = nv50_instobj(memory); struct nv50_instmem *imem = iobj->imem; - struct nvkm_bar *bar = imem->base.subdev.device->bar; struct nvkm_vm *vm; unsigned long flags; - if (!iobj->map && (vm = nvkm_bar_kmap(bar))) + if (!iobj->map && (vm = nvkm_bar_bar2_vmm(imem->base.subdev.device))) nvkm_memory_boot(memory, vm); if (!IS_ERR_OR_NULL(iobj->map)) return iobj->map; -- cgit v1.2.3 From bb7e501a661f820788279063fd9e225bbe9c38e9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: prevent BAR2 mapping of objects during destructor GP100's page table nests a lot more deeply than the GF100-compatible layout we're currently using, which means our hackish-but-simple way of dealing with BAR2 VMM teardown won't work anymore. In order to sanely handle the chicken-and-egg (BAR2's PTs get mapped into themselves) problem, we need prevent page tables getting mapped back into BAR2 during the destruction of its VMM. To do this, we simply key off the state that's now maintained by the BAR2 init/fini functions. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index d600aafae315..c8cb8b8b1323 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -43,7 +43,7 @@ nvkm_bar_bar2_vmm(struct nvkm_device *device) * to know when object access needs to go through the BAR0 window. */ struct nvkm_bar *bar = device->bar; - if (bar && bar->func->bar2.vmm && bar->subdev.oneinit) + if (bar && bar->bar2) return bar->func->bar2.vmm(bar); return NULL; } -- cgit v1.2.3 From 8e644cb29c33dcd2fb718d78d8c33d4eb88cf6f7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar: initialise bar2 during oneinit If we initialise BAR2 earlier, we're able to complete BAR1 setup using the instmem fast-path. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index c6317a0f04a7..b155a7f76ca7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -146,6 +146,9 @@ gf100_bar_oneinit(struct nvkm_bar *base) ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, 3); if (ret) return ret; + + bar->base.subdev.oneinit = true; + nvkm_bar_bar2_init(bar->base.subdev.device); } /* BAR1 */ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 4b912c905551..cf1d0acd2afc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -159,6 +159,9 @@ nv50_bar_oneinit(struct nvkm_bar *base) nvkm_wo32(bar->bar2, 0x14, 0x00000000); nvkm_done(bar->bar2); + bar->base.subdev.oneinit = true; + nvkm_bar_bar2_init(device); + /* BAR1 */ start = 0x0000000000ULL; limit = start + device->func->resource_size(device, 1); -- cgit v1.2.3 From 70433b904a8b6865558ae33cadd8bb85c0d98e12 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar/gm107-: wait for instance block binding to complete Discovered by accident while working to use BAR2 access to instmem objects on more paths. We've apparently been relying on luck up until now! Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h | 2 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 26 ++++----- drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm107.c | 65 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm20b.c | 42 +++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h | 2 + 6 files changed, 126 insertions(+), 13 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm107.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm20b.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h index 75ef15cd8b41..ffa963939e15 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h @@ -24,4 +24,6 @@ int nv50_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int g84_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int gf100_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int gk20a_bar_new(struct nvkm_device *, int, struct nvkm_bar **); +int gm107_bar_new(struct nvkm_device *, int, struct nvkm_bar **); +int gm20b_bar_new(struct nvkm_device *, int, struct nvkm_bar **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 28fd4fa98635..77fe1c145498 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -1958,7 +1958,7 @@ nv108_chipset = { static const struct nvkm_device_chip nv117_chipset = { .name = "GM107", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .clk = gk104_clk_new, @@ -1992,7 +1992,7 @@ nv117_chipset = { static const struct nvkm_device_chip nv118_chipset = { .name = "GM108", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .clk = gk104_clk_new, @@ -2026,7 +2026,7 @@ nv118_chipset = { static const struct nvkm_device_chip nv120_chipset = { .name = "GM200", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2061,7 +2061,7 @@ nv120_chipset = { static const struct nvkm_device_chip nv124_chipset = { .name = "GM204", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2096,7 +2096,7 @@ nv124_chipset = { static const struct nvkm_device_chip nv126_chipset = { .name = "GM206", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2131,7 +2131,7 @@ nv126_chipset = { static const struct nvkm_device_chip nv12b_chipset = { .name = "GM20B", - .bar = gk20a_bar_new, + .bar = gm20b_bar_new, .bus = gf100_bus_new, .clk = gm20b_clk_new, .fb = gm20b_fb_new, @@ -2156,7 +2156,7 @@ nv12b_chipset = { static const struct nvkm_device_chip nv130_chipset = { .name = "GP100", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2191,7 +2191,7 @@ nv130_chipset = { static const struct nvkm_device_chip nv132_chipset = { .name = "GP102", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2226,7 +2226,7 @@ nv132_chipset = { static const struct nvkm_device_chip nv134_chipset = { .name = "GP104", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2261,7 +2261,7 @@ nv134_chipset = { static const struct nvkm_device_chip nv136_chipset = { .name = "GP106", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2296,7 +2296,7 @@ nv136_chipset = { static const struct nvkm_device_chip nv137_chipset = { .name = "GP107", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2331,7 +2331,7 @@ nv137_chipset = { static const struct nvkm_device_chip nv138_chipset = { .name = "GP108", - .bar = gf100_bar_new, + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, @@ -2361,7 +2361,7 @@ nv138_chipset = { static const struct nvkm_device_chip nv13b_chipset = { .name = "GP10B", - .bar = gk20a_bar_new, + .bar = gm20b_bar_new, .bus = gf100_bus_new, .fb = gp10b_fb_new, .fuse = gm107_fuse_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild index 1e138b337955..e5830453813d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild @@ -3,3 +3,5 @@ nvkm-y += nvkm/subdev/bar/nv50.o nvkm-y += nvkm/subdev/bar/g84.o nvkm-y += nvkm/subdev/bar/gf100.o nvkm-y += nvkm/subdev/bar/gk20a.o +nvkm-y += nvkm/subdev/bar/gm107.o +nvkm-y += nvkm/subdev/bar/gm20b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm107.c new file mode 100644 index 000000000000..3ddf9222d935 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm107.c @@ -0,0 +1,65 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "gf100.h" + +#include + +void +gm107_bar_bar1_wait(struct nvkm_bar *bar) +{ + struct nvkm_device *device = bar->subdev.device; + nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x001710) & 0x00000003)) + break; + ); +} + +static void +gm107_bar_bar2_wait(struct nvkm_bar *bar) +{ + struct nvkm_device *device = bar->subdev.device; + nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x001710) & 0x0000000c)) + break; + ); +} + +static const struct nvkm_bar_func +gm107_bar_func = { + .dtor = gf100_bar_dtor, + .oneinit = gf100_bar_oneinit, + .bar1.init = gf100_bar_bar1_init, + .bar1.fini = gf100_bar_bar1_fini, + .bar1.wait = gm107_bar_bar1_wait, + .bar1.vmm = gf100_bar_bar1_vmm, + .bar2.init = gf100_bar_bar2_init, + .bar2.fini = gf100_bar_bar2_fini, + .bar2.wait = gm107_bar_bar2_wait, + .bar2.vmm = gf100_bar_bar2_vmm, + .flush = g84_bar_flush, +}; + +int +gm107_bar_new(struct nvkm_device *device, int index, struct nvkm_bar **pbar) +{ + return gf100_bar_new_(&gm107_bar_func, device, index, pbar); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm20b.c new file mode 100644 index 000000000000..950bff1955ad --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gm20b.c @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "gf100.h" + +static const struct nvkm_bar_func +gm20b_bar_func = { + .dtor = gf100_bar_dtor, + .oneinit = gf100_bar_oneinit, + .bar1.init = gf100_bar_bar1_init, + .bar1.fini = gf100_bar_bar1_fini, + .bar1.wait = gm107_bar_bar1_wait, + .bar1.vmm = gf100_bar_bar1_vmm, + .flush = g84_bar_flush, +}; + +int +gm20b_bar_new(struct nvkm_device *device, int index, struct nvkm_bar **pbar) +{ + int ret = gf100_bar_new_(&gm20b_bar_func, device, index, pbar); + if (ret == 0) + (*pbar)->iomap_uncached = true; + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index f9a07b6d2860..14398e2dbdf9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -28,4 +28,6 @@ void g84_bar_flush(struct nvkm_bar *); void gf100_bar_bar1_fini(struct nvkm_bar *); void gf100_bar_bar2_fini(struct nvkm_bar *); + +void gm107_bar_bar1_wait(struct nvkm_bar *); #endif -- cgit v1.2.3 From dde59b9c341a1b5ce2229f7d4a57f19435da82d7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: add some useful debug output Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 10c987a654ec..372f01ba7766 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -174,14 +174,20 @@ int nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, struct nvkm_memory **pmemory) { + struct nvkm_subdev *subdev = &imem->subdev; struct nvkm_memory *memory = NULL; struct nvkm_instobj *iobj; u32 offset; int ret; ret = imem->func->memory_new(imem, size, align, zero, &memory); - if (ret) + if (ret) { + nvkm_error(subdev, "OOM: %08x %08x %d\n", size, align, ret); goto done; + } + + nvkm_trace(subdev, "new %08x %08x %d: %010llx %010llx\n", size, align, + zero, nvkm_memory_addr(memory), nvkm_memory_size(memory)); if (!imem->func->persistent) { if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) { -- cgit v1.2.3 From 07bbc1c5f49b64323d9e5c1e0d5d7d201e1f2627 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/memory: split info pointers from accessor pointers The accessor functions can change as a result of acquire()/release() calls, and are protected by any refcounting done there. Other functions must remain constant, as they can be called any time. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h | 5 +- drivers/gpu/drm/nouveau/include/nvkm/core/memory.h | 10 +- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 17 ++- .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 10 +- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c | 51 ++++---- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 47 ++++---- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 133 +++++++++++---------- 7 files changed, 155 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h index 1d7ccde7cde8..acd07de3e4ee 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h @@ -9,7 +9,10 @@ struct nvkm_vm; #define NVOBJ_FLAG_HEAP 0x00000004 struct nvkm_gpuobj { - const struct nvkm_gpuobj_func *func; + union { + const struct nvkm_gpuobj_func *func; + const struct nvkm_gpuobj_func *ptrs; + }; struct nvkm_gpuobj *parent; struct nvkm_memory *memory; struct nvkm_mm_node *node; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h index 33ca6769266a..14ce7df9864e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -14,6 +14,7 @@ enum nvkm_memory_target { struct nvkm_memory { const struct nvkm_memory_func *func; + const struct nvkm_memory_ptrs *ptrs; }; struct nvkm_memory_func { @@ -24,9 +25,12 @@ struct nvkm_memory_func { void (*boot)(struct nvkm_memory *, struct nvkm_vm *); void __iomem *(*acquire)(struct nvkm_memory *); void (*release)(struct nvkm_memory *); + void (*map)(struct nvkm_memory *, struct nvkm_vma *, u64 offset); +}; + +struct nvkm_memory_ptrs { u32 (*rd32)(struct nvkm_memory *, u64 offset); void (*wr32)(struct nvkm_memory *, u64 offset, u32 data); - void (*map)(struct nvkm_memory *, struct nvkm_vma *, u64 offset); }; void nvkm_memory_ctor(const struct nvkm_memory_func *, struct nvkm_memory *); @@ -43,8 +47,8 @@ void nvkm_memory_del(struct nvkm_memory **); * macros to guarantee correct behaviour across all chipsets */ #define nvkm_kmap(o) (o)->func->acquire(o) -#define nvkm_ro32(o,a) (o)->func->rd32((o), (a)) -#define nvkm_wo32(o,a,d) (o)->func->wr32((o), (a), (d)) +#define nvkm_ro32(o,a) (o)->ptrs->rd32((o), (a)) +#define nvkm_wo32(o,a,d) (o)->ptrs->wr32((o), (a), (d)) #define nvkm_mo32(o,a,m,d) ({ \ u32 _addr = (a), _data = nvkm_ro32((o), _addr); \ nvkm_wo32((o), _addr, (_data & ~(m)) | (d)); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 372f01ba7766..a15125ed455d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -112,9 +112,13 @@ nvkm_instobj_func = { .size = nvkm_instobj_size, .acquire = nvkm_instobj_acquire, .release = nvkm_instobj_release, + .map = nvkm_instobj_map, +}; + +static const struct nvkm_memory_ptrs +nvkm_instobj_ptrs = { .rd32 = nvkm_instobj_rd32, .wr32 = nvkm_instobj_wr32, - .map = nvkm_instobj_map, }; static void @@ -137,8 +141,10 @@ nvkm_instobj_acquire_slow(struct nvkm_memory *memory) { struct nvkm_instobj *iobj = nvkm_instobj(memory); iobj->map = nvkm_kmap(iobj->parent); - if (iobj->map) + if (iobj->map) { memory->func = &nvkm_instobj_func; + memory->ptrs = &nvkm_instobj_ptrs; + } return iobj->map; } @@ -165,9 +171,13 @@ nvkm_instobj_func_slow = { .boot = nvkm_instobj_boot, .acquire = nvkm_instobj_acquire_slow, .release = nvkm_instobj_release_slow, + .map = nvkm_instobj_map, +}; + +static const struct nvkm_memory_ptrs +nvkm_instobj_ptrs_slow = { .rd32 = nvkm_instobj_rd32_slow, .wr32 = nvkm_instobj_wr32_slow, - .map = nvkm_instobj_map, }; int @@ -196,6 +206,7 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, } nvkm_memory_ctor(&nvkm_instobj_func_slow, &iobj->memory); + iobj->memory.ptrs = &nvkm_instobj_ptrs_slow; iobj->parent = memory; iobj->imem = imem; spin_lock(&iobj->imem->lock); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index cd5adbec5e57..41bf8770cfd7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -346,8 +346,6 @@ gk20a_instobj_func_dma = { .size = gk20a_instobj_size, .acquire = gk20a_instobj_acquire_dma, .release = gk20a_instobj_release_dma, - .rd32 = gk20a_instobj_rd32, - .wr32 = gk20a_instobj_wr32, .map = gk20a_instobj_map, }; @@ -359,9 +357,13 @@ gk20a_instobj_func_iommu = { .size = gk20a_instobj_size, .acquire = gk20a_instobj_acquire_iommu, .release = gk20a_instobj_release_iommu, + .map = gk20a_instobj_map, +}; + +static const struct nvkm_memory_ptrs +gk20a_instobj_ptrs = { .rd32 = gk20a_instobj_rd32, .wr32 = gk20a_instobj_wr32, - .map = gk20a_instobj_map, }; static int @@ -377,6 +379,7 @@ gk20a_instobj_ctor_dma(struct gk20a_instmem *imem, u32 npages, u32 align, *_node = &node->base; nvkm_memory_ctor(&gk20a_instobj_func_dma, &node->base.memory); + node->base.memory.ptrs = &gk20a_instobj_ptrs; node->base.vaddr = dma_alloc_attrs(dev, npages << PAGE_SHIFT, &node->handle, GFP_KERNEL, @@ -424,6 +427,7 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align, node->dma_addrs = (void *)(node->pages + npages); nvkm_memory_ctor(&gk20a_instobj_func_iommu, &node->base.memory); + node->base.memory.ptrs = &gk20a_instobj_ptrs; /* Allocate backing memory */ for (i = 0; i < npages; i++) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index 6133c8bb2d42..d4176cc67708 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c @@ -43,22 +43,31 @@ struct nv04_instobj { struct nvkm_mm_node *node; }; -static enum nvkm_memory_target -nv04_instobj_target(struct nvkm_memory *memory) +static void +nv04_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) { - return NVKM_MEM_TARGET_INST; + struct nv04_instobj *iobj = nv04_instobj(memory); + struct nvkm_device *device = iobj->imem->base.subdev.device; + nvkm_wr32(device, 0x700000 + iobj->node->offset + offset, data); } -static u64 -nv04_instobj_addr(struct nvkm_memory *memory) +static u32 +nv04_instobj_rd32(struct nvkm_memory *memory, u64 offset) { - return nv04_instobj(memory)->node->offset; + struct nv04_instobj *iobj = nv04_instobj(memory); + struct nvkm_device *device = iobj->imem->base.subdev.device; + return nvkm_rd32(device, 0x700000 + iobj->node->offset + offset); } -static u64 -nv04_instobj_size(struct nvkm_memory *memory) +static const struct nvkm_memory_ptrs +nv04_instobj_ptrs = { + .rd32 = nv04_instobj_rd32, + .wr32 = nv04_instobj_wr32, +}; + +static void +nv04_instobj_release(struct nvkm_memory *memory) { - return nv04_instobj(memory)->node->length; } static void __iomem * @@ -69,25 +78,22 @@ nv04_instobj_acquire(struct nvkm_memory *memory) return device->pri + 0x700000 + iobj->node->offset; } -static void -nv04_instobj_release(struct nvkm_memory *memory) +static u64 +nv04_instobj_size(struct nvkm_memory *memory) { + return nv04_instobj(memory)->node->length; } -static u32 -nv04_instobj_rd32(struct nvkm_memory *memory, u64 offset) +static u64 +nv04_instobj_addr(struct nvkm_memory *memory) { - struct nv04_instobj *iobj = nv04_instobj(memory); - struct nvkm_device *device = iobj->imem->base.subdev.device; - return nvkm_rd32(device, 0x700000 + iobj->node->offset + offset); + return nv04_instobj(memory)->node->offset; } -static void -nv04_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) +static enum nvkm_memory_target +nv04_instobj_target(struct nvkm_memory *memory) { - struct nv04_instobj *iobj = nv04_instobj(memory); - struct nvkm_device *device = iobj->imem->base.subdev.device; - nvkm_wr32(device, 0x700000 + iobj->node->offset + offset, data); + return NVKM_MEM_TARGET_INST; } static void * @@ -108,8 +114,6 @@ nv04_instobj_func = { .addr = nv04_instobj_addr, .acquire = nv04_instobj_acquire, .release = nv04_instobj_release, - .rd32 = nv04_instobj_rd32, - .wr32 = nv04_instobj_wr32, }; static int @@ -125,6 +129,7 @@ nv04_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, *pmemory = &iobj->memory; nvkm_memory_ctor(&nv04_instobj_func, &iobj->memory); + iobj->memory.ptrs = &nv04_instobj_ptrs; iobj->imem = imem; mutex_lock(&imem->base.subdev.mutex); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index c0543875e490..5fa2b7c0decc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -45,22 +45,29 @@ struct nv40_instobj { struct nvkm_mm_node *node; }; -static enum nvkm_memory_target -nv40_instobj_target(struct nvkm_memory *memory) +static void +nv40_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) { - return NVKM_MEM_TARGET_INST; + struct nv40_instobj *iobj = nv40_instobj(memory); + iowrite32_native(data, iobj->imem->iomem + iobj->node->offset + offset); } -static u64 -nv40_instobj_addr(struct nvkm_memory *memory) +static u32 +nv40_instobj_rd32(struct nvkm_memory *memory, u64 offset) { - return nv40_instobj(memory)->node->offset; + struct nv40_instobj *iobj = nv40_instobj(memory); + return ioread32_native(iobj->imem->iomem + iobj->node->offset + offset); } -static u64 -nv40_instobj_size(struct nvkm_memory *memory) +static const struct nvkm_memory_ptrs +nv40_instobj_ptrs = { + .rd32 = nv40_instobj_rd32, + .wr32 = nv40_instobj_wr32, +}; + +static void +nv40_instobj_release(struct nvkm_memory *memory) { - return nv40_instobj(memory)->node->length; } static void __iomem * @@ -70,23 +77,22 @@ nv40_instobj_acquire(struct nvkm_memory *memory) return iobj->imem->iomem + iobj->node->offset; } -static void -nv40_instobj_release(struct nvkm_memory *memory) +static u64 +nv40_instobj_size(struct nvkm_memory *memory) { + return nv40_instobj(memory)->node->length; } -static u32 -nv40_instobj_rd32(struct nvkm_memory *memory, u64 offset) +static u64 +nv40_instobj_addr(struct nvkm_memory *memory) { - struct nv40_instobj *iobj = nv40_instobj(memory); - return ioread32_native(iobj->imem->iomem + iobj->node->offset + offset); + return nv40_instobj(memory)->node->offset; } -static void -nv40_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) +static enum nvkm_memory_target +nv40_instobj_target(struct nvkm_memory *memory) { - struct nv40_instobj *iobj = nv40_instobj(memory); - iowrite32_native(data, iobj->imem->iomem + iobj->node->offset + offset); + return NVKM_MEM_TARGET_INST; } static void * @@ -107,8 +113,6 @@ nv40_instobj_func = { .addr = nv40_instobj_addr, .acquire = nv40_instobj_acquire, .release = nv40_instobj_release, - .rd32 = nv40_instobj_rd32, - .wr32 = nv40_instobj_wr32, }; static int @@ -124,6 +128,7 @@ nv40_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, *pmemory = &iobj->memory; nvkm_memory_ctor(&nv40_instobj_func, &iobj->memory); + iobj->memory.ptrs = &nv40_instobj_ptrs; iobj->imem = imem; mutex_lock(&imem->base.subdev.mutex); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index a3cd3e193d03..e3273aed3381 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -49,50 +49,51 @@ struct nv50_instobj { void *map; }; -static enum nvkm_memory_target -nv50_instobj_target(struct nvkm_memory *memory) +static void +nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data) { - return NVKM_MEM_TARGET_VRAM; -} + struct nv50_instobj *iobj = nv50_instobj(memory); + struct nv50_instmem *imem = iobj->imem; + struct nvkm_device *device = imem->base.subdev.device; + u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; + u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; -static u64 -nv50_instobj_addr(struct nvkm_memory *memory) -{ - return nv50_instobj(memory)->mem->offset; + if (unlikely(imem->addr != base)) { + nvkm_wr32(device, 0x001700, base >> 16); + imem->addr = base; + } + nvkm_wr32(device, 0x700000 + addr, data); } -static u64 -nv50_instobj_size(struct nvkm_memory *memory) +static u32 +nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset) { - return (u64)nv50_instobj(memory)->mem->size << NVKM_RAM_MM_SHIFT; + struct nv50_instobj *iobj = nv50_instobj(memory); + struct nv50_instmem *imem = iobj->imem; + struct nvkm_device *device = imem->base.subdev.device; + u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; + u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; + u32 data; + + if (unlikely(imem->addr != base)) { + nvkm_wr32(device, 0x001700, base >> 16); + imem->addr = base; + } + data = nvkm_rd32(device, 0x700000 + addr); + return data; } +static const struct nvkm_memory_ptrs +nv50_instobj_slow = { + .rd32 = nv50_instobj_rd32_slow, + .wr32 = nv50_instobj_wr32_slow, +}; + static void -nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm) +nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) { struct nv50_instobj *iobj = nv50_instobj(memory); - struct nvkm_subdev *subdev = &iobj->imem->base.subdev; - struct nvkm_device *device = subdev->device; - u64 size = nvkm_memory_size(memory); - void __iomem *map; - int ret; - - iobj->map = ERR_PTR(-ENOMEM); - - ret = nvkm_vm_get(vm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar); - if (ret == 0) { - map = ioremap(device->func->resource_addr(device, 3) + - (u32)iobj->bar.offset, size); - if (map) { - nvkm_memory_map(memory, &iobj->bar, 0); - iobj->map = map; - } else { - nvkm_warn(subdev, "PRAMIN ioremap failed\n"); - nvkm_vm_put(&iobj->bar); - } - } else { - nvkm_warn(subdev, "PRAMIN exhausted\n"); - } + nvkm_vm_map_at(vma, offset, iobj->mem); } static void @@ -120,45 +121,50 @@ nv50_instobj_acquire(struct nvkm_memory *memory) return NULL; } -static u32 -nv50_instobj_rd32(struct nvkm_memory *memory, u64 offset) +static void +nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm) { struct nv50_instobj *iobj = nv50_instobj(memory); - struct nv50_instmem *imem = iobj->imem; - struct nvkm_device *device = imem->base.subdev.device; - u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; - u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; - u32 data; + struct nvkm_subdev *subdev = &iobj->imem->base.subdev; + struct nvkm_device *device = subdev->device; + u64 size = nvkm_memory_size(memory); + void __iomem *map; + int ret; - if (unlikely(imem->addr != base)) { - nvkm_wr32(device, 0x001700, base >> 16); - imem->addr = base; + iobj->map = ERR_PTR(-ENOMEM); + + ret = nvkm_vm_get(vm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar); + if (ret == 0) { + map = ioremap(device->func->resource_addr(device, 3) + + (u32)iobj->bar.offset, size); + if (map) { + nvkm_memory_map(memory, &iobj->bar, 0); + iobj->map = map; + } else { + nvkm_warn(subdev, "PRAMIN ioremap failed\n"); + nvkm_vm_put(&iobj->bar); + } + } else { + nvkm_warn(subdev, "PRAMIN exhausted\n"); } - data = nvkm_rd32(device, 0x700000 + addr); - return data; } -static void -nv50_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) +static u64 +nv50_instobj_size(struct nvkm_memory *memory) { - struct nv50_instobj *iobj = nv50_instobj(memory); - struct nv50_instmem *imem = iobj->imem; - struct nvkm_device *device = imem->base.subdev.device; - u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; - u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; + return (u64)nv50_instobj(memory)->mem->size << NVKM_RAM_MM_SHIFT; +} - if (unlikely(imem->addr != base)) { - nvkm_wr32(device, 0x001700, base >> 16); - imem->addr = base; - } - nvkm_wr32(device, 0x700000 + addr, data); +static u64 +nv50_instobj_addr(struct nvkm_memory *memory) +{ + return nv50_instobj(memory)->mem->offset; } -static void -nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) +static enum nvkm_memory_target +nv50_instobj_target(struct nvkm_memory *memory) { - struct nv50_instobj *iobj = nv50_instobj(memory); - nvkm_vm_map_at(vma, offset, iobj->mem); + return NVKM_MEM_TARGET_VRAM; } static void * @@ -183,8 +189,6 @@ nv50_instobj_func = { .boot = nv50_instobj_boot, .acquire = nv50_instobj_acquire, .release = nv50_instobj_release, - .rd32 = nv50_instobj_rd32, - .wr32 = nv50_instobj_wr32, .map = nv50_instobj_map, }; @@ -202,6 +206,7 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, *pmemory = &iobj->memory; nvkm_memory_ctor(&nv50_instobj_func, &iobj->memory); + iobj->memory.ptrs = &nv50_instobj_slow; iobj->imem = imem; size = max((size + 4095) & ~4095, (u32)4096); -- cgit v1.2.3 From 49814f62a26bd5b8f2ad5a16ccb1340ede30ee1a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: allow nvkm_instobj to be directly embedded in backend object This will eliminate a step through the call chain, and give backends more flexibility. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 36 ++++++++++++++-------- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h | 15 +++++++++ 2 files changed, 38 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index a15125ed455d..78f9c2332edd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -23,7 +23,6 @@ */ #include "priv.h" -#include #include /****************************************************************************** @@ -31,15 +30,6 @@ *****************************************************************************/ #define nvkm_instobj(p) container_of((p), struct nvkm_instobj, memory) -struct nvkm_instobj { - struct nvkm_memory memory; - struct nvkm_memory *parent; - struct nvkm_instmem *imem; - struct list_head head; - u32 *suspend; - void __iomem *map; -}; - static enum nvkm_memory_target nvkm_instobj_target(struct nvkm_memory *memory) { @@ -94,7 +84,7 @@ nvkm_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) } static void * -nvkm_instobj_dtor(struct nvkm_memory *memory) +nvkm_instobj_dtor_old(struct nvkm_memory *memory) { struct nvkm_instobj *iobj = nvkm_instobj(memory); spin_lock(&iobj->imem->lock); @@ -106,7 +96,7 @@ nvkm_instobj_dtor(struct nvkm_memory *memory) static const struct nvkm_memory_func nvkm_instobj_func = { - .dtor = nvkm_instobj_dtor, + .dtor = nvkm_instobj_dtor_old, .target = nvkm_instobj_target, .addr = nvkm_instobj_addr, .size = nvkm_instobj_size, @@ -164,7 +154,7 @@ nvkm_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data) static const struct nvkm_memory_func nvkm_instobj_func_slow = { - .dtor = nvkm_instobj_dtor, + .dtor = nvkm_instobj_dtor_old, .target = nvkm_instobj_target, .addr = nvkm_instobj_addr, .size = nvkm_instobj_size, @@ -180,6 +170,26 @@ nvkm_instobj_ptrs_slow = { .wr32 = nvkm_instobj_wr32_slow, }; +void +nvkm_instobj_dtor(struct nvkm_instmem *imem, struct nvkm_instobj *iobj) +{ + spin_lock(&imem->lock); + list_del(&iobj->head); + spin_unlock(&imem->lock); +} + +void +nvkm_instobj_ctor(const struct nvkm_memory_func *func, + struct nvkm_instmem *imem, struct nvkm_instobj *iobj) +{ + nvkm_memory_ctor(func, &iobj->memory); + iobj->parent = &iobj->memory; + iobj->suspend = NULL; + spin_lock(&imem->lock); + list_add_tail(&iobj->head, &imem->list); + spin_unlock(&imem->lock); +} + int nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, struct nvkm_memory **pmemory) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h index ace4471864a3..e0c7f13cfd08 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h @@ -17,4 +17,19 @@ struct nvkm_instmem_func { void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *, int index, struct nvkm_instmem *); + +#include + +struct nvkm_instobj { + struct nvkm_memory memory; + struct nvkm_memory *parent; + struct nvkm_instmem *imem; + struct list_head head; + u32 *suspend; + void __iomem *map; +}; + +void nvkm_instobj_ctor(const struct nvkm_memory_func *func, + struct nvkm_instmem *, struct nvkm_instobj *); +void nvkm_instobj_dtor(struct nvkm_instmem *, struct nvkm_instobj *); #endif -- cgit v1.2.3 From 87717e7f28c9536a71738e54338aafffd9d5a724 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv04: directly embed nvkm_instobj into nv04_instobj Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index d4176cc67708..be907412bc04 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c @@ -24,7 +24,6 @@ #define nv04_instmem(p) container_of((p), struct nv04_instmem, base) #include "priv.h" -#include #include struct nv04_instmem { @@ -35,10 +34,10 @@ struct nv04_instmem { /****************************************************************************** * instmem object implementation *****************************************************************************/ -#define nv04_instobj(p) container_of((p), struct nv04_instobj, memory) +#define nv04_instobj(p) container_of((p), struct nv04_instobj, base.memory) struct nv04_instobj { - struct nvkm_memory memory; + struct nvkm_instobj base; struct nv04_instmem *imem; struct nvkm_mm_node *node; }; @@ -103,6 +102,7 @@ nv04_instobj_dtor(struct nvkm_memory *memory) mutex_lock(&iobj->imem->base.subdev.mutex); nvkm_mm_free(&iobj->imem->heap, &iobj->node); mutex_unlock(&iobj->imem->base.subdev.mutex); + nvkm_instobj_dtor(&iobj->imem->base, &iobj->base); return iobj; } @@ -126,10 +126,10 @@ nv04_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) return -ENOMEM; - *pmemory = &iobj->memory; + *pmemory = &iobj->base.memory; - nvkm_memory_ctor(&nv04_instobj_func, &iobj->memory); - iobj->memory.ptrs = &nv04_instobj_ptrs; + nvkm_instobj_ctor(&nv04_instobj_func, &imem->base, &iobj->base); + iobj->base.memory.ptrs = &nv04_instobj_ptrs; iobj->imem = imem; mutex_lock(&imem->base.subdev.mutex); @@ -214,7 +214,7 @@ nv04_instmem = { .rd32 = nv04_instmem_rd32, .wr32 = nv04_instmem_wr32, .memory_new = nv04_instobj_new, - .persistent = false, + .persistent = true, .zero = false, }; -- cgit v1.2.3 From 62465ac51883ef19af83c575d5fee5526732ffcb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv40: embed nvkm_instobj directly into nv04_instobj Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 5fa2b7c0decc..5ae9dd28dbba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -24,7 +24,6 @@ #define nv40_instmem(p) container_of((p), struct nv40_instmem, base) #include "priv.h" -#include #include #include @@ -37,10 +36,10 @@ struct nv40_instmem { /****************************************************************************** * instmem object implementation *****************************************************************************/ -#define nv40_instobj(p) container_of((p), struct nv40_instobj, memory) +#define nv40_instobj(p) container_of((p), struct nv40_instobj, base.memory) struct nv40_instobj { - struct nvkm_memory memory; + struct nvkm_instobj base; struct nv40_instmem *imem; struct nvkm_mm_node *node; }; @@ -102,6 +101,7 @@ nv40_instobj_dtor(struct nvkm_memory *memory) mutex_lock(&iobj->imem->base.subdev.mutex); nvkm_mm_free(&iobj->imem->heap, &iobj->node); mutex_unlock(&iobj->imem->base.subdev.mutex); + nvkm_instobj_dtor(&iobj->imem->base, &iobj->base); return iobj; } @@ -125,10 +125,10 @@ nv40_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) return -ENOMEM; - *pmemory = &iobj->memory; + *pmemory = &iobj->base.memory; - nvkm_memory_ctor(&nv40_instobj_func, &iobj->memory); - iobj->memory.ptrs = &nv40_instobj_ptrs; + nvkm_instobj_ctor(&nv40_instobj_func, &imem->base, &iobj->base); + iobj->base.memory.ptrs = &nv40_instobj_ptrs; iobj->imem = imem; mutex_lock(&imem->base.subdev.mutex); @@ -231,7 +231,7 @@ nv40_instmem = { .rd32 = nv40_instmem_rd32, .wr32 = nv40_instmem_wr32, .memory_new = nv40_instobj_new, - .persistent = false, + .persistent = true, .zero = false, }; -- cgit v1.2.3 From b807270cbd87bfd2ab72904f6d9d92c17ccfeaab Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv40: map bar2 write-combined Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 5ae9dd28dbba..01453fdaa049 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -67,6 +67,7 @@ nv40_instobj_ptrs = { static void nv40_instobj_release(struct nvkm_memory *memory) { + wmb(); } static void __iomem * @@ -253,8 +254,8 @@ nv40_instmem_new(struct nvkm_device *device, int index, else bar = 3; - imem->iomem = ioremap(device->func->resource_addr(device, bar), - device->func->resource_size(device, bar)); + imem->iomem = ioremap_wc(device->func->resource_addr(device, bar), + device->func->resource_size(device, bar)); if (!imem->iomem) { nvkm_error(&imem->base.subdev, "unable to map PRAMIN BAR\n"); return -EFAULT; -- cgit v1.2.3 From f584bde6095af4d91e917be54c487258856ace89 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50: split object map out from api functions acquire()/boot() will need different logic in addition to performing the actual mapping. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 57 ++++++++++++---------- 1 file changed, 32 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index e3273aed3381..95b2c560fe4b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -89,6 +89,34 @@ nv50_instobj_slow = { .wr32 = nv50_instobj_wr32_slow, }; +static void +nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) +{ + struct nvkm_memory *memory = &iobj->memory; + struct nvkm_subdev *subdev = &iobj->imem->base.subdev; + struct nvkm_device *device = subdev->device; + u64 size = nvkm_memory_size(memory); + void __iomem *map; + int ret; + + iobj->map = ERR_PTR(-ENOMEM); + + ret = nvkm_vm_get(vmm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar); + if (ret == 0) { + map = ioremap(device->func->resource_addr(device, 3) + + (u32)iobj->bar.offset, size); + if (map) { + nvkm_memory_map(memory, &iobj->bar, 0); + iobj->map = map; + } else { + nvkm_warn(subdev, "PRAMIN ioremap failed\n"); + nvkm_vm_put(&iobj->bar); + } + } else { + nvkm_warn(subdev, "PRAMIN exhausted\n"); + } +} + static void nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) { @@ -112,7 +140,7 @@ nv50_instobj_acquire(struct nvkm_memory *memory) unsigned long flags; if (!iobj->map && (vm = nvkm_bar_bar2_vmm(imem->base.subdev.device))) - nvkm_memory_boot(memory, vm); + nv50_instobj_kmap(iobj, vm); if (!IS_ERR_OR_NULL(iobj->map)) return iobj->map; @@ -122,31 +150,10 @@ nv50_instobj_acquire(struct nvkm_memory *memory) } static void -nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm) +nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vmm *vmm) { struct nv50_instobj *iobj = nv50_instobj(memory); - struct nvkm_subdev *subdev = &iobj->imem->base.subdev; - struct nvkm_device *device = subdev->device; - u64 size = nvkm_memory_size(memory); - void __iomem *map; - int ret; - - iobj->map = ERR_PTR(-ENOMEM); - - ret = nvkm_vm_get(vm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar); - if (ret == 0) { - map = ioremap(device->func->resource_addr(device, 3) + - (u32)iobj->bar.offset, size); - if (map) { - nvkm_memory_map(memory, &iobj->bar, 0); - iobj->map = map; - } else { - nvkm_warn(subdev, "PRAMIN ioremap failed\n"); - nvkm_vm_put(&iobj->bar); - } - } else { - nvkm_warn(subdev, "PRAMIN exhausted\n"); - } + nv50_instobj_kmap(iobj, vmm); } static u64 @@ -173,8 +180,8 @@ nv50_instobj_dtor(struct nvkm_memory *memory) struct nv50_instobj *iobj = nv50_instobj(memory); struct nvkm_ram *ram = iobj->imem->base.subdev.device->fb->ram; if (!IS_ERR_OR_NULL(iobj->map)) { - nvkm_vm_put(&iobj->bar); iounmap(iobj->map); + nvkm_vm_put(&iobj->bar); } ram->func->put(ram, &iobj->mem); return iobj; -- cgit v1.2.3 From af515ec8d3fbd8376513eee9648a52d5ab92bbac Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50: move slow-path locking into rd/wr functions This is to simplify upcoming changes. The slow-path is something that currently occurs during bootstrap of the BAR2 VMM, while backing up an object during suspend/resume, or when BAR2 address space runs out. The latter is a real problem that can happen at runtime, and occurs in Fedora 26 already (due to some change that causes a lot of channels to be created at login), so ideally we'd prefer not to make it any slower. We'd also like suspend/resume speed to not suffer. Upcoming commits will solve those problems in a better way, making the extra overhead of moving the locking here a non-issue. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 95b2c560fe4b..d0159d5876f3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -31,8 +31,6 @@ struct nv50_instmem { struct nvkm_instmem base; - unsigned long lock_flags; - spinlock_t lock; u64 addr; }; @@ -57,12 +55,15 @@ nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data) struct nvkm_device *device = imem->base.subdev.device; u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; + unsigned long flags; + spin_lock_irqsave(&imem->base.lock, flags); if (unlikely(imem->addr != base)) { nvkm_wr32(device, 0x001700, base >> 16); imem->addr = base; } nvkm_wr32(device, 0x700000 + addr, data); + spin_unlock_irqrestore(&imem->base.lock, flags); } static u32 @@ -74,12 +75,15 @@ nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset) u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; u32 data; + unsigned long flags; + spin_lock_irqsave(&imem->base.lock, flags); if (unlikely(imem->addr != base)) { nvkm_wr32(device, 0x001700, base >> 16); imem->addr = base; } data = nvkm_rd32(device, 0x700000 + addr); + spin_unlock_irqrestore(&imem->base.lock, flags); return data; } @@ -127,8 +131,6 @@ nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) static void nv50_instobj_release(struct nvkm_memory *memory) { - struct nv50_instmem *imem = nv50_instobj(memory)->imem; - spin_unlock_irqrestore(&imem->lock, imem->lock_flags); } static void __iomem * @@ -137,15 +139,12 @@ nv50_instobj_acquire(struct nvkm_memory *memory) struct nv50_instobj *iobj = nv50_instobj(memory); struct nv50_instmem *imem = iobj->imem; struct nvkm_vm *vm; - unsigned long flags; if (!iobj->map && (vm = nvkm_bar_bar2_vmm(imem->base.subdev.device))) nv50_instobj_kmap(iobj, vm); if (!IS_ERR_OR_NULL(iobj->map)) return iobj->map; - spin_lock_irqsave(&imem->lock, flags); - imem->lock_flags = flags; return NULL; } @@ -254,7 +253,6 @@ nv50_instmem_new(struct nvkm_device *device, int index, if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) return -ENOMEM; nvkm_instmem_ctor(&nv50_instmem, device, index, &imem->base); - spin_lock_init(&imem->lock); *pimem = &imem->base; return 0; } -- cgit v1.2.3 From be55287aa5ba6895e9d4d3ed2f08a1be7a065957 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50: embed nvkm_instobj directly into nv04_instobj This is not as simple as it was for earlier GPUs, due to the need to swap accessor functions depending on whether BAR2 is usable or not. We were previously protected by nvkm_instobj's accessor functions keeping an object mapped permanently, with some unclear magic that managed to hit the slow-path where needed even if an object was marked as mapped. That's been replaced here by reference counting maps (some objects, like page tables can be accessed concurrently), and swapping the functions as necessary. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 134 ++++++++++++++++----- 1 file changed, 102 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index d0159d5876f3..9b5606cb2f4e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -37,13 +37,14 @@ struct nv50_instmem { /****************************************************************************** * instmem object implementation *****************************************************************************/ -#define nv50_instobj(p) container_of((p), struct nv50_instobj, memory) +#define nv50_instobj(p) container_of((p), struct nv50_instobj, base.memory) struct nv50_instobj { - struct nvkm_memory memory; + struct nvkm_instobj base; struct nv50_instmem *imem; struct nvkm_mem *mem; struct nvkm_vma bar; + refcount_t maps; void *map; }; @@ -93,31 +94,59 @@ nv50_instobj_slow = { .wr32 = nv50_instobj_wr32_slow, }; +static void +nv50_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) +{ + iowrite32_native(data, nv50_instobj(memory)->map + offset); +} + +static u32 +nv50_instobj_rd32(struct nvkm_memory *memory, u64 offset) +{ + return ioread32_native(nv50_instobj(memory)->map + offset); +} + +static const struct nvkm_memory_ptrs +nv50_instobj_fast = { + .rd32 = nv50_instobj_rd32, + .wr32 = nv50_instobj_wr32, +}; + static void nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) { - struct nvkm_memory *memory = &iobj->memory; - struct nvkm_subdev *subdev = &iobj->imem->base.subdev; + struct nv50_instmem *imem = iobj->imem; + struct nvkm_memory *memory = &iobj->base.memory; + struct nvkm_subdev *subdev = &imem->base.subdev; struct nvkm_device *device = subdev->device; + struct nvkm_vma bar = {}; u64 size = nvkm_memory_size(memory); - void __iomem *map; int ret; - iobj->map = ERR_PTR(-ENOMEM); - - ret = nvkm_vm_get(vmm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar); - if (ret == 0) { - map = ioremap(device->func->resource_addr(device, 3) + - (u32)iobj->bar.offset, size); - if (map) { - nvkm_memory_map(memory, &iobj->bar, 0); - iobj->map = map; - } else { - nvkm_warn(subdev, "PRAMIN ioremap failed\n"); - nvkm_vm_put(&iobj->bar); - } - } else { - nvkm_warn(subdev, "PRAMIN exhausted\n"); + /* Attempt to allocate BAR2 address-space and map the object + * into it. The lock has to be dropped while doing this due + * to the possibility of recursion for page table allocation. + */ + mutex_unlock(&subdev->mutex); + ret = nvkm_vm_get(vmm, size, 12, NV_MEM_ACCESS_RW, &bar); + if (ret == 0) + nvkm_memory_map(memory, &bar, 0); + mutex_lock(&subdev->mutex); + if (ret || iobj->bar.node) { + /* We either failed, or another thread beat us. */ + mutex_unlock(&subdev->mutex); + nvkm_vm_put(&bar); + mutex_lock(&subdev->mutex); + return; + } + + /* Make the mapping visible to the host. */ + iobj->bar = bar; + iobj->map = ioremap(device->func->resource_addr(device, 3) + + (u32)iobj->bar.offset, size); + if (!iobj->map) { + nvkm_warn(subdev, "PRAMIN ioremap failed\n"); + nvkm_vm_put(&iobj->bar); } } @@ -131,28 +160,66 @@ nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) static void nv50_instobj_release(struct nvkm_memory *memory) { + struct nv50_instobj *iobj = nv50_instobj(memory); + struct nv50_instmem *imem = iobj->imem; + struct nvkm_subdev *subdev = &imem->base.subdev; + + nvkm_bar_flush(subdev->device->bar); + + if (refcount_dec_and_mutex_lock(&iobj->maps, &subdev->mutex)) { + /* Switch back to NULL accessors when last map is gone. */ + iobj->base.memory.ptrs = &nv50_instobj_slow; + mutex_unlock(&subdev->mutex); + } } static void __iomem * nv50_instobj_acquire(struct nvkm_memory *memory) { struct nv50_instobj *iobj = nv50_instobj(memory); - struct nv50_instmem *imem = iobj->imem; - struct nvkm_vm *vm; + struct nvkm_instmem *imem = &iobj->imem->base; + struct nvkm_vmm *vmm; + void __iomem *map = NULL; - if (!iobj->map && (vm = nvkm_bar_bar2_vmm(imem->base.subdev.device))) - nv50_instobj_kmap(iobj, vm); - if (!IS_ERR_OR_NULL(iobj->map)) + /* Already mapped? */ + if (refcount_inc_not_zero(&iobj->maps)) return iobj->map; - return NULL; + /* Take the lock, and re-check that another thread hasn't + * already mapped the object in the meantime. + */ + mutex_lock(&imem->subdev.mutex); + if (refcount_inc_not_zero(&iobj->maps)) { + mutex_unlock(&imem->subdev.mutex); + return iobj->map; + } + + /* Attempt to get a direct CPU mapping of the object. */ + if (!iobj->map && (vmm = nvkm_bar_bar2_vmm(imem->subdev.device))) + nv50_instobj_kmap(iobj, vmm); + map = iobj->map; + + if (!refcount_inc_not_zero(&iobj->maps)) { + if (map) + iobj->base.memory.ptrs = &nv50_instobj_fast; + else + iobj->base.memory.ptrs = &nv50_instobj_slow; + refcount_inc(&iobj->maps); + } + + mutex_unlock(&imem->subdev.mutex); + return map; } static void nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vmm *vmm) { struct nv50_instobj *iobj = nv50_instobj(memory); + struct nvkm_instmem *imem = &iobj->imem->base; + + mutex_lock(&imem->subdev.mutex); nv50_instobj_kmap(iobj, vmm); + mutex_unlock(&imem->subdev.mutex); } static u64 @@ -177,12 +244,14 @@ static void * nv50_instobj_dtor(struct nvkm_memory *memory) { struct nv50_instobj *iobj = nv50_instobj(memory); - struct nvkm_ram *ram = iobj->imem->base.subdev.device->fb->ram; - if (!IS_ERR_OR_NULL(iobj->map)) { + struct nvkm_instmem *imem = &iobj->imem->base; + struct nvkm_ram *ram = imem->subdev.device->fb->ram; + if (iobj->map) { iounmap(iobj->map); nvkm_vm_put(&iobj->bar); } ram->func->put(ram, &iobj->mem); + nvkm_instobj_dtor(imem, &iobj->base); return iobj; } @@ -209,11 +278,12 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) return -ENOMEM; - *pmemory = &iobj->memory; + *pmemory = &iobj->base.memory; - nvkm_memory_ctor(&nv50_instobj_func, &iobj->memory); - iobj->memory.ptrs = &nv50_instobj_slow; + nvkm_instobj_ctor(&nv50_instobj_func, &imem->base, &iobj->base); + iobj->base.memory.ptrs = &nv50_instobj_slow; iobj->imem = imem; + refcount_set(&iobj->maps, 0); size = max((size + 4095) & ~4095, (u32)4096); align = max((align + 4095) & ~4095, (u32)4096); @@ -240,7 +310,7 @@ static const struct nvkm_instmem_func nv50_instmem = { .fini = nv50_instmem_fini, .memory_new = nv50_instobj_new, - .persistent = false, + .persistent = true, .zero = false, }; -- cgit v1.2.3 From dfcbd5506817c7bfba67c7c2232610f7693b1938 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50: map bar2 write-combined Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 9b5606cb2f4e..ec2904a0e9fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -142,8 +142,8 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) /* Make the mapping visible to the host. */ iobj->bar = bar; - iobj->map = ioremap(device->func->resource_addr(device, 3) + - (u32)iobj->bar.offset, size); + iobj->map = ioremap_wc(device->func->resource_addr(device, 3) + + (u32)iobj->bar.offset, size); if (!iobj->map) { nvkm_warn(subdev, "PRAMIN ioremap failed\n"); nvkm_vm_put(&iobj->bar); @@ -164,6 +164,7 @@ nv50_instobj_release(struct nvkm_memory *memory) struct nv50_instmem *imem = iobj->imem; struct nvkm_subdev *subdev = &imem->base.subdev; + wmb(); nvkm_bar_flush(subdev->device->bar); if (refcount_dec_and_mutex_lock(&iobj->maps, &subdev->mutex)) { -- cgit v1.2.3 From 69b136f200006ee37b039195eaeb08942c419ecc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50: prevent fast-path for mapped objects when BAR isn't ready Another piece of solving the "GP100 BAR2 VMM bootstrap" puzzle. Without doing this, we'd attempt to write PDEs for the lower page table levels through BAR2 before BAR2 access has been fully initialised. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index ec2904a0e9fc..1a254e69fece 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -196,9 +196,11 @@ nv50_instobj_acquire(struct nvkm_memory *memory) } /* Attempt to get a direct CPU mapping of the object. */ - if (!iobj->map && (vmm = nvkm_bar_bar2_vmm(imem->subdev.device))) - nv50_instobj_kmap(iobj, vmm); - map = iobj->map; + if ((vmm = nvkm_bar_bar2_vmm(imem->subdev.device))) { + if (!iobj->map) + nv50_instobj_kmap(iobj, vmm); + map = iobj->map; + } if (!refcount_inc_not_zero(&iobj->maps)) { if (map) -- cgit v1.2.3 From 03edf1b31a091254e95793a688abf02b96cfdd85 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50: support eviction of BAR2 mappings A good deal of the structures we map into here aren't accessed very often at all, and Fedora 26 has exposed an issue where after creating a heap of channels, BAR2 space would run out, and we'd need to make use of the slow path while accessing important structures like page tables. This implements an LRU on BAR2 space, which allows eviction of mappings that aren't currently needed, to make space for other objects. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 72 ++++++++++++++++++++-- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 1a254e69fece..a054e8d155ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -32,6 +32,9 @@ struct nv50_instmem { struct nvkm_instmem base; u64 addr; + + /* Mappings that can be evicted when BAR2 space has been exhausted. */ + struct list_head lru; }; /****************************************************************************** @@ -46,6 +49,7 @@ struct nv50_instobj { struct nvkm_vma bar; refcount_t maps; void *map; + struct list_head lru; }; static void @@ -116,11 +120,13 @@ static void nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) { struct nv50_instmem *imem = iobj->imem; + struct nv50_instobj *eobj; struct nvkm_memory *memory = &iobj->base.memory; struct nvkm_subdev *subdev = &imem->base.subdev; struct nvkm_device *device = subdev->device; - struct nvkm_vma bar = {}; + struct nvkm_vma bar = {}, ebar; u64 size = nvkm_memory_size(memory); + void *emap; int ret; /* Attempt to allocate BAR2 address-space and map the object @@ -128,7 +134,30 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) * to the possibility of recursion for page table allocation. */ mutex_unlock(&subdev->mutex); - ret = nvkm_vm_get(vmm, size, 12, NV_MEM_ACCESS_RW, &bar); + while ((ret = nvkm_vm_get(vmm, size, 12, NV_MEM_ACCESS_RW, &bar))) { + /* Evict unused mappings, and keep retrying until we either + * succeed,or there's no more objects left on the LRU. + */ + mutex_lock(&subdev->mutex); + eobj = list_first_entry_or_null(&imem->lru, typeof(*eobj), lru); + if (eobj) { + nvkm_debug(subdev, "evict %016llx %016llx @ %016llx\n", + nvkm_memory_addr(&eobj->base.memory), + nvkm_memory_size(&eobj->base.memory), + eobj->bar.offset); + list_del_init(&eobj->lru); + ebar = eobj->bar; + eobj->bar.node = NULL; + emap = eobj->map; + eobj->map = NULL; + } + mutex_unlock(&subdev->mutex); + if (!eobj) + break; + iounmap(emap); + nvkm_vm_put(&ebar); + } + if (ret == 0) nvkm_memory_map(memory, &bar, 0); mutex_lock(&subdev->mutex); @@ -168,6 +197,14 @@ nv50_instobj_release(struct nvkm_memory *memory) nvkm_bar_flush(subdev->device->bar); if (refcount_dec_and_mutex_lock(&iobj->maps, &subdev->mutex)) { + /* Add the now-unused mapping to the LRU instead of directly + * unmapping it here, in case we need to map it again later. + */ + if (likely(iobj->lru.next) && iobj->map) { + BUG_ON(!list_empty(&iobj->lru)); + list_add_tail(&iobj->lru, &imem->lru); + } + /* Switch back to NULL accessors when last map is gone. */ iobj->base.memory.ptrs = &nv50_instobj_slow; mutex_unlock(&subdev->mutex); @@ -203,6 +240,10 @@ nv50_instobj_acquire(struct nvkm_memory *memory) } if (!refcount_inc_not_zero(&iobj->maps)) { + /* Exclude object from eviction while it's being accessed. */ + if (likely(iobj->lru.next)) + list_del_init(&iobj->lru); + if (map) iobj->base.memory.ptrs = &nv50_instobj_fast; else @@ -220,7 +261,15 @@ nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vmm *vmm) struct nv50_instobj *iobj = nv50_instobj(memory); struct nvkm_instmem *imem = &iobj->imem->base; + /* Exclude bootstrapped objects (ie. the page tables for the + * instmem BAR itself) from eviction. + */ mutex_lock(&imem->subdev.mutex); + if (likely(iobj->lru.next)) { + list_del_init(&iobj->lru); + iobj->lru.next = NULL; + } + nv50_instobj_kmap(iobj, vmm); mutex_unlock(&imem->subdev.mutex); } @@ -249,10 +298,21 @@ nv50_instobj_dtor(struct nvkm_memory *memory) struct nv50_instobj *iobj = nv50_instobj(memory); struct nvkm_instmem *imem = &iobj->imem->base; struct nvkm_ram *ram = imem->subdev.device->fb->ram; - if (iobj->map) { - iounmap(iobj->map); - nvkm_vm_put(&iobj->bar); + struct nvkm_vma bar; + void *map = map; + + mutex_lock(&imem->subdev.mutex); + if (likely(iobj->lru.next)) + list_del(&iobj->lru); + map = iobj->map; + bar = iobj->bar; + mutex_unlock(&imem->subdev.mutex); + + if (map) { + iounmap(map); + nvkm_vm_put(&bar); } + ram->func->put(ram, &iobj->mem); nvkm_instobj_dtor(imem, &iobj->base); return iobj; @@ -287,6 +347,7 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, iobj->base.memory.ptrs = &nv50_instobj_slow; iobj->imem = imem; refcount_set(&iobj->maps, 0); + INIT_LIST_HEAD(&iobj->lru); size = max((size + 4095) & ~4095, (u32)4096); align = max((align + 4095) & ~4095, (u32)4096); @@ -326,6 +387,7 @@ nv50_instmem_new(struct nvkm_device *device, int index, if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) return -ENOMEM; nvkm_instmem_ctor(&nv50_instmem, device, index, &imem->base); + INIT_LIST_HEAD(&imem->lru); *pimem = &imem->base; return 0; } -- cgit v1.2.3 From 71370e620a97fe98daebea86c6ae3775cf0f4fc8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: remove now-unused wrapper for backend objects Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 164 +-------------------- .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h | 4 - 6 files changed, 2 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 78f9c2332edd..4c2fa5c460c7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -28,148 +28,6 @@ /****************************************************************************** * instmem object base implementation *****************************************************************************/ -#define nvkm_instobj(p) container_of((p), struct nvkm_instobj, memory) - -static enum nvkm_memory_target -nvkm_instobj_target(struct nvkm_memory *memory) -{ - memory = nvkm_instobj(memory)->parent; - return nvkm_memory_target(memory); -} - -static u64 -nvkm_instobj_addr(struct nvkm_memory *memory) -{ - memory = nvkm_instobj(memory)->parent; - return nvkm_memory_addr(memory); -} - -static u64 -nvkm_instobj_size(struct nvkm_memory *memory) -{ - memory = nvkm_instobj(memory)->parent; - return nvkm_memory_size(memory); -} - -static void -nvkm_instobj_release(struct nvkm_memory *memory) -{ - struct nvkm_instobj *iobj = nvkm_instobj(memory); - nvkm_bar_flush(iobj->imem->subdev.device->bar); -} - -static void __iomem * -nvkm_instobj_acquire(struct nvkm_memory *memory) -{ - return nvkm_instobj(memory)->map; -} - -static u32 -nvkm_instobj_rd32(struct nvkm_memory *memory, u64 offset) -{ - return ioread32_native(nvkm_instobj(memory)->map + offset); -} - -static void -nvkm_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) -{ - iowrite32_native(data, nvkm_instobj(memory)->map + offset); -} - -static void -nvkm_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) -{ - memory = nvkm_instobj(memory)->parent; - nvkm_memory_map(memory, vma, offset); -} - -static void * -nvkm_instobj_dtor_old(struct nvkm_memory *memory) -{ - struct nvkm_instobj *iobj = nvkm_instobj(memory); - spin_lock(&iobj->imem->lock); - list_del(&iobj->head); - spin_unlock(&iobj->imem->lock); - nvkm_memory_del(&iobj->parent); - return iobj; -} - -static const struct nvkm_memory_func -nvkm_instobj_func = { - .dtor = nvkm_instobj_dtor_old, - .target = nvkm_instobj_target, - .addr = nvkm_instobj_addr, - .size = nvkm_instobj_size, - .acquire = nvkm_instobj_acquire, - .release = nvkm_instobj_release, - .map = nvkm_instobj_map, -}; - -static const struct nvkm_memory_ptrs -nvkm_instobj_ptrs = { - .rd32 = nvkm_instobj_rd32, - .wr32 = nvkm_instobj_wr32, -}; - -static void -nvkm_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm) -{ - memory = nvkm_instobj(memory)->parent; - nvkm_memory_boot(memory, vm); -} - -static void -nvkm_instobj_release_slow(struct nvkm_memory *memory) -{ - struct nvkm_instobj *iobj = nvkm_instobj(memory); - nvkm_instobj_release(memory); - nvkm_done(iobj->parent); -} - -static void __iomem * -nvkm_instobj_acquire_slow(struct nvkm_memory *memory) -{ - struct nvkm_instobj *iobj = nvkm_instobj(memory); - iobj->map = nvkm_kmap(iobj->parent); - if (iobj->map) { - memory->func = &nvkm_instobj_func; - memory->ptrs = &nvkm_instobj_ptrs; - } - return iobj->map; -} - -static u32 -nvkm_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset) -{ - struct nvkm_instobj *iobj = nvkm_instobj(memory); - return nvkm_ro32(iobj->parent, offset); -} - -static void -nvkm_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data) -{ - struct nvkm_instobj *iobj = nvkm_instobj(memory); - return nvkm_wo32(iobj->parent, offset, data); -} - -static const struct nvkm_memory_func -nvkm_instobj_func_slow = { - .dtor = nvkm_instobj_dtor_old, - .target = nvkm_instobj_target, - .addr = nvkm_instobj_addr, - .size = nvkm_instobj_size, - .boot = nvkm_instobj_boot, - .acquire = nvkm_instobj_acquire_slow, - .release = nvkm_instobj_release_slow, - .map = nvkm_instobj_map, -}; - -static const struct nvkm_memory_ptrs -nvkm_instobj_ptrs_slow = { - .rd32 = nvkm_instobj_rd32_slow, - .wr32 = nvkm_instobj_wr32_slow, -}; - void nvkm_instobj_dtor(struct nvkm_instmem *imem, struct nvkm_instobj *iobj) { @@ -183,7 +41,6 @@ nvkm_instobj_ctor(const struct nvkm_memory_func *func, struct nvkm_instmem *imem, struct nvkm_instobj *iobj) { nvkm_memory_ctor(func, &iobj->memory); - iobj->parent = &iobj->memory; iobj->suspend = NULL; spin_lock(&imem->lock); list_add_tail(&iobj->head, &imem->list); @@ -196,7 +53,6 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, { struct nvkm_subdev *subdev = &imem->subdev; struct nvkm_memory *memory = NULL; - struct nvkm_instobj *iobj; u32 offset; int ret; @@ -209,22 +65,6 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, nvkm_trace(subdev, "new %08x %08x %d: %010llx %010llx\n", size, align, zero, nvkm_memory_addr(memory), nvkm_memory_size(memory)); - if (!imem->func->persistent) { - if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) { - ret = -ENOMEM; - goto done; - } - - nvkm_memory_ctor(&nvkm_instobj_func_slow, &iobj->memory); - iobj->memory.ptrs = &nvkm_instobj_ptrs_slow; - iobj->parent = memory; - iobj->imem = imem; - spin_lock(&iobj->imem->lock); - list_add_tail(&iobj->head, &imem->list); - spin_unlock(&iobj->imem->lock); - memory = &iobj->memory; - } - if (!imem->func->zero && zero) { void __iomem *map = nvkm_kmap(memory); if (unlikely(!map)) { @@ -271,7 +111,7 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) if (suspend) { list_for_each_entry(iobj, &imem->list, head) { - struct nvkm_memory *memory = iobj->parent; + struct nvkm_memory *memory = &iobj->memory; u64 size = nvkm_memory_size(memory); iobj->suspend = vmalloc(size); @@ -304,7 +144,7 @@ nvkm_instmem_init(struct nvkm_subdev *subdev) list_for_each_entry(iobj, &imem->list, head) { if (iobj->suspend) { - struct nvkm_memory *memory = iobj->parent; + struct nvkm_memory *memory = &iobj->memory; u64 size = nvkm_memory_size(memory); for (i = 0; i < size; i += 4) nvkm_wo32(memory, i, iobj->suspend[i / 4]); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 41bf8770cfd7..a8b71262f663 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -558,7 +558,6 @@ static const struct nvkm_instmem_func gk20a_instmem = { .dtor = gk20a_instmem_dtor, .memory_new = gk20a_instobj_new, - .persistent = true, .zero = false, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index be907412bc04..df75da764bd4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c @@ -214,7 +214,6 @@ nv04_instmem = { .rd32 = nv04_instmem_rd32, .wr32 = nv04_instmem_wr32, .memory_new = nv04_instobj_new, - .persistent = true, .zero = false, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 01453fdaa049..d8ab5fa86893 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -232,7 +232,6 @@ nv40_instmem = { .rd32 = nv40_instmem_rd32, .wr32 = nv40_instmem_wr32, .memory_new = nv40_instobj_new, - .persistent = true, .zero = false, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index a054e8d155ee..374df1ebe2e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -374,7 +374,6 @@ static const struct nvkm_instmem_func nv50_instmem = { .fini = nv50_instmem_fini, .memory_new = nv50_instobj_new, - .persistent = true, .zero = false, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h index e0c7f13cfd08..e7515d96b31f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h @@ -11,7 +11,6 @@ struct nvkm_instmem_func { void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data); int (*memory_new)(struct nvkm_instmem *, u32 size, u32 align, bool zero, struct nvkm_memory **); - bool persistent; bool zero; }; @@ -22,11 +21,8 @@ void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *, struct nvkm_instobj { struct nvkm_memory memory; - struct nvkm_memory *parent; - struct nvkm_instmem *imem; struct list_head head; u32 *suspend; - void __iomem *map; }; void nvkm_instobj_ctor(const struct nvkm_memory_func *func, -- cgit v1.2.3 From d52ddc953e7f74a8271c88fc0aa3bd0d436b04f0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: separate suspend/resume backup handling into their own functions Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 76 +++++++++++++--------- 1 file changed, 46 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 4c2fa5c460c7..8ad31b436fa0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -28,6 +28,36 @@ /****************************************************************************** * instmem object base implementation *****************************************************************************/ +static void +nvkm_instobj_load(struct nvkm_instobj *iobj) +{ + struct nvkm_memory *memory = &iobj->memory; + const u64 size = nvkm_memory_size(memory); + int i; + + for (i = 0; i < size; i += 4) + nvkm_wo32(memory, i, iobj->suspend[i / 4]); + vfree(iobj->suspend); + iobj->suspend = NULL; +} + +static int +nvkm_instobj_save(struct nvkm_instobj *iobj) +{ + struct nvkm_memory *memory = &iobj->memory; + const u64 size = nvkm_memory_size(memory); + int i; + + iobj->suspend = vmalloc(size); + if (!iobj->suspend) + return -ENOMEM; + + for (i = 0; i < size; i += 4) + iobj->suspend[i / 4] = nvkm_ro32(memory, i); + + return 0; +} + void nvkm_instobj_dtor(struct nvkm_instmem *imem, struct nvkm_instobj *iobj) { @@ -104,34 +134,18 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_instmem *imem = nvkm_instmem(subdev); struct nvkm_instobj *iobj; - int i; - - if (imem->func->fini) - imem->func->fini(imem); if (suspend) { list_for_each_entry(iobj, &imem->list, head) { - struct nvkm_memory *memory = &iobj->memory; - u64 size = nvkm_memory_size(memory); - - iobj->suspend = vmalloc(size); - if (!iobj->suspend) - return -ENOMEM; - - for (i = 0; i < size; i += 4) - iobj->suspend[i / 4] = nvkm_ro32(memory, i); + int ret = nvkm_instobj_save(iobj); + if (ret) + return ret; } } - return 0; -} + if (imem->func->fini) + imem->func->fini(imem); -static int -nvkm_instmem_oneinit(struct nvkm_subdev *subdev) -{ - struct nvkm_instmem *imem = nvkm_instmem(subdev); - if (imem->func->oneinit) - return imem->func->oneinit(imem); return 0; } @@ -140,22 +154,24 @@ nvkm_instmem_init(struct nvkm_subdev *subdev) { struct nvkm_instmem *imem = nvkm_instmem(subdev); struct nvkm_instobj *iobj; - int i; list_for_each_entry(iobj, &imem->list, head) { - if (iobj->suspend) { - struct nvkm_memory *memory = &iobj->memory; - u64 size = nvkm_memory_size(memory); - for (i = 0; i < size; i += 4) - nvkm_wo32(memory, i, iobj->suspend[i / 4]); - vfree(iobj->suspend); - iobj->suspend = NULL; - } + if (iobj->suspend) + nvkm_instobj_load(iobj); } return 0; } +static int +nvkm_instmem_oneinit(struct nvkm_subdev *subdev) +{ + struct nvkm_instmem *imem = nvkm_instmem(subdev); + if (imem->func->oneinit) + return imem->func->oneinit(imem); + return 0; +} + static void * nvkm_instmem_dtor(struct nvkm_subdev *subdev) { -- cgit v1.2.3 From 54c70e3ac6d5634982edd586418710eb7fbb7c76 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: switch to kvmalloc/kvfree for suspend/resume backup Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 8ad31b436fa0..36b3424149b3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -37,7 +37,7 @@ nvkm_instobj_load(struct nvkm_instobj *iobj) for (i = 0; i < size; i += 4) nvkm_wo32(memory, i, iobj->suspend[i / 4]); - vfree(iobj->suspend); + kvfree(iobj->suspend); iobj->suspend = NULL; } @@ -48,7 +48,7 @@ nvkm_instobj_save(struct nvkm_instobj *iobj) const u64 size = nvkm_memory_size(memory); int i; - iobj->suspend = vmalloc(size); + iobj->suspend = kvmalloc(size, GFP_KERNEL); if (!iobj->suspend) return -ENOMEM; -- cgit v1.2.3 From b00b8430468d2922c5ea9a0557c7a36136df98c2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: separate pre-BAR2-bootstrap objects from the rest These will require slow-path access during suspend/resume. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/subdev/instmem.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 27 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h | 1 + 4 files changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h index 40f845e31272..8111c0c3c5ec 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h @@ -9,6 +9,7 @@ struct nvkm_instmem { spinlock_t lock; struct list_head list; + struct list_head boot; u32 reserved; struct nvkm_memory *vbios; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 36b3424149b3..8fc63ec20d6e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -129,6 +129,21 @@ nvkm_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data) return imem->func->wr32(imem, addr, data); } +void +nvkm_instmem_boot(struct nvkm_instmem *imem) +{ + /* Separate bootstrapped objects from normal list, as we need + * to make sure they're accessed with the slowpath on suspend + * and resume. + */ + struct nvkm_instobj *iobj, *itmp; + spin_lock(&imem->lock); + list_for_each_entry_safe(iobj, itmp, &imem->list, head) { + list_move_tail(&iobj->head, &imem->boot); + } + spin_unlock(&imem->lock); +} + static int nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) { @@ -141,6 +156,12 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) if (ret) return ret; } + + list_for_each_entry(iobj, &imem->boot, head) { + int ret = nvkm_instobj_save(iobj); + if (ret) + return ret; + } } if (imem->func->fini) @@ -155,6 +176,11 @@ nvkm_instmem_init(struct nvkm_subdev *subdev) struct nvkm_instmem *imem = nvkm_instmem(subdev); struct nvkm_instobj *iobj; + list_for_each_entry(iobj, &imem->boot, head) { + if (iobj->suspend) + nvkm_instobj_load(iobj); + } + list_for_each_entry(iobj, &imem->list, head) { if (iobj->suspend) nvkm_instobj_load(iobj); @@ -198,4 +224,5 @@ nvkm_instmem_ctor(const struct nvkm_instmem_func *func, imem->func = func; spin_lock_init(&imem->lock); INIT_LIST_HEAD(&imem->list); + INIT_LIST_HEAD(&imem->boot); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 374df1ebe2e8..be5670f9fefa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -271,6 +271,7 @@ nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vmm *vmm) } nv50_instobj_kmap(iobj, vmm); + nvkm_instmem_boot(imem); mutex_unlock(&imem->subdev.mutex); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h index e7515d96b31f..44651ca42d52 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h @@ -16,6 +16,7 @@ struct nvkm_instmem_func { void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *, int index, struct nvkm_instmem *); +void nvkm_instmem_boot(struct nvkm_instmem *); #include -- cgit v1.2.3 From e9be3c7d7ae0aa6e273ac5cf66dfd2d53479bdbf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: use fast-path for suspend backup Before: "imem: suspend completed in 5540487us" After: "imem: suspend completed in 1871526us" Suspend from Fedora 26 gnome desktop on GP102. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index c8cb8b8b1323..190fb730de17 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -74,7 +74,6 @@ nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_bar *bar = nvkm_bar(subdev); bar->func->bar1.fini(bar); - nvkm_bar_bar2_fini(subdev->device); return 0; } @@ -101,6 +100,7 @@ static void * nvkm_bar_dtor(struct nvkm_subdev *subdev) { struct nvkm_bar *bar = nvkm_bar(subdev); + nvkm_bar_bar2_fini(subdev->device); return bar->func->dtor(bar); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 8fc63ec20d6e..d7df7cb6bed3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -46,15 +46,20 @@ nvkm_instobj_save(struct nvkm_instobj *iobj) { struct nvkm_memory *memory = &iobj->memory; const u64 size = nvkm_memory_size(memory); + void __iomem *map; int i; iobj->suspend = kvmalloc(size, GFP_KERNEL); if (!iobj->suspend) return -ENOMEM; - for (i = 0; i < size; i += 4) - iobj->suspend[i / 4] = nvkm_ro32(memory, i); - + if (!(map = nvkm_kmap(memory))) { + for (i = 0; i < size; i += 4) + iobj->suspend[i / 4] = nvkm_ro32(memory, i); + } else { + memcpy_fromio(iobj->suspend, map, size); + } + nvkm_done(memory); return 0; } @@ -157,6 +162,8 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) return ret; } + nvkm_bar_bar2_fini(subdev->device); + list_for_each_entry(iobj, &imem->boot, head) { int ret = nvkm_instobj_save(iobj); if (ret) -- cgit v1.2.3 From ffd937bbd219331e4b67344c104dea09b9ed4a6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: use fast-path for resume restore Before: "imem: init completed in 299277us" After: "imem: init completed in 11574us" Suspend from Fedora 26 gnome desktop on GP102. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 13 +++++++++++-- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 3 +-- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index 190fb730de17..9646adec57cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -81,7 +81,6 @@ static int nvkm_bar_init(struct nvkm_subdev *subdev) { struct nvkm_bar *bar = nvkm_bar(subdev); - nvkm_bar_bar2_init(subdev->device); bar->func->bar1.init(bar); bar->func->bar1.wait(bar); if (bar->func->init) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index d7df7cb6bed3..b03940591a3a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -33,10 +33,17 @@ nvkm_instobj_load(struct nvkm_instobj *iobj) { struct nvkm_memory *memory = &iobj->memory; const u64 size = nvkm_memory_size(memory); + void __iomem *map; int i; - for (i = 0; i < size; i += 4) - nvkm_wo32(memory, i, iobj->suspend[i / 4]); + if (!(map = nvkm_kmap(memory))) { + for (i = 0; i < size; i += 4) + nvkm_wo32(memory, i, iobj->suspend[i / 4]); + } else { + memcpy_toio(map, iobj->suspend, size); + } + nvkm_done(memory); + kvfree(iobj->suspend); iobj->suspend = NULL; } @@ -188,6 +195,8 @@ nvkm_instmem_init(struct nvkm_subdev *subdev) nvkm_instobj_load(iobj); } + nvkm_bar_bar2_init(subdev->device); + list_for_each_entry(iobj, &imem->list, head) { if (iobj->suspend) nvkm_instobj_load(iobj); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index be5670f9fefa..4ccb8cdc7dbc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -206,7 +206,7 @@ nv50_instobj_release(struct nvkm_memory *memory) } /* Switch back to NULL accessors when last map is gone. */ - iobj->base.memory.ptrs = &nv50_instobj_slow; + iobj->base.memory.ptrs = NULL; mutex_unlock(&subdev->mutex); } } @@ -345,7 +345,6 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, *pmemory = &iobj->base.memory; nvkm_instobj_ctor(&nv50_instobj_func, &imem->base, &iobj->base); - iobj->base.memory.ptrs = &nv50_instobj_slow; iobj->imem = imem; refcount_set(&iobj->maps, 0); INIT_LIST_HEAD(&iobj->lru); -- cgit v1.2.3 From 0b11b30de9d2960d87373e50223800c8f9f6a89f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv04-nv4x: move global vmm to nvkm_mmu In a future commit, this will be constructed by common code. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_ttm.c | 5 +---- drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 12 ++++++------ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c | 8 ++++---- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c | 8 ++++---- 7 files changed, 18 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index d333c7668c23..c4326772d481 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -58,6 +58,8 @@ struct nvkm_mmu { u64 limit; u8 dma_bits; u8 lpg_shift; + + struct nvkm_vmm *vmm; }; int nv04_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index ffc3458c89de..65511f320a3a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -192,16 +192,13 @@ const struct ttm_mem_type_manager_func nouveau_gart_manager = { .debug = nouveau_gart_manager_debug }; -/*XXX*/ -#include static int nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); struct nvkm_mmu *mmu = nvxx_mmu(&drm->client.device); - struct nv04_mmu *priv = (void *)mmu; struct nvkm_vm *vm = NULL; - nvkm_vm_ref(priv->vm, &vm, NULL); + nvkm_vm_ref(mmu->vmm, &vm, NULL); man->priv = vm; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c index c95942ef8216..acc45ce5f93e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c @@ -49,8 +49,7 @@ nv04_dmaobj_bind(struct nvkm_dmaobj *base, struct nvkm_gpuobj *parent, int ret; if (dmaobj->clone) { - struct nv04_mmu *mmu = nv04_mmu(device->mmu); - struct nvkm_memory *pgt = mmu->vm->pgt[0].mem[0]; + struct nvkm_memory *pgt = device->mmu->vmm->pgt[0].mem[0]; if (!dmaobj->base.start) return nvkm_gpuobj_wrap(pgt, pgpuobj); nvkm_kmap(pgt); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 37927c3fdc3e..cd16442f1a91 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -81,15 +81,15 @@ nv04_mmu_oneinit(struct nvkm_mmu *base) int ret; ret = nvkm_vm_create(&mmu->base, 0, NV04_PDMA_SIZE, 0, 4096, NULL, - &mmu->vm); + &mmu->base.vmm); if (ret) return ret; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 + 8, 16, true, &dma); - mmu->vm->pgt[0].mem[0] = dma; - mmu->vm->pgt[0].refcount[0] = 1; + mmu->base.vmm->pgt[0].mem[0] = dma; + mmu->base.vmm->pgt[0].refcount[0] = 1; if (ret) return ret; @@ -105,9 +105,9 @@ nv04_mmu_dtor(struct nvkm_mmu *base) { struct nv04_mmu *mmu = nv04_mmu(base); struct nvkm_device *device = mmu->base.subdev.device; - if (mmu->vm) { - nvkm_memory_del(&mmu->vm->pgt[0].mem[0]); - nvkm_vm_ref(NULL, &mmu->vm, NULL); + if (mmu->base.vmm) { + nvkm_memory_del(&mmu->base.vmm->pgt[0].mem[0]); + nvkm_vm_ref(NULL, &mmu->base.vmm, NULL); } if (mmu->nullp) { dma_free_coherent(device->dev, 16 * 1024, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h index 363e33b296d5..6b8f14c6db3d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h @@ -5,7 +5,6 @@ struct nv04_mmu { struct nvkm_mmu base; - struct nvkm_vm *vm; dma_addr_t null; void *nullp; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c index c6a26f907009..9b5375c587a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c @@ -93,14 +93,14 @@ nv41_mmu_oneinit(struct nvkm_mmu *base) int ret; ret = nvkm_vm_create(&mmu->base, 0, NV41_GART_SIZE, 0, 4096, NULL, - &mmu->vm); + &mmu->base.vmm); if (ret) return ret; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, (NV41_GART_SIZE / NV41_GART_PAGE) * 4, 16, true, - &mmu->vm->pgt[0].mem[0]); - mmu->vm->pgt[0].refcount[0] = 1; + &mmu->base.vmm->pgt[0].mem[0]); + mmu->base.vmm->pgt[0].refcount[0] = 1; return ret; } @@ -109,7 +109,7 @@ nv41_mmu_init(struct nvkm_mmu *base) { struct nv04_mmu *mmu = nv04_mmu(base); struct nvkm_device *device = mmu->base.subdev.device; - struct nvkm_memory *dma = mmu->vm->pgt[0].mem[0]; + struct nvkm_memory *dma = mmu->base.vmm->pgt[0].mem[0]; nvkm_wr32(device, 0x100800, 0x00000002 | nvkm_memory_addr(dma)); nvkm_mask(device, 0x10008c, 0x00000100, 0x00000100); nvkm_wr32(device, 0x100820, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c index a648c2395545..cc97500a0901 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c @@ -173,15 +173,15 @@ nv44_mmu_oneinit(struct nvkm_mmu *base) } ret = nvkm_vm_create(&mmu->base, 0, NV44_GART_SIZE, 0, 4096, NULL, - &mmu->vm); + &mmu->base.vmm); if (ret) return ret; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, (NV44_GART_SIZE / NV44_GART_PAGE) * 4, 512 * 1024, true, - &mmu->vm->pgt[0].mem[0]); - mmu->vm->pgt[0].refcount[0] = 1; + &mmu->base.vmm->pgt[0].mem[0]); + mmu->base.vmm->pgt[0].refcount[0] = 1; return ret; } @@ -190,7 +190,7 @@ nv44_mmu_init(struct nvkm_mmu *base) { struct nv04_mmu *mmu = nv04_mmu(base); struct nvkm_device *device = mmu->base.subdev.device; - struct nvkm_memory *gart = mmu->vm->pgt[0].mem[0]; + struct nvkm_memory *gart = mmu->base.vmm->pgt[0].mem[0]; u32 addr; /* calculate vram address of this PRAMIN block, object must be -- cgit v1.2.3 From 2854ab8dd81b73ffd867399fd506f44f6f624bca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb: finalise big page size selection in constructor MMU will need to know this during its constructor, so we can't delay deciding this until init-time. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 12 +++++++++--- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c | 14 ++++++-------- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h | 2 -- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c | 17 +++++++---------- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 8 +++++--- 10 files changed, 32 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index a7049c041594..fa0fad10b62c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -135,8 +135,13 @@ nvkm_fb_init(struct nvkm_subdev *subdev) if (fb->func->init) fb->func->init(fb); - if (fb->func->init_page) - fb->func->init_page(fb); + + if (fb->func->init_page) { + ret = fb->func->init_page(fb); + if (WARN_ON(ret)) + return ret; + } + if (fb->func->init_unkn) fb->func->init_unkn(fb); return 0; @@ -176,7 +181,8 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, nvkm_subdev_ctor(&nvkm_fb, device, index, &fb->subdev); fb->func = func; fb->tile.regions = fb->func->tile.regions; - fb->page = nvkm_longopt(device->cfgopt, "NvFbBigPage", 0); + fb->page = nvkm_longopt(device->cfgopt, "NvFbBigPage", + fb->func->default_bigpage); } int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index a239e73562c8..a308a99ef64e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c @@ -80,20 +80,17 @@ gf100_fb_oneinit(struct nvkm_fb *base) return 0; } -void +int gf100_fb_init_page(struct nvkm_fb *fb) { struct nvkm_device *device = fb->subdev.device; switch (fb->page) { - case 16: - nvkm_mask(device, 0x100c80, 0x00000001, 0x00000001); - break; - case 17: + case 16: nvkm_mask(device, 0x100c80, 0x00000001, 0x00000001); break; + case 17: nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); break; default: - nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); - fb->page = 17; - break; + return -EINVAL; } + return 0; } void @@ -144,6 +141,7 @@ gf100_fb = { .intr = gf100_fb_intr, .ram_new = gf100_ram_new, .memtype_valid = gf100_fb_memtype_valid, + .default_bigpage = 17, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h index 412eb89834e8..e3cf0515bb70 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h @@ -17,7 +17,5 @@ void gf100_fb_intr(struct nvkm_fb *); void gp100_fb_init(struct nvkm_fb *); -void gm200_fb_init_page(struct nvkm_fb *fb); void gm200_fb_init(struct nvkm_fb *base); - #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c index 56af84aa333b..4c012fa02de1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c @@ -33,6 +33,7 @@ gf108_fb = { .intr = gf100_fb_intr, .ram_new = gf108_ram_new, .memtype_valid = gf100_fb_memtype_valid, + .default_bigpage = 17, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c index 4245e2e6e604..7ff647499acf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c @@ -33,6 +33,7 @@ gk104_fb = { .intr = gf100_fb_intr, .ram_new = gk104_ram_new, .memtype_valid = gf100_fb_memtype_valid, + .default_bigpage = 17, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c index 5d34d6136616..59308575b1d4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c @@ -31,6 +31,7 @@ gk20a_fb = { .init_page = gf100_fb_init_page, .intr = gf100_fb_intr, .memtype_valid = gf100_fb_memtype_valid, + .default_bigpage = 17, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c index db699025f546..005aa9d6db32 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c @@ -33,6 +33,7 @@ gm107_fb = { .intr = gf100_fb_intr, .ram_new = gm107_ram_new, .memtype_valid = gf100_fb_memtype_valid, + .default_bigpage = 17, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c index d83da5ddbc1e..cc3f90304c1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c @@ -26,22 +26,18 @@ #include -void +int gm200_fb_init_page(struct nvkm_fb *fb) { struct nvkm_device *device = fb->subdev.device; switch (fb->page) { - case 16: - nvkm_mask(device, 0x100c80, 0x00000801, 0x00000001); - break; - case 17: - nvkm_mask(device, 0x100c80, 0x00000801, 0x00000000); - break; + case 16: nvkm_mask(device, 0x100c80, 0x00000801, 0x00000001); break; + case 17: nvkm_mask(device, 0x100c80, 0x00000801, 0x00000000); break; + case 0: nvkm_mask(device, 0x100c80, 0x00000800, 0x00000800); break; default: - nvkm_mask(device, 0x100c80, 0x00000800, 0x00000800); - fb->page = 0; - break; + return -EINVAL; } + return 0; } void @@ -70,6 +66,7 @@ gm200_fb = { .intr = gf100_fb_intr, .ram_new = gm200_ram_new, .memtype_valid = gf100_fb_memtype_valid, + .default_bigpage = 0 /* per-instance. */, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c index b87c233bcd6d..e66a0a871043 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c @@ -31,6 +31,7 @@ gm20b_fb = { .init_page = gm200_fb_init_page, .intr = gf100_fb_intr, .memtype_valid = gf100_fb_memtype_valid, + .default_bigpage = 0 /* per-instance. */, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index e905d44fa1d5..afaa68da3221 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -8,7 +8,7 @@ struct nvkm_fb_func { void *(*dtor)(struct nvkm_fb *); int (*oneinit)(struct nvkm_fb *); void (*init)(struct nvkm_fb *); - void (*init_page)(struct nvkm_fb *); + int (*init_page)(struct nvkm_fb *); void (*init_unkn)(struct nvkm_fb *); void (*intr)(struct nvkm_fb *); @@ -25,6 +25,8 @@ struct nvkm_fb_func { int (*ram_new)(struct nvkm_fb *, struct nvkm_ram **); bool (*memtype_valid)(struct nvkm_fb *, u32 memtype); + + u8 default_bigpage; }; void nvkm_fb_ctor(const struct nvkm_fb_func *, struct nvkm_device *device, @@ -62,8 +64,8 @@ void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, u32 pitch, u32 flags, struct nvkm_fb_tile *); int gf100_fb_oneinit(struct nvkm_fb *); -void gf100_fb_init_page(struct nvkm_fb *); +int gf100_fb_init_page(struct nvkm_fb *); bool gf100_fb_memtype_valid(struct nvkm_fb *, u32); -void gm200_fb_init_page(struct nvkm_fb *); +int gm200_fb_init_page(struct nvkm_fb *); #endif -- cgit v1.2.3 From 223eaf4bf8a8c9668b82cb4a1c3a4acb60d33aba Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/gr/gf100-gk208: make use of init_gpc_mmu() hook to share setup Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 27 ++++++++++++++++--------- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 13 ++---------- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + 11 files changed, 29 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 99689f4de502..48556bfdbd4a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1903,25 +1903,33 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, return 0; } +void +gf100_gr_init_gpc_mmu(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + struct nvkm_fb *fb = device->fb; + + nvkm_wr32(device, 0x418880, 0x00000000); + nvkm_wr32(device, 0x4188a4, 0x00000000); + nvkm_wr32(device, 0x418888, 0x00000000); + nvkm_wr32(device, 0x41888c, 0x00000000); + nvkm_wr32(device, 0x418890, 0x00000000); + nvkm_wr32(device, 0x418894, 0x00000000); + nvkm_wr32(device, 0x4188b4, nvkm_memory_addr(fb->mmu_wr) >> 8); + nvkm_wr32(device, 0x4188b8, nvkm_memory_addr(fb->mmu_rd) >> 8); +} + int gf100_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - struct nvkm_fb *fb = device->fb; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; int i; - nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08a4), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0888), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x088c), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8); - nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); + gr->func->init_gpc_mmu(gr); gf100_gr_mmio(gr, gr->func->mmio); @@ -2036,6 +2044,7 @@ gf100_gr_gpccs_ucode = { static const struct gf100_gr_func gf100_gr = { .init = gf100_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 290148816360..51c1e380ffb6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -254,6 +254,7 @@ extern const struct gf100_gr_init gf100_gr_init_mpc_0[]; extern const struct gf100_gr_init gf100_gr_init_be_0[]; extern const struct gf100_gr_init gf100_gr_init_fe_1[]; extern const struct gf100_gr_init gf100_gr_init_pe_1[]; +void gf100_gr_init_gpc_mmu(struct gf100_gr *); extern const struct gf100_gr_init gf104_gr_init_ds_0[]; extern const struct gf100_gr_init gf104_gr_init_tex_0[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index d736dcd55ea2..ec0f11983b23 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -115,6 +115,7 @@ gf104_gr_pack_mmio[] = { static const struct gf100_gr_func gf104_gr = { .init = gf100_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 2f0d24498427..cc152eb74123 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -106,6 +106,7 @@ gf108_gr_pack_mmio[] = { static const struct gf100_gr_func gf108_gr = { .init = gf100_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index d1d942eb86af..10d2d73ca8c3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -87,6 +87,7 @@ gf110_gr_pack_mmio[] = { static const struct gf100_gr_func gf110_gr = { .init = gf100_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 0124e468086e..ac09a07c4150 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -123,6 +123,7 @@ gf117_gr_gpccs_ucode = { static const struct gf100_gr_func gf117_gr = { .init = gf100_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 8d8e4cafe28f..7f449ec6f760 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -178,6 +178,7 @@ gf119_gr_pack_mmio[] = { static const struct gf100_gr_func gf119_gr = { .init = gf100_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index ec22da6c99fc..5e82f94c2245 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -24,8 +24,6 @@ #include "gf100.h" #include "ctxgf100.h" -#include - #include /******************************************************************************* @@ -207,21 +205,13 @@ int gk104_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - struct nvkm_fb *fb = device->fb; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; int i; - nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08a4), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0888), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x088c), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8); - nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); + gr->func->init_gpc_mmu(gr); gf100_gr_mmio(gr, gr->func->mmio); @@ -339,6 +329,7 @@ gk104_gr_gpccs_ucode = { static const struct gf100_gr_func gk104_gr = { .init = gk104_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index f31b171a4102..a38e19b61c1d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -183,6 +183,7 @@ gk110_gr_gpccs_ucode = { static const struct gf100_gr_func gk110_gr = { .init = gk104_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index d76dd178007f..1912c0bfd7ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -103,6 +103,7 @@ gk110b_gr_pack_mmio[] = { static const struct gf100_gr_func gk110b_gr = { .init = gk104_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 14bbe6ed02a9..1fc258163f25 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -162,6 +162,7 @@ gk208_gr_gpccs_ucode = { static const struct gf100_gr_func gk208_gr = { .init = gk104_gr_init, + .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, -- cgit v1.2.3 From b6838c14a28c06ea51a60a829ec290e6aec9d128 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/gr/gf100-gk208: copy big page size setting from fb Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 48556bfdbd4a..49c7d08b0ceb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1909,7 +1909,7 @@ gf100_gr_init_gpc_mmu(struct gf100_gr *gr) struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_fb *fb = device->fb; - nvkm_wr32(device, 0x418880, 0x00000000); + nvkm_wr32(device, 0x418880, nvkm_rd32(device, 0x100c80) & 0x00000001); nvkm_wr32(device, 0x4188a4, 0x00000000); nvkm_wr32(device, 0x418888, 0x00000000); nvkm_wr32(device, 0x41888c, 0x00000000); -- cgit v1.2.3 From e75c091baf99dd739f6c3c1135fd667af174bd45 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: store nouveau_drm in nouveau_cli, as opposed to drm_device Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 4 ++-- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 3da87932a21f..e1eb8ba781fe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -187,7 +187,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, struct sg_table *sg, struct reservation_object *robj, struct nouveau_bo **pnvbo) { - struct nouveau_drm *drm = nouveau_drm(cli->dev); + struct nouveau_drm *drm = cli->drm; struct nouveau_bo *nvbo; size_t acc_size; int ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 595630d1fb9e..632edb73ed53 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -128,7 +128,7 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, int ret; snprintf(cli->name, sizeof(cli->name), "%s", sname); - cli->dev = drm->dev; + cli->drm = drm; mutex_init(&cli->mutex); usif_client_init(cli); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index ec60d52790e3..84b847042253 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -86,7 +86,7 @@ enum nouveau_drm_handle { struct nouveau_cli { struct nvif_client base; - struct drm_device *dev; + struct nouveau_drm *drm; struct mutex mutex; struct nvif_device device; @@ -204,7 +204,7 @@ void nouveau_drm_device_remove(struct drm_device *dev); #define NV_PRINTK(l,c,f,a...) do { \ struct nouveau_cli *_cli = (c); \ - dev_##l(_cli->dev->dev, "%s: "f, _cli->name, ##a); \ + dev_##l(_cli->drm->dev->dev, "%s: "f, _cli->name, ##a); \ } while(0) #define NV_FATAL(drm,f,a...) NV_PRINTK(crit, &(drm)->client, f, ##a) #define NV_ERROR(drm,f,a...) NV_PRINTK(err, &(drm)->client, f, ##a) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 2170534101ca..23140c4f3ac5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -179,7 +179,7 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain, uint32_t tile_mode, uint32_t tile_flags, struct nouveau_bo **pnvbo) { - struct nouveau_drm *drm = nouveau_drm(cli->dev); + struct nouveau_drm *drm = cli->drm; struct nouveau_bo *nvbo; u32 flags = 0; int ret; -- cgit v1.2.3 From bc3b0c7aff4d91605d966c01571f579827449d38 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: remove unused sysmem fence code Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 2 -- drivers/gpu/drm/nouveau/nouveau_fence.h | 4 ---- drivers/gpu/drm/nouveau/nv84_fence.c | 38 ++------------------------------- 3 files changed, 2 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 99e14e3e0fe4..3e4412d11571 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -474,8 +474,6 @@ nouveau_fence_new(struct nouveau_channel *chan, bool sysmem, if (!fence) return -ENOMEM; - fence->sysmem = sysmem; - ret = nouveau_fence_emit(fence, chan); if (ret) nouveau_fence_unref(&fence); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index d5e58a38f160..28a213509797 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -12,8 +12,6 @@ struct nouveau_fence { struct list_head head; - bool sysmem; - struct nouveau_channel __rcu *channel; unsigned long timeout; }; @@ -91,13 +89,11 @@ int nouveau_flip_complete(struct nvif_notify *); struct nv84_fence_chan { struct nouveau_fence_chan base; struct nvkm_vma vma; - struct nvkm_vma vma_gart; }; struct nv84_fence_priv { struct nouveau_fence_priv base; struct nouveau_bo *bo; - struct nouveau_bo *bo_gart; u32 *suspend; struct mutex mutex; }; diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index bd7a8a1e4ad9..e5f6249edde9 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -68,12 +68,7 @@ nv84_fence_emit(struct nouveau_fence *fence) { struct nouveau_channel *chan = fence->channel; struct nv84_fence_chan *fctx = chan->fence; - u64 addr = chan->chid * 16; - - if (fence->sysmem) - addr += fctx->vma_gart.offset; - else - addr += fctx->vma.offset; + u64 addr = fctx->vma.offset + chan->chid * 16; return fctx->base.emit32(chan, addr, fence->base.seqno); } @@ -83,12 +78,7 @@ nv84_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *prev, struct nouveau_channel *chan) { struct nv84_fence_chan *fctx = chan->fence; - u64 addr = prev->chid * 16; - - if (fence->sysmem) - addr += fctx->vma_gart.offset; - else - addr += fctx->vma.offset; + u64 addr = fctx->vma.offset + prev->chid * 16; return fctx->base.sync32(chan, addr, fence->base.seqno); } @@ -108,7 +98,6 @@ nv84_fence_context_del(struct nouveau_channel *chan) nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence); mutex_lock(&priv->mutex); - nouveau_bo_vma_del(priv->bo, &fctx->vma_gart); nouveau_bo_vma_del(priv->bo, &fctx->vma); mutex_unlock(&priv->mutex); nouveau_fence_context_del(&fctx->base); @@ -138,10 +127,6 @@ nv84_fence_context_new(struct nouveau_channel *chan) mutex_lock(&priv->mutex); ret = nouveau_bo_vma_add(priv->bo, cli->vm, &fctx->vma); - if (ret == 0) { - ret = nouveau_bo_vma_add(priv->bo_gart, cli->vm, - &fctx->vma_gart); - } mutex_unlock(&priv->mutex); if (ret) @@ -182,10 +167,6 @@ static void nv84_fence_destroy(struct nouveau_drm *drm) { struct nv84_fence_priv *priv = drm->fence; - nouveau_bo_unmap(priv->bo_gart); - if (priv->bo_gart) - nouveau_bo_unpin(priv->bo_gart); - nouveau_bo_ref(NULL, &priv->bo_gart); nouveau_bo_unmap(priv->bo); if (priv->bo) nouveau_bo_unpin(priv->bo); @@ -238,21 +219,6 @@ nv84_fence_create(struct nouveau_drm *drm) nouveau_bo_ref(NULL, &priv->bo); } - if (ret == 0) - ret = nouveau_bo_new(&drm->client, 16 * priv->base.contexts, 0, - TTM_PL_FLAG_TT | TTM_PL_FLAG_UNCACHED, 0, - 0, NULL, NULL, &priv->bo_gart); - if (ret == 0) { - ret = nouveau_bo_pin(priv->bo_gart, TTM_PL_FLAG_TT, false); - if (ret == 0) { - ret = nouveau_bo_map(priv->bo_gart); - if (ret) - nouveau_bo_unpin(priv->bo_gart); - } - if (ret) - nouveau_bo_ref(NULL, &priv->bo_gart); - } - if (ret) nv84_fence_destroy(drm); return ret; -- cgit v1.2.3 From 7760a2e38a8324688e83b91f91ff7be710e70db1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: split various bo flags out into their own members It's far more convenient to deal with like this. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 71 +++++++++++++++++++--------------- drivers/gpu/drm/nouveau/nouveau_bo.h | 10 +++-- drivers/gpu/drm/nouveau/nouveau_gem.c | 11 +++++- drivers/gpu/drm/nouveau/nouveau_gem.h | 3 -- drivers/gpu/drm/nouveau/nouveau_ttm.c | 14 +++---- drivers/gpu/drm/nouveau/nv50_display.c | 8 ++-- 6 files changed, 66 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index e1eb8ba781fe..40a8c6589f3d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -97,7 +97,7 @@ nv10_bo_put_tile_region(struct drm_device *dev, struct nouveau_drm_tile *tile, static struct nouveau_drm_tile * nv10_bo_set_tiling(struct drm_device *dev, u32 addr, - u32 size, u32 pitch, u32 flags) + u32 size, u32 pitch, u32 zeta) { struct nouveau_drm *drm = nouveau_drm(dev); struct nvkm_fb *fb = nvxx_fb(&drm->client.device); @@ -120,8 +120,7 @@ nv10_bo_set_tiling(struct drm_device *dev, u32 addr, } if (found) - nv10_bo_update_tile_region(dev, found, addr, size, - pitch, flags); + nv10_bo_update_tile_region(dev, found, addr, size, pitch, zeta); return found; } @@ -155,27 +154,27 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags, struct nvif_device *device = &drm->client.device; if (device->info.family < NV_DEVICE_INFO_V0_TESLA) { - if (nvbo->tile_mode) { + if (nvbo->mode) { if (device->info.chipset >= 0x40) { *align = 65536; - *size = roundup_64(*size, 64 * nvbo->tile_mode); + *size = roundup_64(*size, 64 * nvbo->mode); } else if (device->info.chipset >= 0x30) { *align = 32768; - *size = roundup_64(*size, 64 * nvbo->tile_mode); + *size = roundup_64(*size, 64 * nvbo->mode); } else if (device->info.chipset >= 0x20) { *align = 16384; - *size = roundup_64(*size, 64 * nvbo->tile_mode); + *size = roundup_64(*size, 64 * nvbo->mode); } else if (device->info.chipset >= 0x10) { *align = 16384; - *size = roundup_64(*size, 32 * nvbo->tile_mode); + *size = roundup_64(*size, 32 * nvbo->mode); } } } else { - *size = roundup_64(*size, (1 << nvbo->page_shift)); - *align = max((1 << nvbo->page_shift), *align); + *size = roundup_64(*size, (1 << nvbo->page)); + *align = max((1 << nvbo->page), *align); } *size = roundup_64(*size, PAGE_SIZE); @@ -207,18 +206,34 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, INIT_LIST_HEAD(&nvbo->head); INIT_LIST_HEAD(&nvbo->entry); INIT_LIST_HEAD(&nvbo->vma_list); - nvbo->tile_mode = tile_mode; - nvbo->tile_flags = tile_flags; nvbo->bo.bdev = &drm->ttm.bdev; nvbo->cli = cli; if (!nvxx_device(&drm->client.device)->func->cpu_coherent) nvbo->force_coherent = flags & TTM_PL_FLAG_UNCACHED; - nvbo->page_shift = 12; + if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) { + nvbo->kind = (tile_flags & 0x0000ff00) >> 8; + nvbo->comp = gf100_pte_storage_type_map[nvbo->kind] != nvbo->kind; + } else + if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { + nvbo->kind = (tile_flags & 0x00007f00) >> 8; + nvbo->comp = (tile_flags & 0x00030000) >> 16; + } else { + nvbo->zeta = (tile_flags & 0x00000007); + } + nvbo->mode = tile_mode; + nvbo->contig = !(tile_flags & NOUVEAU_GEM_TILE_NONCONTIG); + + nvbo->page = 12; if (drm->client.vm) { if (!(flags & TTM_PL_FLAG_TT) && size > 256 * 1024) - nvbo->page_shift = drm->client.vm->mmu->lpg_shift; + nvbo->page = drm->client.vm->mmu->lpg_shift; + else { + if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) + nvbo->kind = gf100_pte_storage_type_map[nvbo->kind]; + nvbo->comp = 0; + } } nouveau_bo_fixup_align(nvbo, flags, &align, &size); @@ -262,7 +277,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type) unsigned i, fpfn, lpfn; if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CELSIUS && - nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && + nvbo->mode && (type & TTM_PL_FLAG_VRAM) && nvbo->bo.mem.num_pages < vram_pages / 4) { /* * Make sure that the color and depth buffers are handled @@ -270,7 +285,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type) * speed up when alpha-blending and depth-test are enabled * at the same time. */ - if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { + if (nvbo->zeta) { fpfn = vram_pages / 2; lpfn = ~0; } else { @@ -321,14 +336,10 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype, bool contig) if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA && memtype == TTM_PL_FLAG_VRAM && contig) { - if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) { - if (bo->mem.mem_type == TTM_PL_VRAM) { - struct nvkm_mem *mem = bo->mem.mm_node; - if (!nvkm_mm_contiguous(mem->mem)) - evict = true; - } - nvbo->tile_flags &= ~NOUVEAU_GEM_TILE_NONCONTIG; + if (!nvbo->contig) { + nvbo->contig = true; force = true; + evict = true; } } @@ -376,7 +387,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype, bool contig) out: if (force && ret) - nvbo->tile_flags |= NOUVEAU_GEM_TILE_NONCONTIG; + nvbo->contig = false; ttm_bo_unreserve(bo); return ret; } @@ -1210,7 +1221,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, list_for_each_entry(vma, &nvbo->vma_list, head) { if (new_reg && new_reg->mem_type != TTM_PL_SYSTEM && (new_reg->mem_type == TTM_PL_VRAM || - nvbo->page_shift != vma->vm->mmu->lpg_shift)) { + nvbo->page != vma->vm->mmu->lpg_shift)) { nvkm_vm_map(vma, new_reg->mm_node); } else { WARN_ON(ttm_bo_wait(bo, false, false)); @@ -1234,8 +1245,7 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_reg, if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_CELSIUS) { *new_tile = nv10_bo_set_tiling(dev, offset, new_reg->size, - nvbo->tile_mode, - nvbo->tile_flags); + nvbo->mode, nvbo->zeta); } return 0; @@ -1408,7 +1418,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) */ if (bo->mem.mem_type != TTM_PL_VRAM) { if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA || - !nouveau_bo_tile_layout(nvbo)) + !nvbo->kind) return 0; if (bo->mem.mem_type == TTM_PL_SYSTEM) { @@ -1596,14 +1606,13 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nvkm_vm *vm, const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT; int ret; - ret = nvkm_vm_get(vm, size, nvbo->page_shift, - NV_MEM_ACCESS_RW, vma); + ret = nvkm_vm_get(vm, size, nvbo->page, NV_MEM_ACCESS_RW, vma); if (ret) return ret; if ( nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && (nvbo->bo.mem.mem_type == TTM_PL_VRAM || - nvbo->page_shift != vma->vm->mmu->lpg_shift)) + nvbo->page != vma->vm->mmu->lpg_shift)) nvkm_vm_map(vma, nvbo->bo.mem.mm_node); list_add_tail(&vma->head, &nvbo->vma_list); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index b06a5385d6dd..a179bbf25dce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -24,12 +24,16 @@ struct nouveau_bo { bool validate_mapped; struct list_head vma_list; - unsigned page_shift; struct nouveau_cli *cli; - u32 tile_mode; - u32 tile_flags; + unsigned contig:1; + unsigned page:5; + unsigned kind:8; + unsigned comp:3; + unsigned zeta:3; + unsigned mode; + struct nouveau_drm_tile *tile; /* Only valid if allocated via nouveau_gem_new() and iff you hold a diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 23140c4f3ac5..2d924739997a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -246,8 +246,15 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT; rep->map_handle = drm_vma_node_offset_addr(&nvbo->bo.vma_node); - rep->tile_mode = nvbo->tile_mode; - rep->tile_flags = nvbo->tile_flags; + rep->tile_mode = nvbo->mode; + rep->tile_flags = nvbo->contig ? 0 : NOUVEAU_GEM_TILE_NONCONTIG; + if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) + rep->tile_flags |= nvbo->kind << 8; + else + if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) + rep->tile_flags |= nvbo->kind << 8 | nvbo->comp << 16; + else + rep->tile_flags |= nvbo->zeta; return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h index 8fa6ed9ddd3a..d39f845dda87 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.h +++ b/drivers/gpu/drm/nouveau/nouveau_gem.h @@ -6,9 +6,6 @@ #include "nouveau_drv.h" #include "nouveau_bo.h" -#define nouveau_bo_tile_layout(nvbo) \ - ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) - static inline struct nouveau_bo * nouveau_gem_object(struct drm_gem_object *gem) { diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 65511f320a3a..b8727413db12 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -88,18 +88,18 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, if (drm->client.device.info.ram_size == 0) return -ENOMEM; - if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) - size_nc = 1 << nvbo->page_shift; + if (!nvbo->contig) + size_nc = 1 << nvbo->page; ret = ram->func->get(ram, reg->num_pages << PAGE_SHIFT, reg->page_alignment << PAGE_SHIFT, size_nc, - (nvbo->tile_flags >> 8) & 0x3ff, &node); + nvbo->comp << 8 | nvbo->kind, &node); if (ret) { reg->mm_node = NULL; return (ret == -ENOSPC) ? 0 : ret; } - node->page_shift = nvbo->page_shift; + node->page_shift = nvbo->page; reg->mm_node = node; reg->start = node->offset >> PAGE_SHIFT; @@ -158,14 +158,12 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, case NV_DEVICE_INFO_V0_CURIE: break; case NV_DEVICE_INFO_V0_TESLA: - if (drm->client.device.info.chipset != 0x50) - node->memtype = (nvbo->tile_flags & 0x7f00) >> 8; - break; case NV_DEVICE_INFO_V0_FERMI: case NV_DEVICE_INFO_V0_KEPLER: case NV_DEVICE_INFO_V0_MAXWELL: case NV_DEVICE_INFO_V0_PASCAL: - node->memtype = (nvbo->tile_flags & 0xff00) >> 8; + if (drm->client.device.info.chipset != 0x50) + node->memtype = nvbo->kind; break; default: NV_WARN(drm, "%s: unhandled family type %x\n", __func__, diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 1f3872f438c9..92d46222c79d 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -424,7 +424,7 @@ nv50_dmac_ctxdma_new(struct nv50_dmac *dmac, struct nouveau_framebuffer *fb) { struct nouveau_drm *drm = nouveau_drm(fb->base.dev); struct nv50_dmac_ctxdma *ctxdma; - const u8 kind = (fb->nvbo->tile_flags & 0x0000ff00) >> 8; + const u8 kind = fb->nvbo->kind; const u32 handle = 0xfb000000 | kind; struct { struct nv_dma_v0 base; @@ -847,7 +847,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, asyw->image.w = fb->base.width; asyw->image.h = fb->base.height; - asyw->image.kind = (fb->nvbo->tile_flags & 0x0000ff00) >> 8; + asyw->image.kind = fb->nvbo->kind; if (asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) asyw->interval = 0; @@ -857,9 +857,9 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, if (asyw->image.kind) { asyw->image.layout = 0; if (drm->client.device.info.chipset >= 0xc0) - asyw->image.block = fb->nvbo->tile_mode >> 4; + asyw->image.block = fb->nvbo->mode >> 4; else - asyw->image.block = fb->nvbo->tile_mode; + asyw->image.block = fb->nvbo->mode; asyw->image.pitch = (fb->base.pitches[0] / 4) << 4; } else { asyw->image.layout = 1; -- cgit v1.2.3 From 425b34f7df63a2eacf24b721a6f450126e691b6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: simplify const-va map condition We don't really care about where the memory is, just that it's compatible with a VMA allocated for a given page size. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 40a8c6589f3d..22d4b90de432 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1212,6 +1212,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, struct ttm_mem_reg *new_reg) { struct nouveau_bo *nvbo = nouveau_bo(bo); + struct nvkm_mem *mem = new_reg ? new_reg->mm_node : NULL; struct nvkm_vma *vma; /* ttm can now (stupidly) pass the driver bos it didn't create... */ @@ -1219,10 +1220,9 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, return; list_for_each_entry(vma, &nvbo->vma_list, head) { - if (new_reg && new_reg->mem_type != TTM_PL_SYSTEM && - (new_reg->mem_type == TTM_PL_VRAM || - nvbo->page != vma->vm->mmu->lpg_shift)) { - nvkm_vm_map(vma, new_reg->mm_node); + if (mem && new_reg->mem_type != TTM_PL_SYSTEM && + mem->page_shift == nvbo->page) { + nvkm_vm_map(vma, mem); } else { WARN_ON(ttm_bo_wait(bo, false, false)); nvkm_vm_unmap(vma); @@ -1604,15 +1604,15 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nvkm_vm *vm, struct nvkm_vma *vma) { const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT; + struct nvkm_mem *mem = nvbo->bo.mem.mm_node; int ret; ret = nvkm_vm_get(vm, size, nvbo->page, NV_MEM_ACCESS_RW, vma); if (ret) return ret; - if ( nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && - (nvbo->bo.mem.mem_type == TTM_PL_VRAM || - nvbo->page != vma->vm->mmu->lpg_shift)) + if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && + mem->page_shift == nvbo->page) nvkm_vm_map(vma, nvbo->bo.mem.mm_node); list_add_tail(&vma->head, &nvbo->vma_list); -- cgit v1.2.3 From a48296ab9dbe8b384ba58db5e8553ba35b774bb2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: swap loop order in move_notify() hook The conditional is the same for every mapping. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 22d4b90de432..50b400edcb88 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1219,11 +1219,13 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, if (bo->destroy != nouveau_bo_del_ttm) return; - list_for_each_entry(vma, &nvbo->vma_list, head) { - if (mem && new_reg->mem_type != TTM_PL_SYSTEM && - mem->page_shift == nvbo->page) { + if (mem && new_reg->mem_type != TTM_PL_SYSTEM && + mem->page_shift == nvbo->page) { + list_for_each_entry(vma, &nvbo->vma_list, head) { nvkm_vm_map(vma, mem); - } else { + } + } else { + list_for_each_entry(vma, &nvbo->vma_list, head) { WARN_ON(ttm_bo_wait(bo, false, false)); nvkm_vm_unmap(vma); } -- cgit v1.2.3 From 792067e00b4e1db30b6d27749a6b902d92564c1f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: remove unnecessary use of ttm_mem_type_manager::priv Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_ttm.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index b8727413db12..663f2983914f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -35,16 +35,12 @@ static int nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { - struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nvkm_fb *fb = nvxx_fb(&drm->client.device); - man->priv = fb; return 0; } static int nouveau_vram_manager_fini(struct ttm_mem_type_manager *man) { - man->priv = NULL; return 0; } @@ -193,20 +189,12 @@ const struct ttm_mem_type_manager_func nouveau_gart_manager = { static int nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { - struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nvkm_mmu *mmu = nvxx_mmu(&drm->client.device); - struct nvkm_vm *vm = NULL; - nvkm_vm_ref(mmu->vmm, &vm, NULL); - man->priv = vm; return 0; } static int nv04_gart_manager_fini(struct ttm_mem_type_manager *man) { - struct nvkm_vm *vm = man->priv; - nvkm_vm_ref(NULL, &vm, NULL); - man->priv = NULL; return 0; } @@ -226,6 +214,8 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, const struct ttm_place *place, struct ttm_mem_reg *reg) { + struct nouveau_drm *drm = nouveau_bdev(man->bdev); + struct nvkm_mmu *mmu = nvxx_mmu(&drm->client.device); struct nvkm_mem *node; int ret; @@ -235,7 +225,7 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, node->page_shift = 12; - ret = nvkm_vm_get(man->priv, reg->num_pages << 12, node->page_shift, + ret = nvkm_vm_get(mmu->vmm, reg->num_pages << 12, node->page_shift, NV_MEM_ACCESS_RW, &node->vma[0]); if (ret) { if (ret == -ENOSPC) { -- cgit v1.2.3 From 6be4421a9f5f6d1e980a88e189453cb766744cac Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: consolidate identical functions in nouveau_ttm.c Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_ttm.c | 63 ++++++++++------------------------- 1 file changed, 17 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 663f2983914f..e6e767558a3b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -33,17 +33,23 @@ #include static int -nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) +nouveau_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { return 0; } static int -nouveau_vram_manager_fini(struct ttm_mem_type_manager *man) +nouveau_manager_fini(struct ttm_mem_type_manager *man) { return 0; } +static void +nouveau_manager_debug(struct ttm_mem_type_manager *man, + struct drm_printer *printer) +{ +} + static inline void nvkm_mem_node_cleanup(struct nvkm_mem *node) { @@ -103,24 +109,13 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, } const struct ttm_mem_type_manager_func nouveau_vram_manager = { - .init = nouveau_vram_manager_init, - .takedown = nouveau_vram_manager_fini, + .init = nouveau_manager_init, + .takedown = nouveau_manager_fini, .get_node = nouveau_vram_manager_new, .put_node = nouveau_vram_manager_del, + .debug = nouveau_manager_debug, }; -static int -nouveau_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) -{ - return 0; -} - -static int -nouveau_gart_manager_fini(struct ttm_mem_type_manager *man) -{ - return 0; -} - static void nouveau_gart_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *reg) @@ -172,32 +167,14 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, return 0; } -static void -nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, - struct drm_printer *printer) -{ -} - const struct ttm_mem_type_manager_func nouveau_gart_manager = { - .init = nouveau_gart_manager_init, - .takedown = nouveau_gart_manager_fini, + .init = nouveau_manager_init, + .takedown = nouveau_manager_fini, .get_node = nouveau_gart_manager_new, .put_node = nouveau_gart_manager_del, - .debug = nouveau_gart_manager_debug + .debug = nouveau_manager_debug }; -static int -nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) -{ - return 0; -} - -static int -nv04_gart_manager_fini(struct ttm_mem_type_manager *man) -{ - return 0; -} - static void nv04_gart_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *reg) { @@ -241,18 +218,12 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, return 0; } -static void -nv04_gart_manager_debug(struct ttm_mem_type_manager *man, - struct drm_printer *printer) -{ -} - const struct ttm_mem_type_manager_func nv04_gart_manager = { - .init = nv04_gart_manager_init, - .takedown = nv04_gart_manager_fini, + .init = nouveau_manager_init, + .takedown = nouveau_manager_fini, .get_node = nv04_gart_manager_new, .put_node = nv04_gart_manager_del, - .debug = nv04_gart_manager_debug + .debug = nouveau_manager_debug }; int -- cgit v1.2.3 From cb7e88e70f52878f4be0fbcc04350cff72f67278 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: hang drm client of a master TTM memory allocations will be hanging off the DRM's client, but the locking needed to do so gets really tricky with all the other use of the DRM's object tree. To solve this, we make the normal DRM client a child of a new master, where the memory allocations will be done from instead. This also solves a potential race with client creation. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 20 ++++++++++++++++---- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +++ 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 632edb73ed53..a705e56f0e57 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -117,7 +117,9 @@ nouveau_cli_fini(struct nouveau_cli *cli) nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL); usif_client_fini(cli); nvif_device_fini(&cli->device); + mutex_lock(&cli->drm->master.lock); nvif_client_fini(&cli->base); + mutex_unlock(&cli->drm->master.lock); } static int @@ -132,12 +134,16 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, mutex_init(&cli->mutex); usif_client_init(cli); - if (cli == &drm->client) { + mutex_init(&cli->lock); + + if (cli == &drm->master) { ret = nvif_driver_init(NULL, nouveau_config, nouveau_debug, cli->name, device, &cli->base); } else { - ret = nvif_client_init(&drm->client.base, cli->name, device, + mutex_lock(&drm->master.lock); + ret = nvif_client_init(&drm->master.base, cli->name, device, &cli->base); + mutex_unlock(&drm->master.lock); } if (ret) { NV_ERROR(drm, "Client allocation failed: %d\n", ret); @@ -433,6 +439,10 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) dev->dev_private = drm; drm->dev = dev; + ret = nouveau_cli_init(drm, "DRM-master", &drm->master); + if (ret) + return ret; + ret = nouveau_cli_init(drm, "DRM", &drm->client); if (ret) return ret; @@ -518,6 +528,7 @@ fail_ttm: nouveau_vga_fini(drm); fail_device: nouveau_cli_fini(&drm->client); + nouveau_cli_fini(&drm->master); kfree(drm); return ret; } @@ -550,6 +561,7 @@ nouveau_drm_unload(struct drm_device *dev) if (drm->hdmi_device) pci_dev_put(drm->hdmi_device); nouveau_cli_fini(&drm->client); + nouveau_cli_fini(&drm->master); kfree(drm); } @@ -618,7 +630,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) } NV_DEBUG(drm, "suspending object tree...\n"); - ret = nvif_client_suspend(&drm->client.base); + ret = nvif_client_suspend(&drm->master.base); if (ret) goto fail_client; @@ -642,7 +654,7 @@ nouveau_do_resume(struct drm_device *dev, bool runtime) struct nouveau_drm *drm = nouveau_drm(dev); NV_DEBUG(drm, "resuming object tree...\n"); - nvif_client_resume(&drm->client.base); + nvif_client_resume(&drm->master.base); NV_DEBUG(drm, "resuming fence...\n"); if (drm->fence && nouveau_fence(drm)->resume) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 84b847042253..610245970c99 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -97,6 +97,8 @@ struct nouveau_cli { struct list_head objects; struct list_head notifys; char name[32]; + + struct mutex lock; }; static inline struct nouveau_cli * @@ -109,6 +111,7 @@ nouveau_cli(struct drm_file *fpriv) #include struct nouveau_drm { + struct nouveau_cli master; struct nouveau_cli client; struct drm_device *dev; -- cgit v1.2.3 From 9ce523cc3bf2ac19922e0a5d4b491221da01d1bc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: separate buffer object backing memory from nvkm structures Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kbuild | 1 + drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 6 - drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 5 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 111 +++++++++------- drivers/gpu/drm/nouveau/nouveau_mem.c | 114 ++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_mem.h | 35 +++++ drivers/gpu/drm/nouveau/nouveau_sgdma.c | 54 ++++---- drivers/gpu/drm/nouveau/nouveau_ttm.c | 143 +++++++-------------- .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 1 - 10 files changed, 285 insertions(+), 186 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nouveau_mem.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_mem.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 2e9ce53ae3a8..3476b61b94b6 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -30,6 +30,7 @@ nouveau-y += nouveau_vga.o # DRM - memory management nouveau-y += nouveau_bo.o nouveau-y += nouveau_gem.o +nouveau-y += nouveau_mem.o nouveau-y += nouveau_prime.o nouveau-y += nouveau_sgdma.o nouveau-y += nouveau_ttm.o diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 28d513fbf44c..dde444a7d3f0 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -22,12 +22,6 @@ #define NV_MEM_COMP_VM 0x03 struct nvkm_mem { - struct drm_device *dev; - - struct nvkm_vma bar_vma; - struct nvkm_vma vma[2]; - u8 page_shift; - struct nvkm_mm_node *tag; struct nvkm_mm_node *mem; dma_addr_t *pages; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index c4326772d481..439938cd6cbf 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -20,7 +20,10 @@ struct nvkm_vma { int refcount; struct nvkm_vm *vm; struct nvkm_mm_node *node; - u64 offset; + union { + u64 offset; + u64 addr; + }; u32 access; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 50b400edcb88..415c0e315981 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -37,6 +37,7 @@ #include "nouveau_bo.h" #include "nouveau_ttm.h" #include "nouveau_gem.h" +#include "nouveau_mem.h" /* * NV10-NV40 tiling helpers @@ -670,14 +671,14 @@ static int nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg) { - struct nvkm_mem *mem = old_reg->mm_node; + struct nouveau_mem *mem = nouveau_mem(old_reg); int ret = RING_SPACE(chan, 10); if (ret == 0) { BEGIN_NVC0(chan, NvSubCopy, 0x0400, 8); - OUT_RING (chan, upper_32_bits(mem->vma[0].offset)); - OUT_RING (chan, lower_32_bits(mem->vma[0].offset)); - OUT_RING (chan, upper_32_bits(mem->vma[1].offset)); - OUT_RING (chan, lower_32_bits(mem->vma[1].offset)); + OUT_RING (chan, upper_32_bits(mem->vma[0].addr)); + OUT_RING (chan, lower_32_bits(mem->vma[0].addr)); + OUT_RING (chan, upper_32_bits(mem->vma[1].addr)); + OUT_RING (chan, lower_32_bits(mem->vma[1].addr)); OUT_RING (chan, PAGE_SIZE); OUT_RING (chan, PAGE_SIZE); OUT_RING (chan, PAGE_SIZE); @@ -702,9 +703,9 @@ static int nvc0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg) { - struct nvkm_mem *mem = old_reg->mm_node; - u64 src_offset = mem->vma[0].offset; - u64 dst_offset = mem->vma[1].offset; + struct nouveau_mem *mem = nouveau_mem(old_reg); + u64 src_offset = mem->vma[0].addr; + u64 dst_offset = mem->vma[1].addr; u32 page_count = new_reg->num_pages; int ret; @@ -740,9 +741,9 @@ static int nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg) { - struct nvkm_mem *mem = old_reg->mm_node; - u64 src_offset = mem->vma[0].offset; - u64 dst_offset = mem->vma[1].offset; + struct nouveau_mem *mem = nouveau_mem(old_reg); + u64 src_offset = mem->vma[0].addr; + u64 dst_offset = mem->vma[1].addr; u32 page_count = new_reg->num_pages; int ret; @@ -779,9 +780,9 @@ static int nva3_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg) { - struct nvkm_mem *mem = old_reg->mm_node; - u64 src_offset = mem->vma[0].offset; - u64 dst_offset = mem->vma[1].offset; + struct nouveau_mem *mem = nouveau_mem(old_reg); + u64 src_offset = mem->vma[0].addr; + u64 dst_offset = mem->vma[1].addr; u32 page_count = new_reg->num_pages; int ret; @@ -817,14 +818,14 @@ static int nv98_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg) { - struct nvkm_mem *mem = old_reg->mm_node; + struct nouveau_mem *mem = nouveau_mem(old_reg); int ret = RING_SPACE(chan, 7); if (ret == 0) { BEGIN_NV04(chan, NvSubCopy, 0x0320, 6); - OUT_RING (chan, upper_32_bits(mem->vma[0].offset)); - OUT_RING (chan, lower_32_bits(mem->vma[0].offset)); - OUT_RING (chan, upper_32_bits(mem->vma[1].offset)); - OUT_RING (chan, lower_32_bits(mem->vma[1].offset)); + OUT_RING (chan, upper_32_bits(mem->vma[0].addr)); + OUT_RING (chan, lower_32_bits(mem->vma[0].addr)); + OUT_RING (chan, upper_32_bits(mem->vma[1].addr)); + OUT_RING (chan, lower_32_bits(mem->vma[1].addr)); OUT_RING (chan, 0x00000000 /* COPY */); OUT_RING (chan, new_reg->num_pages << PAGE_SHIFT); } @@ -835,15 +836,15 @@ static int nv84_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg) { - struct nvkm_mem *mem = old_reg->mm_node; + struct nouveau_mem *mem = nouveau_mem(old_reg); int ret = RING_SPACE(chan, 7); if (ret == 0) { BEGIN_NV04(chan, NvSubCopy, 0x0304, 6); OUT_RING (chan, new_reg->num_pages << PAGE_SHIFT); - OUT_RING (chan, upper_32_bits(mem->vma[0].offset)); - OUT_RING (chan, lower_32_bits(mem->vma[0].offset)); - OUT_RING (chan, upper_32_bits(mem->vma[1].offset)); - OUT_RING (chan, lower_32_bits(mem->vma[1].offset)); + OUT_RING (chan, upper_32_bits(mem->vma[0].addr)); + OUT_RING (chan, lower_32_bits(mem->vma[0].addr)); + OUT_RING (chan, upper_32_bits(mem->vma[1].addr)); + OUT_RING (chan, lower_32_bits(mem->vma[1].addr)); OUT_RING (chan, 0x00000000 /* MODE_COPY, QUERY_NONE */); } return ret; @@ -869,12 +870,12 @@ static int nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg) { - struct nvkm_mem *mem = old_reg->mm_node; + struct nouveau_mem *mem = nouveau_mem(old_reg); u64 length = (new_reg->num_pages << PAGE_SHIFT); - u64 src_offset = mem->vma[0].offset; - u64 dst_offset = mem->vma[1].offset; - int src_tiled = !!mem->memtype; - int dst_tiled = !!((struct nvkm_mem *)new_reg->mm_node)->memtype; + u64 src_offset = mem->vma[0].addr; + u64 dst_offset = mem->vma[1].addr; + int src_tiled = !!mem->kind; + int dst_tiled = !!nouveau_mem(new_reg)->kind; int ret; while (length) { @@ -1011,25 +1012,34 @@ static int nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo, struct ttm_mem_reg *reg) { - struct nvkm_mem *old_mem = bo->mem.mm_node; - struct nvkm_mem *new_mem = reg->mm_node; + struct nouveau_mem *old_mem = nouveau_mem(&bo->mem); + struct nouveau_mem *new_mem = nouveau_mem(reg); + struct nvkm_vm *vmm = drm->client.vm; u64 size = (u64)reg->num_pages << PAGE_SHIFT; int ret; - ret = nvkm_vm_get(drm->client.vm, size, old_mem->page_shift, - NV_MEM_ACCESS_RW, &old_mem->vma[0]); + ret = nvkm_vm_get(vmm, size, old_mem->mem.page, NV_MEM_ACCESS_RW, + &old_mem->vma[0]); if (ret) return ret; - ret = nvkm_vm_get(drm->client.vm, size, new_mem->page_shift, - NV_MEM_ACCESS_RW, &old_mem->vma[1]); + ret = nvkm_vm_get(vmm, size, new_mem->mem.page, NV_MEM_ACCESS_RW, + &old_mem->vma[1]); if (ret) { nvkm_vm_put(&old_mem->vma[0]); return ret; } - nvkm_vm_map(&old_mem->vma[0], old_mem); - nvkm_vm_map(&old_mem->vma[1], new_mem); + ret = nouveau_mem_map(old_mem, vmm, &old_mem->vma[0]); + if (ret) + goto done; + + ret = nouveau_mem_map(new_mem, vmm, &old_mem->vma[1]); +done: + if (ret) { + nvkm_vm_put(&old_mem->vma[1]); + nvkm_vm_put(&old_mem->vma[0]); + } return 0; } @@ -1211,8 +1221,8 @@ static void nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, struct ttm_mem_reg *new_reg) { + struct nouveau_mem *mem = new_reg ? nouveau_mem(new_reg) : NULL; struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nvkm_mem *mem = new_reg ? new_reg->mm_node : NULL; struct nvkm_vma *vma; /* ttm can now (stupidly) pass the driver bos it didn't create... */ @@ -1220,9 +1230,9 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, return; if (mem && new_reg->mem_type != TTM_PL_SYSTEM && - mem->page_shift == nvbo->page) { + mem->mem.page == nvbo->page) { list_for_each_entry(vma, &nvbo->vma_list, head) { - nvkm_vm_map(vma, mem); + nvkm_vm_map(vma, mem->_mem); } } else { list_for_each_entry(vma, &nvbo->vma_list, head) { @@ -1343,7 +1353,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) struct ttm_mem_type_manager *man = &bdev->man[reg->mem_type]; struct nouveau_drm *drm = nouveau_bdev(bdev); struct nvkm_device *device = nvxx_device(&drm->client.device); - struct nvkm_mem *mem = reg->mm_node; + struct nouveau_mem *mem = nouveau_mem(reg); int ret; reg->bus.addr = NULL; @@ -1365,7 +1375,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) reg->bus.is_iomem = !drm->agp.cma; } #endif - if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA || !mem->memtype) + if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA || !mem->kind) /* untiled */ break; /* fallthrough, tiled memory */ @@ -1377,14 +1387,15 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); int page_shift = 12; if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) - page_shift = mem->page_shift; + page_shift = mem->mem.page; - ret = nvkm_vm_get(bar, mem->size << 12, page_shift, - NV_MEM_ACCESS_RW, &mem->bar_vma); + ret = nvkm_vm_get(bar, mem->_mem->size << 12, + page_shift, NV_MEM_ACCESS_RW, + &mem->bar_vma); if (ret) return ret; - nvkm_vm_map(&mem->bar_vma, mem); + nvkm_vm_map(&mem->bar_vma, mem->_mem); reg->bus.offset = mem->bar_vma.offset; } break; @@ -1397,7 +1408,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) static void nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) { - struct nvkm_mem *mem = reg->mm_node; + struct nouveau_mem *mem = nouveau_mem(reg); if (!mem->bar_vma.node) return; @@ -1606,7 +1617,7 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nvkm_vm *vm, struct nvkm_vma *vma) { const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT; - struct nvkm_mem *mem = nvbo->bo.mem.mm_node; + struct nouveau_mem *mem = nouveau_mem(&nvbo->bo.mem); int ret; ret = nvkm_vm_get(vm, size, nvbo->page, NV_MEM_ACCESS_RW, vma); @@ -1614,8 +1625,8 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nvkm_vm *vm, return ret; if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && - mem->page_shift == nvbo->page) - nvkm_vm_map(vma, nvbo->bo.mem.mm_node); + mem->mem.page == nvbo->page) + nvkm_vm_map(vma, mem->_mem); list_add_tail(&vma->head, &nvbo->vma_list); vma->refcount = 1; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c new file mode 100644 index 000000000000..68ac332841ae --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -0,0 +1,114 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "nouveau_mem.h" +#include "nouveau_drv.h" +#include "nouveau_bo.h" + +#include + +int +nouveau_mem_map(struct nouveau_mem *mem, + struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + nvkm_vm_map(vma, mem->_mem); + return 0; +} + +void +nouveau_mem_fini(struct nouveau_mem *mem) +{ + if (mem->vma[1].node) { + nvkm_vm_unmap(&mem->vma[1]); + nvkm_vm_put(&mem->vma[1]); + } + if (mem->vma[0].node) { + nvkm_vm_unmap(&mem->vma[0]); + nvkm_vm_put(&mem->vma[0]); + } +} + +int +nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) +{ + struct nouveau_mem *mem = nouveau_mem(reg); + struct nouveau_cli *cli = mem->cli; + + if (mem->kind && cli->device.info.chipset == 0x50) + mem->comp = mem->kind = 0; + if (mem->comp) { + if (cli->device.info.chipset >= 0xc0) + mem->kind = gf100_pte_storage_type_map[mem->kind]; + mem->comp = 0; + } + + mem->__mem.size = (reg->num_pages << PAGE_SHIFT) >> 12; + mem->__mem.memtype = (mem->comp << 7) | mem->kind; + if (tt->ttm.sg) mem->__mem.sg = tt->ttm.sg; + else mem->__mem.pages = tt->dma_address; + mem->_mem = &mem->__mem; + mem->mem.page = 12; + return 0; +} + +int +nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) +{ + struct nouveau_mem *mem = nouveau_mem(reg); + struct nvkm_ram *ram = nvxx_fb(&mem->cli->device)->ram; + u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page); + int ret; + + mem->mem.page = page; + + ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page, + (mem->comp << 8) | mem->kind, &mem->_mem); + if (ret) + return ret; + + reg->start = mem->_mem->offset >> PAGE_SHIFT; + return ret; +} + +void +nouveau_mem_del(struct ttm_mem_reg *reg) +{ + struct nouveau_mem *mem = nouveau_mem(reg); + nouveau_mem_fini(mem); + kfree(reg->mm_node); + reg->mm_node = NULL; +} + +int +nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp, + struct ttm_mem_reg *reg) +{ + struct nouveau_mem *mem; + + if (!(mem = kzalloc(sizeof(*mem), GFP_KERNEL))) + return -ENOMEM; + mem->cli = cli; + mem->kind = kind; + mem->comp = comp; + + reg->mm_node = mem; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h new file mode 100644 index 000000000000..d00b4f669c4b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -0,0 +1,35 @@ +#ifndef __NOUVEAU_MEM_H__ +#define __NOUVEAU_MEM_H__ +#include + +#include +struct ttm_dma_tt; + +static inline struct nouveau_mem * +nouveau_mem(struct ttm_mem_reg *reg) +{ + return reg->mm_node; +} + +struct nouveau_mem { + struct nouveau_cli *cli; + u8 kind; + u8 comp; + struct { + u8 page; + } mem; + struct nvkm_vma vma[2]; + + struct nvkm_mem __mem; + struct nvkm_mem *_mem; + struct nvkm_vma bar_vma; +}; + +int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp, + struct ttm_mem_reg *); +void nouveau_mem_del(struct ttm_mem_reg *); +int nouveau_mem_vram(struct ttm_mem_reg *, bool contig, u8 page); +int nouveau_mem_host(struct ttm_mem_reg *, struct ttm_dma_tt *); +void nouveau_mem_fini(struct nouveau_mem *); +int nouveau_mem_map(struct nouveau_mem *, struct nvkm_vmm *, struct nvkm_vma *); +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index b7ab268f7d6f..69c606f97784 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -2,6 +2,7 @@ #include #include "nouveau_drv.h" +#include "nouveau_mem.h" #include "nouveau_ttm.h" struct nouveau_sgdma_be { @@ -9,7 +10,7 @@ struct nouveau_sgdma_be { * nouve_bo.c works properly, otherwise have to move them here */ struct ttm_dma_tt ttm; - struct nvkm_mem *node; + struct nouveau_mem *mem; }; static void @@ -27,19 +28,20 @@ static int nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *reg) { struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct nvkm_mem *node = reg->mm_node; - - if (ttm->sg) { - node->sg = ttm->sg; - node->pages = NULL; - } else { - node->sg = NULL; - node->pages = nvbe->ttm.dma_address; + struct nouveau_mem *mem = nouveau_mem(reg); + int ret; + + ret = nouveau_mem_host(reg, &nvbe->ttm); + if (ret) + return ret; + + ret = nouveau_mem_map(mem, mem->cli->vm, &mem->vma[0]); + if (ret) { + nouveau_mem_fini(mem); + return ret; } - node->size = (reg->num_pages << PAGE_SHIFT) >> 12; - nvkm_vm_map(&node->vma[0], node); - nvbe->node = node; + nvbe->mem = mem; return 0; } @@ -47,7 +49,7 @@ static int nv04_sgdma_unbind(struct ttm_tt *ttm) { struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - nvkm_vm_unmap(&nvbe->node->vma[0]); + nouveau_mem_fini(nvbe->mem); return 0; } @@ -61,30 +63,20 @@ static int nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *reg) { struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct nvkm_mem *node = reg->mm_node; - - /* noop: bound in move_notify() */ - if (ttm->sg) { - node->sg = ttm->sg; - node->pages = NULL; - } else { - node->sg = NULL; - node->pages = nvbe->ttm.dma_address; - } - node->size = (reg->num_pages << PAGE_SHIFT) >> 12; - return 0; -} + struct nouveau_mem *mem = nouveau_mem(reg); + int ret; -static int -nv50_sgdma_unbind(struct ttm_tt *ttm) -{ - /* noop: unbound in move_notify() */ + ret = nouveau_mem_host(reg, &nvbe->ttm); + if (ret) + return ret; + + nvbe->mem = mem; return 0; } static struct ttm_backend_func nv50_sgdma_backend = { .bind = nv50_sgdma_bind, - .unbind = nv50_sgdma_unbind, + .unbind = nv04_sgdma_unbind, .destroy = nouveau_sgdma_destroy }; diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index e6e767558a3b..3bf3b60130e0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -23,10 +23,10 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include "nouveau_drv.h" -#include "nouveau_ttm.h" #include "nouveau_gem.h" +#include "nouveau_mem.h" +#include "nouveau_ttm.h" #include @@ -45,23 +45,15 @@ nouveau_manager_fini(struct ttm_mem_type_manager *man) } static void -nouveau_manager_debug(struct ttm_mem_type_manager *man, - struct drm_printer *printer) +nouveau_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *reg) { + nouveau_mem_del(reg); } -static inline void -nvkm_mem_node_cleanup(struct nvkm_mem *node) +static void +nouveau_manager_debug(struct ttm_mem_type_manager *man, + struct drm_printer *printer) { - if (node->vma[0].node) { - nvkm_vm_unmap(&node->vma[0]); - nvkm_vm_put(&node->vma[0]); - } - - if (node->vma[1].node) { - nvkm_vm_unmap(&node->vma[1]); - nvkm_vm_put(&node->vma[1]); - } } static void @@ -70,8 +62,9 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man, { struct nouveau_drm *drm = nouveau_bdev(man->bdev); struct nvkm_ram *ram = nvxx_fb(&drm->client.device)->ram; - nvkm_mem_node_cleanup(reg->mm_node); - ram->func->put(ram, (struct nvkm_mem **)®->mm_node); + struct nvkm_mem *mem = nouveau_mem(reg)->_mem; + nouveau_mem_del(reg); + ram->func->put(ram, &mem); } static int @@ -80,31 +73,29 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, const struct ttm_place *place, struct ttm_mem_reg *reg) { - struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nvkm_ram *ram = nvxx_fb(&drm->client.device)->ram; struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nvkm_mem *node; - u32 size_nc = 0; + struct nouveau_drm *drm = nvbo->cli->drm; + struct nouveau_mem *mem; int ret; if (drm->client.device.info.ram_size == 0) return -ENOMEM; - if (!nvbo->contig) - size_nc = 1 << nvbo->page; + ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg); + mem = nouveau_mem(reg); + if (ret) + return ret; - ret = ram->func->get(ram, reg->num_pages << PAGE_SHIFT, - reg->page_alignment << PAGE_SHIFT, size_nc, - nvbo->comp << 8 | nvbo->kind, &node); + ret = nouveau_mem_vram(reg, nvbo->contig, nvbo->page); if (ret) { - reg->mm_node = NULL; - return (ret == -ENOSPC) ? 0 : ret; + nouveau_mem_del(reg); + if (ret == -ENOSPC) { + reg->mm_node = NULL; + return 0; + } + return ret; } - node->page_shift = nvbo->page; - - reg->mm_node = node; - reg->start = node->offset >> PAGE_SHIFT; return 0; } @@ -116,54 +107,24 @@ const struct ttm_mem_type_manager_func nouveau_vram_manager = { .debug = nouveau_manager_debug, }; -static void -nouveau_gart_manager_del(struct ttm_mem_type_manager *man, - struct ttm_mem_reg *reg) -{ - nvkm_mem_node_cleanup(reg->mm_node); - kfree(reg->mm_node); - reg->mm_node = NULL; -} - static int nouveau_gart_manager_new(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, const struct ttm_place *place, struct ttm_mem_reg *reg) { - struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nvkm_mem *node; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; + struct nouveau_drm *drm = nvbo->cli->drm; + struct nouveau_mem *mem; + int ret; - node->page_shift = 12; - - switch (drm->client.device.info.family) { - case NV_DEVICE_INFO_V0_TNT: - case NV_DEVICE_INFO_V0_CELSIUS: - case NV_DEVICE_INFO_V0_KELVIN: - case NV_DEVICE_INFO_V0_RANKINE: - case NV_DEVICE_INFO_V0_CURIE: - break; - case NV_DEVICE_INFO_V0_TESLA: - case NV_DEVICE_INFO_V0_FERMI: - case NV_DEVICE_INFO_V0_KEPLER: - case NV_DEVICE_INFO_V0_MAXWELL: - case NV_DEVICE_INFO_V0_PASCAL: - if (drm->client.device.info.chipset != 0x50) - node->memtype = nvbo->kind; - break; - default: - NV_WARN(drm, "%s: unhandled family type %x\n", __func__, - drm->client.device.info.family); - break; - } + ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg); + mem = nouveau_mem(reg); + if (ret) + return ret; - reg->mm_node = node; - reg->start = 0; + mem->_mem = &mem->__mem; + reg->start = 0; return 0; } @@ -171,50 +132,40 @@ const struct ttm_mem_type_manager_func nouveau_gart_manager = { .init = nouveau_manager_init, .takedown = nouveau_manager_fini, .get_node = nouveau_gart_manager_new, - .put_node = nouveau_gart_manager_del, + .put_node = nouveau_manager_del, .debug = nouveau_manager_debug }; -static void -nv04_gart_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *reg) -{ - struct nvkm_mem *node = reg->mm_node; - if (node->vma[0].node) - nvkm_vm_put(&node->vma[0]); - kfree(reg->mm_node); - reg->mm_node = NULL; -} - static int nv04_gart_manager_new(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, const struct ttm_place *place, struct ttm_mem_reg *reg) { - struct nouveau_drm *drm = nouveau_bdev(man->bdev); + struct nouveau_bo *nvbo = nouveau_bo(bo); + struct nouveau_drm *drm = nvbo->cli->drm; + struct nouveau_mem *mem; struct nvkm_mmu *mmu = nvxx_mmu(&drm->client.device); - struct nvkm_mem *node; int ret; - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - - node->page_shift = 12; + ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg); + mem = nouveau_mem(reg); + if (ret) + return ret; - ret = nvkm_vm_get(mmu->vmm, reg->num_pages << 12, node->page_shift, - NV_MEM_ACCESS_RW, &node->vma[0]); + ret = nvkm_vm_get(mmu->vmm, reg->num_pages << 12, 12, + NV_MEM_ACCESS_RW, &mem->vma[0]); if (ret) { + nouveau_mem_del(reg); if (ret == -ENOSPC) { reg->mm_node = NULL; - ret = 0; + return 0; } - kfree(node); return ret; } - reg->mm_node = node; - reg->start = node->vma[0].offset >> PAGE_SHIFT; + mem->_mem = &mem->__mem; + reg->start = mem->vma[0].addr >> PAGE_SHIFT; return 0; } @@ -222,7 +173,7 @@ const struct ttm_mem_type_manager_func nv04_gart_manager = { .init = nouveau_manager_init, .takedown = nouveau_manager_fini, .get_node = nv04_gart_manager_new, - .put_node = nv04_gart_manager_del, + .put_node = nouveau_manager_del, .debug = nouveau_manager_debug }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index a8b71262f663..f2879c48d1e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -530,7 +530,6 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, /* present memory for being mapped using small pages */ node->mem.size = size >> 12; node->mem.memtype = 0; - node->mem.page_shift = 12; nvkm_debug(subdev, "alloc size: 0x%x, align: 0x%x, gaddr: 0x%llx\n", size, align, node->mem.offset); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 4ccb8cdc7dbc..bb524e3aa5d9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -356,7 +356,6 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, if (ret) return ret; - iobj->mem->page_shift = 12; return 0; } -- cgit v1.2.3 From 24e8375b1bfdf7f6014b9e3d7903d6a8f81aa249 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: separate constant-va tracking from nvkm vma structure Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kbuild | 1 + drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 - drivers/gpu/drm/nouveau/nouveau_abi16.c | 10 +- drivers/gpu/drm/nouveau/nouveau_abi16.h | 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 51 +-------- drivers/gpu/drm/nouveau/nouveau_bo.h | 7 -- drivers/gpu/drm/nouveau/nouveau_chan.c | 19 ++-- drivers/gpu/drm/nouveau/nouveau_chan.h | 3 +- drivers/gpu/drm/nouveau/nouveau_display.h | 5 +- drivers/gpu/drm/nouveau/nouveau_dma.c | 15 +-- drivers/gpu/drm/nouveau/nouveau_dma.h | 2 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 11 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 4 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 7 +- drivers/gpu/drm/nouveau/nouveau_fence.h | 2 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 68 ++++-------- drivers/gpu/drm/nouveau/nouveau_vmm.c | 128 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_vmm.h | 32 ++++++ drivers/gpu/drm/nouveau/nv50_fbcon.c | 9 +- drivers/gpu/drm/nouveau/nv84_fence.c | 9 +- drivers/gpu/drm/nouveau/nvc0_fbcon.c | 9 +- 21 files changed, 245 insertions(+), 151 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nouveau_vmm.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_vmm.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 3476b61b94b6..9c0c650655e9 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -34,6 +34,7 @@ nouveau-y += nouveau_mem.o nouveau-y += nouveau_prime.o nouveau-y += nouveau_sgdma.o nouveau-y += nouveau_ttm.o +nouveau-y += nouveau_vmm.o # DRM - modesetting nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 439938cd6cbf..549a8782ce35 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -16,8 +16,6 @@ struct nvkm_vm_pgd { }; struct nvkm_vma { - struct list_head head; - int refcount; struct nvkm_vm *vm; struct nvkm_mm_node *node; union { diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index f98f800cc011..9b0b210a37f8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -34,6 +34,7 @@ #include "nouveau_gem.h" #include "nouveau_chan.h" #include "nouveau_abi16.h" +#include "nouveau_vmm.h" static struct nouveau_abi16 * nouveau_abi16(struct drm_file *file_priv) @@ -134,7 +135,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, } if (chan->ntfy) { - nouveau_bo_vma_del(chan->ntfy, &chan->ntfy_vma); + nouveau_vma_del(&chan->ntfy_vma); nouveau_bo_unpin(chan->ntfy); drm_gem_object_unreference_unlocked(&chan->ntfy->gem); } @@ -329,8 +330,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) goto done; if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_bo_vma_add(chan->ntfy, cli->vm, - &chan->ntfy_vma); + ret = nouveau_vma_new(chan->ntfy, &cli->vmm, &chan->ntfy_vma); if (ret) goto done; } @@ -548,8 +548,8 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_VM; - args.start += chan->ntfy_vma.offset; - args.limit += chan->ntfy_vma.offset; + args.start += chan->ntfy_vma->addr; + args.limit += chan->ntfy_vma->addr; } else if (drm->agp.bridge) { args.target = NV_DMA_V0_TARGET_AGP; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h index 841cc556fad8..327747680324 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.h +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h @@ -23,7 +23,7 @@ struct nouveau_abi16_chan { struct nouveau_channel *chan; struct list_head notifiers; struct nouveau_bo *ntfy; - struct nvkm_vma ntfy_vma; + struct nouveau_vma *ntfy_vma; struct nvkm_mm heap; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 415c0e315981..d89f3e700baf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -38,6 +38,7 @@ #include "nouveau_ttm.h" #include "nouveau_gem.h" #include "nouveau_mem.h" +#include "nouveau_vmm.h" /* * NV10-NV40 tiling helpers @@ -1223,7 +1224,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, { struct nouveau_mem *mem = new_reg ? nouveau_mem(new_reg) : NULL; struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nvkm_vma *vma; + struct nouveau_vma *vma; /* ttm can now (stupidly) pass the driver bos it didn't create... */ if (bo->destroy != nouveau_bo_del_ttm) @@ -1232,12 +1233,12 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, if (mem && new_reg->mem_type != TTM_PL_SYSTEM && mem->mem.page == nvbo->page) { list_for_each_entry(vma, &nvbo->vma_list, head) { - nvkm_vm_map(vma, mem->_mem); + nouveau_vma_map(vma, mem); } } else { list_for_each_entry(vma, &nvbo->vma_list, head) { WARN_ON(ttm_bo_wait(bo, false, false)); - nvkm_vm_unmap(vma); + nouveau_vma_unmap(vma); } } } @@ -1599,47 +1600,3 @@ struct ttm_bo_driver nouveau_bo_driver = { .io_mem_free = &nouveau_ttm_io_mem_free, .io_mem_pfn = ttm_bo_default_io_mem_pfn, }; - -struct nvkm_vma * -nouveau_bo_vma_find(struct nouveau_bo *nvbo, struct nvkm_vm *vm) -{ - struct nvkm_vma *vma; - list_for_each_entry(vma, &nvbo->vma_list, head) { - if (vma->vm == vm) - return vma; - } - - return NULL; -} - -int -nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nvkm_vm *vm, - struct nvkm_vma *vma) -{ - const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT; - struct nouveau_mem *mem = nouveau_mem(&nvbo->bo.mem); - int ret; - - ret = nvkm_vm_get(vm, size, nvbo->page, NV_MEM_ACCESS_RW, vma); - if (ret) - return ret; - - if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && - mem->mem.page == nvbo->page) - nvkm_vm_map(vma, mem->_mem); - - list_add_tail(&vma->head, &nvbo->vma_list); - vma->refcount = 1; - return 0; -} - -void -nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nvkm_vma *vma) -{ - if (vma->node) { - if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM) - nvkm_vm_unmap(vma); - nvkm_vm_put(vma); - list_del(&vma->head); - } -} diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index a179bbf25dce..23002bdd94a8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -93,13 +93,6 @@ int nouveau_bo_validate(struct nouveau_bo *, bool interruptible, void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo); void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo); -struct nvkm_vma * -nouveau_bo_vma_find(struct nouveau_bo *, struct nvkm_vm *); - -int nouveau_bo_vma_add(struct nouveau_bo *, struct nvkm_vm *, - struct nvkm_vma *); -void nouveau_bo_vma_del(struct nouveau_bo *, struct nvkm_vma *); - /* TODO: submit equivalent to TTM generic API upstream? */ static inline void __iomem * nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 4af09e9be930..9fdca7b4cb05 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -40,6 +40,7 @@ #include "nouveau_chan.h" #include "nouveau_fence.h" #include "nouveau_abi16.h" +#include "nouveau_vmm.h" MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM"); int nouveau_vram_pushbuf; @@ -91,7 +92,7 @@ nouveau_channel_del(struct nouveau_channel **pchan) nvif_notify_fini(&chan->kill); nvif_object_fini(&chan->user); nvif_object_fini(&chan->push.ctxdma); - nouveau_bo_vma_del(chan->push.buffer, &chan->push.vma); + nouveau_vma_del(&chan->push.vma); nouveau_bo_unmap(chan->push.buffer); if (chan->push.buffer && chan->push.buffer->pin_refcnt) nouveau_bo_unpin(chan->push.buffer); @@ -142,11 +143,11 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, * pushbuf lives in, this is because the GEM code requires that * we be able to call out to other (indirect) push buffers */ - chan->push.vma.offset = chan->push.buffer->bo.offset; + chan->push.addr = chan->push.buffer->bo.offset; if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_bo_vma_add(chan->push.buffer, cli->vm, - &chan->push.vma); + ret = nouveau_vma_new(chan->push.buffer, &cli->vmm, + &chan->push.vma); if (ret) { nouveau_channel_del(pchan); return ret; @@ -156,6 +157,8 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, args.access = NV_DMA_V0_ACCESS_VM; args.start = 0; args.limit = cli->vm->mmu->limit - 1; + + chan->push.addr = chan->push.vma->addr; } else if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) { if (device->info.family == NV_DEVICE_INFO_V0_TNT) { @@ -233,20 +236,20 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, args.kepler.version = 0; args.kepler.engines = engine; args.kepler.ilength = 0x02000; - args.kepler.ioffset = 0x10000 + chan->push.vma.offset; + args.kepler.ioffset = 0x10000 + chan->push.addr; args.kepler.vm = 0; size = sizeof(args.kepler); } else if (oclass[0] >= FERMI_CHANNEL_GPFIFO) { args.fermi.version = 0; args.fermi.ilength = 0x02000; - args.fermi.ioffset = 0x10000 + chan->push.vma.offset; + args.fermi.ioffset = 0x10000 + chan->push.addr; args.fermi.vm = 0; size = sizeof(args.fermi); } else { args.nv50.version = 0; args.nv50.ilength = 0x02000; - args.nv50.ioffset = 0x10000 + chan->push.vma.offset; + args.nv50.ioffset = 0x10000 + chan->push.addr; args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma); args.nv50.vm = 0; size = sizeof(args.nv50); @@ -293,7 +296,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, /* create channel object */ args.version = 0; args.pushbuf = nvif_handle(&chan->push.ctxdma); - args.offset = chan->push.vma.offset; + args.offset = chan->push.addr; do { ret = nvif_object_init(&device->object, 0, *oclass++, diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index 46b947ba1cf4..f29d3a72c48c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -16,8 +16,9 @@ struct nouveau_channel { struct { struct nouveau_bo *buffer; - struct nvkm_vma vma; + struct nouveau_vma *vma; struct nvif_object ctxdma; + u64 addr; } push; /* TODO: this will be reworked in the near future */ diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 201aec2ea5b8..1411bf05b89d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -1,14 +1,11 @@ #ifndef __NOUVEAU_DISPLAY_H__ #define __NOUVEAU_DISPLAY_H__ - -#include - #include "nouveau_drv.h" struct nouveau_framebuffer { struct drm_framebuffer base; struct nouveau_bo *nvbo; - struct nvkm_vma vma; + struct nouveau_vma *vma; u32 r_handle; u32 r_format; u32 r_pitch; diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 2634a1a79888..10e84f6ca2b7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -26,6 +26,7 @@ #include "nouveau_drv.h" #include "nouveau_dma.h" +#include "nouveau_vmm.h" void OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords) @@ -71,11 +72,11 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) return -EBUSY; } - if (val < chan->push.vma.offset || - val > chan->push.vma.offset + (chan->dma.max << 2)) + if (val < chan->push.addr || + val > chan->push.addr + (chan->dma.max << 2)) return -EINVAL; - return (val - chan->push.vma.offset) >> 2; + return (val - chan->push.addr) >> 2; } void @@ -84,13 +85,13 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, { struct nouveau_cli *cli = (void *)chan->user.client; struct nouveau_bo *pb = chan->push.buffer; - struct nvkm_vma *vma; + struct nouveau_vma *vma; int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; u64 offset; - vma = nouveau_bo_vma_find(bo, cli->vm); + vma = nouveau_vma_find(bo, &cli->vmm); BUG_ON(!vma); - offset = vma->offset + delta; + offset = vma->addr + delta; BUG_ON(chan->dma.ib_free < 1); @@ -224,7 +225,7 @@ nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) * instruct the GPU to jump back to the start right * after processing the currently pending commands. */ - OUT_RING(chan, chan->push.vma.offset | 0x20000000); + OUT_RING(chan, chan->push.addr | 0x20000000); /* wait for GET to depart from the skips area. * prevents writing GET==PUT and causing a race diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index aff3a9d0a1fc..74e10b14a7da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -140,7 +140,7 @@ BEGIN_IMC0(struct nouveau_channel *chan, int subc, int mthd, u16 data) #define WRITE_PUT(val) do { \ mb(); \ nouveau_bo_rd32(chan->push.buffer, 0); \ - nvif_wr32(&chan->user, chan->user_put, ((val) << 2) + chan->push.vma.offset); \ + nvif_wr32(&chan->user, chan->user_put, ((val) << 2) + chan->push.addr);\ } while (0) static inline void diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index a705e56f0e57..25a47e8ba42b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -114,8 +114,8 @@ nouveau_name(struct drm_device *dev) static void nouveau_cli_fini(struct nouveau_cli *cli) { - nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL); usif_client_fini(cli); + nouveau_vmm_fini(&cli->vmm); nvif_device_fini(&cli->device); mutex_lock(&cli->drm->master.lock); nvif_client_fini(&cli->base); @@ -472,12 +472,11 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) goto fail_device; } - ret = nvkm_vm_new(nvxx_device(&drm->client.device), - 0, (1ULL << 40), 0x1000, NULL, - &drm->client.vm); + ret = nouveau_vmm_init(&drm->client, 0, &drm->client.vmm); if (ret) goto fail_device; + drm->client.vm = drm->client.vmm.vm; nvxx_client(&drm->client.base)->vm = drm->client.vm; } @@ -863,11 +862,11 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) cli->base.super = false; if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nvkm_vm_new(nvxx_device(&drm->client.device), 0, - (1ULL << 40), 0x1000, NULL, &cli->vm); + ret = nouveau_vmm_init(cli, 0, &cli->vmm); if (ret) goto done; + cli->vm = cli->vmm.vm; nvxx_client(&cli->base)->vm = cli->vm; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 610245970c99..ba8a9ab20562 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -61,6 +61,7 @@ struct platform_device; #include "nouveau_fence.h" #include "nouveau_bios.h" +#include "nouveau_vmm.h" struct nouveau_drm_tile { struct nouveau_fence *fence; @@ -90,8 +91,9 @@ struct nouveau_cli { struct mutex mutex; struct nvif_device device; + struct nouveau_vmm vmm; - struct nvkm_vm *vm; /*XXX*/ + struct nvkm_vm *vm; struct list_head head; void *abi16; struct list_head objects; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 2b12d82aac15..c533d8e04afc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -48,6 +48,7 @@ #include "nouveau_bo.h" #include "nouveau_fbcon.h" #include "nouveau_chan.h" +#include "nouveau_vmm.h" #include "nouveau_crtc.h" @@ -348,7 +349,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, chan = nouveau_nofbaccel ? NULL : drm->channel; if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_bo_vma_add(nvbo, drm->client.vm, &fb->vma); + ret = nouveau_vma_new(nvbo, &drm->client.vmm, &fb->vma); if (ret) { NV_ERROR(drm, "failed to map fb into chan: %d\n", ret); chan = NULL; @@ -402,7 +403,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, out_unlock: if (chan) - nouveau_bo_vma_del(fb->nvbo, &fb->vma); + nouveau_vma_del(&fb->vma); nouveau_bo_unmap(fb->nvbo); out_unpin: nouveau_bo_unpin(fb->nvbo); @@ -429,7 +430,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) drm_fb_helper_fini(&fbcon->helper); if (nouveau_fb->nvbo) { - nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma); + nouveau_vma_del(&nouveau_fb->vma); nouveau_bo_unmap(nouveau_fb->nvbo); nouveau_bo_unpin(nouveau_fb->nvbo); drm_framebuffer_unreference(&nouveau_fb->base); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 28a213509797..d32e58b66a75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -88,7 +88,7 @@ int nouveau_flip_complete(struct nvif_notify *); struct nv84_fence_chan { struct nouveau_fence_chan base; - struct nvkm_vma vma; + struct nouveau_vma *vma; }; struct nv84_fence_priv { diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 2d924739997a..9f82b13293f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -31,6 +31,7 @@ #include "nouveau_ttm.h" #include "nouveau_gem.h" +#include "nouveau_vmm.h" void nouveau_gem_object_del(struct drm_gem_object *gem) @@ -64,8 +65,8 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); - struct nvkm_vma *vma; struct device *dev = drm->dev->dev; + struct nouveau_vma *vma; int ret; if (!cli->vm) @@ -75,30 +76,13 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) if (ret) return ret; - vma = nouveau_bo_vma_find(nvbo, cli->vm); - if (!vma) { - vma = kzalloc(sizeof(*vma), GFP_KERNEL); - if (!vma) { - ret = -ENOMEM; - goto out; - } - - ret = pm_runtime_get_sync(dev); - if (ret < 0 && ret != -EACCES) { - kfree(vma); - goto out; - } - - ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); - if (ret) - kfree(vma); - - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); - } else { - vma->refcount++; - } + ret = pm_runtime_get_sync(dev); + if (ret < 0 && ret != -EACCES) + goto out; + ret = nouveau_vma_new(nvbo, &cli->vmm, &vma); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); out: ttm_bo_unreserve(&nvbo->bo); return ret; @@ -107,14 +91,12 @@ out: static void nouveau_gem_object_delete(void *data) { - struct nvkm_vma *vma = data; - nvkm_vm_unmap(vma); - nvkm_vm_put(vma); - kfree(vma); + struct nouveau_vma *vma = data; + nouveau_vma_del(&vma); } static void -nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nvkm_vma *vma) +nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma) { const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM; struct reservation_object *resv = nvbo->bo.resv; @@ -123,7 +105,7 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nvkm_vma *vma) fobj = reservation_object_get_list(resv); - list_del(&vma->head); + list_del_init(&vma->head); if (fobj && fobj->shared_count > 1) ttm_bo_wait(&nvbo->bo, false, false); @@ -133,14 +115,10 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nvkm_vma *vma) else fence = reservation_object_get_excl(nvbo->bo.resv); - if (fence && mapped) { + if (fence && mapped) nouveau_fence_work(fence, nouveau_gem_object_delete, vma); - } else { - if (mapped) - nvkm_vm_unmap(vma); - nvkm_vm_put(vma); - kfree(vma); - } + else + nouveau_vma_del(&vma); } void @@ -150,7 +128,7 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct device *dev = drm->dev->dev; - struct nvkm_vma *vma; + struct nouveau_vma *vma; int ret; if (!cli->vm) @@ -160,9 +138,9 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) if (ret) return; - vma = nouveau_bo_vma_find(nvbo, cli->vm); + vma = nouveau_vma_find(nvbo, &cli->vmm); if (vma) { - if (--vma->refcount == 0) { + if (--vma->refs == 0) { ret = pm_runtime_get_sync(dev); if (!WARN_ON(ret < 0 && ret != -EACCES)) { nouveau_gem_object_unmap(nvbo, vma); @@ -227,7 +205,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, { struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_bo *nvbo = nouveau_gem_object(gem); - struct nvkm_vma *vma; + struct nouveau_vma *vma; if (is_power_of_2(nvbo->valid_domains)) rep->domain = nvbo->valid_domains; @@ -237,11 +215,11 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; rep->offset = nvbo->bo.offset; if (cli->vm) { - vma = nouveau_bo_vma_find(nvbo, cli->vm); + vma = nouveau_vma_find(nvbo, &cli->vmm); if (!vma) return -EINVAL; - rep->offset = vma->offset; + rep->offset = vma->addr; } rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT; @@ -798,7 +776,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, bo[push[i].bo_index].user_priv; uint32_t cmd; - cmd = chan->push.vma.offset + ((chan->dma.cur + 2) << 2); + cmd = chan->push.addr + ((chan->dma.cur + 2) << 2); cmd |= 0x20000000; if (unlikely(cmd != req->suffix0)) { if (!nvbo->kmap.virtual) { @@ -850,7 +828,7 @@ out_next: req->suffix1 = 0x00000000; } else { req->suffix0 = 0x20000000 | - (chan->push.vma.offset + ((chan->dma.cur + 2) << 2)); + (chan->push.addr + ((chan->dma.cur + 2) << 2)); req->suffix1 = 0x00000000; } diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c new file mode 100644 index 000000000000..855d549e17cf --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -0,0 +1,128 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "nouveau_vmm.h" +#include "nouveau_drv.h" +#include "nouveau_bo.h" +#include "nouveau_mem.h" + +void +nouveau_vma_unmap(struct nouveau_vma *vma) +{ + if (vma->mem) { + nvkm_vm_unmap(&vma->_vma); + vma->mem = NULL; + } +} + +int +nouveau_vma_map(struct nouveau_vma *vma, struct nouveau_mem *mem) +{ + int ret = nouveau_mem_map(mem, vma->vmm->vm, &vma->_vma); + if (ret) + return ret; + vma->mem = mem; + return 0; +} + +struct nouveau_vma * +nouveau_vma_find(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm) +{ + struct nouveau_vma *vma; + + list_for_each_entry(vma, &nvbo->vma_list, head) { + if (vma->vmm == vmm) + return vma; + } + + return NULL; +} + +void +nouveau_vma_del(struct nouveau_vma **pvma) +{ + struct nouveau_vma *vma = *pvma; + if (vma && --vma->refs <= 0) { + if (likely(vma->addr != ~0ULL)) { + nouveau_vma_unmap(vma); + nvkm_vm_put(&vma->_vma); + } + list_del(&vma->head); + *pvma = NULL; + kfree(*pvma); + } +} + +int +nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm, + struct nouveau_vma **pvma) +{ + struct nouveau_mem *mem = nouveau_mem(&nvbo->bo.mem); + struct nouveau_vma *vma; + int ret; + + if ((vma = *pvma = nouveau_vma_find(nvbo, vmm))) { + vma->refs++; + return 0; + } + + if (!(vma = *pvma = kmalloc(sizeof(*vma), GFP_KERNEL))) + return -ENOMEM; + vma->vmm = vmm; + vma->refs = 1; + vma->addr = ~0ULL; + vma->mem = NULL; + list_add_tail(&vma->head, &nvbo->vma_list); + + if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && + mem->mem.page == nvbo->page) { + ret = nvkm_vm_get(vmm->vm, mem->_mem->size << 12, mem->mem.page, + NV_MEM_ACCESS_RW, &vma->_vma); + if (ret) + goto done; + + vma->addr = vma->_vma.offset; + ret = nouveau_vma_map(vma, mem); + } else { + ret = nvkm_vm_get(vmm->vm, mem->_mem->size << 12, mem->mem.page, + NV_MEM_ACCESS_RW, &vma->_vma); + vma->addr = vma->_vma.offset; + } + +done: + if (ret) + nouveau_vma_del(pvma); + return ret; +} + +void +nouveau_vmm_fini(struct nouveau_vmm *vmm) +{ + nvkm_vm_ref(NULL, &vmm->vm, NULL); +} + +int +nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm) +{ + vmm->cli = cli; + return nvkm_vm_new(nvxx_device(&cli->device), 0, (1ULL << 40), + 0x1000, NULL, &vmm->vm); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.h b/drivers/gpu/drm/nouveau/nouveau_vmm.h new file mode 100644 index 000000000000..86ab599aafb2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.h @@ -0,0 +1,32 @@ +#ifndef __NOUVEAU_VMA_H__ +#define __NOUVEAU_VMA_H__ +#include +struct nouveau_bo; +struct nouveau_mem; + +struct nouveau_vma { + struct nouveau_vmm *vmm; + int refs; + struct list_head head; + u64 addr; + + struct nouveau_mem *mem; + + struct nvkm_vma _vma; +}; + +struct nouveau_vma *nouveau_vma_find(struct nouveau_bo *, struct nouveau_vmm *); +int nouveau_vma_new(struct nouveau_bo *, struct nouveau_vmm *, + struct nouveau_vma **); +void nouveau_vma_del(struct nouveau_vma **); +int nouveau_vma_map(struct nouveau_vma *, struct nouveau_mem *); +void nouveau_vma_unmap(struct nouveau_vma *); + +struct nouveau_vmm { + struct nouveau_cli *cli; + struct nvkm_vm *vm; +}; + +int nouveau_vmm_init(struct nouveau_cli *, s32 oclass, struct nouveau_vmm *); +void nouveau_vmm_fini(struct nouveau_vmm *); +#endif diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 327dcd7901ed..facd18564e0d 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -25,6 +25,7 @@ #include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fbcon.h" +#include "nouveau_vmm.h" int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) @@ -239,8 +240,8 @@ nv50_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, info->fix.line_length); OUT_RING(chan, info->var.xres_virtual); OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb->vma.offset)); - OUT_RING(chan, lower_32_bits(fb->vma.offset)); + OUT_RING(chan, upper_32_bits(fb->vma->addr)); + OUT_RING(chan, lower_32_bits(fb->vma->addr)); BEGIN_NV04(chan, NvSub2D, 0x0230, 2); OUT_RING(chan, format); OUT_RING(chan, 1); @@ -248,8 +249,8 @@ nv50_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, info->fix.line_length); OUT_RING(chan, info->var.xres_virtual); OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb->vma.offset)); - OUT_RING(chan, lower_32_bits(fb->vma.offset)); + OUT_RING(chan, upper_32_bits(fb->vma->addr)); + OUT_RING(chan, lower_32_bits(fb->vma->addr)); FIRE_RING(chan); return 0; diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index e5f6249edde9..5f0c0c27d5dc 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -25,6 +25,7 @@ #include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fence.h" +#include "nouveau_vmm.h" #include "nv50_display.h" @@ -68,7 +69,7 @@ nv84_fence_emit(struct nouveau_fence *fence) { struct nouveau_channel *chan = fence->channel; struct nv84_fence_chan *fctx = chan->fence; - u64 addr = fctx->vma.offset + chan->chid * 16; + u64 addr = fctx->vma->addr + chan->chid * 16; return fctx->base.emit32(chan, addr, fence->base.seqno); } @@ -78,7 +79,7 @@ nv84_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *prev, struct nouveau_channel *chan) { struct nv84_fence_chan *fctx = chan->fence; - u64 addr = fctx->vma.offset + prev->chid * 16; + u64 addr = fctx->vma->addr + prev->chid * 16; return fctx->base.sync32(chan, addr, fence->base.seqno); } @@ -98,7 +99,7 @@ nv84_fence_context_del(struct nouveau_channel *chan) nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence); mutex_lock(&priv->mutex); - nouveau_bo_vma_del(priv->bo, &fctx->vma); + nouveau_vma_del(&fctx->vma); mutex_unlock(&priv->mutex); nouveau_fence_context_del(&fctx->base); chan->fence = NULL; @@ -126,7 +127,7 @@ nv84_fence_context_new(struct nouveau_channel *chan) fctx->base.sequence = nv84_fence_read(chan); mutex_lock(&priv->mutex); - ret = nouveau_bo_vma_add(priv->bo, cli->vm, &fctx->vma); + ret = nouveau_vma_new(priv->bo, &cli->vmm, &fctx->vma); mutex_unlock(&priv->mutex); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index 90f27bfa381f..c0deef4fe727 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -25,6 +25,7 @@ #include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fbcon.h" +#include "nouveau_vmm.h" int nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) @@ -239,8 +240,8 @@ nvc0_fbcon_accel_init(struct fb_info *info) OUT_RING (chan, info->fix.line_length); OUT_RING (chan, info->var.xres_virtual); OUT_RING (chan, info->var.yres_virtual); - OUT_RING (chan, upper_32_bits(fb->vma.offset)); - OUT_RING (chan, lower_32_bits(fb->vma.offset)); + OUT_RING (chan, upper_32_bits(fb->vma->addr)); + OUT_RING (chan, lower_32_bits(fb->vma->addr)); BEGIN_NVC0(chan, NvSub2D, 0x0230, 10); OUT_RING (chan, format); OUT_RING (chan, 1); @@ -250,8 +251,8 @@ nvc0_fbcon_accel_init(struct fb_info *info) OUT_RING (chan, info->fix.line_length); OUT_RING (chan, info->var.xres_virtual); OUT_RING (chan, info->var.yres_virtual); - OUT_RING (chan, upper_32_bits(fb->vma.offset)); - OUT_RING (chan, lower_32_bits(fb->vma.offset)); + OUT_RING (chan, upper_32_bits(fb->vma->addr)); + OUT_RING (chan, lower_32_bits(fb->vma->addr)); FIRE_RING (chan); return 0; -- cgit v1.2.3 From 4d058fab63f79e5cf13d21edd9db1a63748da0a1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/mm: have users explicitly define heap identifiers Different sections of VRAM may have different properties (ie. can't be used for compression/display, can't be mapped, etc). We currently already support this, but it's a bit magic. This change makes it more obvious where we're allocating from. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/mm.h | 2 +- drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 4 ++++ drivers/gpu/drm/nouveau/nouveau_abi16.c | 2 +- drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c | 2 +- drivers/gpu/drm/nouveau/nvkm/core/mm.c | 5 +++-- drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 5 +++-- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 9 ++++++--- drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 2 +- 15 files changed, 31 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h index 7bd4897a8a2a..21b1a4d43f51 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h @@ -30,7 +30,7 @@ nvkm_mm_initialised(struct nvkm_mm *mm) return mm->heap_nodes; } -int nvkm_mm_init(struct nvkm_mm *, u32 offset, u32 length, u32 block); +int nvkm_mm_init(struct nvkm_mm *, u8 heap, u32 offset, u32 length, u32 block); int nvkm_mm_fini(struct nvkm_mm *); int nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max, u32 size_min, u32 align, struct nvkm_mm_node **); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index dde444a7d3f0..29b21a4f189c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -123,6 +123,10 @@ struct nvkm_ram { u64 size; #define NVKM_RAM_MM_SHIFT 12 +#define NVKM_RAM_MM_ANY (NVKM_MM_HEAP_ANY + 0) +#define NVKM_RAM_MM_NORMAL (NVKM_MM_HEAP_ANY + 1) +#define NVKM_RAM_MM_NOMAP (NVKM_MM_HEAP_ANY + 2) +#define NVKM_RAM_MM_MIXED (NVKM_MM_HEAP_ANY + 3) struct nvkm_mm vram; struct nvkm_mm tags; u64 stolen; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 9b0b210a37f8..4c4e016aba95 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -340,7 +340,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) if (ret) goto done; - ret = nvkm_mm_init(&chan->heap, 0, PAGE_SIZE, 1); + ret = nvkm_mm_init(&chan->heap, 0, 0, PAGE_SIZE, 1); done: if (ret) nouveau_abi16_chan_fini(abi16, chan); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c index a7bd22706b2a..04e5b2136f0c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c @@ -185,7 +185,7 @@ nvkm_gpuobj_ctor(struct nvkm_device *device, u32 size, int align, bool zero, gpuobj->size = nvkm_memory_size(gpuobj->memory); } - return nvkm_mm_init(&gpuobj->heap, 0, gpuobj->size, 1); + return nvkm_mm_init(&gpuobj->heap, 0, 0, gpuobj->size, 1); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/core/mm.c b/drivers/gpu/drm/nouveau/nvkm/core/mm.c index 5c7891234eea..f78a06a6b2f1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/mm.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/mm.c @@ -237,7 +237,7 @@ nvkm_mm_tail(struct nvkm_mm *mm, u8 heap, u8 type, u32 size_max, u32 size_min, } int -nvkm_mm_init(struct nvkm_mm *mm, u32 offset, u32 length, u32 block) +nvkm_mm_init(struct nvkm_mm *mm, u8 heap, u32 offset, u32 length, u32 block) { struct nvkm_mm_node *node, *prev; u32 next; @@ -274,7 +274,8 @@ nvkm_mm_init(struct nvkm_mm *mm, u32 offset, u32 length, u32 block) list_add_tail(&node->nl_entry, &mm->nodes); list_add_tail(&node->fl_entry, &mm->free); - node->heap = ++mm->heap_nodes; + node->heap = heap; + mm->heap_nodes++; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 30483c5d27c3..d35a32e168d6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -136,7 +136,7 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) if (ret) goto free_domain; - ret = nvkm_mm_init(&tdev->iommu.mm, 0, + ret = nvkm_mm_init(&tdev->iommu.mm, 0, 0, (1ULL << tdev->func->iommu_bit) >> tdev->iommu.pgshift, 1); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index c17d559dbfbe..5d908177766f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -73,13 +73,14 @@ nvkm_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, ram->size = size; if (!nvkm_mm_initialised(&ram->vram)) { - ret = nvkm_mm_init(&ram->vram, 0, size >> NVKM_RAM_MM_SHIFT, 1); + ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, 0, + size >> NVKM_RAM_MM_SHIFT, 1); if (ret) return ret; } if (!nvkm_mm_initialised(&ram->tags)) { - ret = nvkm_mm_init(&ram->tags, 0, tags ? ++tags : 0, 1); + ret = nvkm_mm_init(&ram->tags, 0, 0, tags ? ++tags : 0, 1); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index 4a9bd4f1cb93..f3fcb499242f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -617,7 +617,8 @@ gf100_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, */ if (lower != total) { /* The common memory amount is addressed normally. */ - ret = nvkm_mm_init(&ram->vram, rsvd_head >> NVKM_RAM_MM_SHIFT, + ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, + rsvd_head >> NVKM_RAM_MM_SHIFT, (lower - rsvd_head) >> NVKM_RAM_MM_SHIFT, 1); if (ret) return ret; @@ -625,13 +626,15 @@ gf100_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, /* And the rest is much higher in the physical address * space, and may not be usable for certain operations. */ - ret = nvkm_mm_init(&ram->vram, ubase >> NVKM_RAM_MM_SHIFT, + ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_MIXED, + ubase >> NVKM_RAM_MM_SHIFT, (usize - rsvd_tail) >> NVKM_RAM_MM_SHIFT, 1); if (ret) return ret; } else { /* GPUs without mixed-memory are a lot nicer... */ - ret = nvkm_mm_init(&ram->vram, rsvd_head >> NVKM_RAM_MM_SHIFT, + ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, + rsvd_head >> NVKM_RAM_MM_SHIFT, (total - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT, 1); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c index 017a91de74a0..28ab1914718e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c @@ -81,7 +81,8 @@ mcp77_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) ram->base.stolen = base; nvkm_mm_fini(&ram->base.vram); - return nvkm_mm_init(&ram->base.vram, rsvd_head >> NVKM_RAM_MM_SHIFT, + return nvkm_mm_init(&ram->base.vram, NVKM_RAM_MM_NORMAL, + rsvd_head >> NVKM_RAM_MM_SHIFT, (size - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT, 1); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index 6549b0588309..949188569794 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -669,7 +669,8 @@ nv50_ram_ctor(const struct nvkm_ram_func *func, ram->ranks = (nvkm_rd32(device, 0x100200) & 0x4) ? 2 : 1; nvkm_mm_fini(&ram->vram); - return nvkm_mm_init(&ram->vram, rsvd_head >> NVKM_RAM_MM_SHIFT, + return nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, + rsvd_head >> NVKM_RAM_MM_SHIFT, (size - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT, nv50_fb_vram_rblock(ram) >> NVKM_RAM_MM_SHIFT); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index df75da764bd4..2e1141319e93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c @@ -165,7 +165,7 @@ nv04_instmem_oneinit(struct nvkm_instmem *base) /* PRAMIN aperture maps over the end of VRAM, reserve it */ imem->base.reserved = 512 * 1024; - ret = nvkm_mm_init(&imem->heap, 0, imem->base.reserved, 1); + ret = nvkm_mm_init(&imem->heap, 0, 0, imem->base.reserved, 1); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index d8ab5fa86893..7f52a525d2e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -177,7 +177,7 @@ nv40_instmem_oneinit(struct nvkm_instmem *base) imem->base.reserved += 512 * 1024; /* object storage */ imem->base.reserved = round_up(imem->base.reserved, 4096); - ret = nvkm_mm_init(&imem->heap, 0, imem->base.reserved, 1); + ret = nvkm_mm_init(&imem->heap, 0, 0, imem->base.reserved, 1); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c index 4a0fa0a9b802..6b0cb7f3fa77 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c @@ -183,8 +183,8 @@ gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) tag_size += tag_align; tag_size = (tag_size + 0xfff) >> 12; /* round up */ - ret = nvkm_mm_tail(&ram->vram, 1, 1, tag_size, tag_size, 1, - <c->tag_ram); + ret = nvkm_mm_tail(&ram->vram, NVKM_RAM_MM_NORMAL, 1, tag_size, + tag_size, 1, <c->tag_ram); if (ret) { ltc->num_tags = 0; } else { @@ -197,7 +197,7 @@ gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) } mm_init: - return nvkm_mm_init(<c->tags, 0, ltc->num_tags, 1); + return nvkm_mm_init(<c->tags, 0, 0, ltc->num_tags, 1); } int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c index 0bdfb2f40266..74ed4dd203bc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c @@ -45,7 +45,7 @@ gp100_ltc_oneinit(struct nvkm_ltc *ltc) ltc->ltc_nr = nvkm_rd32(device, 0x12006c); ltc->lts_nr = nvkm_rd32(device, 0x17e280) >> 28; /*XXX: tagram allocation - TBD */ - return nvkm_mm_init(<c->tags, 0, 0, 1); + return nvkm_mm_init(<c->tags, 0, 0, 0, 1); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index f2b1a3e75f17..44c2403e88e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -388,7 +388,7 @@ nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, return -ENOMEM; } - ret = nvkm_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12, + ret = nvkm_mm_init(&vm->mm, 0, mm_offset >> 12, mm_length >> 12, block >> 12); if (ret) { vfree(vm->pgt); -- cgit v1.2.3 From b7e1f3f1ba0de8585ddb5a921714b06fcb92f16e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/mm: introduce functions to access info about a given allocation These will be used in upcoming patches. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/mm.h | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h index 21b1a4d43f51..5c1261351138 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h @@ -39,9 +39,39 @@ int nvkm_mm_tail(struct nvkm_mm *, u8 heap, u8 type, u32 size_max, void nvkm_mm_free(struct nvkm_mm *, struct nvkm_mm_node **); void nvkm_mm_dump(struct nvkm_mm *, const char *); +static inline u32 +nvkm_mm_heap_size(struct nvkm_mm *mm, u8 heap) +{ + struct nvkm_mm_node *node; + u32 size = 0; + list_for_each_entry(node, &mm->nodes, nl_entry) { + if (node->heap == heap) + size += node->length; + } + return size; +} + static inline bool nvkm_mm_contiguous(struct nvkm_mm_node *node) { return !node->next; } + +static inline u32 +nvkm_mm_addr(struct nvkm_mm_node *node) +{ + if (WARN_ON(!nvkm_mm_contiguous(node))) + return 0; + return node->offset; +} + +static inline u32 +nvkm_mm_size(struct nvkm_mm_node *node) +{ + u32 size = 0; + do { + size += node->length; + } while ((node = node->next)); + return size; +} #endif -- cgit v1.2.3 From 7ef44bee64c68db7b7bc0cb341eec41891c6d0a5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb: move comptags mm into nvkm_fb We're moving towards having a central place to handle comptag allocation, and as some GPUs don't have a ram submodule (ie. Tegra), we need to move the mm somewhere else. It probably never belonged in ram anyways. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 5 ++--- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 29b21a4f189c..b838d9385859 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -44,6 +44,7 @@ struct nvkm_fb { struct nvkm_subdev subdev; struct nvkm_ram *ram; + struct nvkm_mm tags; struct { struct nvkm_fb_tile region[16]; @@ -128,7 +129,6 @@ struct nvkm_ram { #define NVKM_RAM_MM_NOMAP (NVKM_MM_HEAP_ANY + 2) #define NVKM_RAM_MM_MIXED (NVKM_MM_HEAP_ANY + 3) struct nvkm_mm vram; - struct nvkm_mm tags; u64 stolen; int ranks; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index fa0fad10b62c..dea04406816d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -159,6 +159,7 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev) for (i = 0; i < fb->tile.regions; i++) fb->func->tile.fini(fb, i, &fb->tile.region[i]); + nvkm_mm_fini(&fb->tags); nvkm_ram_del(&fb->ram); if (fb->func->dtor) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c index 126865dfe777..ec5a438b79de 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c @@ -45,7 +45,7 @@ nv20_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, { u32 tiles = DIV_ROUND_UP(size, 0x40); u32 tags = round_up(tiles / fb->ram->parts, 0x40); - if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) { + if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) { if (!(flags & 2)) tile->zcomp = 0x00000000; /* Z16 */ else tile->zcomp = 0x04000000; /* Z24S8 */ tile->zcomp |= tile->tag->offset; @@ -63,7 +63,7 @@ nv20_fb_tile_fini(struct nvkm_fb *fb, int i, struct nvkm_fb_tile *tile) tile->limit = 0; tile->pitch = 0; tile->zcomp = 0; - nvkm_mm_free(&fb->ram->tags, &tile->tag); + nvkm_mm_free(&fb->tags, &tile->tag); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c index c56746d2a502..bf342a239b48 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c @@ -32,7 +32,7 @@ nv25_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, { u32 tiles = DIV_ROUND_UP(size, 0x40); u32 tags = round_up(tiles / fb->ram->parts, 0x40); - if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) { + if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) { if (!(flags & 2)) tile->zcomp = 0x00100000; /* Z16 */ else tile->zcomp = 0x00200000; /* Z24S8 */ tile->zcomp |= tile->tag->offset; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c index 2a7c4831b821..2280fbae508a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c @@ -51,7 +51,7 @@ nv30_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, { u32 tiles = DIV_ROUND_UP(size, 0x40); u32 tags = round_up(tiles / fb->ram->parts, 0x40); - if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) { + if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) { if (flags & 2) tile->zcomp |= 0x01000000; /* Z16 */ else tile->zcomp |= 0x02000000; /* Z24S8 */ tile->zcomp |= ((tile->tag->offset ) >> 6); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c index 1604b3789ad1..244c3ec3a4ed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c @@ -32,7 +32,7 @@ nv35_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, { u32 tiles = DIV_ROUND_UP(size, 0x40); u32 tags = round_up(tiles / fb->ram->parts, 0x40); - if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) { + if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) { if (flags & 2) tile->zcomp |= 0x04000000; /* Z16 */ else tile->zcomp |= 0x08000000; /* Z24S8 */ tile->zcomp |= ((tile->tag->offset ) >> 6); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c index 80cc0a6e3416..a0a9b1fd0a00 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c @@ -32,7 +32,7 @@ nv36_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, { u32 tiles = DIV_ROUND_UP(size, 0x40); u32 tags = round_up(tiles / fb->ram->parts, 0x40); - if (!nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) { + if (!nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) { if (flags & 2) tile->zcomp |= 0x10000000; /* Z16 */ else tile->zcomp |= 0x20000000; /* Z24S8 */ tile->zcomp |= ((tile->tag->offset ) >> 6); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c index deec46a310f8..bdb97bb03b62 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c @@ -33,7 +33,7 @@ nv40_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, u32 tiles = DIV_ROUND_UP(size, 0x80); u32 tags = round_up(tiles / fb->ram->parts, 0x100); if ( (flags & 2) && - !nvkm_mm_head(&fb->ram->tags, 0, 1, tags, tags, 1, &tile->tag)) { + !nvkm_mm_head(&fb->tags, 0, 1, tags, tags, 1, &tile->tag)) { tile->zcomp = 0x28000000; /* Z24S8_SPLIT_GRAD */ tile->zcomp |= ((tile->tag->offset ) >> 8); tile->zcomp |= ((tile->tag->offset + tags - 1) >> 8) << 13; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 5d908177766f..2cfd4336b5c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -38,7 +38,6 @@ nvkm_ram_del(struct nvkm_ram **pram) if (ram && !WARN_ON(!ram->func)) { if (ram->func->dtor) *pram = ram->func->dtor(ram); - nvkm_mm_fini(&ram->tags); nvkm_mm_fini(&ram->vram); kfree(*pram); *pram = NULL; @@ -79,8 +78,8 @@ nvkm_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, return ret; } - if (!nvkm_mm_initialised(&ram->tags)) { - ret = nvkm_mm_init(&ram->tags, 0, 0, tags ? ++tags : 0, 1); + if (!nvkm_mm_initialised(&fb->tags)) { + ret = nvkm_mm_init(&fb->tags, 0, 0, tags ? ++tags : 0, 1); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index 949188569794..0fa02fbc561d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -502,7 +502,7 @@ __nv50_ram_put(struct nvkm_ram *ram, struct nvkm_mem *mem) next = node->next; nvkm_mm_free(&ram->vram, &node); } - nvkm_mm_free(&ram->tags, &mem->tag); + nvkm_mm_free(&ram->fb->tags, &mem->tag); } void @@ -526,7 +526,7 @@ nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, u32 memtype, struct nvkm_mem **pmem) { struct nvkm_mm *heap = &ram->vram; - struct nvkm_mm *tags = &ram->tags; + struct nvkm_mm *tags = &ram->fb->tags; struct nvkm_mm_node **node, *r; struct nvkm_mem *mem; int comp = (memtype & 0x300) >> 8; -- cgit v1.2.3 From af793b8cd9f62880852379897519bbe69fb59c05 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb: move comptag init out of ram submodule Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 12 +++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c | 8 ++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c | 11 +++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 16 +++------------- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h | 6 ++---- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c | 7 +++---- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 3 +-- 30 files changed, 63 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index dea04406816d..94c53454501d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -100,6 +100,7 @@ static int nvkm_fb_oneinit(struct nvkm_subdev *subdev) { struct nvkm_fb *fb = nvkm_fb(subdev); + u32 tags = 0; if (fb->func->ram_new) { int ret = fb->func->ram_new(fb, &fb->ram); @@ -115,7 +116,16 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev) return ret; } - return 0; + /* Initialise compression tag allocator. + * + * LTC oneinit() will override this on Fermi and newer. + */ + if (fb->func->tags) { + tags = fb->func->tags(fb); + nvkm_debug(subdev, "%d comptags\n", tags); + } + + return nvkm_mm_init(&fb->tags, 0, 0, tags, 1); } static int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c index 9c28392d07e4..06bf95c0c549 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c @@ -27,6 +27,7 @@ static const struct nv50_fb_func g84_fb = { .ram_new = nv50_ram_new, + .tags = nv20_fb_tags, .trap = 0x001d07ff, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c index ebb30608d5ef..9266559b45f9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c @@ -27,6 +27,7 @@ static const struct nv50_fb_func gt215_fb = { .ram_new = gt215_ram_new, + .tags = nv20_fb_tags, .trap = 0x000d0fff, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c index ec5a438b79de..20e47248ba36 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c @@ -77,8 +77,16 @@ nv20_fb_tile_prog(struct nvkm_fb *fb, int i, struct nvkm_fb_tile *tile) nvkm_wr32(device, 0x100300 + (i * 0x04), tile->zcomp); } +u32 +nv20_fb_tags(struct nvkm_fb *fb) +{ + const u32 tags = nvkm_rd32(fb->subdev.device, 0x100320); + return tags ? tags + 1 : 0; +} + static const struct nvkm_fb_func nv20_fb = { + .tags = nv20_fb_tags, .tile.regions = 8, .tile.init = nv20_fb_tile_init, .tile.comp = nv20_fb_tile_comp, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c index bf342a239b48..dc2965514abe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c @@ -44,6 +44,7 @@ nv25_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, static const struct nvkm_fb_func nv25_fb = { + .tags = nv20_fb_tags, .tile.regions = 8, .tile.init = nv20_fb_tile_init, .tile.comp = nv25_fb_tile_comp, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c index 2280fbae508a..28b147d8d628 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c @@ -116,6 +116,7 @@ nv30_fb_init(struct nvkm_fb *fb) static const struct nvkm_fb_func nv30_fb = { + .tags = nv20_fb_tags, .init = nv30_fb_init, .tile.regions = 8, .tile.init = nv30_fb_tile_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c index 244c3ec3a4ed..4e213da6a215 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c @@ -45,6 +45,7 @@ nv35_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, static const struct nvkm_fb_func nv35_fb = { + .tags = nv20_fb_tags, .init = nv30_fb_init, .tile.regions = 8, .tile.init = nv30_fb_tile_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c index a0a9b1fd0a00..9f029f02088c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c @@ -45,6 +45,7 @@ nv36_fb_tile_comp(struct nvkm_fb *fb, int i, u32 size, u32 flags, static const struct nvkm_fb_func nv36_fb = { + .tags = nv20_fb_tags, .init = nv30_fb_init, .tile.regions = 8, .tile.init = nv30_fb_tile_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c index bdb97bb03b62..893bc8b3cc80 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c @@ -51,6 +51,7 @@ nv40_fb_init(struct nvkm_fb *fb) static const struct nvkm_fb_func nv40_fb = { + .tags = nv20_fb_tags, .init = nv40_fb_init, .tile.regions = 8, .tile.init = nv30_fb_tile_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c index 79e57dd5a00f..c1a79564a2f5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c @@ -45,6 +45,7 @@ nv41_fb_init(struct nvkm_fb *fb) static const struct nvkm_fb_func nv41_fb = { + .tags = nv20_fb_tags, .init = nv41_fb_init, .tile.regions = 12, .tile.init = nv30_fb_tile_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c index c505e4429314..d1d5fc952e32 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c @@ -28,6 +28,7 @@ static const struct nvkm_fb_func nv47_fb = { + .tags = nv20_fb_tags, .init = nv41_fb_init, .tile.regions = 15, .tile.init = nv30_fb_tile_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c index 7b91b9f170e5..b3dff3543062 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c @@ -28,6 +28,7 @@ static const struct nvkm_fb_func nv49_fb = { + .tags = nv20_fb_tags, .init = nv41_fb_init, .tile.regions = 15, .tile.init = nv30_fb_tile_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c index 0595e0722bfc..da797c4525b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c @@ -244,6 +244,15 @@ nv50_fb_init(struct nvkm_fb *base) nvkm_wr32(device, 0x100c90, fb->func->trap); } +static u32 +nv50_fb_tags(struct nvkm_fb *base) +{ + struct nv50_fb *fb = nv50_fb(base); + if (fb->func->tags) + return fb->func->tags(&fb->base); + return 0; +} + static void * nv50_fb_dtor(struct nvkm_fb *base) { @@ -262,6 +271,7 @@ nv50_fb_dtor(struct nvkm_fb *base) static const struct nvkm_fb_func nv50_fb_ = { .dtor = nv50_fb_dtor, + .tags = nv50_fb_tags, .oneinit = nv50_fb_oneinit, .init = nv50_fb_init, .intr = nv50_fb_intr, @@ -287,6 +297,7 @@ nv50_fb_new_(const struct nv50_fb_func *func, struct nvkm_device *device, static const struct nv50_fb_func nv50_fb = { .ram_new = nv50_ram_new, + .tags = nv20_fb_tags, .trap = 0x000707ff, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h index faa88c8c66fe..74da4d7dcaa0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h @@ -12,6 +12,7 @@ struct nv50_fb { struct nv50_fb_func { int (*ram_new)(struct nvkm_fb *, struct nvkm_ram **); + u32 (*tags)(struct nvkm_fb *); u32 trap; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index afaa68da3221..329ff5e0115a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -6,6 +6,7 @@ struct nvkm_bios; struct nvkm_fb_func { void *(*dtor)(struct nvkm_fb *); + u32 (*tags)(struct nvkm_fb *); int (*oneinit)(struct nvkm_fb *); void (*init)(struct nvkm_fb *); int (*init_page)(struct nvkm_fb *); @@ -42,6 +43,7 @@ void nv10_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, void nv10_fb_tile_fini(struct nvkm_fb *, int i, struct nvkm_fb_tile *); void nv10_fb_tile_prog(struct nvkm_fb *, int, struct nvkm_fb_tile *); +u32 nv20_fb_tags(struct nvkm_fb *); void nv20_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, u32 pitch, u32 flags, struct nvkm_fb_tile *); void nv20_fb_tile_fini(struct nvkm_fb *, int i, struct nvkm_fb_tile *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 2cfd4336b5c5..69f65daaf1ea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -46,8 +46,7 @@ nvkm_ram_del(struct nvkm_ram **pram) int nvkm_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, - enum nvkm_ram_type type, u64 size, u32 tags, - struct nvkm_ram *ram) + enum nvkm_ram_type type, u64 size, struct nvkm_ram *ram) { static const char *name[] = { [NVKM_RAM_TYPE_UNKNOWN] = "of unknown memory type", @@ -78,23 +77,14 @@ nvkm_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, return ret; } - if (!nvkm_mm_initialised(&fb->tags)) { - ret = nvkm_mm_init(&fb->tags, 0, 0, tags ? ++tags : 0, 1); - if (ret) - return ret; - - nvkm_debug(subdev, "%d compression tags\n", tags); - } - return 0; } int nvkm_ram_new_(const struct nvkm_ram_func *func, struct nvkm_fb *fb, - enum nvkm_ram_type type, u64 size, u32 tags, - struct nvkm_ram **pram) + enum nvkm_ram_type type, u64 size, struct nvkm_ram **pram) { if (!(*pram = kzalloc(sizeof(**pram), GFP_KERNEL))) return -ENOMEM; - return nvkm_ram_ctor(func, fb, type, size, tags, *pram); + return nvkm_ram_ctor(func, fb, type, size, *pram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h index fac7e73c3ddf..a007699b60a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h @@ -3,11 +3,9 @@ #include "priv.h" int nvkm_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *, - enum nvkm_ram_type, u64 size, u32 tags, - struct nvkm_ram *); + enum nvkm_ram_type, u64 size, struct nvkm_ram *); int nvkm_ram_new_(const struct nvkm_ram_func *, struct nvkm_fb *, - enum nvkm_ram_type, u64 size, u32 tags, - struct nvkm_ram **); + enum nvkm_ram_type, u64 size, struct nvkm_ram **); void nvkm_ram_del(struct nvkm_ram **); int nvkm_ram_init(struct nvkm_ram *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index f3fcb499242f..a44298989d3c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -604,7 +604,7 @@ gf100_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, nvkm_debug(subdev, "Upper: %4lld MiB @ %010llx\n", usize >> 20, ubase); nvkm_debug(subdev, "Total: %4lld MiB\n", total >> 20); - ret = nvkm_ram_ctor(func, fb, type, total, 0, ram); + ret = nvkm_ram_ctor(func, fb, type, total, ram); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c index 28ab1914718e..76fa71f0c457 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c @@ -73,7 +73,7 @@ mcp77_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) *pram = &ram->base; ret = nvkm_ram_ctor(&mcp77_ram_func, fb, NVKM_RAM_TYPE_STOLEN, - size, 0, &ram->base); + size, &ram->base); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c index 6f053a03d61c..cc764a93f1a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c @@ -61,5 +61,5 @@ nv04_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) else type = NVKM_RAM_TYPE_SDRAM; - return nvkm_ram_new_(&nv04_ram_func, fb, type, size, 0, pram); + return nvkm_ram_new_(&nv04_ram_func, fb, type, size, pram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c index dfd155c98dbb..afe54e323b18 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c @@ -36,5 +36,5 @@ nv10_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) else type = NVKM_RAM_TYPE_SDRAM; - return nvkm_ram_new_(&nv04_ram_func, fb, type, size, 0, pram); + return nvkm_ram_new_(&nv04_ram_func, fb, type, size, pram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c index 3c6a8710e812..4c07d10bb976 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c @@ -44,5 +44,5 @@ nv1a_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) } return nvkm_ram_new_(&nv04_ram_func, fb, NVKM_RAM_TYPE_STOLEN, - mib * 1024 * 1024, 0, pram); + mib * 1024 * 1024, pram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c index 747e47c10cc7..71d63d7daa75 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c @@ -29,7 +29,6 @@ nv20_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct nvkm_device *device = fb->subdev.device; u32 pbus1218 = nvkm_rd32(device, 0x001218); u32 size = (nvkm_rd32(device, 0x10020c) & 0xff000000); - u32 tags = nvkm_rd32(device, 0x100320); enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN; int ret; @@ -40,7 +39,7 @@ nv20_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) case 0x00000300: type = NVKM_RAM_TYPE_GDDR2; break; } - ret = nvkm_ram_new_(&nv04_ram_func, fb, type, size, tags, pram); + ret = nvkm_ram_new_(&nv04_ram_func, fb, type, size, pram); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c index 70c63535d56b..2b12e388f47a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c @@ -187,13 +187,13 @@ nv40_ram_func = { int nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type type, u64 size, - u32 tags, struct nvkm_ram **pram) + struct nvkm_ram **pram) { struct nv40_ram *ram; if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) return -ENOMEM; *pram = &ram->base; - return nvkm_ram_ctor(&nv40_ram_func, fb, type, size, tags, &ram->base); + return nvkm_ram_ctor(&nv40_ram_func, fb, type, size, &ram->base); } int @@ -202,7 +202,6 @@ nv40_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct nvkm_device *device = fb->subdev.device; u32 pbus1218 = nvkm_rd32(device, 0x001218); u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000; - u32 tags = nvkm_rd32(device, 0x100320); enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN; int ret; @@ -213,7 +212,7 @@ nv40_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) case 0x00000300: type = NVKM_RAM_TYPE_DDR2 ; break; } - ret = nv40_ram_new_(fb, type, size, tags, pram); + ret = nv40_ram_new_(fb, type, size, pram); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.h index 8a0524566b48..ec5dcbfcaea8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.h @@ -9,6 +9,6 @@ struct nv40_ram { u32 coef; }; -int nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type, u64, u32, +int nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type, u64, struct nvkm_ram **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c index 114828be292e..d3fea3726461 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c @@ -28,7 +28,6 @@ nv41_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) { struct nvkm_device *device = fb->subdev.device; u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000; - u32 tags = nvkm_rd32(device, 0x100320); u32 fb474 = nvkm_rd32(device, 0x100474); enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN; int ret; @@ -40,7 +39,7 @@ nv41_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) if (fb474 & 0x00000001) type = NVKM_RAM_TYPE_DDR1; - ret = nv40_ram_new_(fb, type, size, tags, pram); + ret = nv40_ram_new_(fb, type, size, pram); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c index bc56fbf1c788..ab2630e5e6fb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c @@ -38,5 +38,5 @@ nv44_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) if (fb474 & 0x00000001) type = NVKM_RAM_TYPE_DDR1; - return nv40_ram_new_(fb, type, size, 0, pram); + return nv40_ram_new_(fb, type, size, pram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c index c01f4b1022b8..946ca7c2e0b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c @@ -28,7 +28,6 @@ nv49_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) { struct nvkm_device *device = fb->subdev.device; u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000; - u32 tags = nvkm_rd32(device, 0x100320); u32 fb914 = nvkm_rd32(device, 0x100914); enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN; int ret; @@ -40,7 +39,7 @@ nv49_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) case 0x00000003: break; } - ret = nv40_ram_new_(fb, type, size, tags, pram); + ret = nv40_ram_new_(fb, type, size, pram); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c index fa3c2e06203d..02b8bdbc819f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c @@ -29,5 +29,5 @@ nv4e_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct nvkm_device *device = fb->subdev.device; u32 size = nvkm_rd32(device, 0x10020c) & 0xff000000; return nvkm_ram_new_(&nv04_ram_func, fb, NVKM_RAM_TYPE_UNKNOWN, - size, 0, pram); + size, pram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index 0fa02fbc561d..030ac8339f49 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -639,7 +639,6 @@ nv50_ram_ctor(const struct nvkm_ram_func *func, const u32 rsvd_head = ( 256 * 1024); /* vga memory */ const u32 rsvd_tail = (1024 * 1024); /* vbios etc */ u64 size = nvkm_rd32(device, 0x10020c); - u32 tags = nvkm_rd32(device, 0x100320); enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN; int ret; @@ -660,7 +659,7 @@ nv50_ram_ctor(const struct nvkm_ram_func *func, size = (size & 0x000000ff) << 32 | (size & 0xffffff00); - ret = nvkm_ram_ctor(func, fb, type, size, tags, ram); + ret = nvkm_ram_ctor(func, fb, type, size, ram); if (ret) return ret; -- cgit v1.2.3 From b1e839f3b3d82a0774c296f9950214057b045b72 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb/gf100: clear comptags at allocation time rather than mmu map We probably don't want to destroy compression data when doing multiple mappings of a memory object. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 6 +++++- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 3 --- 4 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h index cd755baf9cab..93eeb557a9f2 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h @@ -25,7 +25,7 @@ struct nvkm_ltc { int nvkm_ltc_tags_alloc(struct nvkm_ltc *, u32 count, struct nvkm_mm_node **); void nvkm_ltc_tags_free(struct nvkm_ltc *, struct nvkm_mm_node **); -void nvkm_ltc_tags_clear(struct nvkm_ltc *, u32 first, u32 count); +void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count); int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]); int nvkm_ltc_zbc_depth_get(struct nvkm_ltc *, int index, const u32); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index a44298989d3c..7109e21f4564 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -443,6 +443,7 @@ int gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, u32 memtype, struct nvkm_mem **pmem) { + struct nvkm_device *device = ram->fb->subdev.device; struct nvkm_ltc *ltc = ram->fb->subdev.device->ltc; struct nvkm_mm *mm = &ram->vram; struct nvkm_mm_node **node, *r; @@ -469,7 +470,10 @@ gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, /* compression only works with lpages */ if (align == (1 << (17 - NVKM_RAM_MM_SHIFT))) { int n = size >> 5; - nvkm_ltc_tags_alloc(ltc, n, &mem->tag); + if (!nvkm_ltc_tags_alloc(ltc, n, &mem->tag)) { + nvkm_ltc_tags_clear(device, mem->tag->offset, + mem->tag->length); + } } if (unlikely(!mem->tag)) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index 0c7ef250dcaf..a75320943187 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -41,8 +41,9 @@ nvkm_ltc_tags_free(struct nvkm_ltc *ltc, struct nvkm_mm_node **pnode) } void -nvkm_ltc_tags_clear(struct nvkm_ltc *ltc, u32 first, u32 count) +nvkm_ltc_tags_clear(struct nvkm_device *device, u32 first, u32 count) { + struct nvkm_ltc *ltc = device->ltc; const u32 limit = first + count - 1; BUG_ON((first > limit) || (limit >= ltc->num_tags)); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 7ac507c927bb..cda5b0997c8f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -24,7 +24,6 @@ #include "priv.h" #include -#include #include #include @@ -109,11 +108,9 @@ gf100_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, pte <<= 3; if (mem->tag) { - struct nvkm_ltc *ltc = vma->vm->mmu->subdev.device->ltc; u32 tag = mem->tag->offset + (delta >> 17); phys |= (u64)tag << (32 + 12); next |= (u64)1 << (32 + 12); - nvkm_ltc_tags_clear(ltc, tag, cnt); } nvkm_kmap(pgt); -- cgit v1.2.3 From 6cd7670c1e2a4a70a3d421521aea548e68992621 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/ltc: init comptag mm in fb subdev A single location for the MM allows us to share allocation logic. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c | 7 ++++--- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c | 6 ++++-- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h index 93eeb557a9f2..0e2751bbf153 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h @@ -14,7 +14,6 @@ struct nvkm_ltc { u32 num_tags; u32 tag_base; - struct nvkm_mm tags; struct nvkm_mm_node *tag_ram; int zbc_min; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index a75320943187..f4aa81dd8978 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -28,7 +28,8 @@ int nvkm_ltc_tags_alloc(struct nvkm_ltc *ltc, u32 n, struct nvkm_mm_node **pnode) { - int ret = nvkm_mm_head(<c->tags, 0, 1, n, n, 1, pnode); + struct nvkm_fb *fb = ltc->subdev.device->fb; + int ret = nvkm_mm_head(&fb->tags, 0, 1, n, n, 1, pnode); if (ret) *pnode = NULL; return ret; @@ -37,7 +38,8 @@ nvkm_ltc_tags_alloc(struct nvkm_ltc *ltc, u32 n, struct nvkm_mm_node **pnode) void nvkm_ltc_tags_free(struct nvkm_ltc *ltc, struct nvkm_mm_node **pnode) { - nvkm_mm_free(<c->tags, pnode); + struct nvkm_fb *fb = ltc->subdev.device->fb; + nvkm_mm_free(&fb->tags, pnode); } void @@ -118,7 +120,6 @@ nvkm_ltc_dtor(struct nvkm_subdev *subdev) { struct nvkm_ltc *ltc = nvkm_ltc(subdev); struct nvkm_ram *ram = ltc->subdev.device->fb->ram; - nvkm_mm_fini(<c->tags); if (ram) nvkm_mm_free(&ram->vram, <c->tag_ram); return ltc; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c index 6b0cb7f3fa77..60a5e9e2b264 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c @@ -152,7 +152,8 @@ gf100_ltc_flush(struct nvkm_ltc *ltc) int gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) { - struct nvkm_ram *ram = ltc->subdev.device->fb->ram; + struct nvkm_fb *fb = ltc->subdev.device->fb; + struct nvkm_ram *ram = fb->ram; u32 tag_size, tag_margin, tag_align; int ret; @@ -197,7 +198,8 @@ gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) } mm_init: - return nvkm_mm_init(<c->tags, 0, 0, ltc->num_tags, 1); + nvkm_mm_fini(&fb->tags); + return nvkm_mm_init(&fb->tags, 0, 0, ltc->num_tags, 1); } int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c index 74ed4dd203bc..e34d42108019 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c @@ -45,7 +45,7 @@ gp100_ltc_oneinit(struct nvkm_ltc *ltc) ltc->ltc_nr = nvkm_rd32(device, 0x12006c); ltc->lts_nr = nvkm_rd32(device, 0x17e280) >> 28; /*XXX: tagram allocation - TBD */ - return nvkm_mm_init(<c->tags, 0, 0, 0, 1); + return 0; } static void -- cgit v1.2.3 From 7f53d6dc9a728d54cc4e1d70259376e09675f924 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/memory: comptag allocation nvkm_memory is going to be used by the upcoming mmu rework for the basic representation of a memory allocation, as such, this commit adds support for comptag allocation to nvkm_memory. This is very simple for now, in that it requires comptags for the entire memory allocation even if only certain ranges are compressed. Support for tracking ranges will be added at a later date. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/memory.h | 12 ++++ drivers/gpu/drm/nouveau/nvkm/core/memory.c | 71 ++++++++++++++++++++++ 2 files changed, 83 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h index 14ce7df9864e..ce04e0f74f0c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -5,6 +5,11 @@ struct nvkm_device; struct nvkm_vma; struct nvkm_vm; +struct nvkm_tags { + struct nvkm_mm_node *mn; + refcount_t refcount; +}; + enum nvkm_memory_target { NVKM_MEM_TARGET_INST, /* instance memory */ NVKM_MEM_TARGET_VRAM, /* video memory */ @@ -15,6 +20,7 @@ enum nvkm_memory_target { struct nvkm_memory { const struct nvkm_memory_func *func; const struct nvkm_memory_ptrs *ptrs; + struct nvkm_tags *tags; }; struct nvkm_memory_func { @@ -37,6 +43,12 @@ void nvkm_memory_ctor(const struct nvkm_memory_func *, struct nvkm_memory *); int nvkm_memory_new(struct nvkm_device *, enum nvkm_memory_target, u64 size, u32 align, bool zero, struct nvkm_memory **); void nvkm_memory_del(struct nvkm_memory **); +int nvkm_memory_tags_get(struct nvkm_memory *, struct nvkm_device *, u32 tags, + void (*clear)(struct nvkm_device *, u32, u32), + struct nvkm_tags **); +void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *, + struct nvkm_tags **); + #define nvkm_memory_target(p) (p)->func->target(p) #define nvkm_memory_addr(p) (p)->func->addr(p) #define nvkm_memory_size(p) (p)->func->size(p) diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c index 8903c04c977e..13cfcdde99fd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c @@ -22,8 +22,79 @@ * Authors: Ben Skeggs */ #include +#include +#include #include +void +nvkm_memory_tags_put(struct nvkm_memory *memory, struct nvkm_device *device, + struct nvkm_tags **ptags) +{ + struct nvkm_fb *fb = device->fb; + struct nvkm_tags *tags = *ptags; + if (tags) { + mutex_lock(&fb->subdev.mutex); + if (refcount_dec_and_test(&tags->refcount)) { + nvkm_mm_free(&fb->tags, &tags->mn); + kfree(memory->tags); + memory->tags = NULL; + } + mutex_unlock(&fb->subdev.mutex); + *ptags = NULL; + } +} + +int +nvkm_memory_tags_get(struct nvkm_memory *memory, struct nvkm_device *device, + u32 nr, void (*clr)(struct nvkm_device *, u32, u32), + struct nvkm_tags **ptags) +{ + struct nvkm_fb *fb = device->fb; + struct nvkm_tags *tags; + + mutex_lock(&fb->subdev.mutex); + if ((tags = memory->tags)) { + /* If comptags exist for the memory, but a different amount + * than requested, the buffer is being mapped with settings + * that are incompatible with existing mappings. + */ + if (tags->mn && tags->mn->length != nr) { + mutex_unlock(&fb->subdev.mutex); + return -EINVAL; + } + + refcount_inc(&tags->refcount); + *ptags = tags; + return 0; + } + + if (!(tags = kmalloc(sizeof(*tags), GFP_KERNEL))) { + mutex_unlock(&fb->subdev.mutex); + return -ENOMEM; + } + + if (!nvkm_mm_head(&fb->tags, 0, 1, nr, nr, 1, &tags->mn)) { + if (clr) + clr(device, tags->mn->offset, tags->mn->length); + } else { + /* Failure to allocate HW comptags is not an error, the + * caller should fall back to an uncompressed map. + * + * As memory can be mapped in multiple places, we still + * need to track the allocation failure and ensure that + * any additional mappings remain uncompressed. + * + * This is handled by returning an empty nvkm_tags. + */ + tags->mn = NULL; + } + + refcount_set(&tags->refcount, 1); + mutex_unlock(&fb->subdev.mutex); + *ptags = tags; + return 0; +} + void nvkm_memory_ctor(const struct nvkm_memory_func *func, struct nvkm_memory *memory) -- cgit v1.2.3 From 19a82e492c3d71efe8763d50496a1701dfcf3f15 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/memory: change map interface to support upcoming mmu changes Map flags (access, kind, etc) are currently defined in either the VMA, or the memory object, which turns out to not be ideal for things like suballocated buffers, etc. These will become per-map flags instead, so we need to support passing these arguments in nvkm_memory_map(). Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h | 7 +--- drivers/gpu/drm/nouveau/include/nvkm/core/memory.h | 10 +++-- drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c | 43 ++++++++++++---------- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 3 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 3 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | 15 ++++++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 15 ++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 11 +++++- .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 9 +++-- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 8 ++-- .../gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c | 9 ++++- 11 files changed, 83 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h index acd07de3e4ee..51691667b813 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h @@ -2,8 +2,6 @@ #define __NVKM_GPUOBJ_H__ #include #include -struct nvkm_vma; -struct nvkm_vm; #define NVOBJ_FLAG_ZERO_ALLOC 0x00000001 #define NVOBJ_FLAG_HEAP 0x00000004 @@ -29,15 +27,14 @@ struct nvkm_gpuobj_func { void (*release)(struct nvkm_gpuobj *); u32 (*rd32)(struct nvkm_gpuobj *, u32 offset); void (*wr32)(struct nvkm_gpuobj *, u32 offset, u32 data); + int (*map)(struct nvkm_gpuobj *, u64 offset, struct nvkm_vmm *, + struct nvkm_vma *, void *argv, u32 argc); }; int nvkm_gpuobj_new(struct nvkm_device *, u32 size, int align, bool zero, struct nvkm_gpuobj *parent, struct nvkm_gpuobj **); void nvkm_gpuobj_del(struct nvkm_gpuobj **); int nvkm_gpuobj_wrap(struct nvkm_memory *, struct nvkm_gpuobj **); -int nvkm_gpuobj_map(struct nvkm_gpuobj *, struct nvkm_vm *, u32 access, - struct nvkm_vma *); -void nvkm_gpuobj_unmap(struct nvkm_vma *); void nvkm_gpuobj_memcpy_to(struct nvkm_gpuobj *dst, u32 dstoffset, void *src, u32 length); void nvkm_gpuobj_memcpy_from(void *dst, struct nvkm_gpuobj *src, u32 srcoffset, diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h index ce04e0f74f0c..41bc89af11c0 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -3,7 +3,7 @@ #include struct nvkm_device; struct nvkm_vma; -struct nvkm_vm; +struct nvkm_vmm; struct nvkm_tags { struct nvkm_mm_node *mn; @@ -28,10 +28,11 @@ struct nvkm_memory_func { enum nvkm_memory_target (*target)(struct nvkm_memory *); u64 (*addr)(struct nvkm_memory *); u64 (*size)(struct nvkm_memory *); - void (*boot)(struct nvkm_memory *, struct nvkm_vm *); + void (*boot)(struct nvkm_memory *, struct nvkm_vmm *); void __iomem *(*acquire)(struct nvkm_memory *); void (*release)(struct nvkm_memory *); - void (*map)(struct nvkm_memory *, struct nvkm_vma *, u64 offset); + int (*map)(struct nvkm_memory *, u64 offset, struct nvkm_vmm *, + struct nvkm_vma *, void *argv, u32 argc); }; struct nvkm_memory_ptrs { @@ -53,7 +54,8 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *, #define nvkm_memory_addr(p) (p)->func->addr(p) #define nvkm_memory_size(p) (p)->func->size(p) #define nvkm_memory_boot(p,v) (p)->func->boot((p),(v)) -#define nvkm_memory_map(p,v,o) (p)->func->map((p),(v),(o)) +#define nvkm_memory_map(p,o,vm,va,av,ac) \ + (p)->func->map((p),(o),(vm),(va),(av),(ac)) /* accessor macros - kmap()/done() must bracket use of the other accessor * macros to guarantee correct behaviour across all chipsets diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c index 04e5b2136f0c..1264d5fc632b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c @@ -42,6 +42,14 @@ nvkm_gpuobj_wr32_fast(struct nvkm_gpuobj *gpuobj, u32 offset, u32 data) } /* accessor functions for gpuobjs allocated directly from instmem */ +static int +nvkm_gpuobj_heap_map(struct nvkm_gpuobj *gpuobj, u64 offset, + struct nvkm_vmm *vmm, struct nvkm_vma *vma, + void *argv, u32 argc) +{ + return nvkm_memory_map(gpuobj->memory, offset, vmm, vma, argv, argc); +} + static u32 nvkm_gpuobj_heap_rd32(struct nvkm_gpuobj *gpuobj, u32 offset) { @@ -67,6 +75,7 @@ nvkm_gpuobj_heap_fast = { .release = nvkm_gpuobj_heap_release, .rd32 = nvkm_gpuobj_rd32_fast, .wr32 = nvkm_gpuobj_wr32_fast, + .map = nvkm_gpuobj_heap_map, }; static const struct nvkm_gpuobj_func @@ -74,6 +83,7 @@ nvkm_gpuobj_heap_slow = { .release = nvkm_gpuobj_heap_release, .rd32 = nvkm_gpuobj_heap_rd32, .wr32 = nvkm_gpuobj_heap_wr32, + .map = nvkm_gpuobj_heap_map, }; static void * @@ -90,9 +100,19 @@ nvkm_gpuobj_heap_acquire(struct nvkm_gpuobj *gpuobj) static const struct nvkm_gpuobj_func nvkm_gpuobj_heap = { .acquire = nvkm_gpuobj_heap_acquire, + .map = nvkm_gpuobj_heap_map, }; /* accessor functions for gpuobjs sub-allocated from a parent gpuobj */ +static int +nvkm_gpuobj_map(struct nvkm_gpuobj *gpuobj, u64 offset, + struct nvkm_vmm *vmm, struct nvkm_vma *vma, + void *argv, u32 argc) +{ + return nvkm_memory_map(gpuobj->parent, gpuobj->node->offset + offset, + vmm, vma, argv, argc); +} + static u32 nvkm_gpuobj_rd32(struct nvkm_gpuobj *gpuobj, u32 offset) { @@ -118,6 +138,7 @@ nvkm_gpuobj_fast = { .release = nvkm_gpuobj_release, .rd32 = nvkm_gpuobj_rd32_fast, .wr32 = nvkm_gpuobj_wr32_fast, + .map = nvkm_gpuobj_map, }; static const struct nvkm_gpuobj_func @@ -125,6 +146,7 @@ nvkm_gpuobj_slow = { .release = nvkm_gpuobj_release, .rd32 = nvkm_gpuobj_rd32, .wr32 = nvkm_gpuobj_wr32, + .map = nvkm_gpuobj_map, }; static void * @@ -143,6 +165,7 @@ nvkm_gpuobj_acquire(struct nvkm_gpuobj *gpuobj) static const struct nvkm_gpuobj_func nvkm_gpuobj_func = { .acquire = nvkm_gpuobj_acquire, + .map = nvkm_gpuobj_map, }; static int @@ -218,26 +241,6 @@ nvkm_gpuobj_new(struct nvkm_device *device, u32 size, int align, bool zero, return ret; } -int -nvkm_gpuobj_map(struct nvkm_gpuobj *gpuobj, struct nvkm_vm *vm, - u32 access, struct nvkm_vma *vma) -{ - struct nvkm_memory *memory = gpuobj->memory; - int ret = nvkm_vm_get(vm, gpuobj->size, 12, access, vma); - if (ret == 0) - nvkm_memory_map(memory, vma, 0); - return ret; -} - -void -nvkm_gpuobj_unmap(struct nvkm_vma *vma) -{ - if (vma->node) { - nvkm_vm_unmap(vma); - nvkm_vm_put(vma); - } -} - /* the below is basically only here to support sharing the paged dma object * for PCI(E)GART on <=nv4x chipsets, and should *not* be expected to work * anywhere else. diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index b1ab34f1a0e9..14b1a616d26a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -591,8 +591,7 @@ gf100_fifo_oneinit(struct nvkm_fifo *base) if (ret) return ret; - nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0); - return 0; + return nvkm_memory_map(fifo->user.mem, 0, bar, &fifo->user.bar, NULL, 0); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index cdadff59bb4c..9629416f4947 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -841,8 +841,7 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) if (ret) return ret; - nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0); - return 0; + return nvkm_memory_map(fifo->user.mem, 0, bar, &fifo->user.bar, NULL, 0); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index f9e0377d3d24..6343e0c84d96 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c @@ -126,7 +126,11 @@ gf100_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base, struct nvkm_engine *engine) { struct gf100_fifo_chan *chan = gf100_fifo_chan(base); - nvkm_gpuobj_unmap(&chan->engn[engine->subdev.index].vma); + struct nvkm_vma *vma = &chan->engn[engine->subdev.index].vma; + if (vma->vm) { + nvkm_vm_unmap(vma); + nvkm_vm_put(vma); + } nvkm_gpuobj_del(&chan->engn[engine->subdev.index].inst); } @@ -146,8 +150,13 @@ gf100_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, if (ret) return ret; - return nvkm_gpuobj_map(chan->engn[engn].inst, chan->vm, - NV_MEM_ACCESS_RW, &chan->engn[engn].vma); + ret = nvkm_vm_get(chan->vm, chan->engn[engn].inst->size, 12, + NV_MEM_ACCESS_RW, &chan->engn[engn].vma); + if (ret) + return ret; + + return nvkm_memory_map(chan->engn[engn].inst, 0, chan->vm, + &chan->engn[engn].vma, NULL, 0); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 8abf6f8ef445..6e93b8652c66 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -138,7 +138,11 @@ gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base, struct nvkm_engine *engine) { struct gk104_fifo_chan *chan = gk104_fifo_chan(base); - nvkm_gpuobj_unmap(&chan->engn[engine->subdev.index].vma); + struct nvkm_vma *vma = &chan->engn[engine->subdev.index].vma; + if (vma->vm) { + nvkm_vm_unmap(vma); + nvkm_vm_put(vma); + } nvkm_gpuobj_del(&chan->engn[engine->subdev.index].inst); } @@ -158,8 +162,13 @@ gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, if (ret) return ret; - return nvkm_gpuobj_map(chan->engn[engn].inst, chan->vm, - NV_MEM_ACCESS_RW, &chan->engn[engn].vma); + ret = nvkm_vm_get(chan->vm, chan->engn[engn].inst->size, 12, + NV_MEM_ACCESS_RW, &chan->engn[engn].vma); + if (ret) + return ret; + + return nvkm_memory_map(chan->engn[engn].inst, 0, chan->vm, + &chan->engn[engn].vma, NULL, 0); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 49c7d08b0ceb..0c4ca0fa48cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -403,7 +403,10 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, if (ret) return ret; - nvkm_memory_map(chan->mmio, &chan->mmio_vma, 0); + ret = nvkm_memory_map(chan->mmio, 0, fifoch->vm, + &chan->mmio_vma, NULL, 0); + if (ret) + return ret; /* allocate buffers referenced by mmio list */ for (i = 0; data->size && i < ARRAY_SIZE(gr->mmio_data); i++) { @@ -419,7 +422,11 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, if (ret) return ret; - nvkm_memory_map(chan->data[i].mem, &chan->data[i].vma, 0); + ret = nvkm_memory_map(chan->data[i].mem, 0, fifoch->vm, + &chan->data[i].vma, NULL, 0); + if (ret) + return ret; + data++; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index f2879c48d1e6..73a9511c3101 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -272,12 +272,13 @@ gk20a_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) node->vaddr[offset / 4] = data; } -static void -gk20a_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) +static int +gk20a_instobj_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, + struct nvkm_vma *vma, void *argv, u32 argc) { struct gk20a_instobj *node = gk20a_instobj(memory); - - nvkm_vm_map_at(vma, offset, &node->mem); + nvkm_vm_map_at(vma, 0, &node->mem); + return 0; } static void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index bb524e3aa5d9..657257daa74d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -159,7 +159,7 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) } if (ret == 0) - nvkm_memory_map(memory, &bar, 0); + ret = nvkm_memory_map(memory, 0, vmm, &bar, NULL, 0); mutex_lock(&subdev->mutex); if (ret || iobj->bar.node) { /* We either failed, or another thread beat us. */ @@ -179,11 +179,13 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) } } -static void -nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) +static int +nv50_instobj_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, + struct nvkm_vma *vma, void *argv, u32 argc) { struct nv50_instobj *iobj = nv50_instobj(memory); nvkm_vm_map_at(vma, offset, iobj->mem); + return 0; } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c index 73ca1203281d..d35c041fdcec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c @@ -48,12 +48,16 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob, return ret; /* Map the HS firmware so the HS bootloader can see it */ - ret = nvkm_gpuobj_map(blob, gsb->vm, NV_MEM_ACCESS_RW, &vma); + ret = nvkm_vm_get(gsb->vm, blob->size, 12, NV_MEM_ACCESS_RW, &vma); if (ret) { nvkm_falcon_put(falcon, subdev); return ret; } + ret = nvkm_memory_map(blob, 0, gsb->vm, &vma, NULL, 0); + if (ret) + goto end; + /* Reset and set the falcon up */ ret = nvkm_falcon_reset(falcon); if (ret) @@ -91,7 +95,8 @@ end: nvkm_mc_intr_mask(sb->subdev.device, falcon->owner->index, true); /* We don't need the ACR firmware anymore */ - nvkm_gpuobj_unmap(&vma); + nvkm_vm_unmap(&vma); + nvkm_vm_put(&vma); nvkm_falcon_put(falcon, subdev); return ret; -- cgit v1.2.3 From 2c9c4910f8b126d18fa2a08087f3ae1553e706bc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/memory: add mechanism to retrieve allocation granularity Needed by VMM code to determine whether an allocation is compatible with a given page size (ie. you can't map 4KiB system memory pages into 64KiB GPU pages). Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/memory.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h index 41bc89af11c0..a0bfc37b96db 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -26,6 +26,7 @@ struct nvkm_memory { struct nvkm_memory_func { void *(*dtor)(struct nvkm_memory *); enum nvkm_memory_target (*target)(struct nvkm_memory *); + u8 (*page)(struct nvkm_memory *); u64 (*addr)(struct nvkm_memory *); u64 (*size)(struct nvkm_memory *); void (*boot)(struct nvkm_memory *, struct nvkm_vmm *); @@ -51,6 +52,7 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *, struct nvkm_tags **); #define nvkm_memory_target(p) (p)->func->target(p) +#define nvkm_memory_page(p) (p)->func->page(p) #define nvkm_memory_addr(p) (p)->func->addr(p) #define nvkm_memory_size(p) (p)->func->size(p) #define nvkm_memory_boot(p,v) (p)->func->boot((p),(v)) -- cgit v1.2.3 From 997a89003c2d950466bc289147ffb823c0c51fb0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/memory: add reference counting We need to be able to prevent memory from being freed while it's still mapped in a GPU's address-space. Will be used by upcoming MMU changes. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/memory.h | 4 +++- drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c | 2 +- drivers/gpu/drm/nouveau/nvkm/core/memory.c | 28 ++++++++++++++++++---- drivers/gpu/drm/nouveau/nvkm/engine/falcon.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 6 ++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 6 ++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 6 ++--- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c | 6 ++--- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 6 ++--- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 2 +- 19 files changed, 57 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h index a0bfc37b96db..9c9c400bea98 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -20,6 +20,7 @@ enum nvkm_memory_target { struct nvkm_memory { const struct nvkm_memory_func *func; const struct nvkm_memory_ptrs *ptrs; + struct kref kref; struct nvkm_tags *tags; }; @@ -44,7 +45,8 @@ struct nvkm_memory_ptrs { void nvkm_memory_ctor(const struct nvkm_memory_func *, struct nvkm_memory *); int nvkm_memory_new(struct nvkm_device *, enum nvkm_memory_target, u64 size, u32 align, bool zero, struct nvkm_memory **); -void nvkm_memory_del(struct nvkm_memory **); +struct nvkm_memory *nvkm_memory_ref(struct nvkm_memory *); +void nvkm_memory_unref(struct nvkm_memory **); int nvkm_memory_tags_get(struct nvkm_memory *, struct nvkm_device *, u32 tags, void (*clear)(struct nvkm_device *, u32, u32), struct nvkm_tags **); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c index 1264d5fc632b..d6de2b3ed2c3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c @@ -219,7 +219,7 @@ nvkm_gpuobj_del(struct nvkm_gpuobj **pgpuobj) if (gpuobj->parent) nvkm_mm_free(&gpuobj->parent->heap, &gpuobj->node); nvkm_mm_fini(&gpuobj->heap); - nvkm_memory_del(&gpuobj->memory); + nvkm_memory_unref(&gpuobj->memory); kfree(*pgpuobj); *pgpuobj = NULL; } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c index 13cfcdde99fd..29f4b4070b55 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c @@ -100,20 +100,38 @@ nvkm_memory_ctor(const struct nvkm_memory_func *func, struct nvkm_memory *memory) { memory->func = func; + kref_init(&memory->kref); +} + +static void +nvkm_memory_del(struct kref *kref) +{ + struct nvkm_memory *memory = container_of(kref, typeof(*memory), kref); + if (!WARN_ON(!memory->func)) { + if (memory->func->dtor) + memory = memory->func->dtor(memory); + kfree(memory); + } } void -nvkm_memory_del(struct nvkm_memory **pmemory) +nvkm_memory_unref(struct nvkm_memory **pmemory) { struct nvkm_memory *memory = *pmemory; - if (memory && !WARN_ON(!memory->func)) { - if (memory->func->dtor) - *pmemory = memory->func->dtor(memory); - kfree(*pmemory); + if (memory) { + kref_put(&memory->kref, nvkm_memory_del); *pmemory = NULL; } } +struct nvkm_memory * +nvkm_memory_ref(struct nvkm_memory *memory) +{ + if (memory) + kref_get(&memory->kref); + return memory; +} + int nvkm_memory_new(struct nvkm_device *device, enum nvkm_memory_target target, u64 size, u32 align, bool zero, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c index 2e7b4e2105ef..816ccaedfc73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c @@ -99,7 +99,7 @@ nvkm_falcon_fini(struct nvkm_engine *engine, bool suspend) const u32 base = falcon->addr; if (!suspend) { - nvkm_memory_del(&falcon->core); + nvkm_memory_unref(&falcon->core); if (falcon->external) { vfree(falcon->data.data); vfree(falcon->code.data); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 14b1a616d26a..24a4c28b32c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -642,9 +642,9 @@ gf100_fifo_dtor(struct nvkm_fifo *base) { struct gf100_fifo *fifo = gf100_fifo(base); nvkm_vm_put(&fifo->user.bar); - nvkm_memory_del(&fifo->user.mem); - nvkm_memory_del(&fifo->runlist.mem[0]); - nvkm_memory_del(&fifo->runlist.mem[1]); + nvkm_memory_unref(&fifo->user.mem); + nvkm_memory_unref(&fifo->runlist.mem[0]); + nvkm_memory_unref(&fifo->runlist.mem[1]); return fifo; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 9629416f4947..eddf9f12e9ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -880,11 +880,11 @@ gk104_fifo_dtor(struct nvkm_fifo *base) int i; nvkm_vm_put(&fifo->user.bar); - nvkm_memory_del(&fifo->user.mem); + nvkm_memory_unref(&fifo->user.mem); for (i = 0; i < fifo->runlist_nr; i++) { - nvkm_memory_del(&fifo->runlist[i].mem[1]); - nvkm_memory_del(&fifo->runlist[i].mem[0]); + nvkm_memory_unref(&fifo->runlist[i].mem[1]); + nvkm_memory_unref(&fifo->runlist[i].mem[0]); } return fifo; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c index 66eb12c2b5ba..fa6e094d8068 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c @@ -100,8 +100,8 @@ void * nv50_fifo_dtor(struct nvkm_fifo *base) { struct nv50_fifo *fifo = nv50_fifo(base); - nvkm_memory_del(&fifo->runlist[1]); - nvkm_memory_del(&fifo->runlist[0]); + nvkm_memory_unref(&fifo->runlist[1]); + nvkm_memory_unref(&fifo->runlist[0]); return fifo; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index bc77eea351a5..ce69ec8b13ad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1380,7 +1380,7 @@ gf100_grctx_generate(struct gf100_gr *gr) } done: - nvkm_memory_del(&chan); + nvkm_memory_unref(&chan); return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 0c4ca0fa48cc..4fc4deb2db4b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -354,14 +354,14 @@ gf100_gr_chan_dtor(struct nvkm_object *object) nvkm_vm_unmap(&chan->data[i].vma); nvkm_vm_put(&chan->data[i].vma); } - nvkm_memory_del(&chan->data[i].mem); + nvkm_memory_unref(&chan->data[i].mem); } if (chan->mmio_vma.node) { nvkm_vm_unmap(&chan->mmio_vma); nvkm_vm_put(&chan->mmio_vma); } - nvkm_memory_del(&chan->mmio); + nvkm_memory_unref(&chan->mmio); return chan; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c index d1dc92999dc0..d6840dc81a29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c @@ -59,7 +59,7 @@ void * nv20_gr_chan_dtor(struct nvkm_object *object) { struct nv20_gr_chan *chan = nv20_gr_chan(object); - nvkm_memory_del(&chan->inst); + nvkm_memory_unref(&chan->inst); return chan; } @@ -323,7 +323,7 @@ void * nv20_gr_dtor(struct nvkm_gr *base) { struct nv20_gr *gr = nv20_gr(base); - nvkm_memory_del(&gr->ctxtab); + nvkm_memory_unref(&gr->ctxtab); return gr; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c index 06bdb67a0205..70549381e082 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c @@ -86,7 +86,7 @@ nvkm_xtensa_fini(struct nvkm_engine *engine, bool suspend) nvkm_wr32(device, base + 0xd94, 0); /* FIFO_CTRL */ if (!suspend) - nvkm_memory_del(&xtensa->gpu_fw); + nvkm_memory_unref(&xtensa->gpu_fw); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index b155a7f76ca7..9f7b4e7532b7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -166,14 +166,14 @@ gf100_bar_dtor(struct nvkm_bar *base) nvkm_vm_ref(NULL, &bar->bar[1].vm, bar->bar[1].pgd); nvkm_gpuobj_del(&bar->bar[1].pgd); - nvkm_memory_del(&bar->bar[1].mem); + nvkm_memory_unref(&bar->bar[1].mem); if (bar->bar[0].vm) { - nvkm_memory_del(&bar->bar[0].vm->pgt[0].mem[0]); + nvkm_memory_unref(&bar->bar[0].vm->pgt[0].mem[0]); nvkm_vm_ref(NULL, &bar->bar[0].vm, bar->bar[0].pgd); } nvkm_gpuobj_del(&bar->bar[0].pgd); - nvkm_memory_del(&bar->bar[0].mem); + nvkm_memory_unref(&bar->bar[0].mem); return bar; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index cf1d0acd2afc..1aa6b5390d79 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -201,7 +201,7 @@ nv50_bar_dtor(struct nvkm_bar *base) nvkm_vm_ref(NULL, &bar->bar1_vm, bar->pgd); nvkm_gpuobj_del(&bar->bar2); if (bar->bar2_vm) { - nvkm_memory_del(&bar->bar2_vm->pgt[0].mem[0]); + nvkm_memory_unref(&bar->bar2_vm->pgt[0].mem[0]); nvkm_vm_ref(NULL, &bar->bar2_vm, bar->pgd); } nvkm_gpuobj_del(&bar->pgd); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index 94c53454501d..78248e21a5f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -163,8 +163,8 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev) struct nvkm_fb *fb = nvkm_fb(subdev); int i; - nvkm_memory_del(&fb->mmu_wr); - nvkm_memory_del(&fb->mmu_rd); + nvkm_memory_unref(&fb->mmu_wr); + nvkm_memory_unref(&fb->mmu_rd); for (i = 0; i < fb->tile.regions; i++) fb->func->tile.fini(fb, i, &fb->tile.region[i]); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index b03940591a3a..364ea4492acc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -120,7 +120,7 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, done: if (ret) - nvkm_memory_del(&memory); + nvkm_memory_unref(&memory); *pmemory = memory; return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index 2e1141319e93..6bf0dad46919 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c @@ -199,10 +199,10 @@ static void * nv04_instmem_dtor(struct nvkm_instmem *base) { struct nv04_instmem *imem = nv04_instmem(base); - nvkm_memory_del(&imem->base.ramfc); - nvkm_memory_del(&imem->base.ramro); + nvkm_memory_unref(&imem->base.ramfc); + nvkm_memory_unref(&imem->base.ramro); nvkm_ramht_del(&imem->base.ramht); - nvkm_memory_del(&imem->base.vbios); + nvkm_memory_unref(&imem->base.vbios); nvkm_mm_fini(&imem->heap); return imem; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 7f52a525d2e1..086c118488ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -215,10 +215,10 @@ static void * nv40_instmem_dtor(struct nvkm_instmem *base) { struct nv40_instmem *imem = nv40_instmem(base); - nvkm_memory_del(&imem->base.ramfc); - nvkm_memory_del(&imem->base.ramro); + nvkm_memory_unref(&imem->base.ramfc); + nvkm_memory_unref(&imem->base.ramro); nvkm_ramht_del(&imem->base.ramht); - nvkm_memory_del(&imem->base.vbios); + nvkm_memory_unref(&imem->base.vbios); nvkm_mm_fini(&imem->heap); if (imem->iomem) iounmap(imem->iomem); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 44c2403e88e6..ad11db458fcc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -243,7 +243,7 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde) mmu->func->flush(vm); - nvkm_memory_del(&pgt); + nvkm_memory_unref(&pgt); } } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index cd16442f1a91..43e3b4a77583 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -106,7 +106,7 @@ nv04_mmu_dtor(struct nvkm_mmu *base) struct nv04_mmu *mmu = nv04_mmu(base); struct nvkm_device *device = mmu->base.subdev.device; if (mmu->base.vmm) { - nvkm_memory_del(&mmu->base.vmm->pgt[0].mem[0]); + nvkm_memory_unref(&mmu->base.vmm->pgt[0].mem[0]); nvkm_vm_ref(NULL, &mmu->base.vmm, NULL); } if (mmu->nullp) { -- cgit v1.2.3 From c09597f083960cea492e1d658b9039b06d8a6839 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/core/memory: add some useful accessor macros Adds support for 64-bit writes, and optimised filling of buffers with fixed 32/64-bit values. These will all be used by the upcoming MMU changes. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/os.h | 14 ----------- drivers/gpu/drm/nouveau/include/nvkm/core/memory.h | 28 +++++++++++++++++++++- drivers/gpu/drm/nouveau/include/nvkm/core/os.h | 20 ++++++++++++++++ 3 files changed, 47 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/os.h b/drivers/gpu/drm/nouveau/include/nvif/os.h index 9fcab67c8557..5efdf80d5abc 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/os.h +++ b/drivers/gpu/drm/nouveau/include/nvif/os.h @@ -33,18 +33,4 @@ #include #include - -#ifndef ioread32_native -#ifdef __BIG_ENDIAN -#define ioread16_native ioread16be -#define iowrite16_native iowrite16be -#define ioread32_native ioread32be -#define iowrite32_native iowrite32be -#else /* def __BIG_ENDIAN */ -#define ioread16_native ioread16 -#define iowrite16_native iowrite16 -#define ioread32_native ioread32 -#define iowrite32_native iowrite32 -#endif /* def __BIG_ENDIAN else */ -#endif /* !ioread32_native */ #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h index 9c9c400bea98..13ebf4da2b96 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h @@ -65,6 +65,8 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *, * macros to guarantee correct behaviour across all chipsets */ #define nvkm_kmap(o) (o)->func->acquire(o) +#define nvkm_done(o) (o)->func->release(o) + #define nvkm_ro32(o,a) (o)->ptrs->rd32((o), (a)) #define nvkm_wo32(o,a,d) (o)->ptrs->wr32((o), (a), (d)) #define nvkm_mo32(o,a,m,d) ({ \ @@ -72,5 +74,29 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *, nvkm_wo32((o), _addr, (_data & ~(m)) | (d)); \ _data; \ }) -#define nvkm_done(o) (o)->func->release(o) + +#define nvkm_wo64(o,a,d) do { \ + u64 __a = (a), __d = (d); \ + nvkm_wo32((o), __a + 0, lower_32_bits(__d)); \ + nvkm_wo32((o), __a + 4, upper_32_bits(__d)); \ +} while(0) + +#define nvkm_fill(t,s,o,a,d,c) do { \ + u64 _a = (a), _c = (c), _d = (d), _o = _a >> s, _s = _c << s; \ + u##t __iomem *_m = nvkm_kmap(o); \ + if (likely(_m)) { \ + if (_d) { \ + while (_c--) \ + iowrite##t##_native(_d, &_m[_o++]); \ + } else { \ + memset_io(&_m[_o], _d, _s); \ + } \ + } else { \ + for (; _c; _c--, _a += BIT(s)) \ + nvkm_wo##t((o), _a, _d); \ + } \ + nvkm_done(o); \ +} while(0) +#define nvkm_fo32(o,a,d,c) nvkm_fill(32, 2, (o), (a), (d), (c)) +#define nvkm_fo64(o,a,d,c) nvkm_fill(64, 3, (o), (a), (d), (c)) #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h index cfd9ed361c44..70c5c47300b4 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h @@ -2,4 +2,24 @@ #define __NVKM_OS_H__ #include #define nvkm_vmm nvkm_vm + +#ifdef __BIG_ENDIAN +#define ioread16_native ioread16be +#define iowrite16_native iowrite16be +#define ioread32_native ioread32be +#define iowrite32_native iowrite32be +#else +#define ioread16_native ioread16 +#define iowrite16_native iowrite16 +#define ioread32_native ioread32 +#define iowrite32_native iowrite32 +#endif + +#define iowrite64_native(v,p) do { \ + u32 __iomem *_p = (u32 __iomem *)(p); \ + u64 _v = (v); \ + iowrite32_native(lower_32_bits(_v), &_p[0]); \ + iowrite32_native(upper_32_bits(_v), &_p[1]); \ +} while(0) + #endif -- cgit v1.2.3 From e9a8b218044c693a12a852c558f745267a6b6eb8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb/ram: add interface to allocate vram as an nvkm_memory object Upcoming MMU changes use nvkm_memory as its basic representation of memory, so we need to be able to allocate VRAM like this. The code is basically identical to the current chipset-specific allocators, minus support for compression tags (which will be handled elsewhere anyway). Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 4 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 122 +++++++++++++++++++++++ 2 files changed, 126 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index b838d9385859..942d67174005 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -145,6 +145,10 @@ struct nvkm_ram { struct nvkm_ram_data target; }; +int +nvkm_ram_get(struct nvkm_device *, u8 heap, u8 type, u8 page, u64 size, + bool contig, bool back, struct nvkm_memory **); + struct nvkm_ram_func { u64 upper; u32 (*probe_fbp)(const struct nvkm_ram_func *, struct nvkm_device *, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 69f65daaf1ea..8d17644c1823 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -21,8 +21,130 @@ * * Authors: Ben Skeggs */ +#define nvkm_vram(p) container_of((p), struct nvkm_vram, memory) #include "ram.h" +#include +#include + +struct nvkm_vram { + struct nvkm_memory memory; + struct nvkm_ram *ram; + u8 page; + struct nvkm_mm_node *mn; +}; + +static int +nvkm_vram_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, + struct nvkm_vma *vma, void *argv, u32 argc) +{ + struct nvkm_vram *vram = nvkm_vram(memory); + struct nvkm_mem mem = { + .mem = vram->mn, + }; + nvkm_vm_map_at(vma, offset, &mem); + return 0; +} + +static u64 +nvkm_vram_size(struct nvkm_memory *memory) +{ + return (u64)nvkm_mm_size(nvkm_vram(memory)->mn) << NVKM_RAM_MM_SHIFT; +} + +static u64 +nvkm_vram_addr(struct nvkm_memory *memory) +{ + struct nvkm_vram *vram = nvkm_vram(memory); + if (!nvkm_mm_contiguous(vram->mn)) + return ~0ULL; + return (u64)nvkm_mm_addr(vram->mn) << NVKM_RAM_MM_SHIFT; +} + +static u8 +nvkm_vram_page(struct nvkm_memory *memory) +{ + return nvkm_vram(memory)->page; +} + +static enum nvkm_memory_target +nvkm_vram_target(struct nvkm_memory *memory) +{ + return NVKM_MEM_TARGET_VRAM; +} + +static void * +nvkm_vram_dtor(struct nvkm_memory *memory) +{ + struct nvkm_vram *vram = nvkm_vram(memory); + struct nvkm_mm_node *next = vram->mn; + struct nvkm_mm_node *node; + mutex_lock(&vram->ram->fb->subdev.mutex); + while ((node = next)) { + next = node->next; + nvkm_mm_free(&vram->ram->vram, &node); + } + mutex_unlock(&vram->ram->fb->subdev.mutex); + return vram; +} + +static const struct nvkm_memory_func +nvkm_vram = { + .dtor = nvkm_vram_dtor, + .target = nvkm_vram_target, + .page = nvkm_vram_page, + .addr = nvkm_vram_addr, + .size = nvkm_vram_size, + .map = nvkm_vram_map, +}; + +int +nvkm_ram_get(struct nvkm_device *device, u8 heap, u8 type, u8 rpage, u64 size, + bool contig, bool back, struct nvkm_memory **pmemory) +{ + struct nvkm_ram *ram; + struct nvkm_mm *mm; + struct nvkm_mm_node **node, *r; + struct nvkm_vram *vram; + u8 page = max(rpage, (u8)NVKM_RAM_MM_SHIFT); + u32 align = (1 << page) >> NVKM_RAM_MM_SHIFT; + u32 max = ALIGN(size, 1 << page) >> NVKM_RAM_MM_SHIFT; + u32 min = contig ? max : align; + int ret; + + if (!device->fb || !(ram = device->fb->ram)) + return -ENODEV; + ram = device->fb->ram; + mm = &ram->vram; + + if (!(vram = kzalloc(sizeof(*vram), GFP_KERNEL))) + return -ENOMEM; + nvkm_memory_ctor(&nvkm_vram, &vram->memory); + vram->ram = ram; + vram->page = page; + *pmemory = &vram->memory; + + mutex_lock(&ram->fb->subdev.mutex); + node = &vram->mn; + do { + if (back) + ret = nvkm_mm_tail(mm, heap, type, max, min, align, &r); + else + ret = nvkm_mm_head(mm, heap, type, max, min, align, &r); + if (ret) { + mutex_unlock(&ram->fb->subdev.mutex); + nvkm_memory_unref(pmemory); + return ret; + } + + *node = r; + node = &r->next; + max -= r->length; + } while (max); + mutex_unlock(&ram->fb->subdev.mutex); + return 0; +} + int nvkm_ram_init(struct nvkm_ram *ram) { -- cgit v1.2.3 From 2bfa0b01146586e5098327462a1de090e09b541d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb/ram/gt215: allocate training buffer with nvkm_ram_get() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c index f10664372161..9bace6c4ad0b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c @@ -26,6 +26,7 @@ #include "ram.h" #include "ramfuc.h" +#include #include #include #include @@ -86,7 +87,7 @@ struct gt215_ltrain { u32 r_100720; u32 r_1111e0; u32 r_111400; - struct nvkm_mem *mem; + struct nvkm_memory *memory; }; struct gt215_ram { @@ -279,10 +280,10 @@ gt215_link_train_init(struct gt215_ram *ram) struct gt215_ltrain *train = &ram->ltrain; struct nvkm_device *device = ram->base.fb->subdev.device; struct nvkm_bios *bios = device->bios; - struct nvkm_mem *mem; struct nvbios_M0205E M0205E; u8 ver, hdr, cnt, len; u32 r001700; + u64 addr; int ret, i = 0; train->state = NVA3_TRAIN_UNSUPPORTED; @@ -297,14 +298,14 @@ gt215_link_train_init(struct gt215_ram *ram) train->state = NVA3_TRAIN_ONCE; - ret = ram->base.func->get(&ram->base, 0x8000, 0x10000, 0, 0x800, - &ram->ltrain.mem); + ret = nvkm_ram_get(device, NVKM_RAM_MM_NORMAL, 0x01, 16, 0x8000, + true, true, &ram->ltrain.memory); if (ret) return ret; - mem = ram->ltrain.mem; + addr = nvkm_memory_addr(ram->ltrain.memory); - nvkm_wr32(device, 0x100538, 0x10000000 | (mem->offset >> 16)); + nvkm_wr32(device, 0x100538, 0x10000000 | (addr >> 16)); nvkm_wr32(device, 0x1005a8, 0x0000ffff); nvkm_mask(device, 0x10f800, 0x00000001, 0x00000001); @@ -320,7 +321,7 @@ gt215_link_train_init(struct gt215_ram *ram) /* And upload the pattern */ r001700 = nvkm_rd32(device, 0x1700); - nvkm_wr32(device, 0x1700, mem->offset >> 16); + nvkm_wr32(device, 0x1700, addr >> 16); for (i = 0; i < 16; i++) nvkm_wr32(device, 0x700000 + (i << 2), pattern[i]); for (i = 0; i < 16; i++) @@ -336,8 +337,7 @@ gt215_link_train_init(struct gt215_ram *ram) static void gt215_link_train_fini(struct gt215_ram *ram) { - if (ram->ltrain.mem) - ram->base.func->put(&ram->base, &ram->ltrain.mem); + nvkm_memory_unref(&ram->ltrain.memory); } /* -- cgit v1.2.3 From 7f4f82af6e48c22b3fa5e41aab4dc0fdf0a7717e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50: allocate memory with nvkm_ram_get() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 37 ++++++++-------------- 1 file changed, 14 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 657257daa74d..64e2b6e0e8b1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -45,7 +45,7 @@ struct nv50_instmem { struct nv50_instobj { struct nvkm_instobj base; struct nv50_instmem *imem; - struct nvkm_mem *mem; + struct nvkm_memory *ram; struct nvkm_vma bar; refcount_t maps; void *map; @@ -58,8 +58,8 @@ nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data) struct nv50_instobj *iobj = nv50_instobj(memory); struct nv50_instmem *imem = iobj->imem; struct nvkm_device *device = imem->base.subdev.device; - u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; - u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; + u64 base = (nvkm_memory_addr(iobj->ram) + offset) & 0xffffff00000ULL; + u64 addr = (nvkm_memory_addr(iobj->ram) + offset) & 0x000000fffffULL; unsigned long flags; spin_lock_irqsave(&imem->base.lock, flags); @@ -77,8 +77,8 @@ nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset) struct nv50_instobj *iobj = nv50_instobj(memory); struct nv50_instmem *imem = iobj->imem; struct nvkm_device *device = imem->base.subdev.device; - u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL; - u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL; + u64 base = (nvkm_memory_addr(iobj->ram) + offset) & 0xffffff00000ULL; + u64 addr = (nvkm_memory_addr(iobj->ram) + offset) & 0x000000fffffULL; u32 data; unsigned long flags; @@ -183,9 +183,8 @@ static int nv50_instobj_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, struct nvkm_vma *vma, void *argv, u32 argc) { - struct nv50_instobj *iobj = nv50_instobj(memory); - nvkm_vm_map_at(vma, offset, iobj->mem); - return 0; + memory = nv50_instobj(memory)->ram; + return nvkm_memory_map(memory, offset, vmm, vma, argv, argc); } static void @@ -280,19 +279,19 @@ nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vmm *vmm) static u64 nv50_instobj_size(struct nvkm_memory *memory) { - return (u64)nv50_instobj(memory)->mem->size << NVKM_RAM_MM_SHIFT; + return nvkm_memory_size(nv50_instobj(memory)->ram); } static u64 nv50_instobj_addr(struct nvkm_memory *memory) { - return nv50_instobj(memory)->mem->offset; + return nvkm_memory_addr(nv50_instobj(memory)->ram); } static enum nvkm_memory_target nv50_instobj_target(struct nvkm_memory *memory) { - return NVKM_MEM_TARGET_VRAM; + return nvkm_memory_target(nv50_instobj(memory)->ram); } static void * @@ -300,7 +299,6 @@ nv50_instobj_dtor(struct nvkm_memory *memory) { struct nv50_instobj *iobj = nv50_instobj(memory); struct nvkm_instmem *imem = &iobj->imem->base; - struct nvkm_ram *ram = imem->subdev.device->fb->ram; struct nvkm_vma bar; void *map = map; @@ -316,7 +314,7 @@ nv50_instobj_dtor(struct nvkm_memory *memory) nvkm_vm_put(&bar); } - ram->func->put(ram, &iobj->mem); + nvkm_memory_unref(&iobj->ram); nvkm_instobj_dtor(imem, &iobj->base); return iobj; } @@ -339,8 +337,8 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, { struct nv50_instmem *imem = nv50_instmem(base); struct nv50_instobj *iobj; - struct nvkm_ram *ram = imem->base.subdev.device->fb->ram; - int ret; + struct nvkm_device *device = imem->base.subdev.device; + u8 page = max(order_base_2(align), 12); if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) return -ENOMEM; @@ -351,14 +349,7 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, refcount_set(&iobj->maps, 0); INIT_LIST_HEAD(&iobj->lru); - size = max((size + 4095) & ~4095, (u32)4096); - align = max((align + 4095) & ~4095, (u32)4096); - - ret = ram->func->get(ram, size, align, 0, 0x800, &iobj->mem); - if (ret) - return ret; - - return 0; + return nvkm_ram_get(device, 0, 1, page, size, true, true, &iobj->ram); } /****************************************************************************** -- cgit v1.2.3 From bd447053b33d9c2a173e1d3953c95a7cd5182656 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/ltc/gf100-: allocate tagram with nvkm_ram_get() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c | 5 ++--- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c | 11 ++++++----- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h index 0e2751bbf153..784661ae7e98 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h @@ -14,7 +14,7 @@ struct nvkm_ltc { u32 num_tags; u32 tag_base; - struct nvkm_mm_node *tag_ram; + struct nvkm_memory *tag_ram; int zbc_min; int zbc_max; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index f4aa81dd8978..3bb97b171435 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -23,6 +23,7 @@ */ #include "priv.h" +#include #include int @@ -119,9 +120,7 @@ static void * nvkm_ltc_dtor(struct nvkm_subdev *subdev) { struct nvkm_ltc *ltc = nvkm_ltc(subdev); - struct nvkm_ram *ram = ltc->subdev.device->fb->ram; - if (ram) - nvkm_mm_free(&ram->vram, <c->tag_ram); + nvkm_memory_unref(<c->tag_ram); return ltc; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c index 60a5e9e2b264..59acf568faeb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c @@ -23,6 +23,7 @@ */ #include "priv.h" +#include #include #include @@ -152,7 +153,8 @@ gf100_ltc_flush(struct nvkm_ltc *ltc) int gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) { - struct nvkm_fb *fb = ltc->subdev.device->fb; + struct nvkm_device *device = ltc->subdev.device; + struct nvkm_fb *fb = device->fb; struct nvkm_ram *ram = fb->ram; u32 tag_size, tag_margin, tag_align; int ret; @@ -182,14 +184,13 @@ gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) */ tag_size = (ltc->num_tags / 64) * 0x6000 + tag_margin; tag_size += tag_align; - tag_size = (tag_size + 0xfff) >> 12; /* round up */ - ret = nvkm_mm_tail(&ram->vram, NVKM_RAM_MM_NORMAL, 1, tag_size, - tag_size, 1, <c->tag_ram); + ret = nvkm_ram_get(device, NVKM_RAM_MM_NORMAL, 0x01, 12, tag_size, + true, true, <c->tag_ram); if (ret) { ltc->num_tags = 0; } else { - u64 tag_base = ((u64)ltc->tag_ram->offset << 12) + tag_margin; + u64 tag_base = nvkm_memory_addr(ltc->tag_ram) + tag_margin; tag_base += tag_align - 1; do_div(tag_base, tag_align); -- cgit v1.2.3 From bd275f1d1a982db62edcd22f3aebf6253583ea37 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: wrap nvkm_mem objects in nvkm_memory interfaces This is a transition step, to enable finer-grained commits while transitioning to new MMU interfaces. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 3 ++ drivers/gpu/drm/nouveau/nouveau_mem.c | 33 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_mem.h | 7 +++++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 9 ++++++ 5 files changed, 53 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 942d67174005..9242248a8e88 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -1,6 +1,7 @@ #ifndef __NVKM_FB_H__ #define __NVKM_FB_H__ #include +#include #include @@ -29,6 +30,8 @@ struct nvkm_mem { u64 offset; u64 size; struct sg_table *sg; + + struct nvkm_memory *memory; }; struct nvkm_fb_tile { diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 68ac332841ae..501f72fbb838 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -66,6 +66,7 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) else mem->__mem.pages = tt->dma_address; mem->_mem = &mem->__mem; mem->mem.page = 12; + mem->_mem->memory = &mem->memory; return 0; } @@ -78,6 +79,7 @@ nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) int ret; mem->mem.page = page; + mem->_mem->memory = &mem->memory; ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page, (mem->comp << 8) | mem->kind, &mem->_mem); @@ -97,6 +99,36 @@ nouveau_mem_del(struct ttm_mem_reg *reg) reg->mm_node = NULL; } +static enum nvkm_memory_target +nouveau_mem_memory_target(struct nvkm_memory *memory) +{ + struct nouveau_mem *mem = container_of(memory, typeof(*mem), memory); + if (mem->_mem->mem) + return NVKM_MEM_TARGET_VRAM; + return NVKM_MEM_TARGET_HOST; +}; + +static u8 +nouveau_mem_memory_page(struct nvkm_memory *memory) +{ + struct nouveau_mem *mem = container_of(memory, typeof(*mem), memory); + return mem->mem.page; +}; + +static u64 +nouveau_mem_memory_size(struct nvkm_memory *memory) +{ + struct nouveau_mem *mem = container_of(memory, typeof(*mem), memory); + return mem->_mem->size << 12; +} + +static const struct nvkm_memory_func +nouveau_mem_memory = { + .target = nouveau_mem_memory_target, + .page = nouveau_mem_memory_page, + .size = nouveau_mem_memory_size, +}; + int nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp, struct ttm_mem_reg *reg) @@ -108,6 +140,7 @@ nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp, mem->cli = cli; mem->kind = kind; mem->comp = comp; + nvkm_memory_ctor(&nouveau_mem_memory, &mem->memory); reg->mm_node = mem; return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h index d00b4f669c4b..20930ebc5e21 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.h +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -23,6 +23,13 @@ struct nouveau_mem { struct nvkm_mem __mem; struct nvkm_mem *_mem; struct nvkm_vma bar_vma; + + struct nvkm_memory memory; +}; + +enum nvif_vmm_get { + PTES, + LAZY, }; int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 8d17644c1823..03a860ae75b1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -41,6 +41,7 @@ nvkm_vram_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, struct nvkm_vram *vram = nvkm_vram(memory); struct nvkm_mem mem = { .mem = vram->mn, + .memory = &vram->memory, }; nvkm_vm_map_at(vma, offset, &mem); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 73a9511c3101..816d1231df5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -119,6 +119,12 @@ gk20a_instobj_target(struct nvkm_memory *memory) return NVKM_MEM_TARGET_NCOH; } +static u8 +gk20a_instobj_page(struct nvkm_memory *memory) +{ + return 12; +} + static u64 gk20a_instobj_addr(struct nvkm_memory *memory) { @@ -343,6 +349,7 @@ static const struct nvkm_memory_func gk20a_instobj_func_dma = { .dtor = gk20a_instobj_dtor_dma, .target = gk20a_instobj_target, + .page = gk20a_instobj_page, .addr = gk20a_instobj_addr, .size = gk20a_instobj_size, .acquire = gk20a_instobj_acquire_dma, @@ -354,6 +361,7 @@ static const struct nvkm_memory_func gk20a_instobj_func_iommu = { .dtor = gk20a_instobj_dtor_iommu, .target = gk20a_instobj_target, + .page = gk20a_instobj_page, .addr = gk20a_instobj_addr, .size = gk20a_instobj_size, .acquire = gk20a_instobj_acquire_iommu, @@ -531,6 +539,7 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, /* present memory for being mapped using small pages */ node->mem.size = size >> 12; node->mem.memtype = 0; + node->mem.memory = &node->memory; nvkm_debug(subdev, "alloc size: 0x%x, align: 0x%x, gaddr: 0x%llx\n", size, align, node->mem.offset); -- cgit v1.2.3 From 7b8656636add64ea5c184a5de4a326d33a1d021e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: directly handle comptag allocation Another transition step to allow finer-grained patches transitioning to new MMU backends. Old backends will continue operate as before (accessing nvkm_mem::tag), and new backends will get a reference to the tags allocated here. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h | 2 -- drivers/gpu/drm/nouveau/nouveau_mem.c | 38 +++++++++++++++++++++-- drivers/gpu/drm/nouveau/nouveau_mem.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 20 ------------ drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 15 --------- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c | 18 ----------- 6 files changed, 37 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h index 784661ae7e98..4a224fd22e48 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h @@ -22,8 +22,6 @@ struct nvkm_ltc { u32 zbc_depth[NVKM_LTC_MAX_ZBC_CNT]; }; -int nvkm_ltc_tags_alloc(struct nvkm_ltc *, u32 count, struct nvkm_mm_node **); -void nvkm_ltc_tags_free(struct nvkm_ltc *, struct nvkm_mm_node **); void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count); int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 501f72fbb838..291f1a08da33 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -23,6 +23,8 @@ #include "nouveau_drv.h" #include "nouveau_bo.h" +#include + #include int @@ -44,6 +46,8 @@ nouveau_mem_fini(struct nouveau_mem *mem) nvkm_vm_unmap(&mem->vma[0]); nvkm_vm_put(&mem->vma[0]); } + nvkm_memory_tags_put(&mem->memory, nvxx_device(&mem->cli->device), + &mem->tags); } int @@ -74,17 +78,47 @@ int nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) { struct nouveau_mem *mem = nouveau_mem(reg); - struct nvkm_ram *ram = nvxx_fb(&mem->cli->device)->ram; + struct nouveau_cli *cli = mem->cli; + struct nvkm_device *device = nvxx_device(&cli->device); + struct nvkm_ram *ram = nvxx_fb(&cli->device)->ram; u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page); int ret; mem->mem.page = page; mem->_mem->memory = &mem->memory; + if (cli->device.info.chipset < 0xc0 && mem->comp) { + if (page == 16) { + ret = nvkm_memory_tags_get(mem->_mem->memory, device, + size >> page, NULL, + &mem->tags); + WARN_ON(ret); + } + if (!mem->tags || !mem->tags->mn) + mem->comp = 0; + } else + if (cli->device.info.chipset >= 0xc0 && + gf100_pte_storage_type_map[mem->kind] != mem->kind) { + if (page == 17) { + ret = nvkm_memory_tags_get(mem->_mem->memory, device, + size >> page, + nvkm_ltc_tags_clear, + &mem->tags); + WARN_ON(ret); + } + if (!mem->tags || !mem->tags->mn) + mem->kind = gf100_pte_storage_type_map[mem->kind]; + } + ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page, (mem->comp << 8) | mem->kind, &mem->_mem); - if (ret) + if (ret) { + nvkm_memory_tags_put(mem->_mem->memory, device, &mem->tags); return ret; + } + + if (mem->tags && mem->tags->mn) + mem->_mem->tag = mem->tags->mn; reg->start = mem->_mem->offset >> PAGE_SHIFT; return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h index 20930ebc5e21..89e9e7b9b00c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.h +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -25,6 +25,7 @@ struct nouveau_mem { struct nvkm_vma bar_vma; struct nvkm_memory memory; + struct nvkm_tags *tags; }; enum nvif_vmm_get { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index 7109e21f4564..f0bbbbd18cbd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -32,7 +32,6 @@ #include #include #include -#include struct gf100_ramfuc { struct ramfuc base; @@ -423,7 +422,6 @@ gf100_ram_tidy(struct nvkm_ram *base) void gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem) { - struct nvkm_ltc *ltc = ram->fb->subdev.device->ltc; struct nvkm_mem *mem = *pmem; *pmem = NULL; @@ -431,8 +429,6 @@ gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem) return; mutex_lock(&ram->fb->subdev.mutex); - if (mem->tag) - nvkm_ltc_tags_free(ltc, &mem->tag); __nv50_ram_put(ram, mem); mutex_unlock(&ram->fb->subdev.mutex); @@ -443,14 +439,11 @@ int gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, u32 memtype, struct nvkm_mem **pmem) { - struct nvkm_device *device = ram->fb->subdev.device; - struct nvkm_ltc *ltc = ram->fb->subdev.device->ltc; struct nvkm_mm *mm = &ram->vram; struct nvkm_mm_node **node, *r; struct nvkm_mem *mem; int type = (memtype & 0x0ff); int back = (memtype & 0x800); - const bool comp = gf100_pte_storage_type_map[type] != type; int ret; size >>= NVKM_RAM_MM_SHIFT; @@ -466,19 +459,6 @@ gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, mem->size = size; mutex_lock(&ram->fb->subdev.mutex); - if (comp) { - /* compression only works with lpages */ - if (align == (1 << (17 - NVKM_RAM_MM_SHIFT))) { - int n = size >> 5; - if (!nvkm_ltc_tags_alloc(ltc, n, &mem->tag)) { - nvkm_ltc_tags_clear(device, mem->tag->offset, - mem->tag->length); - } - } - - if (unlikely(!mem->tag)) - type = gf100_pte_storage_type_map[type]; - } mem->memtype = type; node = &mem->mem; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index 030ac8339f49..79312205b0e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -502,7 +502,6 @@ __nv50_ram_put(struct nvkm_ram *ram, struct nvkm_mem *mem) next = node->next; nvkm_mm_free(&ram->vram, &node); } - nvkm_mm_free(&ram->fb->tags, &mem->tag); } void @@ -526,7 +525,6 @@ nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, u32 memtype, struct nvkm_mem **pmem) { struct nvkm_mm *heap = &ram->vram; - struct nvkm_mm *tags = &ram->fb->tags; struct nvkm_mm_node **node, *r; struct nvkm_mem *mem; int comp = (memtype & 0x300) >> 8; @@ -543,19 +541,6 @@ nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, return -ENOMEM; mutex_lock(&ram->fb->subdev.mutex); - if (comp) { - if (align == (1 << (16 - NVKM_RAM_MM_SHIFT))) { - int n = (max >> 4) * comp; - - ret = nvkm_mm_head(tags, 0, 1, n, n, 1, &mem->tag); - if (ret) - mem->tag = NULL; - } - - if (unlikely(!mem->tag)) - comp = 0; - } - mem->memtype = (comp << 7) | type; mem->size = max; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index 3bb97b171435..1f185274d3e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -24,24 +24,6 @@ #include "priv.h" #include -#include - -int -nvkm_ltc_tags_alloc(struct nvkm_ltc *ltc, u32 n, struct nvkm_mm_node **pnode) -{ - struct nvkm_fb *fb = ltc->subdev.device->fb; - int ret = nvkm_mm_head(&fb->tags, 0, 1, n, n, 1, pnode); - if (ret) - *pnode = NULL; - return ret; -} - -void -nvkm_ltc_tags_free(struct nvkm_ltc *ltc, struct nvkm_mm_node **pnode) -{ - struct nvkm_fb *fb = ltc->subdev.device->fb; - nvkm_mm_free(&fb->tags, pnode); -} void nvkm_ltc_tags_clear(struct nvkm_device *device, u32 first, u32 count) -- cgit v1.2.3 From 1de3377555f14495c49c935810c220f014dbef71 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: allocate vram with nvkm_ram_get() This will cause a subtle behaviour change on GPUs that are in mixed-memory configurations in that VRAM in the degraded section of VRAM will no longer be used for TTM buffer objects. That section of VRAM is not meant to be used for displayable/compressed surfaces, and we have no reliable way with the current interfaces to be able to make that decision properly. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_mem.c | 39 +++++++++++++++++++++++++++-------- drivers/gpu/drm/nouveau/nouveau_ttm.c | 6 ++---- 2 files changed, 32 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 291f1a08da33..21d904ded441 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -74,18 +74,44 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) return 0; } +#include + +struct nvkm_vram { + struct nvkm_memory memory; + struct nvkm_ram *ram; + u8 page; + struct nvkm_mm_node *mn; +}; + int nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) { struct nouveau_mem *mem = nouveau_mem(reg); struct nouveau_cli *cli = mem->cli; struct nvkm_device *device = nvxx_device(&cli->device); - struct nvkm_ram *ram = nvxx_fb(&cli->device)->ram; u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page); + u8 type; int ret; mem->mem.page = page; - mem->_mem->memory = &mem->memory; + mem->_mem = &mem->__mem; + + if (cli->device.info.chipset < 0xc0) { + type = nv50_fb_memtype[mem->kind]; + } else { + if (!mem->comp) + mem->kind = gf100_pte_storage_type_map[mem->kind]; + mem->comp = 0; + type = 0x01; + } + + ret = nvkm_ram_get(device, NVKM_RAM_MM_NORMAL, type, page, size, + contig, false, &mem->_mem->memory); + if (ret) + return ret; + + mem->_mem->size = size >> NVKM_RAM_MM_SHIFT; + mem->_mem->offset = nvkm_memory_addr(mem->_mem->memory); if (cli->device.info.chipset < 0xc0 && mem->comp) { if (page == 16) { @@ -110,15 +136,10 @@ nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) mem->kind = gf100_pte_storage_type_map[mem->kind]; } - ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page, - (mem->comp << 8) | mem->kind, &mem->_mem); - if (ret) { - nvkm_memory_tags_put(mem->_mem->memory, device, &mem->tags); - return ret; - } - if (mem->tags && mem->tags->mn) mem->_mem->tag = mem->tags->mn; + mem->_mem->mem = ((struct nvkm_vram *)mem->_mem->memory)->mn; + mem->_mem->memtype = (mem->comp << 7) | mem->kind; reg->start = mem->_mem->offset >> PAGE_SHIFT; return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 3bf3b60130e0..8c4f45ea6234 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -60,11 +60,9 @@ static void nouveau_vram_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *reg) { - struct nouveau_drm *drm = nouveau_bdev(man->bdev); - struct nvkm_ram *ram = nvxx_fb(&drm->client.device)->ram; - struct nvkm_mem *mem = nouveau_mem(reg)->_mem; + struct nvkm_memory *memory = nouveau_mem(reg)->_mem->memory; nouveau_mem_del(reg); - ram->func->put(ram, &mem); + nvkm_memory_unref(&memory); } static int -- cgit v1.2.3 From b4e114f1aa6ac1fd7c12223e032ec429be7d8152 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb/ram: remove old allocators Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 4 -- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h | 5 -- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 67 -------------------- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf108.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm200.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 77 ----------------------- 11 files changed, 167 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 9242248a8e88..e1776506746b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -162,10 +162,6 @@ struct nvkm_ram_func { void *(*dtor)(struct nvkm_ram *); int (*init)(struct nvkm_ram *); - int (*get)(struct nvkm_ram *, u64 size, u32 align, u32 size_nc, - u32 type, struct nvkm_mem **); - void (*put)(struct nvkm_ram *, struct nvkm_mem **); - int (*calc)(struct nvkm_ram *, u32 freq); int (*prog)(struct nvkm_ram *); void (*tidy)(struct nvkm_ram *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h index a007699b60a2..70fd59dcd06d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h @@ -13,9 +13,6 @@ extern const struct nvkm_ram_func nv04_ram_func; int nv50_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *, struct nvkm_ram *); -int nv50_ram_get(struct nvkm_ram *, u64, u32, u32, u32, struct nvkm_mem **); -void nv50_ram_put(struct nvkm_ram *, struct nvkm_mem **); -void __nv50_ram_put(struct nvkm_ram *, struct nvkm_mem *); int gf100_ram_new_(const struct nvkm_ram_func *, struct nvkm_fb *, struct nvkm_ram **); @@ -26,8 +23,6 @@ u32 gf100_ram_probe_fbp(const struct nvkm_ram_func *, u32 gf100_ram_probe_fbp_amount(const struct nvkm_ram_func *, u32, struct nvkm_device *, int, int *); u32 gf100_ram_probe_fbpa_amount(struct nvkm_device *, int); -int gf100_ram_get(struct nvkm_ram *, u64, u32, u32, u32, struct nvkm_mem **); -void gf100_ram_put(struct nvkm_ram *, struct nvkm_mem **); int gf100_ram_init(struct nvkm_ram *); int gf100_ram_calc(struct nvkm_ram *, u32); int gf100_ram_prog(struct nvkm_ram *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index f0bbbbd18cbd..ac87a3b6b7c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -419,71 +419,6 @@ gf100_ram_tidy(struct nvkm_ram *base) ram_exec(&ram->fuc, false); } -void -gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem) -{ - struct nvkm_mem *mem = *pmem; - - *pmem = NULL; - if (unlikely(mem == NULL)) - return; - - mutex_lock(&ram->fb->subdev.mutex); - __nv50_ram_put(ram, mem); - mutex_unlock(&ram->fb->subdev.mutex); - - kfree(mem); -} - -int -gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, - u32 memtype, struct nvkm_mem **pmem) -{ - struct nvkm_mm *mm = &ram->vram; - struct nvkm_mm_node **node, *r; - struct nvkm_mem *mem; - int type = (memtype & 0x0ff); - int back = (memtype & 0x800); - int ret; - - size >>= NVKM_RAM_MM_SHIFT; - align >>= NVKM_RAM_MM_SHIFT; - ncmin >>= NVKM_RAM_MM_SHIFT; - if (!ncmin) - ncmin = size; - - mem = kzalloc(sizeof(*mem), GFP_KERNEL); - if (!mem) - return -ENOMEM; - - mem->size = size; - - mutex_lock(&ram->fb->subdev.mutex); - mem->memtype = type; - - node = &mem->mem; - do { - if (back) - ret = nvkm_mm_tail(mm, 0, 1, size, ncmin, align, &r); - else - ret = nvkm_mm_head(mm, 0, 1, size, ncmin, align, &r); - if (ret) { - mutex_unlock(&ram->fb->subdev.mutex); - ram->func->put(ram, &mem); - return ret; - } - - *node = r; - node = &r->next; - size -= r->length; - } while (size); - mutex_unlock(&ram->fb->subdev.mutex); - - mem->offset = (u64)mem->mem->offset << NVKM_RAM_MM_SHIFT; - *pmem = mem; - return 0; -} - int gf100_ram_init(struct nvkm_ram *base) { @@ -725,8 +660,6 @@ gf100_ram = { .probe_fbp_amount = gf100_ram_probe_fbp_amount, .probe_fbpa_amount = gf100_ram_probe_fbpa_amount, .init = gf100_ram_init, - .get = gf100_ram_get, - .put = gf100_ram_put, .calc = gf100_ram_calc, .prog = gf100_ram_prog, .tidy = gf100_ram_tidy, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf108.c index 985ec64cf369..70a06e3cd55a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf108.c @@ -48,8 +48,6 @@ gf108_ram = { .probe_fbp_amount = gf108_ram_probe_fbp_amount, .probe_fbpa_amount = gf100_ram_probe_fbpa_amount, .init = gf100_ram_init, - .get = gf100_ram_get, - .put = gf100_ram_put, .calc = gf100_ram_calc, .prog = gf100_ram_prog, .tidy = gf100_ram_tidy, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c index 75814f15eb53..8bcb7e79a0cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c @@ -1704,8 +1704,6 @@ gk104_ram = { .probe_fbpa_amount = gf100_ram_probe_fbpa_amount, .dtor = gk104_ram_dtor, .init = gk104_ram_init, - .get = gf100_ram_get, - .put = gf100_ram_put, .calc = gk104_ram_calc, .prog = gk104_ram_prog, .tidy = gk104_ram_tidy, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c index 3f0b56347291..27c68e3f9772 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c @@ -39,8 +39,6 @@ gm107_ram = { .probe_fbpa_amount = gf100_ram_probe_fbpa_amount, .dtor = gk104_ram_dtor, .init = gk104_ram_init, - .get = gf100_ram_get, - .put = gf100_ram_put, .calc = gk104_ram_calc, .prog = gk104_ram_prog, .tidy = gk104_ram_tidy, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm200.c index fd8facf90476..6b0cac1fe7b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm200.c @@ -54,8 +54,6 @@ gm200_ram = { .probe_fbpa_amount = gf100_ram_probe_fbpa_amount, .dtor = gk104_ram_dtor, .init = gk104_ram_init, - .get = gf100_ram_get, - .put = gf100_ram_put, .calc = gk104_ram_calc, .prog = gk104_ram_prog, .tidy = gk104_ram_tidy, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c index df8a87333b67..adb62a6beb63 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c @@ -84,8 +84,6 @@ gp100_ram = { .probe_fbp_amount = gm200_ram_probe_fbp_amount, .probe_fbpa_amount = gp100_ram_probe_fbpa, .init = gp100_ram_init, - .get = gf100_ram_get, - .put = gf100_ram_put, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c index 9bace6c4ad0b..920b3d347803 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c @@ -931,8 +931,6 @@ static const struct nvkm_ram_func gt215_ram_func = { .dtor = gt215_ram_dtor, .init = gt215_ram_init, - .get = nv50_ram_get, - .put = nv50_ram_put, .calc = gt215_ram_calc, .prog = gt215_ram_prog, .tidy = gt215_ram_tidy, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c index 76fa71f0c457..7de18e53ef45 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c @@ -53,8 +53,6 @@ mcp77_ram_init(struct nvkm_ram *base) static const struct nvkm_ram_func mcp77_ram_func = { .init = mcp77_ram_init, - .get = nv50_ram_get, - .put = nv50_ram_put, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index 79312205b0e4..2ccb4b6be153 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -493,85 +493,8 @@ nv50_ram_tidy(struct nvkm_ram *base) ram_exec(&ram->hwsq, false); } -void -__nv50_ram_put(struct nvkm_ram *ram, struct nvkm_mem *mem) -{ - struct nvkm_mm_node *next = mem->mem; - struct nvkm_mm_node *node; - while ((node = next)) { - next = node->next; - nvkm_mm_free(&ram->vram, &node); - } -} - -void -nv50_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem) -{ - struct nvkm_mem *mem = *pmem; - - *pmem = NULL; - if (unlikely(mem == NULL)) - return; - - mutex_lock(&ram->fb->subdev.mutex); - __nv50_ram_put(ram, mem); - mutex_unlock(&ram->fb->subdev.mutex); - - kfree(mem); -} - -int -nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin, - u32 memtype, struct nvkm_mem **pmem) -{ - struct nvkm_mm *heap = &ram->vram; - struct nvkm_mm_node **node, *r; - struct nvkm_mem *mem; - int comp = (memtype & 0x300) >> 8; - int type = (memtype & 0x07f); - int back = (memtype & 0x800); - int min, max, ret; - - max = (size >> NVKM_RAM_MM_SHIFT); - min = ncmin ? (ncmin >> NVKM_RAM_MM_SHIFT) : max; - align >>= NVKM_RAM_MM_SHIFT; - - mem = kzalloc(sizeof(*mem), GFP_KERNEL); - if (!mem) - return -ENOMEM; - - mutex_lock(&ram->fb->subdev.mutex); - mem->memtype = (comp << 7) | type; - mem->size = max; - - type = nv50_fb_memtype[type]; - node = &mem->mem; - do { - if (back) - ret = nvkm_mm_tail(heap, 0, type, max, min, align, &r); - else - ret = nvkm_mm_head(heap, 0, type, max, min, align, &r); - if (ret) { - mutex_unlock(&ram->fb->subdev.mutex); - ram->func->put(ram, &mem); - return ret; - } - - *node = r; - node = &r->next; - max -= r->length; - } while (max); - mutex_unlock(&ram->fb->subdev.mutex); - - mem->offset = (u64)mem->mem->offset << NVKM_RAM_MM_SHIFT; - *pmem = mem; - return 0; -} - static const struct nvkm_ram_func nv50_ram_func = { - .get = nv50_ram_get, - .put = nv50_ram_put, .calc = nv50_ram_calc, .prog = nv50_ram_prog, .tidy = nv50_ram_tidy, -- cgit v1.2.3 From 0f43715fac003613a028d28a2c76fbab4c9f9177 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/g84: fork from nv50 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 26 +++++++------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 43 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 12 +++---- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 10 ++++++ 6 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 549a8782ce35..c1cc42fd6893 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -67,5 +67,6 @@ int nv04_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int nv41_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int nv44_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int nv50_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int g84_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gf100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 77fe1c145498..f90b9a9d22db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -927,7 +927,7 @@ nv84_chipset = { .i2c = nv50_i2c_new, .imem = nv50_instmem_new, .mc = g84_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g84_pci_new, .therm = g84_therm_new, @@ -959,7 +959,7 @@ nv86_chipset = { .i2c = nv50_i2c_new, .imem = nv50_instmem_new, .mc = g84_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g84_pci_new, .therm = g84_therm_new, @@ -991,7 +991,7 @@ nv92_chipset = { .i2c = nv50_i2c_new, .imem = nv50_instmem_new, .mc = g84_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g92_pci_new, .therm = g84_therm_new, @@ -1023,7 +1023,7 @@ nv94_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = g84_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .therm = g84_therm_new, @@ -1055,7 +1055,7 @@ nv96_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = g84_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .therm = g84_therm_new, @@ -1087,7 +1087,7 @@ nv98_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = g98_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .therm = g84_therm_new, @@ -1119,7 +1119,7 @@ nva0_chipset = { .i2c = nv50_i2c_new, .imem = nv50_instmem_new, .mc = g84_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .therm = g84_therm_new, @@ -1151,7 +1151,7 @@ nva3_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = gt215_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .pmu = gt215_pmu_new, @@ -1185,7 +1185,7 @@ nva5_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = gt215_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .pmu = gt215_pmu_new, @@ -1218,7 +1218,7 @@ nva8_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = gt215_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .pmu = gt215_pmu_new, @@ -1251,7 +1251,7 @@ nvaa_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = g98_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .therm = g84_therm_new, @@ -1283,7 +1283,7 @@ nvac_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = g98_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .therm = g84_therm_new, @@ -1315,7 +1315,7 @@ nvaf_chipset = { .i2c = g94_i2c_new, .imem = nv50_instmem_new, .mc = gt215_mc_new, - .mmu = nv50_mmu_new, + .mmu = g84_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, .pmu = gt215_pmu_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 012c9db687b2..2c0db24202d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -3,4 +3,5 @@ nvkm-y += nvkm/subdev/mmu/nv04.o nvkm-y += nvkm/subdev/mmu/nv41.o nvkm-y += nvkm/subdev/mmu/nv44.o nvkm-y += nvkm/subdev/mmu/nv50.o +nvkm-y += nvkm/subdev/mmu/g84.o nvkm-y += nvkm/subdev/mmu/gf100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c new file mode 100644 index 000000000000..a1aca162a8cf --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +static const struct nvkm_mmu_func +g84_mmu = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 29 - 12, + .spg_shift = 12, + .lpg_shift = 16, + .create = nv50_vm_create, + .map_pgt = nv50_vm_map_pgt, + .map = nv50_vm_map, + .map_sg = nv50_vm_map_sg, + .unmap = nv50_vm_unmap, + .flush = nv50_vm_flush, +}; + +int +g84_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&g84_mmu, device, index, pmmu); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index a1f8d65f0276..5811516c9a26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -28,7 +28,7 @@ #include #include -static void +void nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]) { u64 phys = 0xdeadcafe00000000ULL; @@ -73,7 +73,7 @@ vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target) return phys; } -static void +void nv50_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) { @@ -123,7 +123,7 @@ nv50_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, nvkm_done(pgt); } -static void +void nv50_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) { @@ -139,7 +139,7 @@ nv50_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, nvkm_done(pgt); } -static void +void nv50_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) { pte <<= 3; @@ -152,7 +152,7 @@ nv50_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) nvkm_done(pgt); } -static void +void nv50_vm_flush(struct nvkm_vm *vm) { struct nvkm_mmu *mmu = vm->mmu; @@ -198,7 +198,7 @@ nv50_vm_flush(struct nvkm_vm *vm) mutex_unlock(&subdev->mutex); } -static int +int nv50_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, struct lock_class_key *key, struct nvkm_vm **pvm) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 27cedc60b507..1e5ef934c4e7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -36,4 +36,14 @@ struct nvkm_mmu_func { int nvkm_vm_create(struct nvkm_mmu *, u64, u64, u64, u32, struct lock_class_key *, struct nvkm_vm **); + +int nv50_vm_create(struct nvkm_mmu *, u64, u64, u64, struct lock_class_key *, + struct nvkm_vm **); +void nv50_vm_map_pgt(struct nvkm_gpuobj *, u32, struct nvkm_memory **); +void nv50_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, + u32, u32, u64, u64); +void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, + u32, u32, dma_addr_t *); +void nv50_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); +void nv50_vm_flush(struct nvkm_vm *); #endif -- cgit v1.2.3 From db018585a51a08fd80ade568ada7b985abcbaf6e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gk104: fork from gf100 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 18 +++++----- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 12 +++---- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 43 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 10 ++++++ 6 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index c1cc42fd6893..c57263437f26 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -69,4 +69,5 @@ int nv44_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int nv50_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int g84_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gf100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int gk104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index f90b9a9d22db..81a2bc4e57cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -1678,7 +1678,7 @@ nve4_chipset = { .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gk104_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk104_pmu_new, @@ -1717,7 +1717,7 @@ nve6_chipset = { .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gk104_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk104_pmu_new, @@ -1756,7 +1756,7 @@ nve7_chipset = { .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gk104_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk104_pmu_new, @@ -1820,7 +1820,7 @@ nvf0_chipset = { .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gk104_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk110_pmu_new, @@ -1858,7 +1858,7 @@ nvf1_chipset = { .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gk104_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk110_pmu_new, @@ -1896,7 +1896,7 @@ nv106_chipset = { .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk208_pmu_new, @@ -1934,7 +1934,7 @@ nv108_chipset = { .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk208_pmu_new, @@ -1972,7 +1972,7 @@ nv117_chipset = { .imem = nv50_instmem_new, .ltc = gm107_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, @@ -2006,7 +2006,7 @@ nv118_chipset = { .imem = nv50_instmem_new, .ltc = gm107_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk104_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 2c0db24202d1..f1bef6b6400a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -5,3 +5,4 @@ nvkm-y += nvkm/subdev/mmu/nv44.o nvkm-y += nvkm/subdev/mmu/nv50.o nvkm-y += nvkm/subdev/mmu/g84.o nvkm-y += nvkm/subdev/mmu/gf100.o +nvkm-y += nvkm/subdev/mmu/gk104.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index cda5b0997c8f..3cc1013538c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -68,7 +68,7 @@ const u8 gf100_pte_storage_type_map[256] = }; -static void +void gf100_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 index, struct nvkm_memory *pgt[2]) { u32 pde[2] = { 0, 0 }; @@ -98,7 +98,7 @@ gf100_vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target) return phys; } -static void +void gf100_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) { @@ -123,7 +123,7 @@ gf100_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, nvkm_done(pgt); } -static void +void gf100_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) { @@ -142,7 +142,7 @@ gf100_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, nvkm_done(pgt); } -static void +void gf100_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) { nvkm_kmap(pgt); @@ -155,7 +155,7 @@ gf100_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) nvkm_done(pgt); } -static void +void gf100_vm_flush(struct nvkm_vm *vm) { struct nvkm_mmu *mmu = vm->mmu; @@ -189,7 +189,7 @@ gf100_vm_flush(struct nvkm_vm *vm) mutex_unlock(&mmu->subdev.mutex); } -static int +int gf100_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, struct lock_class_key *key, struct nvkm_vm **pvm) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c new file mode 100644 index 000000000000..6ab8e636feb1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +static const struct nvkm_mmu_func +gk104_mmu = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, +}; + +int +gk104_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&gk104_mmu, device, index, pmmu); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 1e5ef934c4e7..9346dae07c68 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -46,4 +46,14 @@ void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, dma_addr_t *); void nv50_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void nv50_vm_flush(struct nvkm_vm *); + +int gf100_vm_create(struct nvkm_mmu *, u64, u64, u64, struct lock_class_key *, + struct nvkm_vm **); +void gf100_vm_map_pgt(struct nvkm_gpuobj *, u32, struct nvkm_memory **); +void gf100_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, + u32, u32, u64, u64); +void gf100_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, + u32, u32, dma_addr_t *); +void gf100_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); +void gf100_vm_flush(struct nvkm_vm *); #endif -- cgit v1.2.3 From d1f6c8d2e9df49eb7387b04b880d643348e97625 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gk20a: fork from gf100 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 43 +++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index c57263437f26..04b3ac1c2121 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -70,4 +70,5 @@ int nv50_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int g84_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gf100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gk104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int gk20a_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 81a2bc4e57cb..b87f6cf12a69 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -1790,7 +1790,7 @@ nvea_chipset = { .imem = gk20a_instmem_new, .ltc = gk104_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gk20a_mmu_new, .pmu = gk20a_pmu_new, .timer = gk20a_timer_new, .top = gk104_top_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index f1bef6b6400a..dde204c47f70 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -6,3 +6,4 @@ nvkm-y += nvkm/subdev/mmu/nv50.o nvkm-y += nvkm/subdev/mmu/g84.o nvkm-y += nvkm/subdev/mmu/gf100.o nvkm-y += nvkm/subdev/mmu/gk104.o +nvkm-y += nvkm/subdev/mmu/gk20a.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c new file mode 100644 index 000000000000..9ea8a91802be --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +static const struct nvkm_mmu_func +gk20a_mmu = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, +}; + +int +gk20a_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&gk20a_mmu, device, index, pmmu); +} -- cgit v1.2.3 From e1e33c791a233cb4cc84175109e42bdd6467889c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gm200: fork from gf100 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 6 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 43 +++++++++++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 04b3ac1c2121..989fd2897f6d 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -71,4 +71,5 @@ int g84_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gf100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gk104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gk20a_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int gm200_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index b87f6cf12a69..c4cd89a7be70 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2039,7 +2039,7 @@ nv120_chipset = { .imem = nv50_instmem_new, .ltc = gm200_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gm200_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, @@ -2074,7 +2074,7 @@ nv124_chipset = { .imem = nv50_instmem_new, .ltc = gm200_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gm200_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, @@ -2109,7 +2109,7 @@ nv126_chipset = { .imem = nv50_instmem_new, .ltc = gm200_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gm200_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index dde204c47f70..b5b260d2fb88 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -7,3 +7,4 @@ nvkm-y += nvkm/subdev/mmu/g84.o nvkm-y += nvkm/subdev/mmu/gf100.o nvkm-y += nvkm/subdev/mmu/gk104.o nvkm-y += nvkm/subdev/mmu/gk20a.o +nvkm-y += nvkm/subdev/mmu/gm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c new file mode 100644 index 000000000000..4bb342fa3d54 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +static const struct nvkm_mmu_func +gm200_mmu = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, +}; + +int +gm200_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&gm200_mmu, device, index, pmmu); +} -- cgit v1.2.3 From cedc4d57df26170a2f1536cec276c5cc809a2462 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gm20b: fork from gf100 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 43 +++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 989fd2897f6d..805d36b049b8 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -72,4 +72,5 @@ int gf100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gk104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gk20a_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gm200_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index c4cd89a7be70..d99093435c25 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2140,7 +2140,7 @@ nv12b_chipset = { .imem = gk20a_instmem_new, .ltc = gm200_ltc_new, .mc = gk20a_mc_new, - .mmu = gf100_mmu_new, + .mmu = gm20b_mmu_new, .pmu = gm20b_pmu_new, .secboot = gm20b_secboot_new, .timer = gk20a_timer_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index b5b260d2fb88..278041ffc940 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -8,3 +8,4 @@ nvkm-y += nvkm/subdev/mmu/gf100.o nvkm-y += nvkm/subdev/mmu/gk104.o nvkm-y += nvkm/subdev/mmu/gk20a.o nvkm-y += nvkm/subdev/mmu/gm200.o +nvkm-y += nvkm/subdev/mmu/gm20b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c new file mode 100644 index 000000000000..06e49a9c8a9f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +static const struct nvkm_mmu_func +gm20b_mmu = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, +}; + +int +gm20b_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&gm20b_mmu, device, index, pmmu); +} -- cgit v1.2.3 From b86a45877ead1d0235674cae58dac7d07f00fa88 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gp100: fork from gf100 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 12 +++---- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 43 +++++++++++++++++++++++ 4 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 805d36b049b8..87baa5e9691c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -73,4 +73,5 @@ int gk104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gk20a_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gm200_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int gp100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index d99093435c25..e14643615698 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2168,7 +2168,7 @@ nv130_chipset = { .imem = nv50_instmem_new, .ltc = gp100_ltc_new, .mc = gp100_mc_new, - .mmu = gf100_mmu_new, + .mmu = gp100_mmu_new, .therm = gp100_therm_new, .secboot = gm200_secboot_new, .pci = gp100_pci_new, @@ -2203,7 +2203,7 @@ nv132_chipset = { .imem = nv50_instmem_new, .ltc = gp100_ltc_new, .mc = gp100_mc_new, - .mmu = gf100_mmu_new, + .mmu = gp100_mmu_new, .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, @@ -2238,7 +2238,7 @@ nv134_chipset = { .imem = nv50_instmem_new, .ltc = gp100_ltc_new, .mc = gp100_mc_new, - .mmu = gf100_mmu_new, + .mmu = gp100_mmu_new, .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, @@ -2273,7 +2273,7 @@ nv136_chipset = { .imem = nv50_instmem_new, .ltc = gp100_ltc_new, .mc = gp100_mc_new, - .mmu = gf100_mmu_new, + .mmu = gp100_mmu_new, .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, @@ -2308,7 +2308,7 @@ nv137_chipset = { .imem = nv50_instmem_new, .ltc = gp100_ltc_new, .mc = gp100_mc_new, - .mmu = gf100_mmu_new, + .mmu = gp100_mmu_new, .therm = gp100_therm_new, .secboot = gp102_secboot_new, .pci = gp100_pci_new, @@ -2343,7 +2343,7 @@ nv138_chipset = { .imem = nv50_instmem_new, .ltc = gp100_ltc_new, .mc = gp100_mc_new, - .mmu = gf100_mmu_new, + .mmu = gp100_mmu_new, .therm = gp100_therm_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 278041ffc940..7d63089aede0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -9,3 +9,4 @@ nvkm-y += nvkm/subdev/mmu/gk104.o nvkm-y += nvkm/subdev/mmu/gk20a.o nvkm-y += nvkm/subdev/mmu/gm200.o nvkm-y += nvkm/subdev/mmu/gm20b.o +nvkm-y += nvkm/subdev/mmu/gp100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c new file mode 100644 index 000000000000..6cfd325ea3a9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +static const struct nvkm_mmu_func +gp100_mmu = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, +}; + +int +gp100_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&gp100_mmu, device, index, pmmu); +} -- cgit v1.2.3 From 6359c982243ee8e4da4ca93cf30ac746a925ea1b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gp10b: fork from gf100 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 43 +++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 87baa5e9691c..6d38e21c5f65 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -74,4 +74,5 @@ int gk20a_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gm200_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gp100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int gp10b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 7d63089aede0..e84ef36eb7e7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -10,3 +10,4 @@ nvkm-y += nvkm/subdev/mmu/gk20a.o nvkm-y += nvkm/subdev/mmu/gm200.o nvkm-y += nvkm/subdev/mmu/gm20b.o nvkm-y += nvkm/subdev/mmu/gp100.o +nvkm-y += nvkm/subdev/mmu/gp10b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c new file mode 100644 index 000000000000..e0a41ce3ddd1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "priv.h" + +static const struct nvkm_mmu_func +gp10b_mmu = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, +}; + +int +gp10b_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&gp10b_mmu, device, index, pmmu); +} -- cgit v1.2.3 From 5e075fdeb166098a3dc493026534c7631e845782 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: automatically handle "un-bootstrapping" of vmm Removes the need to expose internals outside of MMU, and GP100 is both different, and a lot harder to deal with. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 5 +---- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 5 +---- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 3 +++ 4 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 6d38e21c5f65..f26407869e20 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -38,6 +38,8 @@ struct nvkm_vm { struct nvkm_vm_pgt *pgt; u32 fpde; u32 lpde; + + bool bootstrapped; }; int nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 9f7b4e7532b7..8b588d1c776b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -168,10 +168,7 @@ gf100_bar_dtor(struct nvkm_bar *base) nvkm_gpuobj_del(&bar->bar[1].pgd); nvkm_memory_unref(&bar->bar[1].mem); - if (bar->bar[0].vm) { - nvkm_memory_unref(&bar->bar[0].vm->pgt[0].mem[0]); - nvkm_vm_ref(NULL, &bar->bar[0].vm, bar->bar[0].pgd); - } + nvkm_vm_ref(NULL, &bar->bar[0].vm, bar->bar[0].pgd); nvkm_gpuobj_del(&bar->bar[0].pgd); nvkm_memory_unref(&bar->bar[0].mem); return bar; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 1aa6b5390d79..b40c131af20e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -200,10 +200,7 @@ nv50_bar_dtor(struct nvkm_bar *base) nvkm_gpuobj_del(&bar->bar1); nvkm_vm_ref(NULL, &bar->bar1_vm, bar->pgd); nvkm_gpuobj_del(&bar->bar2); - if (bar->bar2_vm) { - nvkm_memory_unref(&bar->bar2_vm->pgt[0].mem[0]); - nvkm_vm_ref(NULL, &bar->bar2_vm, bar->pgd); - } + nvkm_vm_ref(NULL, &bar->bar2_vm, bar->pgd); nvkm_gpuobj_del(&bar->pgd); nvkm_gpuobj_del(&bar->pad); nvkm_gpuobj_del(&bar->mem); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index ad11db458fcc..d9f572db5c29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -357,6 +357,7 @@ nvkm_vm_boot(struct nvkm_vm *vm, u64 size) vm->pgt[0].refcount[0] = 1; vm->pgt[0].mem[0] = pgt; nvkm_memory_boot(pgt, vm); + vm->bootstrapped = true; } return ret; @@ -481,6 +482,8 @@ nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_gpuobj *pgd) } if (*ptr) { + if ((*ptr)->bootstrapped && pgd) + nvkm_memory_unref(&(*ptr)->pgt[0].mem[0]); nvkm_vm_unlink(*ptr, pgd); kref_put(&(*ptr)->refcount, nvkm_vm_del); } -- cgit v1.2.3 From 9a45ddaaa674aa103cd74a0df9a3f9c2c8fb3124 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: implement page table cache Builds up and maintains a small cache of each page table size in order to reduce the frequency of expensive allocations, particularly in the pathological case where an address range ping-pongs between allocated and free. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 5 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 132 +++++++++++++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 15 +++ 3 files changed, 150 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index f26407869e20..61cc4e32e449 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -63,6 +63,11 @@ struct nvkm_mmu { u8 lpg_shift; struct nvkm_vmm *vmm; + + struct { + struct mutex mutex; + struct list_head list; + } ptc; }; int nv04_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index d9f572db5c29..1e4a92e0068e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -26,6 +26,129 @@ #include #include +struct nvkm_mmu_ptc { + struct list_head head; + struct list_head item; + u32 size; + u32 refs; +}; + +static inline struct nvkm_mmu_ptc * +nvkm_mmu_ptc_find(struct nvkm_mmu *mmu, u32 size) +{ + struct nvkm_mmu_ptc *ptc; + + list_for_each_entry(ptc, &mmu->ptc.list, head) { + if (ptc->size == size) + return ptc; + } + + ptc = kmalloc(sizeof(*ptc), GFP_KERNEL); + if (ptc) { + INIT_LIST_HEAD(&ptc->item); + ptc->size = size; + ptc->refs = 0; + list_add(&ptc->head, &mmu->ptc.list); + } + + return ptc; +} + +void +nvkm_mmu_ptc_put(struct nvkm_mmu *mmu, bool force, struct nvkm_mmu_pt **ppt) +{ + struct nvkm_mmu_pt *pt = *ppt; + if (pt) { + /* Either cache or free the object. */ + mutex_lock(&mmu->ptc.mutex); + if (pt->ptc->refs < 8 /* Heuristic. */ && !force) { + list_add_tail(&pt->head, &pt->ptc->item); + pt->ptc->refs++; + } else { + nvkm_memory_unref(&pt->memory); + kfree(pt); + } + mutex_unlock(&mmu->ptc.mutex); + } +} + +struct nvkm_mmu_pt * +nvkm_mmu_ptc_get(struct nvkm_mmu *mmu, u32 size, u32 align, bool zero) +{ + struct nvkm_mmu_ptc *ptc; + struct nvkm_mmu_pt *pt; + int ret; + + /* Lookup cache for this page table size. */ + mutex_lock(&mmu->ptc.mutex); + ptc = nvkm_mmu_ptc_find(mmu, size); + if (!ptc) { + mutex_unlock(&mmu->ptc.mutex); + return NULL; + } + + /* If there's a free PT in the cache, reuse it. */ + pt = list_first_entry_or_null(&ptc->item, typeof(*pt), head); + if (pt) { + if (zero) + nvkm_fo64(pt->memory, 0, 0, size >> 3); + list_del(&pt->head); + ptc->refs--; + mutex_unlock(&mmu->ptc.mutex); + return pt; + } + mutex_unlock(&mmu->ptc.mutex); + + /* No such luck, we need to allocate. */ + if (!(pt = kmalloc(sizeof(*pt), GFP_KERNEL))) + return NULL; + pt->ptc = ptc; + + ret = nvkm_memory_new(mmu->subdev.device, NVKM_MEM_TARGET_INST, + size, align, zero, &pt->memory); + if (ret) { + kfree(pt); + return NULL; + } + + pt->base = 0; + pt->addr = nvkm_memory_addr(pt->memory); + return pt; +} + +void +nvkm_mmu_ptc_dump(struct nvkm_mmu *mmu) +{ + struct nvkm_mmu_ptc *ptc; + list_for_each_entry(ptc, &mmu->ptc.list, head) { + struct nvkm_mmu_pt *pt, *tt; + list_for_each_entry_safe(pt, tt, &ptc->item, head) { + nvkm_memory_unref(&pt->memory); + list_del(&pt->head); + kfree(pt); + } + } +} + +static void +nvkm_mmu_ptc_fini(struct nvkm_mmu *mmu) +{ + struct nvkm_mmu_ptc *ptc, *ptct; + + list_for_each_entry_safe(ptc, ptct, &mmu->ptc.list, head) { + WARN_ON(!list_empty(&ptc->item)); + list_del(&ptc->head); + kfree(ptc); + } +} + +static void +nvkm_mmu_ptc_init(struct nvkm_mmu *mmu) +{ + mutex_init(&mmu->ptc.mutex); + INIT_LIST_HEAD(&mmu->ptc.list); +} + void nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) { @@ -514,9 +637,13 @@ static void * nvkm_mmu_dtor(struct nvkm_subdev *subdev) { struct nvkm_mmu *mmu = nvkm_mmu(subdev); + void *data = mmu; + if (mmu->func->dtor) - return mmu->func->dtor(mmu); - return mmu; + data = mmu->func->dtor(mmu); + + nvkm_mmu_ptc_fini(mmu); + return data; } static const struct nvkm_subdev_func @@ -535,6 +662,7 @@ nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device, mmu->limit = func->limit; mmu->dma_bits = func->dma_bits; mmu->lpg_shift = func->lpg_shift; + nvkm_mmu_ptc_init(mmu); } int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 9346dae07c68..ea56f78c95d4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -56,4 +56,19 @@ void gf100_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, dma_addr_t *); void gf100_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void gf100_vm_flush(struct nvkm_vm *); + +struct nvkm_mmu_pt { + union { + struct nvkm_mmu_ptc *ptc; + }; + struct nvkm_memory *memory; + u16 base; + u64 addr; + struct list_head head; +}; + +void nvkm_mmu_ptc_dump(struct nvkm_mmu *); +struct nvkm_mmu_pt * +nvkm_mmu_ptc_get(struct nvkm_mmu *, u32 size, u32 align, bool zero); +void nvkm_mmu_ptc_put(struct nvkm_mmu *, bool force, struct nvkm_mmu_pt **); #endif -- cgit v1.2.3 From f1280394109a3a3a7ef1c37950d4356b12e75cb9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: implement page table sub-allocation GP100 "big" (which is a funny name, when it supports "even bigger") page tables are small enough that we want to be able to suballocate them from a larger block of memory. This builds on the previous page table cache interfaces so that the VMM code doesn't need to know the difference. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 98 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 2 + 3 files changed, 101 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 61cc4e32e449..40e21f23b41d 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -67,7 +67,7 @@ struct nvkm_mmu { struct { struct mutex mutex; struct list_head list; - } ptc; + } ptc, ptp; }; int nv04_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 1e4a92e0068e..1bdae020057e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -26,6 +26,85 @@ #include #include +struct nvkm_mmu_ptp { + struct nvkm_mmu_pt *pt; + struct list_head head; + u8 shift; + u16 mask; + u16 free; +}; + +static void +nvkm_mmu_ptp_put(struct nvkm_mmu *mmu, bool force, struct nvkm_mmu_pt *pt) +{ + const int slot = pt->base >> pt->ptp->shift; + struct nvkm_mmu_ptp *ptp = pt->ptp; + + /* If there were no free slots in the parent allocation before, + * there will be now, so return PTP to the cache. + */ + if (!ptp->free) + list_add(&ptp->head, &mmu->ptp.list); + ptp->free |= BIT(slot); + + /* If there's no more sub-allocations, destroy PTP. */ + if (ptp->free == ptp->mask) { + nvkm_mmu_ptc_put(mmu, force, &ptp->pt); + list_del(&ptp->head); + kfree(ptp); + } + + kfree(pt); +} + +struct nvkm_mmu_pt * +nvkm_mmu_ptp_get(struct nvkm_mmu *mmu, u32 size, bool zero) +{ + struct nvkm_mmu_pt *pt; + struct nvkm_mmu_ptp *ptp; + int slot; + + if (!(pt = kzalloc(sizeof(*pt), GFP_KERNEL))) + return NULL; + + ptp = list_first_entry_or_null(&mmu->ptp.list, typeof(*ptp), head); + if (!ptp) { + /* Need to allocate a new parent to sub-allocate from. */ + if (!(ptp = kmalloc(sizeof(*ptp), GFP_KERNEL))) { + kfree(pt); + return NULL; + } + + ptp->pt = nvkm_mmu_ptc_get(mmu, 0x1000, 0x1000, false); + if (!ptp->pt) { + kfree(ptp); + kfree(pt); + return NULL; + } + + ptp->shift = order_base_2(size); + slot = nvkm_memory_size(ptp->pt->memory) >> ptp->shift; + ptp->mask = (1 << slot) - 1; + ptp->free = ptp->mask; + list_add(&ptp->head, &mmu->ptp.list); + } + pt->ptp = ptp; + pt->sub = true; + + /* Sub-allocate from parent object, removing PTP from cache + * if there's no more free slots left. + */ + slot = __ffs(ptp->free); + ptp->free &= ~BIT(slot); + if (!ptp->free) + list_del(&ptp->head); + + pt->memory = pt->ptp->pt->memory; + pt->base = slot << ptp->shift; + pt->addr = pt->ptp->pt->addr + pt->base; + return pt; +} + struct nvkm_mmu_ptc { struct list_head head; struct list_head item; @@ -59,6 +138,14 @@ nvkm_mmu_ptc_put(struct nvkm_mmu *mmu, bool force, struct nvkm_mmu_pt **ppt) { struct nvkm_mmu_pt *pt = *ppt; if (pt) { + /* Handle sub-allocated page tables. */ + if (pt->sub) { + mutex_lock(&mmu->ptp.mutex); + nvkm_mmu_ptp_put(mmu, force, pt); + mutex_unlock(&mmu->ptp.mutex); + return; + } + /* Either cache or free the object. */ mutex_lock(&mmu->ptc.mutex); if (pt->ptc->refs < 8 /* Heuristic. */ && !force) { @@ -79,6 +166,14 @@ nvkm_mmu_ptc_get(struct nvkm_mmu *mmu, u32 size, u32 align, bool zero) struct nvkm_mmu_pt *pt; int ret; + /* Sub-allocated page table (ie. GP100 LPT). */ + if (align < 0x1000) { + mutex_lock(&mmu->ptp.mutex); + pt = nvkm_mmu_ptp_get(mmu, align, zero); + mutex_unlock(&mmu->ptp.mutex); + return pt; + } + /* Lookup cache for this page table size. */ mutex_lock(&mmu->ptc.mutex); ptc = nvkm_mmu_ptc_find(mmu, size); @@ -103,6 +198,7 @@ nvkm_mmu_ptc_get(struct nvkm_mmu *mmu, u32 size, u32 align, bool zero) if (!(pt = kmalloc(sizeof(*pt), GFP_KERNEL))) return NULL; pt->ptc = ptc; + pt->sub = false; ret = nvkm_memory_new(mmu->subdev.device, NVKM_MEM_TARGET_INST, size, align, zero, &pt->memory); @@ -147,6 +243,8 @@ nvkm_mmu_ptc_init(struct nvkm_mmu *mmu) { mutex_init(&mmu->ptc.mutex); INIT_LIST_HEAD(&mmu->ptc.list); + mutex_init(&mmu->ptp.mutex); + INIT_LIST_HEAD(&mmu->ptp.list); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index ea56f78c95d4..0f3bb316022a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -60,8 +60,10 @@ void gf100_vm_flush(struct nvkm_vm *); struct nvkm_mmu_pt { union { struct nvkm_mmu_ptc *ptc; + struct nvkm_mmu_ptp *ptp; }; struct nvkm_memory *memory; + bool sub; u16 base; u64 addr; struct list_head head; -- cgit v1.2.3 From 806a7335653743a33f476a3705d55bada95b7dfe Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: implement base for new vm management This is the first chunk of the new VMM code that provides the structures needed to describe a GPU virtual address-space layout, as well as common interfaces to handle VMM creation, and connecting instances to a VMM. The constructor now allocates the PD itself, rather than having the user handle that manually. This won't/can't be used until after all backends have been ported to these interfaces, so a little bit of memory will be wasted on Fermi and newer for a couple of commits in the series. Compatibility has been hacked into the old code to allow each GPU backend to be ported individually. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + drivers/gpu/drm/nouveau/include/nvif/if000c.h | 3 + drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 16 ++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 76 +++++++++-- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 4 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 8 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 147 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 111 ++++++++++++++++ 9 files changed, 350 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if000c.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index d08da82ba7ed..7f0839615b0c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -14,6 +14,8 @@ #define NVIF_CLASS_SW_NV50 /* if0005.h */ -0x00000006 #define NVIF_CLASS_SW_GF100 /* if0005.h */ -0x00000007 +#define NVIF_CLASS_VMM /* if000c.h */ 0x0000000c + /* the below match nvidia-assigned (either in hw, or sw) class numbers */ #define NV_NULL_CLASS 0x00000030 diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000c.h b/drivers/gpu/drm/nouveau/include/nvif/if000c.h new file mode 100644 index 000000000000..6363e22f9dcc --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if000c.h @@ -0,0 +1,3 @@ +#ifndef __NVIF_IF000C_H__ +#define __NVIF_IF000C_H__ +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 40e21f23b41d..8ff71e7f2f5b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -26,20 +26,28 @@ struct nvkm_vma { }; struct nvkm_vm { + const struct nvkm_vmm_func *func; struct nvkm_mmu *mmu; - + const char *name; + struct kref kref; struct mutex mutex; + + u64 start; + u64 limit; + + struct nvkm_vmm_pt *pd; + u16 pd_offset; + struct list_head join; + struct nvkm_mm mm; struct kref refcount; - struct list_head pgd_list; - atomic_t engref[NVKM_SUBDEV_NR]; - struct nvkm_vm_pgt *pgt; u32 fpde; u32 lpde; bool bootstrapped; + atomic_t engref[NVKM_SUBDEV_NR]; }; int nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index e84ef36eb7e7..c786a9f90776 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -11,3 +11,5 @@ nvkm-y += nvkm/subdev/mmu/gm200.o nvkm-y += nvkm/subdev/mmu/gm20b.o nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/gp10b.o + +nvkm-y += nvkm/subdev/mmu/vmm.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 1bdae020057e..d55ec0e85dca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "priv.h" +#include "vmm.h" #include #include @@ -584,22 +585,14 @@ nvkm_vm_boot(struct nvkm_vm *vm, u64 size) return ret; } -int -nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, - u32 block, struct lock_class_key *key, struct nvkm_vm **pvm) +static int +nvkm_vm_legacy(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, + u32 block, struct nvkm_vm *vm) { - static struct lock_class_key _key; - struct nvkm_vm *vm; u64 mm_length = (offset + length) - mm_offset; int ret; - vm = kzalloc(sizeof(*vm), GFP_KERNEL); - if (!vm) - return -ENOMEM; - - __mutex_init(&vm->mutex, "&vm->mutex", key ? key : &_key); INIT_LIST_HEAD(&vm->pgd_list); - vm->mmu = mmu; kref_init(&vm->refcount); vm->fpde = offset >> (mmu->func->pgt_bits + 12); vm->lpde = (offset + length - 1) >> (mmu->func->pgt_bits + 12); @@ -610,16 +603,41 @@ nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, return -ENOMEM; } + if (block > length) + block = length; + ret = nvkm_mm_init(&vm->mm, 0, mm_offset >> 12, mm_length >> 12, block >> 12); if (ret) { vfree(vm->pgt); + return ret; + } + + return 0; +} + +int +nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, + u32 block, struct lock_class_key *key, struct nvkm_vm **pvm) +{ + static struct lock_class_key _key; + struct nvkm_vm *vm; + int ret; + + vm = kzalloc(sizeof(*vm), GFP_KERNEL); + if (!vm) + return -ENOMEM; + + __mutex_init(&vm->mutex, "&vm->mutex", key ? key : &_key); + vm->mmu = mmu; + + ret = nvkm_vm_legacy(mmu, offset, length, mm_offset, block, vm); + if (ret) { kfree(vm); return ret; } *pvm = vm; - return 0; } @@ -628,8 +646,29 @@ nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, struct lock_class_key *key, struct nvkm_vm **pvm) { struct nvkm_mmu *mmu = device->mmu; + + *pvm = NULL; + if (mmu->func->vmm.ctor) { + int ret = mmu->func->vmm.ctor(mmu, mm_offset, + offset + length - mm_offset, + NULL, 0, key, "legacy", pvm); + if (ret) { + nvkm_vm_ref(NULL, pvm, NULL); + return ret; + } + + ret = nvkm_vm_legacy(mmu, offset, length, mm_offset, + (*pvm)->func->page_block ? + (*pvm)->func->page_block : 4096, *pvm); + if (ret) + nvkm_vm_ref(NULL, pvm, NULL); + + return ret; + } + if (!mmu->func->create) return -EINVAL; + return mmu->func->create(mmu, offset, length, mm_offset, key, pvm); } @@ -688,6 +727,9 @@ nvkm_vm_del(struct kref *kref) nvkm_mm_fini(&vm->mm); vfree(vm->pgt); + + if (vm->func) + nvkm_vmm_dtor(vm); kfree(vm); } @@ -717,8 +759,17 @@ static int nvkm_mmu_oneinit(struct nvkm_subdev *subdev) { struct nvkm_mmu *mmu = nvkm_mmu(subdev); + + if (mmu->func->vmm.global) { + int ret = nvkm_vm_new(subdev->device, 0, mmu->limit, 0, + NULL, &mmu->vmm); + if (ret) + return ret; + } + if (mmu->func->oneinit) return mmu->func->oneinit(mmu); + return 0; } @@ -739,6 +790,7 @@ nvkm_mmu_dtor(struct nvkm_subdev *subdev) if (mmu->func->dtor) data = mmu->func->dtor(mmu); + nvkm_vm_ref(NULL, &mmu->vmm, NULL); nvkm_mmu_ptc_fini(mmu); return data; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 43e3b4a77583..5bf757541f7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -105,10 +105,8 @@ nv04_mmu_dtor(struct nvkm_mmu *base) { struct nv04_mmu *mmu = nv04_mmu(base); struct nvkm_device *device = mmu->base.subdev.device; - if (mmu->base.vmm) { + if (mmu->base.vmm) nvkm_memory_unref(&mmu->base.vmm->pgt[0].mem[0]); - nvkm_vm_ref(NULL, &mmu->base.vmm, NULL); - } if (mmu->nullp) { dma_free_coherent(device->dev, 16 * 1024, mmu->nullp, mmu->null); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 0f3bb316022a..ee0a8416df19 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -32,6 +32,14 @@ struct nvkm_mmu_func { void (*unmap)(struct nvkm_vma *, struct nvkm_memory *pgt, u32 pte, u32 cnt); void (*flush)(struct nvkm_vm *); + + struct { + struct nvkm_sclass base; + int (*ctor)(struct nvkm_mmu *, u64 addr, u64 size, + void *argv, u32 argc, struct lock_class_key *, + const char *name, struct nvkm_vmm **); + bool global; + } vmm; }; int nvkm_vm_create(struct nvkm_mmu *, u64, u64, u64, u32, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c new file mode 100644 index 000000000000..93c8398b36a5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -0,0 +1,147 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 NVKM_VMM_LEVELS_MAX 5 +#include "vmm.h" + +static void +nvkm_vmm_pt_del(struct nvkm_vmm_pt **ppgt) +{ + struct nvkm_vmm_pt *pgt = *ppgt; + if (pgt) { + kvfree(pgt->pde); + kfree(pgt); + *ppgt = NULL; + } +} + + +static struct nvkm_vmm_pt * +nvkm_vmm_pt_new(const struct nvkm_vmm_desc *desc, bool sparse, + const struct nvkm_vmm_page *page) +{ + const u32 pten = 1 << desc->bits; + struct nvkm_vmm_pt *pgt; + u32 lpte = 0; + + if (desc->type > PGT) { + if (desc->type == SPT) { + const struct nvkm_vmm_desc *pair = page[-1].desc; + lpte = pten >> (desc->bits - pair->bits); + } else { + lpte = pten; + } + } + + if (!(pgt = kzalloc(sizeof(*pgt) + lpte, GFP_KERNEL))) + return NULL; + pgt->page = page ? page->shift : 0; + pgt->sparse = sparse; + + if (desc->type == PGD) { + pgt->pde = kvzalloc(sizeof(*pgt->pde) * pten, GFP_KERNEL); + if (!pgt->pde) { + kfree(pgt); + return NULL; + } + } + + return pgt; +} + +void +nvkm_vmm_dtor(struct nvkm_vmm *vmm) +{ + if (vmm->pd) { + nvkm_mmu_ptc_put(vmm->mmu, true, &vmm->pd->pt[0]); + nvkm_vmm_pt_del(&vmm->pd); + } +} + +int +nvkm_vmm_ctor(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, + u32 pd_header, u64 addr, u64 size, struct lock_class_key *key, + const char *name, struct nvkm_vmm *vmm) +{ + static struct lock_class_key _key; + const struct nvkm_vmm_page *page = func->page; + const struct nvkm_vmm_desc *desc; + int levels, bits = 0; + + vmm->func = func; + vmm->mmu = mmu; + vmm->name = name; + kref_init(&vmm->kref); + + __mutex_init(&vmm->mutex, "&vmm->mutex", key ? key : &_key); + + /* Locate the smallest page size supported by the backend, it will + * have the the deepest nesting of page tables. + */ + while (page[1].shift) + page++; + + /* Locate the structure that describes the layout of the top-level + * page table, and determine the number of valid bits in a virtual + * address. + */ + for (levels = 0, desc = page->desc; desc->bits; desc++, levels++) + bits += desc->bits; + bits += page->shift; + desc--; + + if (WARN_ON(levels > NVKM_VMM_LEVELS_MAX)) + return -EINVAL; + + vmm->start = addr; + vmm->limit = size ? (addr + size) : (1ULL << bits); + if (vmm->start > vmm->limit || vmm->limit > (1ULL << bits)) + return -EINVAL; + + /* Allocate top-level page table. */ + vmm->pd = nvkm_vmm_pt_new(desc, false, NULL); + if (!vmm->pd) + return -ENOMEM; + vmm->pd->refs[0] = 1; + INIT_LIST_HEAD(&vmm->join); + + /* ... and the GPU storage for it, except on Tesla-class GPUs that + * have the PD embedded in the instance structure. + */ + if (desc->size && mmu->func->vmm.global) { + const u32 size = pd_header + desc->size * (1 << desc->bits); + vmm->pd->pt[0] = nvkm_mmu_ptc_get(mmu, size, desc->align, true); + if (!vmm->pd->pt[0]) + return -ENOMEM; + } + + return 0; +} + +int +nvkm_vmm_new_(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, + u32 hdr, u64 addr, u64 size, struct lock_class_key *key, + const char *name, struct nvkm_vmm **pvmm) +{ + if (!(*pvmm = kzalloc(sizeof(**pvmm), GFP_KERNEL))) + return -ENOMEM; + return nvkm_vmm_ctor(func, mmu, hdr, addr, size, key, name, *pvmm); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h new file mode 100644 index 000000000000..46cc194b2003 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -0,0 +1,111 @@ +#ifndef __NVKM_VMM_H__ +#define __NVKM_VMM_H__ +#include "priv.h" +#include + +struct nvkm_vmm_pt { + /* Some GPUs have a mapping level with a dual page tables to + * support large and small pages in the same address-range. + * + * We track the state of both page tables in one place, which + * is why there's multiple PT pointers/refcounts here. + */ + struct nvkm_mmu_pt *pt[2]; + u32 refs[2]; + + /* Page size handled by this PT. + * + * Tesla backend needs to know this when writinge PDEs, + * otherwise unnecessary. + */ + u8 page; + + /* Entire page table sparse. + * + * Used to propagate sparseness to child page tables. + */ + bool sparse:1; + + /* Tracking for page directories. + * + * The array is indexed by PDE, and will either point to the + * child page table, or indicate the PDE is marked as sparse. + **/ +#define NVKM_VMM_PDE_INVALID(pde) IS_ERR_OR_NULL(pde) +#define NVKM_VMM_PDE_SPARSED(pde) IS_ERR(pde) +#define NVKM_VMM_PDE_SPARSE ERR_PTR(-EBUSY) + struct nvkm_vmm_pt **pde; + + /* Tracking for dual page tables. + * + * There's one entry for each LPTE, keeping track of whether + * there are valid SPTEs in the same address-range. + * + * This information is used to manage LPTE state transitions. + */ +#define NVKM_VMM_PTE_SPARSE 0x80 +#define NVKM_VMM_PTE_VALID 0x40 +#define NVKM_VMM_PTE_SPTES 0x3f + u8 pte[]; +}; + +struct nvkm_vmm_desc_func { +}; + +struct nvkm_vmm_desc { + enum { + PGD, + PGT, + SPT, + LPT, + } type; + u8 bits; /* VMA bits covered by PT. */ + u8 size; /* Bytes-per-PTE. */ + u32 align; /* PT address alignment. */ + const struct nvkm_vmm_desc_func *func; +}; + +struct nvkm_vmm_page { + u8 shift; + const struct nvkm_vmm_desc *desc; +#define NVKM_VMM_PAGE_SPARSE 0x01 +#define NVKM_VMM_PAGE_VRAM 0x02 +#define NVKM_VMM_PAGE_HOST 0x04 +#define NVKM_VMM_PAGE_COMP 0x08 +#define NVKM_VMM_PAGE_Sxxx (NVKM_VMM_PAGE_SPARSE) +#define NVKM_VMM_PAGE_xVxx (NVKM_VMM_PAGE_VRAM) +#define NVKM_VMM_PAGE_SVxx (NVKM_VMM_PAGE_Sxxx | NVKM_VMM_PAGE_VRAM) +#define NVKM_VMM_PAGE_xxHx (NVKM_VMM_PAGE_HOST) +#define NVKM_VMM_PAGE_SxHx (NVKM_VMM_PAGE_Sxxx | NVKM_VMM_PAGE_HOST) +#define NVKM_VMM_PAGE_xVHx (NVKM_VMM_PAGE_xVxx | NVKM_VMM_PAGE_HOST) +#define NVKM_VMM_PAGE_SVHx (NVKM_VMM_PAGE_SVxx | NVKM_VMM_PAGE_HOST) +#define NVKM_VMM_PAGE_xVxC (NVKM_VMM_PAGE_xVxx | NVKM_VMM_PAGE_COMP) +#define NVKM_VMM_PAGE_SVxC (NVKM_VMM_PAGE_SVxx | NVKM_VMM_PAGE_COMP) +#define NVKM_VMM_PAGE_xxHC (NVKM_VMM_PAGE_xxHx | NVKM_VMM_PAGE_COMP) +#define NVKM_VMM_PAGE_SxHC (NVKM_VMM_PAGE_SxHx | NVKM_VMM_PAGE_COMP) + u8 type; +}; + +struct nvkm_vmm_func { + int (*join)(struct nvkm_vmm *, struct nvkm_memory *inst); + void (*part)(struct nvkm_vmm *, struct nvkm_memory *inst); + + u64 page_block; + const struct nvkm_vmm_page page[]; +}; + +int nvkm_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, + u32 pd_header, u64 addr, u64 size, struct lock_class_key *, + const char *name, struct nvkm_vmm **); +int nvkm_vmm_ctor(const struct nvkm_vmm_func *, struct nvkm_mmu *, + u32 pd_header, u64 addr, u64 size, struct lock_class_key *, + const char *name, struct nvkm_vmm *); +void nvkm_vmm_dtor(struct nvkm_vmm *); + +struct nvkm_vmm_user { + struct nvkm_sclass base; + int (*ctor)(struct nvkm_mmu *, u64 addr, u64 size, void *args, u32 argc, + struct lock_class_key *, const char *name, + struct nvkm_vmm **); +}; +#endif -- cgit v1.2.3 From 5b17f3624efa5473e78ff9b09177e3db0806bb27 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv04: implement vmm on top of new base Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 3 +- drivers/gpu/drm/nouveau/include/nvif/if000d.h | 8 +++ drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c | 5 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 33 ++------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 4 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 11 ++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c | 84 ++++++++++++++++++++++ 8 files changed, 113 insertions(+), 36 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if000d.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 7f0839615b0c..d6fc025c912e 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -14,7 +14,8 @@ #define NVIF_CLASS_SW_NV50 /* if0005.h */ -0x00000006 #define NVIF_CLASS_SW_GF100 /* if0005.h */ -0x00000007 -#define NVIF_CLASS_VMM /* if000c.h */ 0x0000000c +#define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c +#define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d /* the below match nvidia-assigned (either in hw, or sw) class numbers */ #define NV_NULL_CLASS 0x00000030 diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000d.h b/drivers/gpu/drm/nouveau/include/nvif/if000d.h new file mode 100644 index 000000000000..0f94eb5005b1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if000d.h @@ -0,0 +1,8 @@ +#ifndef __NVIF_IF000D_H__ +#define __NVIF_IF000D_H__ +#include "if000c.h" + +struct nv04_vmm_vn { + /* nvif_vmm_vX ... */ +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c index acc45ce5f93e..49ef7e57aad4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include @@ -49,7 +49,8 @@ nv04_dmaobj_bind(struct nvkm_dmaobj *base, struct nvkm_gpuobj *parent, int ret; if (dmaobj->clone) { - struct nvkm_memory *pgt = device->mmu->vmm->pgt[0].mem[0]; + struct nvkm_memory *pgt = + device->mmu->vmm->pd->pt[0]->memory; if (!dmaobj->base.start) return nvkm_gpuobj_wrap(pgt, pgpuobj); nvkm_kmap(pgt); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index c786a9f90776..64684a744000 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -13,3 +13,4 @@ nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/vmm.o +nvkm-y += nvkm/subdev/mmu/vmmnv04.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 5bf757541f7b..fc4390de345e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ #include "nv04.h" +#include "vmm.h" -#include +#include #define NV04_PDMA_SIZE (128 * 1024 * 1024) #define NV04_PDMA_PAGE ( 4 * 1024) @@ -73,30 +74,10 @@ nv04_vm_flush(struct nvkm_vm *vm) ******************************************************************************/ static int -nv04_mmu_oneinit(struct nvkm_mmu *base) +nv04_mmu_oneinit(struct nvkm_mmu *mmu) { - struct nv04_mmu *mmu = nv04_mmu(base); - struct nvkm_device *device = mmu->base.subdev.device; - struct nvkm_memory *dma; - int ret; - - ret = nvkm_vm_create(&mmu->base, 0, NV04_PDMA_SIZE, 0, 4096, NULL, - &mmu->base.vmm); - if (ret) - return ret; - - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, - (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 + 8, - 16, true, &dma); - mmu->base.vmm->pgt[0].mem[0] = dma; - mmu->base.vmm->pgt[0].refcount[0] = 1; - if (ret) - return ret; - - nvkm_kmap(dma); - nvkm_wo32(dma, 0x00000, 0x0002103d); /* PCI, RW, PT, !LN */ - nvkm_wo32(dma, 0x00004, NV04_PDMA_SIZE - 1); - nvkm_done(dma); + mmu->vmm->pgt[0].mem[0] = mmu->vmm->pd->pt[0]->memory; + mmu->vmm->pgt[0].refcount[0] = 1; return 0; } @@ -129,7 +110,6 @@ nv04_mmu_new_(const struct nvkm_mmu_func *func, struct nvkm_device *device, const struct nvkm_mmu_func nv04_mmu = { .oneinit = nv04_mmu_oneinit, - .dtor = nv04_mmu_dtor, .limit = NV04_PDMA_SIZE, .dma_bits = 32, .pgt_bits = 32 - 12, @@ -138,10 +118,11 @@ nv04_mmu = { .map_sg = nv04_vm_map_sg, .unmap = nv04_vm_unmap, .flush = nv04_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv04_vmm_new, true }, }; int nv04_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) { - return nv04_mmu_new_(&nv04_mmu, device, index, pmmu); + return nvkm_mmu_new_(&nv04_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index ee0a8416df19..3d8d7e103f20 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -34,7 +34,7 @@ struct nvkm_mmu_func { void (*flush)(struct nvkm_vm *); struct { - struct nvkm_sclass base; + struct nvkm_sclass user; int (*ctor)(struct nvkm_mmu *, u64 addr, u64 size, void *argv, u32 argc, struct lock_class_key *, const char *name, struct nvkm_vmm **); @@ -45,6 +45,8 @@ struct nvkm_mmu_func { int nvkm_vm_create(struct nvkm_mmu *, u64, u64, u64, u32, struct lock_class_key *, struct nvkm_vm **); +extern const struct nvkm_mmu_func nv04_mmu; + int nv50_vm_create(struct nvkm_mmu *, u64, u64, u64, struct lock_class_key *, struct nvkm_vm **); void nv50_vm_map_pgt(struct nvkm_gpuobj *, u32, struct nvkm_memory **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 46cc194b2003..093ddb497c93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -102,10 +102,9 @@ int nvkm_vmm_ctor(const struct nvkm_vmm_func *, struct nvkm_mmu *, const char *name, struct nvkm_vmm *); void nvkm_vmm_dtor(struct nvkm_vmm *); -struct nvkm_vmm_user { - struct nvkm_sclass base; - int (*ctor)(struct nvkm_mmu *, u64 addr, u64 size, void *args, u32 argc, - struct lock_class_key *, const char *name, - struct nvkm_vmm **); -}; +int nv04_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32, + u64, u64, void *, u32, struct lock_class_key *, + const char *, struct nvkm_vmm **); +int nv04_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c new file mode 100644 index 000000000000..1f874b351a39 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +#include +#include + +static const struct nvkm_vmm_desc_func +nv04_vmm_desc_pgt = { +}; + +static const struct nvkm_vmm_desc +nv04_vmm_desc_12[] = { + { PGT, 15, 4, 0x1000, &nv04_vmm_desc_pgt }, + {} +}; + +static const struct nvkm_vmm_func +nv04_vmm = { + .page = { + { 12, &nv04_vmm_desc_12[0], NVKM_VMM_PAGE_HOST }, + {} + } +}; + +int +nv04_vmm_new_(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, + u32 pd_header, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + union { + struct nv04_vmm_vn vn; + } *args = argv; + int ret; + + ret = nvkm_vmm_new_(func, mmu, pd_header, addr, size, key, name, pvmm); + if (ret) + return ret; + + return nvif_unvers(-ENOSYS, &argv, &argc, args->vn); +} + +int +nv04_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + struct nvkm_vmm *vmm; + struct nvkm_memory *mem; + int ret; + + ret = nv04_vmm_new_(&nv04_vmm, mmu, 8, addr, size, + argv, argc, key, name, &vmm); + *pvmm = vmm; + if (ret) + return ret; + + mem = vmm->pd->pt[0]->memory; + nvkm_kmap(mem); + nvkm_wo32(mem, 0x00000, 0x0002103d); /* PCI, RW, PT, !LN */ + nvkm_wo32(mem, 0x00004, vmm->limit - 1); + nvkm_done(mem); + return 0; +} -- cgit v1.2.3 From 77783435c31182166c4679ad75358e1756d1e5da Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv41: implement vmm on top of new base Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c | 44 ++++++++------------ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 3 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c | 49 +++++++++++++++++++++++ 4 files changed, 69 insertions(+), 28 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 64684a744000..4b3e403a76f3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -14,3 +14,4 @@ nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/vmm.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o +nvkm-y += nvkm/subdev/mmu/vmmnv41.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c index 9b5375c587a7..cb037f4a1780 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c @@ -21,12 +21,13 @@ * * Authors: Ben Skeggs */ -#include "nv04.h" +#include "vmm.h" -#include #include #include +#include + #define NV41_GART_SIZE (512 * 1024 * 1024) #define NV41_GART_PAGE ( 4 * 1024) @@ -68,17 +69,17 @@ nv41_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) static void nv41_vm_flush(struct nvkm_vm *vm) { - struct nv04_mmu *mmu = nv04_mmu(vm->mmu); - struct nvkm_device *device = mmu->base.subdev.device; + struct nvkm_subdev *subdev = &vm->mmu->subdev; + struct nvkm_device *device = subdev->device; - mutex_lock(&mmu->base.subdev.mutex); + mutex_lock(&subdev->mutex); nvkm_wr32(device, 0x100810, 0x00000022); nvkm_msec(device, 2000, if (nvkm_rd32(device, 0x100810) & 0x00000020) break; ); nvkm_wr32(device, 0x100810, 0x00000000); - mutex_unlock(&mmu->base.subdev.mutex); + mutex_unlock(&subdev->mutex); } /******************************************************************************* @@ -86,38 +87,24 @@ nv41_vm_flush(struct nvkm_vm *vm) ******************************************************************************/ static int -nv41_mmu_oneinit(struct nvkm_mmu *base) +nv41_mmu_oneinit(struct nvkm_mmu *mmu) { - struct nv04_mmu *mmu = nv04_mmu(base); - struct nvkm_device *device = mmu->base.subdev.device; - int ret; - - ret = nvkm_vm_create(&mmu->base, 0, NV41_GART_SIZE, 0, 4096, NULL, - &mmu->base.vmm); - if (ret) - return ret; - - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, - (NV41_GART_SIZE / NV41_GART_PAGE) * 4, 16, true, - &mmu->base.vmm->pgt[0].mem[0]); - mmu->base.vmm->pgt[0].refcount[0] = 1; - return ret; + mmu->vmm->pgt[0].mem[0] = mmu->vmm->pd->pt[0]->memory; + mmu->vmm->pgt[0].refcount[0] = 1; + return 0; } static void -nv41_mmu_init(struct nvkm_mmu *base) +nv41_mmu_init(struct nvkm_mmu *mmu) { - struct nv04_mmu *mmu = nv04_mmu(base); - struct nvkm_device *device = mmu->base.subdev.device; - struct nvkm_memory *dma = mmu->base.vmm->pgt[0].mem[0]; - nvkm_wr32(device, 0x100800, 0x00000002 | nvkm_memory_addr(dma)); + struct nvkm_device *device = mmu->subdev.device; + nvkm_wr32(device, 0x100800, 0x00000002 | mmu->vmm->pd->pt[0]->addr); nvkm_mask(device, 0x10008c, 0x00000100, 0x00000100); nvkm_wr32(device, 0x100820, 0x00000000); } static const struct nvkm_mmu_func nv41_mmu = { - .dtor = nv04_mmu_dtor, .oneinit = nv41_mmu_oneinit, .init = nv41_mmu_init, .limit = NV41_GART_SIZE, @@ -128,6 +115,7 @@ nv41_mmu = { .map_sg = nv41_vm_map_sg, .unmap = nv41_vm_unmap, .flush = nv41_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv41_vmm_new, true }, }; int @@ -137,5 +125,5 @@ nv41_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) !nvkm_boolopt(device->cfgopt, "NvPCIE", true)) return nv04_mmu_new(device, index, pmmu); - return nv04_mmu_new_(&nv41_mmu, device, index, pmmu); + return nvkm_mmu_new_(&nv41_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 093ddb497c93..16d4a4c7aae4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -105,6 +105,9 @@ void nvkm_vmm_dtor(struct nvkm_vmm *); int nv04_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); + int nv04_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c new file mode 100644 index 000000000000..8a624d7c363a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +static const struct nvkm_vmm_desc_func +nv41_vmm_desc_pgt = { +}; + +static const struct nvkm_vmm_desc +nv41_vmm_desc_12[] = { + { PGT, 17, 4, 0x1000, &nv41_vmm_desc_pgt }, + {} +}; + +static const struct nvkm_vmm_func +nv41_vmm = { + .page = { + { 12, &nv41_vmm_desc_12[0], NVKM_VMM_PAGE_HOST }, + {} + } +}; + +int +nv41_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return nv04_vmm_new_(&nv41_vmm, mmu, 0, addr, size, + argv, argc, key, name, pvmm); +} -- cgit v1.2.3 From 03b0ba7b545ba0c5b19fedb14a771a3517a1328e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv44: implement vmm on top of new base Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 3 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 5 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 27 ---------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h | 17 ------ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c | 61 +++++++-------------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 5 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c | 65 +++++++++++++++++++++++ 10 files changed, 96 insertions(+), 91 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 8ff71e7f2f5b..f171e7a82f57 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -48,6 +48,9 @@ struct nvkm_vm { bool bootstrapped; atomic_t engref[NVKM_SUBDEV_NR]; + + dma_addr_t null; + void *nullp; }; int nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 4b3e403a76f3..f8a46f9a37a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -15,3 +15,4 @@ nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/vmm.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o nvkm-y += nvkm/subdev/mmu/vmmnv41.o +nvkm-y += nvkm/subdev/mmu/vmmnv44.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index d55ec0e85dca..0b4cb7b6a81f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -786,14 +786,11 @@ static void * nvkm_mmu_dtor(struct nvkm_subdev *subdev) { struct nvkm_mmu *mmu = nvkm_mmu(subdev); - void *data = mmu; - if (mmu->func->dtor) - data = mmu->func->dtor(mmu); nvkm_vm_ref(NULL, &mmu->vmm, NULL); nvkm_mmu_ptc_fini(mmu); - return data; + return mmu; } static const struct nvkm_subdev_func diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index fc4390de345e..3e6036431754 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -21,7 +21,6 @@ * * Authors: Ben Skeggs */ -#include "nv04.h" #include "vmm.h" #include @@ -81,32 +80,6 @@ nv04_mmu_oneinit(struct nvkm_mmu *mmu) return 0; } -void * -nv04_mmu_dtor(struct nvkm_mmu *base) -{ - struct nv04_mmu *mmu = nv04_mmu(base); - struct nvkm_device *device = mmu->base.subdev.device; - if (mmu->base.vmm) - nvkm_memory_unref(&mmu->base.vmm->pgt[0].mem[0]); - if (mmu->nullp) { - dma_free_coherent(device->dev, 16 * 1024, - mmu->nullp, mmu->null); - } - return mmu; -} - -int -nv04_mmu_new_(const struct nvkm_mmu_func *func, struct nvkm_device *device, - int index, struct nvkm_mmu **pmmu) -{ - struct nv04_mmu *mmu; - if (!(mmu = kzalloc(sizeof(*mmu), GFP_KERNEL))) - return -ENOMEM; - *pmmu = &mmu->base; - nvkm_mmu_ctor(func, device, index, &mmu->base); - return 0; -} - const struct nvkm_mmu_func nv04_mmu = { .oneinit = nv04_mmu_oneinit, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h deleted file mode 100644 index 6b8f14c6db3d..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __NV04_MMU_PRIV__ -#define __NV04_MMU_PRIV__ -#define nv04_mmu(p) container_of((p), struct nv04_mmu, base) -#include "priv.h" - -struct nv04_mmu { - struct nvkm_mmu base; - dma_addr_t null; - void *nullp; -}; - -int nv04_mmu_new_(const struct nvkm_mmu_func *, struct nvkm_device *, - int index, struct nvkm_mmu **); -void *nv04_mmu_dtor(struct nvkm_mmu *); - -extern const struct nvkm_mmu_func nv04_mmu; -#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c index cc97500a0901..48ca0cdf2acf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c @@ -21,12 +21,13 @@ * * Authors: Ben Skeggs */ -#include "nv04.h" +#include "vmm.h" -#include #include #include +#include + #define NV44_GART_SIZE (512 * 1024 * 1024) #define NV44_GART_PAGE ( 4 * 1024) @@ -84,7 +85,6 @@ static void nv44_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) { - struct nv04_mmu *mmu = nv04_mmu(vma->vm->mmu); u32 tmp[4]; int i; @@ -92,7 +92,7 @@ nv44_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, if (pte & 3) { u32 max = 4 - (pte & 3); u32 part = (cnt > max) ? max : cnt; - nv44_vm_fill(pgt, mmu->null, list, pte, part); + nv44_vm_fill(pgt, vma->vm->null, list, pte, part); pte += part; list += part; cnt -= part; @@ -109,20 +109,18 @@ nv44_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, } if (cnt) - nv44_vm_fill(pgt, mmu->null, list, pte, cnt); + nv44_vm_fill(pgt, vma->vm->null, list, pte, cnt); nvkm_done(pgt); } static void nv44_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) { - struct nv04_mmu *mmu = nv04_mmu(vma->vm->mmu); - nvkm_kmap(pgt); if (pte & 3) { u32 max = 4 - (pte & 3); u32 part = (cnt > max) ? max : cnt; - nv44_vm_fill(pgt, mmu->null, NULL, pte, part); + nv44_vm_fill(pgt, vma->vm->null, NULL, pte, part); pte += part; cnt -= part; } @@ -136,16 +134,15 @@ nv44_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) } if (cnt) - nv44_vm_fill(pgt, mmu->null, NULL, pte, cnt); + nv44_vm_fill(pgt, vma->vm->null, NULL, pte, cnt); nvkm_done(pgt); } static void nv44_vm_flush(struct nvkm_vm *vm) { - struct nv04_mmu *mmu = nv04_mmu(vm->mmu); - struct nvkm_device *device = mmu->base.subdev.device; - nvkm_wr32(device, 0x100814, mmu->base.limit - NV44_GART_PAGE); + struct nvkm_device *device = vm->mmu->subdev.device; + nvkm_wr32(device, 0x100814, vm->mmu->limit - NV44_GART_PAGE); nvkm_wr32(device, 0x100808, 0x00000020); nvkm_msec(device, 2000, if (nvkm_rd32(device, 0x100808) & 0x00000001) @@ -159,38 +156,18 @@ nv44_vm_flush(struct nvkm_vm *vm) ******************************************************************************/ static int -nv44_mmu_oneinit(struct nvkm_mmu *base) +nv44_mmu_oneinit(struct nvkm_mmu *mmu) { - struct nv04_mmu *mmu = nv04_mmu(base); - struct nvkm_device *device = mmu->base.subdev.device; - int ret; - - mmu->nullp = dma_alloc_coherent(device->dev, 16 * 1024, - &mmu->null, GFP_KERNEL); - if (!mmu->nullp) { - nvkm_warn(&mmu->base.subdev, "unable to allocate dummy pages\n"); - mmu->null = 0; - } - - ret = nvkm_vm_create(&mmu->base, 0, NV44_GART_SIZE, 0, 4096, NULL, - &mmu->base.vmm); - if (ret) - return ret; - - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, - (NV44_GART_SIZE / NV44_GART_PAGE) * 4, - 512 * 1024, true, - &mmu->base.vmm->pgt[0].mem[0]); - mmu->base.vmm->pgt[0].refcount[0] = 1; - return ret; + mmu->vmm->pgt[0].mem[0] = mmu->vmm->pd->pt[0]->memory; + mmu->vmm->pgt[0].refcount[0] = 1; + return 0; } static void -nv44_mmu_init(struct nvkm_mmu *base) +nv44_mmu_init(struct nvkm_mmu *mmu) { - struct nv04_mmu *mmu = nv04_mmu(base); - struct nvkm_device *device = mmu->base.subdev.device; - struct nvkm_memory *gart = mmu->base.vmm->pgt[0].mem[0]; + struct nvkm_device *device = mmu->subdev.device; + struct nvkm_memory *gart = mmu->vmm->pgt[0].mem[0]; u32 addr; /* calculate vram address of this PRAMIN block, object must be @@ -201,7 +178,7 @@ nv44_mmu_init(struct nvkm_mmu *base) addr -= ((nvkm_memory_addr(gart) >> 19) + 1) << 19; nvkm_wr32(device, 0x100850, 0x80000000); - nvkm_wr32(device, 0x100818, mmu->null); + nvkm_wr32(device, 0x100818, mmu->vmm->null); nvkm_wr32(device, 0x100804, NV44_GART_SIZE); nvkm_wr32(device, 0x100850, 0x00008000); nvkm_mask(device, 0x10008c, 0x00000200, 0x00000200); @@ -212,7 +189,6 @@ nv44_mmu_init(struct nvkm_mmu *base) static const struct nvkm_mmu_func nv44_mmu = { - .dtor = nv04_mmu_dtor, .oneinit = nv44_mmu_oneinit, .init = nv44_mmu_init, .limit = NV44_GART_SIZE, @@ -223,6 +199,7 @@ nv44_mmu = { .map_sg = nv44_vm_map_sg, .unmap = nv44_vm_unmap, .flush = nv44_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv44_vmm_new, true }, }; int @@ -232,5 +209,5 @@ nv44_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) !nvkm_boolopt(device->cfgopt, "NvPCIE", true)) return nv04_mmu_new(device, index, pmmu); - return nv04_mmu_new_(&nv44_mmu, device, index, pmmu); + return nvkm_mmu_new_(&nv44_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 3d8d7e103f20..bbb9c9cca27d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -9,7 +9,6 @@ int nvkm_mmu_new_(const struct nvkm_mmu_func *, struct nvkm_device *, int index, struct nvkm_mmu **); struct nvkm_mmu_func { - void *(*dtor)(struct nvkm_mmu *); int (*oneinit)(struct nvkm_mmu *); void (*init)(struct nvkm_mmu *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 93c8398b36a5..25e86ce3d29c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -70,6 +70,11 @@ nvkm_vmm_pt_new(const struct nvkm_vmm_desc *desc, bool sparse, void nvkm_vmm_dtor(struct nvkm_vmm *vmm) { + if (vmm->nullp) { + dma_free_coherent(vmm->mmu->subdev.device->dev, 16 * 1024, + vmm->nullp, vmm->null); + } + if (vmm->pd) { nvkm_mmu_ptc_put(vmm->mmu, true, &vmm->pd->pt[0]); nvkm_vmm_pt_del(&vmm->pd); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 16d4a4c7aae4..bade0237c102 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -110,4 +110,6 @@ int nv04_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int nv44_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c new file mode 100644 index 000000000000..2b5704269ac9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c @@ -0,0 +1,65 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +static const struct nvkm_vmm_desc_func +nv44_vmm_desc_pgt = { +}; + +static const struct nvkm_vmm_desc +nv44_vmm_desc_12[] = { + { PGT, 17, 4, 0x80000, &nv44_vmm_desc_pgt }, + {} +}; + +static const struct nvkm_vmm_func +nv44_vmm = { + .page = { + { 12, &nv44_vmm_desc_12[0], NVKM_VMM_PAGE_HOST }, + {} + } +}; + +int +nv44_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + struct nvkm_subdev *subdev = &mmu->subdev; + struct nvkm_vmm *vmm; + int ret; + + ret = nv04_vmm_new_(&nv44_vmm, mmu, 0, addr, size, + argv, argc, key, name, &vmm); + *pvmm = vmm; + if (ret) + return ret; + + vmm->nullp = dma_alloc_coherent(subdev->device->dev, 16 * 1024, + &vmm->null, GFP_KERNEL); + if (!vmm->nullp) { + nvkm_warn(subdev, "unable to allocate dummy pages\n"); + vmm->null = 0; + } + + return 0; +} -- cgit v1.2.3 From 9f6219fde7457df7a982174d496a012f4f42e776 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv50,g84: implement vmm on top of new base Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + drivers/gpu/drm/nouveau/include/nvif/if500d.h | 8 ++ drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 5 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 6 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 9 +++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c | 94 +++++++++++++++++++++++ 10 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if500d.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index d6fc025c912e..9c02927b4ca9 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -16,6 +16,7 @@ #define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d +#define NVIF_CLASS_VMM_NV50 /* if500d.h */ 0x8000500d /* the below match nvidia-assigned (either in hw, or sw) class numbers */ #define NV_NULL_CLASS 0x00000030 diff --git a/drivers/gpu/drm/nouveau/include/nvif/if500d.h b/drivers/gpu/drm/nouveau/include/nvif/if500d.h new file mode 100644 index 000000000000..6a0f47770745 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if500d.h @@ -0,0 +1,8 @@ +#ifndef __NVIF_IF500D_H__ +#define __NVIF_IF500D_H__ +#include "if000c.h" + +struct nv50_vmm_vn { + /* nvif_vmm_vX ... */ +}; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index f171e7a82f57..71d4863378f4 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -36,7 +36,6 @@ struct nvkm_vm { u64 limit; struct nvkm_vmm_pt *pd; - u16 pd_offset; struct list_head join; struct nvkm_mm mm; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index f8a46f9a37a0..2ec7e50568ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -16,3 +16,4 @@ nvkm-y += nvkm/subdev/mmu/vmm.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o nvkm-y += nvkm/subdev/mmu/vmmnv41.o nvkm-y += nvkm/subdev/mmu/vmmnv44.o +nvkm-y += nvkm/subdev/mmu/vmmnv50.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 0b4cb7b6a81f..1965a52ebe60 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -727,7 +727,6 @@ nvkm_vm_del(struct kref *kref) nvkm_mm_fini(&vm->mm); vfree(vm->pgt); - if (vm->func) nvkm_vmm_dtor(vm); kfree(vm); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index a1aca162a8cf..bb15ae97f421 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -19,7 +19,9 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include "vmm.h" + +#include static const struct nvkm_mmu_func g84_mmu = { @@ -34,6 +36,7 @@ g84_mmu = { .map_sg = nv50_vm_map_sg, .unmap = nv50_vm_unmap, .flush = nv50_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index 5811516c9a26..4e1c70db85c0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -21,13 +21,15 @@ * * Authors: Ben Skeggs */ -#include "priv.h" +#include "vmm.h" #include #include #include #include +#include + void nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]) { @@ -205,7 +207,6 @@ nv50_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, u32 block = (1 << (mmu->func->pgt_bits + 12)); if (block > length) block = length; - return nvkm_vm_create(mmu, offset, length, mm_offset, block, key, pvm); } @@ -222,6 +223,7 @@ nv50_mmu = { .map_sg = nv50_vm_map_sg, .unmap = nv50_vm_unmap, .flush = nv50_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index bbb9c9cca27d..ac6d84537c5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -38,6 +38,7 @@ struct nvkm_mmu_func { void *argv, u32 argc, struct lock_class_key *, const char *name, struct nvkm_vmm **); bool global; + u32 pd_offset; } vmm; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index bade0237c102..894f701c2fe8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -94,6 +94,11 @@ struct nvkm_vmm_func { const struct nvkm_vmm_page page[]; }; +struct nvkm_vmm_join { + struct nvkm_memory *inst; + struct list_head head; +}; + int nvkm_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32 pd_header, u64 addr, u64 size, struct lock_class_key *, const char *name, struct nvkm_vmm **); @@ -112,4 +117,8 @@ int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int nv44_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int nv50_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); +int g84_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c new file mode 100644 index 000000000000..db27381b67c6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c @@ -0,0 +1,94 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +#include +#include + +static const struct nvkm_vmm_desc_func +nv50_vmm_pgt = { +}; + +static const struct nvkm_vmm_desc_func +nv50_vmm_pgd = { +}; + +static const struct nvkm_vmm_desc +nv50_vmm_desc_12[] = { + { PGT, 17, 8, 0x1000, &nv50_vmm_pgt }, + { PGD, 11, 0, 0x0000, &nv50_vmm_pgd }, + {} +}; + +static const struct nvkm_vmm_desc +nv50_vmm_desc_16[] = { + { PGT, 13, 8, 0x1000, &nv50_vmm_pgt }, + { PGD, 11, 0, 0x0000, &nv50_vmm_pgd }, + {} +}; + +static void +nv50_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + struct nvkm_vmm_join *join; + + list_for_each_entry(join, &vmm->join, head) { + if (join->inst == inst) { + list_del(&join->head); + kfree(join); + break; + } + } +} + +static int +nv50_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + struct nvkm_vmm_join *join; + + if (!(join = kmalloc(sizeof(*join), GFP_KERNEL))) + return -ENOMEM; + join->inst = inst; + list_add_tail(&join->head, &vmm->join); + return 0; +} + +static const struct nvkm_vmm_func +nv50_vmm = { + .join = nv50_vmm_join, + .part = nv50_vmm_part, + .page_block = 1 << 29, + .page = { + { 16, &nv50_vmm_desc_16[0], NVKM_VMM_PAGE_xVxC }, + { 12, &nv50_vmm_desc_12[0], NVKM_VMM_PAGE_xVHx }, + {} + } +}; + +int +nv50_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return nv04_vmm_new_(&nv50_vmm, mmu, 0, addr, size, + argv, argc, key, name, pvmm); +} -- cgit v1.2.3 From 540a1dde57bf4ce7acd2c5cc494bea03aa261484 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gf100: implement vmm on top of new base Adds support for: - Selection of a 64KiB big page size (NvFbBigPage=16). - System-memory PDs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + drivers/gpu/drm/nouveau/include/nvif/if900d.h | 8 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 6 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 12 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c | 145 +++++++++++++++++++++ 6 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if900d.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 9c02927b4ca9..df8d6a32d2dc 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -17,6 +17,7 @@ #define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d #define NVIF_CLASS_VMM_NV50 /* if500d.h */ 0x8000500d +#define NVIF_CLASS_VMM_GF100 /* if900d.h */ 0x8000900d /* the below match nvidia-assigned (either in hw, or sw) class numbers */ #define NV_NULL_CLASS 0x00000030 diff --git a/drivers/gpu/drm/nouveau/include/nvif/if900d.h b/drivers/gpu/drm/nouveau/include/nvif/if900d.h new file mode 100644 index 000000000000..112716f889c6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if900d.h @@ -0,0 +1,8 @@ +#ifndef __NVIF_IF900D_H__ +#define __NVIF_IF900D_H__ +#include "if000c.h" + +struct gf100_vmm_vn { + /* nvif_vmm_vX ... */ +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 2ec7e50568ab..908e57a2fc96 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -17,3 +17,4 @@ nvkm-y += nvkm/subdev/mmu/vmmnv04.o nvkm-y += nvkm/subdev/mmu/vmmnv41.o nvkm-y += nvkm/subdev/mmu/vmmnv44.o nvkm-y += nvkm/subdev/mmu/vmmnv50.o +nvkm-y += nvkm/subdev/mmu/vmmgf100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 3cc1013538c5..6a942e2bcc39 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -21,12 +21,13 @@ * * Authors: Ben Skeggs */ -#include "priv.h" +#include "vmm.h" +#include #include #include -#include +#include /* Map from compressed to corresponding uncompressed storage type. * The value 0xff represents an invalid storage type. @@ -209,6 +210,7 @@ gf100_mmu = { .map_sg = gf100_vm_map_sg, .unmap = gf100_vm_unmap, .flush = gf100_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 894f701c2fe8..1e207ce3faa8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -52,6 +52,9 @@ struct nvkm_vmm_pt { struct nvkm_vmm_desc_func { }; +extern const struct nvkm_vmm_desc_func gf100_vmm_pgd; +extern const struct nvkm_vmm_desc_func gf100_vmm_pgt; + struct nvkm_vmm_desc { enum { PGD, @@ -111,6 +114,13 @@ int nv04_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gf100_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, + struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); +int gf100_vmm_join_(struct nvkm_vmm *, struct nvkm_memory *, u64 base); +int gf100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); +void gf100_vmm_part(struct nvkm_vmm *, struct nvkm_memory *); + int nv04_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, @@ -121,4 +131,6 @@ int nv50_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int g84_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gf100_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c new file mode 100644 index 000000000000..f8234af0120c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c @@ -0,0 +1,145 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +#include + +const struct nvkm_vmm_desc_func +gf100_vmm_pgt = { +}; + +const struct nvkm_vmm_desc_func +gf100_vmm_pgd = { +}; + +static const struct nvkm_vmm_desc +gf100_vmm_desc_17_12[] = { + { SPT, 15, 8, 0x1000, &gf100_vmm_pgt }, + { PGD, 13, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +static const struct nvkm_vmm_desc +gf100_vmm_desc_17_17[] = { + { LPT, 10, 8, 0x1000, &gf100_vmm_pgt }, + { PGD, 13, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +static const struct nvkm_vmm_desc +gf100_vmm_desc_16_12[] = { + { SPT, 14, 8, 0x1000, &gf100_vmm_pgt }, + { PGD, 14, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +static const struct nvkm_vmm_desc +gf100_vmm_desc_16_16[] = { + { LPT, 10, 8, 0x1000, &gf100_vmm_pgt }, + { PGD, 14, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +void +gf100_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + nvkm_fo64(inst, 0x0200, 0x00000000, 2); +} + +int +gf100_vmm_join_(struct nvkm_vmm *vmm, struct nvkm_memory *inst, u64 base) +{ + struct nvkm_mmu_pt *pd = vmm->pd->pt[0]; + + switch (nvkm_memory_target(pd->memory)) { + case NVKM_MEM_TARGET_VRAM: base |= 0ULL << 0; break; + case NVKM_MEM_TARGET_HOST: base |= 2ULL << 0; + base |= BIT_ULL(2) /* VOL. */; + break; + case NVKM_MEM_TARGET_NCOH: base |= 3ULL << 0; break; + default: + WARN_ON(1); + return -EINVAL; + } + base |= pd->addr; + + nvkm_kmap(inst); + nvkm_wo64(inst, 0x0200, base); + nvkm_wo64(inst, 0x0208, vmm->limit - 1); + nvkm_done(inst); + return 0; +} + +int +gf100_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + return gf100_vmm_join_(vmm, inst, 0); +} + +static const struct nvkm_vmm_func +gf100_vmm_17 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 17, &gf100_vmm_desc_17_17[0], NVKM_VMM_PAGE_xVxC }, + { 12, &gf100_vmm_desc_17_12[0], NVKM_VMM_PAGE_xVHx }, + {} + } +}; + +static const struct nvkm_vmm_func +gf100_vmm_16 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 16, &gf100_vmm_desc_16_16[0], NVKM_VMM_PAGE_xVxC }, + { 12, &gf100_vmm_desc_16_12[0], NVKM_VMM_PAGE_xVHx }, + {} + } +}; + +int +gf100_vmm_new_(const struct nvkm_vmm_func *func_16, + const struct nvkm_vmm_func *func_17, + struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + switch (mmu->subdev.device->fb->page) { + case 16: return nv04_vmm_new_(func_16, mmu, 0, addr, size, + argv, argc, key, name, pvmm); + case 17: return nv04_vmm_new_(func_17, mmu, 0, addr, size, + argv, argc, key, name, pvmm); + default: + WARN_ON(1); + return -EINVAL; + } +} + +int +gf100_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return gf100_vmm_new_(&gf100_vmm_16, &gf100_vmm_17, mmu, addr, + size, argv, argc, key, name, pvmm); +} -- cgit v1.2.3 From 7de078aa7902fc515286735219173ad263a7610c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gk104,gk20a: implement vmm on top of new base Adds support for: - Selection of a 64KiB big page size (NvFbBigPage=16). - System-memory PDs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 5 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 5 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 9 +++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c | 85 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c | 53 ++++++++++++++ 6 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 908e57a2fc96..e65daffff9bf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -18,3 +18,5 @@ nvkm-y += nvkm/subdev/mmu/vmmnv41.o nvkm-y += nvkm/subdev/mmu/vmmnv44.o nvkm-y += nvkm/subdev/mmu/vmmnv50.o nvkm-y += nvkm/subdev/mmu/vmmgf100.o +nvkm-y += nvkm/subdev/mmu/vmmgk104.o +nvkm-y += nvkm/subdev/mmu/vmmgk20a.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index 6ab8e636feb1..1facdab4aa9e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -19,7 +19,9 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include "vmm.h" + +#include static const struct nvkm_mmu_func gk104_mmu = { @@ -34,6 +36,7 @@ gk104_mmu = { .map_sg = gf100_vm_map_sg, .unmap = gf100_vm_unmap, .flush = gf100_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index 9ea8a91802be..3d699c35a181 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -19,7 +19,9 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include "vmm.h" + +#include static const struct nvkm_mmu_func gk20a_mmu = { @@ -34,6 +36,7 @@ gk20a_mmu = { .map_sg = gf100_vm_map_sg, .unmap = gf100_vm_unmap, .flush = gf100_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 1e207ce3faa8..914ae3f53cca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -68,6 +68,11 @@ struct nvkm_vmm_desc { const struct nvkm_vmm_desc_func *func; }; +extern const struct nvkm_vmm_desc gk104_vmm_desc_16_12[]; +extern const struct nvkm_vmm_desc gk104_vmm_desc_16_16[]; +extern const struct nvkm_vmm_desc gk104_vmm_desc_17_12[]; +extern const struct nvkm_vmm_desc gk104_vmm_desc_17_17[]; + struct nvkm_vmm_page { u8 shift; const struct nvkm_vmm_desc *desc; @@ -133,4 +138,8 @@ int g84_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int gf100_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gk104_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); +int gk20a_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c new file mode 100644 index 000000000000..0d33700e3d88 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c @@ -0,0 +1,85 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +static const struct nvkm_vmm_desc_func +gk104_vmm_lpt = { +}; + +const struct nvkm_vmm_desc +gk104_vmm_desc_17_12[] = { + { SPT, 15, 8, 0x1000, &gf100_vmm_pgt }, + { PGD, 13, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +const struct nvkm_vmm_desc +gk104_vmm_desc_17_17[] = { + { LPT, 10, 8, 0x1000, &gk104_vmm_lpt }, + { PGD, 13, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +const struct nvkm_vmm_desc +gk104_vmm_desc_16_12[] = { + { SPT, 14, 8, 0x1000, &gf100_vmm_pgt }, + { PGD, 14, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +const struct nvkm_vmm_desc +gk104_vmm_desc_16_16[] = { + { LPT, 10, 8, 0x1000, &gk104_vmm_lpt }, + { PGD, 14, 8, 0x1000, &gf100_vmm_pgd }, + {} +}; + +static const struct nvkm_vmm_func +gk104_vmm_17 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 17, &gk104_vmm_desc_17_17[0], NVKM_VMM_PAGE_xVxC }, + { 12, &gk104_vmm_desc_17_12[0], NVKM_VMM_PAGE_xVHx }, + {} + } +}; + +static const struct nvkm_vmm_func +gk104_vmm_16 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 16, &gk104_vmm_desc_16_16[0], NVKM_VMM_PAGE_xVxC }, + { 12, &gk104_vmm_desc_16_12[0], NVKM_VMM_PAGE_xVHx }, + {} + } +}; + +int +gk104_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return gf100_vmm_new_(&gk104_vmm_16, &gk104_vmm_17, mmu, addr, + size, argv, argc, key, name, pvmm); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c new file mode 100644 index 000000000000..e000c3d1554a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +static const struct nvkm_vmm_func +gk20a_vmm_17 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 17, &gk104_vmm_desc_17_17[0], NVKM_VMM_PAGE_xxHC }, + { 12, &gk104_vmm_desc_17_12[0], NVKM_VMM_PAGE_xxHx }, + {} + } +}; + +static const struct nvkm_vmm_func +gk20a_vmm_16 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 16, &gk104_vmm_desc_16_16[0], NVKM_VMM_PAGE_xxHC }, + { 12, &gk104_vmm_desc_16_12[0], NVKM_VMM_PAGE_xxHx }, + {} + } +}; + +int +gk20a_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return gf100_vmm_new_(&gk20a_vmm_16, &gk20a_vmm_17, mmu, addr, + size, argv, argc, key, name, pvmm); +} -- cgit v1.2.3 From 5f300fed645597689f1e6fed8800fc7e3d01e212 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gm200,gm20b: implement vmm on top of new base Adds support for: - Per-VMM selection of big page size. - System-memory PDs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + drivers/gpu/drm/nouveau/include/nvif/ifb00d.h | 14 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 25 +++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 25 +++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 23 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c | 151 +++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c | 64 +++++++++ 8 files changed, 303 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/ifb00d.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index df8d6a32d2dc..76dff0697f63 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -18,6 +18,7 @@ #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d #define NVIF_CLASS_VMM_NV50 /* if500d.h */ 0x8000500d #define NVIF_CLASS_VMM_GF100 /* if900d.h */ 0x8000900d +#define NVIF_CLASS_VMM_GM200 /* ifb00d.h */ 0x8000b00d /* the below match nvidia-assigned (either in hw, or sw) class numbers */ #define NV_NULL_CLASS 0x00000030 diff --git a/drivers/gpu/drm/nouveau/include/nvif/ifb00d.h b/drivers/gpu/drm/nouveau/include/nvif/ifb00d.h new file mode 100644 index 000000000000..2e1e99810361 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/ifb00d.h @@ -0,0 +1,14 @@ +#ifndef __NVIF_IFB00D_H__ +#define __NVIF_IFB00D_H__ +#include "if000c.h" + +struct gm200_vmm_vn { + /* nvif_vmm_vX ... */ +}; + +struct gm200_vmm_v0 { + /* nvif_vmm_vX ... */ + __u8 version; + __u8 bigpage; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index e65daffff9bf..55963dc4dc41 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -20,3 +20,5 @@ nvkm-y += nvkm/subdev/mmu/vmmnv50.o nvkm-y += nvkm/subdev/mmu/vmmgf100.o nvkm-y += nvkm/subdev/mmu/vmmgk104.o nvkm-y += nvkm/subdev/mmu/vmmgk20a.o +nvkm-y += nvkm/subdev/mmu/vmmgm200.o +nvkm-y += nvkm/subdev/mmu/vmmgm20b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index 4bb342fa3d54..8d6be5b3e8e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -19,7 +19,11 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include "vmm.h" + +#include + +#include static const struct nvkm_mmu_func gm200_mmu = { @@ -34,10 +38,29 @@ gm200_mmu = { .map_sg = gf100_vm_map_sg, .unmap = gf100_vm_unmap, .flush = gf100_vm_flush, + .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm200_vmm_new }, +}; + +static const struct nvkm_mmu_func +gm200_mmu_fixed = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm200_vmm_new_fixed }, }; int gm200_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) { + if (device->fb->page) + return nvkm_mmu_new_(&gm200_mmu_fixed, device, index, pmmu); return nvkm_mmu_new_(&gm200_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 06e49a9c8a9f..2894c7cbcdbb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -19,7 +19,11 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include "vmm.h" + +#include + +#include static const struct nvkm_mmu_func gm20b_mmu = { @@ -34,10 +38,29 @@ gm20b_mmu = { .map_sg = gf100_vm_map_sg, .unmap = gf100_vm_unmap, .flush = gf100_vm_flush, + .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new }, +}; + +static const struct nvkm_mmu_func +gm20b_mmu_fixed = { + .limit = (1ULL << 40), + .dma_bits = 40, + .pgt_bits = 27 - 12, + .spg_shift = 12, + .lpg_shift = 17, + .create = gf100_vm_create, + .map_pgt = gf100_vm_map_pgt, + .map = gf100_vm_map, + .map_sg = gf100_vm_map_sg, + .unmap = gf100_vm_unmap, + .flush = gf100_vm_flush, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new_fixed }, }; int gm20b_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) { + if (device->fb->page) + return nvkm_mmu_new_(&gm20b_mmu_fixed, device, index, pmmu); return nvkm_mmu_new_(&gm20b_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 914ae3f53cca..5cca1b449bdb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -73,6 +73,11 @@ extern const struct nvkm_vmm_desc gk104_vmm_desc_16_16[]; extern const struct nvkm_vmm_desc gk104_vmm_desc_17_12[]; extern const struct nvkm_vmm_desc gk104_vmm_desc_17_17[]; +extern const struct nvkm_vmm_desc gm200_vmm_desc_16_12[]; +extern const struct nvkm_vmm_desc gm200_vmm_desc_16_16[]; +extern const struct nvkm_vmm_desc gm200_vmm_desc_17_12[]; +extern const struct nvkm_vmm_desc gm200_vmm_desc_17_17[]; + struct nvkm_vmm_page { u8 shift; const struct nvkm_vmm_desc *desc; @@ -126,6 +131,12 @@ int gf100_vmm_join_(struct nvkm_vmm *, struct nvkm_memory *, u64 base); int gf100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); void gf100_vmm_part(struct nvkm_vmm *, struct nvkm_memory *); +int gm200_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, + struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, struct nvkm_vmm **); +int gm200_vmm_join_(struct nvkm_vmm *, struct nvkm_memory *, u64 base); +int gm200_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); + int nv04_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, @@ -142,4 +153,16 @@ int gk104_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int gk20a_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gm200_vmm_new_fixed(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); +int gm200_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); +int gm20b_vmm_new_fixed(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); +int gm20b_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c new file mode 100644 index 000000000000..43138560b108 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c @@ -0,0 +1,151 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +#include +#include + +static const struct nvkm_vmm_desc_func +gm200_vmm_spt = { +}; + +static const struct nvkm_vmm_desc_func +gm200_vmm_lpt = { +}; + +static const struct nvkm_vmm_desc_func +gm200_vmm_pgd = { +}; + +const struct nvkm_vmm_desc +gm200_vmm_desc_17_12[] = { + { SPT, 15, 8, 0x1000, &gm200_vmm_spt }, + { PGD, 13, 8, 0x1000, &gm200_vmm_pgd }, + {} +}; + +const struct nvkm_vmm_desc +gm200_vmm_desc_17_17[] = { + { LPT, 10, 8, 0x1000, &gm200_vmm_lpt }, + { PGD, 13, 8, 0x1000, &gm200_vmm_pgd }, + {} +}; + +const struct nvkm_vmm_desc +gm200_vmm_desc_16_12[] = { + { SPT, 14, 8, 0x1000, &gm200_vmm_spt }, + { PGD, 14, 8, 0x1000, &gm200_vmm_pgd }, + {} +}; + +const struct nvkm_vmm_desc +gm200_vmm_desc_16_16[] = { + { LPT, 10, 8, 0x1000, &gm200_vmm_lpt }, + { PGD, 14, 8, 0x1000, &gm200_vmm_pgd }, + {} +}; + +int +gm200_vmm_join_(struct nvkm_vmm *vmm, struct nvkm_memory *inst, u64 base) +{ + if (vmm->func->page[1].shift == 16) + base |= BIT_ULL(11); + return gf100_vmm_join_(vmm, inst, base); +} + +int +gm200_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + return gm200_vmm_join_(vmm, inst, 0); +} + +static const struct nvkm_vmm_func +gm200_vmm_17 = { + .join = gm200_vmm_join, + .part = gf100_vmm_part, + .page = { + { 27, &gm200_vmm_desc_17_17[1], NVKM_VMM_PAGE_Sxxx }, + { 17, &gm200_vmm_desc_17_17[0], NVKM_VMM_PAGE_SVxC }, + { 12, &gm200_vmm_desc_17_12[0], NVKM_VMM_PAGE_SVHx }, + {} + } +}; + +static const struct nvkm_vmm_func +gm200_vmm_16 = { + .join = gm200_vmm_join, + .part = gf100_vmm_part, + .page = { + { 27, &gm200_vmm_desc_16_16[1], NVKM_VMM_PAGE_Sxxx }, + { 16, &gm200_vmm_desc_16_16[0], NVKM_VMM_PAGE_SVxC }, + { 12, &gm200_vmm_desc_16_12[0], NVKM_VMM_PAGE_SVHx }, + {} + } +}; + +int +gm200_vmm_new_(const struct nvkm_vmm_func *func_16, + const struct nvkm_vmm_func *func_17, + struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + const struct nvkm_vmm_func *func; + union { + struct gm200_vmm_vn vn; + struct gm200_vmm_v0 v0; + } *args = argv; + int ret = -ENOSYS; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + switch (args->v0.bigpage) { + case 16: func = func_16; break; + case 17: func = func_17; break; + default: + return -EINVAL; + } + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + func = func_17; + } else + return ret; + + return nvkm_vmm_new_(func, mmu, 0, addr, size, key, name, pvmm); +} + +int +gm200_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return gm200_vmm_new_(&gm200_vmm_16, &gm200_vmm_17, mmu, addr, + size, argv, argc, key, name, pvmm); +} + +int +gm200_vmm_new_fixed(struct nvkm_mmu *mmu, u64 addr, u64 size, + void *argv, u32 argc, struct lock_class_key *key, + const char *name, struct nvkm_vmm **pvmm) +{ + return gf100_vmm_new_(&gm200_vmm_16, &gm200_vmm_17, mmu, addr, + size, argv, argc, key, name, pvmm); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c new file mode 100644 index 000000000000..ec24c43f86cc --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +static const struct nvkm_vmm_func +gm20b_vmm_17 = { + .join = gm200_vmm_join, + .part = gf100_vmm_part, + .page = { + { 27, &gm200_vmm_desc_17_17[1], NVKM_VMM_PAGE_Sxxx }, + { 17, &gm200_vmm_desc_17_17[0], NVKM_VMM_PAGE_SxHC }, + { 12, &gm200_vmm_desc_17_12[0], NVKM_VMM_PAGE_SxHx }, + {} + } +}; + +static const struct nvkm_vmm_func +gm20b_vmm_16 = { + .join = gm200_vmm_join, + .part = gf100_vmm_part, + .page = { + { 27, &gm200_vmm_desc_16_16[1], NVKM_VMM_PAGE_Sxxx }, + { 16, &gm200_vmm_desc_16_16[0], NVKM_VMM_PAGE_SxHC }, + { 12, &gm200_vmm_desc_16_12[0], NVKM_VMM_PAGE_SxHx }, + {} + } +}; + +int +gm20b_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return gm200_vmm_new_(&gm20b_vmm_16, &gm20b_vmm_17, mmu, addr, + size, argv, argc, key, name, pvmm); +} + +int +gm20b_vmm_new_fixed(struct nvkm_mmu *mmu, u64 addr, u64 size, + void *argv, u32 argc, struct lock_class_key *key, + const char *name, struct nvkm_vmm **pvmm) +{ + return gf100_vmm_new_(&gm20b_vmm_16, &gm20b_vmm_17, mmu, addr, + size, argv, argc, key, name, pvmm); +} -- cgit v1.2.3 From 8e39abff45888a54b3d9dc20434940dabeda077f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gp100,gp10b: implement vmm on top of new base Adds support for: - Selection of old/new-style page table layout (GP100MmuLayout=0/1). - System-memory PDs. New layout disabled by default for the moment, as we don't have a backend that can handle it yet. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + drivers/gpu/drm/nouveau/include/nvif/ifc00d.h | 8 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 23 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 23 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 11 +++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 89 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c | 46 +++++++++++ 8 files changed, 179 insertions(+), 24 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/ifc00d.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 76dff0697f63..d5236daf54c4 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -19,6 +19,7 @@ #define NVIF_CLASS_VMM_NV50 /* if500d.h */ 0x8000500d #define NVIF_CLASS_VMM_GF100 /* if900d.h */ 0x8000900d #define NVIF_CLASS_VMM_GM200 /* ifb00d.h */ 0x8000b00d +#define NVIF_CLASS_VMM_GP100 /* ifc00d.h */ 0x8000c00d /* the below match nvidia-assigned (either in hw, or sw) class numbers */ #define NV_NULL_CLASS 0x00000030 diff --git a/drivers/gpu/drm/nouveau/include/nvif/ifc00d.h b/drivers/gpu/drm/nouveau/include/nvif/ifc00d.h new file mode 100644 index 000000000000..39be62ca7339 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/ifc00d.h @@ -0,0 +1,8 @@ +#ifndef __NVIF_IFC00D_H__ +#define __NVIF_IFC00D_H__ +#include "if000c.h" + +struct gp100_vmm_vn { + /* nvif_vmm_vX ... */ +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 55963dc4dc41..e7ef528fb5bf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -22,3 +22,5 @@ nvkm-y += nvkm/subdev/mmu/vmmgk104.o nvkm-y += nvkm/subdev/mmu/vmmgk20a.o nvkm-y += nvkm/subdev/mmu/vmmgm200.o nvkm-y += nvkm/subdev/mmu/vmmgm20b.o +nvkm-y += nvkm/subdev/mmu/vmmgp100.o +nvkm-y += nvkm/subdev/mmu/vmmgp10b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c index 6cfd325ea3a9..b1ba864b4b35 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -19,25 +19,24 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include "vmm.h" + +#include + +#include static const struct nvkm_mmu_func gp100_mmu = { - .limit = (1ULL << 40), - .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, - .lpg_shift = 17, - .create = gf100_vm_create, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, + .limit = (1ULL << 49), + .dma_bits = 47, + .lpg_shift = 16, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp100_vmm_new }, }; int gp100_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) { + if (!nvkm_boolopt(device->cfgopt, "GP100MmuLayout", false)) + return gm200_mmu_new(device, index, pmmu); return nvkm_mmu_new_(&gp100_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c index e0a41ce3ddd1..5d760a198b22 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c @@ -19,25 +19,24 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include "vmm.h" + +#include + +#include static const struct nvkm_mmu_func gp10b_mmu = { - .limit = (1ULL << 40), - .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, - .lpg_shift = 17, - .create = gf100_vm_create, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, + .limit = (1ULL << 49), + .dma_bits = 47, + .lpg_shift = 16, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp10b_vmm_new }, }; int gp10b_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) { + if (!nvkm_boolopt(device->cfgopt, "GP100MmuLayout", false)) + return gm20b_mmu_new(device, index, pmmu); return nvkm_mmu_new_(&gp10b_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 5cca1b449bdb..504408d8014b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -78,6 +78,9 @@ extern const struct nvkm_vmm_desc gm200_vmm_desc_16_16[]; extern const struct nvkm_vmm_desc gm200_vmm_desc_17_12[]; extern const struct nvkm_vmm_desc gm200_vmm_desc_17_17[]; +extern const struct nvkm_vmm_desc gp100_vmm_desc_12[]; +extern const struct nvkm_vmm_desc gp100_vmm_desc_16[]; + struct nvkm_vmm_page { u8 shift; const struct nvkm_vmm_desc *desc; @@ -137,6 +140,8 @@ int gm200_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, int gm200_vmm_join_(struct nvkm_vmm *, struct nvkm_memory *, u64 base); int gm200_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); +int gp100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); + int nv04_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, @@ -165,4 +170,10 @@ int gm20b_vmm_new_fixed(struct nvkm_mmu *, u64, u64, void *, u32, int gm20b_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gp100_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); +int gp10b_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c new file mode 100644 index 000000000000..68f67812aecc --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c @@ -0,0 +1,89 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +static const struct nvkm_vmm_desc_func +gp100_vmm_desc_spt = { +}; + +static const struct nvkm_vmm_desc_func +gp100_vmm_desc_lpt = { +}; + +static const struct nvkm_vmm_desc_func +gp100_vmm_desc_pd0 = { +}; + +static const struct nvkm_vmm_desc_func +gp100_vmm_desc_pd1 = { +}; + +const struct nvkm_vmm_desc +gp100_vmm_desc_16[] = { + { LPT, 5, 8, 0x0100, &gp100_vmm_desc_lpt }, + { PGD, 8, 16, 0x1000, &gp100_vmm_desc_pd0 }, + { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 }, + { PGD, 2, 8, 0x1000, &gp100_vmm_desc_pd1 }, + {} +}; + +const struct nvkm_vmm_desc +gp100_vmm_desc_12[] = { + { SPT, 9, 8, 0x1000, &gp100_vmm_desc_spt }, + { PGD, 8, 16, 0x1000, &gp100_vmm_desc_pd0 }, + { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gp100_vmm_desc_pd1 }, + { PGD, 2, 8, 0x1000, &gp100_vmm_desc_pd1 }, + {} +}; + +int +gp100_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + const u64 base = BIT_ULL(10) /* VER2 */ | BIT_ULL(11); /* 64KiB */ + return gf100_vmm_join_(vmm, inst, base); +} + +static const struct nvkm_vmm_func +gp100_vmm = { + .join = gp100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx }, + { 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx }, + { 29, &gp100_vmm_desc_16[2], NVKM_VMM_PAGE_Sxxx }, + { 21, &gp100_vmm_desc_16[1], NVKM_VMM_PAGE_SVxC }, + { 16, &gp100_vmm_desc_16[0], NVKM_VMM_PAGE_SVxC }, + { 12, &gp100_vmm_desc_12[0], NVKM_VMM_PAGE_SVHx }, + {} + } +}; + +int +gp100_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return nv04_vmm_new_(&gp100_vmm, mmu, 0, addr, size, + argv, argc, key, name, pvmm); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c new file mode 100644 index 000000000000..8b7f9b82750c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmm.h" + +static const struct nvkm_vmm_func +gp10b_vmm = { + .join = gp100_vmm_join, + .part = gf100_vmm_part, + .page = { + { 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx }, + { 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx }, + { 29, &gp100_vmm_desc_16[2], NVKM_VMM_PAGE_Sxxx }, + { 21, &gp100_vmm_desc_16[1], NVKM_VMM_PAGE_SxHC }, + { 16, &gp100_vmm_desc_16[0], NVKM_VMM_PAGE_SxHC }, + { 12, &gp100_vmm_desc_12[0], NVKM_VMM_PAGE_SxHx }, + {} + } +}; + +int +gp10b_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return nv04_vmm_new_(&gp10b_vmm, mmu, 0, addr, size, + argv, argc, key, name, pvmm); +} -- cgit v1.2.3 From af3b8d53869c175fce424b6bfd1f49c1b53baef1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: remove old vm creation hooks Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 30 +------------------------ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 8 ------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 2 -- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 2 -- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 11 --------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 10 --------- 9 files changed, 1 insertion(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 1965a52ebe60..9fdd1446da5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -616,31 +616,6 @@ nvkm_vm_legacy(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, return 0; } -int -nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, - u32 block, struct lock_class_key *key, struct nvkm_vm **pvm) -{ - static struct lock_class_key _key; - struct nvkm_vm *vm; - int ret; - - vm = kzalloc(sizeof(*vm), GFP_KERNEL); - if (!vm) - return -ENOMEM; - - __mutex_init(&vm->mutex, "&vm->mutex", key ? key : &_key); - vm->mmu = mmu; - - ret = nvkm_vm_legacy(mmu, offset, length, mm_offset, block, vm); - if (ret) { - kfree(vm); - return ret; - } - - *pvm = vm; - return 0; -} - int nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, struct lock_class_key *key, struct nvkm_vm **pvm) @@ -666,10 +641,7 @@ nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, return ret; } - if (!mmu->func->create) - return -EINVAL; - - return mmu->func->create(mmu, offset, length, mm_offset, key, pvm); + return -EINVAL; } static int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index bb15ae97f421..13f8247a2ee4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -30,7 +30,6 @@ g84_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, - .create = nv50_vm_create, .map_pgt = nv50_vm_map_pgt, .map = nv50_vm_map, .map_sg = nv50_vm_map_sg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 6a942e2bcc39..536260782cff 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -190,13 +190,6 @@ gf100_vm_flush(struct nvkm_vm *vm) mutex_unlock(&mmu->subdev.mutex); } -int -gf100_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, - struct lock_class_key *key, struct nvkm_vm **pvm) -{ - return nvkm_vm_create(mmu, offset, length, mm_offset, 4096, key, pvm); -} - static const struct nvkm_mmu_func gf100_mmu = { .limit = (1ULL << 40), @@ -204,7 +197,6 @@ gf100_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index 1facdab4aa9e..693aa1b875f2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -30,7 +30,6 @@ gk104_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index 3d699c35a181..b774d9a25c3e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -30,7 +30,6 @@ gk20a_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index 8d6be5b3e8e8..41332613c644 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -32,7 +32,6 @@ gm200_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, @@ -48,7 +47,6 @@ gm200_mmu_fixed = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 2894c7cbcdbb..25b16975bddd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -32,7 +32,6 @@ gm20b_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, @@ -48,7 +47,6 @@ gm20b_mmu_fixed = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index 4e1c70db85c0..ba1c04e00701 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -200,16 +200,6 @@ nv50_vm_flush(struct nvkm_vm *vm) mutex_unlock(&subdev->mutex); } -int -nv50_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, - struct lock_class_key *key, struct nvkm_vm **pvm) -{ - u32 block = (1 << (mmu->func->pgt_bits + 12)); - if (block > length) - block = length; - return nvkm_vm_create(mmu, offset, length, mm_offset, block, key, pvm); -} - static const struct nvkm_mmu_func nv50_mmu = { .limit = (1ULL << 40), @@ -217,7 +207,6 @@ nv50_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, - .create = nv50_vm_create, .map_pgt = nv50_vm_map_pgt, .map = nv50_vm_map, .map_sg = nv50_vm_map_sg, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index ac6d84537c5f..f490a636e9f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -18,9 +18,6 @@ struct nvkm_mmu_func { u8 spg_shift; u8 lpg_shift; - int (*create)(struct nvkm_mmu *, u64 offset, u64 length, u64 mm_offset, - struct lock_class_key *, struct nvkm_vm **); - void (*map_pgt)(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]); void (*map)(struct nvkm_vma *, struct nvkm_memory *, @@ -42,13 +39,8 @@ struct nvkm_mmu_func { } vmm; }; -int nvkm_vm_create(struct nvkm_mmu *, u64, u64, u64, u32, - struct lock_class_key *, struct nvkm_vm **); - extern const struct nvkm_mmu_func nv04_mmu; -int nv50_vm_create(struct nvkm_mmu *, u64, u64, u64, struct lock_class_key *, - struct nvkm_vm **); void nv50_vm_map_pgt(struct nvkm_gpuobj *, u32, struct nvkm_memory **); void nv50_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, u64, u64); @@ -57,8 +49,6 @@ void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, void nv50_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void nv50_vm_flush(struct nvkm_vm *); -int gf100_vm_create(struct nvkm_mmu *, u64, u64, u64, struct lock_class_key *, - struct nvkm_vm **); void gf100_vm_map_pgt(struct nvkm_gpuobj *, u32, struct nvkm_memory **); void gf100_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, u64, u64); -- cgit v1.2.3 From d30af7ce2c96e57b503da1d70454818331f0a6d5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: handle instance block setup We previously required each VMM user to allocate their own page directory and fill in the instance block themselves. It makes more sense to handle this in a common location. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/engine/falcon.h | 4 +- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 8 +-- drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/changf100.h | 1 - .../gpu/drm/nouveau/nvkm/engine/fifo/changk104.h | 1 - .../gpu/drm/nouveau/nvkm/engine/fifo/channv50.c | 5 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | 19 +---- .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 19 +---- drivers/gpu/drm/nouveau/nvkm/falcon/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/falcon/v1.c | 6 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 30 +++----- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 3 +- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 20 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 81 +++++----------------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 38 +++++----- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 14 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 6 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c | 21 ++---- .../gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h | 3 +- 20 files changed, 93 insertions(+), 192 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h index 8f9d132fbedf..f0024fb5a5af 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h @@ -78,7 +78,7 @@ struct nvkm_falcon_func { void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool); void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8); void (*read_dmem)(struct nvkm_falcon *, u32, u32, u8, void *); - void (*bind_context)(struct nvkm_falcon *, struct nvkm_gpuobj *); + void (*bind_context)(struct nvkm_falcon *, struct nvkm_memory *); int (*wait_for_halt)(struct nvkm_falcon *, u32); int (*clear_interrupt)(struct nvkm_falcon *, u32); void (*set_start_addr)(struct nvkm_falcon *, u32 start_addr); @@ -113,7 +113,7 @@ void nvkm_falcon_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool); void nvkm_falcon_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8); void nvkm_falcon_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *); -void nvkm_falcon_bind_context(struct nvkm_falcon *, struct nvkm_gpuobj *); +void nvkm_falcon_bind_context(struct nvkm_falcon *, struct nvkm_memory *); void nvkm_falcon_set_start_addr(struct nvkm_falcon *, u32); void nvkm_falcon_start(struct nvkm_falcon *); int nvkm_falcon_wait_for_halt(struct nvkm_falcon *, u32); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 71d4863378f4..eb6704a2fc8f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -10,11 +10,6 @@ struct nvkm_vm_pgt { u32 refcount[2]; }; -struct nvkm_vm_pgd { - struct list_head head; - struct nvkm_gpuobj *obj; -}; - struct nvkm_vma { struct nvkm_vm *vm; struct nvkm_mm_node *node; @@ -40,7 +35,6 @@ struct nvkm_vm { struct nvkm_mm mm; struct kref refcount; - struct list_head pgd_list; struct nvkm_vm_pgt *pgt; u32 fpde; u32 lpde; @@ -54,7 +48,7 @@ struct nvkm_vm { int nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset, struct lock_class_key *, struct nvkm_vm **); -int nvkm_vm_ref(struct nvkm_vm *, struct nvkm_vm **, struct nvkm_gpuobj *pgd); +int nvkm_vm_ref(struct nvkm_vm *, struct nvkm_vm **, struct nvkm_memory *inst); int nvkm_vm_boot(struct nvkm_vm *, u64 size); int nvkm_vm_get(struct nvkm_vm *, u64 size, u32 page_shift, u32 access, struct nvkm_vma *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c index 61797c4dd07a..705a6d951d32 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c @@ -281,5 +281,5 @@ g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vm, u64 push, if (ret) return ret; - return nvkm_vm_ref(chan->base.vm, &chan->vm, chan->pgd); + return nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h index 7d697e2dce1a..a902f848a878 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h @@ -11,7 +11,6 @@ struct gf100_fifo_chan { struct list_head head; bool killed; - struct nvkm_gpuobj *pgd; struct nvkm_vm *vm; struct { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h index 230f64e5f731..1cd5b8d3fb2e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h @@ -12,7 +12,6 @@ struct gk104_fifo_chan { struct list_head head; bool killed; - struct nvkm_gpuobj *pgd; struct nvkm_vm *vm; struct { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c index 25b60aff40e4..161aa9ec73bc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c @@ -206,7 +206,8 @@ void * nv50_fifo_chan_dtor(struct nvkm_fifo_chan *base) { struct nv50_fifo_chan *chan = nv50_fifo_chan(base); - nvkm_vm_ref(NULL, &chan->vm, chan->pgd); + if (chan->base.inst) + nvkm_vm_ref(NULL, &chan->vm, chan->base.inst->memory); nvkm_ramht_del(&chan->ramht); nvkm_gpuobj_del(&chan->pgd); nvkm_gpuobj_del(&chan->eng); @@ -266,5 +267,5 @@ nv50_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vm, u64 push, if (ret) return ret; - return nvkm_vm_ref(chan->base.vm, &chan->vm, chan->pgd); + return nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index 6343e0c84d96..695d0721b1ad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c @@ -200,8 +200,8 @@ static void * gf100_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) { struct gf100_fifo_chan *chan = gf100_fifo_chan(base); - nvkm_vm_ref(NULL, &chan->vm, chan->pgd); - nvkm_gpuobj_del(&chan->pgd); + if (chan->base.inst) + nvkm_vm_ref(NULL, &chan->vm, chan->base.inst->memory); return chan; } @@ -225,7 +225,6 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, struct fermi_channel_gpfifo_v0 v0; } *args = data; struct gf100_fifo *fifo = gf100_fifo(base); - struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_object *parent = oclass->parent; struct gf100_fifo_chan *chan; u64 usermem, ioffset, ilength; @@ -263,19 +262,7 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, args->v0.chid = chan->base.chid; - /* page directory */ - ret = nvkm_gpuobj_new(device, 0x10000, 0x1000, false, NULL, &chan->pgd); - if (ret) - return ret; - - nvkm_kmap(chan->base.inst); - nvkm_wo32(chan->base.inst, 0x0200, lower_32_bits(chan->pgd->addr)); - nvkm_wo32(chan->base.inst, 0x0204, upper_32_bits(chan->pgd->addr)); - nvkm_wo32(chan->base.inst, 0x0208, 0xffffffff); - nvkm_wo32(chan->base.inst, 0x020c, 0x000000ff); - nvkm_done(chan->base.inst); - - ret = nvkm_vm_ref(chan->base.vm, &chan->vm, chan->pgd); + ret = nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 6e93b8652c66..978c9ad952b3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -213,8 +213,8 @@ static void * gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) { struct gk104_fifo_chan *chan = gk104_fifo_chan(base); - nvkm_vm_ref(NULL, &chan->vm, chan->pgd); - nvkm_gpuobj_del(&chan->pgd); + if (chan->base.inst) + nvkm_vm_ref(NULL, &chan->vm, chan->base.inst->memory); return chan; } @@ -242,7 +242,6 @@ gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, const struct nvkm_oclass *oclass, struct nvkm_object **pobject) { - struct nvkm_device *device = fifo->base.engine.subdev.device; struct gk104_fifo_chan *chan; int runlist = -1, ret = -ENOSYS, i, j; u32 engines = 0, present = 0; @@ -302,19 +301,7 @@ gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, *chid = chan->base.chid; - /* Page directory. */ - ret = nvkm_gpuobj_new(device, 0x10000, 0x1000, false, NULL, &chan->pgd); - if (ret) - return ret; - - nvkm_kmap(chan->base.inst); - nvkm_wo32(chan->base.inst, 0x0200, lower_32_bits(chan->pgd->addr)); - nvkm_wo32(chan->base.inst, 0x0204, upper_32_bits(chan->pgd->addr)); - nvkm_wo32(chan->base.inst, 0x0208, 0xffffffff); - nvkm_wo32(chan->base.inst, 0x020c, 0x000000ff); - nvkm_done(chan->base.inst); - - ret = nvkm_vm_ref(chan->base.vm, &chan->vm, chan->pgd); + ret = nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/base.c b/drivers/gpu/drm/nouveau/nvkm/falcon/base.c index 1b7f48efd8b1..14be41f24155 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/base.c @@ -60,7 +60,7 @@ nvkm_falcon_read_dmem(struct nvkm_falcon *falcon, u32 start, u32 size, u8 port, } void -nvkm_falcon_bind_context(struct nvkm_falcon *falcon, struct nvkm_gpuobj *inst) +nvkm_falcon_bind_context(struct nvkm_falcon *falcon, struct nvkm_memory *inst) { if (!falcon->func->bind_context) { nvkm_error(falcon->user, diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/v1.c b/drivers/gpu/drm/nouveau/nvkm/falcon/v1.c index 669c24028470..9def926f24d4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/v1.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/v1.c @@ -180,7 +180,7 @@ nvkm_falcon_v1_read_dmem(struct nvkm_falcon *falcon, u32 start, u32 size, } static void -nvkm_falcon_v1_bind_context(struct nvkm_falcon *falcon, struct nvkm_gpuobj *ctx) +nvkm_falcon_v1_bind_context(struct nvkm_falcon *falcon, struct nvkm_memory *ctx) { u32 inst_loc; u32 fbif; @@ -216,7 +216,7 @@ nvkm_falcon_v1_bind_context(struct nvkm_falcon *falcon, struct nvkm_gpuobj *ctx) nvkm_falcon_wr32(falcon, fbif + 4 * FALCON_DMAIDX_PHYS_SYS_NCOH, 0x6); /* Set context */ - switch (nvkm_memory_target(ctx->memory)) { + switch (nvkm_memory_target(ctx)) { case NVKM_MEM_TARGET_VRAM: inst_loc = 0; break; case NVKM_MEM_TARGET_HOST: inst_loc = 2; break; case NVKM_MEM_TARGET_NCOH: inst_loc = 3; break; @@ -228,7 +228,7 @@ nvkm_falcon_v1_bind_context(struct nvkm_falcon *falcon, struct nvkm_gpuobj *ctx) /* Enable context */ nvkm_falcon_mask(falcon, 0x048, 0x1, 0x1); nvkm_falcon_wr32(falcon, 0x054, - ((ctx->addr >> 12) & 0xfffffff) | + ((nvkm_memory_addr(ctx) >> 12) & 0xfffffff) | (inst_loc << 28) | (1 << 30)); nvkm_falcon_mask(falcon, 0x090, 0x10000, 0x10000); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 8b588d1c776b..8077e1a5017a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -23,7 +23,7 @@ */ #include "gf100.h" -#include +#include #include #include #include @@ -53,7 +53,7 @@ gf100_bar_bar1_init(struct nvkm_bar *base) { struct nvkm_device *device = base->subdev.device; struct gf100_bar *bar = gf100_bar(base); - const u32 addr = nvkm_memory_addr(bar->bar[1].mem) >> 12; + const u32 addr = nvkm_memory_addr(bar->bar[1].inst) >> 12; nvkm_wr32(device, 0x001704, 0x80000000 | addr); } @@ -74,7 +74,7 @@ gf100_bar_bar2_init(struct nvkm_bar *base) { struct nvkm_device *device = base->subdev.device; struct gf100_bar *bar = gf100_bar(base); - u32 addr = nvkm_memory_addr(bar->bar[0].mem) >> 12; + u32 addr = nvkm_memory_addr(bar->bar[0].inst) >> 12; if (bar->bar2_halve) addr |= 0x40000000; nvkm_wr32(device, 0x001714, 0x80000000 | addr); @@ -90,11 +90,7 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, int ret; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0, false, - &bar_vm->mem); - if (ret) - return ret; - - ret = nvkm_gpuobj_new(device, 0x8000, 0, false, NULL, &bar_vm->pgd); + &bar_vm->inst); if (ret) return ret; @@ -119,17 +115,11 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, } } - ret = nvkm_vm_ref(vm, &bar_vm->vm, bar_vm->pgd); + ret = nvkm_vm_ref(vm, &bar_vm->vm, bar_vm->inst); nvkm_vm_ref(NULL, &vm, NULL); if (ret) return ret; - nvkm_kmap(bar_vm->mem); - nvkm_wo32(bar_vm->mem, 0x0200, lower_32_bits(bar_vm->pgd->addr)); - nvkm_wo32(bar_vm->mem, 0x0204, upper_32_bits(bar_vm->pgd->addr)); - nvkm_wo32(bar_vm->mem, 0x0208, lower_32_bits(bar_len - 1)); - nvkm_wo32(bar_vm->mem, 0x020c, upper_32_bits(bar_len - 1)); - nvkm_done(bar_vm->mem); return 0; } @@ -164,13 +154,11 @@ gf100_bar_dtor(struct nvkm_bar *base) { struct gf100_bar *bar = gf100_bar(base); - nvkm_vm_ref(NULL, &bar->bar[1].vm, bar->bar[1].pgd); - nvkm_gpuobj_del(&bar->bar[1].pgd); - nvkm_memory_unref(&bar->bar[1].mem); + nvkm_vm_ref(NULL, &bar->bar[1].vm, bar->bar[1].inst); + nvkm_memory_unref(&bar->bar[1].inst); - nvkm_vm_ref(NULL, &bar->bar[0].vm, bar->bar[0].pgd); - nvkm_gpuobj_del(&bar->bar[0].pgd); - nvkm_memory_unref(&bar->bar[0].mem); + nvkm_vm_ref(NULL, &bar->bar[0].vm, bar->bar[0].inst); + nvkm_memory_unref(&bar->bar[0].inst); return bar; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index fc1a7bd975a7..9ce80c6b6fec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -4,8 +4,7 @@ #include "priv.h" struct gf100_barN { - struct nvkm_memory *mem; - struct nvkm_gpuobj *pgd; + struct nvkm_memory *inst; struct nvkm_vm *vm; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index b40c131af20e..9300529917fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -140,7 +140,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) if (ret) return ret; - ret = nvkm_vm_ref(vm, &bar->bar2_vm, bar->pgd); + ret = nvkm_vm_ref(vm, &bar->bar2_vm, bar->mem->memory); nvkm_vm_ref(NULL, &vm, NULL); if (ret) return ret; @@ -172,7 +172,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) atomic_inc(&vm->engref[NVKM_SUBDEV_BAR]); - ret = nvkm_vm_ref(vm, &bar->bar1_vm, bar->pgd); + ret = nvkm_vm_ref(vm, &bar->bar1_vm, bar->mem->memory); nvkm_vm_ref(NULL, &vm, NULL); if (ret) return ret; @@ -197,13 +197,15 @@ void * nv50_bar_dtor(struct nvkm_bar *base) { struct nv50_bar *bar = nv50_bar(base); - nvkm_gpuobj_del(&bar->bar1); - nvkm_vm_ref(NULL, &bar->bar1_vm, bar->pgd); - nvkm_gpuobj_del(&bar->bar2); - nvkm_vm_ref(NULL, &bar->bar2_vm, bar->pgd); - nvkm_gpuobj_del(&bar->pgd); - nvkm_gpuobj_del(&bar->pad); - nvkm_gpuobj_del(&bar->mem); + if (bar->mem) { + nvkm_gpuobj_del(&bar->bar1); + nvkm_vm_ref(NULL, &bar->bar1_vm, bar->mem->memory); + nvkm_gpuobj_del(&bar->bar2); + nvkm_vm_ref(NULL, &bar->bar2_vm, bar->mem->memory); + nvkm_gpuobj_del(&bar->pgd); + nvkm_gpuobj_del(&bar->pad); + nvkm_gpuobj_del(&bar->mem); + } return bar; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 9fdd1446da5f..22264d3db22f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -446,7 +446,6 @@ static void nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde) { struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_vm_pgd *vpgd; struct nvkm_vm_pgt *vpgt; struct nvkm_memory *pgt; u32 pde; @@ -459,9 +458,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde) pgt = vpgt->mem[big]; vpgt->mem[big] = NULL; - list_for_each_entry(vpgd, &vm->pgd_list, head) { - mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem); - } + if (mmu->func->map_pgt) + mmu->func->map_pgt(vm, pde, vpgt->mem); mmu->func->flush(vm); @@ -474,7 +472,6 @@ nvkm_vm_map_pgt(struct nvkm_vm *vm, u32 pde, u32 type) { struct nvkm_mmu *mmu = vm->mmu; struct nvkm_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; - struct nvkm_vm_pgd *vpgd; int big = (type != mmu->func->spg_shift); u32 pgt_size; int ret; @@ -487,9 +484,8 @@ nvkm_vm_map_pgt(struct nvkm_vm *vm, u32 pde, u32 type) if (unlikely(ret)) return ret; - list_for_each_entry(vpgd, &vm->pgd_list, head) { - mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem); - } + if (mmu->func->map_pgt) + mmu->func->map_pgt(vm, pde, vpgt->mem); vpgt->refcount[big]++; return 0; @@ -592,7 +588,6 @@ nvkm_vm_legacy(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, u64 mm_length = (offset + length) - mm_offset; int ret; - INIT_LIST_HEAD(&vm->pgd_list); kref_init(&vm->refcount); vm->fpde = offset >> (mmu->func->pgt_bits + 12); vm->lpde = (offset + length - 1) >> (mmu->func->pgt_bits + 12); @@ -644,58 +639,10 @@ nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, return -EINVAL; } -static int -nvkm_vm_link(struct nvkm_vm *vm, struct nvkm_gpuobj *pgd) -{ - struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_vm_pgd *vpgd; - int i; - - if (!pgd) - return 0; - - vpgd = kzalloc(sizeof(*vpgd), GFP_KERNEL); - if (!vpgd) - return -ENOMEM; - - vpgd->obj = pgd; - - mutex_lock(&vm->mutex); - for (i = vm->fpde; i <= vm->lpde; i++) - mmu->func->map_pgt(pgd, i, vm->pgt[i - vm->fpde].mem); - list_add(&vpgd->head, &vm->pgd_list); - mutex_unlock(&vm->mutex); - return 0; -} - -static void -nvkm_vm_unlink(struct nvkm_vm *vm, struct nvkm_gpuobj *mpgd) -{ - struct nvkm_vm_pgd *vpgd, *tmp; - - if (!mpgd) - return; - - mutex_lock(&vm->mutex); - list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { - if (vpgd->obj == mpgd) { - list_del(&vpgd->head); - kfree(vpgd); - break; - } - } - mutex_unlock(&vm->mutex); -} - static void nvkm_vm_del(struct kref *kref) { struct nvkm_vm *vm = container_of(kref, typeof(*vm), refcount); - struct nvkm_vm_pgd *vpgd, *tmp; - - list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { - nvkm_vm_unlink(vm, vpgd->obj); - } nvkm_mm_fini(&vm->mm); vfree(vm->pgt); @@ -705,20 +652,28 @@ nvkm_vm_del(struct kref *kref) } int -nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_gpuobj *pgd) +nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) { if (ref) { - int ret = nvkm_vm_link(ref, pgd); - if (ret) - return ret; + if (ref->func->join && inst) { + int ret = ref->func->join(ref, inst), i; + if (ret) + return ret; + + if (ref->mmu->func->map_pgt) { + for (i = ref->fpde; i <= ref->lpde; i++) + ref->mmu->func->map_pgt(ref, i, ref->pgt[i - ref->fpde].mem); + } + } kref_get(&ref->refcount); } if (*ptr) { - if ((*ptr)->bootstrapped && pgd) + if ((*ptr)->func->part && inst) + (*ptr)->func->part(*ptr, inst); + if ((*ptr)->bootstrapped && inst) nvkm_memory_unref(&(*ptr)->pgt[0].mem[0]); - nvkm_vm_unlink(*ptr, pgd); kref_put(&(*ptr)->refcount, nvkm_vm_del); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 536260782cff..167c201d29e3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -70,8 +70,9 @@ const u8 gf100_pte_storage_type_map[256] = void -gf100_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 index, struct nvkm_memory *pgt[2]) +gf100_vm_map_pgt(struct nvkm_vmm *vmm, u32 index, struct nvkm_memory *pgt[2]) { + struct nvkm_memory *pgd = vmm->pd->pt[0]->memory; u32 pde[2] = { 0, 0 }; if (pgt[0]) @@ -161,7 +162,6 @@ gf100_vm_flush(struct nvkm_vm *vm) { struct nvkm_mmu *mmu = vm->mmu; struct nvkm_device *device = mmu->subdev.device; - struct nvkm_vm_pgd *vpgd; u32 type; type = 0x00000001; /* PAGE_ALL */ @@ -169,24 +169,22 @@ gf100_vm_flush(struct nvkm_vm *vm) type |= 0x00000004; /* HUB_ONLY */ mutex_lock(&mmu->subdev.mutex); - list_for_each_entry(vpgd, &vm->pgd_list, head) { - /* looks like maybe a "free flush slots" counter, the - * faster you write to 0x100cbc to more it decreases - */ - nvkm_msec(device, 2000, - if (nvkm_rd32(device, 0x100c80) & 0x00ff0000) - break; - ); - - nvkm_wr32(device, 0x100cb8, vpgd->obj->addr >> 8); - nvkm_wr32(device, 0x100cbc, 0x80000000 | type); - - /* wait for flush to be queued? */ - nvkm_msec(device, 2000, - if (nvkm_rd32(device, 0x100c80) & 0x00008000) - break; - ); - } + /* looks like maybe a "free flush slots" counter, the + * faster you write to 0x100cbc to more it decreases + */ + nvkm_msec(device, 2000, + if (nvkm_rd32(device, 0x100c80) & 0x00ff0000) + break; + ); + + nvkm_wr32(device, 0x100cb8, vm->pd->pt[0]->addr >> 8); + nvkm_wr32(device, 0x100cbc, 0x80000000 | type); + + /* wait for flush to be queued? */ + nvkm_msec(device, 2000, + if (nvkm_rd32(device, 0x100c80) & 0x00008000) + break; + ); mutex_unlock(&mmu->subdev.mutex); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index ba1c04e00701..da75d1da0658 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -31,8 +31,10 @@ #include void -nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]) +nv50_vm_map_pgt(struct nvkm_vmm *vmm, u32 pde, struct nvkm_memory *pgt[2]) { + struct nvkm_vmm_join *join; + u32 pdeo = vmm->mmu->func->vmm.pd_offset + (pde * 8); u64 phys = 0xdeadcafe00000000ULL; u32 coverage = 0; @@ -56,10 +58,12 @@ nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]) phys |= 0x20; } - nvkm_kmap(pgd); - nvkm_wo32(pgd, (pde * 8) + 0, lower_32_bits(phys)); - nvkm_wo32(pgd, (pde * 8) + 4, upper_32_bits(phys)); - nvkm_done(pgd); + list_for_each_entry(join, &vmm->join, head) { + nvkm_kmap(join->inst); + nvkm_wo32(join->inst, pdeo + 0, lower_32_bits(phys)); + nvkm_wo32(join->inst, pdeo + 4, upper_32_bits(phys)); + nvkm_done(join->inst); + } } static inline u64 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index f490a636e9f0..3271ec1c3c83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -18,7 +18,7 @@ struct nvkm_mmu_func { u8 spg_shift; u8 lpg_shift; - void (*map_pgt)(struct nvkm_gpuobj *pgd, u32 pde, + void (*map_pgt)(struct nvkm_vmm *, u32 pde, struct nvkm_memory *pgt[2]); void (*map)(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32 pte, u32 cnt, @@ -41,7 +41,7 @@ struct nvkm_mmu_func { extern const struct nvkm_mmu_func nv04_mmu; -void nv50_vm_map_pgt(struct nvkm_gpuobj *, u32, struct nvkm_memory **); +void nv50_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); void nv50_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, u64, u64); void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, @@ -49,7 +49,7 @@ void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, void nv50_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void nv50_vm_flush(struct nvkm_vm *); -void gf100_vm_map_pgt(struct nvkm_gpuobj *, u32, struct nvkm_memory **); +void gf100_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); void gf100_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, u64, u64); void gf100_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 25e86ce3d29c..7e00b9adca05 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -131,7 +131,7 @@ nvkm_vmm_ctor(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, /* ... and the GPU storage for it, except on Tesla-class GPUs that * have the PD embedded in the instance structure. */ - if (desc->size && mmu->func->vmm.global) { + if (desc->size) { const u32 size = pd_header + desc->size * (1 << desc->bits); vmm->pd->pt[0] = nvkm_mmu_ptc_get(mmu, size, desc->align, true); if (!vmm->pd->pt[0]) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c index d35c041fdcec..6c068c5bd3c2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c @@ -112,11 +112,8 @@ gm200_secboot_oneinit(struct nvkm_secboot *sb) int ret; /* Allocate instance block and VM */ - ret = nvkm_gpuobj_new(device, 0x1000, 0, true, NULL, &gsb->inst); - if (ret) - return ret; - - ret = nvkm_gpuobj_new(device, 0x8000, 0, true, NULL, &gsb->pgd); + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0, true, + &gsb->inst); if (ret) return ret; @@ -126,18 +123,11 @@ gm200_secboot_oneinit(struct nvkm_secboot *sb) atomic_inc(&vm->engref[NVKM_SUBDEV_PMU]); - ret = nvkm_vm_ref(vm, &gsb->vm, gsb->pgd); + ret = nvkm_vm_ref(vm, &gsb->vm, gsb->inst); nvkm_vm_ref(NULL, &vm, NULL); if (ret) return ret; - nvkm_kmap(gsb->inst); - nvkm_wo32(gsb->inst, 0x200, lower_32_bits(gsb->pgd->addr)); - nvkm_wo32(gsb->inst, 0x204, upper_32_bits(gsb->pgd->addr)); - nvkm_wo32(gsb->inst, 0x208, lower_32_bits(vm_area_len - 1)); - nvkm_wo32(gsb->inst, 0x20c, upper_32_bits(vm_area_len - 1)); - nvkm_done(gsb->inst); - if (sb->acr->func->oneinit) { ret = sb->acr->func->oneinit(sb->acr, sb); if (ret) @@ -165,9 +155,8 @@ gm200_secboot_dtor(struct nvkm_secboot *sb) sb->acr->func->dtor(sb->acr); - nvkm_vm_ref(NULL, &gsb->vm, gsb->pgd); - nvkm_gpuobj_del(&gsb->pgd); - nvkm_gpuobj_del(&gsb->inst); + nvkm_vm_ref(NULL, &gsb->vm, gsb->inst); + nvkm_memory_unref(&gsb->inst); return gsb; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h index c8ab3d76bdef..a2b60fab42e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h @@ -29,8 +29,7 @@ struct gm200_secboot { struct nvkm_secboot base; /* Instance block & address space used for HS FW execution */ - struct nvkm_gpuobj *inst; - struct nvkm_gpuobj *pgd; + struct nvkm_memory *inst; struct nvkm_vm *vm; }; #define gm200_secboot(sb) container_of(sb, struct gm200_secboot, base) -- cgit v1.2.3 From ac47c15b76d0f2c42eedde7e993a0d3db92f215d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fifo/nv04-nv40: fix missing nvkm_kmap() calls around ramfc access Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c index 0a7b6ed5ed28..c213122cf088 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c @@ -95,6 +95,7 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base) nvkm_mask(device, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0); c = fifo->ramfc; + nvkm_kmap(fctx); do { u32 rm = ((1ULL << c->bits) - 1) << c->regs; u32 cm = ((1ULL << c->bits) - 1) << c->ctxs; @@ -102,6 +103,7 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base) u32 cv = (nvkm_ro32(fctx, c->ctxp + data) & ~cm); nvkm_wo32(fctx, c->ctxp + data, cv | (rv << c->ctxs)); } while ((++c)->bits); + nvkm_done(fctx); c = fifo->ramfc; do { -- cgit v1.2.3 From f8a1203920e7de49bd99bfed76a82f0c93de2020 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/ltc/gm200: limit NV_MMU_PTE_COMPTAGLINE bits to 16 where required If NV_PFB_MMU_CTRL_USE_FULL_COMP_TAG_LINE is TRUE, then the last bit of NV_MMU_PTE_COMPTAGLINE is re-purposed to select the upper/lower half of a compression tag when using 64KiB big pages. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c index 59acf568faeb..a21ef45b8572 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c @@ -156,6 +156,7 @@ gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) struct nvkm_device *device = ltc->subdev.device; struct nvkm_fb *fb = device->fb; struct nvkm_ram *ram = fb->ram; + u32 bits = (nvkm_rd32(device, 0x100c80) & 0x00001000) ? 16 : 17; u32 tag_size, tag_margin, tag_align; int ret; @@ -167,8 +168,8 @@ gf100_ltc_oneinit_tag_ram(struct nvkm_ltc *ltc) /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */ ltc->num_tags = (ram->size >> 17) / 4; - if (ltc->num_tags > (1 << 17)) - ltc->num_tags = 1 << 17; /* we have 17 bits in PTE */ + if (ltc->num_tags > (1 << bits)) + ltc->num_tags = 1 << bits; /* we have 16/17 bits in PTE */ ltc->num_tags = (ltc->num_tags + 63) & ~63; /* round up to 64 */ tag_align = ltc->ltc_nr * 0x800; -- cgit v1.2.3 From bda9e379f61f937af7ee9b2a32d54bc50a94cd80 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb/gm200: enable NV_PFB_MMU_CTRL_USE_FULL_COMP_TAG_LINE where appropriate To avoid wasting compression tags when using 64KiB pages, we need to enable this so we can select between upper/lower comptagline in PTEs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c index cc3f90304c1c..1be0b9e98b84 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c @@ -31,9 +31,9 @@ gm200_fb_init_page(struct nvkm_fb *fb) { struct nvkm_device *device = fb->subdev.device; switch (fb->page) { - case 16: nvkm_mask(device, 0x100c80, 0x00000801, 0x00000001); break; - case 17: nvkm_mask(device, 0x100c80, 0x00000801, 0x00000000); break; - case 0: nvkm_mask(device, 0x100c80, 0x00000800, 0x00000800); break; + case 16: nvkm_mask(device, 0x100c80, 0x00001801, 0x00001001); break; + case 17: nvkm_mask(device, 0x100c80, 0x00001801, 0x00000000); break; + case 0: nvkm_mask(device, 0x100c80, 0x00001800, 0x00001800); break; default: return -EINVAL; } -- cgit v1.2.3 From eb813999f20097d24310836dfa07a97e2eb0c936 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: implement new vmm backend This is the common code to support a rework of the VMM backends. It adds support for more than 2 levels of page table nesting, which is required to be able to support GP100's MMU layout. Sparse mappings (that don't cause MMU faults when accessed) are now supported, where the backend provides it. Dual-PT handling had to become more sophisticated to support sparse, but this also allows us to support an optimisation the MMU provides on GK104 and newer. Certain operations can now be combined into a single page tree walk to avoid some overhead, but also enables optimsations like skipping PTE unmap writes when the PT will be destroyed anyway. The old backend has been hacked up to forward requests onto the new backend, if present, so that it's possible to bisect between issues in the backend changes vs the upcoming frontend changes. Until the new frontend has been merged, new backends will leak BAR2 page tables on module unload. This is expected, and it's not worth the effort of hacking around this as it doesn't effect runtime. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kconfig | 7 + drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 23 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 117 ++++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 580 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 112 +++++ 5 files changed, 836 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index c02a13406a81..4b75ad40dd80 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -56,6 +56,13 @@ config NOUVEAU_DEBUG_DEFAULT help Selects the default debug level +config NOUVEAU_DEBUG_MMU + bool "Enable additional MMU debugging" + depends on DRM_NOUVEAU + default n + help + Say Y here if you want to enable verbose MMU debug output. + config DRM_NOUVEAU_BACKLIGHT bool "Support for backlight control" depends on DRM_NOUVEAU diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index eb6704a2fc8f..ccd87d508d04 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -1,6 +1,7 @@ #ifndef __NVKM_MMU_H__ #define __NVKM_MMU_H__ #include +#include #include struct nvkm_gpuobj; struct nvkm_mem; @@ -11,6 +12,8 @@ struct nvkm_vm_pgt { }; struct nvkm_vma { + struct nvkm_memory *memory; + struct nvkm_tags *tags; struct nvkm_vm *vm; struct nvkm_mm_node *node; union { @@ -24,6 +27,7 @@ struct nvkm_vm { const struct nvkm_vmm_func *func; struct nvkm_mmu *mmu; const char *name; + u32 debug; struct kref kref; struct mutex mutex; @@ -58,6 +62,25 @@ void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, struct nvkm_mem *); void nvkm_vm_unmap(struct nvkm_vma *); void nvkm_vm_unmap_at(struct nvkm_vma *, u64 offset, u64 length); +int nvkm_vmm_boot(struct nvkm_vmm *); + +struct nvkm_vmm_map { + struct nvkm_memory *memory; + u64 offset; + + struct nvkm_mm_node *mem; + struct scatterlist *sgl; + dma_addr_t *dma; + u64 off; + + const struct nvkm_vmm_page *page; + + struct nvkm_tags *tags; + u64 next; + u64 type; + u64 ctag; +}; + struct nvkm_mmu { const struct nvkm_mmu_func *func; struct nvkm_subdev subdev; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 22264d3db22f..536187952372 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -213,6 +213,36 @@ nvkm_mmu_ptc_get(struct nvkm_mmu *mmu, u32 size, u32 align, bool zero) return pt; } +static void +nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, + struct nvkm_mem *mem, nvkm_vmm_pte_func fn, + struct nvkm_vmm_map *map) +{ + struct nvkm_vmm *vmm = vma->vm; + void *argv = NULL; + u32 argc = 0; + int ret; + + map->memory = mem->memory; + map->page = page; + + if (vmm->func->valid) { + ret = vmm->func->valid(vmm, argv, argc, map); + if (WARN_ON(ret)) + return; + } + + mutex_lock(&vmm->mutex); + nvkm_vmm_ptes_map(vmm, page, ((u64)vma->node->offset << 12) + delta, + (u64)vma->node->length << 12, map, fn); + mutex_unlock(&vmm->mutex); + + nvkm_memory_tags_put(vma->memory, vmm->mmu->subdev.device, &vma->tags); + nvkm_memory_unref(&vma->memory); + vma->memory = nvkm_memory_ref(map->memory); + vma->tags = map->tags; +} + void nvkm_mmu_ptc_dump(struct nvkm_mmu *mmu) { @@ -251,6 +281,7 @@ nvkm_mmu_ptc_init(struct nvkm_mmu *mmu) void nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) { + const struct nvkm_vmm_page *page = vma->vm->func->page; struct nvkm_vm *vm = vma->vm; struct nvkm_mmu *mmu = vm->mmu; struct nvkm_mm_node *r = node->mem; @@ -262,6 +293,14 @@ nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) u32 max = 1 << (mmu->func->pgt_bits - bits); u32 end, len; + if (page->desc->func->unmap) { + struct nvkm_vmm_map map = { .mem = node->mem }; + while (page->shift != vma->node->type) + page++; + nvkm_vm_map_(page, vma, delta, node, page->desc->func->mem, &map); + return; + } + delta = 0; while (r) { u64 phys = (u64)r->offset << 12; @@ -297,6 +336,7 @@ static void nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length, struct nvkm_mem *mem) { + const struct nvkm_vmm_page *page = vma->vm->func->page; struct nvkm_vm *vm = vma->vm; struct nvkm_mmu *mmu = vm->mmu; int big = vma->node->type != mmu->func->spg_shift; @@ -311,6 +351,14 @@ nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length, int i; struct scatterlist *sg; + if (page->desc->func->unmap) { + struct nvkm_vmm_map map = { .sgl = mem->sg->sgl }; + while (page->shift != vma->node->type) + page++; + nvkm_vm_map_(page, vma, delta, mem, page->desc->func->sgl, &map); + return; + } + for_each_sg(mem->sg->sgl, sg, mem->sg->nents, i) { struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; sglen = sg_dma_len(sg) >> PAGE_SHIFT; @@ -355,6 +403,7 @@ static void nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length, struct nvkm_mem *mem) { + const struct nvkm_vmm_page *page = vma->vm->func->page; struct nvkm_vm *vm = vma->vm; struct nvkm_mmu *mmu = vm->mmu; dma_addr_t *list = mem->pages; @@ -367,6 +416,14 @@ nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length, u32 max = 1 << (mmu->func->pgt_bits - bits); u32 end, len; + if (page->desc->func->unmap) { + struct nvkm_vmm_map map = { .dma = mem->pages }; + while (page->shift != vma->node->type) + page++; + nvkm_vm_map_(page, vma, delta, mem, page->desc->func->dma, &map); + return; + } + while (num) { struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; @@ -415,6 +472,17 @@ nvkm_vm_unmap_at(struct nvkm_vma *vma, u64 delta, u64 length) u32 max = 1 << (mmu->func->pgt_bits - bits); u32 end, len; + if (vm->func->page->desc->func->unmap) { + const struct nvkm_vmm_page *page = vm->func->page; + while (page->shift != vma->node->type) + page++; + mutex_lock(&vm->mutex); + nvkm_vmm_ptes_unmap(vm, page, (vma->node->offset << 12) + delta, + vma->node->length << 12, false); + mutex_unlock(&vm->mutex); + return; + } + while (num) { struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; @@ -440,6 +508,9 @@ void nvkm_vm_unmap(struct nvkm_vma *vma) { nvkm_vm_unmap_at(vma, 0, (u64)vma->node->length << 12); + + nvkm_memory_tags_put(vma->memory, vma->vm->mmu->subdev.device, &vma->tags); + nvkm_memory_unref(&vma->memory); } static void @@ -509,6 +580,22 @@ nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access, return ret; } + if (vm->func->page->desc->func->unmap) { + const struct nvkm_vmm_page *page = vm->func->page; + while (page->shift != page_shift) + page++; + + ret = nvkm_vmm_ptes_get(vm, page, vma->node->offset << 12, + vma->node->length << 12); + if (ret) { + nvkm_mm_free(&vm->mm, &vma->node); + mutex_unlock(&vm->mutex); + return ret; + } + + goto done; + } + fpde = (vma->node->offset >> mmu->func->pgt_bits); lpde = (vma->node->offset + vma->node->length - 1) >> mmu->func->pgt_bits; @@ -530,8 +617,11 @@ nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access, return ret; } } +done: mutex_unlock(&vm->mutex); + vma->memory = NULL; + vma->tags = NULL; vma->vm = NULL; nvkm_vm_ref(vm, &vma->vm, NULL); vma->offset = (u64)vma->node->offset << 12; @@ -551,11 +641,25 @@ nvkm_vm_put(struct nvkm_vma *vma) vm = vma->vm; mmu = vm->mmu; + nvkm_memory_tags_put(vma->memory, mmu->subdev.device, &vma->tags); + nvkm_memory_unref(&vma->memory); + fpde = (vma->node->offset >> mmu->func->pgt_bits); lpde = (vma->node->offset + vma->node->length - 1) >> mmu->func->pgt_bits; mutex_lock(&vm->mutex); + if (vm->func->page->desc->func->unmap) { + const struct nvkm_vmm_page *page = vm->func->page; + while (page->shift != vma->node->type) + page++; + + nvkm_vmm_ptes_put(vm, page, vma->node->offset << 12, + vma->node->length << 12); + goto done; + } + nvkm_vm_unmap_pgt(vm, vma->node->type != mmu->func->spg_shift, fpde, lpde); +done: nvkm_mm_free(&vm->mm, &vma->node); mutex_unlock(&vm->mutex); @@ -569,6 +673,9 @@ nvkm_vm_boot(struct nvkm_vm *vm, u64 size) struct nvkm_memory *pgt; int ret; + if (vm->func->page->desc->func->unmap) + return nvkm_vmm_boot(vm); + ret = nvkm_memory_new(mmu->subdev.device, NVKM_MEM_TARGET_INST, (size >> mmu->func->spg_shift) * 8, 0x1000, true, &pgt); if (ret == 0) { @@ -660,7 +767,7 @@ nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) if (ret) return ret; - if (ref->mmu->func->map_pgt) { + if (!ref->func->page->desc->func->unmap && ref->mmu->func->map_pgt) { for (i = ref->fpde; i <= ref->lpde; i++) ref->mmu->func->map_pgt(ref, i, ref->pgt[i - ref->fpde].mem); } @@ -672,8 +779,12 @@ nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) if (*ptr) { if ((*ptr)->func->part && inst) (*ptr)->func->part(*ptr, inst); - if ((*ptr)->bootstrapped && inst) - nvkm_memory_unref(&(*ptr)->pgt[0].mem[0]); + if ((*ptr)->bootstrapped && inst) { + if (!(*ptr)->func->page->desc->func->unmap) { + nvkm_memory_unref(&(*ptr)->pgt[0].mem[0]); + (*ptr)->bootstrapped = false; + } + } kref_put(&(*ptr)->refcount, nvkm_vm_del); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 7e00b9adca05..46c7fecf0054 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -67,9 +67,559 @@ nvkm_vmm_pt_new(const struct nvkm_vmm_desc *desc, bool sparse, return pgt; } +struct nvkm_vmm_iter { + const struct nvkm_vmm_page *page; + const struct nvkm_vmm_desc *desc; + struct nvkm_vmm *vmm; + u64 cnt; + u16 max, lvl; + u32 pte[NVKM_VMM_LEVELS_MAX]; + struct nvkm_vmm_pt *pt[NVKM_VMM_LEVELS_MAX]; + int flush; +}; + +#ifdef CONFIG_NOUVEAU_DEBUG_MMU +static const char * +nvkm_vmm_desc_type(const struct nvkm_vmm_desc *desc) +{ + switch (desc->type) { + case PGD: return "PGD"; + case PGT: return "PGT"; + case SPT: return "SPT"; + case LPT: return "LPT"; + default: + return "UNKNOWN"; + } +} + +static void +nvkm_vmm_trace(struct nvkm_vmm_iter *it, char *buf) +{ + int lvl; + for (lvl = it->max; lvl >= 0; lvl--) { + if (lvl >= it->lvl) + buf += sprintf(buf, "%05x:", it->pte[lvl]); + else + buf += sprintf(buf, "xxxxx:"); + } +} + +#define TRA(i,f,a...) do { \ + char _buf[NVKM_VMM_LEVELS_MAX * 7]; \ + struct nvkm_vmm_iter *_it = (i); \ + nvkm_vmm_trace(_it, _buf); \ + VMM_TRACE(_it->vmm, "%s "f, _buf, ##a); \ +} while(0) +#else +#define TRA(i,f,a...) +#endif + +static inline void +nvkm_vmm_flush_mark(struct nvkm_vmm_iter *it) +{ + it->flush = min(it->flush, it->max - it->lvl); +} + +static inline void +nvkm_vmm_flush(struct nvkm_vmm_iter *it) +{ + if (it->flush != NVKM_VMM_LEVELS_MAX) { + if (it->vmm->func->flush) { + TRA(it, "flush: %d", it->flush); + it->vmm->func->flush(it->vmm, it->flush); + } + it->flush = NVKM_VMM_LEVELS_MAX; + } +} + +static void +nvkm_vmm_unref_pdes(struct nvkm_vmm_iter *it) +{ + const struct nvkm_vmm_desc *desc = it->desc; + const int type = desc[it->lvl].type == SPT; + struct nvkm_vmm_pt *pgd = it->pt[it->lvl + 1]; + struct nvkm_vmm_pt *pgt = it->pt[it->lvl]; + struct nvkm_mmu_pt *pt = pgt->pt[type]; + struct nvkm_vmm *vmm = it->vmm; + u32 pdei = it->pte[it->lvl + 1]; + + /* Recurse up the tree, unreferencing/destroying unneeded PDs. */ + it->lvl++; + if (--pgd->refs[0]) { + const struct nvkm_vmm_desc_func *func = desc[it->lvl].func; + /* PD has other valid PDEs, so we need a proper update. */ + TRA(it, "PDE unmap %s", nvkm_vmm_desc_type(&desc[it->lvl - 1])); + pgt->pt[type] = NULL; + if (!pgt->refs[!type]) { + /* PDE no longer required. */ + if (pgd->pt[0]) { + if (pgt->sparse) { + func->sparse(vmm, pgd->pt[0], pdei, 1); + pgd->pde[pdei] = NVKM_VMM_PDE_SPARSE; + } else { + func->unmap(vmm, pgd->pt[0], pdei, 1); + pgd->pde[pdei] = NULL; + } + } else { + /* Special handling for Tesla-class GPUs, + * where there's no central PD, but each + * instance has its own embedded PD. + */ + func->pde(vmm, pgd, pdei); + pgd->pde[pdei] = NULL; + } + } else { + /* PDE was pointing at dual-PTs and we're removing + * one of them, leaving the other in place. + */ + func->pde(vmm, pgd, pdei); + } + + /* GPU may have cached the PTs, flush before freeing. */ + nvkm_vmm_flush_mark(it); + nvkm_vmm_flush(it); + } else { + /* PD has no valid PDEs left, so we can just destroy it. */ + nvkm_vmm_unref_pdes(it); + } + + /* Destroy PD/PT. */ + TRA(it, "PDE free %s", nvkm_vmm_desc_type(&desc[it->lvl - 1])); + nvkm_mmu_ptc_put(vmm->mmu, vmm->bootstrapped, &pt); + if (!pgt->refs[!type]) + nvkm_vmm_pt_del(&pgt); + it->lvl--; +} + +static void +nvkm_vmm_unref_sptes(struct nvkm_vmm_iter *it, struct nvkm_vmm_pt *pgt, + const struct nvkm_vmm_desc *desc, u32 ptei, u32 ptes) +{ + const struct nvkm_vmm_desc *pair = it->page[-1].desc; + const u32 sptb = desc->bits - pair->bits; + const u32 sptn = 1 << sptb; + struct nvkm_vmm *vmm = it->vmm; + u32 spti = ptei & (sptn - 1), lpti, pteb; + + /* Determine how many SPTEs are being touched under each LPTE, + * and drop reference counts. + */ + for (lpti = ptei >> sptb; ptes; spti = 0, lpti++) { + const u32 pten = min(sptn - spti, ptes); + pgt->pte[lpti] -= pten; + ptes -= pten; + } + + /* We're done here if there's no corresponding LPT. */ + if (!pgt->refs[0]) + return; + + for (ptei = pteb = ptei >> sptb; ptei < lpti; pteb = ptei) { + /* Skip over any LPTEs that still have valid SPTEs. */ + if (pgt->pte[pteb] & NVKM_VMM_PTE_SPTES) { + for (ptes = 1, ptei++; ptei < lpti; ptes++, ptei++) { + if (!(pgt->pte[ptei] & NVKM_VMM_PTE_SPTES)) + break; + } + continue; + } + + /* As there's no more non-UNMAPPED SPTEs left in the range + * covered by a number of LPTEs, the LPTEs once again take + * control over their address range. + * + * Determine how many LPTEs need to transition state. + */ + pgt->pte[ptei] &= ~NVKM_VMM_PTE_VALID; + for (ptes = 1, ptei++; ptei < lpti; ptes++, ptei++) { + if (pgt->pte[ptei] & NVKM_VMM_PTE_SPTES) + break; + pgt->pte[ptei] &= ~NVKM_VMM_PTE_VALID; + } + + if (pgt->pte[pteb] & NVKM_VMM_PTE_SPARSE) { + TRA(it, "LPTE %05x: U -> S %d PTEs", pteb, ptes); + pair->func->sparse(vmm, pgt->pt[0], pteb, ptes); + } else + if (pair->func->invalid) { + /* If the MMU supports it, restore the LPTE to the + * INVALID state to tell the MMU there is no point + * trying to fetch the corresponding SPTEs. + */ + TRA(it, "LPTE %05x: U -> I %d PTEs", pteb, ptes); + pair->func->invalid(vmm, pgt->pt[0], pteb, ptes); + } + } +} + +static bool +nvkm_vmm_unref_ptes(struct nvkm_vmm_iter *it, u32 ptei, u32 ptes) +{ + const struct nvkm_vmm_desc *desc = it->desc; + const int type = desc->type == SPT; + struct nvkm_vmm_pt *pgt = it->pt[0]; + + /* Drop PTE references. */ + pgt->refs[type] -= ptes; + + /* Dual-PTs need special handling, unless PDE becoming invalid. */ + if (desc->type == SPT && (pgt->refs[0] || pgt->refs[1])) + nvkm_vmm_unref_sptes(it, pgt, desc, ptei, ptes); + + /* PT no longer neeed? Destroy it. */ + if (!pgt->refs[type]) { + it->lvl++; + TRA(it, "%s empty", nvkm_vmm_desc_type(desc)); + it->lvl--; + nvkm_vmm_unref_pdes(it); + return false; /* PTE writes for unmap() not necessary. */ + } + + return true; +} + +static void +nvkm_vmm_ref_sptes(struct nvkm_vmm_iter *it, struct nvkm_vmm_pt *pgt, + const struct nvkm_vmm_desc *desc, u32 ptei, u32 ptes) +{ + const struct nvkm_vmm_desc *pair = it->page[-1].desc; + const u32 sptb = desc->bits - pair->bits; + const u32 sptn = 1 << sptb; + struct nvkm_vmm *vmm = it->vmm; + u32 spti = ptei & (sptn - 1), lpti, pteb; + + /* Determine how many SPTEs are being touched under each LPTE, + * and increase reference counts. + */ + for (lpti = ptei >> sptb; ptes; spti = 0, lpti++) { + const u32 pten = min(sptn - spti, ptes); + pgt->pte[lpti] += pten; + ptes -= pten; + } + + /* We're done here if there's no corresponding LPT. */ + if (!pgt->refs[0]) + return; + + for (ptei = pteb = ptei >> sptb; ptei < lpti; pteb = ptei) { + /* Skip over any LPTEs that already have valid SPTEs. */ + if (pgt->pte[pteb] & NVKM_VMM_PTE_VALID) { + for (ptes = 1, ptei++; ptei < lpti; ptes++, ptei++) { + if (!(pgt->pte[ptei] & NVKM_VMM_PTE_VALID)) + break; + } + continue; + } + + /* As there are now non-UNMAPPED SPTEs in the range covered + * by a number of LPTEs, we need to transfer control of the + * address range to the SPTEs. + * + * Determine how many LPTEs need to transition state. + */ + pgt->pte[ptei] |= NVKM_VMM_PTE_VALID; + for (ptes = 1, ptei++; ptei < lpti; ptes++, ptei++) { + if (pgt->pte[ptei] & NVKM_VMM_PTE_VALID) + break; + pgt->pte[ptei] |= NVKM_VMM_PTE_VALID; + } + + if (pgt->pte[pteb] & NVKM_VMM_PTE_SPARSE) { + const u32 spti = pteb * sptn; + const u32 sptc = ptes * sptn; + /* The entire LPTE is marked as sparse, we need + * to make sure that the SPTEs are too. + */ + TRA(it, "SPTE %05x: U -> S %d PTEs", spti, sptc); + desc->func->sparse(vmm, pgt->pt[1], spti, sptc); + /* Sparse LPTEs prevent SPTEs from being accessed. */ + TRA(it, "LPTE %05x: S -> U %d PTEs", pteb, ptes); + pair->func->unmap(vmm, pgt->pt[0], pteb, ptes); + } else + if (pair->func->invalid) { + /* MMU supports blocking SPTEs by marking an LPTE + * as INVALID. We need to reverse that here. + */ + TRA(it, "LPTE %05x: I -> U %d PTEs", pteb, ptes); + pair->func->unmap(vmm, pgt->pt[0], pteb, ptes); + } + } +} + +static bool +nvkm_vmm_ref_ptes(struct nvkm_vmm_iter *it, u32 ptei, u32 ptes) +{ + const struct nvkm_vmm_desc *desc = it->desc; + const int type = desc->type == SPT; + struct nvkm_vmm_pt *pgt = it->pt[0]; + + /* Take PTE references. */ + pgt->refs[type] += ptes; + + /* Dual-PTs need special handling. */ + if (desc->type == SPT) + nvkm_vmm_ref_sptes(it, pgt, desc, ptei, ptes); + + return true; +} + +static void +nvkm_vmm_sparse_ptes(const struct nvkm_vmm_desc *desc, + struct nvkm_vmm_pt *pgt, u32 ptei, u32 ptes) +{ + if (desc->type == PGD) { + while (ptes--) + pgt->pde[ptei++] = NVKM_VMM_PDE_SPARSE; + } else + if (desc->type == LPT) { + memset(&pgt->pte[ptei], NVKM_VMM_PTE_SPARSE, ptes); + } +} + +static bool +nvkm_vmm_ref_hwpt(struct nvkm_vmm_iter *it, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + const struct nvkm_vmm_desc *desc = &it->desc[it->lvl - 1]; + const int type = desc->type == SPT; + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + const bool zero = !pgt->sparse && !desc->func->invalid; + struct nvkm_vmm *vmm = it->vmm; + struct nvkm_mmu *mmu = vmm->mmu; + struct nvkm_mmu_pt *pt; + u32 pten = 1 << desc->bits; + u32 pteb, ptei, ptes; + u32 size = desc->size * pten; + + pgd->refs[0]++; + + pgt->pt[type] = nvkm_mmu_ptc_get(mmu, size, desc->align, zero); + if (!pgt->pt[type]) { + it->lvl--; + nvkm_vmm_unref_pdes(it); + return false; + } + + if (zero) + goto done; + + pt = pgt->pt[type]; + + if (desc->type == LPT && pgt->refs[1]) { + /* SPT already exists covering the same range as this LPT, + * which means we need to be careful that any LPTEs which + * overlap valid SPTEs are unmapped as opposed to invalid + * or sparse, which would prevent the MMU from looking at + * the SPTEs on some GPUs. + */ + for (ptei = pteb = 0; ptei < pten; pteb = ptei) { + bool spte = pgt->pte[ptei] & NVKM_VMM_PTE_SPTES; + for (ptes = 1, ptei++; ptei < pten; ptes++, ptei++) { + bool next = pgt->pte[ptei] & NVKM_VMM_PTE_SPTES; + if (spte != next) + break; + } + + if (!spte) { + if (pgt->sparse) + desc->func->sparse(vmm, pt, pteb, ptes); + else + desc->func->invalid(vmm, pt, pteb, ptes); + memset(&pgt->pte[pteb], 0x00, ptes); + } else { + desc->func->unmap(vmm, pt, pteb, ptes); + while (ptes--) + pgt->pte[pteb++] |= NVKM_VMM_PTE_VALID; + } + } + } else { + if (pgt->sparse) { + nvkm_vmm_sparse_ptes(desc, pgt, 0, pten); + desc->func->sparse(vmm, pt, 0, pten); + } else { + desc->func->invalid(vmm, pt, 0, pten); + } + } + +done: + TRA(it, "PDE write %s", nvkm_vmm_desc_type(desc)); + it->desc[it->lvl].func->pde(it->vmm, pgd, pdei); + nvkm_vmm_flush_mark(it); + return true; +} + +static bool +nvkm_vmm_ref_swpt(struct nvkm_vmm_iter *it, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + const struct nvkm_vmm_desc *desc = &it->desc[it->lvl - 1]; + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + + pgt = nvkm_vmm_pt_new(desc, NVKM_VMM_PDE_SPARSED(pgt), it->page); + if (!pgt) { + if (!pgd->refs[0]) + nvkm_vmm_unref_pdes(it); + return false; + } + + pgd->pde[pdei] = pgt; + return true; +} + +static inline u64 +nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size, const char *name, bool ref, + bool (*REF_PTES)(struct nvkm_vmm_iter *, u32, u32), + nvkm_vmm_pte_func MAP_PTES, struct nvkm_vmm_map *map, + nvkm_vmm_pxe_func CLR_PTES) +{ + const struct nvkm_vmm_desc *desc = page->desc; + struct nvkm_vmm_iter it; + u64 bits = addr >> page->shift; + + it.page = page; + it.desc = desc; + it.vmm = vmm; + it.cnt = size >> page->shift; + it.flush = NVKM_VMM_LEVELS_MAX; + + /* Deconstruct address into PTE indices for each mapping level. */ + for (it.lvl = 0; desc[it.lvl].bits; it.lvl++) { + it.pte[it.lvl] = bits & ((1 << desc[it.lvl].bits) - 1); + bits >>= desc[it.lvl].bits; + } + it.max = --it.lvl; + it.pt[it.max] = vmm->pd; + + it.lvl = 0; + TRA(&it, "%s: %016llx %016llx %d %lld PTEs", name, + addr, size, page->shift, it.cnt); + it.lvl = it.max; + + /* Depth-first traversal of page tables. */ + while (it.cnt) { + struct nvkm_vmm_pt *pgt = it.pt[it.lvl]; + const int type = desc->type == SPT; + const u32 pten = 1 << desc->bits; + const u32 ptei = it.pte[0]; + const u32 ptes = min_t(u64, it.cnt, pten - ptei); + + /* Walk down the tree, finding page tables for each level. */ + for (; it.lvl; it.lvl--) { + const u32 pdei = it.pte[it.lvl]; + struct nvkm_vmm_pt *pgd = pgt; + + /* Software PT. */ + if (ref && NVKM_VMM_PDE_INVALID(pgd->pde[pdei])) { + if (!nvkm_vmm_ref_swpt(&it, pgd, pdei)) + goto fail; + } + it.pt[it.lvl - 1] = pgt = pgd->pde[pdei]; + + /* Hardware PT. + * + * This is a separate step from above due to GF100 and + * newer having dual page tables at some levels, which + * are refcounted independently. + */ + if (ref && !pgt->refs[desc[it.lvl - 1].type == SPT]) { + if (!nvkm_vmm_ref_hwpt(&it, pgd, pdei)) + goto fail; + } + } + + /* Handle PTE updates. */ + if (!REF_PTES || REF_PTES(&it, ptei, ptes)) { + struct nvkm_mmu_pt *pt = pgt->pt[type]; + if (MAP_PTES || CLR_PTES) { + if (MAP_PTES) + MAP_PTES(vmm, pt, ptei, ptes, map); + else + CLR_PTES(vmm, pt, ptei, ptes); + nvkm_vmm_flush_mark(&it); + } + } + + /* Walk back up the tree to the next position. */ + it.pte[it.lvl] += ptes; + it.cnt -= ptes; + if (it.cnt) { + while (it.pte[it.lvl] == (1 << desc[it.lvl].bits)) { + it.pte[it.lvl++] = 0; + it.pte[it.lvl]++; + } + } + }; + + nvkm_vmm_flush(&it); + return ~0ULL; + +fail: + /* Reconstruct the failure address so the caller is able to + * reverse any partially completed operations. + */ + addr = it.pte[it.max--]; + do { + addr = addr << desc[it.max].bits; + addr |= it.pte[it.max]; + } while (it.max--); + + return addr << page->shift; +} + +void +nvkm_vmm_ptes_unmap(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size, bool sparse) +{ + const struct nvkm_vmm_desc_func *func = page->desc->func; + nvkm_vmm_iter(vmm, page, addr, size, "unmap", false, NULL, NULL, NULL, + sparse ? func->sparse : func->invalid ? func->invalid : + func->unmap); +} + +void +nvkm_vmm_ptes_map(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size, struct nvkm_vmm_map *map, + nvkm_vmm_pte_func func) +{ + nvkm_vmm_iter(vmm, page, addr, size, "map", false, + NULL, func, map, NULL); +} + +void +nvkm_vmm_ptes_put(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size) +{ + nvkm_vmm_iter(vmm, page, addr, size, "unref", false, + nvkm_vmm_unref_ptes, NULL, NULL, NULL); +} + +int +nvkm_vmm_ptes_get(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size) +{ + u64 fail = nvkm_vmm_iter(vmm, page, addr, size, "ref", true, + nvkm_vmm_ref_ptes, NULL, NULL, NULL); + if (fail != ~0ULL) { + if (fail != addr) + nvkm_vmm_ptes_put(vmm, page, addr, fail - addr); + return -ENOMEM; + } + return 0; +} + void nvkm_vmm_dtor(struct nvkm_vmm *vmm) { + if (vmm->bootstrapped) { + const struct nvkm_vmm_page *page = vmm->func->page; + const u64 limit = vmm->limit - vmm->start; + + while (page[1].shift) + page++; + + nvkm_mmu_ptc_dump(vmm->mmu); + nvkm_vmm_ptes_put(vmm, page, vmm->start, limit); + } + if (vmm->nullp) { dma_free_coherent(vmm->mmu->subdev.device->dev, 16 * 1024, vmm->nullp, vmm->null); @@ -94,6 +644,7 @@ nvkm_vmm_ctor(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, vmm->func = func; vmm->mmu = mmu; vmm->name = name; + vmm->debug = mmu->subdev.debug; kref_init(&vmm->kref); __mutex_init(&vmm->mutex, "&vmm->mutex", key ? key : &_key); @@ -150,3 +701,32 @@ nvkm_vmm_new_(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, return -ENOMEM; return nvkm_vmm_ctor(func, mmu, hdr, addr, size, key, name, *pvmm); } + +static bool +nvkm_vmm_boot_ptes(struct nvkm_vmm_iter *it, u32 ptei, u32 ptes) +{ + const struct nvkm_vmm_desc *desc = it->desc; + const int type = desc->type == SPT; + nvkm_memory_boot(it->pt[0]->pt[type]->memory, it->vmm); + return false; +} + +int +nvkm_vmm_boot(struct nvkm_vmm *vmm) +{ + const struct nvkm_vmm_page *page = vmm->func->page; + const u64 limit = vmm->limit - vmm->start; + int ret; + + while (page[1].shift) + page++; + + ret = nvkm_vmm_ptes_get(vmm, page, vmm->start, limit); + if (ret) + return ret; + + nvkm_vmm_iter(vmm, page, vmm->start, limit, "bootstrap", false, + nvkm_vmm_boot_ptes, NULL, NULL, NULL); + vmm->bootstrapped = true; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 504408d8014b..042d84c5e950 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -2,6 +2,7 @@ #define __NVKM_VMM_H__ #include "priv.h" #include +enum nvkm_memory_target; struct nvkm_vmm_pt { /* Some GPUs have a mapping level with a dual page tables to @@ -49,7 +50,23 @@ struct nvkm_vmm_pt { u8 pte[]; }; +typedef void (*nvkm_vmm_pxe_func)(struct nvkm_vmm *, + struct nvkm_mmu_pt *, u32 ptei, u32 ptes); +typedef void (*nvkm_vmm_pde_func)(struct nvkm_vmm *, + struct nvkm_vmm_pt *, u32 pdei); +typedef void (*nvkm_vmm_pte_func)(struct nvkm_vmm *, struct nvkm_mmu_pt *, + u32 ptei, u32 ptes, struct nvkm_vmm_map *); + struct nvkm_vmm_desc_func { + nvkm_vmm_pxe_func invalid; + nvkm_vmm_pxe_func unmap; + nvkm_vmm_pxe_func sparse; + + nvkm_vmm_pde_func pde; + + nvkm_vmm_pte_func mem; + nvkm_vmm_pte_func dma; + nvkm_vmm_pte_func sgl; }; extern const struct nvkm_vmm_desc_func gf100_vmm_pgd; @@ -106,6 +123,11 @@ struct nvkm_vmm_func { int (*join)(struct nvkm_vmm *, struct nvkm_memory *inst); void (*part)(struct nvkm_vmm *, struct nvkm_memory *inst); + int (*aper)(enum nvkm_memory_target); + int (*valid)(struct nvkm_vmm *, void *argv, u32 argc, + struct nvkm_vmm_map *); + void (*flush)(struct nvkm_vmm *, int depth); + u64 page_block; const struct nvkm_vmm_page page[]; }; @@ -122,6 +144,15 @@ int nvkm_vmm_ctor(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32 pd_header, u64 addr, u64 size, struct lock_class_key *, const char *name, struct nvkm_vmm *); void nvkm_vmm_dtor(struct nvkm_vmm *); +void nvkm_vmm_ptes_put(struct nvkm_vmm *, const struct nvkm_vmm_page *, + u64 addr, u64 size); +int nvkm_vmm_ptes_get(struct nvkm_vmm *, const struct nvkm_vmm_page *, + u64 addr, u64 size); +void nvkm_vmm_ptes_map(struct nvkm_vmm *, const struct nvkm_vmm_page *, + u64 addr, u64 size, struct nvkm_vmm_map *, + nvkm_vmm_pte_func); +void nvkm_vmm_ptes_unmap(struct nvkm_vmm *, const struct nvkm_vmm_page *, + u64 addr, u64 size, bool sparse); int nv04_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32, u64, u64, void *, u32, struct lock_class_key *, @@ -176,4 +207,85 @@ int gp100_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, int gp10b_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); + +#define VMM_PRINT(l,v,p,f,a...) do { \ + struct nvkm_vmm *_vmm = (v); \ + if (CONFIG_NOUVEAU_DEBUG >= (l) && _vmm->debug >= (l)) { \ + nvkm_printk_(&_vmm->mmu->subdev, 0, p, "%s: "f"\n", \ + _vmm->name, ##a); \ + } \ +} while(0) +#define VMM_DEBUG(v,f,a...) VMM_PRINT(NV_DBG_DEBUG, (v), info, f, ##a) +#define VMM_TRACE(v,f,a...) VMM_PRINT(NV_DBG_TRACE, (v), info, f, ##a) +#define VMM_SPAM(v,f,a...) VMM_PRINT(NV_DBG_SPAM , (v), dbg, f, ##a) + +#define VMM_MAP_ITER(VMM,PT,PTEI,PTEN,MAP,FILL,BASE,SIZE,NEXT) do { \ + nvkm_kmap((PT)->memory); \ + while (PTEN) { \ + u64 _ptes = ((SIZE) - MAP->off) >> MAP->page->shift; \ + u64 _addr = ((BASE) + MAP->off); \ + \ + if (_ptes > PTEN) { \ + MAP->off += PTEN << MAP->page->shift; \ + _ptes = PTEN; \ + } else { \ + MAP->off = 0; \ + NEXT; \ + } \ + \ + VMM_SPAM(VMM, "ITER %08x %08x PTE(s)", PTEI, (u32)_ptes); \ + \ + FILL(VMM, PT, PTEI, _ptes, MAP, _addr); \ + PTEI += _ptes; \ + PTEN -= _ptes; \ + }; \ + nvkm_done((PT)->memory); \ +} while(0) + +#define VMM_MAP_ITER_MEM(VMM,PT,PTEI,PTEN,MAP,FILL) \ + VMM_MAP_ITER(VMM,PT,PTEI,PTEN,MAP,FILL, \ + ((u64)MAP->mem->offset << NVKM_RAM_MM_SHIFT), \ + ((u64)MAP->mem->length << NVKM_RAM_MM_SHIFT), \ + (MAP->mem = MAP->mem->next)) +#define VMM_MAP_ITER_DMA(VMM,PT,PTEI,PTEN,MAP,FILL) \ + VMM_MAP_ITER(VMM,PT,PTEI,PTEN,MAP,FILL, \ + *MAP->dma, PAGE_SIZE, MAP->dma++) +#define VMM_MAP_ITER_SGL(VMM,PT,PTEI,PTEN,MAP,FILL) \ + VMM_MAP_ITER(VMM,PT,PTEI,PTEN,MAP,FILL, \ + sg_dma_address(MAP->sgl), sg_dma_len(MAP->sgl), \ + (MAP->sgl = sg_next(MAP->sgl))) + +#define VMM_FO(m,o,d,c,b) nvkm_fo##b((m)->memory, (o), (d), (c)) +#define VMM_WO(m,o,d,c,b) nvkm_wo##b((m)->memory, (o), (d)) +#define VMM_XO(m,v,o,d,c,b,fn,f,a...) do { \ + const u32 _pteo = (o); u##b _data = (d); \ + VMM_SPAM((v), " %010llx "f, (m)->addr + _pteo, _data, ##a); \ + VMM_##fn((m), (m)->base + _pteo, _data, (c), b); \ +} while(0) + +#define VMM_WO032(m,v,o,d) VMM_XO((m),(v),(o),(d), 1, 32, WO, "%08x") +#define VMM_FO032(m,v,o,d,c) \ + VMM_XO((m),(v),(o),(d),(c), 32, FO, "%08x %08x", (c)) + +#define VMM_WO064(m,v,o,d) VMM_XO((m),(v),(o),(d), 1, 64, WO, "%016llx") +#define VMM_FO064(m,v,o,d,c) \ + VMM_XO((m),(v),(o),(d),(c), 64, FO, "%016llx %08x", (c)) + +#define VMM_XO128(m,v,o,lo,hi,c,f,a...) do { \ + u32 _pteo = (o), _ptes = (c); \ + const u64 _addr = (m)->addr + _pteo; \ + VMM_SPAM((v), " %010llx %016llx%016llx"f, _addr, (hi), (lo), ##a); \ + while (_ptes--) { \ + nvkm_wo64((m)->memory, (m)->base + _pteo + 0, (lo)); \ + nvkm_wo64((m)->memory, (m)->base + _pteo + 8, (hi)); \ + _pteo += 0x10; \ + } \ +} while(0) + +#define VMM_WO128(m,v,o,lo,hi) VMM_XO128((m),(v),(o),(lo),(hi), 1, "") +#define VMM_FO128(m,v,o,lo,hi,c) do { \ + nvkm_kmap((m)->memory); \ + VMM_XO128((m),(v),(o),(lo),(hi),(c), " %08x", (c)); \ + nvkm_done((m)->memory); \ +} while(0) #endif -- cgit v1.2.3 From dd12d158eb91442674111a423d88abee4180b5a9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv04: implement new vmm backend Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/if000d.h | 4 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 57 ---------------------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c | 58 ++++++++++++++++++++++- 4 files changed, 62 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000d.h b/drivers/gpu/drm/nouveau/include/nvif/if000d.h index 0f94eb5005b1..516ec9401401 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if000d.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if000d.h @@ -5,4 +5,8 @@ struct nv04_vmm_vn { /* nvif_vmm_vX ... */ }; + +struct nv04_vmm_map_vn { + /* nvif_vmm_map_vX ... */ +}; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 3e6036431754..13438dbc6063 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -26,71 +26,14 @@ #include #define NV04_PDMA_SIZE (128 * 1024 * 1024) -#define NV04_PDMA_PAGE ( 4 * 1024) - -/******************************************************************************* - * VM map/unmap callbacks - ******************************************************************************/ - -static void -nv04_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, - struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) -{ - pte = 0x00008 + (pte * 4); - nvkm_kmap(pgt); - while (cnt) { - u32 page = PAGE_SIZE / NV04_PDMA_PAGE; - u32 phys = (u32)*list++; - while (cnt && page--) { - nvkm_wo32(pgt, pte, phys | 3); - phys += NV04_PDMA_PAGE; - pte += 4; - cnt -= 1; - } - } - nvkm_done(pgt); -} - -static void -nv04_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) -{ - pte = 0x00008 + (pte * 4); - nvkm_kmap(pgt); - while (cnt--) { - nvkm_wo32(pgt, pte, 0x00000000); - pte += 4; - } - nvkm_done(pgt); -} - -static void -nv04_vm_flush(struct nvkm_vm *vm) -{ -} - -/******************************************************************************* - * MMU subdev - ******************************************************************************/ - -static int -nv04_mmu_oneinit(struct nvkm_mmu *mmu) -{ - mmu->vmm->pgt[0].mem[0] = mmu->vmm->pd->pt[0]->memory; - mmu->vmm->pgt[0].refcount[0] = 1; - return 0; -} const struct nvkm_mmu_func nv04_mmu = { - .oneinit = nv04_mmu_oneinit, .limit = NV04_PDMA_SIZE, .dma_bits = 32, .pgt_bits = 32 - 12, .spg_shift = 12, .lpg_shift = 12, - .map_sg = nv04_vm_map_sg, - .unmap = nv04_vm_unmap, - .flush = nv04_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv04_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 042d84c5e950..cbb8d47fbd11 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -157,6 +157,7 @@ void nvkm_vmm_ptes_unmap(struct nvkm_vmm *, const struct nvkm_vmm_page *, int nv04_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int nv04_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *); int gf100_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, struct nvkm_mmu *, u64, u64, void *, u32, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c index 1f874b351a39..0cab1ffc9f64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c @@ -24,8 +24,50 @@ #include #include +static inline void +nv04_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u32 data = addr | 0x00000003; /* PRESENT, RW. */ + while (ptes--) { + VMM_WO032(pt, vmm, 8 + ptei++ * 4, data); + data += 0x00001000; + } +} + +static void +nv04_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, nv04_vmm_pgt_pte); +} + +static void +nv04_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ +#if PAGE_SHIFT == 12 + nvkm_kmap(pt->memory); + while (ptes--) + VMM_WO032(pt, vmm, 8 + (ptei++ * 4), *map->dma++ | 0x00000003); + nvkm_done(pt->memory); +#else + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, nv04_vmm_pgt_pte); +#endif +} + +static void +nv04_vmm_pgt_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + VMM_FO032(pt, vmm, 8 + (ptei * 4), 0, ptes); +} + static const struct nvkm_vmm_desc_func nv04_vmm_desc_pgt = { + .unmap = nv04_vmm_pgt_unmap, + .dma = nv04_vmm_pgt_dma, + .sgl = nv04_vmm_pgt_sgl, }; static const struct nvkm_vmm_desc @@ -34,8 +76,22 @@ nv04_vmm_desc_12[] = { {} }; +int +nv04_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, + struct nvkm_vmm_map *map) +{ + union { + struct nv04_vmm_map_vn vn; + } *args = argv; + int ret = -ENOSYS; + if ((ret = nvif_unvers(ret, &argv, &argc, args->vn))) + VMM_DEBUG(vmm, "args"); + return ret; +} + static const struct nvkm_vmm_func nv04_vmm = { + .valid = nv04_vmm_valid, .page = { { 12, &nv04_vmm_desc_12[0], NVKM_VMM_PAGE_HOST }, {} @@ -65,8 +121,8 @@ nv04_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, struct lock_class_key *key, const char *name, struct nvkm_vmm **pvmm) { - struct nvkm_vmm *vmm; struct nvkm_memory *mem; + struct nvkm_vmm *vmm; int ret; ret = nv04_vmm_new_(&nv04_vmm, mmu, 8, addr, size, -- cgit v1.2.3 From 473f9aca6c1063bf77cd61c2683fc496850d63b3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv41: implement new vmm backend Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c | 69 ----------------------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c | 64 +++++++++++++++++++++ 2 files changed, 64 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c index cb037f4a1780..457cf509591b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c @@ -24,75 +24,10 @@ #include "vmm.h" #include -#include #include #define NV41_GART_SIZE (512 * 1024 * 1024) -#define NV41_GART_PAGE ( 4 * 1024) - -/******************************************************************************* - * VM map/unmap callbacks - ******************************************************************************/ - -static void -nv41_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, - struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) -{ - pte = pte * 4; - nvkm_kmap(pgt); - while (cnt) { - u32 page = PAGE_SIZE / NV41_GART_PAGE; - u64 phys = (u64)*list++; - while (cnt && page--) { - nvkm_wo32(pgt, pte, (phys >> 7) | 1); - phys += NV41_GART_PAGE; - pte += 4; - cnt -= 1; - } - } - nvkm_done(pgt); -} - -static void -nv41_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) -{ - pte = pte * 4; - nvkm_kmap(pgt); - while (cnt--) { - nvkm_wo32(pgt, pte, 0x00000000); - pte += 4; - } - nvkm_done(pgt); -} - -static void -nv41_vm_flush(struct nvkm_vm *vm) -{ - struct nvkm_subdev *subdev = &vm->mmu->subdev; - struct nvkm_device *device = subdev->device; - - mutex_lock(&subdev->mutex); - nvkm_wr32(device, 0x100810, 0x00000022); - nvkm_msec(device, 2000, - if (nvkm_rd32(device, 0x100810) & 0x00000020) - break; - ); - nvkm_wr32(device, 0x100810, 0x00000000); - mutex_unlock(&subdev->mutex); -} - -/******************************************************************************* - * MMU subdev - ******************************************************************************/ - -static int -nv41_mmu_oneinit(struct nvkm_mmu *mmu) -{ - mmu->vmm->pgt[0].mem[0] = mmu->vmm->pd->pt[0]->memory; - mmu->vmm->pgt[0].refcount[0] = 1; - return 0; -} static void nv41_mmu_init(struct nvkm_mmu *mmu) @@ -105,16 +40,12 @@ nv41_mmu_init(struct nvkm_mmu *mmu) static const struct nvkm_mmu_func nv41_mmu = { - .oneinit = nv41_mmu_oneinit, .init = nv41_mmu_init, .limit = NV41_GART_SIZE, .dma_bits = 39, .pgt_bits = 32 - 12, .spg_shift = 12, .lpg_shift = 12, - .map_sg = nv41_vm_map_sg, - .unmap = nv41_vm_unmap, - .flush = nv41_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv41_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c index 8a624d7c363a..b595f130e573 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv41.c @@ -21,8 +21,54 @@ */ #include "vmm.h" +#include + +static void +nv41_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u32 data = (addr >> 7) | 0x00000001; /* VALID. */ + while (ptes--) { + VMM_WO032(pt, vmm, ptei++ * 4, data); + data += 0x00000020; + } +} + +static void +nv41_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, nv41_vmm_pgt_pte); +} + +static void +nv41_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ +#if PAGE_SHIFT == 12 + nvkm_kmap(pt->memory); + while (ptes--) { + const u32 data = (*map->dma++ >> 7) | 0x00000001; + VMM_WO032(pt, vmm, ptei++ * 4, data); + } + nvkm_done(pt->memory); +#else + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, nv41_vmm_pgt_pte); +#endif +} + +static void +nv41_vmm_pgt_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + VMM_FO032(pt, vmm, ptei * 4, 0, ptes); +} + static const struct nvkm_vmm_desc_func nv41_vmm_desc_pgt = { + .unmap = nv41_vmm_pgt_unmap, + .dma = nv41_vmm_pgt_dma, + .sgl = nv41_vmm_pgt_sgl, }; static const struct nvkm_vmm_desc @@ -31,8 +77,26 @@ nv41_vmm_desc_12[] = { {} }; +static void +nv41_vmm_flush(struct nvkm_vmm *vmm, int level) +{ + struct nvkm_subdev *subdev = &vmm->mmu->subdev; + struct nvkm_device *device = subdev->device; + + mutex_lock(&subdev->mutex); + nvkm_wr32(device, 0x100810, 0x00000022); + nvkm_msec(device, 2000, + if (nvkm_rd32(device, 0x100810) & 0x00000020) + break; + ); + nvkm_wr32(device, 0x100810, 0x00000000); + mutex_unlock(&subdev->mutex); +} + static const struct nvkm_vmm_func nv41_vmm = { + .valid = nv04_vmm_valid, + .flush = nv41_vmm_flush, .page = { { 12, &nv41_vmm_desc_12[0], NVKM_VMM_PAGE_HOST }, {} -- cgit v1.2.3 From 6ce513529aa57a8c4f61e588142643a9252037ae Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv44: implement new vmm backend Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c | 144 +------------------ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c | 165 ++++++++++++++++++++++ 2 files changed, 168 insertions(+), 141 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c index 48ca0cdf2acf..2072139bff4d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c @@ -24,150 +24,16 @@ #include "vmm.h" #include -#include #include #define NV44_GART_SIZE (512 * 1024 * 1024) -#define NV44_GART_PAGE ( 4 * 1024) - -/******************************************************************************* - * VM map/unmap callbacks - ******************************************************************************/ - -static void -nv44_vm_fill(struct nvkm_memory *pgt, dma_addr_t null, - dma_addr_t *list, u32 pte, u32 cnt) -{ - u32 base = (pte << 2) & ~0x0000000f; - u32 tmp[4]; - - tmp[0] = nvkm_ro32(pgt, base + 0x0); - tmp[1] = nvkm_ro32(pgt, base + 0x4); - tmp[2] = nvkm_ro32(pgt, base + 0x8); - tmp[3] = nvkm_ro32(pgt, base + 0xc); - - while (cnt--) { - u32 addr = list ? (*list++ >> 12) : (null >> 12); - switch (pte++ & 0x3) { - case 0: - tmp[0] &= ~0x07ffffff; - tmp[0] |= addr; - break; - case 1: - tmp[0] &= ~0xf8000000; - tmp[0] |= addr << 27; - tmp[1] &= ~0x003fffff; - tmp[1] |= addr >> 5; - break; - case 2: - tmp[1] &= ~0xffc00000; - tmp[1] |= addr << 22; - tmp[2] &= ~0x0001ffff; - tmp[2] |= addr >> 10; - break; - case 3: - tmp[2] &= ~0xfffe0000; - tmp[2] |= addr << 17; - tmp[3] &= ~0x00000fff; - tmp[3] |= addr >> 15; - break; - } - } - - nvkm_wo32(pgt, base + 0x0, tmp[0]); - nvkm_wo32(pgt, base + 0x4, tmp[1]); - nvkm_wo32(pgt, base + 0x8, tmp[2]); - nvkm_wo32(pgt, base + 0xc, tmp[3] | 0x40000000); -} - -static void -nv44_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, - struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) -{ - u32 tmp[4]; - int i; - - nvkm_kmap(pgt); - if (pte & 3) { - u32 max = 4 - (pte & 3); - u32 part = (cnt > max) ? max : cnt; - nv44_vm_fill(pgt, vma->vm->null, list, pte, part); - pte += part; - list += part; - cnt -= part; - } - - while (cnt >= 4) { - for (i = 0; i < 4; i++) - tmp[i] = *list++ >> 12; - nvkm_wo32(pgt, pte++ * 4, tmp[0] >> 0 | tmp[1] << 27); - nvkm_wo32(pgt, pte++ * 4, tmp[1] >> 5 | tmp[2] << 22); - nvkm_wo32(pgt, pte++ * 4, tmp[2] >> 10 | tmp[3] << 17); - nvkm_wo32(pgt, pte++ * 4, tmp[3] >> 15 | 0x40000000); - cnt -= 4; - } - - if (cnt) - nv44_vm_fill(pgt, vma->vm->null, list, pte, cnt); - nvkm_done(pgt); -} - -static void -nv44_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) -{ - nvkm_kmap(pgt); - if (pte & 3) { - u32 max = 4 - (pte & 3); - u32 part = (cnt > max) ? max : cnt; - nv44_vm_fill(pgt, vma->vm->null, NULL, pte, part); - pte += part; - cnt -= part; - } - - while (cnt >= 4) { - nvkm_wo32(pgt, pte++ * 4, 0x00000000); - nvkm_wo32(pgt, pte++ * 4, 0x00000000); - nvkm_wo32(pgt, pte++ * 4, 0x00000000); - nvkm_wo32(pgt, pte++ * 4, 0x00000000); - cnt -= 4; - } - - if (cnt) - nv44_vm_fill(pgt, vma->vm->null, NULL, pte, cnt); - nvkm_done(pgt); -} - -static void -nv44_vm_flush(struct nvkm_vm *vm) -{ - struct nvkm_device *device = vm->mmu->subdev.device; - nvkm_wr32(device, 0x100814, vm->mmu->limit - NV44_GART_PAGE); - nvkm_wr32(device, 0x100808, 0x00000020); - nvkm_msec(device, 2000, - if (nvkm_rd32(device, 0x100808) & 0x00000001) - break; - ); - nvkm_wr32(device, 0x100808, 0x00000000); -} - -/******************************************************************************* - * MMU subdev - ******************************************************************************/ - -static int -nv44_mmu_oneinit(struct nvkm_mmu *mmu) -{ - mmu->vmm->pgt[0].mem[0] = mmu->vmm->pd->pt[0]->memory; - mmu->vmm->pgt[0].refcount[0] = 1; - return 0; -} static void nv44_mmu_init(struct nvkm_mmu *mmu) { struct nvkm_device *device = mmu->subdev.device; - struct nvkm_memory *gart = mmu->vmm->pgt[0].mem[0]; + struct nvkm_memory *pt = mmu->vmm->pd->pt[0]->memory; u32 addr; /* calculate vram address of this PRAMIN block, object must be @@ -175,11 +41,11 @@ nv44_mmu_init(struct nvkm_mmu *mmu) * of 512KiB for this to work correctly */ addr = nvkm_rd32(device, 0x10020c); - addr -= ((nvkm_memory_addr(gart) >> 19) + 1) << 19; + addr -= ((nvkm_memory_addr(pt) >> 19) + 1) << 19; nvkm_wr32(device, 0x100850, 0x80000000); nvkm_wr32(device, 0x100818, mmu->vmm->null); - nvkm_wr32(device, 0x100804, NV44_GART_SIZE); + nvkm_wr32(device, 0x100804, (nvkm_memory_size(pt) / 4) * 4096); nvkm_wr32(device, 0x100850, 0x00008000); nvkm_mask(device, 0x10008c, 0x00000200, 0x00000200); nvkm_wr32(device, 0x100820, 0x00000000); @@ -189,16 +55,12 @@ nv44_mmu_init(struct nvkm_mmu *mmu) static const struct nvkm_mmu_func nv44_mmu = { - .oneinit = nv44_mmu_oneinit, .init = nv44_mmu_init, .limit = NV44_GART_SIZE, .dma_bits = 39, .pgt_bits = 32 - 12, .spg_shift = 12, .lpg_shift = 12, - .map_sg = nv44_vm_map_sg, - .unmap = nv44_vm_unmap, - .flush = nv44_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv44_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c index 2b5704269ac9..b834e4352334 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv44.c @@ -21,8 +21,158 @@ */ #include "vmm.h" +#include + +static void +nv44_vmm_pgt_fill(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + dma_addr_t *list, u32 ptei, u32 ptes) +{ + u32 pteo = (ptei << 2) & ~0x0000000f; + u32 tmp[4]; + + tmp[0] = nvkm_ro32(pt->memory, pteo + 0x0); + tmp[1] = nvkm_ro32(pt->memory, pteo + 0x4); + tmp[2] = nvkm_ro32(pt->memory, pteo + 0x8); + tmp[3] = nvkm_ro32(pt->memory, pteo + 0xc); + + while (ptes--) { + u32 addr = (list ? *list++ : vmm->null) >> 12; + switch (ptei++ & 0x3) { + case 0: + tmp[0] &= ~0x07ffffff; + tmp[0] |= addr; + break; + case 1: + tmp[0] &= ~0xf8000000; + tmp[0] |= addr << 27; + tmp[1] &= ~0x003fffff; + tmp[1] |= addr >> 5; + break; + case 2: + tmp[1] &= ~0xffc00000; + tmp[1] |= addr << 22; + tmp[2] &= ~0x0001ffff; + tmp[2] |= addr >> 10; + break; + case 3: + tmp[2] &= ~0xfffe0000; + tmp[2] |= addr << 17; + tmp[3] &= ~0x00000fff; + tmp[3] |= addr >> 15; + break; + } + } + + VMM_WO032(pt, vmm, pteo + 0x0, tmp[0]); + VMM_WO032(pt, vmm, pteo + 0x4, tmp[1]); + VMM_WO032(pt, vmm, pteo + 0x8, tmp[2]); + VMM_WO032(pt, vmm, pteo + 0xc, tmp[3] | 0x40000000); +} + +static void +nv44_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + dma_addr_t tmp[4], i; + + if (ptei & 3) { + const u32 pten = min(ptes, 4 - (ptei & 3)); + for (i = 0; i < pten; i++, addr += 0x1000) + tmp[i] = addr; + nv44_vmm_pgt_fill(vmm, pt, tmp, ptei, pten); + ptei += pten; + ptes -= pten; + } + + while (ptes >= 4) { + for (i = 0; i < 4; i++, addr += 0x1000) + tmp[i] = addr >> 12; + VMM_WO032(pt, vmm, ptei++ * 4, tmp[0] >> 0 | tmp[1] << 27); + VMM_WO032(pt, vmm, ptei++ * 4, tmp[1] >> 5 | tmp[2] << 22); + VMM_WO032(pt, vmm, ptei++ * 4, tmp[2] >> 10 | tmp[3] << 17); + VMM_WO032(pt, vmm, ptei++ * 4, tmp[3] >> 15 | 0x40000000); + ptes -= 4; + } + + if (ptes) { + for (i = 0; i < ptes; i++, addr += 0x1000) + tmp[i] = addr; + nv44_vmm_pgt_fill(vmm, pt, tmp, ptei, ptes); + } +} + +static void +nv44_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, nv44_vmm_pgt_pte); +} + +static void +nv44_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ +#if PAGE_SHIFT == 12 + nvkm_kmap(pt->memory); + if (ptei & 3) { + const u32 pten = min(ptes, 4 - (ptei & 3)); + nv44_vmm_pgt_fill(vmm, pt, map->dma, ptei, pten); + ptei += pten; + ptes -= pten; + map->dma += pten; + } + + while (ptes >= 4) { + u32 tmp[4], i; + for (i = 0; i < 4; i++) + tmp[i] = *map->dma++ >> 12; + VMM_WO032(pt, vmm, ptei++ * 4, tmp[0] >> 0 | tmp[1] << 27); + VMM_WO032(pt, vmm, ptei++ * 4, tmp[1] >> 5 | tmp[2] << 22); + VMM_WO032(pt, vmm, ptei++ * 4, tmp[2] >> 10 | tmp[3] << 17); + VMM_WO032(pt, vmm, ptei++ * 4, tmp[3] >> 15 | 0x40000000); + ptes -= 4; + } + + if (ptes) { + nv44_vmm_pgt_fill(vmm, pt, map->dma, ptei, ptes); + map->dma += ptes; + } + nvkm_done(pt->memory); +#else + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, nv44_vmm_pgt_pte); +#endif +} + +static void +nv44_vmm_pgt_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + nvkm_kmap(pt->memory); + if (ptei & 3) { + const u32 pten = min(ptes, 4 - (ptei & 3)); + nv44_vmm_pgt_fill(vmm, pt, NULL, ptei, pten); + ptei += pten; + ptes -= pten; + } + + while (ptes > 4) { + VMM_WO032(pt, vmm, ptei++ * 4, 0x00000000); + VMM_WO032(pt, vmm, ptei++ * 4, 0x00000000); + VMM_WO032(pt, vmm, ptei++ * 4, 0x00000000); + VMM_WO032(pt, vmm, ptei++ * 4, 0x00000000); + ptes -= 4; + } + + if (ptes) + nv44_vmm_pgt_fill(vmm, pt, NULL, ptei, ptes); + nvkm_done(pt->memory); +} + static const struct nvkm_vmm_desc_func nv44_vmm_desc_pgt = { + .unmap = nv44_vmm_pgt_unmap, + .dma = nv44_vmm_pgt_dma, + .sgl = nv44_vmm_pgt_sgl, }; static const struct nvkm_vmm_desc @@ -31,8 +181,23 @@ nv44_vmm_desc_12[] = { {} }; +static void +nv44_vmm_flush(struct nvkm_vmm *vmm, int level) +{ + struct nvkm_device *device = vmm->mmu->subdev.device; + nvkm_wr32(device, 0x100814, vmm->limit - 4096); + nvkm_wr32(device, 0x100808, 0x000000020); + nvkm_msec(device, 2000, + if (nvkm_rd32(device, 0x100808) & 0x00000001) + break; + ); + nvkm_wr32(device, 0x100808, 0x00000000); +} + static const struct nvkm_vmm_func nv44_vmm = { + .valid = nv04_vmm_valid, + .flush = nv44_vmm_flush, .page = { { 12, &nv44_vmm_desc_12[0], NVKM_VMM_PAGE_HOST }, {} -- cgit v1.2.3 From fd542a3e525c9f7a7de186cb24208c035bcea2d1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv50,g84: implement new vmm backend Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/if500d.h | 13 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 19 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 6 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 213 +++------------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 10 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c | 293 +++++++++++++++++++++- 6 files changed, 360 insertions(+), 194 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/if500d.h b/drivers/gpu/drm/nouveau/include/nvif/if500d.h index 6a0f47770745..c29a7822b363 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if500d.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if500d.h @@ -5,4 +5,17 @@ struct nv50_vmm_vn { /* nvif_vmm_vX ... */ }; + +struct nv50_vmm_map_vn { + /* nvif_vmm_map_vX ... */ +}; + +struct nv50_vmm_map_v0 { + /* nvif_vmm_map_vX ... */ + __u8 version; + __u8 ro; + __u8 priv; + __u8 kind; + __u8 comp; +}; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 536187952372..4d75dcb41468 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -27,6 +27,8 @@ #include #include +#include + struct nvkm_mmu_ptp { struct nvkm_mmu_pt *pt; struct list_head head; @@ -218,6 +220,9 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, struct nvkm_mem *mem, nvkm_vmm_pte_func fn, struct nvkm_vmm_map *map) { + union { + struct nv50_vmm_map_v0 nv50; + } args; struct nvkm_vmm *vmm = vma->vm; void *argv = NULL; u32 argc = 0; @@ -227,6 +232,20 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, map->page = page; if (vmm->func->valid) { + switch (vmm->mmu->subdev.device->card_type) { + case NV_50: + args.nv50.version = 0; + args.nv50.ro = !(vma->access & NV_MEM_ACCESS_WO); + args.nv50.priv = !!(vma->access & NV_MEM_ACCESS_SYS); + args.nv50.kind = (mem->memtype & 0x07f); + args.nv50.comp = (mem->memtype & 0x180) >> 7; + argv = &args.nv50; + argc = sizeof(args.nv50); + break; + default: + break; + } + ret = vmm->func->valid(vmm, argv, argc, map); if (WARN_ON(ret)) return; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index 13f8247a2ee4..e436c610b3df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -30,12 +30,8 @@ g84_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, - .map_pgt = nv50_vm_map_pgt, - .map = nv50_vm_map, - .map_sg = nv50_vm_map_sg, - .unmap = nv50_vm_unmap, - .flush = nv50_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, + .kind = nv50_mmu_kind, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index da75d1da0658..31d6f9626e56 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -23,185 +23,40 @@ */ #include "vmm.h" -#include -#include -#include -#include - #include -void -nv50_vm_map_pgt(struct nvkm_vmm *vmm, u32 pde, struct nvkm_memory *pgt[2]) -{ - struct nvkm_vmm_join *join; - u32 pdeo = vmm->mmu->func->vmm.pd_offset + (pde * 8); - u64 phys = 0xdeadcafe00000000ULL; - u32 coverage = 0; - - if (pgt[0]) { - /* present, 4KiB pages */ - phys = 0x00000003 | nvkm_memory_addr(pgt[0]); - coverage = (nvkm_memory_size(pgt[0]) >> 3) << 12; - } else - if (pgt[1]) { - /* present, 64KiB pages */ - phys = 0x00000001 | nvkm_memory_addr(pgt[1]); - coverage = (nvkm_memory_size(pgt[1]) >> 3) << 16; - } - - if (phys & 1) { - if (coverage <= 32 * 1024 * 1024) - phys |= 0x60; - else if (coverage <= 64 * 1024 * 1024) - phys |= 0x40; - else if (coverage <= 128 * 1024 * 1024) - phys |= 0x20; - } - - list_for_each_entry(join, &vmm->join, head) { - nvkm_kmap(join->inst); - nvkm_wo32(join->inst, pdeo + 0, lower_32_bits(phys)); - nvkm_wo32(join->inst, pdeo + 4, upper_32_bits(phys)); - nvkm_done(join->inst); - } -} - -static inline u64 -vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target) +const u8 * +nv50_mmu_kind(struct nvkm_mmu *base, int *count) { - phys |= 1; /* present */ - phys |= (u64)memtype << 40; - phys |= target << 4; - if (vma->access & NV_MEM_ACCESS_SYS) - phys |= (1 << 6); - if (!(vma->access & NV_MEM_ACCESS_WO)) - phys |= (1 << 3); - return phys; -} - -void -nv50_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, - struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) -{ - struct nvkm_ram *ram = vma->vm->mmu->subdev.device->fb->ram; - u32 comp = (mem->memtype & 0x180) >> 7; - u32 block, target; - int i; - - /* IGPs don't have real VRAM, re-target to stolen system memory */ - target = 0; - if (ram->stolen) { - phys += ram->stolen; - target = 3; - } - - phys = vm_addr(vma, phys, mem->memtype, target); - pte <<= 3; - cnt <<= 3; - - nvkm_kmap(pgt); - while (cnt) { - u32 offset_h = upper_32_bits(phys); - u32 offset_l = lower_32_bits(phys); - - for (i = 7; i >= 0; i--) { - block = 1 << (i + 3); - if (cnt >= block && !(pte & (block - 1))) - break; - } - offset_l |= (i << 7); - - phys += block << (vma->node->type - 3); - cnt -= block; - if (comp) { - u32 tag = mem->tag->offset + ((delta >> 16) * comp); - offset_h |= (tag << 17); - delta += block << (vma->node->type - 3); - } - - while (block) { - nvkm_wo32(pgt, pte + 0, offset_l); - nvkm_wo32(pgt, pte + 4, offset_h); - pte += 8; - block -= 8; - } - } - nvkm_done(pgt); -} - -void -nv50_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, - struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) -{ - u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 3 : 2; - pte <<= 3; - nvkm_kmap(pgt); - while (cnt--) { - u64 phys = vm_addr(vma, (u64)*list++, mem->memtype, target); - nvkm_wo32(pgt, pte + 0, lower_32_bits(phys)); - nvkm_wo32(pgt, pte + 4, upper_32_bits(phys)); - pte += 8; - } - nvkm_done(pgt); -} - -void -nv50_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) -{ - pte <<= 3; - nvkm_kmap(pgt); - while (cnt--) { - nvkm_wo32(pgt, pte + 0, 0x00000000); - nvkm_wo32(pgt, pte + 4, 0x00000000); - pte += 8; - } - nvkm_done(pgt); -} - -void -nv50_vm_flush(struct nvkm_vm *vm) -{ - struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_subdev *subdev = &mmu->subdev; - struct nvkm_device *device = subdev->device; - int i, vme; - - mutex_lock(&subdev->mutex); - for (i = 0; i < NVKM_SUBDEV_NR; i++) { - if (!atomic_read(&vm->engref[i])) - continue; - - /* unfortunate hw bug workaround... */ - if (i == NVKM_ENGINE_GR && device->gr) { - int ret = nvkm_gr_tlb_flush(device->gr); - if (ret != -ENODEV) - continue; - } - - switch (i) { - case NVKM_ENGINE_GR : vme = 0x00; break; - case NVKM_ENGINE_VP : - case NVKM_ENGINE_MSPDEC: vme = 0x01; break; - case NVKM_SUBDEV_BAR : vme = 0x06; break; - case NVKM_ENGINE_MSPPP : - case NVKM_ENGINE_MPEG : vme = 0x08; break; - case NVKM_ENGINE_BSP : - case NVKM_ENGINE_MSVLD : vme = 0x09; break; - case NVKM_ENGINE_CIPHER: - case NVKM_ENGINE_SEC : vme = 0x0a; break; - case NVKM_ENGINE_CE0 : vme = 0x0d; break; - default: - continue; - } - - nvkm_wr32(device, 0x100c80, (vme << 16) | 1); - if (nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x100c80) & 0x00000001)) - break; - ) < 0) - nvkm_error(subdev, "vm flush timeout: engine %d\n", vme); - } - mutex_unlock(&subdev->mutex); + /* 0x01: no bank swizzle + * 0x02: bank swizzled + * 0x7f: invalid + * + * 0x01/0x02 are values understood by the VRAM allocator, + * and are required to avoid mixing the two types within + * a certain range. + */ + static const u8 + kind[128] = { + 0x01, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x00 */ + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x01, 0x01, 0x01, 0x01, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x10 */ + 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, 0x7f, 0x7f, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, /* 0x20 */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x30 */ + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, /* 0x40 */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x7f, /* 0x50 */ + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, /* 0x60 */ + 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, + 0x01, 0x7f, 0x02, 0x7f, 0x01, 0x7f, 0x02, 0x7f, /* 0x70 */ + 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x7f, 0x7f + }; + *count = ARRAY_SIZE(kind); + return kind; } static const struct nvkm_mmu_func @@ -211,12 +66,8 @@ nv50_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, - .map_pgt = nv50_vm_map_pgt, - .map = nv50_vm_map, - .map_sg = nv50_vm_map_sg, - .unmap = nv50_vm_unmap, - .flush = nv50_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, + .kind = nv50_mmu_kind, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 3271ec1c3c83..326781246714 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -37,17 +37,13 @@ struct nvkm_mmu_func { bool global; u32 pd_offset; } vmm; + + const u8 *(*kind)(struct nvkm_mmu *, int *count); }; extern const struct nvkm_mmu_func nv04_mmu; -void nv50_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); -void nv50_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, - u32, u32, u64, u64); -void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, - u32, u32, dma_addr_t *); -void nv50_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); -void nv50_vm_flush(struct nvkm_vm *); +const u8 *nv50_mmu_kind(struct nvkm_mmu *, int *count); void gf100_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); void gf100_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c index db27381b67c6..863a2edd9861 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c @@ -21,15 +21,146 @@ */ #include "vmm.h" +#include +#include +#include + #include #include +static inline void +nv50_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u64 next = addr | map->type, data; + u32 pten; + int log2blk; + + map->type += ptes * map->ctag; + + while (ptes) { + for (log2blk = 7; log2blk >= 0; log2blk--) { + pten = 1 << log2blk; + if (ptes >= pten && IS_ALIGNED(ptei, pten)) + break; + } + + data = next | (log2blk << 7); + next += pten * map->next; + ptes -= pten; + + while (pten--) + VMM_WO064(pt, vmm, ptei++ * 8, data); + } +} + +static void +nv50_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, nv50_vmm_pgt_pte); +} + +static void +nv50_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + if (map->page->shift == PAGE_SHIFT) { + VMM_SPAM(vmm, "DMAA %08x %08x PTE(s)", ptei, ptes); + nvkm_kmap(pt->memory); + while (ptes--) { + const u64 data = *map->dma++ | map->type; + VMM_WO064(pt, vmm, ptei++ * 8, data); + map->type += map->ctag; + } + nvkm_done(pt->memory); + return; + } + + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, nv50_vmm_pgt_pte); +} + +static void +nv50_vmm_pgt_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, nv50_vmm_pgt_pte); +} + +static void +nv50_vmm_pgt_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + VMM_FO064(pt, vmm, ptei * 8, 0ULL, ptes); +} + static const struct nvkm_vmm_desc_func nv50_vmm_pgt = { + .unmap = nv50_vmm_pgt_unmap, + .mem = nv50_vmm_pgt_mem, + .dma = nv50_vmm_pgt_dma, + .sgl = nv50_vmm_pgt_sgl, }; +static bool +nv50_vmm_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgt, u64 *pdata) +{ + struct nvkm_mmu_pt *pt; + u64 data = 0xdeadcafe00000000ULL; + if (pgt && (pt = pgt->pt[0])) { + switch (pgt->page) { + case 16: data = 0x00000001; break; + case 12: data = 0x00000003; + switch (nvkm_memory_size(pt->memory)) { + case 0x100000: data |= 0x00000000; break; + case 0x040000: data |= 0x00000020; break; + case 0x020000: data |= 0x00000040; break; + case 0x010000: data |= 0x00000060; break; + default: + WARN_ON(1); + return false; + } + break; + default: + WARN_ON(1); + return false; + } + + switch (nvkm_memory_target(pt->memory)) { + case NVKM_MEM_TARGET_VRAM: data |= 0x00000000; break; + case NVKM_MEM_TARGET_HOST: data |= 0x00000008; break; + case NVKM_MEM_TARGET_NCOH: data |= 0x0000000c; break; + default: + WARN_ON(1); + return false; + } + + data |= pt->addr; + } + *pdata = data; + return true; +} + +static void +nv50_vmm_pgd_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_join *join; + u32 pdeo = vmm->mmu->func->vmm.pd_offset + (pdei * 8); + u64 data; + + if (!nv50_vmm_pde(vmm, pgd->pde[pdei], &data)) + return; + + list_for_each_entry(join, &vmm->join, head) { + nvkm_kmap(join->inst); + nvkm_wo64(join->inst, pdeo, data); + nvkm_done(join->inst); + } +} + static const struct nvkm_vmm_desc_func nv50_vmm_pgd = { + .pde = nv50_vmm_pgd_pde, }; static const struct nvkm_vmm_desc @@ -46,6 +177,150 @@ nv50_vmm_desc_16[] = { {} }; +static void +nv50_vmm_flush(struct nvkm_vmm *vmm, int level) +{ + struct nvkm_subdev *subdev = &vmm->mmu->subdev; + struct nvkm_device *device = subdev->device; + int i, id; + + mutex_lock(&subdev->mutex); + for (i = 0; i < NVKM_SUBDEV_NR; i++) { + if (!atomic_read(&vmm->engref[i])) + continue; + + /* unfortunate hw bug workaround... */ + if (i == NVKM_ENGINE_GR && device->gr) { + int ret = nvkm_gr_tlb_flush(device->gr); + if (ret != -ENODEV) + continue; + } + + switch (i) { + case NVKM_ENGINE_GR : id = 0x00; break; + case NVKM_ENGINE_VP : + case NVKM_ENGINE_MSPDEC: id = 0x01; break; + case NVKM_SUBDEV_BAR : id = 0x06; break; + case NVKM_ENGINE_MSPPP : + case NVKM_ENGINE_MPEG : id = 0x08; break; + case NVKM_ENGINE_BSP : + case NVKM_ENGINE_MSVLD : id = 0x09; break; + case NVKM_ENGINE_CIPHER: + case NVKM_ENGINE_SEC : id = 0x0a; break; + case NVKM_ENGINE_CE0 : id = 0x0d; break; + default: + continue; + } + + nvkm_wr32(device, 0x100c80, (id << 16) | 1); + if (nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x100c80) & 0x00000001)) + break; + ) < 0) + nvkm_error(subdev, "%s mmu invalidate timeout\n", + nvkm_subdev_name[i]); + } + mutex_unlock(&subdev->mutex); +} + +static int +nv50_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, + struct nvkm_vmm_map *map) +{ + const struct nvkm_vmm_page *page = map->page; + union { + struct nv50_vmm_map_vn vn; + struct nv50_vmm_map_v0 v0; + } *args = argv; + struct nvkm_device *device = vmm->mmu->subdev.device; + struct nvkm_ram *ram = device->fb->ram; + struct nvkm_memory *memory = map->memory; + u8 aper, kind, comp, priv, ro; + int kindn, ret = -ENOSYS; + const u8 *kindm; + + map->type = map->ctag = 0; + map->next = 1 << page->shift; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + ro = !!args->v0.ro; + priv = !!args->v0.priv; + kind = args->v0.kind & 0x7f; + comp = args->v0.comp & 0x03; + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + ro = 0; + priv = 0; + kind = 0x00; + comp = 0; + } else { + VMM_DEBUG(vmm, "args"); + return ret; + } + + switch (nvkm_memory_target(memory)) { + case NVKM_MEM_TARGET_VRAM: + if (ram->stolen) { + map->type |= ram->stolen; + aper = 3; + } else { + aper = 0; + } + break; + case NVKM_MEM_TARGET_HOST: + aper = 2; + break; + case NVKM_MEM_TARGET_NCOH: + aper = 3; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + kindm = vmm->mmu->func->kind(vmm->mmu, &kindn); + if (kind >= kindn || kindm[kind] == 0x7f) { + VMM_DEBUG(vmm, "kind %02x", kind); + return -EINVAL; + } + + if (map->mem && map->mem->type != kindm[kind]) { + VMM_DEBUG(vmm, "kind %02x bankswz: %d %d", kind, + kindm[kind], map->mem->type); + return -EINVAL; + } + + if (comp) { + u32 tags = (nvkm_memory_size(memory) >> 16) * comp; + if (aper != 0 || !(page->type & NVKM_VMM_PAGE_COMP)) { + VMM_DEBUG(vmm, "comp %d %02x", aper, page->type); + return -EINVAL; + } + + ret = nvkm_memory_tags_get(memory, device, tags, NULL, + &map->tags); + if (ret) { + VMM_DEBUG(vmm, "comp %d", ret); + return ret; + } + + if (map->tags->mn) { + u32 tags = map->tags->mn->offset + (map->offset >> 16); + map->ctag |= (u64)comp << 49; + map->type |= (u64)comp << 47; + map->type |= (u64)tags << 49; + map->next |= map->ctag; + } + } + + map->type |= BIT(0); /* Valid. */ + map->type |= (u64)ro << 3; + map->type |= (u64)aper << 4; + map->type |= (u64)priv << 6; + map->type |= (u64)kind << 40; + return 0; +} + static void nv50_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst) { @@ -63,19 +338,35 @@ nv50_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst) static int nv50_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) { + const u32 pd_offset = vmm->mmu->func->vmm.pd_offset; struct nvkm_vmm_join *join; + int ret = 0; + u64 data; + u32 pdei; if (!(join = kmalloc(sizeof(*join), GFP_KERNEL))) return -ENOMEM; join->inst = inst; list_add_tail(&join->head, &vmm->join); - return 0; + + nvkm_kmap(join->inst); + for (pdei = vmm->start >> 29; pdei <= (vmm->limit - 1) >> 29; pdei++) { + if (!nv50_vmm_pde(vmm, vmm->pd->pde[pdei], &data)) { + ret = -EINVAL; + break; + } + nvkm_wo64(join->inst, pd_offset + (pdei * 8), data); + } + nvkm_done(join->inst); + return ret; } static const struct nvkm_vmm_func nv50_vmm = { .join = nv50_vmm_join, .part = nv50_vmm_part, + .valid = nv50_vmm_valid, + .flush = nv50_vmm_flush, .page_block = 1 << 29, .page = { { 16, &nv50_vmm_desc_16[0], NVKM_VMM_PAGE_xVxC }, -- cgit v1.2.3 From b77791da0ee009dcb1813d8b00919962b6a5f851 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gf100: implement new vmm backend Adds support for: - 64KiB big page size. - System-memory PTs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/if900d.h | 13 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 15 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 12 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 12 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c | 258 +++++++++++++++++++++ 6 files changed, 306 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/if900d.h b/drivers/gpu/drm/nouveau/include/nvif/if900d.h index 112716f889c6..49aa50583c3d 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if900d.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if900d.h @@ -5,4 +5,17 @@ struct gf100_vmm_vn { /* nvif_vmm_vX ... */ }; + +struct gf100_vmm_map_vn { + /* nvif_vmm_map_vX ... */ +}; + +struct gf100_vmm_map_v0 { + /* nvif_vmm_map_vX ... */ + __u8 version; + __u8 vol; + __u8 ro; + __u8 priv; + __u8 kind; +}; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 4d75dcb41468..741021ff8c27 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -28,6 +28,7 @@ #include #include +#include struct nvkm_mmu_ptp { struct nvkm_mmu_pt *pt; @@ -222,6 +223,7 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, { union { struct nv50_vmm_map_v0 nv50; + struct gf100_vmm_map_v0 gf100; } args; struct nvkm_vmm *vmm = vma->vm; void *argv = NULL; @@ -242,6 +244,19 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, argv = &args.nv50; argc = sizeof(args.nv50); break; + case NV_C0: + case NV_E0: + case GM100: + case GP100: { + args.gf100.version = 0; + args.gf100.vol = (nvkm_memory_target(map->memory) != NVKM_MEM_TARGET_VRAM); + args.gf100.ro = !(vma->access & NV_MEM_ACCESS_WO); + args.gf100.priv = !!(vma->access & NV_MEM_ACCESS_SYS); + args.gf100.kind = (mem->memtype & 0x0ff); + argv = &args.gf100; + argc = sizeof(args.gf100); + } + break; default: break; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 167c201d29e3..39bf26684b41 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -68,6 +68,12 @@ const u8 gf100_pte_storage_type_map[256] = 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff }; +const u8 * +gf100_mmu_kind(struct nvkm_mmu *mmu, int *count) +{ + *count = ARRAY_SIZE(gf100_pte_storage_type_map); + return gf100_pte_storage_type_map; +} void gf100_vm_map_pgt(struct nvkm_vmm *vmm, u32 index, struct nvkm_memory *pgt[2]) @@ -195,12 +201,8 @@ gf100_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new }, + .kind = gf100_mmu_kind, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 326781246714..64f765ec3e6e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -52,6 +52,7 @@ void gf100_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, dma_addr_t *); void gf100_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void gf100_vm_flush(struct nvkm_vm *); +const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count); struct nvkm_mmu_pt { union { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index cbb8d47fbd11..dfc4b46129bd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -70,7 +70,15 @@ struct nvkm_vmm_desc_func { }; extern const struct nvkm_vmm_desc_func gf100_vmm_pgd; +void gf100_vmm_pgd_pde(struct nvkm_vmm *, struct nvkm_vmm_pt *, u32); extern const struct nvkm_vmm_desc_func gf100_vmm_pgt; +void gf100_vmm_pgt_unmap(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32); +void gf100_vmm_pgt_mem(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32, + struct nvkm_vmm_map *); +void gf100_vmm_pgt_dma(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32, + struct nvkm_vmm_map *); +void gf100_vmm_pgt_sgl(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32, + struct nvkm_vmm_map *); struct nvkm_vmm_desc { enum { @@ -165,6 +173,10 @@ int gf100_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, int gf100_vmm_join_(struct nvkm_vmm *, struct nvkm_memory *, u64 base); int gf100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); void gf100_vmm_part(struct nvkm_vmm *, struct nvkm_memory *); +int gf100_vmm_aper(enum nvkm_memory_target); +int gf100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *); +void gf100_vmm_flush_(struct nvkm_vmm *, int); +void gf100_vmm_flush(struct nvkm_vmm *, int); int gm200_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, struct nvkm_mmu *, u64, u64, void *, u32, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c index f8234af0120c..ddd44ad797b7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c @@ -22,13 +22,131 @@ #include "vmm.h" #include +#include +#include + +#include +#include + +static inline void +gf100_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u64 base = (addr >> 8) | map->type; + u64 data = base; + + if (map->ctag && !(map->next & (1ULL << 44))) { + while (ptes--) { + data = base | ((map->ctag >> 1) << 44); + if (!(map->ctag++ & 1)) + data |= BIT_ULL(60); + + VMM_WO064(pt, vmm, ptei++ * 8, data); + base += map->next; + } + } else { + map->type += ptes * map->ctag; + + while (ptes--) { + VMM_WO064(pt, vmm, ptei++ * 8, data); + data += map->next; + } + } +} + +void +gf100_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, gf100_vmm_pgt_pte); +} + +void +gf100_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + if (map->page->shift == PAGE_SHIFT) { + VMM_SPAM(vmm, "DMAA %08x %08x PTE(s)", ptei, ptes); + nvkm_kmap(pt->memory); + while (ptes--) { + const u64 data = (*map->dma++ >> 8) | map->type; + VMM_WO064(pt, vmm, ptei++ * 8, data); + map->type += map->ctag; + } + nvkm_done(pt->memory); + return; + } + + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, gf100_vmm_pgt_pte); +} + +void +gf100_vmm_pgt_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gf100_vmm_pgt_pte); +} + +void +gf100_vmm_pgt_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + VMM_FO064(pt, vmm, ptei * 8, 0ULL, ptes); +} const struct nvkm_vmm_desc_func gf100_vmm_pgt = { + .unmap = gf100_vmm_pgt_unmap, + .mem = gf100_vmm_pgt_mem, + .dma = gf100_vmm_pgt_dma, + .sgl = gf100_vmm_pgt_sgl, }; +void +gf100_vmm_pgd_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + struct nvkm_mmu_pt *pd = pgd->pt[0]; + struct nvkm_mmu_pt *pt; + u64 data = 0; + + if ((pt = pgt->pt[0])) { + switch (nvkm_memory_target(pt->memory)) { + case NVKM_MEM_TARGET_VRAM: data |= 1ULL << 0; break; + case NVKM_MEM_TARGET_HOST: data |= 2ULL << 0; + data |= BIT_ULL(35); /* VOL */ + break; + case NVKM_MEM_TARGET_NCOH: data |= 3ULL << 0; break; + default: + WARN_ON(1); + return; + } + data |= pt->addr >> 8; + } + + if ((pt = pgt->pt[1])) { + switch (nvkm_memory_target(pt->memory)) { + case NVKM_MEM_TARGET_VRAM: data |= 1ULL << 32; break; + case NVKM_MEM_TARGET_HOST: data |= 2ULL << 32; + data |= BIT_ULL(34); /* VOL */ + break; + case NVKM_MEM_TARGET_NCOH: data |= 3ULL << 32; break; + default: + WARN_ON(1); + return; + } + data |= pt->addr << 24; + } + + nvkm_kmap(pd->memory); + VMM_WO064(pd, vmm, pdei * 8, data); + nvkm_done(pd->memory); +} + const struct nvkm_vmm_desc_func gf100_vmm_pgd = { + .unmap = gf100_vmm_pgt_unmap, + .pde = gf100_vmm_pgd_pde, }; static const struct nvkm_vmm_desc @@ -59,6 +177,140 @@ gf100_vmm_desc_16_16[] = { {} }; +void +gf100_vmm_flush_(struct nvkm_vmm *vmm, int depth) +{ + struct nvkm_subdev *subdev = &vmm->mmu->subdev; + struct nvkm_device *device = subdev->device; + u32 type; + + type = 0x00000001; /* PAGE_ALL */ + if (atomic_read(&vmm->engref[NVKM_SUBDEV_BAR])) + type |= 0x00000004; /* HUB_ONLY */ + + mutex_lock(&subdev->mutex); + /* Looks like maybe a "free flush slots" counter, the + * faster you write to 0x100cbc to more it decreases. + */ + nvkm_msec(device, 2000, + if (nvkm_rd32(device, 0x100c80) & 0x00ff0000) + break; + ); + + nvkm_wr32(device, 0x100cb8, vmm->pd->pt[0]->addr >> 8); + nvkm_wr32(device, 0x100cbc, 0x80000000 | type); + + /* Wait for flush to be queued? */ + nvkm_msec(device, 2000, + if (nvkm_rd32(device, 0x100c80) & 0x00008000) + break; + ); + mutex_unlock(&subdev->mutex); +} + +void +gf100_vmm_flush(struct nvkm_vmm *vmm, int depth) +{ + gf100_vmm_flush_(vmm, 0); +} + +int +gf100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, + struct nvkm_vmm_map *map) +{ + const enum nvkm_memory_target target = nvkm_memory_target(map->memory); + const struct nvkm_vmm_page *page = map->page; + const bool gm20x = page->desc->func->sparse != NULL; + union { + struct gf100_vmm_map_vn vn; + struct gf100_vmm_map_v0 v0; + } *args = argv; + struct nvkm_device *device = vmm->mmu->subdev.device; + struct nvkm_memory *memory = map->memory; + u8 kind, priv, ro, vol; + int kindn, aper, ret = -ENOSYS; + const u8 *kindm; + + map->next = (1 << page->shift) >> 8; + map->type = map->ctag = 0; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + vol = !!args->v0.vol; + ro = !!args->v0.ro; + priv = !!args->v0.priv; + kind = args->v0.kind; + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + vol = target == NVKM_MEM_TARGET_HOST; + ro = 0; + priv = 0; + kind = 0x00; + } else { + VMM_DEBUG(vmm, "args"); + return ret; + } + + aper = vmm->func->aper(target); + if (WARN_ON(aper < 0)) + return aper; + + kindm = vmm->mmu->func->kind(vmm->mmu, &kindn); + if (kind >= kindn || kindm[kind] == 0xff) { + VMM_DEBUG(vmm, "kind %02x", kind); + return -EINVAL; + } + + if (kindm[kind] != kind) { + u32 comp = (page->shift == 16 && !gm20x) ? 16 : 17; + u32 tags = ALIGN(nvkm_memory_size(memory), 1 << 17) >> comp; + if (aper != 0 || !(page->type & NVKM_VMM_PAGE_COMP)) { + VMM_DEBUG(vmm, "comp %d %02x", aper, page->type); + return -EINVAL; + } + + ret = nvkm_memory_tags_get(memory, device, tags, + nvkm_ltc_tags_clear, + &map->tags); + if (ret) { + VMM_DEBUG(vmm, "comp %d", ret); + return ret; + } + + if (map->tags->mn) { + u64 tags = map->tags->mn->offset + (map->offset >> 17); + if (page->shift == 17 || !gm20x) { + map->type |= tags << 44; + map->ctag |= 1ULL << 44; + map->next |= 1ULL << 44; + } else { + map->ctag |= tags << 1 | 1; + } + } else { + kind = kindm[kind]; + } + } + + map->type |= BIT(0); + map->type |= (u64)priv << 1; + map->type |= (u64) ro << 2; + map->type |= (u64) vol << 32; + map->type |= (u64)aper << 33; + map->type |= (u64)kind << 36; + return 0; +} + +int +gf100_vmm_aper(enum nvkm_memory_target target) +{ + switch (target) { + case NVKM_MEM_TARGET_VRAM: return 0; + case NVKM_MEM_TARGET_HOST: return 2; + case NVKM_MEM_TARGET_NCOH: return 3; + default: + return -EINVAL; + } +} + void gf100_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst) { @@ -99,6 +351,9 @@ static const struct nvkm_vmm_func gf100_vmm_17 = { .join = gf100_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 17, &gf100_vmm_desc_17_17[0], NVKM_VMM_PAGE_xVxC }, { 12, &gf100_vmm_desc_17_12[0], NVKM_VMM_PAGE_xVHx }, @@ -110,6 +365,9 @@ static const struct nvkm_vmm_func gf100_vmm_16 = { .join = gf100_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 16, &gf100_vmm_desc_16_16[0], NVKM_VMM_PAGE_xVxC }, { 12, &gf100_vmm_desc_16_12[0], NVKM_VMM_PAGE_xVHx }, -- cgit v1.2.3 From b597764327e1af1b4948f6e7478acc5c7f1f6c49 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gk104,gk20a: implement new vmm backend Adds support for: - 64KiB big page size. - System-memory PTs. - LPTE "invalid" state. - (Tegra) Use of video memory aperture. Adds support for marking LPTEs invalid, resulting in the corresponding SPTEs being ignored, which is supposed to speed up TLB invalidates. On The Tegra side, this will switch to using the video memory aperture for all mappings. The HW will still target non-coherent system memory, but this aperture needs to be selected in order to support compression. Tegra's instmem backend somewhat cheated to get this effect previously. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 6 +----- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 6 +----- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 4 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c | 17 +++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c | 18 ++++++++++++++++++ 5 files changed, 41 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index 693aa1b875f2..8cbd0723c25b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -30,12 +30,8 @@ gk104_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new }, + .kind = gf100_mmu_kind, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index b774d9a25c3e..57def7244d38 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -30,12 +30,8 @@ gk20a_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new }, + .kind = gf100_mmu_kind, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index dfc4b46129bd..75f642900140 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -80,6 +80,8 @@ void gf100_vmm_pgt_dma(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32, void gf100_vmm_pgt_sgl(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32, struct nvkm_vmm_map *); +void gk104_vmm_lpt_invalid(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32); + struct nvkm_vmm_desc { enum { PGD, @@ -178,6 +180,8 @@ int gf100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *); void gf100_vmm_flush_(struct nvkm_vmm *, int); void gf100_vmm_flush(struct nvkm_vmm *, int); +int gk20a_vmm_aper(enum nvkm_memory_target); + int gm200_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c index 0d33700e3d88..0ebb7bccfcd2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk104.c @@ -21,8 +21,19 @@ */ #include "vmm.h" +void +gk104_vmm_lpt_invalid(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + /* VALID_FALSE + PRIV tells the MMU to ignore corresponding SPTEs. */ + VMM_FO064(pt, vmm, ptei * 8, BIT_ULL(1) /* PRIV. */, ptes); +} + static const struct nvkm_vmm_desc_func gk104_vmm_lpt = { + .invalid = gk104_vmm_lpt_invalid, + .unmap = gf100_vmm_pgt_unmap, + .mem = gf100_vmm_pgt_mem, }; const struct nvkm_vmm_desc @@ -57,6 +68,9 @@ static const struct nvkm_vmm_func gk104_vmm_17 = { .join = gf100_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 17, &gk104_vmm_desc_17_17[0], NVKM_VMM_PAGE_xVxC }, { 12, &gk104_vmm_desc_17_12[0], NVKM_VMM_PAGE_xVHx }, @@ -68,6 +82,9 @@ static const struct nvkm_vmm_func gk104_vmm_16 = { .join = gf100_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 16, &gk104_vmm_desc_16_16[0], NVKM_VMM_PAGE_xVxC }, { 12, &gk104_vmm_desc_16_12[0], NVKM_VMM_PAGE_xVHx }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c index e000c3d1554a..8086994a0446 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c @@ -21,10 +21,25 @@ */ #include "vmm.h" +#include + +int +gk20a_vmm_aper(enum nvkm_memory_target target) +{ + switch (target) { + case NVKM_MEM_TARGET_NCOH: return 0; + default: + return -EINVAL; + } +} + static const struct nvkm_vmm_func gk20a_vmm_17 = { .join = gf100_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 17, &gk104_vmm_desc_17_17[0], NVKM_VMM_PAGE_xxHC }, { 12, &gk104_vmm_desc_17_12[0], NVKM_VMM_PAGE_xxHx }, @@ -36,6 +51,9 @@ static const struct nvkm_vmm_func gk20a_vmm_16 = { .join = gf100_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 16, &gk104_vmm_desc_16_16[0], NVKM_VMM_PAGE_xxHC }, { 12, &gk104_vmm_desc_16_12[0], NVKM_VMM_PAGE_xxHx }, -- cgit v1.2.3 From e12cf6ad43888c152c3b2edb59525587cd98a227 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gm200,gm20b: implement new vmm backend Adds support for: - 64KiB big page size. - System-memory PTs. - LPTE "invalid" state. - (Tegra) Use of video memory aperture. - Sparse PDEs/PTEs. - Additional blocklinear kinds. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/ifb00d.h | 13 ++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 54 ++++++++++++++++++---- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 12 +---- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c | 34 ++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c | 6 +++ 6 files changed, 101 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/ifb00d.h b/drivers/gpu/drm/nouveau/include/nvif/ifb00d.h index 2e1e99810361..a0e419830595 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/ifb00d.h +++ b/drivers/gpu/drm/nouveau/include/nvif/ifb00d.h @@ -11,4 +11,17 @@ struct gm200_vmm_v0 { __u8 version; __u8 bigpage; }; + +struct gm200_vmm_map_vn { + /* nvif_vmm_map_vX ... */ +}; + +struct gm200_vmm_map_v0 { + /* nvif_vmm_map_vX ... */ + __u8 version; + __u8 vol; + __u8 ro; + __u8 priv; + __u8 kind; +}; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index 41332613c644..c38c899e463c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -25,6 +25,48 @@ #include +const u8 * +gm200_mmu_kind(struct nvkm_mmu *mmu, int *count) +{ + static const u8 + kind[256] = { + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, /* 0x00 */ + 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, /* 0x10 */ + 0x11, 0x11, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x27, /* 0x20 */ + 0x28, 0x29, 0x2a, 0x2b, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 */ + 0xff, 0xff, 0x26, 0x27, 0x28, 0x29, 0x26, 0x27, + 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0x46, 0xff, /* 0x40 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x46, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, /* 0x50 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x60 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */ + 0xff, 0xff, 0xff, 0x7b, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x7b, /* 0x80 */ + 0x7b, 0x7b, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xa7, /* 0xa0 */ + 0xa8, 0xa9, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, + 0xa8, 0xa9, 0xaa, 0xc3, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */ + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xc3, 0xc3, + 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */ + 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, + 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, /* 0xe0 */ + 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xf0 */ + 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff + }; + *count = ARRAY_SIZE(kind); + return kind; +} + static const struct nvkm_mmu_func gm200_mmu = { .limit = (1ULL << 40), @@ -32,12 +74,8 @@ gm200_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm200_vmm_new }, + .kind = gm200_mmu_kind, }; static const struct nvkm_mmu_func @@ -47,12 +85,8 @@ gm200_mmu_fixed = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm200_vmm_new_fixed }, + .kind = gm200_mmu_kind, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 25b16975bddd..8cd6d1617bd7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -32,12 +32,8 @@ gm20b_mmu = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new }, + .kind = gm200_mmu_kind, }; static const struct nvkm_mmu_func @@ -47,12 +43,8 @@ gm20b_mmu_fixed = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .map_pgt = gf100_vm_map_pgt, - .map = gf100_vm_map, - .map_sg = gf100_vm_map_sg, - .unmap = gf100_vm_unmap, - .flush = gf100_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new_fixed }, + .kind = gm200_mmu_kind, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 64f765ec3e6e..5828dd82cba7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -54,6 +54,8 @@ void gf100_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void gf100_vm_flush(struct nvkm_vm *); const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count); +const u8 *gm200_mmu_kind(struct nvkm_mmu *, int *); + struct nvkm_mmu_pt { union { struct nvkm_mmu_ptc *ptc; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c index 43138560b108..a1676a4644fe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm200.c @@ -24,16 +24,44 @@ #include #include +static void +gm200_vmm_pgt_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + /* VALID_FALSE + VOL tells the MMU to treat the PTE as sparse. */ + VMM_FO064(pt, vmm, ptei * 8, BIT_ULL(32) /* VOL. */, ptes); +} + static const struct nvkm_vmm_desc_func gm200_vmm_spt = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gm200_vmm_pgt_sparse, + .mem = gf100_vmm_pgt_mem, + .dma = gf100_vmm_pgt_dma, + .sgl = gf100_vmm_pgt_sgl, }; static const struct nvkm_vmm_desc_func gm200_vmm_lpt = { + .invalid = gk104_vmm_lpt_invalid, + .unmap = gf100_vmm_pgt_unmap, + .sparse = gm200_vmm_pgt_sparse, + .mem = gf100_vmm_pgt_mem, }; +static void +gm200_vmm_pgd_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes) +{ + /* VALID_FALSE + VOL_BIG tells the MMU to treat the PDE as sparse. */ + VMM_FO064(pt, vmm, pdei * 8, BIT_ULL(35) /* VOL_BIG. */, pdes); +} + static const struct nvkm_vmm_desc_func gm200_vmm_pgd = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gm200_vmm_pgd_sparse, + .pde = gf100_vmm_pgd_pde, }; const struct nvkm_vmm_desc @@ -82,6 +110,9 @@ static const struct nvkm_vmm_func gm200_vmm_17 = { .join = gm200_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 27, &gm200_vmm_desc_17_17[1], NVKM_VMM_PAGE_Sxxx }, { 17, &gm200_vmm_desc_17_17[0], NVKM_VMM_PAGE_SVxC }, @@ -94,6 +125,9 @@ static const struct nvkm_vmm_func gm200_vmm_16 = { .join = gm200_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 27, &gm200_vmm_desc_16_16[1], NVKM_VMM_PAGE_Sxxx }, { 16, &gm200_vmm_desc_16_16[0], NVKM_VMM_PAGE_SVxC }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c index ec24c43f86cc..64d4b6cff8dd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c @@ -25,6 +25,9 @@ static const struct nvkm_vmm_func gm20b_vmm_17 = { .join = gm200_vmm_join, .part = gf100_vmm_part, + .aper = gk20a_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 27, &gm200_vmm_desc_17_17[1], NVKM_VMM_PAGE_Sxxx }, { 17, &gm200_vmm_desc_17_17[0], NVKM_VMM_PAGE_SxHC }, @@ -37,6 +40,9 @@ static const struct nvkm_vmm_func gm20b_vmm_16 = { .join = gm200_vmm_join, .part = gf100_vmm_part, + .aper = gk20a_vmm_aper, + .valid = gf100_vmm_valid, + .flush = gf100_vmm_flush, .page = { { 27, &gm200_vmm_desc_16_16[1], NVKM_VMM_PAGE_Sxxx }, { 16, &gm200_vmm_desc_16_16[0], NVKM_VMM_PAGE_SxHC }, -- cgit v1.2.3 From f9400afb1e11c33830bd99a0c9fafe3f4d07a7cc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gp100,gp10b: implement new vmm backend Adds support for: - 64KiB/2MiB big page sizes (128KiB not supported by HW with new PT layout). - System-memory PTs. - LPTE "invalid" state. - (Tegra) Use of video memory aperture. - Sparse PDEs/PTEs. - Additional blocklinear kinds. - 49-bit address-space. GP100 supports an entirely new 5-level page table layout that provides an expanded 49-bit address-space. It also supports the layout present on previous generations, which we've been making do with until now. This commit implements support for the new layout, and enables it by default. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/ifc00d.h | 13 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 123 ---------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 3 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b. | 0 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 3 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 7 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 258 +++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c | 3 + 10 files changed, 281 insertions(+), 133 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b. (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/ifc00d.h b/drivers/gpu/drm/nouveau/include/nvif/ifc00d.h index 39be62ca7339..1d9c637859f3 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/ifc00d.h +++ b/drivers/gpu/drm/nouveau/include/nvif/ifc00d.h @@ -5,4 +5,17 @@ struct gp100_vmm_vn { /* nvif_vmm_vX ... */ }; + +struct gp100_vmm_map_vn { + /* nvif_vmm_map_vX ... */ +}; + +struct gp100_vmm_map_v0 { + /* nvif_vmm_map_vX ... */ + __u8 version; + __u8 vol; + __u8 ro; + __u8 priv; + __u8 kind; +}; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 39bf26684b41..24e2d933524d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -23,10 +23,6 @@ */ #include "vmm.h" -#include -#include -#include - #include /* Map from compressed to corresponding uncompressed storage type. @@ -75,125 +71,6 @@ gf100_mmu_kind(struct nvkm_mmu *mmu, int *count) return gf100_pte_storage_type_map; } -void -gf100_vm_map_pgt(struct nvkm_vmm *vmm, u32 index, struct nvkm_memory *pgt[2]) -{ - struct nvkm_memory *pgd = vmm->pd->pt[0]->memory; - u32 pde[2] = { 0, 0 }; - - if (pgt[0]) - pde[1] = 0x00000001 | (nvkm_memory_addr(pgt[0]) >> 8); - if (pgt[1]) - pde[0] = 0x00000001 | (nvkm_memory_addr(pgt[1]) >> 8); - - nvkm_kmap(pgd); - nvkm_wo32(pgd, (index * 8) + 0, pde[0]); - nvkm_wo32(pgd, (index * 8) + 4, pde[1]); - nvkm_done(pgd); -} - -static inline u64 -gf100_vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target) -{ - phys >>= 8; - - phys |= 0x00000001; /* present */ - if (vma->access & NV_MEM_ACCESS_SYS) - phys |= 0x00000002; - - phys |= ((u64)target << 32); - phys |= ((u64)memtype << 36); - return phys; -} - -void -gf100_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, - struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) -{ - u64 next = 1 << (vma->node->type - 8); - - phys = gf100_vm_addr(vma, phys, mem->memtype, 0); - pte <<= 3; - - if (mem->tag) { - u32 tag = mem->tag->offset + (delta >> 17); - phys |= (u64)tag << (32 + 12); - next |= (u64)1 << (32 + 12); - } - - nvkm_kmap(pgt); - while (cnt--) { - nvkm_wo32(pgt, pte + 0, lower_32_bits(phys)); - nvkm_wo32(pgt, pte + 4, upper_32_bits(phys)); - phys += next; - pte += 8; - } - nvkm_done(pgt); -} - -void -gf100_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, - struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) -{ - u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5; - /* compressed storage types are invalid for system memory */ - u32 memtype = gf100_pte_storage_type_map[mem->memtype & 0xff]; - - nvkm_kmap(pgt); - pte <<= 3; - while (cnt--) { - u64 phys = gf100_vm_addr(vma, *list++, memtype, target); - nvkm_wo32(pgt, pte + 0, lower_32_bits(phys)); - nvkm_wo32(pgt, pte + 4, upper_32_bits(phys)); - pte += 8; - } - nvkm_done(pgt); -} - -void -gf100_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) -{ - nvkm_kmap(pgt); - pte <<= 3; - while (cnt--) { - nvkm_wo32(pgt, pte + 0, 0x00000000); - nvkm_wo32(pgt, pte + 4, 0x00000000); - pte += 8; - } - nvkm_done(pgt); -} - -void -gf100_vm_flush(struct nvkm_vm *vm) -{ - struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_device *device = mmu->subdev.device; - u32 type; - - type = 0x00000001; /* PAGE_ALL */ - if (atomic_read(&vm->engref[NVKM_SUBDEV_BAR])) - type |= 0x00000004; /* HUB_ONLY */ - - mutex_lock(&mmu->subdev.mutex); - /* looks like maybe a "free flush slots" counter, the - * faster you write to 0x100cbc to more it decreases - */ - nvkm_msec(device, 2000, - if (nvkm_rd32(device, 0x100c80) & 0x00ff0000) - break; - ); - - nvkm_wr32(device, 0x100cb8, vm->pd->pt[0]->addr >> 8); - nvkm_wr32(device, 0x100cbc, 0x80000000 | type); - - /* wait for flush to be queued? */ - nvkm_msec(device, 2000, - if (nvkm_rd32(device, 0x100c80) & 0x00008000) - break; - ); - mutex_unlock(&mmu->subdev.mutex); -} - static const struct nvkm_mmu_func gf100_mmu = { .limit = (1ULL << 40), diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c index b1ba864b4b35..0cc9c89c0e73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -31,12 +31,13 @@ gp100_mmu = { .dma_bits = 47, .lpg_shift = 16, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp100_vmm_new }, + .kind = gm200_mmu_kind, }; int gp100_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) { - if (!nvkm_boolopt(device->cfgopt, "GP100MmuLayout", false)) + if (!nvkm_boolopt(device->cfgopt, "GP100MmuLayout", true)) return gm200_mmu_new(device, index, pmmu); return nvkm_mmu_new_(&gp100_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b. b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b. new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c index 5d760a198b22..5c7217697760 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c @@ -31,12 +31,13 @@ gp10b_mmu = { .dma_bits = 47, .lpg_shift = 16, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp10b_vmm_new }, + .kind = gm200_mmu_kind, }; int gp10b_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) { - if (!nvkm_boolopt(device->cfgopt, "GP100MmuLayout", false)) + if (!nvkm_boolopt(device->cfgopt, "GP100MmuLayout", true)) return gm20b_mmu_new(device, index, pmmu); return nvkm_mmu_new_(&gp10b_mmu, device, index, pmmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 5828dd82cba7..08d211d9fc55 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -45,13 +45,6 @@ extern const struct nvkm_mmu_func nv04_mmu; const u8 *nv50_mmu_kind(struct nvkm_mmu *, int *count); -void gf100_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); -void gf100_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, - u32, u32, u64, u64); -void gf100_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, - u32, u32, dma_addr_t *); -void gf100_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); -void gf100_vm_flush(struct nvkm_vm *); const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count); const u8 *gm200_mmu_kind(struct nvkm_mmu *, int *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 75f642900140..bb1353e95068 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -189,6 +189,8 @@ int gm200_vmm_join_(struct nvkm_vmm *, struct nvkm_memory *, u64 base); int gm200_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); int gp100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); +int gp100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *); +void gp100_vmm_flush(struct nvkm_vmm *, int); int nv04_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c index ddd44ad797b7..faf5a7e9265e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c @@ -182,7 +182,7 @@ gf100_vmm_flush_(struct nvkm_vmm *vmm, int depth) { struct nvkm_subdev *subdev = &vmm->mmu->subdev; struct nvkm_device *device = subdev->device; - u32 type; + u32 type = depth << 24; type = 0x00000001; /* PAGE_ALL */ if (atomic_read(&vmm->engref[NVKM_SUBDEV_BAR])) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c index 68f67812aecc..059fafe0e771 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c @@ -21,20 +21,190 @@ */ #include "vmm.h" +#include +#include + +#include +#include + +static inline void +gp100_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u64 data = (addr >> 4) | map->type; + + map->type += ptes * map->ctag; + + while (ptes--) { + VMM_WO064(pt, vmm, ptei++ * 8, data); + data += map->next; + } +} + +static void +gp100_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, gp100_vmm_pgt_pte); +} + +static void +gp100_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + if (map->page->shift == PAGE_SHIFT) { + VMM_SPAM(vmm, "DMAA %08x %08x PTE(s)", ptei, ptes); + nvkm_kmap(pt->memory); + while (ptes--) { + const u64 data = (*map->dma++ >> 4) | map->type; + VMM_WO064(pt, vmm, ptei++ * 8, data); + map->type += map->ctag; + } + nvkm_done(pt->memory); + return; + } + + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, gp100_vmm_pgt_pte); +} + +static void +gp100_vmm_pgt_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gp100_vmm_pgt_pte); +} + +static void +gp100_vmm_pgt_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + /* VALID_FALSE + VOL tells the MMU to treat the PTE as sparse. */ + VMM_FO064(pt, vmm, ptei * 8, BIT_ULL(3) /* VOL. */, ptes); +} + static const struct nvkm_vmm_desc_func gp100_vmm_desc_spt = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gp100_vmm_pgt_sparse, + .mem = gp100_vmm_pgt_mem, + .dma = gp100_vmm_pgt_dma, + .sgl = gp100_vmm_pgt_sgl, }; +static void +gp100_vmm_lpt_invalid(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + /* VALID_FALSE + PRIV tells the MMU to ignore corresponding SPTEs. */ + VMM_FO064(pt, vmm, ptei * 8, BIT_ULL(5) /* PRIV. */, ptes); +} + static const struct nvkm_vmm_desc_func gp100_vmm_desc_lpt = { + .invalid = gp100_vmm_lpt_invalid, + .unmap = gf100_vmm_pgt_unmap, + .sparse = gp100_vmm_pgt_sparse, + .mem = gp100_vmm_pgt_mem, }; +static inline void +gp100_vmm_pd0_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u64 data = (addr >> 4) | map->type; + + map->type += ptes * map->ctag; + + while (ptes--) { + VMM_WO128(pt, vmm, ptei++ * 0x10, data, 0ULL); + data += map->next; + } +} + +static void +gp100_vmm_pd0_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gp100_vmm_pd0_pte); +} + +static inline bool +gp100_vmm_pde(struct nvkm_mmu_pt *pt, u64 *data) +{ + switch (nvkm_memory_target(pt->memory)) { + case NVKM_MEM_TARGET_VRAM: *data |= 1ULL << 1; break; + case NVKM_MEM_TARGET_HOST: *data |= 2ULL << 1; + *data |= BIT_ULL(3); /* VOL. */ + break; + case NVKM_MEM_TARGET_NCOH: *data |= 3ULL << 1; break; + default: + WARN_ON(1); + return false; + } + *data |= pt->addr >> 4; + return true; +} + +static void +gp100_vmm_pd0_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + struct nvkm_mmu_pt *pd = pgd->pt[0]; + u64 data[2] = {}; + + if (pgt->pt[0] && !gp100_vmm_pde(pgt->pt[0], &data[0])) + return; + if (pgt->pt[1] && !gp100_vmm_pde(pgt->pt[1], &data[1])) + return; + + nvkm_kmap(pd->memory); + VMM_WO128(pd, vmm, pdei * 0x10, data[0], data[1]); + nvkm_done(pd->memory); +} + +static void +gp100_vmm_pd0_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes) +{ + /* VALID_FALSE + VOL_BIG tells the MMU to treat the PDE as sparse. */ + VMM_FO128(pt, vmm, pdei * 0x10, BIT_ULL(3) /* VOL_BIG. */, 0ULL, pdes); +} + +static void +gp100_vmm_pd0_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes) +{ + VMM_FO128(pt, vmm, pdei * 0x10, 0ULL, 0ULL, pdes); +} + static const struct nvkm_vmm_desc_func gp100_vmm_desc_pd0 = { + .unmap = gp100_vmm_pd0_unmap, + .sparse = gp100_vmm_pd0_sparse, + .pde = gp100_vmm_pd0_pde, + .mem = gp100_vmm_pd0_mem, }; +static void +gp100_vmm_pd1_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + struct nvkm_mmu_pt *pd = pgd->pt[0]; + u64 data = 0; + + if (!gp100_vmm_pde(pgt->pt[0], &data)) + return; + + nvkm_kmap(pd->memory); + VMM_WO064(pd, vmm, pdei * 8, data); + nvkm_done(pd->memory); +} + static const struct nvkm_vmm_desc_func gp100_vmm_desc_pd1 = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gp100_vmm_pgt_sparse, + .pde = gp100_vmm_pd1_pde, }; const struct nvkm_vmm_desc @@ -57,6 +227,91 @@ gp100_vmm_desc_12[] = { {} }; +int +gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, + struct nvkm_vmm_map *map) +{ + const enum nvkm_memory_target target = nvkm_memory_target(map->memory); + const struct nvkm_vmm_page *page = map->page; + union { + struct gp100_vmm_map_vn vn; + struct gp100_vmm_map_v0 v0; + } *args = argv; + struct nvkm_device *device = vmm->mmu->subdev.device; + struct nvkm_memory *memory = map->memory; + u8 kind, priv, ro, vol; + int kindn, aper, ret = -ENOSYS; + const u8 *kindm; + + map->next = (1ULL << page->shift) >> 4; + map->type = 0; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + vol = !!args->v0.vol; + ro = !!args->v0.ro; + priv = !!args->v0.priv; + kind = args->v0.kind; + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + vol = target == NVKM_MEM_TARGET_HOST; + ro = 0; + priv = 0; + kind = 0x00; + } else { + VMM_DEBUG(vmm, "args"); + return ret; + } + + aper = vmm->func->aper(target); + if (WARN_ON(aper < 0)) + return aper; + + kindm = vmm->mmu->func->kind(vmm->mmu, &kindn); + if (kind >= kindn || kindm[kind] == 0xff) { + VMM_DEBUG(vmm, "kind %02x", kind); + return -EINVAL; + } + + if (kindm[kind] != kind) { + u64 tags = nvkm_memory_size(memory) >> 16; + if (aper != 0 || !(page->type & NVKM_VMM_PAGE_COMP)) { + VMM_DEBUG(vmm, "comp %d %02x", aper, page->type); + return -EINVAL; + } + + ret = nvkm_memory_tags_get(memory, device, tags, + nvkm_ltc_tags_clear, + &map->tags); + if (ret) { + VMM_DEBUG(vmm, "comp %d", ret); + return ret; + } + + if (map->tags->mn) { + tags = map->tags->mn->offset + (map->offset >> 16); + map->ctag |= ((1ULL << page->shift) >> 16) << 36; + map->type |= tags << 36; + map->next |= map->ctag; + } else { + kind = kindm[kind]; + } + } + + map->type |= BIT(0); + map->type |= (u64)aper << 1; + map->type |= (u64) vol << 3; + map->type |= (u64)priv << 5; + map->type |= (u64) ro << 6; + map->type |= (u64)kind << 56; + return 0; +} + +void +gp100_vmm_flush(struct nvkm_vmm *vmm, int depth) +{ + gf100_vmm_flush_(vmm, 5 /* CACHE_LEVEL_UP_TO_PDE3 */ - depth); +} + int gp100_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) { @@ -68,6 +323,9 @@ static const struct nvkm_vmm_func gp100_vmm = { .join = gp100_vmm_join, .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gp100_vmm_valid, + .flush = gp100_vmm_flush, .page = { { 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx }, { 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c index 8b7f9b82750c..3dcc6bddb32f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c @@ -25,6 +25,9 @@ static const struct nvkm_vmm_func gp10b_vmm = { .join = gp100_vmm_join, .part = gf100_vmm_part, + .aper = gk20a_vmm_aper, + .valid = gp100_vmm_valid, + .flush = gp100_vmm_flush, .page = { { 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx }, { 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx }, -- cgit v1.2.3 From 26880e76863ace2dd34c14fcadaedf97a2ace417 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: remove support for old backends Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 1 - drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 3 - drivers/gpu/drm/nouveau/nouveau_mem.c | 30 --- drivers/gpu/drm/nouveau/nouveau_mem.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 288 +--------------------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 4 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 4 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 14 -- 16 files changed, 3 insertions(+), 358 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index e1776506746b..5b5ff5a9a127 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -23,7 +23,6 @@ #define NV_MEM_COMP_VM 0x03 struct nvkm_mem { - struct nvkm_mm_node *tag; struct nvkm_mm_node *mem; dma_addr_t *pages; u32 memtype; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index ccd87d508d04..630c3cbaf2b9 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -39,9 +39,6 @@ struct nvkm_vm { struct nvkm_mm mm; struct kref refcount; - struct nvkm_vm_pgt *pgt; - u32 fpde; - u32 lpde; bool bootstrapped; atomic_t engref[NVKM_SUBDEV_NR]; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 21d904ded441..70fbe5e72b55 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -23,8 +23,6 @@ #include "nouveau_drv.h" #include "nouveau_bo.h" -#include - #include int @@ -46,8 +44,6 @@ nouveau_mem_fini(struct nouveau_mem *mem) nvkm_vm_unmap(&mem->vma[0]); nvkm_vm_put(&mem->vma[0]); } - nvkm_memory_tags_put(&mem->memory, nvxx_device(&mem->cli->device), - &mem->tags); } int @@ -112,32 +108,6 @@ nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) mem->_mem->size = size >> NVKM_RAM_MM_SHIFT; mem->_mem->offset = nvkm_memory_addr(mem->_mem->memory); - - if (cli->device.info.chipset < 0xc0 && mem->comp) { - if (page == 16) { - ret = nvkm_memory_tags_get(mem->_mem->memory, device, - size >> page, NULL, - &mem->tags); - WARN_ON(ret); - } - if (!mem->tags || !mem->tags->mn) - mem->comp = 0; - } else - if (cli->device.info.chipset >= 0xc0 && - gf100_pte_storage_type_map[mem->kind] != mem->kind) { - if (page == 17) { - ret = nvkm_memory_tags_get(mem->_mem->memory, device, - size >> page, - nvkm_ltc_tags_clear, - &mem->tags); - WARN_ON(ret); - } - if (!mem->tags || !mem->tags->mn) - mem->kind = gf100_pte_storage_type_map[mem->kind]; - } - - if (mem->tags && mem->tags->mn) - mem->_mem->tag = mem->tags->mn; mem->_mem->mem = ((struct nvkm_vram *)mem->_mem->memory)->mn; mem->_mem->memtype = (mem->comp << 7) | mem->kind; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h index 89e9e7b9b00c..20930ebc5e21 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.h +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -25,7 +25,6 @@ struct nouveau_mem { struct nvkm_vma bar_vma; struct nvkm_memory memory; - struct nvkm_tags *tags; }; enum nvif_vmm_get { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 741021ff8c27..31832398f1e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -24,7 +24,6 @@ #include "priv.h" #include "vmm.h" -#include #include #include @@ -316,17 +315,6 @@ void nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) { const struct nvkm_vmm_page *page = vma->vm->func->page; - struct nvkm_vm *vm = vma->vm; - struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_mm_node *r = node->mem; - int big = vma->node->type != mmu->func->spg_shift; - u32 offset = vma->node->offset + (delta >> 12); - u32 bits = vma->node->type - 12; - u32 pde = (offset >> mmu->func->pgt_bits) - vm->fpde; - u32 pte = (offset & ((1 << mmu->func->pgt_bits) - 1)) >> bits; - u32 max = 1 << (mmu->func->pgt_bits - bits); - u32 end, len; - if (page->desc->func->unmap) { struct nvkm_vmm_map map = { .mem = node->mem }; while (page->shift != vma->node->type) @@ -334,36 +322,6 @@ nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) nvkm_vm_map_(page, vma, delta, node, page->desc->func->mem, &map); return; } - - delta = 0; - while (r) { - u64 phys = (u64)r->offset << 12; - u32 num = r->length >> bits; - - while (num) { - struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; - - end = (pte + num); - if (unlikely(end >= max)) - end = max; - len = end - pte; - - mmu->func->map(vma, pgt, node, pte, len, phys, delta); - - num -= len; - pte += len; - if (unlikely(end >= max)) { - phys += len << (bits + 12); - pde++; - pte = 0; - } - - delta += (u64)len << vma->node->type; - } - r = r->next; - } - - mmu->func->flush(vm); } static void @@ -371,20 +329,6 @@ nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length, struct nvkm_mem *mem) { const struct nvkm_vmm_page *page = vma->vm->func->page; - struct nvkm_vm *vm = vma->vm; - struct nvkm_mmu *mmu = vm->mmu; - int big = vma->node->type != mmu->func->spg_shift; - u32 offset = vma->node->offset + (delta >> 12); - u32 bits = vma->node->type - 12; - u32 num = length >> vma->node->type; - u32 pde = (offset >> mmu->func->pgt_bits) - vm->fpde; - u32 pte = (offset & ((1 << mmu->func->pgt_bits) - 1)) >> bits; - u32 max = 1 << (mmu->func->pgt_bits - bits); - unsigned m, sglen; - u32 end, len; - int i; - struct scatterlist *sg; - if (page->desc->func->unmap) { struct nvkm_vmm_map map = { .sgl = mem->sg->sgl }; while (page->shift != vma->node->type) @@ -392,45 +336,6 @@ nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length, nvkm_vm_map_(page, vma, delta, mem, page->desc->func->sgl, &map); return; } - - for_each_sg(mem->sg->sgl, sg, mem->sg->nents, i) { - struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; - sglen = sg_dma_len(sg) >> PAGE_SHIFT; - - end = pte + sglen; - if (unlikely(end >= max)) - end = max; - len = end - pte; - - for (m = 0; m < len; m++) { - dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT); - - mmu->func->map_sg(vma, pgt, mem, pte, 1, &addr); - num--; - pte++; - - if (num == 0) - goto finish; - } - if (unlikely(end >= max)) { - pde++; - pte = 0; - } - if (m < sglen) { - for (; m < sglen; m++) { - dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT); - - mmu->func->map_sg(vma, pgt, mem, pte, 1, &addr); - num--; - pte++; - if (num == 0) - goto finish; - } - } - - } -finish: - mmu->func->flush(vm); } static void @@ -438,18 +343,6 @@ nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length, struct nvkm_mem *mem) { const struct nvkm_vmm_page *page = vma->vm->func->page; - struct nvkm_vm *vm = vma->vm; - struct nvkm_mmu *mmu = vm->mmu; - dma_addr_t *list = mem->pages; - int big = vma->node->type != mmu->func->spg_shift; - u32 offset = vma->node->offset + (delta >> 12); - u32 bits = vma->node->type - 12; - u32 num = length >> vma->node->type; - u32 pde = (offset >> mmu->func->pgt_bits) - vm->fpde; - u32 pte = (offset & ((1 << mmu->func->pgt_bits) - 1)) >> bits; - u32 max = 1 << (mmu->func->pgt_bits - bits); - u32 end, len; - if (page->desc->func->unmap) { struct nvkm_vmm_map map = { .dma = mem->pages }; while (page->shift != vma->node->type) @@ -457,27 +350,6 @@ nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length, nvkm_vm_map_(page, vma, delta, mem, page->desc->func->dma, &map); return; } - - while (num) { - struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; - - end = (pte + num); - if (unlikely(end >= max)) - end = max; - len = end - pte; - - mmu->func->map_sg(vma, pgt, mem, pte, len, list); - - num -= len; - pte += len; - list += len; - if (unlikely(end >= max)) { - pde++; - pte = 0; - } - } - - mmu->func->flush(vm); } void @@ -496,16 +368,6 @@ void nvkm_vm_unmap_at(struct nvkm_vma *vma, u64 delta, u64 length) { struct nvkm_vm *vm = vma->vm; - struct nvkm_mmu *mmu = vm->mmu; - int big = vma->node->type != mmu->func->spg_shift; - u32 offset = vma->node->offset + (delta >> 12); - u32 bits = vma->node->type - 12; - u32 num = length >> vma->node->type; - u32 pde = (offset >> mmu->func->pgt_bits) - vm->fpde; - u32 pte = (offset & ((1 << mmu->func->pgt_bits) - 1)) >> bits; - u32 max = 1 << (mmu->func->pgt_bits - bits); - u32 end, len; - if (vm->func->page->desc->func->unmap) { const struct nvkm_vmm_page *page = vm->func->page; while (page->shift != vma->node->type) @@ -516,26 +378,6 @@ nvkm_vm_unmap_at(struct nvkm_vma *vma, u64 delta, u64 length) mutex_unlock(&vm->mutex); return; } - - while (num) { - struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; - - end = (pte + num); - if (unlikely(end >= max)) - end = max; - len = end - pte; - - mmu->func->unmap(vma, pgt, pte, len); - - num -= len; - pte += len; - if (unlikely(end >= max)) { - pde++; - pte = 0; - } - } - - mmu->func->flush(vm); } void @@ -547,63 +389,12 @@ nvkm_vm_unmap(struct nvkm_vma *vma) nvkm_memory_unref(&vma->memory); } -static void -nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde) -{ - struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_vm_pgt *vpgt; - struct nvkm_memory *pgt; - u32 pde; - - for (pde = fpde; pde <= lpde; pde++) { - vpgt = &vm->pgt[pde - vm->fpde]; - if (--vpgt->refcount[big]) - continue; - - pgt = vpgt->mem[big]; - vpgt->mem[big] = NULL; - - if (mmu->func->map_pgt) - mmu->func->map_pgt(vm, pde, vpgt->mem); - - mmu->func->flush(vm); - - nvkm_memory_unref(&pgt); - } -} - -static int -nvkm_vm_map_pgt(struct nvkm_vm *vm, u32 pde, u32 type) -{ - struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; - int big = (type != mmu->func->spg_shift); - u32 pgt_size; - int ret; - - pgt_size = (1 << (mmu->func->pgt_bits + 12)) >> type; - pgt_size *= 8; - - ret = nvkm_memory_new(mmu->subdev.device, NVKM_MEM_TARGET_INST, - pgt_size, 0x1000, true, &vpgt->mem[big]); - if (unlikely(ret)) - return ret; - - if (mmu->func->map_pgt) - mmu->func->map_pgt(vm, pde, vpgt->mem); - - vpgt->refcount[big]++; - return 0; -} - int nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access, struct nvkm_vma *vma) { - struct nvkm_mmu *mmu = vm->mmu; u32 align = (1 << page_shift) >> 12; u32 msize = size >> 12; - u32 fpde, lpde, pde; int ret; mutex_lock(&vm->mutex); @@ -626,32 +417,7 @@ nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access, mutex_unlock(&vm->mutex); return ret; } - - goto done; - } - - fpde = (vma->node->offset >> mmu->func->pgt_bits); - lpde = (vma->node->offset + vma->node->length - 1) >> mmu->func->pgt_bits; - - for (pde = fpde; pde <= lpde; pde++) { - struct nvkm_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; - int big = (vma->node->type != mmu->func->spg_shift); - - if (likely(vpgt->refcount[big])) { - vpgt->refcount[big]++; - continue; - } - - ret = nvkm_vm_map_pgt(vm, pde, vma->node->type); - if (ret) { - if (pde != fpde) - nvkm_vm_unmap_pgt(vm, big, fpde, pde - 1); - nvkm_mm_free(&vm->mm, &vma->node); - mutex_unlock(&vm->mutex); - return ret; - } } -done: mutex_unlock(&vm->mutex); vma->memory = NULL; @@ -668,7 +434,6 @@ nvkm_vm_put(struct nvkm_vma *vma) { struct nvkm_mmu *mmu; struct nvkm_vm *vm; - u32 fpde, lpde; if (unlikely(vma->node == NULL)) return; @@ -678,9 +443,6 @@ nvkm_vm_put(struct nvkm_vma *vma) nvkm_memory_tags_put(vma->memory, mmu->subdev.device, &vma->tags); nvkm_memory_unref(&vma->memory); - fpde = (vma->node->offset >> mmu->func->pgt_bits); - lpde = (vma->node->offset + vma->node->length - 1) >> mmu->func->pgt_bits; - mutex_lock(&vm->mutex); if (vm->func->page->desc->func->unmap) { const struct nvkm_vmm_page *page = vm->func->page; @@ -689,11 +451,8 @@ nvkm_vm_put(struct nvkm_vma *vma) nvkm_vmm_ptes_put(vm, page, vma->node->offset << 12, vma->node->length << 12); - goto done; } - nvkm_vm_unmap_pgt(vm, vma->node->type != mmu->func->spg_shift, fpde, lpde); -done: nvkm_mm_free(&vm->mm, &vma->node); mutex_unlock(&vm->mutex); @@ -703,23 +462,7 @@ done: int nvkm_vm_boot(struct nvkm_vm *vm, u64 size) { - struct nvkm_mmu *mmu = vm->mmu; - struct nvkm_memory *pgt; - int ret; - - if (vm->func->page->desc->func->unmap) - return nvkm_vmm_boot(vm); - - ret = nvkm_memory_new(mmu->subdev.device, NVKM_MEM_TARGET_INST, - (size >> mmu->func->spg_shift) * 8, 0x1000, true, &pgt); - if (ret == 0) { - vm->pgt[0].refcount[0] = 1; - vm->pgt[0].mem[0] = pgt; - nvkm_memory_boot(pgt, vm); - vm->bootstrapped = true; - } - - return ret; + return nvkm_vmm_boot(vm); } static int @@ -730,24 +473,14 @@ nvkm_vm_legacy(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, int ret; kref_init(&vm->refcount); - vm->fpde = offset >> (mmu->func->pgt_bits + 12); - vm->lpde = (offset + length - 1) >> (mmu->func->pgt_bits + 12); - - vm->pgt = vzalloc((vm->lpde - vm->fpde + 1) * sizeof(*vm->pgt)); - if (!vm->pgt) { - kfree(vm); - return -ENOMEM; - } if (block > length) block = length; ret = nvkm_mm_init(&vm->mm, 0, mm_offset >> 12, mm_length >> 12, block >> 12); - if (ret) { - vfree(vm->pgt); + if (ret) return ret; - } return 0; } @@ -786,7 +519,6 @@ nvkm_vm_del(struct kref *kref) struct nvkm_vm *vm = container_of(kref, typeof(*vm), refcount); nvkm_mm_fini(&vm->mm); - vfree(vm->pgt); if (vm->func) nvkm_vmm_dtor(vm); kfree(vm); @@ -797,14 +529,9 @@ nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) { if (ref) { if (ref->func->join && inst) { - int ret = ref->func->join(ref, inst), i; + int ret = ref->func->join(ref, inst); if (ret) return ret; - - if (!ref->func->page->desc->func->unmap && ref->mmu->func->map_pgt) { - for (i = ref->fpde; i <= ref->lpde; i++) - ref->mmu->func->map_pgt(ref, i, ref->pgt[i - ref->fpde].mem); - } } kref_get(&ref->refcount); @@ -813,12 +540,6 @@ nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) if (*ptr) { if ((*ptr)->func->part && inst) (*ptr)->func->part(*ptr, inst); - if ((*ptr)->bootstrapped && inst) { - if (!(*ptr)->func->page->desc->func->unmap) { - nvkm_memory_unref(&(*ptr)->pgt[0].mem[0]); - (*ptr)->bootstrapped = false; - } - } kref_put(&(*ptr)->refcount, nvkm_vm_del); } @@ -838,9 +559,6 @@ nvkm_mmu_oneinit(struct nvkm_subdev *subdev) return ret; } - if (mmu->func->oneinit) - return mmu->func->oneinit(mmu); - return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index e436c610b3df..c90c9980478b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -27,8 +27,6 @@ static const struct nvkm_mmu_func g84_mmu = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 29 - 12, - .spg_shift = 12, .lpg_shift = 16, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, .kind = nv50_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 24e2d933524d..ca5ca27188cd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -75,8 +75,6 @@ static const struct nvkm_mmu_func gf100_mmu = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new }, .kind = gf100_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index 8cbd0723c25b..db7353aa25df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -27,8 +27,6 @@ static const struct nvkm_mmu_func gk104_mmu = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new }, .kind = gf100_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index 57def7244d38..2dfe8b1ba109 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -27,8 +27,6 @@ static const struct nvkm_mmu_func gk20a_mmu = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new }, .kind = gf100_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index c38c899e463c..a9628baf5372 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -71,8 +71,6 @@ static const struct nvkm_mmu_func gm200_mmu = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, .lpg_shift = 17, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm200_vmm_new }, .kind = gm200_mmu_kind, @@ -82,8 +80,6 @@ static const struct nvkm_mmu_func gm200_mmu_fixed = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm200_vmm_new_fixed }, .kind = gm200_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 8cd6d1617bd7..5d14c138af02 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -29,8 +29,6 @@ static const struct nvkm_mmu_func gm20b_mmu = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, .lpg_shift = 17, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new }, .kind = gm200_mmu_kind, @@ -40,8 +38,6 @@ static const struct nvkm_mmu_func gm20b_mmu_fixed = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 27 - 12, - .spg_shift = 12, .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new_fixed }, .kind = gm200_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 13438dbc6063..3ae70e218bc0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -31,8 +31,6 @@ const struct nvkm_mmu_func nv04_mmu = { .limit = NV04_PDMA_SIZE, .dma_bits = 32, - .pgt_bits = 32 - 12, - .spg_shift = 12, .lpg_shift = 12, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv04_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c index 457cf509591b..5bcbc10d8564 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c @@ -43,8 +43,6 @@ nv41_mmu = { .init = nv41_mmu_init, .limit = NV41_GART_SIZE, .dma_bits = 39, - .pgt_bits = 32 - 12, - .spg_shift = 12, .lpg_shift = 12, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv41_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c index 2072139bff4d..998287021e3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c @@ -58,8 +58,6 @@ nv44_mmu = { .init = nv44_mmu_init, .limit = NV44_GART_SIZE, .dma_bits = 39, - .pgt_bits = 32 - 12, - .spg_shift = 12, .lpg_shift = 12, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv44_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index 31d6f9626e56..7af1f89fe004 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -63,8 +63,6 @@ static const struct nvkm_mmu_func nv50_mmu = { .limit = (1ULL << 40), .dma_bits = 40, - .pgt_bits = 29 - 12, - .spg_shift = 12, .lpg_shift = 16, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, .kind = nv50_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 08d211d9fc55..bc4571a20690 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -9,26 +9,12 @@ int nvkm_mmu_new_(const struct nvkm_mmu_func *, struct nvkm_device *, int index, struct nvkm_mmu **); struct nvkm_mmu_func { - int (*oneinit)(struct nvkm_mmu *); void (*init)(struct nvkm_mmu *); u64 limit; u8 dma_bits; - u32 pgt_bits; - u8 spg_shift; u8 lpg_shift; - void (*map_pgt)(struct nvkm_vmm *, u32 pde, - struct nvkm_memory *pgt[2]); - void (*map)(struct nvkm_vma *, struct nvkm_memory *, - struct nvkm_mem *, u32 pte, u32 cnt, - u64 phys, u64 delta); - void (*map_sg)(struct nvkm_vma *, struct nvkm_memory *, - struct nvkm_mem *, u32 pte, u32 cnt, dma_addr_t *); - void (*unmap)(struct nvkm_vma *, struct nvkm_memory *pgt, - u32 pte, u32 cnt); - void (*flush)(struct nvkm_vm *); - struct { struct nvkm_sclass user; int (*ctor)(struct nvkm_mmu *, u64 addr, u64 size, -- cgit v1.2.3 From f9463a4bc8ea2df5ea25c4d6e0be72011e559b95 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: implement new vmm frontend These are the new priviledged interfaces to the VMM backends, and expose some functionality that wasn't previously available. It's now possible to allocate a chunk of address-space (even all of it), without causing page tables to be allocated up-front, and then map into it at arbitrary locations. This is the basic primitive used to support features such as sparse mapping, or to allow userspace control over its own address-space, or HMM (where the GPU driver isn't in control of the address-space layout). Rather than being tied to a subtle combination of memory object and VMA properties, arguments that control map flags (ro, kind, etc) are passed explicitly at map time. The compatibility hacks to implement the old frontend on top of the new driver backends have been replaced with something similar to implement the old frontend's interfaces on top of the new frontend. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 4 +- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 48 +- drivers/gpu/drm/nouveau/nouveau_mem.h | 2 + .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 152 +--- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 787 ++++++++++++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 17 +- drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h | 1 + 8 files changed, 858 insertions(+), 154 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 5b5ff5a9a127..4af663d4d3c7 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -1,9 +1,7 @@ #ifndef __NVKM_FB_H__ #define __NVKM_FB_H__ #include -#include - -#include +#include /* memory type/access flags, do not match hardware values */ #define NV_MEM_ACCESS_RO 1 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 630c3cbaf2b9..7fa60d79ec4c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -1,9 +1,6 @@ #ifndef __NVKM_MMU_H__ #define __NVKM_MMU_H__ #include -#include -#include -struct nvkm_gpuobj; struct nvkm_mem; struct nvkm_vm_pgt { @@ -12,14 +9,25 @@ struct nvkm_vm_pgt { }; struct nvkm_vma { - struct nvkm_memory *memory; - struct nvkm_tags *tags; + struct list_head head; + struct rb_node tree; + u64 addr; + u64 size:50; + bool mapref:1; /* PTs (de)referenced on (un)map (vs pre-allocated). */ + bool sparse:1; /* Unmapped PDEs/PTEs will not trigger MMU faults. */ +#define NVKM_VMA_PAGE_NONE 7 + u8 page:3; /* Requested page type (index, or NONE for automatic). */ + u8 refd:3; /* Current page type (index, or NONE for unreferenced). */ + bool used:1; /* Region allocated. */ + bool part:1; /* Region was split from an allocated region by map(). */ + bool user:1; /* Region user-allocated. */ + bool busy:1; /* Region busy (for temporarily preventing user access). */ + struct nvkm_memory *memory; /* Memory currently mapped into VMA. */ + struct nvkm_tags *tags; /* Compression tag reference. */ + + struct nvkm_vma *node; struct nvkm_vm *vm; - struct nvkm_mm_node *node; - union { - u64 offset; - u64 addr; - }; + u64 offset; u32 access; }; @@ -37,8 +45,9 @@ struct nvkm_vm { struct nvkm_vmm_pt *pd; struct list_head join; - struct nvkm_mm mm; - struct kref refcount; + struct list_head list; + struct rb_root free; + struct rb_root root; bool bootstrapped; atomic_t engref[NVKM_SUBDEV_NR]; @@ -57,9 +66,16 @@ void nvkm_vm_put(struct nvkm_vma *); void nvkm_vm_map(struct nvkm_vma *, struct nvkm_mem *); void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, struct nvkm_mem *); void nvkm_vm_unmap(struct nvkm_vma *); -void nvkm_vm_unmap_at(struct nvkm_vma *, u64 offset, u64 length); +int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *, const char *name, struct nvkm_vmm **); +struct nvkm_vmm *nvkm_vmm_ref(struct nvkm_vmm *); +void nvkm_vmm_unref(struct nvkm_vmm **); int nvkm_vmm_boot(struct nvkm_vmm *); +int nvkm_vmm_join(struct nvkm_vmm *, struct nvkm_memory *inst); +void nvkm_vmm_part(struct nvkm_vmm *, struct nvkm_memory *inst); +int nvkm_vmm_get(struct nvkm_vmm *, u8 page, u64 size, struct nvkm_vma **); +void nvkm_vmm_put(struct nvkm_vmm *, struct nvkm_vma **); struct nvkm_vmm_map { struct nvkm_memory *memory; @@ -78,6 +94,12 @@ struct nvkm_vmm_map { u64 ctag; }; +int nvkm_vmm_map(struct nvkm_vmm *, struct nvkm_vma *, void *argv, u32 argc, + struct nvkm_vmm_map *); +void nvkm_vmm_unmap(struct nvkm_vmm *, struct nvkm_vma *); + +struct nvkm_vmm *nvkm_uvmm_search(struct nvkm_client *, u64 handle); + struct nvkm_mmu { const struct nvkm_mmu_func *func; struct nvkm_subdev subdev; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h index 20930ebc5e21..48388c538420 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.h +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -1,6 +1,8 @@ #ifndef __NOUVEAU_MEM_H__ #define __NOUVEAU_MEM_H__ +#include #include +#include #include struct ttm_dma_tt; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 816d1231df5f..39f6e8e42339 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -48,6 +48,7 @@ #include #include #include +#include struct gk20a_instobj { struct nvkm_memory memory; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 31832398f1e9..9bf688df24f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -266,14 +266,14 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, } mutex_lock(&vmm->mutex); - nvkm_vmm_ptes_map(vmm, page, ((u64)vma->node->offset << 12) + delta, - (u64)vma->node->length << 12, map, fn); + nvkm_vmm_ptes_map(vmm, page, vma->node->addr + delta, + vma->node->size, map, fn); mutex_unlock(&vmm->mutex); - nvkm_memory_tags_put(vma->memory, vmm->mmu->subdev.device, &vma->tags); - nvkm_memory_unref(&vma->memory); - vma->memory = nvkm_memory_ref(map->memory); - vma->tags = map->tags; + nvkm_memory_tags_put(vma->node->memory, vmm->mmu->subdev.device, &vma->node->tags); + nvkm_memory_unref(&vma->node->memory); + vma->node->memory = nvkm_memory_ref(map->memory); + vma->node->tags = map->tags; } void @@ -314,11 +314,9 @@ nvkm_mmu_ptc_init(struct nvkm_mmu *mmu) void nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) { - const struct nvkm_vmm_page *page = vma->vm->func->page; + const struct nvkm_vmm_page *page = &vma->vm->func->page[vma->node->page]; if (page->desc->func->unmap) { struct nvkm_vmm_map map = { .mem = node->mem }; - while (page->shift != vma->node->type) - page++; nvkm_vm_map_(page, vma, delta, node, page->desc->func->mem, &map); return; } @@ -328,11 +326,9 @@ static void nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length, struct nvkm_mem *mem) { - const struct nvkm_vmm_page *page = vma->vm->func->page; + const struct nvkm_vmm_page *page = &vma->vm->func->page[vma->node->page]; if (page->desc->func->unmap) { struct nvkm_vmm_map map = { .sgl = mem->sg->sgl }; - while (page->shift != vma->node->type) - page++; nvkm_vm_map_(page, vma, delta, mem, page->desc->func->sgl, &map); return; } @@ -342,11 +338,9 @@ static void nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length, struct nvkm_mem *mem) { - const struct nvkm_vmm_page *page = vma->vm->func->page; + const struct nvkm_vmm_page *page = &vma->vm->func->page[vma->node->page]; if (page->desc->func->unmap) { struct nvkm_vmm_map map = { .dma = mem->pages }; - while (page->shift != vma->node->type) - page++; nvkm_vm_map_(page, vma, delta, mem, page->desc->func->dma, &map); return; } @@ -364,67 +358,30 @@ nvkm_vm_map(struct nvkm_vma *vma, struct nvkm_mem *node) nvkm_vm_map_at(vma, 0, node); } -void -nvkm_vm_unmap_at(struct nvkm_vma *vma, u64 delta, u64 length) -{ - struct nvkm_vm *vm = vma->vm; - if (vm->func->page->desc->func->unmap) { - const struct nvkm_vmm_page *page = vm->func->page; - while (page->shift != vma->node->type) - page++; - mutex_lock(&vm->mutex); - nvkm_vmm_ptes_unmap(vm, page, (vma->node->offset << 12) + delta, - vma->node->length << 12, false); - mutex_unlock(&vm->mutex); - return; - } -} - void nvkm_vm_unmap(struct nvkm_vma *vma) { - nvkm_vm_unmap_at(vma, 0, (u64)vma->node->length << 12); - - nvkm_memory_tags_put(vma->memory, vma->vm->mmu->subdev.device, &vma->tags); - nvkm_memory_unref(&vma->memory); + nvkm_vmm_unmap(vma->vm, vma->node); } int nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access, struct nvkm_vma *vma) { - u32 align = (1 << page_shift) >> 12; - u32 msize = size >> 12; int ret; mutex_lock(&vm->mutex); - ret = nvkm_mm_head(&vm->mm, 0, page_shift, msize, msize, align, - &vma->node); - if (unlikely(ret != 0)) { - mutex_unlock(&vm->mutex); - return ret; - } - - if (vm->func->page->desc->func->unmap) { - const struct nvkm_vmm_page *page = vm->func->page; - while (page->shift != page_shift) - page++; - - ret = nvkm_vmm_ptes_get(vm, page, vma->node->offset << 12, - vma->node->length << 12); - if (ret) { - nvkm_mm_free(&vm->mm, &vma->node); - mutex_unlock(&vm->mutex); - return ret; - } - } + ret = nvkm_vmm_get_locked(vm, true, false, false, page_shift, 0, + size, &vma->node); mutex_unlock(&vm->mutex); + if (ret) + return ret; vma->memory = NULL; vma->tags = NULL; vma->vm = NULL; nvkm_vm_ref(vm, &vma->vm, NULL); - vma->offset = (u64)vma->node->offset << 12; + vma->offset = vma->addr = vma->node->addr; vma->access = access; return 0; } @@ -432,30 +389,7 @@ nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access, void nvkm_vm_put(struct nvkm_vma *vma) { - struct nvkm_mmu *mmu; - struct nvkm_vm *vm; - - if (unlikely(vma->node == NULL)) - return; - vm = vma->vm; - mmu = vm->mmu; - - nvkm_memory_tags_put(vma->memory, mmu->subdev.device, &vma->tags); - nvkm_memory_unref(&vma->memory); - - mutex_lock(&vm->mutex); - if (vm->func->page->desc->func->unmap) { - const struct nvkm_vmm_page *page = vm->func->page; - while (page->shift != vma->node->type) - page++; - - nvkm_vmm_ptes_put(vm, page, vma->node->offset << 12, - vma->node->length << 12); - } - - nvkm_mm_free(&vm->mm, &vma->node); - mutex_unlock(&vm->mutex); - + nvkm_vmm_put(vma->vm, &vma->node); nvkm_vm_ref(NULL, &vma->vm, NULL); } @@ -465,26 +399,6 @@ nvkm_vm_boot(struct nvkm_vm *vm, u64 size) return nvkm_vmm_boot(vm); } -static int -nvkm_vm_legacy(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, - u32 block, struct nvkm_vm *vm) -{ - u64 mm_length = (offset + length) - mm_offset; - int ret; - - kref_init(&vm->refcount); - - if (block > length) - block = length; - - ret = nvkm_mm_init(&vm->mm, 0, mm_offset >> 12, mm_length >> 12, - block >> 12); - if (ret) - return ret; - - return 0; -} - int nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, struct lock_class_key *key, struct nvkm_vm **pvm) @@ -501,46 +415,28 @@ nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, return ret; } - ret = nvkm_vm_legacy(mmu, offset, length, mm_offset, - (*pvm)->func->page_block ? - (*pvm)->func->page_block : 4096, *pvm); - if (ret) - nvkm_vm_ref(NULL, pvm, NULL); - return ret; } return -EINVAL; } -static void -nvkm_vm_del(struct kref *kref) -{ - struct nvkm_vm *vm = container_of(kref, typeof(*vm), refcount); - - nvkm_mm_fini(&vm->mm); - if (vm->func) - nvkm_vmm_dtor(vm); - kfree(vm); -} - int nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) { if (ref) { - if (ref->func->join && inst) { - int ret = ref->func->join(ref, inst); + if (inst) { + int ret = nvkm_vmm_join(ref, inst); if (ret) return ret; } - kref_get(&ref->refcount); + nvkm_vmm_ref(ref); } if (*ptr) { - if ((*ptr)->func->part && inst) - (*ptr)->func->part(*ptr, inst); - kref_put(&(*ptr)->refcount, nvkm_vm_del); + nvkm_vmm_part(*ptr, inst); + nvkm_vmm_unref(ptr); } *ptr = ref; @@ -553,8 +449,8 @@ nvkm_mmu_oneinit(struct nvkm_subdev *subdev) struct nvkm_mmu *mmu = nvkm_mmu(subdev); if (mmu->func->vmm.global) { - int ret = nvkm_vm_new(subdev->device, 0, mmu->limit, 0, - NULL, &mmu->vmm); + int ret = nvkm_vmm_new(subdev->device, 0, 0, NULL, 0, NULL, + "gart", &mmu->vmm); if (ret) return ret; } @@ -576,7 +472,7 @@ nvkm_mmu_dtor(struct nvkm_subdev *subdev) { struct nvkm_mmu *mmu = nvkm_mmu(subdev); - nvkm_vm_ref(NULL, &mmu->vmm, NULL); + nvkm_vmm_unref(&mmu->vmm); nvkm_mmu_ptc_fini(mmu); return mmu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 46c7fecf0054..31c4acaf44a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -22,6 +22,8 @@ #define NVKM_VMM_LEVELS_MAX 5 #include "vmm.h" +#include + static void nvkm_vmm_pt_del(struct nvkm_vmm_pt **ppgt) { @@ -376,6 +378,25 @@ nvkm_vmm_sparse_ptes(const struct nvkm_vmm_desc *desc, } } +static bool +nvkm_vmm_sparse_unref_ptes(struct nvkm_vmm_iter *it, u32 ptei, u32 ptes) +{ + struct nvkm_vmm_pt *pt = it->pt[0]; + if (it->desc->type == PGD) + memset(&pt->pde[ptei], 0x00, sizeof(pt->pde[0]) * ptes); + else + if (it->desc->type == LPT) + memset(&pt->pte[ptei], 0x00, sizeof(pt->pte[0]) * ptes); + return nvkm_vmm_unref_ptes(it, ptei, ptes); +} + +static bool +nvkm_vmm_sparse_ref_ptes(struct nvkm_vmm_iter *it, u32 ptei, u32 ptes) +{ + nvkm_vmm_sparse_ptes(it->desc, it->pt[0], ptei, ptes); + return nvkm_vmm_ref_ptes(it, ptei, ptes); +} + static bool nvkm_vmm_ref_hwpt(struct nvkm_vmm_iter *it, struct nvkm_vmm_pt *pgd, u32 pdei) { @@ -565,7 +586,111 @@ fail: return addr << page->shift; } -void +static void +nvkm_vmm_ptes_sparse_put(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size) +{ + nvkm_vmm_iter(vmm, page, addr, size, "sparse unref", false, + nvkm_vmm_sparse_unref_ptes, NULL, NULL, + page->desc->func->invalid ? + page->desc->func->invalid : page->desc->func->unmap); +} + +static int +nvkm_vmm_ptes_sparse_get(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size) +{ + if ((page->type & NVKM_VMM_PAGE_SPARSE)) { + u64 fail = nvkm_vmm_iter(vmm, page, addr, size, "sparse ref", + true, nvkm_vmm_sparse_ref_ptes, NULL, + NULL, page->desc->func->sparse); + if (fail != ~0ULL) { + if ((size = fail - addr)) + nvkm_vmm_ptes_sparse_put(vmm, page, addr, size); + return -ENOMEM; + } + return 0; + } + return -EINVAL; +} + +static int +nvkm_vmm_ptes_sparse(struct nvkm_vmm *vmm, u64 addr, u64 size, bool ref) +{ + const struct nvkm_vmm_page *page = vmm->func->page; + int m = 0, i; + u64 start = addr; + u64 block; + + while (size) { + /* Limit maximum page size based on remaining size. */ + while (size < (1ULL << page[m].shift)) + m++; + i = m; + + /* Find largest page size suitable for alignment. */ + while (!IS_ALIGNED(addr, 1ULL << page[i].shift)) + i++; + + /* Determine number of PTEs at this page size. */ + if (i != m) { + /* Limited to alignment boundary of next page size. */ + u64 next = 1ULL << page[i - 1].shift; + u64 part = ALIGN(addr, next) - addr; + if (size - part >= next) + block = (part >> page[i].shift) << page[i].shift; + else + block = (size >> page[i].shift) << page[i].shift; + } else { + block = (size >> page[i].shift) << page[i].shift;; + } + + /* Perform operation. */ + if (ref) { + int ret = nvkm_vmm_ptes_sparse_get(vmm, &page[i], addr, block); + if (ret) { + if ((size = addr - start)) + nvkm_vmm_ptes_sparse(vmm, start, size, false); + return ret; + } + } else { + nvkm_vmm_ptes_sparse_put(vmm, &page[i], addr, block); + } + + size -= block; + addr += block; + } + + return 0; +} + +static void +nvkm_vmm_ptes_unmap_put(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size, bool sparse) +{ + const struct nvkm_vmm_desc_func *func = page->desc->func; + nvkm_vmm_iter(vmm, page, addr, size, "unmap + unref", + false, nvkm_vmm_unref_ptes, NULL, NULL, + sparse ? func->sparse : func->invalid ? func->invalid : + func->unmap); +} + +static int +nvkm_vmm_ptes_get_map(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, + u64 addr, u64 size, struct nvkm_vmm_map *map, + nvkm_vmm_pte_func func) +{ + u64 fail = nvkm_vmm_iter(vmm, page, addr, size, "ref + map", true, + nvkm_vmm_ref_ptes, func, map, NULL); + if (fail != ~0ULL) { + if ((size = fail - addr)) + nvkm_vmm_ptes_unmap_put(vmm, page, addr, size, false); + return -ENOMEM; + } + return 0; +} + +static void nvkm_vmm_ptes_unmap(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, u64 addr, u64 size, bool sparse) { @@ -584,7 +709,7 @@ nvkm_vmm_ptes_map(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, NULL, func, map, NULL); } -void +static void nvkm_vmm_ptes_put(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, u64 addr, u64 size) { @@ -592,7 +717,7 @@ nvkm_vmm_ptes_put(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, nvkm_vmm_unref_ptes, NULL, NULL, NULL); } -int +static int nvkm_vmm_ptes_get(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, u64 addr, u64 size) { @@ -606,9 +731,120 @@ nvkm_vmm_ptes_get(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, return 0; } +static inline struct nvkm_vma * +nvkm_vma_new(u64 addr, u64 size) +{ + struct nvkm_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); + if (vma) { + vma->addr = addr; + vma->size = size; + vma->page = NVKM_VMA_PAGE_NONE; + vma->refd = NVKM_VMA_PAGE_NONE; + } + return vma; +} + +struct nvkm_vma * +nvkm_vma_tail(struct nvkm_vma *vma, u64 tail) +{ + struct nvkm_vma *new; + + BUG_ON(vma->size == tail); + + if (!(new = nvkm_vma_new(vma->addr + (vma->size - tail), tail))) + return NULL; + vma->size -= tail; + + new->mapref = vma->mapref; + new->sparse = vma->sparse; + new->page = vma->page; + new->refd = vma->refd; + new->used = vma->used; + new->part = vma->part; + new->user = vma->user; + new->busy = vma->busy; + list_add(&new->head, &vma->head); + return new; +} + +static void +nvkm_vmm_free_insert(struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + struct rb_node **ptr = &vmm->free.rb_node; + struct rb_node *parent = NULL; + + while (*ptr) { + struct nvkm_vma *this = rb_entry(*ptr, typeof(*this), tree); + parent = *ptr; + if (vma->size < this->size) + ptr = &parent->rb_left; + else + if (vma->size > this->size) + ptr = &parent->rb_right; + else + if (vma->addr < this->addr) + ptr = &parent->rb_left; + else + if (vma->addr > this->addr) + ptr = &parent->rb_right; + else + BUG(); + } + + rb_link_node(&vma->tree, parent, ptr); + rb_insert_color(&vma->tree, &vmm->free); +} + void +nvkm_vmm_node_insert(struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + struct rb_node **ptr = &vmm->root.rb_node; + struct rb_node *parent = NULL; + + while (*ptr) { + struct nvkm_vma *this = rb_entry(*ptr, typeof(*this), tree); + parent = *ptr; + if (vma->addr < this->addr) + ptr = &parent->rb_left; + else + if (vma->addr > this->addr) + ptr = &parent->rb_right; + else + BUG(); + } + + rb_link_node(&vma->tree, parent, ptr); + rb_insert_color(&vma->tree, &vmm->root); +} + +struct nvkm_vma * +nvkm_vmm_node_search(struct nvkm_vmm *vmm, u64 addr) +{ + struct rb_node *node = vmm->root.rb_node; + while (node) { + struct nvkm_vma *vma = rb_entry(node, typeof(*vma), tree); + if (addr < vma->addr) + node = node->rb_left; + else + if (addr >= vma->addr + vma->size) + node = node->rb_right; + else + return vma; + } + return NULL; +} + +static void nvkm_vmm_dtor(struct nvkm_vmm *vmm) { + struct nvkm_vma *vma; + struct rb_node *node; + + while ((node = rb_first(&vmm->root))) { + struct nvkm_vma *vma = rb_entry(node, typeof(*vma), tree); + nvkm_vmm_put(vmm, &vma); + } + if (vmm->bootstrapped) { const struct nvkm_vmm_page *page = vmm->func->page; const u64 limit = vmm->limit - vmm->start; @@ -620,6 +856,11 @@ nvkm_vmm_dtor(struct nvkm_vmm *vmm) nvkm_vmm_ptes_put(vmm, page, vmm->start, limit); } + vma = list_first_entry(&vmm->list, typeof(*vma), head); + list_del(&vma->head); + kfree(vma); + WARN_ON(!list_empty(&vmm->list)); + if (vmm->nullp) { dma_free_coherent(vmm->mmu->subdev.device->dev, 16 * 1024, vmm->nullp, vmm->null); @@ -639,6 +880,7 @@ nvkm_vmm_ctor(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, static struct lock_class_key _key; const struct nvkm_vmm_page *page = func->page; const struct nvkm_vmm_desc *desc; + struct nvkm_vma *vma; int levels, bits = 0; vmm->func = func; @@ -689,6 +931,16 @@ nvkm_vmm_ctor(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, return -ENOMEM; } + /* Initialise address-space MM. */ + INIT_LIST_HEAD(&vmm->list); + vmm->free = RB_ROOT; + vmm->root = RB_ROOT; + + if (!(vma = nvkm_vma_new(vmm->start, vmm->limit - vmm->start))) + return -ENOMEM; + + nvkm_vmm_free_insert(vmm, vma); + list_add(&vma->head, &vmm->list); return 0; } @@ -702,6 +954,494 @@ nvkm_vmm_new_(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, return nvkm_vmm_ctor(func, mmu, hdr, addr, size, key, name, *pvmm); } +#define node(root, dir) ((root)->head.dir == &vmm->list) ? NULL : \ + list_entry((root)->head.dir, struct nvkm_vma, head) + +void +nvkm_vmm_unmap_region(struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + struct nvkm_vma *next; + + nvkm_memory_tags_put(vma->memory, vmm->mmu->subdev.device, &vma->tags); + nvkm_memory_unref(&vma->memory); + + if (vma->part) { + struct nvkm_vma *prev = node(vma, prev); + if (!prev->memory) { + prev->size += vma->size; + rb_erase(&vma->tree, &vmm->root); + list_del(&vma->head); + kfree(vma); + vma = prev; + } + } + + next = node(vma, next); + if (next && next->part) { + if (!next->memory) { + vma->size += next->size; + rb_erase(&next->tree, &vmm->root); + list_del(&next->head); + kfree(next); + } + } +} + +void +nvkm_vmm_unmap_locked(struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + const struct nvkm_vmm_page *page = &vmm->func->page[vma->refd]; + + if (vma->mapref) { + nvkm_vmm_ptes_unmap_put(vmm, page, vma->addr, vma->size, vma->sparse); + vma->refd = NVKM_VMA_PAGE_NONE; + } else { + nvkm_vmm_ptes_unmap(vmm, page, vma->addr, vma->size, vma->sparse); + } + + nvkm_vmm_unmap_region(vmm, vma); +} + +void +nvkm_vmm_unmap(struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + if (vma->memory) { + mutex_lock(&vmm->mutex); + nvkm_vmm_unmap_locked(vmm, vma); + mutex_unlock(&vmm->mutex); + } +} + +static int +nvkm_vmm_map_valid(struct nvkm_vmm *vmm, struct nvkm_vma *vma, + void *argv, u32 argc, struct nvkm_vmm_map *map) +{ + switch (nvkm_memory_target(map->memory)) { + case NVKM_MEM_TARGET_VRAM: + if (!(map->page->type & NVKM_VMM_PAGE_VRAM)) { + VMM_DEBUG(vmm, "%d !VRAM", map->page->shift); + return -EINVAL; + } + break; + case NVKM_MEM_TARGET_HOST: + case NVKM_MEM_TARGET_NCOH: + if (!(map->page->type & NVKM_VMM_PAGE_HOST)) { + VMM_DEBUG(vmm, "%d !HOST", map->page->shift); + return -EINVAL; + } + break; + default: + WARN_ON(1); + return -ENOSYS; + } + + if (!IS_ALIGNED( vma->addr, 1ULL << map->page->shift) || + !IS_ALIGNED((u64)vma->size, 1ULL << map->page->shift) || + !IS_ALIGNED( map->offset, 1ULL << map->page->shift) || + nvkm_memory_page(map->memory) < map->page->shift) { + VMM_DEBUG(vmm, "alignment %016llx %016llx %016llx %d %d", + vma->addr, (u64)vma->size, map->offset, map->page->shift, + nvkm_memory_page(map->memory)); + return -EINVAL; + } + + return vmm->func->valid(vmm, argv, argc, map); +} + +static int +nvkm_vmm_map_choose(struct nvkm_vmm *vmm, struct nvkm_vma *vma, + void *argv, u32 argc, struct nvkm_vmm_map *map) +{ + for (map->page = vmm->func->page; map->page->shift; map->page++) { + VMM_DEBUG(vmm, "trying %d", map->page->shift); + if (!nvkm_vmm_map_valid(vmm, vma, argv, argc, map)) + return 0; + } + return -EINVAL; +} + +static int +nvkm_vmm_map_locked(struct nvkm_vmm *vmm, struct nvkm_vma *vma, + void *argv, u32 argc, struct nvkm_vmm_map *map) +{ + nvkm_vmm_pte_func func; + int ret; + + /* Make sure we won't overrun the end of the memory object. */ + if (unlikely(nvkm_memory_size(map->memory) < map->offset + vma->size)) { + VMM_DEBUG(vmm, "overrun %016llx %016llx %016llx", + nvkm_memory_size(map->memory), + map->offset, (u64)vma->size); + return -EINVAL; + } + + /* Check remaining arguments for validity. */ + if (vma->page == NVKM_VMA_PAGE_NONE && + vma->refd == NVKM_VMA_PAGE_NONE) { + /* Find the largest page size we can perform the mapping at. */ + const u32 debug = vmm->debug; + vmm->debug = 0; + ret = nvkm_vmm_map_choose(vmm, vma, argv, argc, map); + vmm->debug = debug; + if (ret) { + VMM_DEBUG(vmm, "invalid at any page size"); + nvkm_vmm_map_choose(vmm, vma, argv, argc, map); + return -EINVAL; + } + } else { + /* Page size of the VMA is already pre-determined. */ + if (vma->refd != NVKM_VMA_PAGE_NONE) + map->page = &vmm->func->page[vma->refd]; + else + map->page = &vmm->func->page[vma->page]; + + ret = nvkm_vmm_map_valid(vmm, vma, argv, argc, map); + if (ret) { + VMM_DEBUG(vmm, "invalid %d\n", ret); + return ret; + } + } + + /* Deal with the 'offset' argument, and fetch the backend function. */ + map->off = map->offset; + if (map->mem) { + for (; map->off; map->mem = map->mem->next) { + u64 size = (u64)map->mem->length << NVKM_RAM_MM_SHIFT; + if (size > map->off) + break; + map->off -= size; + } + func = map->page->desc->func->mem; + } else + if (map->sgl) { + for (; map->off; map->sgl = sg_next(map->sgl)) { + u64 size = sg_dma_len(map->sgl); + if (size > map->off) + break; + map->off -= size; + } + func = map->page->desc->func->sgl; + } else { + map->dma += map->offset >> PAGE_SHIFT; + map->off = map->offset & PAGE_MASK; + func = map->page->desc->func->dma; + } + + /* Perform the map. */ + if (vma->refd == NVKM_VMA_PAGE_NONE) { + ret = nvkm_vmm_ptes_get_map(vmm, map->page, vma->addr, vma->size, map, func); + if (ret) + return ret; + + vma->refd = map->page - vmm->func->page; + } else { + nvkm_vmm_ptes_map(vmm, map->page, vma->addr, vma->size, map, func); + } + + nvkm_memory_tags_put(vma->memory, vmm->mmu->subdev.device, &vma->tags); + nvkm_memory_unref(&vma->memory); + vma->memory = nvkm_memory_ref(map->memory); + vma->tags = map->tags; + return 0; +} + +int +nvkm_vmm_map(struct nvkm_vmm *vmm, struct nvkm_vma *vma, void *argv, u32 argc, + struct nvkm_vmm_map *map) +{ + int ret; + mutex_lock(&vmm->mutex); + ret = nvkm_vmm_map_locked(vmm, vma, argv, argc, map); + vma->busy = false; + mutex_unlock(&vmm->mutex); + return ret; +} + +static void +nvkm_vmm_put_region(struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + struct nvkm_vma *prev, *next; + + if ((prev = node(vma, prev)) && !prev->used) { + rb_erase(&prev->tree, &vmm->free); + list_del(&prev->head); + vma->addr = prev->addr; + vma->size += prev->size; + kfree(prev); + } + + if ((next = node(vma, next)) && !next->used) { + rb_erase(&next->tree, &vmm->free); + list_del(&next->head); + vma->size += next->size; + kfree(next); + } + + nvkm_vmm_free_insert(vmm, vma); +} + +void +nvkm_vmm_put_locked(struct nvkm_vmm *vmm, struct nvkm_vma *vma) +{ + const struct nvkm_vmm_page *page = vmm->func->page; + struct nvkm_vma *next = vma; + + BUG_ON(vma->part); + + if (vma->mapref || !vma->sparse) { + do { + const bool map = next->memory != NULL; + const u8 refd = next->refd; + const u64 addr = next->addr; + u64 size = next->size; + + /* Merge regions that are in the same state. */ + while ((next = node(next, next)) && next->part && + (next->memory != NULL) == map && + (next->refd == refd)) + size += next->size; + + if (map) { + /* Region(s) are mapped, merge the unmap + * and dereference into a single walk of + * the page tree. + */ + nvkm_vmm_ptes_unmap_put(vmm, &page[refd], addr, + size, vma->sparse); + } else + if (refd != NVKM_VMA_PAGE_NONE) { + /* Drop allocation-time PTE references. */ + nvkm_vmm_ptes_put(vmm, &page[refd], addr, size); + } + } while (next && next->part); + } + + /* Merge any mapped regions that were split from the initial + * address-space allocation back into the allocated VMA, and + * release memory/compression resources. + */ + next = vma; + do { + if (next->memory) + nvkm_vmm_unmap_region(vmm, next); + } while ((next = node(vma, next)) && next->part); + + if (vma->sparse && !vma->mapref) { + /* Sparse region that was allocated with a fixed page size, + * meaning all relevant PTEs were referenced once when the + * region was allocated, and remained that way, regardless + * of whether memory was mapped into it afterwards. + * + * The process of unmapping, unsparsing, and dereferencing + * PTEs can be done in a single page tree walk. + */ + nvkm_vmm_ptes_sparse_put(vmm, &page[vma->refd], vma->addr, vma->size); + } else + if (vma->sparse) { + /* Sparse region that wasn't allocated with a fixed page size, + * PTE references were taken both at allocation time (to make + * the GPU see the region as sparse), and when mapping memory + * into the region. + * + * The latter was handled above, and the remaining references + * are dealt with here. + */ + nvkm_vmm_ptes_sparse(vmm, vma->addr, vma->size, false); + } + + /* Remove VMA from the list of allocated nodes. */ + rb_erase(&vma->tree, &vmm->root); + + /* Merge VMA back into the free list. */ + vma->page = NVKM_VMA_PAGE_NONE; + vma->refd = NVKM_VMA_PAGE_NONE; + vma->used = false; + vma->user = false; + nvkm_vmm_put_region(vmm, vma); +} + +void +nvkm_vmm_put(struct nvkm_vmm *vmm, struct nvkm_vma **pvma) +{ + struct nvkm_vma *vma = *pvma; + if (vma) { + mutex_lock(&vmm->mutex); + nvkm_vmm_put_locked(vmm, vma); + mutex_unlock(&vmm->mutex); + *pvma = NULL; + } +} + +int +nvkm_vmm_get_locked(struct nvkm_vmm *vmm, bool getref, bool mapref, bool sparse, + u8 shift, u8 align, u64 size, struct nvkm_vma **pvma) +{ + const struct nvkm_vmm_page *page = &vmm->func->page[NVKM_VMA_PAGE_NONE]; + struct rb_node *node = NULL, *temp; + struct nvkm_vma *vma = NULL, *tmp; + u64 addr, tail; + int ret; + + VMM_TRACE(vmm, "getref %d mapref %d sparse %d " + "shift: %d align: %d size: %016llx", + getref, mapref, sparse, shift, align, size); + + /* Zero-sized, or lazily-allocated sparse VMAs, make no sense. */ + if (unlikely(!size || (!getref && !mapref && sparse))) { + VMM_DEBUG(vmm, "args %016llx %d %d %d", + size, getref, mapref, sparse); + return -EINVAL; + } + + /* Tesla-class GPUs can only select page size per-PDE, which means + * we're required to know the mapping granularity up-front to find + * a suitable region of address-space. + * + * The same goes if we're requesting up-front allocation of PTES. + */ + if (unlikely((getref || vmm->func->page_block) && !shift)) { + VMM_DEBUG(vmm, "page size required: %d %016llx", + getref, vmm->func->page_block); + return -EINVAL; + } + + /* If a specific page size was requested, determine its index and + * make sure the requested size is a multiple of the page size. + */ + if (shift) { + for (page = vmm->func->page; page->shift; page++) { + if (shift == page->shift) + break; + } + + if (!page->shift || !IS_ALIGNED(size, 1ULL << page->shift)) { + VMM_DEBUG(vmm, "page %d %016llx", shift, size); + return -EINVAL; + } + align = max_t(u8, align, shift); + } else { + align = max_t(u8, align, 12); + } + + /* Locate smallest block that can possibly satisfy the allocation. */ + temp = vmm->free.rb_node; + while (temp) { + struct nvkm_vma *this = rb_entry(temp, typeof(*this), tree); + if (this->size < size) { + temp = temp->rb_right; + } else { + node = temp; + temp = temp->rb_left; + } + } + + if (unlikely(!node)) + return -ENOSPC; + + /* Take into account alignment restrictions, trying larger blocks + * in turn until we find a suitable free block. + */ + do { + struct nvkm_vma *this = rb_entry(node, typeof(*this), tree); + struct nvkm_vma *prev = node(this, prev); + struct nvkm_vma *next = node(this, next); + const int p = page - vmm->func->page; + + addr = this->addr; + if (vmm->func->page_block && prev && prev->page != p) + addr = roundup(addr, vmm->func->page_block); + addr = ALIGN(addr, 1ULL << align); + + tail = this->addr + this->size; + if (vmm->func->page_block && next && next->page != p) + tail = rounddown(tail, vmm->func->page_block); + + if (addr <= tail && tail - addr >= size) { + rb_erase(&this->tree, &vmm->free); + vma = this; + break; + } + } while ((node = rb_next(node))); + + if (unlikely(!vma)) + return -ENOSPC; + + /* If the VMA we found isn't already exactly the requested size, + * it needs to be split, and the remaining free blocks returned. + */ + if (addr != vma->addr) { + if (!(tmp = nvkm_vma_tail(vma, vma->size + vma->addr - addr))) { + nvkm_vmm_put_region(vmm, vma); + return -ENOMEM; + } + nvkm_vmm_free_insert(vmm, vma); + vma = tmp; + } + + if (size != vma->size) { + if (!(tmp = nvkm_vma_tail(vma, vma->size - size))) { + nvkm_vmm_put_region(vmm, vma); + return -ENOMEM; + } + nvkm_vmm_free_insert(vmm, tmp); + } + + /* Pre-allocate page tables and/or setup sparse mappings. */ + if (sparse && getref) + ret = nvkm_vmm_ptes_sparse_get(vmm, page, vma->addr, vma->size); + else if (sparse) + ret = nvkm_vmm_ptes_sparse(vmm, vma->addr, vma->size, true); + else if (getref) + ret = nvkm_vmm_ptes_get(vmm, page, vma->addr, vma->size); + else + ret = 0; + if (ret) { + nvkm_vmm_put_region(vmm, vma); + return ret; + } + + vma->mapref = mapref && !getref; + vma->sparse = sparse; + vma->page = page - vmm->func->page; + vma->refd = getref ? vma->page : NVKM_VMA_PAGE_NONE; + vma->used = true; + nvkm_vmm_node_insert(vmm, vma); + *pvma = vma; + return 0; +} + +int +nvkm_vmm_get(struct nvkm_vmm *vmm, u8 page, u64 size, struct nvkm_vma **pvma) +{ + int ret; + mutex_lock(&vmm->mutex); + ret = nvkm_vmm_get_locked(vmm, false, true, false, page, 0, size, pvma); + mutex_unlock(&vmm->mutex); + return ret; +} + +void +nvkm_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + if (vmm->func->part && inst) { + mutex_lock(&vmm->mutex); + vmm->func->part(vmm, inst); + mutex_unlock(&vmm->mutex); + } +} + +int +nvkm_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + int ret = 0; + if (vmm->func->join) { + mutex_lock(&vmm->mutex); + ret = vmm->func->join(vmm, inst); + mutex_unlock(&vmm->mutex); + } + return ret; +} + static bool nvkm_vmm_boot_ptes(struct nvkm_vmm_iter *it, u32 ptei, u32 ptes) { @@ -730,3 +1470,44 @@ nvkm_vmm_boot(struct nvkm_vmm *vmm) vmm->bootstrapped = true; return 0; } + +static void +nvkm_vmm_del(struct kref *kref) +{ + struct nvkm_vmm *vmm = container_of(kref, typeof(*vmm), kref); + nvkm_vmm_dtor(vmm); + kfree(vmm); +} + +void +nvkm_vmm_unref(struct nvkm_vmm **pvmm) +{ + struct nvkm_vmm *vmm = *pvmm; + if (vmm) { + kref_put(&vmm->kref, nvkm_vmm_del); + *pvmm = NULL; + } +} + +struct nvkm_vmm * +nvkm_vmm_ref(struct nvkm_vmm *vmm) +{ + if (vmm) + kref_get(&vmm->kref); + return vmm; +} + +int +nvkm_vmm_new(struct nvkm_device *device, u64 addr, u64 size, void *argv, + u32 argc, struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + struct nvkm_mmu *mmu = device->mmu; + struct nvkm_vmm *vmm = NULL; + int ret; + ret = mmu->func->vmm.ctor(mmu, addr, size, argv, argc, key, name, &vmm); + if (ret) + nvkm_vmm_unref(&vmm); + *pvmm = vmm; + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index bb1353e95068..5808012f7395 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -153,16 +153,19 @@ int nvkm_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, int nvkm_vmm_ctor(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32 pd_header, u64 addr, u64 size, struct lock_class_key *, const char *name, struct nvkm_vmm *); -void nvkm_vmm_dtor(struct nvkm_vmm *); -void nvkm_vmm_ptes_put(struct nvkm_vmm *, const struct nvkm_vmm_page *, - u64 addr, u64 size); -int nvkm_vmm_ptes_get(struct nvkm_vmm *, const struct nvkm_vmm_page *, - u64 addr, u64 size); +struct nvkm_vma *nvkm_vmm_node_search(struct nvkm_vmm *, u64 addr); +int nvkm_vmm_get_locked(struct nvkm_vmm *, bool getref, bool mapref, + bool sparse, u8 page, u8 align, u64 size, + struct nvkm_vma **pvma); +void nvkm_vmm_put_locked(struct nvkm_vmm *, struct nvkm_vma *); +void nvkm_vmm_unmap_locked(struct nvkm_vmm *, struct nvkm_vma *); +void nvkm_vmm_unmap_region(struct nvkm_vmm *vmm, struct nvkm_vma *vma); void nvkm_vmm_ptes_map(struct nvkm_vmm *, const struct nvkm_vmm_page *, u64 addr, u64 size, struct nvkm_vmm_map *, nvkm_vmm_pte_func); -void nvkm_vmm_ptes_unmap(struct nvkm_vmm *, const struct nvkm_vmm_page *, - u64 addr, u64 size, bool sparse); + +struct nvkm_vma *nvkm_vma_tail(struct nvkm_vma *, u64 tail); +void nvkm_vmm_node_insert(struct nvkm_vmm *, struct nvkm_vma *); int nv04_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, u32, u64, u64, void *, u32, struct lock_class_key *, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h index 885e919a8720..d9091f029506 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h @@ -25,6 +25,7 @@ #include #include +struct nvkm_gpuobj; struct nvkm_secboot_func { int (*oneinit)(struct nvkm_secboot *); -- cgit v1.2.3 From fc584e1a4a579c3279ed563b890415c13b2f85ac Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar/nv50: initialise vmm with new interfaces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 33 +++++++++++++------------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h | 4 ++-- 2 files changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 9300529917fc..157b076a1272 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -46,7 +46,7 @@ nv50_bar_flush(struct nvkm_bar *base) struct nvkm_vmm * nv50_bar_bar1_vmm(struct nvkm_bar *base) { - return nv50_bar(base)->bar1_vm; + return nv50_bar(base)->bar1_vmm; } void @@ -72,7 +72,7 @@ nv50_bar_bar1_init(struct nvkm_bar *base) struct nvkm_vmm * nv50_bar_bar2_vmm(struct nvkm_bar *base) { - return nv50_bar(base)->bar2_vm; + return nv50_bar(base)->bar2_vmm; } void @@ -109,7 +109,6 @@ nv50_bar_oneinit(struct nvkm_bar *base) struct nvkm_device *device = bar->base.subdev.device; static struct lock_class_key bar1_lock; static struct lock_class_key bar2_lock; - struct nvkm_vm *vm; u64 start, limit; int ret; @@ -130,18 +129,19 @@ nv50_bar_oneinit(struct nvkm_bar *base) start = 0x0100000000ULL; limit = start + device->func->resource_size(device, 3); - ret = nvkm_vm_new(device, start, limit - start, start, &bar2_lock, &vm); + ret = nvkm_vmm_new(device, start, limit-- - start, NULL, 0, + &bar2_lock, "bar2", &bar->bar2_vmm); if (ret) return ret; - atomic_inc(&vm->engref[NVKM_SUBDEV_BAR]); + atomic_inc(&bar->bar2_vmm->engref[NVKM_SUBDEV_BAR]); + bar->bar2_vmm->debug = bar->base.subdev.debug; - ret = nvkm_vm_boot(vm, limit-- - start); + ret = nvkm_vmm_boot(bar->bar2_vmm); if (ret) return ret; - ret = nvkm_vm_ref(vm, &bar->bar2_vm, bar->mem->memory); - nvkm_vm_ref(NULL, &vm, NULL); + ret = nvkm_vmm_join(bar->bar2_vmm, bar->mem->memory); if (ret) return ret; @@ -166,14 +166,13 @@ nv50_bar_oneinit(struct nvkm_bar *base) start = 0x0000000000ULL; limit = start + device->func->resource_size(device, 1); - ret = nvkm_vm_new(device, start, limit-- - start, start, &bar1_lock, &vm); - if (ret) - return ret; + ret = nvkm_vmm_new(device, start, limit-- - start, NULL, 0, + &bar1_lock, "bar1", &bar->bar1_vmm); - atomic_inc(&vm->engref[NVKM_SUBDEV_BAR]); + atomic_inc(&bar->bar1_vmm->engref[NVKM_SUBDEV_BAR]); + bar->bar1_vmm->debug = bar->base.subdev.debug; - ret = nvkm_vm_ref(vm, &bar->bar1_vm, bar->mem->memory); - nvkm_vm_ref(NULL, &vm, NULL); + ret = nvkm_vmm_join(bar->bar1_vmm, bar->mem->memory); if (ret) return ret; @@ -199,9 +198,11 @@ nv50_bar_dtor(struct nvkm_bar *base) struct nv50_bar *bar = nv50_bar(base); if (bar->mem) { nvkm_gpuobj_del(&bar->bar1); - nvkm_vm_ref(NULL, &bar->bar1_vm, bar->mem->memory); + nvkm_vmm_part(bar->bar1_vmm, bar->mem->memory); + nvkm_vmm_unref(&bar->bar1_vmm); nvkm_gpuobj_del(&bar->bar2); - nvkm_vm_ref(NULL, &bar->bar2_vm, bar->mem->memory); + nvkm_vmm_part(bar->bar2_vmm, bar->mem->memory); + nvkm_vmm_unref(&bar->bar2_vmm); nvkm_gpuobj_del(&bar->pgd); nvkm_gpuobj_del(&bar->pad); nvkm_gpuobj_del(&bar->mem); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index b5fe26aab118..140b76f588b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -9,9 +9,9 @@ struct nv50_bar { struct nvkm_gpuobj *mem; struct nvkm_gpuobj *pad; struct nvkm_gpuobj *pgd; - struct nvkm_vm *bar1_vm; + struct nvkm_vmm *bar1_vmm; struct nvkm_gpuobj *bar1; - struct nvkm_vm *bar2_vm; + struct nvkm_vmm *bar2_vmm; struct nvkm_gpuobj *bar2; }; -- cgit v1.2.3 From 7eac5f4eb06a661ddee9b2ebb75799bf0c7cbf65 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/bar/gf100: initialise vmm with new interfaces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 30 +++++++++++-------------- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h | 2 +- 2 files changed, 14 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 8077e1a5017a..a3ba7f50198b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -31,7 +31,7 @@ struct nvkm_vmm * gf100_bar_bar1_vmm(struct nvkm_bar *base) { - return gf100_bar(base)->bar[1].vm; + return gf100_bar(base)->bar[1].vmm; } void @@ -60,7 +60,7 @@ gf100_bar_bar1_init(struct nvkm_bar *base) struct nvkm_vmm * gf100_bar_bar2_vmm(struct nvkm_bar *base) { - return gf100_bar(base)->bar[0].vm; + return gf100_bar(base)->bar[0].vmm; } void @@ -85,7 +85,6 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, struct lock_class_key *key, int bar_nr) { struct nvkm_device *device = bar->base.subdev.device; - struct nvkm_vm *vm; resource_size_t bar_len; int ret; @@ -98,29 +97,24 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, if (bar_nr == 3 && bar->bar2_halve) bar_len >>= 1; - ret = nvkm_vm_new(device, 0, bar_len, 0, key, &vm); + ret = nvkm_vmm_new(device, 0, bar_len, NULL, 0, key, + (bar_nr == 3) ? "bar2" : "bar1", &bar_vm->vmm); if (ret) return ret; - atomic_inc(&vm->engref[NVKM_SUBDEV_BAR]); + atomic_inc(&bar_vm->vmm->engref[NVKM_SUBDEV_BAR]); + bar_vm->vmm->debug = bar->base.subdev.debug; /* * Bootstrap page table lookup. */ if (bar_nr == 3) { - ret = nvkm_vm_boot(vm, bar_len); - if (ret) { - nvkm_vm_ref(NULL, &vm, NULL); + ret = nvkm_vmm_boot(bar_vm->vmm); + if (ret) return ret; - } } - ret = nvkm_vm_ref(vm, &bar_vm->vm, bar_vm->inst); - nvkm_vm_ref(NULL, &vm, NULL); - if (ret) - return ret; - - return 0; + return nvkm_vmm_join(bar_vm->vmm, bar_vm->inst); } int @@ -154,10 +148,12 @@ gf100_bar_dtor(struct nvkm_bar *base) { struct gf100_bar *bar = gf100_bar(base); - nvkm_vm_ref(NULL, &bar->bar[1].vm, bar->bar[1].inst); + nvkm_vmm_part(bar->bar[1].vmm, bar->bar[1].inst); + nvkm_vmm_unref(&bar->bar[1].vmm); nvkm_memory_unref(&bar->bar[1].inst); - nvkm_vm_ref(NULL, &bar->bar[0].vm, bar->bar[0].inst); + nvkm_vmm_part(bar->bar[0].vmm, bar->bar[0].inst); + nvkm_vmm_unref(&bar->bar[0].vmm); nvkm_memory_unref(&bar->bar[0].inst); return bar; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index 9ce80c6b6fec..e4da39139e95 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -5,7 +5,7 @@ struct gf100_barN { struct nvkm_memory *inst; - struct nvkm_vm *vm; + struct nvkm_vmm *vmm; }; struct gf100_bar { -- cgit v1.2.3 From 85f7c3a03689d300acdbc82270246f83e2a5d472 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/secboot/gm200: initialise vmm with new interfaces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c | 18 +++++++++--------- drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c index 6c068c5bd3c2..5722295cb584 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c @@ -48,13 +48,13 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob, return ret; /* Map the HS firmware so the HS bootloader can see it */ - ret = nvkm_vm_get(gsb->vm, blob->size, 12, NV_MEM_ACCESS_RW, &vma); + ret = nvkm_vm_get(gsb->vmm, blob->size, 12, NV_MEM_ACCESS_RW, &vma); if (ret) { nvkm_falcon_put(falcon, subdev); return ret; } - ret = nvkm_memory_map(blob, 0, gsb->vm, &vma, NULL, 0); + ret = nvkm_memory_map(blob, 0, gsb->vmm, &vma, NULL, 0); if (ret) goto end; @@ -107,8 +107,6 @@ gm200_secboot_oneinit(struct nvkm_secboot *sb) { struct gm200_secboot *gsb = gm200_secboot(sb); struct nvkm_device *device = sb->subdev.device; - struct nvkm_vm *vm; - const u64 vm_area_len = 600 * 1024; int ret; /* Allocate instance block and VM */ @@ -117,14 +115,15 @@ gm200_secboot_oneinit(struct nvkm_secboot *sb) if (ret) return ret; - ret = nvkm_vm_new(device, 0, vm_area_len, 0, NULL, &vm); + ret = nvkm_vmm_new(device, 0, 600 * 1024, NULL, 0, NULL, "acr", + &gsb->vmm); if (ret) return ret; - atomic_inc(&vm->engref[NVKM_SUBDEV_PMU]); + atomic_inc(&gsb->vmm->engref[NVKM_SUBDEV_PMU]); + gsb->vmm->debug = gsb->base.subdev.debug; - ret = nvkm_vm_ref(vm, &gsb->vm, gsb->inst); - nvkm_vm_ref(NULL, &vm, NULL); + ret = nvkm_vmm_join(gsb->vmm, gsb->inst); if (ret) return ret; @@ -155,7 +154,8 @@ gm200_secboot_dtor(struct nvkm_secboot *sb) sb->acr->func->dtor(sb->acr); - nvkm_vm_ref(NULL, &gsb->vm, gsb->inst); + nvkm_vmm_part(gsb->vmm, gsb->inst); + nvkm_vmm_unref(&gsb->vmm); nvkm_memory_unref(&gsb->inst); return gsb; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h index a2b60fab42e8..62c5e162099a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h @@ -30,7 +30,7 @@ struct gm200_secboot { /* Instance block & address space used for HS FW execution */ struct nvkm_memory *inst; - struct nvkm_vm *vm; + struct nvkm_vmm *vmm; }; #define gm200_secboot(sb) container_of(sb, struct gm200_secboot, base) -- cgit v1.2.3 From f66c57d9229c313de3adf340c604b1c7a40e5306 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fifo: initialise vmm with new interfaces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 33 ++++++++++++---------- drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c | 6 +--- .../gpu/drm/nouveau/nvkm/engine/fifo/changf100.h | 2 -- .../gpu/drm/nouveau/nvkm/engine/fifo/changk104.h | 2 -- .../gpu/drm/nouveau/nvkm/engine/fifo/channv50.c | 8 +----- .../gpu/drm/nouveau/nvkm/engine/fifo/channv50.h | 1 - .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | 13 ++------- .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 13 ++------- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 8 +++--- 10 files changed, 31 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index 0e65ad7e6eed..e42d686fbd8b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -22,7 +22,7 @@ struct nvkm_fifo_chan { u16 chid; struct nvkm_gpuobj *inst; struct nvkm_gpuobj *push; - struct nvkm_vm *vm; + struct nvkm_vmm *vmm; void __iomem *user; u64 addr; u32 size; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index 7aea0a8692ae..ac94b57777c4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -27,6 +27,7 @@ #include #include #include +#include #include struct nvkm_fifo_chan_object { @@ -117,8 +118,8 @@ nvkm_fifo_chan_child_del(struct nvkm_oproxy *base) if (chan->func->engine_dtor) chan->func->engine_dtor(chan, engine); nvkm_object_del(&engn->object); - if (chan->vm) - atomic_dec(&chan->vm->engref[engine->subdev.index]); + if (chan->vmm) + atomic_dec(&chan->vmm->engref[engine->subdev.index]); } } @@ -151,8 +152,8 @@ nvkm_fifo_chan_child_new(const struct nvkm_oclass *oclass, void *data, u32 size, .engine = oclass->engine, }; - if (chan->vm) - atomic_inc(&chan->vm->engref[engine->subdev.index]); + if (chan->vmm) + atomic_inc(&chan->vmm->engref[engine->subdev.index]); if (engine->func->fifo.cclass) { ret = engine->func->fifo.cclass(chan, &cclass, @@ -327,7 +328,10 @@ nvkm_fifo_chan_dtor(struct nvkm_object *object) if (chan->user) iounmap(chan->user); - nvkm_vm_ref(NULL, &chan->vm, NULL); + if (chan->vmm) { + nvkm_vmm_part(chan->vmm, chan->inst->memory); + nvkm_vmm_unref(&chan->vmm); + } nvkm_gpuobj_del(&chan->push); nvkm_gpuobj_del(&chan->inst); @@ -355,7 +359,6 @@ nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *func, { struct nvkm_client *client = oclass->client; struct nvkm_device *device = fifo->engine.subdev.device; - struct nvkm_mmu *mmu = device->mmu; struct nvkm_dmaobj *dmaobj; unsigned long flags; int ret; @@ -384,16 +387,16 @@ nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *func, } /* channel address space */ - if (!vm && mmu) { - if (!client->vm || client->vm->mmu == mmu) { - ret = nvkm_vm_ref(client->vm, &chan->vm, NULL); - if (ret) - return ret; - } else { + if (!device->mmu->func->vmm.global) { + struct nvkm_vmm *vmm = client->vm; + if (vmm->mmu != device->mmu) return -EINVAL; - } - } else { - return -ENOENT; + + ret = nvkm_vmm_join(vmm, chan->inst->memory); + if (ret) + return ret; + + chan->vmm = nvkm_vmm_ref(vmm); } /* allocate channel id */ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c index 705a6d951d32..1870310549e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c @@ -277,9 +277,5 @@ g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vm, u64 push, if (ret) return ret; - ret = nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht); - if (ret) - return ret; - - return nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); + return nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h index a902f848a878..f4400b33c00d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h @@ -11,8 +11,6 @@ struct gf100_fifo_chan { struct list_head head; bool killed; - struct nvkm_vm *vm; - struct { struct nvkm_gpuobj *inst; struct nvkm_vma vma; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h index 1cd5b8d3fb2e..1259fb2337be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h @@ -12,8 +12,6 @@ struct gk104_fifo_chan { struct list_head head; bool killed; - struct nvkm_vm *vm; - struct { struct nvkm_gpuobj *inst; struct nvkm_vma vma; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c index 161aa9ec73bc..01453279dbc0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c @@ -206,8 +206,6 @@ void * nv50_fifo_chan_dtor(struct nvkm_fifo_chan *base) { struct nv50_fifo_chan *chan = nv50_fifo_chan(base); - if (chan->base.inst) - nvkm_vm_ref(NULL, &chan->vm, chan->base.inst->memory); nvkm_ramht_del(&chan->ramht); nvkm_gpuobj_del(&chan->pgd); nvkm_gpuobj_del(&chan->eng); @@ -263,9 +261,5 @@ nv50_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vm, u64 push, if (ret) return ret; - ret = nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht); - if (ret) - return ret; - - return nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); + return nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h index 4b9da469b704..a0c04c6329a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h @@ -13,7 +13,6 @@ struct nv50_fifo_chan { struct nvkm_gpuobj *eng; struct nvkm_gpuobj *pgd; struct nvkm_ramht *ramht; - struct nvkm_vm *vm; struct nvkm_gpuobj *engn[NVKM_SUBDEV_NR]; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index 695d0721b1ad..3e2b1a82e640 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c @@ -150,12 +150,12 @@ gf100_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, if (ret) return ret; - ret = nvkm_vm_get(chan->vm, chan->engn[engn].inst->size, 12, + ret = nvkm_vm_get(chan->base.vmm, chan->engn[engn].inst->size, 12, NV_MEM_ACCESS_RW, &chan->engn[engn].vma); if (ret) return ret; - return nvkm_memory_map(chan->engn[engn].inst, 0, chan->vm, + return nvkm_memory_map(chan->engn[engn].inst, 0, chan->base.vmm, &chan->engn[engn].vma, NULL, 0); } @@ -199,10 +199,7 @@ gf100_fifo_gpfifo_init(struct nvkm_fifo_chan *base) static void * gf100_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) { - struct gf100_fifo_chan *chan = gf100_fifo_chan(base); - if (chan->base.inst) - nvkm_vm_ref(NULL, &chan->vm, chan->base.inst->memory); - return chan; + return gf100_fifo_chan(base); } static const struct nvkm_fifo_chan_func @@ -262,10 +259,6 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, args->v0.chid = chan->base.chid; - ret = nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); - if (ret) - return ret; - /* clear channel control registers */ usermem = chan->base.chid * 0x1000; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 978c9ad952b3..1c3ee4410287 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -162,12 +162,12 @@ gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, if (ret) return ret; - ret = nvkm_vm_get(chan->vm, chan->engn[engn].inst->size, 12, + ret = nvkm_vm_get(chan->base.vmm, chan->engn[engn].inst->size, 12, NV_MEM_ACCESS_RW, &chan->engn[engn].vma); if (ret) return ret; - return nvkm_memory_map(chan->engn[engn].inst, 0, chan->vm, + return nvkm_memory_map(chan->engn[engn].inst, 0, chan->base.vmm, &chan->engn[engn].vma, NULL, 0); } @@ -212,10 +212,7 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base) static void * gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) { - struct gk104_fifo_chan *chan = gk104_fifo_chan(base); - if (chan->base.inst) - nvkm_vm_ref(NULL, &chan->vm, chan->base.inst->memory); - return chan; + return gk104_fifo_chan(base); } static const struct nvkm_fifo_chan_func @@ -301,10 +298,6 @@ gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, *chid = chan->base.chid; - ret = nvkm_vm_ref(chan->base.vm, &chan->vm, chan->base.inst->memory); - if (ret) - return ret; - /* Clear channel control registers. */ usermem = chan->base.chid * 0x200; ilength = order_base_2(ilength / 8); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 4fc4deb2db4b..b6cde1385941 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -398,12 +398,12 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, if (ret) return ret; - ret = nvkm_vm_get(fifoch->vm, 0x1000, 12, NV_MEM_ACCESS_RW | + ret = nvkm_vm_get(fifoch->vmm, 0x1000, 12, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS, &chan->mmio_vma); if (ret) return ret; - ret = nvkm_memory_map(chan->mmio, 0, fifoch->vm, + ret = nvkm_memory_map(chan->mmio, 0, fifoch->vmm, &chan->mmio_vma, NULL, 0); if (ret) return ret; @@ -416,13 +416,13 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, if (ret) return ret; - ret = nvkm_vm_get(fifoch->vm, + ret = nvkm_vm_get(fifoch->vmm, nvkm_memory_size(chan->data[i].mem), 12, data->access, &chan->data[i].vma); if (ret) return ret; - ret = nvkm_memory_map(chan->data[i].mem, 0, fifoch->vm, + ret = nvkm_memory_map(chan->data[i].mem, 0, fifoch->vmm, &chan->data[i].vma, NULL, 0); if (ret) return ret; -- cgit v1.2.3 From 6f4dc18c166cd36d8e9dfd130874060065bedd1c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fb/ram: use new interfaces for vmm operations Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 03a860ae75b1..5305078f730e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -39,12 +39,22 @@ nvkm_vram_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, struct nvkm_vma *vma, void *argv, u32 argc) { struct nvkm_vram *vram = nvkm_vram(memory); - struct nvkm_mem mem = { - .mem = vram->mn, + struct nvkm_vmm_map map = { .memory = &vram->memory, + .offset = offset, + .mem = vram->mn, }; - nvkm_vm_map_at(vma, offset, &mem); - return 0; + + if (vma->vm) { + struct nvkm_mem mem = { + .mem = vram->mn, + .memory = &vram->memory, + }; + nvkm_vm_map_at(vma, offset, &mem); + return 0; + } + + return nvkm_vmm_map(vmm, vma, argv, argc, &map); } static u64 -- cgit v1.2.3 From 9202d732e6bc3b46566db3ed25f7a5a3eeaee3c1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem/nv50-: use new interfaces for vmm operations Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 45 +++++++++++++--------- drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 28 +++++++------- 2 files changed, 41 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 39f6e8e42339..2f60f0d18aeb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -52,7 +52,7 @@ struct gk20a_instobj { struct nvkm_memory memory; - struct nvkm_mem mem; + struct nvkm_mm_node *mn; struct gk20a_instmem *imem; /* CPU mapping */ @@ -129,13 +129,13 @@ gk20a_instobj_page(struct nvkm_memory *memory) static u64 gk20a_instobj_addr(struct nvkm_memory *memory) { - return gk20a_instobj(memory)->mem.offset; + return (u64)gk20a_instobj(memory)->mn->offset << 12; } static u64 gk20a_instobj_size(struct nvkm_memory *memory) { - return (u64)gk20a_instobj(memory)->mem.size << 12; + return (u64)gk20a_instobj(memory)->mn->length << 12; } /* @@ -284,8 +284,22 @@ gk20a_instobj_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, struct nvkm_vma *vma, void *argv, u32 argc) { struct gk20a_instobj *node = gk20a_instobj(memory); - nvkm_vm_map_at(vma, 0, &node->mem); - return 0; + struct nvkm_vmm_map map = { + .memory = &node->memory, + .offset = offset, + .mem = node->mn, + }; + + if (vma->vm) { + struct nvkm_mem mem = { + .mem = node->mn, + .memory = &node->memory, + }; + nvkm_vm_map_at(vma, 0, &mem); + return 0; + } + + return nvkm_vmm_map(vmm, vma, argv, argc, &map); } static void * @@ -298,8 +312,8 @@ gk20a_instobj_dtor_dma(struct nvkm_memory *memory) if (unlikely(!node->base.vaddr)) goto out; - dma_free_attrs(dev, node->base.mem.size << PAGE_SHIFT, node->base.vaddr, - node->handle, imem->attrs); + dma_free_attrs(dev, (u64)node->base.mn->length << PAGE_SHIFT, + node->base.vaddr, node->handle, imem->attrs); out: return node; @@ -311,7 +325,7 @@ gk20a_instobj_dtor_iommu(struct nvkm_memory *memory) struct gk20a_instobj_iommu *node = gk20a_instobj_iommu(memory); struct gk20a_instmem *imem = node->base.imem; struct device *dev = imem->base.subdev.device->dev; - struct nvkm_mm_node *r = node->base.mem.mem; + struct nvkm_mm_node *r = node->base.mn; int i; if (unlikely(!r)) @@ -329,7 +343,7 @@ gk20a_instobj_dtor_iommu(struct nvkm_memory *memory) r->offset &= ~BIT(imem->iommu_bit - imem->iommu_pgshift); /* Unmap pages from GPU address space and free them */ - for (i = 0; i < node->base.mem.size; i++) { + for (i = 0; i < node->base.mn->length; i++) { iommu_unmap(imem->domain, (r->offset + i) << imem->iommu_pgshift, PAGE_SIZE); dma_unmap_page(dev, node->dma_addrs[i], PAGE_SIZE, @@ -410,8 +424,7 @@ gk20a_instobj_ctor_dma(struct gk20a_instmem *imem, u32 npages, u32 align, node->r.offset = node->handle >> 12; node->r.length = (npages << PAGE_SHIFT) >> 12; - node->base.mem.offset = node->handle; - node->base.mem.mem = &node->r; + node->base.mn = &node->r; return 0; } @@ -488,8 +501,7 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align, /* IOMMU bit tells that an address is to be resolved through the IOMMU */ r->offset |= BIT(imem->iommu_bit - imem->iommu_pgshift); - node->base.mem.offset = ((u64)r->offset) << imem->iommu_pgshift; - node->base.mem.mem = r; + node->base.mn = r; return 0; release_area: @@ -537,13 +549,8 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, node->imem = imem; - /* present memory for being mapped using small pages */ - node->mem.size = size >> 12; - node->mem.memtype = 0; - node->mem.memory = &node->memory; - nvkm_debug(subdev, "alloc size: 0x%x, align: 0x%x, gaddr: 0x%llx\n", - size, align, node->mem.offset); + size, align, (u64)node->mn->offset << 12); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 64e2b6e0e8b1..1ba7289684aa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -46,7 +46,7 @@ struct nv50_instobj { struct nvkm_instobj base; struct nv50_instmem *imem; struct nvkm_memory *ram; - struct nvkm_vma bar; + struct nvkm_vma *bar; refcount_t maps; void *map; struct list_head lru; @@ -124,7 +124,7 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) struct nvkm_memory *memory = &iobj->base.memory; struct nvkm_subdev *subdev = &imem->base.subdev; struct nvkm_device *device = subdev->device; - struct nvkm_vma bar = {}, ebar; + struct nvkm_vma *bar = NULL, *ebar; u64 size = nvkm_memory_size(memory); void *emap; int ret; @@ -134,7 +134,7 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) * to the possibility of recursion for page table allocation. */ mutex_unlock(&subdev->mutex); - while ((ret = nvkm_vm_get(vmm, size, 12, NV_MEM_ACCESS_RW, &bar))) { + while ((ret = nvkm_vmm_get(vmm, 12, size, &bar))) { /* Evict unused mappings, and keep retrying until we either * succeed,or there's no more objects left on the LRU. */ @@ -144,10 +144,10 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) nvkm_debug(subdev, "evict %016llx %016llx @ %016llx\n", nvkm_memory_addr(&eobj->base.memory), nvkm_memory_size(&eobj->base.memory), - eobj->bar.offset); + eobj->bar->addr); list_del_init(&eobj->lru); ebar = eobj->bar; - eobj->bar.node = NULL; + eobj->bar = NULL; emap = eobj->map; eobj->map = NULL; } @@ -155,16 +155,16 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) if (!eobj) break; iounmap(emap); - nvkm_vm_put(&ebar); + nvkm_vmm_put(vmm, &ebar); } if (ret == 0) - ret = nvkm_memory_map(memory, 0, vmm, &bar, NULL, 0); + ret = nvkm_memory_map(memory, 0, vmm, bar, NULL, 0); mutex_lock(&subdev->mutex); - if (ret || iobj->bar.node) { + if (ret || iobj->bar) { /* We either failed, or another thread beat us. */ mutex_unlock(&subdev->mutex); - nvkm_vm_put(&bar); + nvkm_vmm_put(vmm, &bar); mutex_lock(&subdev->mutex); return; } @@ -172,10 +172,10 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) /* Make the mapping visible to the host. */ iobj->bar = bar; iobj->map = ioremap_wc(device->func->resource_addr(device, 3) + - (u32)iobj->bar.offset, size); + (u32)iobj->bar->addr, size); if (!iobj->map) { nvkm_warn(subdev, "PRAMIN ioremap failed\n"); - nvkm_vm_put(&iobj->bar); + nvkm_vmm_put(vmm, &iobj->bar); } } @@ -299,7 +299,7 @@ nv50_instobj_dtor(struct nvkm_memory *memory) { struct nv50_instobj *iobj = nv50_instobj(memory); struct nvkm_instmem *imem = &iobj->imem->base; - struct nvkm_vma bar; + struct nvkm_vma *bar; void *map = map; mutex_lock(&imem->subdev.mutex); @@ -310,8 +310,10 @@ nv50_instobj_dtor(struct nvkm_memory *memory) mutex_unlock(&imem->subdev.mutex); if (map) { + struct nvkm_vmm *vmm = nvkm_bar_bar2_vmm(imem->subdev.device); iounmap(map); - nvkm_vm_put(&bar); + if (likely(vmm)) /* Can be NULL during BAR destructor. */ + nvkm_vmm_put(vmm, &bar); } nvkm_memory_unref(&iobj->ram); -- cgit v1.2.3 From 8c967c554818a0f98f8cad86cc561ab43bbbf1e7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/secboot/gm200: use new interfaces for vmm operations Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c index 5722295cb584..5e91b3f90065 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c @@ -39,7 +39,7 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob, { struct gm200_secboot *gsb = gm200_secboot(sb); struct nvkm_subdev *subdev = &gsb->base.subdev; - struct nvkm_vma vma; + struct nvkm_vma *vma = NULL; u32 start_address; int ret; @@ -48,13 +48,13 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob, return ret; /* Map the HS firmware so the HS bootloader can see it */ - ret = nvkm_vm_get(gsb->vmm, blob->size, 12, NV_MEM_ACCESS_RW, &vma); + ret = nvkm_vmm_get(gsb->vmm, 12, blob->size, &vma); if (ret) { nvkm_falcon_put(falcon, subdev); return ret; } - ret = nvkm_memory_map(blob, 0, gsb->vmm, &vma, NULL, 0); + ret = nvkm_memory_map(blob, 0, gsb->vmm, vma, NULL, 0); if (ret) goto end; @@ -65,7 +65,7 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob, nvkm_falcon_bind_context(falcon, gsb->inst); /* Load the HS bootloader into the falcon's IMEM/DMEM */ - ret = sb->acr->func->load(sb->acr, falcon, blob, vma.offset); + ret = sb->acr->func->load(sb->acr, falcon, blob, vma->addr); if (ret < 0) goto end; @@ -95,8 +95,7 @@ end: nvkm_mc_intr_mask(sb->subdev.device, falcon->owner->index, true); /* We don't need the ACR firmware anymore */ - nvkm_vm_unmap(&vma); - nvkm_vm_put(&vma); + nvkm_vmm_put(gsb->vmm, &vma); nvkm_falcon_put(falcon, subdev); return ret; -- cgit v1.2.3 From 01f349fcad68d80939db53d9110135e6341b786d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/fifo/gf100-: use new interfaces for vmm operations Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 12 ++++++------ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 12 ++++++------ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | 16 ++++++---------- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 16 ++++++---------- 8 files changed, 28 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h index f4400b33c00d..fc1142af02cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changf100.h @@ -13,7 +13,7 @@ struct gf100_fifo_chan { struct { struct nvkm_gpuobj *inst; - struct nvkm_vma vma; + struct nvkm_vma *vma; } engn[NVKM_SUBDEV_NR]; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h index 1259fb2337be..5beb5c628473 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h @@ -14,7 +14,7 @@ struct gk104_fifo_chan { struct { struct nvkm_gpuobj *inst; - struct nvkm_vma vma; + struct nvkm_vma *vma; } engn[NVKM_SUBDEV_NR]; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 24a4c28b32c5..f69576868164 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -586,12 +585,12 @@ gf100_fifo_oneinit(struct nvkm_fifo *base) if (ret) return ret; - ret = nvkm_vm_get(bar, nvkm_memory_size(fifo->user.mem), 12, - NV_MEM_ACCESS_RW, &fifo->user.bar); + ret = nvkm_vmm_get(bar, 12, nvkm_memory_size(fifo->user.mem), + &fifo->user.bar); if (ret) return ret; - return nvkm_memory_map(fifo->user.mem, 0, bar, &fifo->user.bar, NULL, 0); + return nvkm_memory_map(fifo->user.mem, 0, bar, fifo->user.bar, NULL, 0); } static void @@ -630,7 +629,7 @@ gf100_fifo_init(struct nvkm_fifo *base) } nvkm_mask(device, 0x002200, 0x00000001, 0x00000001); - nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar.offset >> 12); + nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar->addr >> 12); nvkm_wr32(device, 0x002100, 0xffffffff); nvkm_wr32(device, 0x002140, 0x7fffffff); @@ -641,7 +640,8 @@ static void * gf100_fifo_dtor(struct nvkm_fifo *base) { struct gf100_fifo *fifo = gf100_fifo(base); - nvkm_vm_put(&fifo->user.bar); + struct nvkm_device *device = fifo->base.engine.subdev.device; + nvkm_vmm_put(nvkm_bar_bar1_vmm(device), &fifo->user.bar); nvkm_memory_unref(&fifo->user.mem); nvkm_memory_unref(&fifo->runlist.mem[0]); nvkm_memory_unref(&fifo->runlist.mem[1]); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h index 70db58eab9c3..b81a2ad48aa4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h @@ -26,7 +26,7 @@ struct gf100_fifo { struct { struct nvkm_memory *mem; - struct nvkm_vma bar; + struct nvkm_vma *bar; } user; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index eddf9f12e9ee..84bd703dd897 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -836,12 +835,12 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) if (ret) return ret; - ret = nvkm_vm_get(bar, nvkm_memory_size(fifo->user.mem), 12, - NV_MEM_ACCESS_RW, &fifo->user.bar); + ret = nvkm_vmm_get(bar, 12, nvkm_memory_size(fifo->user.mem), + &fifo->user.bar); if (ret) return ret; - return nvkm_memory_map(fifo->user.mem, 0, bar, &fifo->user.bar, NULL, 0); + return nvkm_memory_map(fifo->user.mem, 0, bar, fifo->user.bar, NULL, 0); } static void @@ -867,7 +866,7 @@ gk104_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, 0x04014c + (i * 0x2000), 0xffffffff); /* INTREN */ } - nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar.offset >> 12); + nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar->addr >> 12); nvkm_wr32(device, 0x002100, 0xffffffff); nvkm_wr32(device, 0x002140, 0x7fffffff); @@ -877,9 +876,10 @@ static void * gk104_fifo_dtor(struct nvkm_fifo *base) { struct gk104_fifo *fifo = gk104_fifo(base); + struct nvkm_device *device = fifo->base.engine.subdev.device; int i; - nvkm_vm_put(&fifo->user.bar); + nvkm_vmm_put(nvkm_bar_bar1_vmm(device), &fifo->user.bar); nvkm_memory_unref(&fifo->user.mem); for (i = 0; i < fifo->runlist_nr; i++) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 44bff98d6725..466f1051f91a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -37,7 +37,7 @@ struct gk104_fifo { struct { struct nvkm_memory *mem; - struct nvkm_vma bar; + struct nvkm_vma *bar; } user; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index 3e2b1a82e640..78114068c6dd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c @@ -111,7 +111,7 @@ gf100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base, struct nvkm_gpuobj *inst = chan->base.inst; if (offset) { - u64 addr = chan->engn[engine->subdev.index].vma.offset; + u64 addr = chan->engn[engine->subdev.index].vma->addr; nvkm_kmap(inst); nvkm_wo32(inst, offset + 0x00, lower_32_bits(addr) | 4); nvkm_wo32(inst, offset + 0x04, upper_32_bits(addr)); @@ -126,11 +126,7 @@ gf100_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base, struct nvkm_engine *engine) { struct gf100_fifo_chan *chan = gf100_fifo_chan(base); - struct nvkm_vma *vma = &chan->engn[engine->subdev.index].vma; - if (vma->vm) { - nvkm_vm_unmap(vma); - nvkm_vm_put(vma); - } + nvkm_vmm_put(chan->base.vmm, &chan->engn[engine->subdev.index].vma); nvkm_gpuobj_del(&chan->engn[engine->subdev.index].inst); } @@ -150,13 +146,13 @@ gf100_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, if (ret) return ret; - ret = nvkm_vm_get(chan->base.vmm, chan->engn[engn].inst->size, 12, - NV_MEM_ACCESS_RW, &chan->engn[engn].vma); + ret = nvkm_vmm_get(chan->base.vmm, 12, chan->engn[engn].inst->size, + &chan->engn[engn].vma); if (ret) return ret; return nvkm_memory_map(chan->engn[engn].inst, 0, chan->base.vmm, - &chan->engn[engn].vma, NULL, 0); + chan->engn[engn].vma, NULL, 0); } static void @@ -252,7 +248,7 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, (1ULL << NVKM_ENGINE_MSPPP) | (1ULL << NVKM_ENGINE_MSVLD) | (1ULL << NVKM_ENGINE_SW), - 1, fifo->user.bar.offset, 0x1000, + 1, fifo->user.bar->addr, 0x1000, oclass, &chan->base); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 1c3ee4410287..368f5f5138a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -117,7 +117,7 @@ gk104_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base, u32 offset = gk104_fifo_gpfifo_engine_addr(engine); if (offset) { - u64 addr = chan->engn[engine->subdev.index].vma.offset; + u64 addr = chan->engn[engine->subdev.index].vma->addr; u32 datalo = lower_32_bits(addr) | 0x00000004; u32 datahi = upper_32_bits(addr); nvkm_kmap(inst); @@ -138,11 +138,7 @@ gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base, struct nvkm_engine *engine) { struct gk104_fifo_chan *chan = gk104_fifo_chan(base); - struct nvkm_vma *vma = &chan->engn[engine->subdev.index].vma; - if (vma->vm) { - nvkm_vm_unmap(vma); - nvkm_vm_put(vma); - } + nvkm_vmm_put(chan->base.vmm, &chan->engn[engine->subdev.index].vma); nvkm_gpuobj_del(&chan->engn[engine->subdev.index].inst); } @@ -162,13 +158,13 @@ gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, if (ret) return ret; - ret = nvkm_vm_get(chan->base.vmm, chan->engn[engn].inst->size, 12, - NV_MEM_ACCESS_RW, &chan->engn[engn].vma); + ret = nvkm_vmm_get(chan->base.vmm, 12, chan->engn[engn].inst->size, + &chan->engn[engn].vma); if (ret) return ret; return nvkm_memory_map(chan->engn[engn].inst, 0, chan->base.vmm, - &chan->engn[engn].vma, NULL, 0); + chan->engn[engn].vma, NULL, 0); } static void @@ -291,7 +287,7 @@ gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, ret = nvkm_fifo_chan_ctor(&gk104_fifo_gpfifo_func, &fifo->base, 0x1000, 0x1000, true, vm, 0, subdevs, - 1, fifo->user.bar.offset, 0x200, + 1, fifo->user.bar->addr, 0x200, oclass, &chan->base); if (ret) return ret; -- cgit v1.2.3 From 019e4d76c6e91b3eae1d8d88b8683a24c1ec26d3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/gr/gf100-: use new interfaces for vmm operations Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 13 +++----- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 3 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 3 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 6 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 9 ++---- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 6 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 3 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 39 +++++++++++------------ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 7 ++-- 10 files changed, 39 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index ce69ec8b13ad..8c60b24eae04 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -986,14 +986,14 @@ gf100_grctx_pack_tpc[] = { ******************************************************************************/ int -gf100_grctx_mmio_data(struct gf100_grctx *info, u32 size, u32 align, u32 access) +gf100_grctx_mmio_data(struct gf100_grctx *info, u32 size, u32 align, bool priv) { if (info->data) { info->buffer[info->buffer_nr] = round_up(info->addr, align); info->addr = info->buffer[info->buffer_nr] + size; info->data->size = size; info->data->align = align; - info->data->access = access; + info->data->priv = priv; info->data++; return info->buffer_nr++; } @@ -1028,9 +1028,8 @@ void gf100_grctx_generate_bundle(struct gf100_grctx *info) { const struct gf100_grctx_func *grctx = info->gr->func->grctx; - const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; const int s = 8; - const int b = mmio_vram(info, grctx->bundle_size, (1 << s), access); + const int b = mmio_vram(info, grctx->bundle_size, (1 << s), true); mmio_refn(info, 0x408004, 0x00000000, s, b); mmio_wr32(info, 0x408008, 0x80000000 | (grctx->bundle_size >> s)); mmio_refn(info, 0x418808, 0x00000000, s, b); @@ -1041,9 +1040,8 @@ void gf100_grctx_generate_pagepool(struct gf100_grctx *info) { const struct gf100_grctx_func *grctx = info->gr->func->grctx; - const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; const int s = 8; - const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), access); + const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), true); mmio_refn(info, 0x40800c, 0x00000000, s, b); mmio_wr32(info, 0x408010, 0x80000000); mmio_refn(info, 0x419004, 0x00000000, s, b); @@ -1057,9 +1055,8 @@ gf100_grctx_generate_attrib(struct gf100_grctx *info) const struct gf100_grctx_func *grctx = gr->func->grctx; const u32 attrib = grctx->attrib_nr; const u32 size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); - const u32 access = NV_MEM_ACCESS_RW; const int s = 12; - const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), access); + const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false); int gpc, tpc; u32 bo = 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 017180d147cf..4731e56fbb11 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -11,7 +11,7 @@ struct gf100_grctx { u64 addr; }; -int gf100_grctx_mmio_data(struct gf100_grctx *, u32 size, u32 align, u32 access); +int gf100_grctx_mmio_data(struct gf100_grctx *, u32 size, u32 align, bool priv); void gf100_grctx_mmio_item(struct gf100_grctx *, u32 addr, u32 data, int s, int); #define mmio_vram(a,b,c,d) gf100_grctx_mmio_data((a), (b), (c), (d)) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index 505cdcbfc085..82f71b10c06e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -735,9 +735,8 @@ gf108_grctx_generate_attrib(struct gf100_grctx *info) const u32 alpha = grctx->alpha_nr; const u32 beta = grctx->attrib_nr; const u32 size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); - const u32 access = NV_MEM_ACCESS_RW; const int s = 12; - const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), access); + const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false); const int timeslice_mode = 1; const int max_batches = 0xffff; u32 bo = 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 74a64e3fd59a..19301d88577d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -187,9 +187,8 @@ gf117_grctx_generate_attrib(struct gf100_grctx *info) const u32 alpha = grctx->alpha_nr; const u32 beta = grctx->attrib_nr; const u32 size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); - const u32 access = NV_MEM_ACCESS_RW; const int s = 12; - const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), access); + const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false); const int timeslice_mode = 1; const int max_batches = 0xffff; u32 bo = 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index c46b3fdf7203..825c8fd500bc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -847,9 +847,8 @@ gk104_grctx_generate_bundle(struct gf100_grctx *info) const u32 state_limit = min(grctx->bundle_min_gpm_fifo_depth, grctx->bundle_size / 0x20); const u32 token_limit = grctx->bundle_token_limit; - const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; const int s = 8; - const int b = mmio_vram(info, grctx->bundle_size, (1 << s), access); + const int b = mmio_vram(info, grctx->bundle_size, (1 << s), true); mmio_refn(info, 0x408004, 0x00000000, s, b); mmio_wr32(info, 0x408008, 0x80000000 | (grctx->bundle_size >> s)); mmio_refn(info, 0x418808, 0x00000000, s, b); @@ -861,9 +860,8 @@ void gk104_grctx_generate_pagepool(struct gf100_grctx *info) { const struct gf100_grctx_func *grctx = info->gr->func->grctx; - const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; const int s = 8; - const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), access); + const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), true); mmio_refn(info, 0x40800c, 0x00000000, s, b); mmio_wr32(info, 0x408010, 0x80000000); mmio_refn(info, 0x419004, 0x00000000, s, b); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index 4c4b5ab6e46d..9b43d4ce3eaa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -867,9 +867,8 @@ gm107_grctx_generate_bundle(struct gf100_grctx *info) const u32 state_limit = min(grctx->bundle_min_gpm_fifo_depth, grctx->bundle_size / 0x20); const u32 token_limit = grctx->bundle_token_limit; - const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; const int s = 8; - const int b = mmio_vram(info, grctx->bundle_size, (1 << s), access); + const int b = mmio_vram(info, grctx->bundle_size, (1 << s), true); mmio_refn(info, 0x408004, 0x00000000, s, b); mmio_wr32(info, 0x408008, 0x80000000 | (grctx->bundle_size >> s)); mmio_refn(info, 0x418e24, 0x00000000, s, b); @@ -881,9 +880,8 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *info) { const struct gf100_grctx_func *grctx = info->gr->func->grctx; - const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; const int s = 8; - const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), access); + const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), true); mmio_refn(info, 0x40800c, 0x00000000, s, b); mmio_wr32(info, 0x408010, 0x80000000); mmio_refn(info, 0x419004, 0x00000000, s, b); @@ -900,9 +898,8 @@ gm107_grctx_generate_attrib(struct gf100_grctx *info) const u32 alpha = grctx->alpha_nr; const u32 attrib = grctx->attrib_nr; const u32 size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); - const u32 access = NV_MEM_ACCESS_RW; const int s = 12; - const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), access); + const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false); const int max_batches = 0xffff; u32 bo = 0; u32 ao = bo + grctx->attrib_nr_max * gr->tpc_total; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index 7833bc777a29..88ea322d956c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -33,9 +33,8 @@ void gp100_grctx_generate_pagepool(struct gf100_grctx *info) { const struct gf100_grctx_func *grctx = info->gr->func->grctx; - const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; const int s = 8; - const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), access); + const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), true); mmio_refn(info, 0x40800c, 0x00000000, s, b); mmio_wr32(info, 0x408010, 0x80000000); mmio_refn(info, 0x419004, 0x00000000, s, b); @@ -51,9 +50,8 @@ gp100_grctx_generate_attrib(struct gf100_grctx *info) const u32 attrib = grctx->attrib_nr; const u32 pertpc = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); const u32 size = roundup(gr->tpc_total * pertpc, 0x80); - const u32 access = NV_MEM_ACCESS_RW; const int s = 12; - const int b = mmio_vram(info, size, (1 << s), access); + const int b = mmio_vram(info, size, (1 << s), false); const int max_batches = 0xffff; u32 ao = 0; u32 bo = ao + grctx->alpha_nr_max * gr->tpc_total; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 80b7ab0bee3a..7a66b4c2eb18 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -38,9 +38,8 @@ gp102_grctx_generate_attrib(struct gf100_grctx *info) const u32 attrib = grctx->attrib_nr; const u32 pertpc = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); const u32 size = roundup(gr->tpc_total * pertpc, 0x80); - const u32 access = NV_MEM_ACCESS_RW; const int s = 12; - const int b = mmio_vram(info, size, (1 << s), access); + const int b = mmio_vram(info, size, (1 << s), false); const int max_batches = 0xffff; u32 ao = 0; u32 bo = ao + grctx->alpha_nr_max * gr->tpc_total; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index b6cde1385941..4b3d5432a53e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -37,6 +37,7 @@ #include #include +#include #include /******************************************************************************* @@ -327,13 +328,13 @@ gf100_gr_chan_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent, if (!gr->firmware) { nvkm_wo32(*pgpuobj, 0x00, chan->mmio_nr / 2); - nvkm_wo32(*pgpuobj, 0x04, chan->mmio_vma.offset >> 8); + nvkm_wo32(*pgpuobj, 0x04, chan->mmio_vma->addr >> 8); } else { nvkm_wo32(*pgpuobj, 0xf4, 0); nvkm_wo32(*pgpuobj, 0xf8, 0); nvkm_wo32(*pgpuobj, 0x10, chan->mmio_nr / 2); - nvkm_wo32(*pgpuobj, 0x14, lower_32_bits(chan->mmio_vma.offset)); - nvkm_wo32(*pgpuobj, 0x18, upper_32_bits(chan->mmio_vma.offset)); + nvkm_wo32(*pgpuobj, 0x14, lower_32_bits(chan->mmio_vma->addr)); + nvkm_wo32(*pgpuobj, 0x18, upper_32_bits(chan->mmio_vma->addr)); nvkm_wo32(*pgpuobj, 0x1c, 1); nvkm_wo32(*pgpuobj, 0x20, 0); nvkm_wo32(*pgpuobj, 0x28, 0); @@ -350,18 +351,13 @@ gf100_gr_chan_dtor(struct nvkm_object *object) int i; for (i = 0; i < ARRAY_SIZE(chan->data); i++) { - if (chan->data[i].vma.node) { - nvkm_vm_unmap(&chan->data[i].vma); - nvkm_vm_put(&chan->data[i].vma); - } + nvkm_vmm_put(chan->vmm, &chan->data[i].vma); nvkm_memory_unref(&chan->data[i].mem); } - if (chan->mmio_vma.node) { - nvkm_vm_unmap(&chan->mmio_vma); - nvkm_vm_put(&chan->mmio_vma); - } + nvkm_vmm_put(chan->vmm, &chan->mmio_vma); nvkm_memory_unref(&chan->mmio); + nvkm_vmm_unref(&chan->vmm); return chan; } @@ -380,6 +376,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, struct gf100_gr_data *data = gr->mmio_data; struct gf100_gr_mmio *mmio = gr->mmio_list; struct gf100_gr_chan *chan; + struct gf100_vmm_map_v0 args = { .priv = 1 }; struct nvkm_device *device = gr->base.engine.subdev.device; int ret, i; @@ -387,6 +384,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, return -ENOMEM; nvkm_object_ctor(&gf100_gr_chan, oclass, &chan->object); chan->gr = gr; + chan->vmm = nvkm_vmm_ref(fifoch->vmm); *pobject = &chan->object; /* allocate memory for a "mmio list" buffer that's used by the HUB @@ -398,13 +396,12 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, if (ret) return ret; - ret = nvkm_vm_get(fifoch->vmm, 0x1000, 12, NV_MEM_ACCESS_RW | - NV_MEM_ACCESS_SYS, &chan->mmio_vma); + ret = nvkm_vmm_get(fifoch->vmm, 12, 0x1000, &chan->mmio_vma); if (ret) return ret; ret = nvkm_memory_map(chan->mmio, 0, fifoch->vmm, - &chan->mmio_vma, NULL, 0); + chan->mmio_vma, &args, sizeof(args)); if (ret) return ret; @@ -416,14 +413,16 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, if (ret) return ret; - ret = nvkm_vm_get(fifoch->vmm, - nvkm_memory_size(chan->data[i].mem), 12, - data->access, &chan->data[i].vma); + ret = nvkm_vmm_get(fifoch->vmm, 12, + nvkm_memory_size(chan->data[i].mem), + &chan->data[i].vma); if (ret) return ret; - ret = nvkm_memory_map(chan->data[i].mem, 0, fifoch->vmm, - &chan->data[i].vma, NULL, 0); + args.priv = data->priv; + + ret = nvkm_memory_map(chan->data[i].mem, 0, chan->vmm, + chan->data[i].vma, &args, sizeof(args)); if (ret) return ret; @@ -437,7 +436,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, u32 data = mmio->data; if (mmio->buffer >= 0) { - u64 info = chan->data[mmio->buffer].vma.offset; + u64 info = chan->data[mmio->buffer].vma->addr; data |= info >> mmio->shift; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 51c1e380ffb6..d7c2adb9b543 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -45,7 +45,7 @@ struct gf100_gr_data { u32 size; u32 align; - u32 access; + bool priv; }; struct gf100_gr_mmio { @@ -161,14 +161,15 @@ void gp100_gr_init_rop_active_fbps(struct gf100_gr *); struct gf100_gr_chan { struct nvkm_object object; struct gf100_gr *gr; + struct nvkm_vmm *vmm; struct nvkm_memory *mmio; - struct nvkm_vma mmio_vma; + struct nvkm_vma *mmio_vma; int mmio_nr; struct { struct nvkm_memory *mem; - struct nvkm_vma vma; + struct nvkm_vma *vma; } data[4]; }; -- cgit v1.2.3 From 2cabefcbd097e27def6d29d52d5d2cf8797c11e4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/gr/gf100-: replace hardcoded instance/vmm setup in grctx generation Could be useful for if/when a future GPU removes support for the GF100 PT layout. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 110 ++++++++++++---------- 1 file changed, 58 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 8c60b24eae04..881015080d83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1264,85 +1264,87 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_mc_unk260(device, 1); } +#define CB_RESERVED 0x80000 + int gf100_grctx_generate(struct gf100_gr *gr) { const struct gf100_grctx_func *grctx = gr->func->grctx; struct nvkm_subdev *subdev = &gr->base.engine.subdev; struct nvkm_device *device = subdev->device; - struct nvkm_memory *chan; + struct nvkm_memory *inst = NULL; + struct nvkm_memory *data = NULL; + struct nvkm_vmm *vmm = NULL; + struct nvkm_vma *ctx = NULL; struct gf100_grctx info; int ret, i; u64 addr; - /* allocate memory to for a "channel", which we'll use to generate - * the default context values + /* Allocate memory to for a "channel", which we'll use to generate + * the default context values. */ - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x80000 + gr->size, - 0x1000, true, &chan); - if (ret) { - nvkm_error(subdev, "failed to allocate chan memory, %d\n", ret); - return ret; - } + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, + 0x1000, 0x1000, true, &inst); + if (ret) + goto done; - addr = nvkm_memory_addr(chan); + ret = nvkm_vmm_new(device, 0, 0, NULL, 0, NULL, "grctx", &vmm); + if (ret) + goto done; - /* PGD pointer */ - nvkm_kmap(chan); - nvkm_wo32(chan, 0x0200, lower_32_bits(addr + 0x1000)); - nvkm_wo32(chan, 0x0204, upper_32_bits(addr + 0x1000)); - nvkm_wo32(chan, 0x0208, 0xffffffff); - nvkm_wo32(chan, 0x020c, 0x000000ff); + vmm->debug = subdev->debug; - /* PGT[0] pointer */ - nvkm_wo32(chan, 0x1000, 0x00000000); - nvkm_wo32(chan, 0x1004, 0x00000001 | (addr + 0x2000) >> 8); + ret = nvkm_vmm_join(vmm, inst); + if (ret) + goto done; - /* identity-map the whole "channel" into its own vm */ - for (i = 0; i < nvkm_memory_size(chan) / 4096; i++) { - u64 addr = ((nvkm_memory_addr(chan) + (i * 4096)) >> 8) | 1; - nvkm_wo32(chan, 0x2000 + (i * 8), lower_32_bits(addr)); - nvkm_wo32(chan, 0x2004 + (i * 8), upper_32_bits(addr)); - } + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, + CB_RESERVED + gr->size, 0, true, &data); + if (ret) + goto done; - /* context pointer (virt) */ - nvkm_wo32(chan, 0x0210, 0x00080004); - nvkm_wo32(chan, 0x0214, 0x00000000); - nvkm_done(chan); + ret = nvkm_vmm_get(vmm, 0, nvkm_memory_size(data), &ctx); + if (ret) + goto done; - nvkm_wr32(device, 0x100cb8, (addr + 0x1000) >> 8); - nvkm_wr32(device, 0x100cbc, 0x80000001); - nvkm_msec(device, 2000, - if (nvkm_rd32(device, 0x100c80) & 0x00008000) - break; - ); + ret = nvkm_memory_map(data, 0, vmm, ctx, NULL, 0); + if (ret) + goto done; + + + /* Setup context pointer. */ + nvkm_kmap(inst); + nvkm_wo32(inst, 0x0210, lower_32_bits(ctx->addr + CB_RESERVED) | 4); + nvkm_wo32(inst, 0x0214, upper_32_bits(ctx->addr + CB_RESERVED)); + nvkm_done(inst); - /* setup default state for mmio list construction */ + /* Setup default state for mmio list construction. */ info.gr = gr; info.data = gr->mmio_data; info.mmio = gr->mmio_list; - info.addr = 0x2000 + (i * 8); + info.addr = ctx->addr; info.buffer_nr = 0; - /* make channel current */ + /* Make channel current. */ + addr = nvkm_memory_addr(inst) >> 12; if (gr->firmware) { nvkm_wr32(device, 0x409840, 0x00000030); - nvkm_wr32(device, 0x409500, 0x80000000 | addr >> 12); + nvkm_wr32(device, 0x409500, 0x80000000 | addr); nvkm_wr32(device, 0x409504, 0x00000003); nvkm_msec(device, 2000, if (nvkm_rd32(device, 0x409800) & 0x00000010) break; ); - nvkm_kmap(chan); - nvkm_wo32(chan, 0x8001c, 1); - nvkm_wo32(chan, 0x80020, 0); - nvkm_wo32(chan, 0x80028, 0); - nvkm_wo32(chan, 0x8002c, 0); - nvkm_done(chan); + nvkm_kmap(data); + nvkm_wo32(data, 0x1c, 1); + nvkm_wo32(data, 0x20, 0); + nvkm_wo32(data, 0x28, 0); + nvkm_wo32(data, 0x2c, 0); + nvkm_done(data); } else { nvkm_wr32(device, 0x409840, 0x80000000); - nvkm_wr32(device, 0x409500, 0x80000000 | addr >> 12); + nvkm_wr32(device, 0x409500, 0x80000000 | addr); nvkm_wr32(device, 0x409504, 0x00000001); nvkm_msec(device, 2000, if (nvkm_rd32(device, 0x409800) & 0x80000000) @@ -1352,8 +1354,8 @@ gf100_grctx_generate(struct gf100_gr *gr) grctx->main(gr, &info); - /* trigger a context unload by unsetting the "next channel valid" bit - * and faking a context switch interrupt + /* Trigger a context unload by unsetting the "next channel valid" bit + * and faking a context switch interrupt. */ nvkm_mask(device, 0x409b04, 0x80000000, 0x00000000); nvkm_wr32(device, 0x409000, 0x00000100); @@ -1367,17 +1369,21 @@ gf100_grctx_generate(struct gf100_gr *gr) gr->data = kmalloc(gr->size, GFP_KERNEL); if (gr->data) { - nvkm_kmap(chan); + nvkm_kmap(data); for (i = 0; i < gr->size; i += 4) - gr->data[i / 4] = nvkm_ro32(chan, 0x80000 + i); - nvkm_done(chan); + gr->data[i / 4] = nvkm_ro32(data, CB_RESERVED + i); + nvkm_done(data); ret = 0; } else { ret = -ENOMEM; } done: - nvkm_memory_unref(&chan); + nvkm_vmm_put(vmm, &ctx); + nvkm_memory_unref(&data); + nvkm_vmm_part(vmm, inst); + nvkm_vmm_unref(&vmm); + nvkm_memory_unref(&inst); return ret; } -- cgit v1.2.3 From 3a314f747ba5b4cca22a36603768c176d1761afd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: remove explicit unmaps If the VMA is being deleted, we don't need to explicity unmap first anymore. The MMU code will automatically merge the operations into a single page tree walk. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 1 - drivers/gpu/drm/nouveau/nouveau_mem.c | 10 ++-------- drivers/gpu/drm/nouveau/nouveau_vmm.c | 4 +--- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d89f3e700baf..f4545773756a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1414,7 +1414,6 @@ nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) if (!mem->bar_vma.node) return; - nvkm_vm_unmap(&mem->bar_vma); nvkm_vm_put(&mem->bar_vma); } diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 70fbe5e72b55..17c6efb0ebec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -36,14 +36,8 @@ nouveau_mem_map(struct nouveau_mem *mem, void nouveau_mem_fini(struct nouveau_mem *mem) { - if (mem->vma[1].node) { - nvkm_vm_unmap(&mem->vma[1]); - nvkm_vm_put(&mem->vma[1]); - } - if (mem->vma[0].node) { - nvkm_vm_unmap(&mem->vma[0]); - nvkm_vm_put(&mem->vma[0]); - } + nvkm_vm_put(&mem->vma[1]); + nvkm_vm_put(&mem->vma[0]); } int diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index 855d549e17cf..6dc14f92b988 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -61,10 +61,8 @@ nouveau_vma_del(struct nouveau_vma **pvma) { struct nouveau_vma *vma = *pvma; if (vma && --vma->refs <= 0) { - if (likely(vma->addr != ~0ULL)) { - nouveau_vma_unmap(vma); + if (likely(vma->addr != ~0ULL)) nvkm_vm_put(&vma->_vma); - } list_del(&vma->head); *pvma = NULL; kfree(*pvma); -- cgit v1.2.3 From 51645eb71485dd3d72d9fe2acd0298057afdf437 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: build up information on available memory types Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 20 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 120 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 1 + 11 files changed, 151 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 7fa60d79ec4c..11a169d3ed8c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -108,6 +108,26 @@ struct nvkm_mmu { u8 dma_bits; u8 lpg_shift; + int heap_nr; + struct { +#define NVKM_MEM_VRAM 0x01 +#define NVKM_MEM_HOST 0x02 +#define NVKM_MEM_COMP 0x04 +#define NVKM_MEM_DISP 0x08 + u8 type; + u64 size; + } heap[4]; + + int type_nr; + struct { +#define NVKM_MEM_KIND 0x10 +#define NVKM_MEM_MAPPABLE 0x20 +#define NVKM_MEM_COHERENT 0x40 +#define NVKM_MEM_UNCACHED 0x80 + u8 type; + u8 heap; + } type[16]; + struct nvkm_vmm *vmm; struct { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 9bf688df24f0..be600049f221 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -24,6 +24,7 @@ #include "priv.h" #include "vmm.h" +#include #include #include @@ -443,11 +444,130 @@ nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) return 0; } +static void +nvkm_mmu_type(struct nvkm_mmu *mmu, int heap, u8 type) +{ + if (heap >= 0 && !WARN_ON(mmu->type_nr == ARRAY_SIZE(mmu->type))) { + mmu->type[mmu->type_nr].type = type | mmu->heap[heap].type; + mmu->type[mmu->type_nr].heap = heap; + mmu->type_nr++; + } +} + +static int +nvkm_mmu_heap(struct nvkm_mmu *mmu, u8 type, u64 size) +{ + if (size) { + if (!WARN_ON(mmu->heap_nr == ARRAY_SIZE(mmu->heap))) { + mmu->heap[mmu->heap_nr].type = type; + mmu->heap[mmu->heap_nr].size = size; + return mmu->heap_nr++; + } + } + return -EINVAL; +} + +static void +nvkm_mmu_host(struct nvkm_mmu *mmu) +{ + struct nvkm_device *device = mmu->subdev.device; + u8 type = NVKM_MEM_KIND * !!mmu->func->kind_sys; + int heap; + + /* Non-mappable system memory. */ + heap = nvkm_mmu_heap(mmu, NVKM_MEM_HOST, ~0ULL); + nvkm_mmu_type(mmu, heap, type); + + /* Non-coherent, cached, system memory. + * + * Block-linear mappings of system memory must be done through + * BAR1, and cannot be supported on systems where we're unable + * to map BAR1 with write-combining. + */ + type |= NVKM_MEM_MAPPABLE; + if (!device->bar || device->bar->iomap_uncached) + nvkm_mmu_type(mmu, heap, type & ~NVKM_MEM_KIND); + else + nvkm_mmu_type(mmu, heap, type); + + /* Coherent, cached, system memory. + * + * Unsupported on systems that aren't able to support snooped + * mappings, and also for block-linear mappings which must be + * done through BAR1. + */ + type |= NVKM_MEM_COHERENT; + if (device->func->cpu_coherent) + nvkm_mmu_type(mmu, heap, type & ~NVKM_MEM_KIND); + + /* Uncached system memory. */ + nvkm_mmu_type(mmu, heap, type |= NVKM_MEM_UNCACHED); +} + +static void +nvkm_mmu_vram(struct nvkm_mmu *mmu) +{ + struct nvkm_device *device = mmu->subdev.device; + struct nvkm_mm *mm = &device->fb->ram->vram; + const u32 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); + const u32 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); + const u32 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); + u8 type = NVKM_MEM_KIND * !!mmu->func->kind; + u8 heap = NVKM_MEM_VRAM; + int heapM, heapN, heapU; + + /* Mixed-memory doesn't support compression or display. */ + heapM = nvkm_mmu_heap(mmu, heap, sizeM << NVKM_RAM_MM_SHIFT); + + heap |= NVKM_MEM_COMP; + heap |= NVKM_MEM_DISP; + heapN = nvkm_mmu_heap(mmu, heap, sizeN << NVKM_RAM_MM_SHIFT); + heapU = nvkm_mmu_heap(mmu, heap, sizeU << NVKM_RAM_MM_SHIFT); + + /* Add non-mappable VRAM types first so that they're preferred + * over anything else. Mixed-memory will be slower than other + * heaps, it's prioritised last. + */ + nvkm_mmu_type(mmu, heapU, type); + nvkm_mmu_type(mmu, heapN, type); + nvkm_mmu_type(mmu, heapM, type); + + /* Add host memory types next, under the assumption that users + * wanting mappable memory want to use them as staging buffers + * or the like. + */ + nvkm_mmu_host(mmu); + + /* Mappable VRAM types go last, as they're basically the worst + * possible type to ask for unless there's no other choice. + */ + if (device->bar) { + /* Write-combined BAR1 access. */ + type |= NVKM_MEM_MAPPABLE; + if (!device->bar->iomap_uncached) { + nvkm_mmu_type(mmu, heapN, type); + nvkm_mmu_type(mmu, heapM, type); + } + + /* Uncached BAR1 access. */ + type |= NVKM_MEM_COHERENT; + type |= NVKM_MEM_UNCACHED; + nvkm_mmu_type(mmu, heapN, type); + nvkm_mmu_type(mmu, heapM, type); + } +} + static int nvkm_mmu_oneinit(struct nvkm_subdev *subdev) { struct nvkm_mmu *mmu = nvkm_mmu(subdev); + /* Determine available memory types. */ + if (mmu->subdev.device->fb && mmu->subdev.device->fb->ram) + nvkm_mmu_vram(mmu); + else + nvkm_mmu_host(mmu); + if (mmu->func->vmm.global) { int ret = nvkm_vmm_new(subdev->device, 0, 0, NULL, 0, NULL, "gart", &mmu->vmm); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index c90c9980478b..0f4c9533c967 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -30,6 +30,7 @@ g84_mmu = { .lpg_shift = 16, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, .kind = nv50_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index ca5ca27188cd..81e9145f96a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -78,6 +78,7 @@ gf100_mmu = { .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new }, .kind = gf100_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index db7353aa25df..95f07acaed2f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -30,6 +30,7 @@ gk104_mmu = { .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new }, .kind = gf100_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index 2dfe8b1ba109..18d4a321bd64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -30,6 +30,7 @@ gk20a_mmu = { .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new }, .kind = gf100_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index a9628baf5372..f961f782ac9b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -74,6 +74,7 @@ gm200_mmu = { .lpg_shift = 17, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm200_vmm_new }, .kind = gm200_mmu_kind, + .kind_sys = true, }; static const struct nvkm_mmu_func @@ -83,6 +84,7 @@ gm200_mmu_fixed = { .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm200_vmm_new_fixed }, .kind = gm200_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 5d14c138af02..585fe80f87af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -32,6 +32,7 @@ gm20b_mmu = { .lpg_shift = 17, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new }, .kind = gm200_mmu_kind, + .kind_sys = true, }; static const struct nvkm_mmu_func @@ -41,6 +42,7 @@ gm20b_mmu_fixed = { .lpg_shift = 17, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new_fixed }, .kind = gm200_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c index 0cc9c89c0e73..4ebb45a275ea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -32,6 +32,7 @@ gp100_mmu = { .lpg_shift = 16, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp100_vmm_new }, .kind = gm200_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c index 5c7217697760..e864cfe57ae6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c @@ -32,6 +32,7 @@ gp10b_mmu = { .lpg_shift = 16, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp10b_vmm_new }, .kind = gm200_mmu_kind, + .kind_sys = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index bc4571a20690..d8d63ae7e0f7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -25,6 +25,7 @@ struct nvkm_mmu_func { } vmm; const u8 *(*kind)(struct nvkm_mmu *, int *count); + bool kind_sys; }; extern const struct nvkm_mmu_func nv04_mmu; -- cgit v1.2.3 From eaf1a69110f4497746d5b6e35929dbdc860040d2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: add base for type-based memory allocation Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + drivers/gpu/drm/nouveau/include/nvif/if000a.h | 13 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c | 242 +++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h | 8 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 8 + 6 files changed, 275 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if000a.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index d5236daf54c4..f81cc3e683d9 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -14,6 +14,8 @@ #define NVIF_CLASS_SW_NV50 /* if0005.h */ -0x00000006 #define NVIF_CLASS_SW_GF100 /* if0005.h */ -0x00000007 +#define NVIF_CLASS_MEM /* if000a.h */ 0x8000000a + #define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d #define NVIF_CLASS_VMM_NV50 /* if500d.h */ 0x8000500d diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000a.h b/drivers/gpu/drm/nouveau/include/nvif/if000a.h new file mode 100644 index 000000000000..e6e8764abf4a --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if000a.h @@ -0,0 +1,13 @@ +#ifndef __NVIF_IF000A_H__ +#define __NVIF_IF000A_H__ + +struct nvif_mem_ram_vn { +}; + +struct nvif_mem_ram_v0 { + __u8 version; + __u8 pad01[7]; + dma_addr_t *dma; + struct scatterlist *sgl; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index e7ef528fb5bf..941b629550c1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -12,6 +12,8 @@ nvkm-y += nvkm/subdev/mmu/gm20b.o nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/gp10b.o +nvkm-y += nvkm/subdev/mmu/mem.o + nvkm-y += nvkm/subdev/mmu/vmm.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o nvkm-y += nvkm/subdev/mmu/vmmnv41.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c new file mode 100644 index 000000000000..39808489f21d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c @@ -0,0 +1,242 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 nvkm_mem(p) container_of((p), struct nvkm_mem, memory) +#include "mem.h" + +#include + +#include +#include + +struct nvkm_mem { + struct nvkm_memory memory; + enum nvkm_memory_target target; + struct nvkm_mmu *mmu; + u64 pages; + struct page **mem; + union { + struct scatterlist *sgl; + dma_addr_t *dma; + }; +}; + +static enum nvkm_memory_target +nvkm_mem_target(struct nvkm_memory *memory) +{ + return nvkm_mem(memory)->target; +} + +static u8 +nvkm_mem_page(struct nvkm_memory *memory) +{ + return PAGE_SHIFT; +} + +static u64 +nvkm_mem_addr(struct nvkm_memory *memory) +{ + struct nvkm_mem *mem = nvkm_mem(memory); + if (mem->pages == 1 && mem->mem) + return mem->dma[0]; + return ~0ULL; +} + +static u64 +nvkm_mem_size(struct nvkm_memory *memory) +{ + return nvkm_mem(memory)->pages << PAGE_SHIFT; +} + +static int +nvkm_mem_map_dma(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, + struct nvkm_vma *vma, void *argv, u32 argc) +{ + struct nvkm_mem *mem = nvkm_mem(memory); + struct nvkm_vmm_map map = { + .memory = &mem->memory, + .offset = offset, + .dma = mem->dma, + }; + return nvkm_vmm_map(vmm, vma, argv, argc, &map); +} + +static void * +nvkm_mem_dtor(struct nvkm_memory *memory) +{ + struct nvkm_mem *mem = nvkm_mem(memory); + if (mem->mem) { + while (mem->pages--) { + dma_unmap_page(mem->mmu->subdev.device->dev, + mem->dma[mem->pages], PAGE_SIZE, + DMA_BIDIRECTIONAL); + __free_page(mem->mem[mem->pages]); + } + kvfree(mem->dma); + kvfree(mem->mem); + } + return mem; +} + +static const struct nvkm_memory_func +nvkm_mem_dma = { + .dtor = nvkm_mem_dtor, + .target = nvkm_mem_target, + .page = nvkm_mem_page, + .addr = nvkm_mem_addr, + .size = nvkm_mem_size, + .map = nvkm_mem_map_dma, +}; + +static int +nvkm_mem_map_sgl(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, + struct nvkm_vma *vma, void *argv, u32 argc) +{ + struct nvkm_mem *mem = nvkm_mem(memory); + struct nvkm_vmm_map map = { + .memory = &mem->memory, + .offset = offset, + .sgl = mem->sgl, + }; + return nvkm_vmm_map(vmm, vma, argv, argc, &map); +} + +static const struct nvkm_memory_func +nvkm_mem_sgl = { + .dtor = nvkm_mem_dtor, + .target = nvkm_mem_target, + .page = nvkm_mem_page, + .addr = nvkm_mem_addr, + .size = nvkm_mem_size, + .map = nvkm_mem_map_sgl, +}; + +int +nvkm_mem_map_host(struct nvkm_memory *memory, void **pmap) +{ + struct nvkm_mem *mem = nvkm_mem(memory); + if (mem->mem) { + *pmap = vmap(mem->mem, mem->pages, VM_MAP, PAGE_KERNEL); + return *pmap ? 0 : -EFAULT; + } + return -EINVAL; +} + +static int +nvkm_mem_new_host(struct nvkm_mmu *mmu, int type, u8 page, u64 size, + void *argv, u32 argc, struct nvkm_memory **pmemory) +{ + struct device *dev = mmu->subdev.device->dev; + union { + struct nvif_mem_ram_vn vn; + struct nvif_mem_ram_v0 v0; + } *args = argv; + int ret = -ENOSYS; + enum nvkm_memory_target target; + struct nvkm_mem *mem; + gfp_t gfp = GFP_USER | __GFP_ZERO; + + if ( (mmu->type[type].type & NVKM_MEM_COHERENT) && + !(mmu->type[type].type & NVKM_MEM_UNCACHED)) + target = NVKM_MEM_TARGET_HOST; + else + target = NVKM_MEM_TARGET_NCOH; + + if (page != PAGE_SHIFT) + return -EINVAL; + + if (!(mem = kzalloc(sizeof(*mem), GFP_KERNEL))) + return -ENOMEM; + mem->target = target; + mem->mmu = mmu; + *pmemory = &mem->memory; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + if (args->v0.dma) { + nvkm_memory_ctor(&nvkm_mem_dma, &mem->memory); + mem->dma = args->v0.dma; + } else { + nvkm_memory_ctor(&nvkm_mem_sgl, &mem->memory); + mem->sgl = args->v0.sgl; + } + + if (!IS_ALIGNED(size, PAGE_SIZE)) + return -EINVAL; + mem->pages = size >> PAGE_SHIFT; + return 0; + } else + if ( (ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + kfree(mem); + return ret; + } + + nvkm_memory_ctor(&nvkm_mem_dma, &mem->memory); + size = ALIGN(size, PAGE_SIZE) >> PAGE_SHIFT; + + if (!(mem->mem = kvmalloc(sizeof(*mem->mem) * size, GFP_KERNEL))) + return -ENOMEM; + if (!(mem->dma = kvmalloc(sizeof(*mem->dma) * size, GFP_KERNEL))) + return -ENOMEM; + + if (mmu->dma_bits > 32) + gfp |= GFP_HIGHUSER; + else + gfp |= GFP_DMA32; + + for (mem->pages = 0; size; size--, mem->pages++) { + struct page *p = alloc_page(gfp); + if (!p) + return -ENOMEM; + + mem->dma[mem->pages] = dma_map_page(mmu->subdev.device->dev, + p, 0, PAGE_SIZE, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, mem->dma[mem->pages])) { + __free_page(p); + return -ENOMEM; + } + + mem->mem[mem->pages] = p; + } + + return 0; +} + +int +nvkm_mem_new_type(struct nvkm_mmu *mmu, int type, u8 page, u64 size, + void *argv, u32 argc, struct nvkm_memory **pmemory) +{ + struct nvkm_memory *memory = NULL; + int ret; + + if (mmu->type[type].type & NVKM_MEM_VRAM) { + ret = mmu->func->mem.vram(mmu, type, page, size, + argv, argc, &memory); + } else { + ret = nvkm_mem_new_host(mmu, type, page, size, + argv, argc, &memory); + } + + if (ret) + nvkm_memory_unref(&memory); + *pmemory = memory; + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h new file mode 100644 index 000000000000..442adecdb289 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h @@ -0,0 +1,8 @@ +#ifndef __NVKM_MEM_H__ +#define __NVKM_MEM_H__ +#include "priv.h" + +int nvkm_mem_new_type(struct nvkm_mmu *, int type, u8 page, u64 size, + void *argv, u32 argc, struct nvkm_memory **); +int nvkm_mem_map_host(struct nvkm_memory *, void **pmap); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index d8d63ae7e0f7..00869fcc5751 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -15,6 +15,14 @@ struct nvkm_mmu_func { u8 dma_bits; u8 lpg_shift; + struct { + struct nvkm_sclass user; + int (*vram)(struct nvkm_mmu *, int type, u8 page, u64 size, + void *argv, u32 argc, struct nvkm_memory **); + int (*umap)(struct nvkm_mmu *, struct nvkm_memory *, void *argv, + u32 argc, u64 *addr, u64 *size, struct nvkm_vma **); + } mem; + struct { struct nvkm_sclass user; int (*ctor)(struct nvkm_mmu *, u64 addr, u64 size, -- cgit v1.2.3 From 957e18a70da19373f966c20dcf3ae5e1d49f9ed0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv04-nv4x: type-based vram allocation and bar mapping Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + drivers/gpu/drm/nouveau/include/nvif/if000b.h | 11 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h | 5 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c | 69 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c | 2 + 8 files changed, 93 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if000b.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index f81cc3e683d9..b1bc758a9518 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -15,6 +15,7 @@ #define NVIF_CLASS_SW_GF100 /* if0005.h */ -0x00000007 #define NVIF_CLASS_MEM /* if000a.h */ 0x8000000a +#define NVIF_CLASS_MEM_NV04 /* if000b.h */ 0x8000000b #define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000b.h b/drivers/gpu/drm/nouveau/include/nvif/if000b.h new file mode 100644 index 000000000000..c677fb0293da --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if000b.h @@ -0,0 +1,11 @@ +#ifndef __NVIF_IF000B_H__ +#define __NVIF_IF000B_H__ +#include "if000a.h" + +struct nv04_mem_vn { + /* nvkm_mem_vX ... */ +}; + +struct nv04_mem_map_vn { +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 941b629550c1..241f41da3881 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -13,6 +13,7 @@ nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/mem.o +nvkm-y += nvkm/subdev/mmu/memnv04.o nvkm-y += nvkm/subdev/mmu/vmm.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h index 442adecdb289..2986ee36bf00 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h @@ -5,4 +5,9 @@ int nvkm_mem_new_type(struct nvkm_mmu *, int type, u8 page, u64 size, void *argv, u32 argc, struct nvkm_memory **); int nvkm_mem_map_host(struct nvkm_memory *, void **pmap); + +int nv04_mem_new(struct nvkm_mmu *, int, u8, u64, void *, u32, + struct nvkm_memory **); +int nv04_mem_map(struct nvkm_mmu *, struct nvkm_memory *, void *, u32, + u64 *, u64 *, struct nvkm_vma **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c new file mode 100644 index 000000000000..79a3b0cc9f5b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "mem.h" + +#include +#include + +#include +#include + +int +nv04_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, + u32 argc, u64 *paddr, u64 *psize, struct nvkm_vma **pvma) +{ + union { + struct nv04_mem_map_vn vn; + } *args = argv; + struct nvkm_device *device = mmu->subdev.device; + const u64 addr = nvkm_memory_addr(memory); + int ret = -ENOSYS; + + if ((ret = nvif_unvers(ret, &argv, &argc, args->vn))) + return ret; + + *paddr = device->func->resource_addr(device, 1) + addr; + *psize = nvkm_memory_size(memory); + *pvma = ERR_PTR(-ENODEV); + return 0; +} + +int +nv04_mem_new(struct nvkm_mmu *mmu, int type, u8 page, u64 size, + void *argv, u32 argc, struct nvkm_memory **pmemory) +{ + union { + struct nv04_mem_vn vn; + } *args = argv; + int ret = -ENOSYS; + + if ((ret = nvif_unvers(ret, &argv, &argc, args->vn))) + return ret; + + if (mmu->type[type].type & NVKM_MEM_MAPPABLE) + type = NVKM_RAM_MM_NORMAL; + else + type = NVKM_RAM_MM_NOMAP; + + return nvkm_ram_get(mmu->subdev.device, type, 0x01, page, + size, true, false, pmemory); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 3ae70e218bc0..94db229bd929 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -21,6 +21,7 @@ * * Authors: Ben Skeggs */ +#include "mem.h" #include "vmm.h" #include @@ -32,6 +33,7 @@ nv04_mmu = { .limit = NV04_PDMA_SIZE, .dma_bits = 32, .lpg_shift = 12, + .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv04_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c index 5bcbc10d8564..caee0858f522 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c @@ -21,6 +21,7 @@ * * Authors: Ben Skeggs */ +#include "mem.h" #include "vmm.h" #include @@ -44,6 +45,7 @@ nv41_mmu = { .limit = NV41_GART_SIZE, .dma_bits = 39, .lpg_shift = 12, + .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv41_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c index 998287021e3f..5f15ec58bbd4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c @@ -21,6 +21,7 @@ * * Authors: Ben Skeggs */ +#include "mem.h" #include "vmm.h" #include @@ -59,6 +60,7 @@ nv44_mmu = { .limit = NV44_GART_SIZE, .dma_bits = 39, .lpg_shift = 12, + .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv44_vmm_new, true }, }; -- cgit v1.2.3 From 0766116157bf10a0680f4dc7530717e3b4d1a31e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/nv50,g84: type-based vram allocation and bar mapping Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + drivers/gpu/drm/nouveau/include/nvif/if500b.h | 25 +++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h | 5 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c | 88 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 2 + 7 files changed, 124 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if500b.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index b1bc758a9518..a9a79ff1ef5c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -16,6 +16,7 @@ #define NVIF_CLASS_MEM /* if000a.h */ 0x8000000a #define NVIF_CLASS_MEM_NV04 /* if000b.h */ 0x8000000b +#define NVIF_CLASS_MEM_NV50 /* if500b.h */ 0x8000500b #define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d diff --git a/drivers/gpu/drm/nouveau/include/nvif/if500b.h b/drivers/gpu/drm/nouveau/include/nvif/if500b.h new file mode 100644 index 000000000000..c7c8431fb2ce --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if500b.h @@ -0,0 +1,25 @@ +#ifndef __NVIF_IF500B_H__ +#define __NVIF_IF500B_H__ +#include "if000a.h" + +struct nv50_mem_vn { + /* nvif_mem_vX ... */ +}; + +struct nv50_mem_v0 { + /* nvif_mem_vX ... */ + __u8 version; + __u8 bankswz; + __u8 contig; +}; + +struct nv50_mem_map_vn { +}; + +struct nv50_mem_map_v0 { + __u8 version; + __u8 ro; + __u8 kind; + __u8 comp; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 241f41da3881..7e8e32898194 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -14,6 +14,7 @@ nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/mem.o nvkm-y += nvkm/subdev/mmu/memnv04.o +nvkm-y += nvkm/subdev/mmu/memnv50.o nvkm-y += nvkm/subdev/mmu/vmm.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index 0f4c9533c967..f5d061cd2f2d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include "mem.h" #include "vmm.h" #include @@ -28,6 +29,7 @@ g84_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 16, + .mem = {{ -1, 0, NVIF_CLASS_MEM_NV50}, nv50_mem_new, nv50_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, .kind = nv50_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h index 2986ee36bf00..c2395081e21d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h @@ -10,4 +10,9 @@ int nv04_mem_new(struct nvkm_mmu *, int, u8, u64, void *, u32, struct nvkm_memory **); int nv04_mem_map(struct nvkm_mmu *, struct nvkm_memory *, void *, u32, u64 *, u64 *, struct nvkm_vma **); + +int nv50_mem_new(struct nvkm_mmu *, int, u8, u64, void *, u32, + struct nvkm_memory **); +int nv50_mem_map(struct nvkm_mmu *, struct nvkm_memory *, void *, u32, + u64 *, u64 *, struct nvkm_vma **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c new file mode 100644 index 000000000000..46759b89fc1f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c @@ -0,0 +1,88 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "mem.h" + +#include +#include +#include + +#include +#include +#include +#include + +int +nv50_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, + u32 argc, u64 *paddr, u64 *psize, struct nvkm_vma **pvma) +{ + struct nv50_vmm_map_v0 uvmm = {}; + union { + struct nv50_mem_map_vn vn; + struct nv50_mem_map_v0 v0; + } *args = argv; + struct nvkm_device *device = mmu->subdev.device; + struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); + u64 size = nvkm_memory_size(memory); + int ret = -ENOSYS; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + uvmm.ro = args->v0.ro; + uvmm.kind = args->v0.kind; + uvmm.comp = args->v0.comp; + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + } else + return ret; + + ret = nvkm_vmm_get(bar, 12, size, pvma); + if (ret) + return ret; + + *paddr = device->func->resource_addr(device, 1) + (*pvma)->addr; + *psize = (*pvma)->size; + return nvkm_memory_map(memory, 0, bar, *pvma, &uvmm, sizeof(uvmm)); +} + +int +nv50_mem_new(struct nvkm_mmu *mmu, int type, u8 page, u64 size, + void *argv, u32 argc, struct nvkm_memory **pmemory) +{ + union { + struct nv50_mem_vn vn; + struct nv50_mem_v0 v0; + } *args = argv; + int ret = -ENOSYS; + bool contig; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + type = args->v0.bankswz ? 0x02 : 0x01; + contig = args->v0.contig; + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + type = 0x01; + contig = false; + } else + return -ENOSYS; + + return nvkm_ram_get(mmu->subdev.device, NVKM_RAM_MM_NORMAL, type, + page, size, contig, false, pmemory); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index 7af1f89fe004..8b702f42d8ce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -21,6 +21,7 @@ * * Authors: Ben Skeggs */ +#include "mem.h" #include "vmm.h" #include @@ -64,6 +65,7 @@ nv50_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 16, + .mem = {{ -1, 0, NVIF_CLASS_MEM_NV50}, nv50_mem_new, nv50_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, .kind = nv50_mmu_kind, }; -- cgit v1.2.3 From 68af607d269cd8ea74d789f256ab0a522e5dad4f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu/gf100-: type-based vram allocation and bar mapping Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + drivers/gpu/drm/nouveau/include/nvif/if900b.h | 23 ++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 3 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 3 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h | 5 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c | 94 ++++++++++++++++++++++ 12 files changed, 140 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if900b.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index a9a79ff1ef5c..8db1c973db29 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -17,6 +17,7 @@ #define NVIF_CLASS_MEM /* if000a.h */ 0x8000000a #define NVIF_CLASS_MEM_NV04 /* if000b.h */ 0x8000000b #define NVIF_CLASS_MEM_NV50 /* if500b.h */ 0x8000500b +#define NVIF_CLASS_MEM_GF100 /* if900b.h */ 0x8000900b #define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d diff --git a/drivers/gpu/drm/nouveau/include/nvif/if900b.h b/drivers/gpu/drm/nouveau/include/nvif/if900b.h new file mode 100644 index 000000000000..9b164548eea8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if900b.h @@ -0,0 +1,23 @@ +#ifndef __NVIF_IF900B_H__ +#define __NVIF_IF900B_H__ +#include "if000a.h" + +struct gf100_mem_vn { + /* nvif_mem_vX ... */ +}; + +struct gf100_mem_v0 { + /* nvif_mem_vX ... */ + __u8 version; + __u8 contig; +}; + +struct gf100_mem_map_vn { +}; + +struct gf100_mem_map_v0 { + __u8 version; + __u8 ro; + __u8 kind; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 7e8e32898194..5893d16018a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -15,6 +15,7 @@ nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/mem.o nvkm-y += nvkm/subdev/mmu/memnv04.o nvkm-y += nvkm/subdev/mmu/memnv50.o +nvkm-y += nvkm/subdev/mmu/memgf100.o nvkm-y += nvkm/subdev/mmu/vmm.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 81e9145f96a1..e054c01d00b8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -21,6 +21,7 @@ * * Authors: Ben Skeggs */ +#include "mem.h" #include "vmm.h" #include @@ -76,6 +77,7 @@ gf100_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new }, .kind = gf100_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index 95f07acaed2f..53df3dd2d104 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include "mem.h" #include "vmm.h" #include @@ -28,6 +29,7 @@ gk104_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new }, .kind = gf100_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index 18d4a321bd64..9894718fa3e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include "mem.h" #include "vmm.h" #include @@ -28,6 +29,7 @@ gk20a_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new }, .kind = gf100_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index f961f782ac9b..b9c1e5055840 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include "mem.h" #include "vmm.h" #include @@ -72,6 +73,7 @@ gm200_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm200_vmm_new }, .kind = gm200_mmu_kind, .kind_sys = true, @@ -82,6 +84,7 @@ gm200_mmu_fixed = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm200_vmm_new_fixed }, .kind = gm200_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 585fe80f87af..0060f95fc0c0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include "mem.h" #include "vmm.h" #include @@ -30,6 +31,7 @@ gm20b_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new }, .kind = gm200_mmu_kind, .kind_sys = true, @@ -40,6 +42,7 @@ gm20b_mmu_fixed = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new_fixed }, .kind = gm200_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c index 4ebb45a275ea..bd876cd864e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include "mem.h" #include "vmm.h" #include @@ -30,6 +31,7 @@ gp100_mmu = { .limit = (1ULL << 49), .dma_bits = 47, .lpg_shift = 16, + .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp100_vmm_new }, .kind = gm200_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c index e864cfe57ae6..f5be9bec5a8e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c @@ -19,6 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include "mem.h" #include "vmm.h" #include @@ -30,6 +31,7 @@ gp10b_mmu = { .limit = (1ULL << 49), .dma_bits = 47, .lpg_shift = 16, + .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp10b_vmm_new }, .kind = gm200_mmu_kind, .kind_sys = true, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h index c2395081e21d..234267e1b215 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.h @@ -15,4 +15,9 @@ int nv50_mem_new(struct nvkm_mmu *, int, u8, u64, void *, u32, struct nvkm_memory **); int nv50_mem_map(struct nvkm_mmu *, struct nvkm_memory *, void *, u32, u64 *, u64 *, struct nvkm_vma **); + +int gf100_mem_new(struct nvkm_mmu *, int, u8, u64, void *, u32, + struct nvkm_memory **); +int gf100_mem_map(struct nvkm_mmu *, struct nvkm_memory *, void *, u32, + u64 *, u64 *, struct nvkm_vma **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c new file mode 100644 index 000000000000..d9c9bee45222 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c @@ -0,0 +1,94 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "mem.h" + +#include +#include +#include + +#include +#include +#include +#include + +int +gf100_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, + u32 argc, u64 *paddr, u64 *psize, struct nvkm_vma **pvma) +{ + struct gf100_vmm_map_v0 uvmm = {}; + union { + struct gf100_mem_map_vn vn; + struct gf100_mem_map_v0 v0; + } *args = argv; + struct nvkm_device *device = mmu->subdev.device; + struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); + int ret = -ENOSYS; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + uvmm.ro = args->v0.ro; + uvmm.kind = args->v0.kind; + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + } else + return ret; + + ret = nvkm_vmm_get(bar, nvkm_memory_page(memory), + nvkm_memory_size(memory), pvma); + if (ret) + return ret; + + ret = nvkm_memory_map(memory, 0, bar, *pvma, &uvmm, sizeof(uvmm)); + if (ret) + return ret; + + *paddr = device->func->resource_addr(device, 1) + (*pvma)->addr; + *psize = (*pvma)->size; + return 0; +} + +int +gf100_mem_new(struct nvkm_mmu *mmu, int type, u8 page, u64 size, + void *argv, u32 argc, struct nvkm_memory **pmemory) +{ + union { + struct gf100_mem_vn vn; + struct gf100_mem_v0 v0; + } *args = argv; + int ret = -ENOSYS; + bool contig; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + contig = args->v0.contig; + } else + if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) { + contig = false; + } else + return ret; + + if (mmu->type[type].type & (NVKM_MEM_DISP | NVKM_MEM_COMP)) + type = NVKM_RAM_MM_NORMAL; + else + type = NVKM_RAM_MM_MIXED; + + return nvkm_ram_get(mmu->subdev.device, type, 0x01, page, + size, contig, false, pmemory); +} -- cgit v1.2.3 From eea5cf0f0170fbc54fbb3c501b0ec7cce7f68369 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: define user interfaces to mmu Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 5 + drivers/gpu/drm/nouveau/include/nvif/if0008.h | 42 ++++++ drivers/gpu/drm/nouveau/include/nvif/mmu.h | 56 ++++++++ drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 2 + drivers/gpu/drm/nouveau/nvif/Kbuild | 1 + drivers/gpu/drm/nouveau/nvif/mmu.c | 117 +++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/device/user.c | 5 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 4 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 4 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c | 148 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h | 14 ++ 24 files changed, 413 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/if0008.h create mode 100644 drivers/gpu/drm/nouveau/include/nvif/mmu.h create mode 100644 drivers/gpu/drm/nouveau/nvif/mmu.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 8db1c973db29..56aade45067d 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -14,6 +14,11 @@ #define NVIF_CLASS_SW_NV50 /* if0005.h */ -0x00000006 #define NVIF_CLASS_SW_GF100 /* if0005.h */ -0x00000007 +#define NVIF_CLASS_MMU /* if0008.h */ 0x80000008 +#define NVIF_CLASS_MMU_NV04 /* if0008.h */ 0x80000009 +#define NVIF_CLASS_MMU_NV50 /* if0008.h */ 0x80005009 +#define NVIF_CLASS_MMU_GF100 /* if0008.h */ 0x80009009 + #define NVIF_CLASS_MEM /* if000a.h */ 0x8000000a #define NVIF_CLASS_MEM_NV04 /* if000b.h */ 0x8000000b #define NVIF_CLASS_MEM_NV50 /* if500b.h */ 0x8000500b diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0008.h b/drivers/gpu/drm/nouveau/include/nvif/if0008.h new file mode 100644 index 000000000000..8450127420f5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if0008.h @@ -0,0 +1,42 @@ +#ifndef __NVIF_IF0008_H__ +#define __NVIF_IF0008_H__ +struct nvif_mmu_v0 { + __u8 version; + __u8 dmabits; + __u8 heap_nr; + __u8 type_nr; + __u16 kind_nr; +}; + +#define NVIF_MMU_V0_HEAP 0x00 +#define NVIF_MMU_V0_TYPE 0x01 +#define NVIF_MMU_V0_KIND 0x02 + +struct nvif_mmu_heap_v0 { + __u8 version; + __u8 index; + __u8 pad02[6]; + __u64 size; +}; + +struct nvif_mmu_type_v0 { + __u8 version; + __u8 index; + __u8 heap; + __u8 vram; + __u8 host; + __u8 comp; + __u8 disp; + __u8 kind; + __u8 mappable; + __u8 coherent; + __u8 uncached; +}; + +struct nvif_mmu_kind_v0 { + __u8 version; + __u8 pad01[1]; + __u16 count; + __u8 data[]; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/mmu.h b/drivers/gpu/drm/nouveau/include/nvif/mmu.h new file mode 100644 index 000000000000..c8cd5b5b0688 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/mmu.h @@ -0,0 +1,56 @@ +#ifndef __NVIF_MMU_H__ +#define __NVIF_MMU_H__ +#include + +struct nvif_mmu { + struct nvif_object object; + u8 dmabits; + u8 heap_nr; + u8 type_nr; + u16 kind_nr; + + struct { + u64 size; + } *heap; + + struct { +#define NVIF_MEM_VRAM 0x01 +#define NVIF_MEM_HOST 0x02 +#define NVIF_MEM_COMP 0x04 +#define NVIF_MEM_DISP 0x08 +#define NVIF_MEM_KIND 0x10 +#define NVIF_MEM_MAPPABLE 0x20 +#define NVIF_MEM_COHERENT 0x40 +#define NVIF_MEM_UNCACHED 0x80 + u8 type; + u8 heap; + } *type; + + u8 *kind; +}; + +int nvif_mmu_init(struct nvif_object *, s32 oclass, struct nvif_mmu *); +void nvif_mmu_fini(struct nvif_mmu *); + +static inline bool +nvif_mmu_kind_valid(struct nvif_mmu *mmu, u8 kind) +{ + const u8 invalid = mmu->kind_nr - 1; + if (kind) { + if (kind >= mmu->kind_nr || mmu->kind[kind] == invalid) + return false; + } + return true; +} + +static inline int +nvif_mmu_type(struct nvif_mmu *mmu, u8 mask) +{ + int i; + for (i = 0; i < mmu->type_nr; i++) { + if ((mmu->type[i].type & mask) == mask) + return i; + } + return -EINVAL; +} +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 11a169d3ed8c..c58394baeb7c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -134,6 +134,8 @@ struct nvkm_mmu { struct mutex mutex; struct list_head list; } ptc, ptp; + + struct nvkm_device_oclass user; }; int nv04_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index 067b5e9f5ec1..1f23a08cf701 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -2,4 +2,5 @@ nvif-y := nvif/object.o nvif-y += nvif/client.o nvif-y += nvif/device.o nvif-y += nvif/driver.o +nvif-y += nvif/mmu.o nvif-y += nvif/notify.o diff --git a/drivers/gpu/drm/nouveau/nvif/mmu.c b/drivers/gpu/drm/nouveau/nvif/mmu.c new file mode 100644 index 000000000000..15d0dcbf7ab4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/mmu.c @@ -0,0 +1,117 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include + +#include +#include + +void +nvif_mmu_fini(struct nvif_mmu *mmu) +{ + kfree(mmu->kind); + kfree(mmu->type); + kfree(mmu->heap); + nvif_object_fini(&mmu->object); +} + +int +nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu) +{ + struct nvif_mmu_v0 args; + int ret, i; + + args.version = 0; + mmu->heap = NULL; + mmu->type = NULL; + mmu->kind = NULL; + + ret = nvif_object_init(parent, 0, oclass, &args, sizeof(args), + &mmu->object); + if (ret) + goto done; + + mmu->dmabits = args.dmabits; + mmu->heap_nr = args.heap_nr; + mmu->type_nr = args.type_nr; + mmu->kind_nr = args.kind_nr; + + mmu->heap = kmalloc(sizeof(*mmu->heap) * mmu->heap_nr, GFP_KERNEL); + mmu->type = kmalloc(sizeof(*mmu->type) * mmu->type_nr, GFP_KERNEL); + if (ret = -ENOMEM, !mmu->heap || !mmu->type) + goto done; + + mmu->kind = kmalloc(sizeof(*mmu->kind) * mmu->kind_nr, GFP_KERNEL); + if (!mmu->kind && mmu->kind_nr) + goto done; + + for (i = 0; i < mmu->heap_nr; i++) { + struct nvif_mmu_heap_v0 args = { .index = i }; + + ret = nvif_object_mthd(&mmu->object, NVIF_MMU_V0_HEAP, + &args, sizeof(args)); + if (ret) + goto done; + + mmu->heap[i].size = args.size; + } + + for (i = 0; i < mmu->type_nr; i++) { + struct nvif_mmu_type_v0 args = { .index = i }; + + ret = nvif_object_mthd(&mmu->object, NVIF_MMU_V0_TYPE, + &args, sizeof(args)); + if (ret) + goto done; + + mmu->type[i].type = 0; + if (args.vram) mmu->type[i].type |= NVIF_MEM_VRAM; + if (args.host) mmu->type[i].type |= NVIF_MEM_HOST; + if (args.comp) mmu->type[i].type |= NVIF_MEM_COMP; + if (args.disp) mmu->type[i].type |= NVIF_MEM_DISP; + if (args.kind ) mmu->type[i].type |= NVIF_MEM_KIND; + if (args.mappable) mmu->type[i].type |= NVIF_MEM_MAPPABLE; + if (args.coherent) mmu->type[i].type |= NVIF_MEM_COHERENT; + if (args.uncached) mmu->type[i].type |= NVIF_MEM_UNCACHED; + mmu->type[i].heap = args.heap; + } + + if (mmu->kind_nr) { + struct nvif_mmu_kind_v0 *kind; + u32 argc = sizeof(*kind) + sizeof(*kind->data) * mmu->kind_nr; + + if (ret = -ENOMEM, !(kind = kmalloc(argc, GFP_KERNEL))) + goto done; + kind->version = 0; + kind->count = mmu->kind_nr; + + ret = nvif_object_mthd(&mmu->object, NVIF_MMU_V0_KIND, + kind, argc); + if (ret == 0) + memcpy(mmu->kind, kind->data, kind->count); + kfree(kind); + } + +done: + if (ret) + nvif_mmu_fini(mmu); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index e9b90e40f274..17adcb4e8854 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -294,6 +294,11 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index, if (!sclass) { switch (index) { case 0: sclass = &nvkm_control_oclass; break; + case 1: + if (!device->mmu) + return -EINVAL; + sclass = &device->mmu->user; + break; default: return -EINVAL; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 5893d16018a7..0c2fa272721f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -29,3 +29,5 @@ nvkm-y += nvkm/subdev/mmu/vmmgm200.o nvkm-y += nvkm/subdev/mmu/vmmgm20b.o nvkm-y += nvkm/subdev/mmu/vmmgp100.o nvkm-y += nvkm/subdev/mmu/vmmgp10b.o + +nvkm-y += nvkm/subdev/mmu/ummu.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index be600049f221..e0fa0cae7960 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "priv.h" +#include "ummu.h" #include "vmm.h" #include @@ -615,6 +615,8 @@ nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device, mmu->dma_bits = func->dma_bits; mmu->lpg_shift = func->lpg_shift; nvkm_mmu_ptc_init(mmu); + mmu->user.ctor = nvkm_ummu_new; + mmu->user.base = func->mmu.user; } int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index f5d061cd2f2d..e53f9beda7e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -29,6 +29,7 @@ g84_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 16, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV50}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_NV50}, nv50_mem_new, nv50_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, .kind = nv50_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index e054c01d00b8..85d237d3963c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -77,6 +77,7 @@ gf100_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new }, .kind = gf100_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index 53df3dd2d104..30c0217ac807 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -29,6 +29,7 @@ gk104_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new }, .kind = gf100_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index 9894718fa3e0..b7bff4369d30 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -29,6 +29,7 @@ gk20a_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new }, .kind = gf100_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index b9c1e5055840..3cabeabbcea6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -73,6 +73,7 @@ gm200_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm200_vmm_new }, .kind = gm200_mmu_kind, @@ -84,6 +85,7 @@ gm200_mmu_fixed = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm200_vmm_new_fixed }, .kind = gm200_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 0060f95fc0c0..802652539d9a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -31,6 +31,7 @@ gm20b_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new }, .kind = gm200_mmu_kind, @@ -42,6 +43,7 @@ gm20b_mmu_fixed = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 17, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new_fixed }, .kind = gm200_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c index bd876cd864e0..92fc18eec147 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -31,6 +31,7 @@ gp100_mmu = { .limit = (1ULL << 49), .dma_bits = 47, .lpg_shift = 16, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp100_vmm_new }, .kind = gm200_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c index f5be9bec5a8e..e1b0f82e2e05 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c @@ -31,6 +31,7 @@ gp10b_mmu = { .limit = (1ULL << 49), .dma_bits = 47, .lpg_shift = 16, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp10b_vmm_new }, .kind = gm200_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 94db229bd929..7505a7213156 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -33,6 +33,7 @@ nv04_mmu = { .limit = NV04_PDMA_SIZE, .dma_bits = 32, .lpg_shift = 12, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV04}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv04_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c index caee0858f522..8e683a0f796d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c @@ -45,6 +45,7 @@ nv41_mmu = { .limit = NV41_GART_SIZE, .dma_bits = 39, .lpg_shift = 12, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV04}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv41_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c index 5f15ec58bbd4..2fdc4c787b7a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c @@ -60,6 +60,7 @@ nv44_mmu = { .limit = NV44_GART_SIZE, .dma_bits = 39, .lpg_shift = 12, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV04}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv44_vmm_new, true }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index 8b702f42d8ce..334f7fb460ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -65,6 +65,7 @@ nv50_mmu = { .limit = (1ULL << 40), .dma_bits = 40, .lpg_shift = 16, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV50}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_NV50}, nv50_mem_new, nv50_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, .kind = nv50_mmu_kind, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 00869fcc5751..9d7ff166e505 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -15,6 +15,10 @@ struct nvkm_mmu_func { u8 dma_bits; u8 lpg_shift; + struct { + struct nvkm_sclass user; + } mmu; + struct { struct nvkm_sclass user; int (*vram)(struct nvkm_mmu *, int type, u8 page, u64 size, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c new file mode 100644 index 000000000000..eba03d6c7b64 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c @@ -0,0 +1,148 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "ummu.h" + +#include +#include + +static int +nvkm_ummu_heap(struct nvkm_ummu *ummu, void *argv, u32 argc) +{ + struct nvkm_mmu *mmu = ummu->mmu; + union { + struct nvif_mmu_heap_v0 v0; + } *args = argv; + int ret = -ENOSYS; + u8 index; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + if ((index = args->v0.index) >= mmu->heap_nr) + return -EINVAL; + args->v0.size = mmu->heap[index].size; + } else + return ret; + + return 0; +} + +static int +nvkm_ummu_type(struct nvkm_ummu *ummu, void *argv, u32 argc) +{ + struct nvkm_mmu *mmu = ummu->mmu; + union { + struct nvif_mmu_type_v0 v0; + } *args = argv; + int ret = -ENOSYS; + u8 type, index; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + if ((index = args->v0.index) >= mmu->type_nr) + return -EINVAL; + type = mmu->type[index].type; + args->v0.heap = mmu->type[index].heap; + args->v0.vram = !!(type & NVKM_MEM_VRAM); + args->v0.host = !!(type & NVKM_MEM_HOST); + args->v0.comp = !!(type & NVKM_MEM_COMP); + args->v0.disp = !!(type & NVKM_MEM_DISP); + args->v0.kind = !!(type & NVKM_MEM_KIND); + args->v0.mappable = !!(type & NVKM_MEM_MAPPABLE); + args->v0.coherent = !!(type & NVKM_MEM_COHERENT); + args->v0.uncached = !!(type & NVKM_MEM_UNCACHED); + } else + return ret; + + return 0; +} + +static int +nvkm_ummu_kind(struct nvkm_ummu *ummu, void *argv, u32 argc) +{ + struct nvkm_mmu *mmu = ummu->mmu; + union { + struct nvif_mmu_kind_v0 v0; + } *args = argv; + const u8 *kind = NULL; + int ret = -ENOSYS, count = 0; + + if (mmu->func->kind) + kind = mmu->func->kind(mmu, &count); + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, true))) { + if (argc != args->v0.count * sizeof(*args->v0.data)) + return -EINVAL; + if (args->v0.count > count) + return -EINVAL; + memcpy(args->v0.data, kind, args->v0.count); + } else + return ret; + + return 0; +} + +static int +nvkm_ummu_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc) +{ + struct nvkm_ummu *ummu = nvkm_ummu(object); + switch (mthd) { + case NVIF_MMU_V0_HEAP: return nvkm_ummu_heap(ummu, argv, argc); + case NVIF_MMU_V0_TYPE: return nvkm_ummu_type(ummu, argv, argc); + case NVIF_MMU_V0_KIND: return nvkm_ummu_kind(ummu, argv, argc); + default: + break; + } + return -EINVAL; +} + +static const struct nvkm_object_func +nvkm_ummu = { + .mthd = nvkm_ummu_mthd, +}; + +int +nvkm_ummu_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, + void *argv, u32 argc, struct nvkm_object **pobject) +{ + union { + struct nvif_mmu_v0 v0; + } *args = argv; + struct nvkm_mmu *mmu = device->mmu; + struct nvkm_ummu *ummu; + int ret = -ENOSYS, kinds = 0; + + if (mmu->func->kind) + mmu->func->kind(mmu, &kinds); + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + args->v0.dmabits = mmu->dma_bits; + args->v0.heap_nr = mmu->heap_nr; + args->v0.type_nr = mmu->type_nr; + args->v0.kind_nr = kinds; + } else + return ret; + + if (!(ummu = kzalloc(sizeof(*ummu), GFP_KERNEL))) + return -ENOMEM; + nvkm_object_ctor(&nvkm_ummu, oclass, &ummu->object); + ummu->mmu = mmu; + *pobject = &ummu->object; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h new file mode 100644 index 000000000000..0cd510dcfc68 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h @@ -0,0 +1,14 @@ +#ifndef __NVKM_UMMU_H__ +#define __NVKM_UMMU_H__ +#define nvkm_ummu(p) container_of((p), struct nvkm_ummu, object) +#include +#include "priv.h" + +struct nvkm_ummu { + struct nvkm_object object; + struct nvkm_mmu *mmu; +}; + +int nvkm_ummu_new(struct nvkm_device *, const struct nvkm_oclass *, + void *argv, u32 argc, struct nvkm_object **); +#endif -- cgit v1.2.3 From c83c4097eba8950bc7028f0846c21f9718dd8697 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: define user interfaces to mmu memory allocation Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/if000a.h | 9 + drivers/gpu/drm/nouveau/include/nvif/mem.h | 18 ++ drivers/gpu/drm/nouveau/include/nvkm/core/client.h | 3 + drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + drivers/gpu/drm/nouveau/nvif/Kbuild | 1 + drivers/gpu/drm/nouveau/nvif/mem.c | 88 ++++++++++ drivers/gpu/drm/nouveau/nvkm/core/client.c | 2 + drivers/gpu/drm/nouveau/nvkm/core/ioctl.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c | 192 +++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.h | 26 +++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c | 21 +++ 12 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/mem.h create mode 100644 drivers/gpu/drm/nouveau/nvif/mem.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000a.h b/drivers/gpu/drm/nouveau/include/nvif/if000a.h index e6e8764abf4a..88d0938fbd5a 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if000a.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if000a.h @@ -1,5 +1,14 @@ #ifndef __NVIF_IF000A_H__ #define __NVIF_IF000A_H__ +struct nvif_mem_v0 { + __u8 version; + __u8 type; + __u8 page; + __u8 pad03[5]; + __u64 size; + __u64 addr; + __u8 data[]; +}; struct nvif_mem_ram_vn { }; diff --git a/drivers/gpu/drm/nouveau/include/nvif/mem.h b/drivers/gpu/drm/nouveau/include/nvif/mem.h new file mode 100644 index 000000000000..b542fe38398e --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/mem.h @@ -0,0 +1,18 @@ +#ifndef __NVIF_MEM_H__ +#define __NVIF_MEM_H__ +#include "mmu.h" + +struct nvif_mem { + struct nvif_object object; + u8 type; + u8 page; + u64 addr; + u64 size; +}; + +int nvif_mem_init_type(struct nvif_mmu *mmu, s32 oclass, int type, u8 page, + u64 size, void *argv, u32 argc, struct nvif_mem *); +int nvif_mem_init(struct nvif_mmu *mmu, s32 oclass, u8 type, u8 page, + u64 size, void *argv, u32 argc, struct nvif_mem *); +void nvif_mem_fini(struct nvif_mem *); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h index e876634da10a..fa58efb0d42a 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h @@ -17,6 +17,9 @@ struct nvkm_client { int (*ntfy)(const void *, u32, const void *, u32); struct nvkm_vm *vm; + + struct list_head umem; + spinlock_t lock; }; int nvkm_client_new(const char *name, u64 device, const char *cfg, diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index c58394baeb7c..0de5f8b7096a 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -98,6 +98,7 @@ int nvkm_vmm_map(struct nvkm_vmm *, struct nvkm_vma *, void *argv, u32 argc, struct nvkm_vmm_map *); void nvkm_vmm_unmap(struct nvkm_vmm *, struct nvkm_vma *); +struct nvkm_memory *nvkm_umem_search(struct nvkm_client *, u64); struct nvkm_vmm *nvkm_uvmm_search(struct nvkm_client *, u64 handle); struct nvkm_mmu { diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index 1f23a08cf701..2e0a90b4dda8 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -2,5 +2,6 @@ nvif-y := nvif/object.o nvif-y += nvif/client.o nvif-y += nvif/device.o nvif-y += nvif/driver.o +nvif-y += nvif/mem.o nvif-y += nvif/mmu.o nvif-y += nvif/notify.o diff --git a/drivers/gpu/drm/nouveau/nvif/mem.c b/drivers/gpu/drm/nouveau/nvif/mem.c new file mode 100644 index 000000000000..0f9382c60145 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/mem.c @@ -0,0 +1,88 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include +#include + +#include + +void +nvif_mem_fini(struct nvif_mem *mem) +{ + nvif_object_fini(&mem->object); +} + +int +nvif_mem_init_type(struct nvif_mmu *mmu, s32 oclass, int type, u8 page, + u64 size, void *argv, u32 argc, struct nvif_mem *mem) +{ + struct nvif_mem_v0 *args; + u8 stack[128]; + int ret; + + mem->object.client = NULL; + if (type < 0) + return -EINVAL; + + if (sizeof(*args) + argc > sizeof(stack)) { + if (!(args = kmalloc(sizeof(*args) + argc, GFP_KERNEL))) + return -ENOMEM; + } else { + args = (void *)stack; + } + args->version = 0; + args->type = type; + args->page = page; + args->size = size; + memcpy(args->data, argv, argc); + + ret = nvif_object_init(&mmu->object, 0, oclass, args, + sizeof(*args) + argc, &mem->object); + if (ret == 0) { + mem->type = mmu->type[type].type; + mem->page = args->page; + mem->addr = args->addr; + mem->size = args->size; + } + + if (args != (void *)stack) + kfree(args); + return ret; + +} + +int +nvif_mem_init(struct nvif_mmu *mmu, s32 oclass, u8 type, u8 page, + u64 size, void *argv, u32 argc, struct nvif_mem *mem) +{ + int ret = -EINVAL, i; + + mem->object.client = NULL; + + for (i = 0; ret && i < mmu->type_nr; i++) { + if ((mmu->type[i].type & type) == type) { + ret = nvif_mem_init_type(mmu, oclass, i, page, size, + argv, argc, mem); + } + } + + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c index 0d3a896892b4..ac671202919e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c @@ -301,5 +301,7 @@ nvkm_client_new(const char *name, u64 device, const char *cfg, client->debug = nvkm_dbgopt(dbg, "CLIENT"); client->objroot = RB_ROOT; client->ntfy = ntfy; + INIT_LIST_HEAD(&client->umem); + spin_lock_init(&client->lock); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c index a28018ee5b19..d777df5a64e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c @@ -53,7 +53,7 @@ nvkm_ioctl_sclass(struct nvkm_client *client, union { struct nvif_ioctl_sclass_v0 v0; } *args = data; - struct nvkm_oclass oclass; + struct nvkm_oclass oclass = { .client = client }; int ret = -ENOSYS, i = 0; nvif_ioctl(object, "sclass size %d\n", size); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 0c2fa272721f..34f5aae8f3a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -30,4 +30,5 @@ nvkm-y += nvkm/subdev/mmu/vmmgm20b.o nvkm-y += nvkm/subdev/mmu/vmmgp100.o nvkm-y += nvkm/subdev/mmu/vmmgp10b.o +nvkm-y += nvkm/subdev/mmu/umem.o nvkm-y += nvkm/subdev/mmu/ummu.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c new file mode 100644 index 000000000000..fac2f9a45ea6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c @@ -0,0 +1,192 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "umem.h" +#include "ummu.h" + +#include +#include +#include + +#include +#include +#include + +static const struct nvkm_object_func nvkm_umem; +struct nvkm_memory * +nvkm_umem_search(struct nvkm_client *client, u64 handle) +{ + struct nvkm_client *master = client->object.client; + struct nvkm_memory *memory = NULL; + struct nvkm_object *object; + struct nvkm_umem *umem; + + object = nvkm_object_search(client, handle, &nvkm_umem); + if (IS_ERR(object)) { + if (client->super && client != master) { + spin_lock(&master->lock); + list_for_each_entry(umem, &master->umem, head) { + if (umem->object.object == handle) { + memory = nvkm_memory_ref(umem->memory); + break; + } + } + spin_unlock(&master->lock); + } + } else { + umem = nvkm_umem(object); + if (!umem->priv || client->super) + memory = nvkm_memory_ref(umem->memory); + } + + return memory ? memory : ERR_PTR(-ENOENT); +} + +static int +nvkm_umem_unmap(struct nvkm_object *object) +{ + struct nvkm_umem *umem = nvkm_umem(object); + + if (!umem->map) + return -EEXIST; + + if (umem->io) { + if (!IS_ERR(umem->bar)) { + struct nvkm_device *device = umem->mmu->subdev.device; + nvkm_vmm_put(nvkm_bar_bar1_vmm(device), &umem->bar); + } else { + umem->bar = NULL; + } + } else { + vunmap(umem->map); + umem->map = NULL; + } + + return 0; +} + +static int +nvkm_umem_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *handle, u64 *length) +{ + struct nvkm_umem *umem = nvkm_umem(object); + struct nvkm_mmu *mmu = umem->mmu; + + if (!umem->mappable) + return -EINVAL; + if (umem->map) + return -EEXIST; + + if ((umem->type & NVKM_MEM_HOST) && !argc) { + int ret = nvkm_mem_map_host(umem->memory, &umem->map); + if (ret) + return ret; + + *handle = (unsigned long)(void *)umem->map; + *length = nvkm_memory_size(umem->memory); + *type = NVKM_OBJECT_MAP_VA; + return 0; + } else + if ((umem->type & NVKM_MEM_VRAM) || + (umem->type & NVKM_MEM_KIND)) { + int ret = mmu->func->mem.umap(mmu, umem->memory, argv, argc, + handle, length, &umem->bar); + if (ret) + return ret; + + *type = NVKM_OBJECT_MAP_IO; + } else { + return -EINVAL; + } + + umem->io = (*type == NVKM_OBJECT_MAP_IO); + return 0; +} + +static void * +nvkm_umem_dtor(struct nvkm_object *object) +{ + struct nvkm_umem *umem = nvkm_umem(object); + spin_lock(&umem->object.client->lock); + list_del_init(&umem->head); + spin_unlock(&umem->object.client->lock); + nvkm_memory_unref(&umem->memory); + return umem; +} + +static const struct nvkm_object_func +nvkm_umem = { + .dtor = nvkm_umem_dtor, + .map = nvkm_umem_map, + .unmap = nvkm_umem_unmap, +}; + +int +nvkm_umem_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + struct nvkm_mmu *mmu = nvkm_ummu(oclass->parent)->mmu; + union { + struct nvif_mem_v0 v0; + } *args = argv; + struct nvkm_umem *umem; + int type, ret = -ENOSYS; + u8 page; + u64 size; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, true))) { + type = args->v0.type; + page = args->v0.page; + size = args->v0.size; + } else + return ret; + + if (type >= mmu->type_nr) + return -EINVAL; + + if (!(umem = kzalloc(sizeof(*umem), GFP_KERNEL))) + return -ENOMEM; + nvkm_object_ctor(&nvkm_umem, oclass, &umem->object); + umem->mmu = mmu; + umem->type = mmu->type[type].type; + umem->priv = oclass->client->super; + INIT_LIST_HEAD(&umem->head); + *pobject = &umem->object; + + if (mmu->type[type].type & NVKM_MEM_MAPPABLE) { + page = max_t(u8, page, PAGE_SHIFT); + umem->mappable = true; + } + + ret = nvkm_mem_new_type(mmu, type, page, size, argv, argc, + &umem->memory); + if (ret) + return ret; + + spin_lock(&umem->object.client->lock); + list_add(&umem->head, &umem->object.client->umem); + spin_unlock(&umem->object.client->lock); + + args->v0.page = nvkm_memory_page(umem->memory); + args->v0.addr = nvkm_memory_addr(umem->memory); + args->v0.size = nvkm_memory_size(umem->memory); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.h new file mode 100644 index 000000000000..85cf692d620a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.h @@ -0,0 +1,26 @@ +#ifndef __NVKM_UMEM_H__ +#define __NVKM_UMEM_H__ +#define nvkm_umem(p) container_of((p), struct nvkm_umem, object) +#include +#include "mem.h" + +struct nvkm_umem { + struct nvkm_object object; + struct nvkm_mmu *mmu; + u8 type:8; + bool priv:1; + bool mappable:1; + bool io:1; + + struct nvkm_memory *memory; + struct list_head head; + + union { + struct nvkm_vma *bar; + void *map; + }; +}; + +int nvkm_umem_new(const struct nvkm_oclass *, void *argv, u32 argc, + struct nvkm_object **); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c index eba03d6c7b64..ed192ab3728b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c @@ -20,10 +20,30 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include "ummu.h" +#include "umem.h" + +#include #include #include +static int +nvkm_ummu_sclass(struct nvkm_object *object, int index, + struct nvkm_oclass *oclass) +{ + struct nvkm_mmu *mmu = nvkm_ummu(object)->mmu; + + if (mmu->func->mem.user.oclass && oclass->client->super) { + if (index-- == 0) { + oclass->base = mmu->func->mem.user; + oclass->ctor = nvkm_umem_new; + return 0; + } + } + + return -EINVAL; +} + static int nvkm_ummu_heap(struct nvkm_ummu *ummu, void *argv, u32 argc) { @@ -115,6 +135,7 @@ nvkm_ummu_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc) static const struct nvkm_object_func nvkm_ummu = { .mthd = nvkm_ummu_mthd, + .sclass = nvkm_ummu_sclass, }; int -- cgit v1.2.3 From 920d2b5ef2157e169d85cb778feca558c56b8370 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/mmu: define user interfaces to mmu vmm opertaions Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/if000c.h | 61 +++++ drivers/gpu/drm/nouveau/include/nvif/vmm.h | 42 +++ drivers/gpu/drm/nouveau/nvif/Kbuild | 1 + drivers/gpu/drm/nouveau/nvif/vmm.c | 167 ++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c | 9 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c | 352 +++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h | 14 + 8 files changed, 647 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/vmm.h create mode 100644 drivers/gpu/drm/nouveau/nvif/vmm.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000c.h b/drivers/gpu/drm/nouveau/include/nvif/if000c.h index 6363e22f9dcc..2928ecd989ad 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if000c.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if000c.h @@ -1,3 +1,64 @@ #ifndef __NVIF_IF000C_H__ #define __NVIF_IF000C_H__ +struct nvif_vmm_v0 { + __u8 version; + __u8 page_nr; + __u8 pad02[6]; + __u64 addr; + __u64 size; + __u8 data[]; +}; + +#define NVIF_VMM_V0_PAGE 0x00 +#define NVIF_VMM_V0_GET 0x01 +#define NVIF_VMM_V0_PUT 0x02 +#define NVIF_VMM_V0_MAP 0x03 +#define NVIF_VMM_V0_UNMAP 0x04 + +struct nvif_vmm_page_v0 { + __u8 version; + __u8 index; + __u8 shift; + __u8 sparse; + __u8 vram; + __u8 host; + __u8 comp; + __u8 pad07[1]; +}; + +struct nvif_vmm_get_v0 { + __u8 version; +#define NVIF_VMM_GET_V0_ADDR 0x00 +#define NVIF_VMM_GET_V0_PTES 0x01 +#define NVIF_VMM_GET_V0_LAZY 0x02 + __u8 type; + __u8 sparse; + __u8 page; + __u8 align; + __u8 pad05[3]; + __u64 size; + __u64 addr; +}; + +struct nvif_vmm_put_v0 { + __u8 version; + __u8 pad01[7]; + __u64 addr; +}; + +struct nvif_vmm_map_v0 { + __u8 version; + __u8 pad01[7]; + __u64 addr; + __u64 size; + __u64 memory; + __u64 offset; + __u8 data[]; +}; + +struct nvif_vmm_unmap_v0 { + __u8 version; + __u8 pad01[7]; + __u64 addr; +}; #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/vmm.h b/drivers/gpu/drm/nouveau/include/nvif/vmm.h new file mode 100644 index 000000000000..c5db8a2e82df --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/vmm.h @@ -0,0 +1,42 @@ +#ifndef __NVIF_VMM_H__ +#define __NVIF_VMM_H__ +#include +struct nvif_mem; +struct nvif_mmu; + +enum nvif_vmm_get { + ADDR, + PTES, + LAZY +}; + +struct nvif_vma { + u64 addr; + u64 size; +}; + +struct nvif_vmm { + struct nvif_object object; + u64 start; + u64 limit; + + struct { + u8 shift; + bool sparse:1; + bool vram:1; + bool host:1; + bool comp:1; + } *page; + int page_nr; +}; + +int nvif_vmm_init(struct nvif_mmu *, s32 oclass, u64 addr, u64 size, + void *argv, u32 argc, struct nvif_vmm *); +void nvif_vmm_fini(struct nvif_vmm *); +int nvif_vmm_get(struct nvif_vmm *, enum nvif_vmm_get, bool sparse, + u8 page, u8 align, u64 size, struct nvif_vma *); +void nvif_vmm_put(struct nvif_vmm *, struct nvif_vma *); +int nvif_vmm_map(struct nvif_vmm *, u64 addr, u64 size, void *argv, u32 argc, + struct nvif_mem *, u64 offset); +int nvif_vmm_unmap(struct nvif_vmm *, u64); +#endif diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index 2e0a90b4dda8..f1675a4ab6fa 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -5,3 +5,4 @@ nvif-y += nvif/driver.o nvif-y += nvif/mem.o nvif-y += nvif/mmu.o nvif-y += nvif/notify.o +nvif-y += nvif/vmm.o diff --git a/drivers/gpu/drm/nouveau/nvif/vmm.c b/drivers/gpu/drm/nouveau/nvif/vmm.c new file mode 100644 index 000000000000..31cdb2d2e1ff --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/vmm.c @@ -0,0 +1,167 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include +#include + +#include + +int +nvif_vmm_unmap(struct nvif_vmm *vmm, u64 addr) +{ + return nvif_object_mthd(&vmm->object, NVIF_VMM_V0_UNMAP, + &(struct nvif_vmm_unmap_v0) { .addr = addr }, + sizeof(struct nvif_vmm_unmap_v0)); +} + +int +nvif_vmm_map(struct nvif_vmm *vmm, u64 addr, u64 size, void *argv, u32 argc, + struct nvif_mem *mem, u64 offset) +{ + struct nvif_vmm_map_v0 *args; + u8 stack[16]; + int ret; + + if (sizeof(*args) + argc > sizeof(stack)) { + if (!(args = kmalloc(sizeof(*args) + argc, GFP_KERNEL))) + return -ENOMEM; + } else { + args = (void *)stack; + } + + args->version = 0; + args->addr = addr; + args->size = size; + args->memory = nvif_handle(&mem->object); + args->offset = offset; + memcpy(args->data, argv, argc); + + ret = nvif_object_mthd(&vmm->object, NVIF_VMM_V0_MAP, + args, sizeof(*args) + argc); + if (args != (void *)stack) + kfree(args); + return ret; +} + +void +nvif_vmm_put(struct nvif_vmm *vmm, struct nvif_vma *vma) +{ + if (vma->size) { + WARN_ON(nvif_object_mthd(&vmm->object, NVIF_VMM_V0_PUT, + &(struct nvif_vmm_put_v0) { + .addr = vma->addr, + }, sizeof(struct nvif_vmm_put_v0))); + vma->size = 0; + } +} + +int +nvif_vmm_get(struct nvif_vmm *vmm, enum nvif_vmm_get type, bool sparse, + u8 page, u8 align, u64 size, struct nvif_vma *vma) +{ + struct nvif_vmm_get_v0 args; + int ret; + + args.version = vma->size = 0; + args.sparse = sparse; + args.page = page; + args.align = align; + args.size = size; + + switch (type) { + case ADDR: args.type = NVIF_VMM_GET_V0_ADDR; break; + case PTES: args.type = NVIF_VMM_GET_V0_PTES; break; + case LAZY: args.type = NVIF_VMM_GET_V0_LAZY; break; + default: + WARN_ON(1); + return -EINVAL; + } + + ret = nvif_object_mthd(&vmm->object, NVIF_VMM_V0_GET, + &args, sizeof(args)); + if (ret == 0) { + vma->addr = args.addr; + vma->size = args.size; + } + return ret; +} + +void +nvif_vmm_fini(struct nvif_vmm *vmm) +{ + kfree(vmm->page); + nvif_object_fini(&vmm->object); +} + +int +nvif_vmm_init(struct nvif_mmu *mmu, s32 oclass, u64 addr, u64 size, + void *argv, u32 argc, struct nvif_vmm *vmm) +{ + struct nvif_vmm_v0 *args; + u32 argn = sizeof(*args) + argc; + int ret = -ENOSYS, i; + + vmm->object.client = NULL; + vmm->page = NULL; + + if (!(args = kmalloc(argn, GFP_KERNEL))) + return -ENOMEM; + args->version = 0; + args->addr = addr; + args->size = size; + memcpy(args->data, argv, argc); + + ret = nvif_object_init(&mmu->object, 0, oclass, args, argn, + &vmm->object); + if (ret) + goto done; + + vmm->start = args->addr; + vmm->limit = args->size; + + vmm->page_nr = args->page_nr; + vmm->page = kmalloc(sizeof(*vmm->page) * vmm->page_nr, GFP_KERNEL); + if (!vmm->page) { + ret = -ENOMEM; + goto done; + } + + for (i = 0; i < vmm->page_nr; i++) { + struct nvif_vmm_page_v0 args = { .index = i }; + + ret = nvif_object_mthd(&vmm->object, NVIF_VMM_V0_PAGE, + &args, sizeof(args)); + if (ret) + break; + + vmm->page[i].shift = args.shift; + vmm->page[i].sparse = args.sparse; + vmm->page[i].vram = args.vram; + vmm->page[i].host = args.host; + vmm->page[i].comp = args.comp; + } + +done: + if (ret) + nvif_vmm_fini(vmm); + kfree(args); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 34f5aae8f3a1..352a65f9371c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -32,3 +32,4 @@ nvkm-y += nvkm/subdev/mmu/vmmgp10b.o nvkm-y += nvkm/subdev/mmu/umem.o nvkm-y += nvkm/subdev/mmu/ummu.o +nvkm-y += nvkm/subdev/mmu/uvmm.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c index ed192ab3728b..353f10f92b77 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c @@ -21,6 +21,7 @@ */ #include "ummu.h" #include "umem.h" +#include "uvmm.h" #include @@ -41,6 +42,14 @@ nvkm_ummu_sclass(struct nvkm_object *object, int index, } } + if (mmu->func->vmm.user.oclass) { + if (index-- == 0) { + oclass->base = mmu->func->vmm.user; + oclass->ctor = nvkm_uvmm_new; + return 0; + } + } + return -EINVAL; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c new file mode 100644 index 000000000000..fa81d0c1ba41 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c @@ -0,0 +1,352 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "uvmm.h" +#include "umem.h" +#include "ummu.h" + +#include +#include + +#include +#include + +static const struct nvkm_object_func nvkm_uvmm; +struct nvkm_vmm * +nvkm_uvmm_search(struct nvkm_client *client, u64 handle) +{ + struct nvkm_object *object; + + object = nvkm_object_search(client, handle, &nvkm_uvmm); + if (IS_ERR(object)) + return (void *)object; + + return nvkm_uvmm(object)->vmm; +} + +static int +nvkm_uvmm_mthd_unmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc) +{ + struct nvkm_client *client = uvmm->object.client; + union { + struct nvif_vmm_unmap_v0 v0; + } *args = argv; + struct nvkm_vmm *vmm = uvmm->vmm; + struct nvkm_vma *vma; + int ret = -ENOSYS; + u64 addr; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + addr = args->v0.addr; + } else + return ret; + + mutex_lock(&vmm->mutex); + vma = nvkm_vmm_node_search(vmm, addr); + if (ret = -ENOENT, !vma || vma->addr != addr) { + VMM_DEBUG(vmm, "lookup %016llx: %016llx", + addr, vma ? vma->addr : ~0ULL); + goto done; + } + + if (ret = -ENOENT, (!vma->user && !client->super) || vma->busy) { + VMM_DEBUG(vmm, "denied %016llx: %d %d %d", addr, + vma->user, !client->super, vma->busy); + goto done; + } + + if (ret = -EINVAL, !vma->memory) { + VMM_DEBUG(vmm, "unmapped"); + goto done; + } + + nvkm_vmm_unmap_locked(vmm, vma); + ret = 0; +done: + mutex_unlock(&vmm->mutex); + return ret; +} + +static int +nvkm_uvmm_mthd_map(struct nvkm_uvmm *uvmm, void *argv, u32 argc) +{ + struct nvkm_client *client = uvmm->object.client; + union { + struct nvif_vmm_map_v0 v0; + } *args = argv; + u64 addr, size, handle, offset; + struct nvkm_vmm *vmm = uvmm->vmm; + struct nvkm_vma *vma; + struct nvkm_memory *memory; + int ret = -ENOSYS; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, true))) { + addr = args->v0.addr; + size = args->v0.size; + handle = args->v0.memory; + offset = args->v0.offset; + } else + return ret; + + if (IS_ERR((memory = nvkm_umem_search(client, handle)))) { + VMM_DEBUG(vmm, "memory %016llx %ld\n", handle, PTR_ERR(memory)); + return PTR_ERR(memory); + } + + mutex_lock(&vmm->mutex); + if (ret = -ENOENT, !(vma = nvkm_vmm_node_search(vmm, addr))) { + VMM_DEBUG(vmm, "lookup %016llx", addr); + goto fail; + } + + if (ret = -ENOENT, (!vma->user && !client->super) || vma->busy) { + VMM_DEBUG(vmm, "denied %016llx: %d %d %d", addr, + vma->user, !client->super, vma->busy); + goto fail; + } + + if (ret = -EINVAL, vma->addr != addr || vma->size != size) { + if (addr + size > vma->addr + vma->size || vma->memory || + (vma->refd == NVKM_VMA_PAGE_NONE && !vma->mapref)) { + VMM_DEBUG(vmm, "split %d %d %d " + "%016llx %016llx %016llx %016llx", + !!vma->memory, vma->refd, vma->mapref, + addr, size, vma->addr, (u64)vma->size); + goto fail; + } + + if (vma->addr != addr) { + const u64 tail = vma->size + vma->addr - addr; + if (ret = -ENOMEM, !(vma = nvkm_vma_tail(vma, tail))) + goto fail; + vma->part = true; + nvkm_vmm_node_insert(vmm, vma); + } + + if (vma->size != size) { + const u64 tail = vma->size - size; + struct nvkm_vma *tmp; + if (ret = -ENOMEM, !(tmp = nvkm_vma_tail(vma, tail))) { + nvkm_vmm_unmap_region(vmm, vma); + goto fail; + } + tmp->part = true; + nvkm_vmm_node_insert(vmm, tmp); + } + } + vma->busy = true; + mutex_unlock(&vmm->mutex); + + ret = nvkm_memory_map(memory, offset, vmm, vma, argv, argc); + if (ret == 0) { + /* Successful map will clear vma->busy. */ + nvkm_memory_unref(&memory); + return 0; + } + + mutex_lock(&vmm->mutex); + vma->busy = false; + nvkm_vmm_unmap_region(vmm, vma); +fail: + mutex_unlock(&vmm->mutex); + nvkm_memory_unref(&memory); + return ret; +} + +static int +nvkm_uvmm_mthd_put(struct nvkm_uvmm *uvmm, void *argv, u32 argc) +{ + struct nvkm_client *client = uvmm->object.client; + union { + struct nvif_vmm_put_v0 v0; + } *args = argv; + struct nvkm_vmm *vmm = uvmm->vmm; + struct nvkm_vma *vma; + int ret = -ENOSYS; + u64 addr; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + addr = args->v0.addr; + } else + return ret; + + mutex_lock(&vmm->mutex); + vma = nvkm_vmm_node_search(vmm, args->v0.addr); + if (ret = -ENOENT, !vma || vma->addr != addr || vma->part) { + VMM_DEBUG(vmm, "lookup %016llx: %016llx %d", addr, + vma ? vma->addr : ~0ULL, vma ? vma->part : 0); + goto done; + } + + if (ret = -ENOENT, (!vma->user && !client->super) || vma->busy) { + VMM_DEBUG(vmm, "denied %016llx: %d %d %d", addr, + vma->user, !client->super, vma->busy); + goto done; + } + + nvkm_vmm_put_locked(vmm, vma); + ret = 0; +done: + mutex_unlock(&vmm->mutex); + return ret; +} + +static int +nvkm_uvmm_mthd_get(struct nvkm_uvmm *uvmm, void *argv, u32 argc) +{ + struct nvkm_client *client = uvmm->object.client; + union { + struct nvif_vmm_get_v0 v0; + } *args = argv; + struct nvkm_vmm *vmm = uvmm->vmm; + struct nvkm_vma *vma; + int ret = -ENOSYS; + bool getref, mapref, sparse; + u8 page, align; + u64 size; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + getref = args->v0.type == NVIF_VMM_GET_V0_PTES; + mapref = args->v0.type == NVIF_VMM_GET_V0_ADDR; + sparse = args->v0.sparse; + page = args->v0.page; + align = args->v0.align; + size = args->v0.size; + } else + return ret; + + mutex_lock(&vmm->mutex); + ret = nvkm_vmm_get_locked(vmm, getref, mapref, sparse, + page, align, size, &vma); + mutex_unlock(&vmm->mutex); + if (ret) + return ret; + + args->v0.addr = vma->addr; + vma->user = !client->super; + return ret; +} + +static int +nvkm_uvmm_mthd_page(struct nvkm_uvmm *uvmm, void *argv, u32 argc) +{ + union { + struct nvif_vmm_page_v0 v0; + } *args = argv; + const struct nvkm_vmm_page *page; + int ret = -ENOSYS; + u8 type, index, nr; + + page = uvmm->vmm->func->page; + for (nr = 0; page[nr].shift; nr++); + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + if ((index = args->v0.index) >= nr) + return -EINVAL; + type = page[index].type; + args->v0.shift = page[index].shift; + args->v0.sparse = !!(type & NVKM_VMM_PAGE_SPARSE); + args->v0.vram = !!(type & NVKM_VMM_PAGE_VRAM); + args->v0.host = !!(type & NVKM_VMM_PAGE_HOST); + args->v0.comp = !!(type & NVKM_VMM_PAGE_COMP); + } else + return -ENOSYS; + + return 0; +} + +static int +nvkm_uvmm_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc) +{ + struct nvkm_uvmm *uvmm = nvkm_uvmm(object); + switch (mthd) { + case NVIF_VMM_V0_PAGE : return nvkm_uvmm_mthd_page (uvmm, argv, argc); + case NVIF_VMM_V0_GET : return nvkm_uvmm_mthd_get (uvmm, argv, argc); + case NVIF_VMM_V0_PUT : return nvkm_uvmm_mthd_put (uvmm, argv, argc); + case NVIF_VMM_V0_MAP : return nvkm_uvmm_mthd_map (uvmm, argv, argc); + case NVIF_VMM_V0_UNMAP : return nvkm_uvmm_mthd_unmap (uvmm, argv, argc); + default: + break; + } + return -EINVAL; +} + +static void * +nvkm_uvmm_dtor(struct nvkm_object *object) +{ + struct nvkm_uvmm *uvmm = nvkm_uvmm(object); + nvkm_vmm_unref(&uvmm->vmm); + return uvmm; +} + +static const struct nvkm_object_func +nvkm_uvmm = { + .dtor = nvkm_uvmm_dtor, + .mthd = nvkm_uvmm_mthd, +}; + +int +nvkm_uvmm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + struct nvkm_mmu *mmu = nvkm_ummu(oclass->parent)->mmu; + const bool more = oclass->base.maxver >= 0; + union { + struct nvif_vmm_v0 v0; + } *args = argv; + const struct nvkm_vmm_page *page; + struct nvkm_uvmm *uvmm; + int ret = -ENOSYS; + u64 addr, size; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, more))) { + addr = args->v0.addr; + size = args->v0.size; + } else + return ret; + + if (!(uvmm = kzalloc(sizeof(*uvmm), GFP_KERNEL))) + return -ENOMEM; + nvkm_object_ctor(&nvkm_uvmm, oclass, &uvmm->object); + *pobject = &uvmm->object; + + if (!mmu->vmm) { + ret = mmu->func->vmm.ctor(mmu, addr, size, argv, argc, + NULL, "user", &uvmm->vmm); + if (ret) + return ret; + + uvmm->vmm->debug = max(uvmm->vmm->debug, oclass->client->debug); + } else { + if (size) + return -EINVAL; + + uvmm->vmm = nvkm_vmm_ref(mmu->vmm); + } + + page = uvmm->vmm->func->page; + args->v0.page_nr = 0; + while (page && (page++)->shift) + args->v0.page_nr++; + args->v0.addr = uvmm->vmm->start; + args->v0.size = uvmm->vmm->limit; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h new file mode 100644 index 000000000000..71dab55e18a9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h @@ -0,0 +1,14 @@ +#ifndef __NVKM_UVMM_H__ +#define __NVKM_UVMM_H__ +#define nvkm_uvmm(p) container_of((p), struct nvkm_uvmm, object) +#include +#include "vmm.h" + +struct nvkm_uvmm { + struct nvkm_object object; + struct nvkm_vmm *vmm; +}; + +int nvkm_uvmm_new(const struct nvkm_oclass *, void *argv, u32 argc, + struct nvkm_object **); +#endif -- cgit v1.2.3 From 359088d5b8ec06196a9ea53e7e59167514220465 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: remove trivial cases of nvxx_device() usage Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_abi16.c | 30 +++++++++++++++----------- drivers/gpu/drm/nouveau/nouveau_bo.c | 38 ++++++++++++--------------------- 2 files changed, 31 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 4c4e016aba95..ece650a0c5f9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -185,29 +185,33 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) getparam->value = device->info.chipset; break; case NOUVEAU_GETPARAM_PCI_VENDOR: - if (nvxx_device(device)->func->pci) + if (device->info.platform != NV_DEVICE_INFO_V0_SOC) getparam->value = dev->pdev->vendor; else getparam->value = 0; break; case NOUVEAU_GETPARAM_PCI_DEVICE: - if (nvxx_device(device)->func->pci) + if (device->info.platform != NV_DEVICE_INFO_V0_SOC) getparam->value = dev->pdev->device; else getparam->value = 0; break; case NOUVEAU_GETPARAM_BUS_TYPE: - if (!nvxx_device(device)->func->pci) - getparam->value = 3; - else - if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP)) - getparam->value = 0; - else - if (!pci_is_pcie(dev->pdev)) - getparam->value = 1; - else - getparam->value = 2; - break; + switch (device->info.platform) { + case NV_DEVICE_INFO_V0_AGP : getparam->value = 0; break; + case NV_DEVICE_INFO_V0_PCI : getparam->value = 1; break; + case NV_DEVICE_INFO_V0_PCIE: getparam->value = 2; break; + case NV_DEVICE_INFO_V0_SOC : getparam->value = 3; break; + case NV_DEVICE_INFO_V0_IGP : + if (!pci_is_pcie(dev->pdev)) + getparam->value = 1; + else + getparam->value = 2; + break; + default: + WARN_ON(1); + break; + } case NOUVEAU_GETPARAM_FB_SIZE: getparam->value = drm->gem.vram_available; break; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index f4545773756a..5ccbd98bfafd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -50,8 +50,7 @@ nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg, { struct nouveau_drm *drm = nouveau_drm(dev); int i = reg - drm->tile.reg; - struct nvkm_device *device = nvxx_device(&drm->client.device); - struct nvkm_fb *fb = device->fb; + struct nvkm_fb *fb = nvxx_fb(&drm->client.device); struct nvkm_fb_tile *tile = &fb->tile.region[i]; nouveau_fence_unref(®->fence); @@ -459,7 +458,6 @@ void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) { struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); - struct nvkm_device *device = nvxx_device(&drm->client.device); struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; @@ -471,7 +469,8 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) return; for (i = 0; i < ttm_dma->ttm.num_pages; i++) - dma_sync_single_for_device(device->dev, ttm_dma->dma_address[i], + dma_sync_single_for_device(drm->dev->dev, + ttm_dma->dma_address[i], PAGE_SIZE, DMA_TO_DEVICE); } @@ -479,7 +478,6 @@ void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) { struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); - struct nvkm_device *device = nvxx_device(&drm->client.device); struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; @@ -491,7 +489,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) return; for (i = 0; i < ttm_dma->ttm.num_pages; i++) - dma_sync_single_for_cpu(device->dev, ttm_dma->dma_address[i], + dma_sync_single_for_cpu(drm->dev->dev, ttm_dma->dma_address[i], PAGE_SIZE, DMA_FROM_DEVICE); } @@ -1468,9 +1466,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) { struct ttm_dma_tt *ttm_dma = (void *)ttm; struct nouveau_drm *drm; - struct nvkm_device *device; - struct drm_device *dev; - struct device *pdev; + struct device *dev; unsigned i; int r; bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); @@ -1487,9 +1483,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) } drm = nouveau_bdev(ttm->bdev); - device = nvxx_device(&drm->client.device); - dev = drm->dev; - pdev = device->dev; + dev = drm->dev->dev; #if IS_ENABLED(CONFIG_AGP) if (drm->agp.bridge) { @@ -1499,7 +1493,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) #if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86) if (swiotlb_nr_tbl()) { - return ttm_dma_populate((void *)ttm, dev->dev); + return ttm_dma_populate((void *)ttm, dev); } #endif @@ -1511,12 +1505,12 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) for (i = 0; i < ttm->num_pages; i++) { dma_addr_t addr; - addr = dma_map_page(pdev, ttm->pages[i], 0, PAGE_SIZE, + addr = dma_map_page(dev, ttm->pages[i], 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(pdev, addr)) { + if (dma_mapping_error(dev, addr)) { while (i--) { - dma_unmap_page(pdev, ttm_dma->dma_address[i], + dma_unmap_page(dev, ttm_dma->dma_address[i], PAGE_SIZE, DMA_BIDIRECTIONAL); ttm_dma->dma_address[i] = 0; } @@ -1534,9 +1528,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) { struct ttm_dma_tt *ttm_dma = (void *)ttm; struct nouveau_drm *drm; - struct nvkm_device *device; - struct drm_device *dev; - struct device *pdev; + struct device *dev; unsigned i; bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); @@ -1544,9 +1536,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) return; drm = nouveau_bdev(ttm->bdev); - device = nvxx_device(&drm->client.device); - dev = drm->dev; - pdev = device->dev; + dev = drm->dev->dev; #if IS_ENABLED(CONFIG_AGP) if (drm->agp.bridge) { @@ -1557,14 +1547,14 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) #if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86) if (swiotlb_nr_tbl()) { - ttm_dma_unpopulate((void *)ttm, dev->dev); + ttm_dma_unpopulate((void *)ttm, dev); return; } #endif for (i = 0; i < ttm->num_pages; i++) { if (ttm_dma->dma_address[i]) { - dma_unmap_page(pdev, ttm_dma->dma_address[i], PAGE_SIZE, + dma_unmap_page(dev, ttm_dma->dma_address[i], PAGE_SIZE, DMA_BIDIRECTIONAL); } } -- cgit v1.2.3 From 01670a79d5fa2f6659d18af6d52cca6c44f73646 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: allocate mmu object for every client Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 20 ++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 2 ++ 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 25a47e8ba42b..2eddf19abb40 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -116,6 +116,7 @@ nouveau_cli_fini(struct nouveau_cli *cli) { usif_client_fini(cli); nouveau_vmm_fini(&cli->vmm); + nvif_mmu_fini(&cli->mmu); nvif_device_fini(&cli->device); mutex_lock(&cli->drm->master.lock); nvif_client_fini(&cli->base); @@ -126,6 +127,13 @@ static int nouveau_cli_init(struct nouveau_drm *drm, const char *sname, struct nouveau_cli *cli) { + static const struct nvif_mclass + mmus[] = { + { NVIF_CLASS_MMU_GF100, -1 }, + { NVIF_CLASS_MMU_NV50 , -1 }, + { NVIF_CLASS_MMU_NV04 , -1 }, + {} + }; u64 device = nouveau_name(drm->dev); int ret; @@ -160,6 +168,18 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, goto done; } + ret = nvif_mclass(&cli->device.object, mmus); + if (ret < 0) { + NV_ERROR(drm, "No supported MMU class\n"); + goto done; + } + + ret = nvif_mmu_init(&cli->device.object, mmus[ret].oclass, &cli->mmu); + if (ret) { + NV_ERROR(drm, "MMU allocation failed: %d\n", ret); + goto done; + } + done: if (ret) nouveau_cli_fini(cli); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index ba8a9ab20562..ac5c66e60b2a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -91,6 +92,7 @@ struct nouveau_cli { struct mutex mutex; struct nvif_device device; + struct nvif_mmu mmu; struct nouveau_vmm vmm; struct nvkm_vm *vm; -- cgit v1.2.3 From a220dd73215be28285f6c90355abbe9e21974c77 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: check kind validity against mmu object This is already handled in the top-level gem_new() ioctl in another manner, but this will be removed in a future commit. Ideally we'd not need to check up-front at all, and let the VMM code handle error checking, but there are paths in the current BO management code where this isn't possible due to map() not always being called during BO creation, and map() calls not being allowed to fail during buffer migration. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 5ccbd98bfafd..8aa2bc6f78fb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -189,6 +189,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, { struct nouveau_drm *drm = cli->drm; struct nouveau_bo *nvbo; + struct nvif_mmu *mmu = &cli->mmu; size_t acc_size; int ret; int type = ttm_bo_type_device; @@ -215,11 +216,20 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) { nvbo->kind = (tile_flags & 0x0000ff00) >> 8; - nvbo->comp = gf100_pte_storage_type_map[nvbo->kind] != nvbo->kind; + if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { + kfree(nvbo); + return -EINVAL; + } + + nvbo->comp = mmu->kind[nvbo->kind] != nvbo->kind; } else if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { nvbo->kind = (tile_flags & 0x00007f00) >> 8; nvbo->comp = (tile_flags & 0x00030000) >> 16; + if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { + kfree(nvbo); + return -EINVAL; + } } else { nvbo->zeta = (tile_flags & 0x00000007); } @@ -232,7 +242,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, nvbo->page = drm->client.vm->mmu->lpg_shift; else { if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) - nvbo->kind = gf100_pte_storage_type_map[nvbo->kind]; + nvbo->kind = mmu->kind[nvbo->kind]; nvbo->comp = 0; } } -- cgit v1.2.3 From 325a72827c2c000f6f3810a3e680fa1101d94456 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau: consolidate handling of dma mask Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_ttm.c | 31 +--------------------- drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c | 24 ++++++++--------- drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 2 -- 3 files changed, 13 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 8c4f45ea6234..3211f78da4dd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -253,7 +253,6 @@ nouveau_ttm_init(struct nouveau_drm *drm) struct nvkm_device *device = nvxx_device(&drm->client.device); struct nvkm_pci *pci = device->pci; struct drm_device *dev = drm->dev; - u8 bits; int ret; if (pci && pci->agp.bridge) { @@ -263,34 +262,6 @@ nouveau_ttm_init(struct nouveau_drm *drm) drm->agp.cma = pci->agp.cma; } - bits = nvxx_mmu(&drm->client.device)->dma_bits; - if (nvxx_device(&drm->client.device)->func->pci) { - if (drm->agp.bridge) - bits = 32; - } else if (device->func->tegra) { - struct nvkm_device_tegra *tegra = device->func->tegra(device); - - /* - * If the platform can use a IOMMU, then the addressable DMA - * space is constrained by the IOMMU bit - */ - if (tegra->func->iommu_bit) - bits = min(bits, tegra->func->iommu_bit); - - } - - ret = dma_set_mask(dev->dev, DMA_BIT_MASK(bits)); - if (ret && bits != 32) { - bits = 32; - ret = dma_set_mask(dev->dev, DMA_BIT_MASK(bits)); - } - if (ret) - return ret; - - ret = dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(bits)); - if (ret) - dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(32)); - ret = nouveau_ttm_global_init(drm); if (ret) return ret; @@ -300,7 +271,7 @@ nouveau_ttm_init(struct nouveau_drm *drm) &nouveau_bo_driver, dev->anon_inode->i_mapping, DRM_FILE_PAGE_OFFSET, - bits <= 32 ? true : false); + drm->client.mmu.dmabits <= 32 ? true : false); if (ret) { NV_ERROR(drm, "error initialising bo driver, %d\n", ret); return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c index 74a1ffa425f7..f302d2b5782a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c @@ -1627,7 +1627,7 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, const struct nvkm_device_pci_vendor *pciv; const char *name = NULL; struct nvkm_device_pci *pdev; - int ret; + int ret, bits; ret = pci_enable_device(pci_dev); if (ret) @@ -1679,17 +1679,17 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, if (ret) return ret; - /* - * Set a preliminary DMA mask based on the .dma_bits member of the - * MMU subdevice. This allows other subdevices to create DMA mappings - * in their init() or oneinit() methods, which may be called before the - * TTM layer sets the DMA mask definitively. - * This is necessary for platforms where the default DMA mask of 32 - * does not cover any system memory, i.e., when all RAM is > 4 GB. - */ - if (pdev->device.mmu) - dma_set_mask_and_coherent(&pci_dev->dev, - DMA_BIT_MASK(pdev->device.mmu->dma_bits)); + /* Set DMA mask based on capabilities reported by the MMU subdev. */ + if (pdev->device.mmu && !pdev->device.pci->agp.bridge) + bits = pdev->device.mmu->dma_bits; + else + bits = 32; + + ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(bits)); + if (ret && bits != 32) { + dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)); + pdev->device.mmu->dma_bits = 32; + } return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index d35a32e168d6..78597da6313a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -309,8 +309,6 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, /** * The IOMMU bit defines the upper limit of the GPU-addressable space. - * This will be refined in nouveau_ttm_init but we need to do it early - * for instmem to behave properly */ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(tdev->func->iommu_bit)); if (ret) -- cgit v1.2.3 From 658c71f4e7cabce658692a81732563e74de0c952 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: fetch memory type indices that we care about for ttm Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +++ drivers/gpu/drm/nouveau/nouveau_ttm.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index ac5c66e60b2a..6d6795b5b3ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -140,6 +140,9 @@ struct nouveau_drm { struct nouveau_channel *chan; struct nvif_object copy; int mtrr; + int type_vram; + int type_host; + int type_ncoh; } ttm; /* GEM interface support */ diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 3211f78da4dd..f64a55421a96 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -252,8 +252,36 @@ nouveau_ttm_init(struct nouveau_drm *drm) { struct nvkm_device *device = nvxx_device(&drm->client.device); struct nvkm_pci *pci = device->pci; + struct nvif_mmu *mmu = &drm->client.mmu; struct drm_device *dev = drm->dev; - int ret; + int typei, ret; + + typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | + NVIF_MEM_COHERENT); + if (typei < 0) + return -ENOSYS; + + drm->ttm.type_host = typei; + + typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE); + if (typei < 0) + return -ENOSYS; + + drm->ttm.type_ncoh = typei; + + if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && + drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { + typei = nvif_mmu_type(mmu, NVIF_MEM_VRAM | NVIF_MEM_MAPPABLE | + NVIF_MEM_KIND | + NVIF_MEM_COMP | + NVIF_MEM_DISP); + if (typei < 0) + return -ENOSYS; + + drm->ttm.type_vram = typei; + } else { + drm->ttm.type_vram = -1; + } if (pci && pci->agp.bridge) { drm->agp.bridge = pci->agp.bridge; -- cgit v1.2.3 From b34720200bb1334c78aaecb999cc2b18a71b9277 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: use nvif_mmu_type to determine BAR1 caching Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/device.h | 1 - drivers/gpu/drm/nouveau/nouveau_bo.c | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index bcb981711617..9a29b7ca3105 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -58,7 +58,6 @@ u64 nvif_device_time(struct nvif_device *); #define nvxx_bios(a) nvxx_device(a)->bios #define nvxx_fb(a) nvxx_device(a)->fb #define nvxx_mmu(a) nvxx_device(a)->mmu -#define nvxx_bar(a) nvxx_device(a)->bar #define nvxx_gpio(a) nvxx_device(a)->gpio #define nvxx_clk(a) nvxx_device(a)->clk #define nvxx_i2c(a) nvxx_device(a)->i2c diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 8aa2bc6f78fb..6e7e283e18b5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -589,6 +589,7 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man) { struct nouveau_drm *drm = nouveau_bdev(bdev); + struct nvif_mmu *mmu = &drm->client.mmu; switch (type) { case TTM_PL_SYSTEM: @@ -605,7 +606,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { /* Some BARs do not support being ioremapped WC */ - if (nvxx_bar(&drm->client.device)->iomap_uncached) { + const u8 type = mmu->type[drm->ttm.type_vram].type; + if (type & NVIF_MEM_UNCACHED) { man->available_caching = TTM_PL_FLAG_UNCACHED; man->default_caching = TTM_PL_FLAG_UNCACHED; } -- cgit v1.2.3 From acb16cfa95f1cc6fb4b1b52da27bdbeb079ef115 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: replace use of cpu_coherent with memory types Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6e7e283e18b5..3577ab2d5d69 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -211,8 +211,17 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, nvbo->bo.bdev = &drm->ttm.bdev; nvbo->cli = cli; - if (!nvxx_device(&drm->client.device)->func->cpu_coherent) - nvbo->force_coherent = flags & TTM_PL_FLAG_UNCACHED; + /* This is confusing, and doesn't actually mean we want an uncached + * mapping, but is what NOUVEAU_GEM_DOMAIN_COHERENT gets translated + * into in nouveau_gem_new(). + */ + if (flags & TTM_PL_FLAG_UNCACHED) { + /* Determine if we can get a cache-coherent map, forcing + * uncached mapping if we can't. + */ + if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) + nvbo->force_coherent = true; + } if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) { nvbo->kind = (tile_flags & 0x0000ff00) >> 8; -- cgit v1.2.3 From 96da0bcd51964ca708d8de2987ff473a9da4406d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: allocate vmm object for every client Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 50 ++++++++++++++++++----------------- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nouveau_gem.c | 8 +++--- drivers/gpu/drm/nouveau/nouveau_mem.h | 5 ---- drivers/gpu/drm/nouveau/nouveau_vmm.c | 12 ++++++--- drivers/gpu/drm/nouveau/nouveau_vmm.h | 4 ++- 6 files changed, 44 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 2eddf19abb40..a6aaddecd8c5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -134,6 +134,15 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, { NVIF_CLASS_MMU_NV04 , -1 }, {} }; + static const struct nvif_mclass + vmms[] = { + { NVIF_CLASS_VMM_GP100, -1 }, + { NVIF_CLASS_VMM_GM200, -1 }, + { NVIF_CLASS_VMM_GF100, -1 }, + { NVIF_CLASS_VMM_NV50 , -1 }, + { NVIF_CLASS_VMM_NV04 , -1 }, + {} + }; u64 device = nouveau_name(drm->dev); int ret; @@ -180,6 +189,23 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, goto done; } + ret = nvif_mclass(&cli->mmu.object, vmms); + if (ret < 0) { + NV_ERROR(drm, "No supported VMM class\n"); + goto done; + } + + ret = nouveau_vmm_init(cli, vmms[ret].oclass, &cli->vmm); + if (ret) { + NV_ERROR(drm, "VMM allocation failed: %d\n", ret); + goto done; + } + + if (1) { + cli->vm = cli->vmm.vm; + nvxx_client(&cli->base)->vm = cli->vm; + } + done: if (ret) nouveau_cli_fini(cli); @@ -486,20 +512,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) nouveau_vga_init(drm); - if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - if (!nvxx_device(&drm->client.device)->mmu) { - ret = -ENOSYS; - goto fail_device; - } - - ret = nouveau_vmm_init(&drm->client, 0, &drm->client.vmm); - if (ret) - goto fail_device; - - drm->client.vm = drm->client.vmm.vm; - nvxx_client(&drm->client.base)->vm = drm->client.vm; - } - ret = nouveau_ttm_init(drm); if (ret) goto fail_ttm; @@ -545,7 +557,6 @@ fail_bios: nouveau_ttm_fini(drm); fail_ttm: nouveau_vga_fini(drm); -fail_device: nouveau_cli_fini(&drm->client); nouveau_cli_fini(&drm->master); kfree(drm); @@ -881,15 +892,6 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) cli->base.super = false; - if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_vmm_init(cli, 0, &cli->vmm); - if (ret) - goto done; - - cli->vm = cli->vmm.vm; - nvxx_client(&cli->base)->vm = cli->vm; - } - fpriv->driver_priv = cli; mutex_lock(&drm->client.mutex); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6d6795b5b3ef..25e0fb73747b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -43,6 +43,7 @@ #include #include #include +#include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 9f82b13293f5..a600c4386c72 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -33,6 +33,8 @@ #include "nouveau_gem.h" #include "nouveau_vmm.h" +#include + void nouveau_gem_object_del(struct drm_gem_object *gem) { @@ -69,7 +71,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) struct nouveau_vma *vma; int ret; - if (!cli->vm) + if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50) return 0; ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL); @@ -131,7 +133,7 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) struct nouveau_vma *vma; int ret; - if (!cli->vm) + if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50) return; ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL); @@ -214,7 +216,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, else rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; rep->offset = nvbo->bo.offset; - if (cli->vm) { + if (cli->vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) { vma = nouveau_vma_find(nvbo, &cli->vmm); if (!vma) return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h index 48388c538420..3e34566116c4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.h +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -29,11 +29,6 @@ struct nouveau_mem { struct nvkm_memory memory; }; -enum nvif_vmm_get { - PTES, - LAZY, -}; - int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp, struct ttm_mem_reg *); void nouveau_mem_del(struct ttm_mem_reg *); diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index 6dc14f92b988..656f43ad012d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -114,13 +114,19 @@ done: void nouveau_vmm_fini(struct nouveau_vmm *vmm) { - nvkm_vm_ref(NULL, &vmm->vm, NULL); + nvif_vmm_fini(&vmm->vmm); + vmm->cli = NULL; } int nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm) { + int ret = nvif_vmm_init(&cli->mmu, oclass, PAGE_SIZE, 0, NULL, 0, + &vmm->vmm); + if (ret) + return ret; + vmm->cli = cli; - return nvkm_vm_new(nvxx_device(&cli->device), 0, (1ULL << 40), - 0x1000, NULL, &vmm->vm); + vmm->vm = nvkm_uvmm(vmm->vmm.object.priv)->vmm; + return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.h b/drivers/gpu/drm/nouveau/nouveau_vmm.h index 86ab599aafb2..c7b9c55bc535 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.h +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.h @@ -1,6 +1,7 @@ #ifndef __NOUVEAU_VMA_H__ #define __NOUVEAU_VMA_H__ -#include +#include +#include struct nouveau_bo; struct nouveau_mem; @@ -24,6 +25,7 @@ void nouveau_vma_unmap(struct nouveau_vma *); struct nouveau_vmm { struct nouveau_cli *cli; + struct nvif_vmm vmm; struct nvkm_vm *vm; }; -- cgit v1.2.3 From 3c5026395bcdaa956fa5c6ec7571f1a04847c74b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: switch to vmm limit Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_chan.c | 12 +++++------- drivers/gpu/drm/nouveau/nouveau_ttm.c | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 9fdca7b4cb05..f3ed5896b842 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -107,7 +107,6 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, u32 size, struct nouveau_channel **pchan) { struct nouveau_cli *cli = (void *)device->object.client; - struct nvkm_mmu *mmu = nvxx_mmu(device); struct nv_dma_v0 args = {}; struct nouveau_channel *chan; u32 target; @@ -156,7 +155,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_VM; args.start = 0; - args.limit = cli->vm->mmu->limit - 1; + args.limit = cli->vmm.vmm.limit - 1; chan->push.addr = chan->push.vma->addr; } else @@ -188,7 +187,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_RDWR; args.start = 0; - args.limit = mmu->limit - 1; + args.limit = cli->vmm.vmm.limit - 1; } } @@ -317,7 +316,6 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) struct nvif_device *device = chan->device; struct nouveau_cli *cli = (void *)chan->user.client; struct nouveau_drm *drm = chan->drm; - struct nvkm_mmu *mmu = nvxx_mmu(device); struct nv_dma_v0 args = {}; int ret, i; @@ -342,7 +340,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_VM; args.start = 0; - args.limit = cli->vm->mmu->limit - 1; + args.limit = cli->vmm.vmm.limit - 1; } else { args.target = NV_DMA_V0_TARGET_VRAM; args.access = NV_DMA_V0_ACCESS_RDWR; @@ -359,7 +357,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_VM; args.start = 0; - args.limit = cli->vm->mmu->limit - 1; + args.limit = cli->vmm.vmm.limit - 1; } else if (chan->drm->agp.bridge) { args.target = NV_DMA_V0_TARGET_AGP; @@ -371,7 +369,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_RDWR; args.start = 0; - args.limit = mmu->limit - 1; + args.limit = cli->vmm.vmm.limit - 1; } ret = nvif_object_init(&chan->user, gart, NV_DMA_IN_MEMORY, diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index f64a55421a96..15c1091cccb5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -323,7 +323,7 @@ nouveau_ttm_init(struct nouveau_drm *drm) /* GART init */ if (!drm->agp.bridge) { - drm->gem.gart_available = nvxx_mmu(&drm->client.device)->limit; + drm->gem.gart_available = drm->client.vmm.vmm.limit; } else { drm->gem.gart_available = drm->agp.size; } -- cgit v1.2.3 From 832ca2ac3c95feb01e53c24fcd1a00b4cf05cbdc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: pass handle of vmm object to channel allocation ioctls Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/cl506e.h | 2 +- drivers/gpu/drm/nouveau/include/nvif/cl506f.h | 2 +- drivers/gpu/drm/nouveau/include/nvif/cl826e.h | 2 +- drivers/gpu/drm/nouveau/include/nvif/cl826f.h | 2 +- drivers/gpu/drm/nouveau/include/nvif/cl906f.h | 2 +- drivers/gpu/drm/nouveau/include/nvif/cla06f.h | 2 +- drivers/gpu/drm/nouveau/nouveau_chan.c | 7 ++++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 12 +++++++----- drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c | 7 +++++-- drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c | 7 +++++-- drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | 8 +++++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 14 ++++++++------ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c | 6 +++--- 17 files changed, 54 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl506e.h b/drivers/gpu/drm/nouveau/include/nvif/cl506e.h index aa94b8cf9679..f50866011002 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl506e.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl506e.h @@ -5,7 +5,7 @@ struct nv50_channel_dma_v0 { __u8 version; __u8 chid; __u8 pad02[6]; - __u64 vm; + __u64 vmm; __u64 pushbuf; __u64 offset; }; diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl506f.h b/drivers/gpu/drm/nouveau/include/nvif/cl506f.h index 3b7101966de4..0e5bbb553158 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl506f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl506f.h @@ -8,6 +8,6 @@ struct nv50_channel_gpfifo_v0 { __u32 ilength; __u64 ioffset; __u64 pushbuf; - __u64 vm; + __u64 vmm; }; #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl826e.h b/drivers/gpu/drm/nouveau/include/nvif/cl826e.h index 91e33db21a2f..7f6a8ce5a418 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl826e.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl826e.h @@ -5,7 +5,7 @@ struct g82_channel_dma_v0 { __u8 version; __u8 chid; __u8 pad02[6]; - __u64 vm; + __u64 vmm; __u64 pushbuf; __u64 offset; }; diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl826f.h b/drivers/gpu/drm/nouveau/include/nvif/cl826f.h index e34efd4ec537..c4d35522331a 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl826f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl826f.h @@ -8,7 +8,7 @@ struct g82_channel_gpfifo_v0 { __u32 ilength; __u64 ioffset; __u64 pushbuf; - __u64 vm; + __u64 vmm; }; #define NV826F_V0_NTFY_NON_STALL_INTERRUPT 0x00 diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl906f.h b/drivers/gpu/drm/nouveau/include/nvif/cl906f.h index a2d5410a491b..169161c1587f 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl906f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl906f.h @@ -7,7 +7,7 @@ struct fermi_channel_gpfifo_v0 { __u8 pad02[2]; __u32 ilength; __u64 ioffset; - __u64 vm; + __u64 vmm; }; #define NV906F_V0_NTFY_NON_STALL_INTERRUPT 0x00 diff --git a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h b/drivers/gpu/drm/nouveau/include/nvif/cla06f.h index 2efa3d048bb9..3e57089526e3 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cla06f.h @@ -22,7 +22,7 @@ struct kepler_channel_gpfifo_a_v0 { __u32 engines; __u32 ilength; __u64 ioffset; - __u64 vm; + __u64 vmm; }; #define NVA06F_V0_NTFY_NON_STALL_INTERRUPT 0x00 diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index f3ed5896b842..34dbcf5f7f4e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -205,6 +205,7 @@ static int nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, u32 engine, struct nouveau_channel **pchan) { + struct nouveau_cli *cli = (void *)device->object.client; static const u16 oclasses[] = { PASCAL_CHANNEL_GPFIFO_A, MAXWELL_CHANNEL_GPFIFO_A, KEPLER_CHANNEL_GPFIFO_B, @@ -236,21 +237,21 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, args.kepler.engines = engine; args.kepler.ilength = 0x02000; args.kepler.ioffset = 0x10000 + chan->push.addr; - args.kepler.vm = 0; + args.kepler.vmm = nvif_handle(&cli->vmm.vmm.object); size = sizeof(args.kepler); } else if (oclass[0] >= FERMI_CHANNEL_GPFIFO) { args.fermi.version = 0; args.fermi.ilength = 0x02000; args.fermi.ioffset = 0x10000 + chan->push.addr; - args.fermi.vm = 0; + args.fermi.vmm = nvif_handle(&cli->vmm.vmm.object); size = sizeof(args.fermi); } else { args.nv50.version = 0; args.nv50.ilength = 0x02000; args.nv50.ioffset = 0x10000 + chan->push.addr; args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma); - args.nv50.vm = 0; + args.nv50.vmm = nvif_handle(&cli->vmm.vmm.object); size = sizeof(args.nv50); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index ac94b57777c4..d83485385934 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -27,7 +27,6 @@ #include #include #include -#include #include struct nvkm_fifo_chan_object { @@ -353,8 +352,8 @@ nvkm_fifo_chan_func = { int nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *func, struct nvkm_fifo *fifo, u32 size, u32 align, bool zero, - u64 vm, u64 push, u64 engines, int bar, u32 base, u32 user, - const struct nvkm_oclass *oclass, + u64 hvmm, u64 push, u64 engines, int bar, u32 base, + u32 user, const struct nvkm_oclass *oclass, struct nvkm_fifo_chan *chan) { struct nvkm_client *client = oclass->client; @@ -387,8 +386,11 @@ nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *func, } /* channel address space */ - if (!device->mmu->func->vmm.global) { - struct nvkm_vmm *vmm = client->vm; + if (hvmm) { + struct nvkm_vmm *vmm = nvkm_uvmm_search(client, hvmm); + if (IS_ERR(vmm)) + return PTR_ERR(vmm); + if (vmm->mmu != device->mmu) return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c index 1870310549e8..a5c998fe4485 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c @@ -229,15 +229,18 @@ g84_fifo_chan_func = { }; int -g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vm, u64 push, +g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push, const struct nvkm_oclass *oclass, struct nv50_fifo_chan *chan) { struct nvkm_device *device = fifo->base.engine.subdev.device; int ret; + if (!vmm) + return -EINVAL; + ret = nvkm_fifo_chan_ctor(&g84_fifo_chan_func, &fifo->base, - 0x10000, 0x1000, false, vm, push, + 0x10000, 0x1000, false, vmm, push, (1ULL << NVKM_ENGINE_BSP) | (1ULL << NVKM_ENGINE_CE0) | (1ULL << NVKM_ENGINE_CIPHER) | diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c index 01453279dbc0..85f7dbf53c99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c @@ -228,15 +228,18 @@ nv50_fifo_chan_func = { }; int -nv50_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vm, u64 push, +nv50_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push, const struct nvkm_oclass *oclass, struct nv50_fifo_chan *chan) { struct nvkm_device *device = fifo->base.engine.subdev.device; int ret; + if (!vmm) + return -EINVAL; + ret = nvkm_fifo_chan_ctor(&nv50_fifo_chan_func, &fifo->base, - 0x10000, 0x1000, false, vm, push, + 0x10000, 0x1000, false, vmm, push, (1ULL << NVKM_ENGINE_DMAOBJ) | (1ULL << NVKM_ENGINE_SW) | (1ULL << NVKM_ENGINE_GR) | diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h index a0c04c6329a8..d853056e040b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h @@ -17,14 +17,14 @@ struct nv50_fifo_chan { struct nvkm_gpuobj *engn[NVKM_SUBDEV_NR]; }; -int nv50_fifo_chan_ctor(struct nv50_fifo *, u64 vm, u64 push, +int nv50_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push, const struct nvkm_oclass *, struct nv50_fifo_chan *); void *nv50_fifo_chan_dtor(struct nvkm_fifo_chan *); void nv50_fifo_chan_fini(struct nvkm_fifo_chan *); void nv50_fifo_chan_engine_dtor(struct nvkm_fifo_chan *, struct nvkm_engine *); void nv50_fifo_chan_object_dtor(struct nvkm_fifo_chan *, int); -int g84_fifo_chan_ctor(struct nv50_fifo *, u64 vm, u64 push, +int g84_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push, const struct nvkm_oclass *, struct nv50_fifo_chan *); extern const struct nvkm_fifo_chan_oclass nv50_fifo_dma_oclass; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c index caa914074752..fc34cddcd2f5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c @@ -44,9 +44,9 @@ g84_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, nvif_ioctl(parent, "create channel dma size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(parent, "create channel dma vers %d vm %llx " + nvif_ioctl(parent, "create channel dma vers %d vmm %llx " "pushbuf %llx offset %016llx\n", - args->v0.version, args->v0.vm, args->v0.pushbuf, + args->v0.version, args->v0.vmm, args->v0.pushbuf, args->v0.offset); if (!args->v0.pushbuf) return -EINVAL; @@ -57,7 +57,7 @@ g84_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return -ENOMEM; *pobject = &chan->base.object; - ret = g84_fifo_chan_ctor(fifo, args->v0.vm, args->v0.pushbuf, + ret = g84_fifo_chan_ctor(fifo, args->v0.vmm, args->v0.pushbuf, oclass, chan); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c index 480bc3777be5..8043718ad150 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c @@ -44,9 +44,9 @@ nv50_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, nvif_ioctl(parent, "create channel dma size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(parent, "create channel dma vers %d vm %llx " + nvif_ioctl(parent, "create channel dma vers %d vmm %llx " "pushbuf %llx offset %016llx\n", - args->v0.version, args->v0.vm, args->v0.pushbuf, + args->v0.version, args->v0.vmm, args->v0.pushbuf, args->v0.offset); if (!args->v0.pushbuf) return -EINVAL; @@ -57,7 +57,7 @@ nv50_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return -ENOMEM; *pobject = &chan->base.object; - ret = nv50_fifo_chan_ctor(fifo, args->v0.vm, args->v0.pushbuf, + ret = nv50_fifo_chan_ctor(fifo, args->v0.vmm, args->v0.pushbuf, oclass, chan); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c index 77c2f2a28bf3..2121f517b1dd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c @@ -45,10 +45,10 @@ g84_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, nvif_ioctl(parent, "create channel gpfifo size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx " + nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx " "pushbuf %llx ioffset %016llx " "ilength %08x\n", - args->v0.version, args->v0.vm, args->v0.pushbuf, + args->v0.version, args->v0.vmm, args->v0.pushbuf, args->v0.ioffset, args->v0.ilength); if (!args->v0.pushbuf) return -EINVAL; @@ -59,7 +59,7 @@ g84_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return -ENOMEM; *pobject = &chan->base.object; - ret = g84_fifo_chan_ctor(fifo, args->v0.vm, args->v0.pushbuf, + ret = g84_fifo_chan_ctor(fifo, args->v0.vmm, args->v0.pushbuf, oclass, chan); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index 78114068c6dd..75f9632789b3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c @@ -225,10 +225,12 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, nvif_ioctl(parent, "create channel gpfifo size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx " + nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx " "ioffset %016llx ilength %08x\n", - args->v0.version, args->v0.vm, args->v0.ioffset, + args->v0.version, args->v0.vmm, args->v0.ioffset, args->v0.ilength); + if (!args->v0.vmm) + return -EINVAL; } else return ret; @@ -240,7 +242,7 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, INIT_LIST_HEAD(&chan->head); ret = nvkm_fifo_chan_ctor(&gf100_fifo_gpfifo_func, &fifo->base, - 0x1000, 0x1000, true, args->v0.vm, 0, + 0x1000, 0x1000, true, args->v0.vmm, 0, (1ULL << NVKM_ENGINE_CE0) | (1ULL << NVKM_ENGINE_CE1) | (1ULL << NVKM_ENGINE_GR) | diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 368f5f5138a3..80c87521bebe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -231,7 +231,7 @@ struct gk104_fifo_chan_func { static int gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, struct gk104_fifo *fifo, u32 *engmask, u16 *chid, - u64 vm, u64 ioffset, u64 ilength, + u64 vmm, u64 ioffset, u64 ilength, const struct nvkm_oclass *oclass, struct nvkm_object **pobject) { @@ -241,6 +241,9 @@ gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, u64 subdevs = 0; u64 usermem; + if (!vmm) + return -EINVAL; + /* Determine which downstream engines are present */ for (i = 0; i < fifo->engine_nr; i++) { struct nvkm_engine *engine = fifo->engine[i].engine; @@ -286,7 +289,7 @@ gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, INIT_LIST_HEAD(&chan->head); ret = nvkm_fifo_chan_ctor(&gk104_fifo_gpfifo_func, &fifo->base, - 0x1000, 0x1000, true, vm, 0, subdevs, + 0x1000, 0x1000, true, vmm, 0, subdevs, 1, fifo->user.bar->addr, 0x200, oclass, &chan->base); if (ret) @@ -358,18 +361,17 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, nvif_ioctl(parent, "create channel gpfifo size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx " + nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx " "ioffset %016llx ilength %08x engine %08x\n", - args->v0.version, args->v0.vm, args->v0.ioffset, + args->v0.version, args->v0.vmm, args->v0.ioffset, args->v0.ilength, args->v0.engines); return gk104_fifo_gpfifo_new_(gk104_fifo_gpfifo, fifo, &args->v0.engines, &args->v0.chid, - args->v0.vm, + args->v0.vmm, args->v0.ioffset, args->v0.ilength, oclass, pobject); - } return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c index c5a7de9db259..d8f28ec1e4a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c @@ -45,10 +45,10 @@ nv50_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, nvif_ioctl(parent, "create channel gpfifo size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx " + nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx " "pushbuf %llx ioffset %016llx " "ilength %08x\n", - args->v0.version, args->v0.vm, args->v0.pushbuf, + args->v0.version, args->v0.vmm, args->v0.pushbuf, args->v0.ioffset, args->v0.ilength); if (!args->v0.pushbuf) return -EINVAL; @@ -59,7 +59,7 @@ nv50_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return -ENOMEM; *pobject = &chan->base.object; - ret = nv50_fifo_chan_ctor(fifo, args->v0.vm, args->v0.pushbuf, + ret = nv50_fifo_chan_ctor(fifo, args->v0.vmm, args->v0.pushbuf, oclass, chan); if (ret) return ret; -- cgit v1.2.3 From 7f50762423b4825674ee7fe10fa37abdafdcf754 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: determine memory class for each client Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 16 ++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + 2 files changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index a6aaddecd8c5..e82da06d82f0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -127,6 +127,13 @@ static int nouveau_cli_init(struct nouveau_drm *drm, const char *sname, struct nouveau_cli *cli) { + static const struct nvif_mclass + mems[] = { + { NVIF_CLASS_MEM_GF100, -1 }, + { NVIF_CLASS_MEM_NV50 , -1 }, + { NVIF_CLASS_MEM_NV04 , -1 }, + {} + }; static const struct nvif_mclass mmus[] = { { NVIF_CLASS_MMU_GF100, -1 }, @@ -201,11 +208,20 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, goto done; } + ret = nvif_mclass(&cli->mmu.object, mems); + if (ret < 0) { + NV_ERROR(drm, "No supported MEM class\n"); + goto done; + } + + cli->mem = &mems[ret]; + if (1) { cli->vm = cli->vmm.vm; nvxx_client(&cli->base)->vm = cli->vm; } + return 0; done: if (ret) nouveau_cli_fini(cli); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 25e0fb73747b..df9d9a71dde5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -95,6 +95,7 @@ struct nouveau_cli { struct nvif_device device; struct nvif_mmu mmu; struct nouveau_vmm vmm; + const struct nvif_mclass *mem; struct nvkm_vm *vm; struct list_head head; -- cgit v1.2.3 From 814a23243bd2aaa9aafe03d85d0502a73be42b58 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: implement per-client delayed workqueue with fence support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 56 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 14 +++++++++ 2 files changed, 70 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index e82da06d82f0..0ff4d669e372 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -111,9 +111,63 @@ nouveau_name(struct drm_device *dev) return nouveau_platform_name(to_platform_device(dev->dev)); } +static inline bool +nouveau_cli_work_ready(struct dma_fence *fence, bool wait) +{ + if (!dma_fence_is_signaled(fence)) { + if (!wait) + return false; + WARN_ON(dma_fence_wait_timeout(fence, false, 2 * HZ) <= 0); + } + dma_fence_put(fence); + return true; +} + +static void +nouveau_cli_work_flush(struct nouveau_cli *cli, bool wait) +{ + struct nouveau_cli_work *work, *wtmp; + mutex_lock(&cli->lock); + list_for_each_entry_safe(work, wtmp, &cli->worker, head) { + if (!work->fence || nouveau_cli_work_ready(work->fence, wait)) { + list_del(&work->head); + work->func(work); + } + } + mutex_unlock(&cli->lock); +} + +static void +nouveau_cli_work_fence(struct dma_fence *fence, struct dma_fence_cb *cb) +{ + struct nouveau_cli_work *work = container_of(cb, typeof(*work), cb); + schedule_work(&work->cli->work); +} + +void +nouveau_cli_work_queue(struct nouveau_cli *cli, struct dma_fence *fence, + struct nouveau_cli_work *work) +{ + work->fence = dma_fence_get(fence); + work->cli = cli; + mutex_lock(&cli->lock); + list_add_tail(&work->head, &cli->worker); + mutex_unlock(&cli->lock); + if (dma_fence_add_callback(fence, &work->cb, nouveau_cli_work_fence)) + nouveau_cli_work_fence(fence, &work->cb); +} + +static void +nouveau_cli_work(struct work_struct *w) +{ + struct nouveau_cli *cli = container_of(w, typeof(*cli), work); + nouveau_cli_work_flush(cli, false); +} + static void nouveau_cli_fini(struct nouveau_cli *cli) { + nouveau_cli_work_flush(cli, true); usif_client_fini(cli); nouveau_vmm_fini(&cli->vmm); nvif_mmu_fini(&cli->mmu); @@ -158,6 +212,8 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, mutex_init(&cli->mutex); usif_client_init(cli); + INIT_WORK(&cli->work, nouveau_cli_work); + INIT_LIST_HEAD(&cli->worker); mutex_init(&cli->lock); if (cli == &drm->master) { diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index df9d9a71dde5..68088b361e5e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -104,9 +104,23 @@ struct nouveau_cli { struct list_head notifys; char name[32]; + struct work_struct work; + struct list_head worker; struct mutex lock; }; +struct nouveau_cli_work { + void (*func)(struct nouveau_cli_work *); + struct nouveau_cli *cli; + struct list_head head; + + struct dma_fence *fence; + struct dma_fence_cb cb; +}; + +void nouveau_cli_work_queue(struct nouveau_cli *, struct dma_fence *, + struct nouveau_cli_work *); + static inline struct nouveau_cli * nouveau_cli(struct drm_file *fpriv) { -- cgit v1.2.3 From 00d041d087c1715039bf7a610140ffe1af347b55 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: queue delayed unmapping of VMAs on client workqueue VMAs are about to not take references on the VMM they belong to, which means more care is required when handling delayed unmapping. Queuing it on the client workqueue ensures all pending VMA unmaps will have completed before the VMM is destroyed. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 36 +++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index a600c4386c72..2cf94e059170 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -90,19 +90,33 @@ out: return ret; } +struct nouveau_gem_object_unmap { + struct nouveau_cli_work work; + struct nouveau_vma *vma; +}; + static void -nouveau_gem_object_delete(void *data) +nouveau_gem_object_delete(struct nouveau_vma *vma) { - struct nouveau_vma *vma = data; nouveau_vma_del(&vma); } +static void +nouveau_gem_object_delete_work(struct nouveau_cli_work *w) +{ + struct nouveau_gem_object_unmap *work = + container_of(w, typeof(*work), work); + nouveau_gem_object_delete(work->vma); + kfree(work); +} + static void nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma) { const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM; struct reservation_object *resv = nvbo->bo.resv; struct reservation_object_list *fobj; + struct nouveau_gem_object_unmap *work; struct dma_fence *fence = NULL; fobj = reservation_object_get_list(resv); @@ -117,10 +131,20 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma) else fence = reservation_object_get_excl(nvbo->bo.resv); - if (fence && mapped) - nouveau_fence_work(fence, nouveau_gem_object_delete, vma); - else - nouveau_vma_del(&vma); + if (!fence || !mapped) { + nouveau_gem_object_delete(vma); + return; + } + + if (!(work = kmalloc(sizeof(*work), GFP_KERNEL))) { + WARN_ON(dma_fence_wait_timeout(fence, false, 2 * HZ) <= 0); + nouveau_gem_object_delete(vma); + return; + } + + work->work.func = nouveau_gem_object_delete_work; + work->vma = vma; + nouveau_cli_work_queue(vma->vmm->cli, fence, &work->work); } void -- cgit v1.2.3 From 10842ba074e95efad1ac7de2f5279910988f3e68 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: remove unused nouveau_fence_work() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 56 --------------------------------- drivers/gpu/drm/nouveau/nouveau_fence.h | 1 - 2 files changed, 57 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 3e4412d11571..503fa94dc06d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -199,62 +199,6 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha WARN_ON(ret); } -struct nouveau_fence_work { - struct work_struct work; - struct dma_fence_cb cb; - void (*func)(void *); - void *data; -}; - -static void -nouveau_fence_work_handler(struct work_struct *kwork) -{ - struct nouveau_fence_work *work = container_of(kwork, typeof(*work), work); - work->func(work->data); - kfree(work); -} - -static void nouveau_fence_work_cb(struct dma_fence *fence, struct dma_fence_cb *cb) -{ - struct nouveau_fence_work *work = container_of(cb, typeof(*work), cb); - - schedule_work(&work->work); -} - -void -nouveau_fence_work(struct dma_fence *fence, - void (*func)(void *), void *data) -{ - struct nouveau_fence_work *work; - - if (dma_fence_is_signaled(fence)) - goto err; - - work = kmalloc(sizeof(*work), GFP_KERNEL); - if (!work) { - /* - * this might not be a nouveau fence any more, - * so force a lazy wait here - */ - WARN_ON(nouveau_fence_wait((struct nouveau_fence *)fence, - true, false)); - goto err; - } - - INIT_WORK(&work->work, nouveau_fence_work_handler); - work->func = func; - work->data = data; - - if (dma_fence_add_callback(fence, &work->cb, nouveau_fence_work_cb) < 0) - goto err_free; - return; - -err_free: - kfree(work); -err: - func(data); -} - int nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) { diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index d32e58b66a75..c36031aa013e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -22,7 +22,6 @@ void nouveau_fence_unref(struct nouveau_fence **); int nouveau_fence_emit(struct nouveau_fence *, struct nouveau_channel *); bool nouveau_fence_done(struct nouveau_fence *); -void nouveau_fence_work(struct dma_fence *, void (*)(void *), void *); int nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr); int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool exclusive, bool intr); -- cgit v1.2.3 From d7722134b8254bcee6086230723814cddf9ab54b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: switch over to new memory and vmm interfaces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/device.h | 2 - drivers/gpu/drm/nouveau/nouveau_bo.c | 92 +++++++----- drivers/gpu/drm/nouveau/nouveau_chan.c | 11 ++ drivers/gpu/drm/nouveau/nouveau_gem.c | 1 + drivers/gpu/drm/nouveau/nouveau_mem.c | 192 +++++++++++++++----------- drivers/gpu/drm/nouveau/nouveau_mem.h | 21 +-- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 2 +- drivers/gpu/drm/nouveau/nouveau_ttm.c | 18 +-- drivers/gpu/drm/nouveau/nouveau_vmm.c | 24 ++-- drivers/gpu/drm/nouveau/nouveau_vmm.h | 2 - 10 files changed, 209 insertions(+), 156 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index 9a29b7ca3105..e130af489a47 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -38,7 +38,6 @@ u64 nvif_device_time(struct nvif_device *); /*XXX*/ #include #include -#include #include #include #include @@ -57,7 +56,6 @@ u64 nvif_device_time(struct nvif_device *); }) #define nvxx_bios(a) nvxx_device(a)->bios #define nvxx_fb(a) nvxx_device(a)->fb -#define nvxx_mmu(a) nvxx_device(a)->mmu #define nvxx_gpio(a) nvxx_device(a)->gpio #define nvxx_clk(a) nvxx_device(a)->clk #define nvxx_i2c(a) nvxx_device(a)->i2c diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 3577ab2d5d69..8cab46ec8637 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -40,6 +40,10 @@ #include "nouveau_mem.h" #include "nouveau_vmm.h" +#include +#include +#include + /* * NV10-NV40 tiling helpers */ @@ -1034,21 +1038,18 @@ nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo, { struct nouveau_mem *old_mem = nouveau_mem(&bo->mem); struct nouveau_mem *new_mem = nouveau_mem(reg); - struct nvkm_vm *vmm = drm->client.vm; - u64 size = (u64)reg->num_pages << PAGE_SHIFT; + struct nvif_vmm *vmm = &drm->client.vmm.vmm; int ret; - ret = nvkm_vm_get(vmm, size, old_mem->mem.page, NV_MEM_ACCESS_RW, - &old_mem->vma[0]); + ret = nvif_vmm_get(vmm, LAZY, false, old_mem->mem.page, 0, + old_mem->mem.size, &old_mem->vma[0]); if (ret) return ret; - ret = nvkm_vm_get(vmm, size, new_mem->mem.page, NV_MEM_ACCESS_RW, - &old_mem->vma[1]); - if (ret) { - nvkm_vm_put(&old_mem->vma[0]); - return ret; - } + ret = nvif_vmm_get(vmm, LAZY, false, new_mem->mem.page, 0, + new_mem->mem.size, &old_mem->vma[1]); + if (ret) + goto done; ret = nouveau_mem_map(old_mem, vmm, &old_mem->vma[0]); if (ret) @@ -1057,8 +1058,8 @@ nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo, ret = nouveau_mem_map(new_mem, vmm, &old_mem->vma[1]); done: if (ret) { - nvkm_vm_put(&old_mem->vma[1]); - nvkm_vm_put(&old_mem->vma[0]); + nvif_vmm_put(vmm, &old_mem->vma[1]); + nvif_vmm_put(vmm, &old_mem->vma[0]); } return 0; } @@ -1374,7 +1375,6 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) struct nouveau_drm *drm = nouveau_bdev(bdev); struct nvkm_device *device = nvxx_device(&drm->client.device); struct nouveau_mem *mem = nouveau_mem(reg); - int ret; reg->bus.addr = NULL; reg->bus.offset = 0; @@ -1395,7 +1395,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) reg->bus.is_iomem = !drm->agp.cma; } #endif - if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA || !mem->kind) + if (drm->client.mem->oclass < NVIF_CLASS_MEM_NV50 || !mem->kind) /* untiled */ break; /* fallthrough, tiled memory */ @@ -1403,20 +1403,40 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) reg->bus.offset = reg->start << PAGE_SHIFT; reg->bus.base = device->func->resource_addr(device, 1); reg->bus.is_iomem = true; - if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); - int page_shift = 12; - if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) - page_shift = mem->mem.page; - - ret = nvkm_vm_get(bar, mem->_mem->size << 12, - page_shift, NV_MEM_ACCESS_RW, - &mem->bar_vma); - if (ret) - return ret; + if (drm->client.mem->oclass >= NVIF_CLASS_MEM_NV50) { + union { + struct nv50_mem_map_v0 nv50; + struct gf100_mem_map_v0 gf100; + } args; + u64 handle, length; + u32 argc = 0; + int ret; + + switch (mem->mem.object.oclass) { + case NVIF_CLASS_MEM_NV50: + args.nv50.version = 0; + args.nv50.ro = 0; + args.nv50.kind = mem->kind; + args.nv50.comp = mem->comp; + break; + case NVIF_CLASS_MEM_GF100: + args.gf100.version = 0; + args.gf100.ro = 0; + args.gf100.kind = mem->kind; + break; + default: + WARN_ON(1); + break; + } + + ret = nvif_object_map_handle(&mem->mem.object, + &argc, argc, + &handle, &length); + if (ret != 1) + return ret ? ret : -EINVAL; - nvkm_vm_map(&mem->bar_vma, mem->_mem); - reg->bus.offset = mem->bar_vma.offset; + reg->bus.base = 0; + reg->bus.offset = handle; } break; default: @@ -1428,12 +1448,22 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) static void nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) { + struct nouveau_drm *drm = nouveau_bdev(bdev); struct nouveau_mem *mem = nouveau_mem(reg); - if (!mem->bar_vma.node) - return; - - nvkm_vm_put(&mem->bar_vma); + if (drm->client.mem->oclass >= NVIF_CLASS_MEM_NV50) { + switch (reg->mem_type) { + case TTM_PL_TT: + if (mem->kind) + nvif_object_unmap_handle(&mem->mem.object); + break; + case TTM_PL_VRAM: + nvif_object_unmap_handle(&mem->mem.object); + break; + default: + break; + } + } } static int diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 34dbcf5f7f4e..af1116655910 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -84,6 +84,14 @@ nouveau_channel_del(struct nouveau_channel **pchan) { struct nouveau_channel *chan = *pchan; if (chan) { + struct nouveau_cli *cli = (void *)chan->user.client; + bool super; + + if (cli) { + super = cli->base.super; + cli->base.super = true; + } + if (chan->fence) nouveau_fence(chan->drm)->context_del(chan); nvif_object_fini(&chan->nvsw); @@ -98,6 +106,9 @@ nouveau_channel_del(struct nouveau_channel **pchan) nouveau_bo_unpin(chan->push.buffer); nouveau_bo_ref(NULL, &chan->push.buffer); kfree(chan); + + if (cli) + cli->base.super = super; } *pchan = NULL; } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 2cf94e059170..832cf367f071 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -31,6 +31,7 @@ #include "nouveau_ttm.h" #include "nouveau_gem.h" +#include "nouveau_mem.h" #include "nouveau_vmm.h" #include diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 17c6efb0ebec..589a9621db76 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -25,19 +25,70 @@ #include +#include +#include +#include +#include +#include +#include + int nouveau_mem_map(struct nouveau_mem *mem, - struct nvkm_vmm *vmm, struct nvkm_vma *vma) + struct nvif_vmm *vmm, struct nvif_vma *vma) { - nvkm_vm_map(vma, mem->_mem); - return 0; + union { + struct nv50_vmm_map_v0 nv50; + struct gf100_vmm_map_v0 gf100; + } args; + u32 argc = 0; + bool super; + int ret; + + switch (vmm->object.oclass) { + case NVIF_CLASS_VMM_NV04: + break; + case NVIF_CLASS_VMM_NV50: + args.nv50.version = 0; + args.nv50.ro = 0; + args.nv50.priv = 0; + args.nv50.kind = mem->kind; + args.nv50.comp = mem->comp; + argc = sizeof(args.nv50); + break; + case NVIF_CLASS_VMM_GF100: + case NVIF_CLASS_VMM_GM200: + case NVIF_CLASS_VMM_GP100: + args.gf100.version = 0; + if (mem->mem.type & NVIF_MEM_VRAM) + args.gf100.vol = 0; + else + args.gf100.vol = 1; + args.gf100.ro = 0; + args.gf100.priv = 0; + args.gf100.kind = mem->kind; + argc = sizeof(args.gf100); + break; + default: + WARN_ON(1); + return -ENOSYS; + } + + super = vmm->object.client->super; + vmm->object.client->super = true; + ret = nvif_vmm_map(vmm, vma->addr, mem->mem.size, &args, argc, + &mem->mem, 0); + vmm->object.client->super = super; + return ret; } void nouveau_mem_fini(struct nouveau_mem *mem) { - nvkm_vm_put(&mem->vma[1]); - nvkm_vm_put(&mem->vma[0]); + nvif_vmm_put(&mem->cli->drm->client.vmm.vmm, &mem->vma[1]); + nvif_vmm_put(&mem->cli->drm->client.vmm.vmm, &mem->vma[0]); + mutex_lock(&mem->cli->drm->master.lock); + nvif_mem_fini(&mem->mem); + mutex_unlock(&mem->cli->drm->master.lock); } int @@ -45,67 +96,79 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) { struct nouveau_mem *mem = nouveau_mem(reg); struct nouveau_cli *cli = mem->cli; + struct nouveau_drm *drm = cli->drm; + struct nvif_mmu *mmu = &cli->mmu; + struct nvif_mem_ram_v0 args = {}; + bool super = cli->base.super; + u8 type; + int ret; + + if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) + type = drm->ttm.type_ncoh; + else + type = drm->ttm.type_host; - if (mem->kind && cli->device.info.chipset == 0x50) + if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) mem->comp = mem->kind = 0; - if (mem->comp) { - if (cli->device.info.chipset >= 0xc0) - mem->kind = gf100_pte_storage_type_map[mem->kind]; + if (mem->comp && !(mmu->type[type].type & NVIF_MEM_COMP)) { + if (mmu->object.oclass >= NVIF_CLASS_MMU_GF100) + mem->kind = mmu->kind[mem->kind]; mem->comp = 0; } - mem->__mem.size = (reg->num_pages << PAGE_SHIFT) >> 12; - mem->__mem.memtype = (mem->comp << 7) | mem->kind; - if (tt->ttm.sg) mem->__mem.sg = tt->ttm.sg; - else mem->__mem.pages = tt->dma_address; - mem->_mem = &mem->__mem; - mem->mem.page = 12; - mem->_mem->memory = &mem->memory; - return 0; -} - -#include + if (tt->ttm.sg) args.sgl = tt->ttm.sg->sgl; + else args.dma = tt->dma_address; -struct nvkm_vram { - struct nvkm_memory memory; - struct nvkm_ram *ram; - u8 page; - struct nvkm_mm_node *mn; -}; + mutex_lock(&drm->master.lock); + cli->base.super = true; + ret = nvif_mem_init_type(mmu, cli->mem->oclass, type, PAGE_SHIFT, + reg->num_pages << PAGE_SHIFT, + &args, sizeof(args), &mem->mem); + cli->base.super = super; + mutex_unlock(&drm->master.lock); + return ret; +} int nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) { struct nouveau_mem *mem = nouveau_mem(reg); struct nouveau_cli *cli = mem->cli; - struct nvkm_device *device = nvxx_device(&cli->device); + struct nouveau_drm *drm = cli->drm; + struct nvif_mmu *mmu = &cli->mmu; + bool super = cli->base.super; u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page); - u8 type; int ret; - mem->mem.page = page; - mem->_mem = &mem->__mem; - - if (cli->device.info.chipset < 0xc0) { - type = nv50_fb_memtype[mem->kind]; - } else { - if (!mem->comp) - mem->kind = gf100_pte_storage_type_map[mem->kind]; - mem->comp = 0; - type = 0x01; + mutex_lock(&drm->master.lock); + cli->base.super = true; + switch (cli->mem->oclass) { + case NVIF_CLASS_MEM_GF100: + ret = nvif_mem_init_type(mmu, cli->mem->oclass, + drm->ttm.type_vram, page, size, + &(struct gf100_mem_v0) { + .contig = contig, + }, sizeof(struct gf100_mem_v0), + &mem->mem); + break; + case NVIF_CLASS_MEM_NV50: + ret = nvif_mem_init_type(mmu, cli->mem->oclass, + drm->ttm.type_vram, page, size, + &(struct nv50_mem_v0) { + .bankswz = mmu->kind[mem->kind] == 2, + .contig = contig, + }, sizeof(struct nv50_mem_v0), + &mem->mem); + break; + default: + ret = -ENOSYS; + WARN_ON(1); + break; } + cli->base.super = super; + mutex_unlock(&drm->master.lock); - ret = nvkm_ram_get(device, NVKM_RAM_MM_NORMAL, type, page, size, - contig, false, &mem->_mem->memory); - if (ret) - return ret; - - mem->_mem->size = size >> NVKM_RAM_MM_SHIFT; - mem->_mem->offset = nvkm_memory_addr(mem->_mem->memory); - mem->_mem->mem = ((struct nvkm_vram *)mem->_mem->memory)->mn; - mem->_mem->memtype = (mem->comp << 7) | mem->kind; - - reg->start = mem->_mem->offset >> PAGE_SHIFT; + reg->start = mem->mem.addr >> PAGE_SHIFT; return ret; } @@ -118,36 +181,6 @@ nouveau_mem_del(struct ttm_mem_reg *reg) reg->mm_node = NULL; } -static enum nvkm_memory_target -nouveau_mem_memory_target(struct nvkm_memory *memory) -{ - struct nouveau_mem *mem = container_of(memory, typeof(*mem), memory); - if (mem->_mem->mem) - return NVKM_MEM_TARGET_VRAM; - return NVKM_MEM_TARGET_HOST; -}; - -static u8 -nouveau_mem_memory_page(struct nvkm_memory *memory) -{ - struct nouveau_mem *mem = container_of(memory, typeof(*mem), memory); - return mem->mem.page; -}; - -static u64 -nouveau_mem_memory_size(struct nvkm_memory *memory) -{ - struct nouveau_mem *mem = container_of(memory, typeof(*mem), memory); - return mem->_mem->size << 12; -} - -static const struct nvkm_memory_func -nouveau_mem_memory = { - .target = nouveau_mem_memory_target, - .page = nouveau_mem_memory_page, - .size = nouveau_mem_memory_size, -}; - int nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp, struct ttm_mem_reg *reg) @@ -159,7 +192,6 @@ nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp, mem->cli = cli; mem->kind = kind; mem->comp = comp; - nvkm_memory_ctor(&nouveau_mem_memory, &mem->memory); reg->mm_node = mem; return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.h b/drivers/gpu/drm/nouveau/nouveau_mem.h index 3e34566116c4..f6d039e73812 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.h +++ b/drivers/gpu/drm/nouveau/nouveau_mem.h @@ -1,12 +1,11 @@ #ifndef __NOUVEAU_MEM_H__ #define __NOUVEAU_MEM_H__ -#include -#include -#include - #include struct ttm_dma_tt; +#include +#include + static inline struct nouveau_mem * nouveau_mem(struct ttm_mem_reg *reg) { @@ -17,16 +16,8 @@ struct nouveau_mem { struct nouveau_cli *cli; u8 kind; u8 comp; - struct { - u8 page; - } mem; - struct nvkm_vma vma[2]; - - struct nvkm_mem __mem; - struct nvkm_mem *_mem; - struct nvkm_vma bar_vma; - - struct nvkm_memory memory; + struct nvif_mem mem; + struct nvif_vma vma[2]; }; int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp, @@ -35,5 +26,5 @@ void nouveau_mem_del(struct ttm_mem_reg *); int nouveau_mem_vram(struct ttm_mem_reg *, bool contig, u8 page); int nouveau_mem_host(struct ttm_mem_reg *, struct ttm_dma_tt *); void nouveau_mem_fini(struct nouveau_mem *); -int nouveau_mem_map(struct nouveau_mem *, struct nvkm_vmm *, struct nvkm_vma *); +int nouveau_mem_map(struct nouveau_mem *, struct nvif_vmm *, struct nvif_vma *); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 69c606f97784..941bf33bd249 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -35,7 +35,7 @@ nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *reg) if (ret) return ret; - ret = nouveau_mem_map(mem, mem->cli->vm, &mem->vma[0]); + ret = nouveau_mem_map(mem, &mem->cli->vmm.vmm, &mem->vma[0]); if (ret) { nouveau_mem_fini(mem); return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 15c1091cccb5..08b974b30482 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -56,15 +56,6 @@ nouveau_manager_debug(struct ttm_mem_type_manager *man, { } -static void -nouveau_vram_manager_del(struct ttm_mem_type_manager *man, - struct ttm_mem_reg *reg) -{ - struct nvkm_memory *memory = nouveau_mem(reg)->_mem->memory; - nouveau_mem_del(reg); - nvkm_memory_unref(&memory); -} - static int nouveau_vram_manager_new(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, @@ -101,7 +92,7 @@ const struct ttm_mem_type_manager_func nouveau_vram_manager = { .init = nouveau_manager_init, .takedown = nouveau_manager_fini, .get_node = nouveau_vram_manager_new, - .put_node = nouveau_vram_manager_del, + .put_node = nouveau_manager_del, .debug = nouveau_manager_debug, }; @@ -121,7 +112,6 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, if (ret) return ret; - mem->_mem = &mem->__mem; reg->start = 0; return 0; } @@ -143,7 +133,6 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, struct nouveau_bo *nvbo = nouveau_bo(bo); struct nouveau_drm *drm = nvbo->cli->drm; struct nouveau_mem *mem; - struct nvkm_mmu *mmu = nvxx_mmu(&drm->client.device); int ret; ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg); @@ -151,8 +140,8 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, if (ret) return ret; - ret = nvkm_vm_get(mmu->vmm, reg->num_pages << 12, 12, - NV_MEM_ACCESS_RW, &mem->vma[0]); + ret = nvif_vmm_get(&mem->cli->vmm.vmm, PTES, false, 12, 0, + reg->num_pages << PAGE_SHIFT, &mem->vma[0]); if (ret) { nouveau_mem_del(reg); if (ret == -ENOSPC) { @@ -162,7 +151,6 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, return ret; } - mem->_mem = &mem->__mem; reg->start = mem->vma[0].addr >> PAGE_SHIFT; return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index 656f43ad012d..2367ddf19513 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -28,7 +28,7 @@ void nouveau_vma_unmap(struct nouveau_vma *vma) { if (vma->mem) { - nvkm_vm_unmap(&vma->_vma); + nvif_vmm_unmap(&vma->vmm->vmm, vma->addr); vma->mem = NULL; } } @@ -36,7 +36,8 @@ nouveau_vma_unmap(struct nouveau_vma *vma) int nouveau_vma_map(struct nouveau_vma *vma, struct nouveau_mem *mem) { - int ret = nouveau_mem_map(mem, vma->vmm->vm, &vma->_vma); + struct nvif_vma tmp = { .addr = vma->addr }; + int ret = nouveau_mem_map(mem, &vma->vmm->vmm, &tmp); if (ret) return ret; vma->mem = mem; @@ -61,8 +62,10 @@ nouveau_vma_del(struct nouveau_vma **pvma) { struct nouveau_vma *vma = *pvma; if (vma && --vma->refs <= 0) { - if (likely(vma->addr != ~0ULL)) - nvkm_vm_put(&vma->_vma); + if (likely(vma->addr != ~0ULL)) { + struct nvif_vma tmp = { .addr = vma->addr, .size = 1 }; + nvif_vmm_put(&vma->vmm->vmm, &tmp); + } list_del(&vma->head); *pvma = NULL; kfree(*pvma); @@ -75,6 +78,7 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm, { struct nouveau_mem *mem = nouveau_mem(&nvbo->bo.mem); struct nouveau_vma *vma; + struct nvif_vma tmp; int ret; if ((vma = *pvma = nouveau_vma_find(nvbo, vmm))) { @@ -92,17 +96,17 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm, if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && mem->mem.page == nvbo->page) { - ret = nvkm_vm_get(vmm->vm, mem->_mem->size << 12, mem->mem.page, - NV_MEM_ACCESS_RW, &vma->_vma); + ret = nvif_vmm_get(&vmm->vmm, LAZY, false, mem->mem.page, 0, + mem->mem.size, &tmp); if (ret) goto done; - vma->addr = vma->_vma.offset; + vma->addr = tmp.addr; ret = nouveau_vma_map(vma, mem); } else { - ret = nvkm_vm_get(vmm->vm, mem->_mem->size << 12, mem->mem.page, - NV_MEM_ACCESS_RW, &vma->_vma); - vma->addr = vma->_vma.offset; + ret = nvif_vmm_get(&vmm->vmm, PTES, false, mem->mem.page, 0, + mem->mem.size, &tmp); + vma->addr = tmp.addr; } done: diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.h b/drivers/gpu/drm/nouveau/nouveau_vmm.h index c7b9c55bc535..90de326b0a82 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.h +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.h @@ -12,8 +12,6 @@ struct nouveau_vma { u64 addr; struct nouveau_mem *mem; - - struct nvkm_vma _vma; }; struct nouveau_vma *nouveau_vma_find(struct nouveau_bo *, struct nouveau_vmm *); -- cgit v1.2.3 From 7dc6a446da7caf5ea5cf48f2b8843366ee8b0979 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau: improve selection of GPU page size Enables the use of Pascal's 2MiB pages for larger buffers. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 48 ++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 8cab46ec8637..2615912430cc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -194,9 +194,10 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, struct nouveau_drm *drm = cli->drm; struct nouveau_bo *nvbo; struct nvif_mmu *mmu = &cli->mmu; + struct nvif_vmm *vmm = &cli->vmm.vmm; size_t acc_size; - int ret; int type = ttm_bo_type_device; + int ret, i, pi = -1; if (!size) { NV_WARN(drm, "skipped size %016llx\n", size); @@ -249,16 +250,43 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, nvbo->mode = tile_mode; nvbo->contig = !(tile_flags & NOUVEAU_GEM_TILE_NONCONTIG); - nvbo->page = 12; - if (drm->client.vm) { - if (!(flags & TTM_PL_FLAG_TT) && size > 256 * 1024) - nvbo->page = drm->client.vm->mmu->lpg_shift; - else { - if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) - nvbo->kind = mmu->kind[nvbo->kind]; - nvbo->comp = 0; - } + /* Determine the desirable target GPU page size for the buffer. */ + for (i = 0; i < vmm->page_nr; i++) { + /* Because we cannot currently allow VMM maps to fail + * during buffer migration, we need to determine page + * size for the buffer up-front, and pre-allocate its + * page tables. + * + * Skip page sizes that can't support needed domains. + */ + if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && + (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) + continue; + if ((flags & TTM_PL_FLAG_TT ) && !vmm->page[i].host) + continue; + + /* Select this page size if it's the first that supports + * the potential memory domains, or when it's compatible + * with the requested compression settings. + */ + if (pi < 0 || !nvbo->comp || vmm->page[i].comp) + pi = i; + + /* Stop once the buffer is larger than the current page size. */ + if (size >= 1ULL << vmm->page[i].shift) + break; + } + + if (WARN_ON(pi < 0)) + return -EINVAL; + + /* Disable compression if suitable settings couldn't be found. */ + if (nvbo->comp && !vmm->page[pi].comp) { + if (mmu->object.oclass >= NVIF_CLASS_MMU_GF100) + nvbo->kind = mmu->kind[nvbo->kind]; + nvbo->comp = 0; } + nvbo->page = vmm->page[pi].shift; nouveau_bo_fixup_align(nvbo, flags, &align, &size); nvbo->bo.mem.num_pages = size >> PAGE_SHIFT; -- cgit v1.2.3 From 632b740c5481988152a3a60319aaa49c99577b77 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau/mmu: remove old vmm frontend Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/device.h | 2 - drivers/gpu/drm/nouveau/include/nvkm/core/client.h | 2 - drivers/gpu/drm/nouveau/include/nvkm/core/os.h | 2 - drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 14 -- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 26 +-- drivers/gpu/drm/nouveau/nouveau_drm.c | 6 - drivers/gpu/drm/nouveau/nouveau_drv.h | 1 - drivers/gpu/drm/nouveau/nouveau_gem.c | 7 - drivers/gpu/drm/nouveau/nouveau_vmm.c | 1 - drivers/gpu/drm/nouveau/nouveau_vmm.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 6 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c | 10 -- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp10b.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c | 9 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c | 19 -- drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 5 - drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 9 - .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 11 -- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 195 --------------------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 78 ++++----- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c | 4 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 4 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 4 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c | 4 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c | 4 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 2 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 3 - 57 files changed, 40 insertions(+), 427 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index e130af489a47..b579633b80c0 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -63,10 +63,8 @@ u64 nvif_device_time(struct nvif_device *); #define nvxx_therm(a) nvxx_device(a)->therm #define nvxx_volt(a) nvxx_device(a)->volt -#include #include #include -#include #define nvxx_fifo(a) nvxx_device(a)->fifo #define nvxx_gr(a) nvxx_device(a)->gr diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h index fa58efb0d42a..79624f6d0a2b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h @@ -16,8 +16,6 @@ struct nvkm_client { void *data; int (*ntfy)(const void *, u32, const void *, u32); - struct nvkm_vm *vm; - struct list_head umem; spinlock_t lock; }; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h index 70c5c47300b4..1f0108fdd24a 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h @@ -1,7 +1,6 @@ #ifndef __NVKM_OS_H__ #define __NVKM_OS_H__ #include -#define nvkm_vmm nvkm_vm #ifdef __BIG_ENDIAN #define ioread16_native ioread16be @@ -21,5 +20,4 @@ iowrite32_native(lower_32_bits(_v), &_p[0]); \ iowrite32_native(upper_32_bits(_v), &_p[1]); \ } while(0) - #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 4af663d4d3c7..a00fd2e59215 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -20,17 +20,6 @@ #define NVKM_RAM_TYPE_VM 0x7f #define NV_MEM_COMP_VM 0x03 -struct nvkm_mem { - struct nvkm_mm_node *mem; - dma_addr_t *pages; - u32 memtype; - u64 offset; - u64 size; - struct sg_table *sg; - - struct nvkm_memory *memory; -}; - struct nvkm_fb_tile { struct nvkm_mm_node *tag; u32 addr; @@ -57,7 +46,6 @@ struct nvkm_fb { struct nvkm_memory *mmu_wr; }; -bool nvkm_fb_memtype_valid(struct nvkm_fb *, u32 memtype); void nvkm_fb_tile_init(struct nvkm_fb *, int region, u32 addr, u32 size, u32 pitch, u32 flags, struct nvkm_fb_tile *); void nvkm_fb_tile_fini(struct nvkm_fb *, int region, struct nvkm_fb_tile *); @@ -163,6 +151,4 @@ struct nvkm_ram_func { int (*prog)(struct nvkm_ram *); void (*tidy)(struct nvkm_ram *); }; - -extern const u8 gf100_pte_storage_type_map[256]; #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 0de5f8b7096a..975c42f620a0 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -1,12 +1,6 @@ #ifndef __NVKM_MMU_H__ #define __NVKM_MMU_H__ #include -struct nvkm_mem; - -struct nvkm_vm_pgt { - struct nvkm_memory *mem[2]; - u32 refcount[2]; -}; struct nvkm_vma { struct list_head head; @@ -24,14 +18,9 @@ struct nvkm_vma { bool busy:1; /* Region busy (for temporarily preventing user access). */ struct nvkm_memory *memory; /* Memory currently mapped into VMA. */ struct nvkm_tags *tags; /* Compression tag reference. */ - - struct nvkm_vma *node; - struct nvkm_vm *vm; - u64 offset; - u32 access; }; -struct nvkm_vm { +struct nvkm_vmm { const struct nvkm_vmm_func *func; struct nvkm_mmu *mmu; const char *name; @@ -56,17 +45,6 @@ struct nvkm_vm { void *nullp; }; -int nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset, - struct lock_class_key *, struct nvkm_vm **); -int nvkm_vm_ref(struct nvkm_vm *, struct nvkm_vm **, struct nvkm_memory *inst); -int nvkm_vm_boot(struct nvkm_vm *, u64 size); -int nvkm_vm_get(struct nvkm_vm *, u64 size, u32 page_shift, u32 access, - struct nvkm_vma *); -void nvkm_vm_put(struct nvkm_vma *); -void nvkm_vm_map(struct nvkm_vma *, struct nvkm_mem *); -void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, struct nvkm_mem *); -void nvkm_vm_unmap(struct nvkm_vma *); - int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc, struct lock_class_key *, const char *name, struct nvkm_vmm **); struct nvkm_vmm *nvkm_vmm_ref(struct nvkm_vmm *); @@ -105,9 +83,7 @@ struct nvkm_mmu { const struct nvkm_mmu_func *func; struct nvkm_subdev subdev; - u64 limit; u8 dma_bits; - u8 lpg_shift; int heap_nr; struct { diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 0ff4d669e372..8d4a5be3b913 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -271,12 +271,6 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, } cli->mem = &mems[ret]; - - if (1) { - cli->vm = cli->vmm.vm; - nvxx_client(&cli->base)->vm = cli->vm; - } - return 0; done: if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 68088b361e5e..e86b8220a4bb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -97,7 +97,6 @@ struct nouveau_cli { struct nouveau_vmm vmm; const struct nvif_mclass *mem; - struct nvkm_vm *vm; struct list_head head; void *abi16; struct list_head objects; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 832cf367f071..efc89aaef66a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -267,18 +267,11 @@ int nouveau_gem_ioctl_new(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_cli *cli = nouveau_cli(file_priv); - struct nvkm_fb *fb = nvxx_fb(&drm->client.device); struct drm_nouveau_gem_new *req = data; struct nouveau_bo *nvbo = NULL; int ret = 0; - if (!nvkm_fb_memtype_valid(fb, req->info.tile_flags)) { - NV_PRINTK(err, cli, "bad page flags: 0x%08x\n", req->info.tile_flags); - return -EINVAL; - } - ret = nouveau_gem_new(cli, req->info.size, req->align, req->info.domain, req->info.tile_mode, req->info.tile_flags, &nvbo); diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index 2367ddf19513..9e2628dd8e4d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -131,6 +131,5 @@ nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm) return ret; vmm->cli = cli; - vmm->vm = nvkm_uvmm(vmm->vmm.object.priv)->vmm; return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.h b/drivers/gpu/drm/nouveau/nouveau_vmm.h index 90de326b0a82..5c31f43678d3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.h +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.h @@ -1,6 +1,5 @@ #ifndef __NOUVEAU_VMA_H__ #define __NOUVEAU_VMA_H__ -#include #include struct nouveau_bo; struct nouveau_mem; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index 78248e21a5f0..73b5d46104bd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -31,12 +31,6 @@ #include #include -bool -nvkm_fb_memtype_valid(struct nvkm_fb *fb, u32 memtype) -{ - return fb->func->memtype_valid(fb, memtype); -} - void nvkm_fb_tile_fini(struct nvkm_fb *fb, int region, struct nvkm_fb_tile *tile) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index a308a99ef64e..47d28c279707 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c @@ -27,15 +27,6 @@ #include #include -extern const u8 gf100_pte_storage_type_map[256]; - -bool -gf100_fb_memtype_valid(struct nvkm_fb *fb, u32 tile_flags) -{ - u8 memtype = (tile_flags & 0x0000ff00) >> 8; - return likely((gf100_pte_storage_type_map[memtype] != 0xff)); -} - void gf100_fb_intr(struct nvkm_fb *base) { @@ -140,7 +131,6 @@ gf100_fb = { .init_page = gf100_fb_init_page, .intr = gf100_fb_intr, .ram_new = gf100_ram_new, - .memtype_valid = gf100_fb_memtype_valid, .default_bigpage = 17, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c index 4c012fa02de1..4a9f463745b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c @@ -32,7 +32,6 @@ gf108_fb = { .init_page = gf100_fb_init_page, .intr = gf100_fb_intr, .ram_new = gf108_ram_new, - .memtype_valid = gf100_fb_memtype_valid, .default_bigpage = 17, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c index 7ff647499acf..0a6e8eaad42c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c @@ -32,7 +32,6 @@ gk104_fb = { .init_page = gf100_fb_init_page, .intr = gf100_fb_intr, .ram_new = gk104_ram_new, - .memtype_valid = gf100_fb_memtype_valid, .default_bigpage = 17, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c index 59308575b1d4..a7e29b125094 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c @@ -30,7 +30,6 @@ gk20a_fb = { .init = gf100_fb_init, .init_page = gf100_fb_init_page, .intr = gf100_fb_intr, - .memtype_valid = gf100_fb_memtype_valid, .default_bigpage = 17, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c index 005aa9d6db32..69c876d5d1c1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c @@ -32,7 +32,6 @@ gm107_fb = { .init_page = gf100_fb_init_page, .intr = gf100_fb_intr, .ram_new = gm107_ram_new, - .memtype_valid = gf100_fb_memtype_valid, .default_bigpage = 17, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c index 1be0b9e98b84..8137e19d3292 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c @@ -65,7 +65,6 @@ gm200_fb = { .init_page = gm200_fb_init_page, .intr = gf100_fb_intr, .ram_new = gm200_ram_new, - .memtype_valid = gf100_fb_memtype_valid, .default_bigpage = 0 /* per-instance. */, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c index e66a0a871043..12db61e31128 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c @@ -30,7 +30,6 @@ gm20b_fb = { .init = gm200_fb_init, .init_page = gm200_fb_init_page, .intr = gf100_fb_intr, - .memtype_valid = gf100_fb_memtype_valid, .default_bigpage = 0 /* per-instance. */, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c index 98474aec1921..147f69b30cd8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c @@ -59,7 +59,6 @@ gp100_fb = { .init_page = gm200_fb_init_page, .init_unkn = gp100_fb_init_unkn, .ram_new = gp100_ram_new, - .memtype_valid = gf100_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c index 73b4ae1c73dc..b84b9861ef26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c @@ -33,7 +33,6 @@ gp102_fb = { .init = gp100_fb_init, .init_page = gm200_fb_init_page, .ram_new = gp100_ram_new, - .memtype_valid = gf100_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp10b.c index f2b1fbf428d5..af8e43979dc1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp10b.c @@ -28,7 +28,6 @@ gp10b_fb = { .init = gm200_fb_init, .init_page = gm200_fb_init_page, .intr = gf100_fb_intr, - .memtype_valid = gf100_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c index 8ff2e5db4571..c886664533c8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c @@ -25,14 +25,6 @@ #include "ram.h" #include "regsnv04.h" -bool -nv04_fb_memtype_valid(struct nvkm_fb *fb, u32 tile_flags) -{ - if (!(tile_flags & 0xff00)) - return true; - return false; -} - static void nv04_fb_init(struct nvkm_fb *fb) { @@ -49,7 +41,6 @@ static const struct nvkm_fb_func nv04_fb = { .init = nv04_fb_init, .ram_new = nv04_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c index e8c44f5a3d84..c998b7e96aa3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c @@ -61,7 +61,6 @@ nv10_fb = { .tile.fini = nv10_fb_tile_fini, .tile.prog = nv10_fb_tile_prog, .ram_new = nv10_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c index 2ae0beb87567..7b9f04f44af8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c @@ -33,7 +33,6 @@ nv1a_fb = { .tile.fini = nv10_fb_tile_fini, .tile.prog = nv10_fb_tile_prog, .ram_new = nv1a_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c index 20e47248ba36..a021d21ff153 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c @@ -93,7 +93,6 @@ nv20_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv20_fb_tile_prog, .ram_new = nv20_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c index dc2965514abe..7709f5fe9a45 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c @@ -51,7 +51,6 @@ nv25_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv20_fb_tile_prog, .ram_new = nv20_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c index 28b147d8d628..8aa782666507 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c @@ -124,7 +124,6 @@ nv30_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv20_fb_tile_prog, .ram_new = nv20_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c index 4e213da6a215..6e83dcff72e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c @@ -53,7 +53,6 @@ nv35_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv20_fb_tile_prog, .ram_new = nv20_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c index 9f029f02088c..2a07617bb44c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c @@ -53,7 +53,6 @@ nv36_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv20_fb_tile_prog, .ram_new = nv20_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c index 893bc8b3cc80..955160778b5b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c @@ -59,7 +59,6 @@ nv40_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv20_fb_tile_prog, .ram_new = nv40_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c index c1a79564a2f5..b77f08d34cc3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c @@ -53,7 +53,6 @@ nv41_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv41_fb_tile_prog, .ram_new = nv41_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c index 06246cce5ec4..b59dc486083d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c @@ -62,7 +62,6 @@ nv44_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv44_fb_tile_prog, .ram_new = nv44_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c index 3598a1aa65be..cab7d20fa039 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c @@ -48,7 +48,6 @@ nv46_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv44_fb_tile_prog, .ram_new = nv44_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c index d1d5fc952e32..a8b0ad4c871d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c @@ -36,7 +36,6 @@ nv47_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv41_fb_tile_prog, .ram_new = nv41_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c index b3dff3543062..d0b317bb0252 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c @@ -36,7 +36,6 @@ nv49_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv41_fb_tile_prog, .ram_new = nv49_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c index 4e98210c1b1c..6a6f0c086071 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c @@ -34,7 +34,6 @@ nv4e_fb = { .tile.fini = nv20_fb_tile_fini, .tile.prog = nv44_fb_tile_prog, .ram_new = nv44_ram_new, - .memtype_valid = nv04_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c index da797c4525b2..b2f5bf8144ea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c @@ -28,18 +28,6 @@ #include #include -int -nv50_fb_memtype[0x80] = { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0 -}; - static int nv50_fb_ram_new(struct nvkm_fb *base, struct nvkm_ram **pram) { @@ -47,12 +35,6 @@ nv50_fb_ram_new(struct nvkm_fb *base, struct nvkm_ram **pram) return fb->func->ram_new(&fb->base, pram); } -static bool -nv50_fb_memtype_valid(struct nvkm_fb *fb, u32 memtype) -{ - return nv50_fb_memtype[(memtype & 0xff00) >> 8] != 0; -} - static const struct nvkm_enum vm_dispatch_subclients[] = { { 0x00000000, "GRCTX" }, { 0x00000001, "NOTIFY" }, @@ -276,7 +258,6 @@ nv50_fb_ = { .init = nv50_fb_init, .intr = nv50_fb_intr, .ram_new = nv50_fb_ram_new, - .memtype_valid = nv50_fb_memtype_valid, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h index 74da4d7dcaa0..13231d4b00d9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h @@ -18,5 +18,4 @@ struct nv50_fb_func { int nv50_fb_new_(const struct nv50_fb_func *, struct nvkm_device *, int index, struct nvkm_fb **pfb); -extern int nv50_fb_memtype[0x80]; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index 329ff5e0115a..e05d95240e85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -25,8 +25,6 @@ struct nvkm_fb_func { int (*ram_new)(struct nvkm_fb *, struct nvkm_ram **); - bool (*memtype_valid)(struct nvkm_fb *, u32 memtype); - u8 default_bigpage; }; @@ -36,8 +34,6 @@ int nvkm_fb_new_(const struct nvkm_fb_func *, struct nvkm_device *device, int index, struct nvkm_fb **); int nvkm_fb_bios_memtype(struct nvkm_bios *); -bool nv04_fb_memtype_valid(struct nvkm_fb *, u32 memtype); - void nv10_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, u32 pitch, u32 flags, struct nvkm_fb_tile *); void nv10_fb_tile_fini(struct nvkm_fb *, int i, struct nvkm_fb_tile *); @@ -67,7 +63,6 @@ void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, int gf100_fb_oneinit(struct nvkm_fb *); int gf100_fb_init_page(struct nvkm_fb *); -bool gf100_fb_memtype_valid(struct nvkm_fb *, u32); int gm200_fb_init_page(struct nvkm_fb *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 5305078f730e..24c7bd505731 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -45,15 +45,6 @@ nvkm_vram_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, .mem = vram->mn, }; - if (vma->vm) { - struct nvkm_mem mem = { - .mem = vram->mn, - .memory = &vram->memory, - }; - nvkm_vm_map_at(vma, offset, &mem); - return 0; - } - return nvkm_vmm_map(vmm, vma, argv, argc, &map); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 2f60f0d18aeb..985f2990ab0d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -44,9 +44,7 @@ #include "priv.h" #include -#include #include -#include #include #include @@ -290,15 +288,6 @@ gk20a_instobj_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, .mem = node->mn, }; - if (vma->vm) { - struct nvkm_mem mem = { - .mem = node->mn, - .memory = &node->memory, - }; - nvkm_vm_map_at(vma, 0, &mem); - return 0; - } - return nvkm_vmm_map(vmm, vma, argv, argc, &map); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index e0fa0cae7960..ee11ccaf0563 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -216,67 +216,6 @@ nvkm_mmu_ptc_get(struct nvkm_mmu *mmu, u32 size, u32 align, bool zero) return pt; } -static void -nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, - struct nvkm_mem *mem, nvkm_vmm_pte_func fn, - struct nvkm_vmm_map *map) -{ - union { - struct nv50_vmm_map_v0 nv50; - struct gf100_vmm_map_v0 gf100; - } args; - struct nvkm_vmm *vmm = vma->vm; - void *argv = NULL; - u32 argc = 0; - int ret; - - map->memory = mem->memory; - map->page = page; - - if (vmm->func->valid) { - switch (vmm->mmu->subdev.device->card_type) { - case NV_50: - args.nv50.version = 0; - args.nv50.ro = !(vma->access & NV_MEM_ACCESS_WO); - args.nv50.priv = !!(vma->access & NV_MEM_ACCESS_SYS); - args.nv50.kind = (mem->memtype & 0x07f); - args.nv50.comp = (mem->memtype & 0x180) >> 7; - argv = &args.nv50; - argc = sizeof(args.nv50); - break; - case NV_C0: - case NV_E0: - case GM100: - case GP100: { - args.gf100.version = 0; - args.gf100.vol = (nvkm_memory_target(map->memory) != NVKM_MEM_TARGET_VRAM); - args.gf100.ro = !(vma->access & NV_MEM_ACCESS_WO); - args.gf100.priv = !!(vma->access & NV_MEM_ACCESS_SYS); - args.gf100.kind = (mem->memtype & 0x0ff); - argv = &args.gf100; - argc = sizeof(args.gf100); - } - break; - default: - break; - } - - ret = vmm->func->valid(vmm, argv, argc, map); - if (WARN_ON(ret)) - return; - } - - mutex_lock(&vmm->mutex); - nvkm_vmm_ptes_map(vmm, page, vma->node->addr + delta, - vma->node->size, map, fn); - mutex_unlock(&vmm->mutex); - - nvkm_memory_tags_put(vma->node->memory, vmm->mmu->subdev.device, &vma->node->tags); - nvkm_memory_unref(&vma->node->memory); - vma->node->memory = nvkm_memory_ref(map->memory); - vma->node->tags = map->tags; -} - void nvkm_mmu_ptc_dump(struct nvkm_mmu *mmu) { @@ -312,138 +251,6 @@ nvkm_mmu_ptc_init(struct nvkm_mmu *mmu) INIT_LIST_HEAD(&mmu->ptp.list); } -void -nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) -{ - const struct nvkm_vmm_page *page = &vma->vm->func->page[vma->node->page]; - if (page->desc->func->unmap) { - struct nvkm_vmm_map map = { .mem = node->mem }; - nvkm_vm_map_(page, vma, delta, node, page->desc->func->mem, &map); - return; - } -} - -static void -nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length, - struct nvkm_mem *mem) -{ - const struct nvkm_vmm_page *page = &vma->vm->func->page[vma->node->page]; - if (page->desc->func->unmap) { - struct nvkm_vmm_map map = { .sgl = mem->sg->sgl }; - nvkm_vm_map_(page, vma, delta, mem, page->desc->func->sgl, &map); - return; - } -} - -static void -nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length, - struct nvkm_mem *mem) -{ - const struct nvkm_vmm_page *page = &vma->vm->func->page[vma->node->page]; - if (page->desc->func->unmap) { - struct nvkm_vmm_map map = { .dma = mem->pages }; - nvkm_vm_map_(page, vma, delta, mem, page->desc->func->dma, &map); - return; - } -} - -void -nvkm_vm_map(struct nvkm_vma *vma, struct nvkm_mem *node) -{ - if (node->sg) - nvkm_vm_map_sg_table(vma, 0, node->size << 12, node); - else - if (node->pages) - nvkm_vm_map_sg(vma, 0, node->size << 12, node); - else - nvkm_vm_map_at(vma, 0, node); -} - -void -nvkm_vm_unmap(struct nvkm_vma *vma) -{ - nvkm_vmm_unmap(vma->vm, vma->node); -} - -int -nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access, - struct nvkm_vma *vma) -{ - int ret; - - mutex_lock(&vm->mutex); - ret = nvkm_vmm_get_locked(vm, true, false, false, page_shift, 0, - size, &vma->node); - mutex_unlock(&vm->mutex); - if (ret) - return ret; - - vma->memory = NULL; - vma->tags = NULL; - vma->vm = NULL; - nvkm_vm_ref(vm, &vma->vm, NULL); - vma->offset = vma->addr = vma->node->addr; - vma->access = access; - return 0; -} - -void -nvkm_vm_put(struct nvkm_vma *vma) -{ - nvkm_vmm_put(vma->vm, &vma->node); - nvkm_vm_ref(NULL, &vma->vm, NULL); -} - -int -nvkm_vm_boot(struct nvkm_vm *vm, u64 size) -{ - return nvkm_vmm_boot(vm); -} - -int -nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, - struct lock_class_key *key, struct nvkm_vm **pvm) -{ - struct nvkm_mmu *mmu = device->mmu; - - *pvm = NULL; - if (mmu->func->vmm.ctor) { - int ret = mmu->func->vmm.ctor(mmu, mm_offset, - offset + length - mm_offset, - NULL, 0, key, "legacy", pvm); - if (ret) { - nvkm_vm_ref(NULL, pvm, NULL); - return ret; - } - - return ret; - } - - return -EINVAL; -} - -int -nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_memory *inst) -{ - if (ref) { - if (inst) { - int ret = nvkm_vmm_join(ref, inst); - if (ret) - return ret; - } - - nvkm_vmm_ref(ref); - } - - if (*ptr) { - nvkm_vmm_part(*ptr, inst); - nvkm_vmm_unref(ptr); - } - - *ptr = ref; - return 0; -} - static void nvkm_mmu_type(struct nvkm_mmu *mmu, int heap, u8 type) { @@ -611,9 +418,7 @@ nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device, { nvkm_subdev_ctor(&nvkm_mmu, device, index, &mmu->subdev); mmu->func = func; - mmu->limit = func->limit; mmu->dma_bits = func->dma_bits; - mmu->lpg_shift = func->lpg_shift; nvkm_mmu_ptc_init(mmu); mmu->user.ctor = nvkm_ummu_new; mmu->user.base = func->mmu.user; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c index e53f9beda7e8..8accda5a772b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c @@ -26,9 +26,7 @@ static const struct nvkm_mmu_func g84_mmu = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 16, .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV50}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_NV50}, nv50_mem_new, nv50_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 85d237d3963c..2d075246dc46 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -29,54 +29,52 @@ /* Map from compressed to corresponding uncompressed storage type. * The value 0xff represents an invalid storage type. */ -const u8 gf100_pte_storage_type_map[256] = -{ - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, /* 0x00 */ - 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, /* 0x10 */ - 0x11, 0x11, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x27, /* 0x20 */ - 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 */ - 0xff, 0xff, 0x26, 0x27, 0x28, 0x29, 0x26, 0x27, - 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0x46, 0xff, /* 0x40 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x46, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, /* 0x50 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x60 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */ - 0xff, 0xff, 0xff, 0x7b, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x7b, /* 0x80 */ - 0x7b, 0x7b, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xa7, /* 0xa0 */ - 0xa8, 0xa9, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, - 0xa8, 0xa9, 0xaa, 0xc3, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */ - 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xc3, 0xc3, - 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */ - 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, - 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, /* 0xe0 */ - 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff, - 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xf0 */ - 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff -}; - const u8 * gf100_mmu_kind(struct nvkm_mmu *mmu, int *count) { - *count = ARRAY_SIZE(gf100_pte_storage_type_map); - return gf100_pte_storage_type_map; + static const u8 + kind[256] = { + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, /* 0x00 */ + 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, /* 0x10 */ + 0x11, 0x11, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x27, /* 0x20 */ + 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 */ + 0xff, 0xff, 0x26, 0x27, 0x28, 0x29, 0x26, 0x27, + 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0x46, 0xff, /* 0x40 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x46, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, /* 0x50 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x60 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */ + 0xff, 0xff, 0xff, 0x7b, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x7b, /* 0x80 */ + 0x7b, 0x7b, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xa7, /* 0xa0 */ + 0xa8, 0xa9, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, + 0xa8, 0xa9, 0xaa, 0xc3, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */ + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xc3, 0xc3, + 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */ + 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, + 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, /* 0xe0 */ + 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xf0 */ + 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff + }; + + *count = ARRAY_SIZE(kind); + return kind; } static const struct nvkm_mmu_func gf100_mmu = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 17, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c index 30c0217ac807..3d7d1eb1cff9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk104.c @@ -26,9 +26,7 @@ static const struct nvkm_mmu_func gk104_mmu = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 17, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk104_vmm_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c index b7bff4369d30..ac74965a60d4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c @@ -26,9 +26,7 @@ static const struct nvkm_mmu_func gk20a_mmu = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 17, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gk20a_vmm_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c index 3cabeabbcea6..dbf644ebac97 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm200.c @@ -70,9 +70,7 @@ gm200_mmu_kind(struct nvkm_mmu *mmu, int *count) static const struct nvkm_mmu_func gm200_mmu = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 17, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm200_vmm_new }, @@ -82,9 +80,7 @@ gm200_mmu = { static const struct nvkm_mmu_func gm200_mmu_fixed = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 17, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm200_vmm_new_fixed }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c index 802652539d9a..7353a94b4091 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c @@ -28,9 +28,7 @@ static const struct nvkm_mmu_func gm20b_mmu = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 17, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, 0, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new }, @@ -40,9 +38,7 @@ gm20b_mmu = { static const struct nvkm_mmu_func gm20b_mmu_fixed = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 17, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GM200}, gm20b_vmm_new_fixed }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c index 92fc18eec147..651b8805c67c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -28,9 +28,7 @@ static const struct nvkm_mmu_func gp100_mmu = { - .limit = (1ULL << 49), .dma_bits = 47, - .lpg_shift = 16, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp100_vmm_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c index e1b0f82e2e05..3bd3db31e0bb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c @@ -28,9 +28,7 @@ static const struct nvkm_mmu_func gp10b_mmu = { - .limit = (1ULL << 49), .dma_bits = 47, - .lpg_shift = 16, .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_GF100}, .umap = gf100_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gp10b_vmm_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 7505a7213156..d201c887c2cd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -26,13 +26,9 @@ #include -#define NV04_PDMA_SIZE (128 * 1024 * 1024) - const struct nvkm_mmu_func nv04_mmu = { - .limit = NV04_PDMA_SIZE, .dma_bits = 32, - .lpg_shift = 12, .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV04}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv04_vmm_new, true }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c index 8e683a0f796d..adca81895c09 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c @@ -28,8 +28,6 @@ #include -#define NV41_GART_SIZE (512 * 1024 * 1024) - static void nv41_mmu_init(struct nvkm_mmu *mmu) { @@ -42,9 +40,7 @@ nv41_mmu_init(struct nvkm_mmu *mmu) static const struct nvkm_mmu_func nv41_mmu = { .init = nv41_mmu_init, - .limit = NV41_GART_SIZE, .dma_bits = 39, - .lpg_shift = 12, .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV04}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv41_vmm_new, true }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c index 2fdc4c787b7a..598c53a27bde 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c @@ -28,8 +28,6 @@ #include -#define NV44_GART_SIZE (512 * 1024 * 1024) - static void nv44_mmu_init(struct nvkm_mmu *mmu) { @@ -57,9 +55,7 @@ nv44_mmu_init(struct nvkm_mmu *mmu) static const struct nvkm_mmu_func nv44_mmu = { .init = nv44_mmu_init, - .limit = NV44_GART_SIZE, .dma_bits = 39, - .lpg_shift = 12, .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV04}}, .mem = {{ -1, -1, NVIF_CLASS_MEM_NV04}, nv04_mem_new, nv04_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV04}, nv44_vmm_new, true }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c index 334f7fb460ab..db3dfbbb2aa0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c @@ -62,9 +62,7 @@ nv50_mmu_kind(struct nvkm_mmu *base, int *count) static const struct nvkm_mmu_func nv50_mmu = { - .limit = (1ULL << 40), .dma_bits = 40, - .lpg_shift = 16, .mmu = {{ -1, -1, NVIF_CLASS_MMU_NV50}}, .mem = {{ -1, 0, NVIF_CLASS_MEM_NV50}, nv50_mem_new, nv50_mem_map }, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index 9d7ff166e505..d024d8055fcb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -11,9 +11,7 @@ int nvkm_mmu_new_(const struct nvkm_mmu_func *, struct nvkm_device *, struct nvkm_mmu_func { void (*init)(struct nvkm_mmu *); - u64 limit; u8 dma_bits; - u8 lpg_shift; struct { struct nvkm_sclass user; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 31c4acaf44a0..6446bc61b084 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -700,7 +700,7 @@ nvkm_vmm_ptes_unmap(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, func->unmap); } -void +static void nvkm_vmm_ptes_map(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, u64 addr, u64 size, struct nvkm_vmm_map *map, nvkm_vmm_pte_func func) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 5808012f7395..6d8f61ea467a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -160,9 +160,6 @@ int nvkm_vmm_get_locked(struct nvkm_vmm *, bool getref, bool mapref, void nvkm_vmm_put_locked(struct nvkm_vmm *, struct nvkm_vma *); void nvkm_vmm_unmap_locked(struct nvkm_vmm *, struct nvkm_vma *); void nvkm_vmm_unmap_region(struct nvkm_vmm *vmm, struct nvkm_vma *vma); -void nvkm_vmm_ptes_map(struct nvkm_vmm *, const struct nvkm_vmm_page *, - u64 addr, u64 size, struct nvkm_vmm_map *, - nvkm_vmm_pte_func); struct nvkm_vma *nvkm_vma_tail(struct nvkm_vma *, u64 tail); void nvkm_vmm_node_insert(struct nvkm_vmm *, struct nvkm_vma *); -- cgit v1.2.3 From 46bda4f4af5d061ce07148e833ff4deb50737536 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:20 +1000 Subject: drm/nouveau/gr/gf100-: don't prevent module load if firmware missing Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 4b3d5432a53e..2f8dc107047d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1861,8 +1861,12 @@ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname, int ret; ret = nvkm_firmware_get(device, fwname, &fw); - if (ret) - return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret); + if (ret) { + ret = gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret); + if (ret) + return -ENODEV; + return 0; + } fuc->size = fw->size; fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL); -- cgit v1.2.3 From 6497c2baf2c66938bfff51af9806d495bbb506f9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 3 Nov 2017 08:36:25 +1000 Subject: drm/nouveau/mmu: swap out round for ALIGN Rounding value is guaranteed to be power-of-two, so this is better anyway. Fixes build on 32-bit. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 6446bc61b084..e35d3e17cd7c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -1349,12 +1349,12 @@ nvkm_vmm_get_locked(struct nvkm_vmm *vmm, bool getref, bool mapref, bool sparse, addr = this->addr; if (vmm->func->page_block && prev && prev->page != p) - addr = roundup(addr, vmm->func->page_block); + addr = ALIGN(addr, vmm->func->page_block); addr = ALIGN(addr, 1ULL << align); tail = this->addr + this->size; if (vmm->func->page_block && next && next->page != p) - tail = rounddown(tail, vmm->func->page_block); + tail = ALIGN_DOWN(addr, vmm->func->page_block); if (addr <= tail && tail - addr >= size) { rb_erase(&this->tree, &vmm->free); -- cgit v1.2.3 From 690f43ab1b659a7e072a2a0b33ff5783828c168b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 3 Nov 2017 08:37:27 +1000 Subject: drm/nouveau/core/memory: fix missing mutex unlock Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/core/memory.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c index 29f4b4070b55..e85a08ecd9da 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c @@ -64,6 +64,7 @@ nvkm_memory_tags_get(struct nvkm_memory *memory, struct nvkm_device *device, } refcount_inc(&tags->refcount); + mutex_unlock(&fb->subdev.mutex); *ptags = tags; return 0; } -- cgit v1.2.3 From 1a5c8164b335fb841fd9b41cd3d659de2f1c912b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 2 Nov 2017 18:48:12 +0000 Subject: drm/nouveau/bios: make const arrays hwsq_signature and edid_sig static Don't populate arrays hwsq_signature and edid_sig on the stack but instead make them static. Makes the object code smaller by over 190 bytes: Before: text data bss dec hex filename 35676 3312 64 39052 988c nouveau_bios.o After: text data bss dec hex filename 35319 3472 64 38855 97c7 nouveau_bios.o (gcc version 7.2.0 x86_64) Signed-off-by: Colin Ian King Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index c4ef3a0a737e..66bf2aff4a3e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -1968,7 +1968,7 @@ static int load_nv17_hw_sequencer_ucode(struct drm_device *dev, * The microcode entries are found by the "HWSQ" signature. */ - const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' }; + static const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' }; const int sz = sizeof(hwsq_signature); int hwsq_offset; @@ -1984,7 +1984,7 @@ uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); struct nvbios *bios = &drm->vbios; - const uint8_t edid_sig[] = { + static const uint8_t edid_sig[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; uint16_t offset = 0; uint16_t newoffset; -- cgit v1.2.3 From 21dce3f4643eb541c7058e37b89a44a573ac95f6 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 2 Nov 2017 15:06:25 -0500 Subject: drm/nouveau/devinit/nv04: mark expected switch fall-throughs In preparation to enabling -Wimplicit-fallthrough, mark switch cases where we are expecting to fall through. Addresses-Coverity-ID: 143119 Addresses-Coverity-ID: 143120 Addresses-Coverity-ID: 143121 Addresses-Coverity-ID: 143122 Addresses-Coverity-ID: 143123 Addresses-Coverity-ID: 143124 Signed-off-by: Gustavo A. R. Silva Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c index 158977f8a6e6..c3dae05348eb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c @@ -119,11 +119,11 @@ powerctrl_1_shift(int chip_version, int reg) switch (reg) { case 0x680520: - shift += 4; + shift += 4; /* fall through */ case 0x680508: - shift += 4; + shift += 4; /* fall through */ case 0x680504: - shift += 4; + shift += 4; /* fall through */ case 0x680500: shift += 4; } @@ -245,11 +245,11 @@ setPLL_double_highregs(struct nvkm_devinit *init, u32 reg1, switch (reg1) { case 0x680504: - shift_c040 += 2; + shift_c040 += 2; /* fall through */ case 0x680500: - shift_c040 += 2; + shift_c040 += 2; /* fall through */ case 0x680520: - shift_c040 += 2; + shift_c040 += 2; /* fall through */ case 0x680508: shift_c040 += 2; } -- cgit v1.2.3 From d34ded7ece57782e75bf31bb145836b9f280750f Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 2 Nov 2017 15:20:33 -0500 Subject: drm/nouveau/bios/timing: mark expected switch fall-throughs In preparation to enabling -Wimplicit-fallthrough, mark switch cases where we are expecting to fall through. Addresses-Coverity-ID: 1260018 Addresses-Coverity-ID: 1260019 Addresses-Coverity-ID: 1260022 Signed-off-by: Gustavo A. R. Silva Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c index 7e83c3985020..20ff5173cf8f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c @@ -115,16 +115,21 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx, switch (min_t(u8, *hdr, 25)) { case 25: p->timing_10_24 = nvbios_rd08(bios, data + 0x18); + /* fall through */ case 24: case 23: case 22: p->timing_10_21 = nvbios_rd08(bios, data + 0x15); + /* fall through */ case 21: p->timing_10_20 = nvbios_rd08(bios, data + 0x14); + /* fall through */ case 20: p->timing_10_CWL = nvbios_rd08(bios, data + 0x13); + /* fall through */ case 19: p->timing_10_18 = nvbios_rd08(bios, data + 0x12); + /* fall through */ case 18: case 17: p->timing_10_16 = nvbios_rd08(bios, data + 0x10); -- cgit v1.2.3 From e477e940dad1836c6f6d23353e424665b9316b6e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 2 Nov 2017 12:25:39 +0100 Subject: drm/amdgpu/virt: don't dereference undefined 'module' struct Accessing the THIS_MODULE directly is only possible when modules are enabled, otherwise we get a build failure: drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c: In function 'amdgpu_virt_init_data_exchange': drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c:331:20: error: dereferencing pointer to incomplete type 'struct module' Further, THIS_MODULE is NULL when the driver is built-in, so the code would likely cause a NULL pointer dereference. This adds an #ifdef check to avoid the compile-time error, plus a NULL pointer check before dereferencing THIS_MODULE. It might be better to find a way to avoid using the module version altogether. Fixes: 2dc8f81e4f82 ("drm/amdgpu: SR-IOV data exchange between PF&VF") Signed-off-by: Arnd Bergmann Signed-off-by: Alex Deucher Reviewed-by: Harry Wentland Reviewed-By: Xiangliang Yu --- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index e97f80f86005..4e4a476593e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -328,9 +328,11 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) sizeof(amdgim_vf2pf_info)); AMDGPU_FW_VRAM_VF2PF_READ(adev, driver_version, &str); +#ifdef MODULE if (THIS_MODULE->version != NULL) strcpy(str, THIS_MODULE->version); else +#endif strcpy(str, "N/A"); AMDGPU_FW_VRAM_VF2PF_WRITE(adev, driver_cert, 0); -- cgit v1.2.3 From e073db5c5d7ad311efa8f4192a2047b006bbc5f3 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 1 Nov 2017 10:57:31 +0100 Subject: drm/vc4: Fix wrong printk format in vc4_bo_stats_debugfs() vc4->purgeable.size and vc4->purgeable.purged_size are size_t fields and should be printed with a %zd specifier. Fixes: b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl") Signed-off-by: Boris Brezillon Reviewed-by: Gustavo Padovan Reviewed-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20171101095731.14878-1-boris.brezillon@free-electrons.com (cherry picked from commit 50f365cde4ffb5ae70c3f02384bbb46698aba65c) Signed-off-by: Eric Anholt --- drivers/gpu/drm/vc4/vc4_bo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 01a53ba304f8..98a6cb9f44fc 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -88,11 +88,11 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) mutex_lock(&vc4->purgeable.lock); if (vc4->purgeable.num) - seq_printf(m, "%30s: %6dkb BOs (%d)\n", "userspace BO cache", + seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "userspace BO cache", vc4->purgeable.size / 1024, vc4->purgeable.num); if (vc4->purgeable.purged_num) - seq_printf(m, "%30s: %6dkb BOs (%d)\n", "total purged BO", + seq_printf(m, "%30s: %6zdkb BOs (%d)\n", "total purged BO", vc4->purgeable.purged_size / 1024, vc4->purgeable.purged_num); mutex_unlock(&vc4->purgeable.lock); -- cgit v1.2.3 From 37c5f2c99adf63adf13f1ca309a1ffce25c5589a Mon Sep 17 00:00:00 2001 From: Akshu Agrawal Date: Mon, 18 Sep 2017 12:26:07 +0530 Subject: drm/amd/amdgpu: Enabling ACP clock in hw_init (v2) Enabling of ACP in hw_init does away with requirement of order of probe on designware_i2s and acp dma driver. designware_i2s reads i2s registers and this use to fail if acp dma driver was not probed prior to it. BUG=:b:62103837 TEST=modprobe snd-soc-acp-pcm modprobe snd-soc-acp-rt5645-mach aplay -l **** List of PLAYBACK Hardware Devices **** card 0: acprt5650 [acprt5650], device 0: RT5645_AIF1 rt5645-aif1-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 v2: use proper device in dev_err to fix warnings (Alex) Signed-off-by: Akshu Agrawal Reviewed-on: https://chromium-review.googlesource.com/670207 Reviewed-by: Jason Clinton Reviewed-on: https://chromium-review.googlesource.com/676628 Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 159 +++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index a52795d9b458..023bfdb3e63f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -35,41 +35,50 @@ #include "acp_gfx_if.h" -#define ACP_TILE_ON_MASK 0x03 -#define ACP_TILE_OFF_MASK 0x02 -#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f -#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 - -#define ACP_TILE_P1_MASK 0x3e -#define ACP_TILE_P2_MASK 0x3d -#define ACP_TILE_DSP0_MASK 0x3b -#define ACP_TILE_DSP1_MASK 0x37 - -#define ACP_TILE_DSP2_MASK 0x2f - -#define ACP_DMA_REGS_END 0x146c0 -#define ACP_I2S_PLAY_REGS_START 0x14840 -#define ACP_I2S_PLAY_REGS_END 0x148b4 -#define ACP_I2S_CAP_REGS_START 0x148b8 -#define ACP_I2S_CAP_REGS_END 0x1496c - -#define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac -#define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 -#define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c -#define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 - -#define mmACP_PGFSM_RETAIN_REG 0x51c9 -#define mmACP_PGFSM_CONFIG_REG 0x51ca -#define mmACP_PGFSM_READ_REG_0 0x51cc - -#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 -#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 -#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa -#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb - -#define ACP_TIMEOUT_LOOP 0x000000FF -#define ACP_DEVS 3 -#define ACP_SRC_ID 162 +#define ACP_TILE_ON_MASK 0x03 +#define ACP_TILE_OFF_MASK 0x02 +#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f +#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 + +#define ACP_TILE_P1_MASK 0x3e +#define ACP_TILE_P2_MASK 0x3d +#define ACP_TILE_DSP0_MASK 0x3b +#define ACP_TILE_DSP1_MASK 0x37 + +#define ACP_TILE_DSP2_MASK 0x2f + +#define ACP_DMA_REGS_END 0x146c0 +#define ACP_I2S_PLAY_REGS_START 0x14840 +#define ACP_I2S_PLAY_REGS_END 0x148b4 +#define ACP_I2S_CAP_REGS_START 0x148b8 +#define ACP_I2S_CAP_REGS_END 0x1496c + +#define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac +#define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 +#define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c +#define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 + +#define mmACP_PGFSM_RETAIN_REG 0x51c9 +#define mmACP_PGFSM_CONFIG_REG 0x51ca +#define mmACP_PGFSM_READ_REG_0 0x51cc + +#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 +#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 +#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa +#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb + +#define mmACP_CONTROL 0x5131 +#define mmACP_STATUS 0x5133 +#define mmACP_SOFT_RESET 0x5134 +#define ACP_CONTROL__ClkEn_MASK 0x1 +#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 +#define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 +#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF +#define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF + +#define ACP_TIMEOUT_LOOP 0x000000FF +#define ACP_DEVS 3 +#define ACP_SRC_ID 162 enum { ACP_TILE_P1 = 0, @@ -260,6 +269,8 @@ static int acp_hw_init(void *handle) { int r, i; uint64_t acp_base; + u32 val = 0; + u32 count = 0; struct device *dev; struct i2s_platform_data *i2s_pdata; @@ -400,6 +411,46 @@ static int acp_hw_init(void *handle) } } + /* Assert Soft reset of ACP */ + val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); + + val |= ACP_SOFT_RESET__SoftResetAud_MASK; + cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); + + count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; + while (true) { + val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); + if (ACP_SOFT_RESET__SoftResetAudDone_MASK == + (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) + break; + if (--count == 0) { + dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); + return -ETIMEDOUT; + } + udelay(100); + } + /* Enable clock to ACP and wait until the clock is enabled */ + val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); + val = val | ACP_CONTROL__ClkEn_MASK; + cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); + + count = ACP_CLOCK_EN_TIME_OUT_VALUE; + + while (true) { + val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); + if (val & (u32) 0x1) + break; + if (--count == 0) { + dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); + return -ETIMEDOUT; + } + udelay(100); + } + /* Deassert the SOFT RESET flags */ + val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); + val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; + cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); + return 0; } @@ -412,6 +463,8 @@ static int acp_hw_init(void *handle) static int acp_hw_fini(void *handle) { int i, ret; + u32 val = 0; + u32 count = 0; struct device *dev; struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -419,6 +472,42 @@ static int acp_hw_fini(void *handle) if (!adev->acp.acp_cell) return 0; + /* Assert Soft reset of ACP */ + val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); + + val |= ACP_SOFT_RESET__SoftResetAud_MASK; + cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); + + count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; + while (true) { + val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); + if (ACP_SOFT_RESET__SoftResetAudDone_MASK == + (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) + break; + if (--count == 0) { + dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); + return -ETIMEDOUT; + } + udelay(100); + } + /* Disable ACP clock */ + val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); + val &= ~ACP_CONTROL__ClkEn_MASK; + cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); + + count = ACP_CLOCK_EN_TIME_OUT_VALUE; + + while (true) { + val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); + if (val & (u32) 0x1) + break; + if (--count == 0) { + dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); + return -ETIMEDOUT; + } + udelay(100); + } + if (adev->acp.acp_genpd) { for (i = 0; i < ACP_DEVS ; i++) { dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); -- cgit v1.2.3 From e1fc12c5d9ad06a2a74e97a91f1b0c5f4c723b50 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 3 Nov 2017 16:00:35 +0100 Subject: drm/ttm: Always and only destroy bo->ttm_resv in ttm_bo_release_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a use-after-free due to a race condition in ttm_bo_cleanup_refs_and_unlock, which allows one task to reserve a BO and destroy its ttm_resv while another task is waiting for it to signal in reservation_object_wait_timeout_rcu. v2: * Always initialize bo->ttm_resv in ttm_bo_init_reserved (Christian König) Fixes: 0d2bd2ae045d "drm/ttm: fix memory leak while individualizing BOs" Reviewed-by: Chunming Zhou # v1 Reviewed-by: Christian König Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 379ec41d2c69..c088703777e2 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -150,8 +150,7 @@ static void ttm_bo_release_list(struct kref *list_kref) ttm_tt_destroy(bo->ttm); atomic_dec(&bo->glob->bo_count); dma_fence_put(bo->moving); - if (bo->resv == &bo->ttm_resv) - reservation_object_fini(&bo->ttm_resv); + reservation_object_fini(&bo->ttm_resv); mutex_destroy(&bo->wu_mutex); if (bo->destroy) bo->destroy(bo); @@ -402,14 +401,11 @@ static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo) if (bo->resv == &bo->ttm_resv) return 0; - reservation_object_init(&bo->ttm_resv); BUG_ON(!reservation_object_trylock(&bo->ttm_resv)); r = reservation_object_copy_fences(&bo->ttm_resv, bo->resv); - if (r) { + if (r) reservation_object_unlock(&bo->ttm_resv); - reservation_object_fini(&bo->ttm_resv); - } return r; } @@ -457,10 +453,8 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) if (reservation_object_test_signaled_rcu(&bo->ttm_resv, true)) { ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); - if (bo->resv != &bo->ttm_resv) { + if (bo->resv != &bo->ttm_resv) reservation_object_unlock(&bo->ttm_resv); - reservation_object_fini(&bo->ttm_resv); - } ttm_bo_cleanup_memtype_use(bo); return; @@ -560,8 +554,6 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo, } ttm_bo_del_from_lru(bo); - if (!list_empty(&bo->ddestroy) && (bo->resv != &bo->ttm_resv)) - reservation_object_fini(&bo->ttm_resv); list_del_init(&bo->ddestroy); kref_put(&bo->list_kref, ttm_bo_ref_bug); @@ -1210,8 +1202,8 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, lockdep_assert_held(&bo->resv->lock.base); } else { bo->resv = &bo->ttm_resv; - reservation_object_init(&bo->ttm_resv); } + reservation_object_init(&bo->ttm_resv); atomic_inc(&bo->glob->bo_count); drm_vma_node_reset(&bo->vma_node); bo->priority = 0; -- cgit v1.2.3 From 767601d100a53e653233aebca7c262ce0addfa99 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 3 Nov 2017 16:00:35 +0100 Subject: drm/ttm: Downgrade pr_err to pr_debug for memory allocation failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Memory allocation failure should generally be handled gracefully by callers. In particular, with transparent hugepage support, attempts to allocate huge pages can fail under memory pressure, but the callers fall back to allocating individual pages instead. In that case, there would be spurious [TTM] Unable to get page %u error messages in dmesg. Reviewed-by: Christian König Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 13 ++++++------- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 12 ++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 4d688c8d7853..316f831ad5f0 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -329,7 +329,7 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free, pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), GFP_KERNEL); if (!pages_to_free) { - pr_err("Failed to allocate memory for pool free operation\n"); + pr_debug("Failed to allocate memory for pool free operation\n"); return 0; } @@ -517,7 +517,7 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); if (!caching_array) { - pr_err("Unable to allocate table for new pages\n"); + pr_debug("Unable to allocate table for new pages\n"); return -ENOMEM; } @@ -525,7 +525,7 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, p = alloc_pages(gfp_flags, order); if (!p) { - pr_err("Unable to get page %u\n", i); + pr_debug("Unable to get page %u\n", i); /* store already allocated pages in the pool after * setting the caching state */ @@ -625,7 +625,7 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, int ttm_flags, ++pool->nrefills; pool->npages += alloc_size; } else { - pr_err("Failed to fill pool (%p)\n", pool); + pr_debug("Failed to fill pool (%p)\n", pool); /* If we have any pages left put them to the pool. */ list_for_each_entry(p, &new_pages, lru) { ++cpages; @@ -885,8 +885,7 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, while (npages) { p = alloc_page(gfp_flags); if (!p) { - - pr_err("Unable to allocate page\n"); + pr_debug("Unable to allocate page\n"); return -ENOMEM; } @@ -925,7 +924,7 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, /* If there is any pages in the list put them back to * the pool. */ - pr_err("Failed to allocate extra pages for large request\n"); + pr_debug("Failed to allocate extra pages for large request\n"); ttm_put_pages(pages, count, flags, cstate); return r; } diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 96ad12906621..6b2627fe9bc1 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -463,7 +463,7 @@ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free, GFP_KERNEL); if (!pages_to_free) { - pr_err("%s: Failed to allocate memory for pool free operation\n", + pr_debug("%s: Failed to allocate memory for pool free operation\n", pool->dev_name); return 0; } @@ -755,7 +755,7 @@ static int ttm_dma_pool_alloc_new_pages(struct dma_pool *pool, caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); if (!caching_array) { - pr_err("%s: Unable to allocate table for new pages\n", + pr_debug("%s: Unable to allocate table for new pages\n", pool->dev_name); return -ENOMEM; } @@ -768,8 +768,8 @@ static int ttm_dma_pool_alloc_new_pages(struct dma_pool *pool, for (i = 0, cpages = 0; i < count; ++i) { dma_p = __ttm_dma_alloc_page(pool); if (!dma_p) { - pr_err("%s: Unable to get page %u\n", - pool->dev_name, i); + pr_debug("%s: Unable to get page %u\n", + pool->dev_name, i); /* store already allocated pages in the pool after * setting the caching state */ @@ -855,8 +855,8 @@ static int ttm_dma_page_pool_fill_locked(struct dma_pool *pool, struct dma_page *d_page; unsigned cpages = 0; - pr_err("%s: Failed to fill %s pool (r:%d)!\n", - pool->dev_name, pool->name, r); + pr_debug("%s: Failed to fill %s pool (r:%d)!\n", + pool->dev_name, pool->name, r); list_for_each_entry(d_page, &d_pages, page_list) { cpages++; -- cgit v1.2.3 From 30cfcf01665f3c8d8dc3ebb3dfb1a8248f53404a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 6 Nov 2017 14:58:43 +0100 Subject: drm/rockchip: add CONFIG_OF dependency for lvds Build-testing on randconfig kernels revealed a dependency in the newly added lvds sub-driver: drivers/gpu/drm/rockchip/rockchip_lvds.c: In function 'rockchip_lvds_bind': drivers/gpu/drm/rockchip/rockchip_lvds.c:380:24: error: 'struct drm_bridge' has no member named 'of_node' remote = lvds->bridge->of_node; We could work around that in the code, adding a Kconfig dependency seems easier. Fixes: 34cc0aa25456 ("drm/rockchip: Add support for Rockchip Soc LVDS") Signed-off-by: Arnd Bergmann Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20171106135852.1355487-1-arnd@arndb.de --- drivers/gpu/drm/rockchip/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index 3c70c6224bd2..0ccc76217ee4 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -60,7 +60,7 @@ config ROCKCHIP_INNO_HDMI config ROCKCHIP_LVDS bool "Rockchip LVDS support" depends on DRM_ROCKCHIP - depends on PINCTRL + depends on PINCTRL && OF help Choose this option to enable support for Rockchip LVDS controllers. Rockchip rk3288 SoC has LVDS TX Controller can be used, and it -- cgit v1.2.3 From a111fbc4c44d2981f1a8fef64418685be5e30280 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 23 Oct 2017 18:25:40 +0300 Subject: drm/vblank: Tune drm_crtc_accurate_vblank_count() WARN down to a debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 632c6e4edef1 ("drm/vblank: Fix flip event vblank count") even drivers that don't implement accurate vblank timestamps will end up using drm_crtc_accurate_vblank_count(). That leads to a WARN every time drm_crtc_arm_vblank_event() gets called. The could be as often as every frame for each active crtc. Considering drm_crtc_accurate_vblank_count() is never any worse than the drm_vblank_count() we used previously, let's just skip the WARN unless DRM_UT_VBL is enabled. That way people won't be bothered by this unless they're debugging vblank code. And let's also change it to WARN_ONCE() so that even when you're debugging vblank code you won't get drowned by constant WARNs. Cc: stable@vger.kernel.org Cc: Daniel Vetter Cc: "Szyprowski, Marek" Cc: Andrzej Hajda Reported-by: Andrzej Hajda Fixes: 632c6e4edef1 ("drm/vblank: Fix flip event vblank count") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171023152540.15364-1-ville.syrjala@linux.intel.com Acked-by: Benjamin Gaignard Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_vblank.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 57cc6e37c810..09c1c4ff93ca 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -299,8 +299,8 @@ u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc) u32 vblank; unsigned long flags; - WARN(!dev->driver->get_vblank_timestamp, - "This function requires support for accurate vblank timestamps."); + WARN_ONCE(drm_debug & DRM_UT_VBL && !dev->driver->get_vblank_timestamp, + "This function requires support for accurate vblank timestamps."); spin_lock_irqsave(&dev->vblank_time_lock, flags); -- cgit v1.2.3 From 7da2e3e09e3186b672822aaade407d17eb35551f Mon Sep 17 00:00:00 2001 From: Roger He Date: Thu, 2 Nov 2017 13:14:27 +0800 Subject: drm/amd/amdgpu: fix evicted VRAM bo adjudgement condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Roger He Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index b577b717caa0..1f036af85ba6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1193,9 +1193,6 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, unsigned long num_pages = bo->mem.num_pages; struct drm_mm_node *node = bo->mem.mm_node; - if (bo->mem.start != AMDGPU_BO_INVALID_OFFSET) - return ttm_bo_eviction_valuable(bo, place); - switch (bo->mem.mem_type) { case TTM_PL_TT: return true; @@ -1210,7 +1207,7 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, num_pages -= node->size; ++node; } - break; + return false; default: break; -- cgit v1.2.3 From 1d864b82a2bde6c583f23dfc7183d07dc9b48b6d Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 6 Nov 2017 10:33:45 +0800 Subject: drm/amd/powerplay: suppress KASAN out of bounds warning in vega10_populate_all_memory_levels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Evan Quan Tested-and-Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 4239b98cf6db..b66df60afe01 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -1807,6 +1807,10 @@ static int vega10_populate_all_memory_levels(struct pp_hwmgr *hwmgr) mem_channels = (cgs_read_register(hwmgr->device, reg) & DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK) >> DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT; + PP_ASSERT_WITH_CODE(mem_channels < ARRAY_SIZE(channel_number), + "Mem Channel Index Exceeded maximum!", + return -1); + pp_table->NumMemoryChannels = cpu_to_le16(mem_channels); pp_table->MemoryChannelWidth = cpu_to_le16(HBM_MEMORY_CHANNEL_WIDTH * -- cgit v1.2.3 From 0d1da3c15291c478193b7310dfef023add2249cc Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Sun, 3 Sep 2017 14:00:57 +0200 Subject: drm/amd/powerplay: initialize a variable before using it Function vega10_apply_state_adjust_rules() only initializes stable_pstate_sclk_dpm_percentage when data->registry_data.stable_pstate_sclk_dpm_percentage is not between 1 and 100. The variable is then used to compute stable_pstate_sclk, which therefore uses an uninitialized value. Fix this by initializing stable_pstate_sclk_dpm_percentage to data->registry_data.stable_pstate_sclk_dpm_percentage. This issue has been found while building the kernel with clang. The compiler reported a -Wsometimes-uninitialized warning. Reviewed-by: Alex Deucher Fixes: f83a9991648b ("drm/amd/powerplay: add Vega10 powerplay support (v5)") Signed-off-by: Nicolas Iooss Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index b66df60afe01..4f79c21f27ed 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -3138,6 +3138,8 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, minimum_clocks.memoryClock = hwmgr->display_config.min_mem_set_clock; if (PP_CAP(PHM_PlatformCaps_StablePState)) { + stable_pstate_sclk_dpm_percentage = + data->registry_data.stable_pstate_sclk_dpm_percentage; PP_ASSERT_WITH_CODE( data->registry_data.stable_pstate_sclk_dpm_percentage >= 1 && data->registry_data.stable_pstate_sclk_dpm_percentage <= 100, -- cgit v1.2.3 From 40a9960b046290939b56ce8e51f365258f27f264 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 30 Sep 2017 11:13:28 +0300 Subject: drm/amdgpu: potential uninitialized variable in amdgpu_vce_ring_parse_cs() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We shifted some code around in commit 9cca0b8e5df0 ("drm/amdgpu: move amdgpu_cs_sysvm_access_required into find_mapping") and now my static checker complains that "r" might not be initialized at the end of the function. I've reviewed the code, and that seems possible, but it's also possible I may have missed something. Reviewed-by: Christian König Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index b46280c1279f..2918de2f39ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -648,7 +648,7 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) uint32_t allocated = 0; uint32_t tmp, handle = 0; uint32_t *size = &tmp; - int i, r, idx = 0; + int i, r = 0, idx = 0; p->job->vm = NULL; ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo); -- cgit v1.2.3 From 78aa02c713fcf19e9bc8511ab61a5fd6c877cc01 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 30 Sep 2017 11:14:13 +0300 Subject: drm/amdgpu: Potential uninitialized variable in amdgpu_vm_update_directories() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit ea09729c9302 ("drm/amdgpu: rework page directory filling v2") then it becomes a lot harder to verify that "r" is initialized. My static checker complains and so I've reviewed the code. It does look like it might be buggy... Anyway, it doesn't hurt to set "r" to zero at the start. Reviewed-by: Christian König Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 010d14195a5e..c8c26f21993c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1244,7 +1244,7 @@ static void amdgpu_vm_invalidate_level(struct amdgpu_vm *vm, int amdgpu_vm_update_directories(struct amdgpu_device *adev, struct amdgpu_vm *vm) { - int r; + int r = 0; spin_lock(&vm->status_lock); while (!list_empty(&vm->relocated)) { -- cgit v1.2.3 From dce1e131dd4dc68099ff1b70aa03cd2d0acf8639 Mon Sep 17 00:00:00 2001 From: Pixel Ding Date: Wed, 8 Nov 2017 10:20:01 +0800 Subject: drm/amdgpu: bypass lru touch for KIQ ring submission MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KIQ ring submission is used for register accessing on SRIOV VF that could happen both in irq enabled and irq disabled cases. Inversion lock could happen on adev->ring_lru_list_lock, while this operation is useless and just adds overhead in this use case. Signed-off-by: Pixel Ding Reviewed-by: Monk Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index e5ece1fae149..a98fbbb4739f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -136,7 +136,8 @@ void amdgpu_ring_commit(struct amdgpu_ring *ring) if (ring->funcs->end_use) ring->funcs->end_use(ring); - amdgpu_ring_lru_touch(ring->adev, ring); + if (ring->funcs->type != AMDGPU_RING_TYPE_KIQ) + amdgpu_ring_lru_touch(ring->adev, ring); } /** -- cgit v1.2.3 From cdd9a8b8599b952e2b39763090689ec2ad8e40c3 Mon Sep 17 00:00:00 2001 From: pding Date: Tue, 7 Nov 2017 14:32:36 +0800 Subject: drm/amdgpu: use irq-safe lock for kiq->ring_lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This lock is used during register accessing in SRIOV guest. The register accessing could happen both in irq enabled and irq disabled cases. Always use irq-safe lock. Signed-off-by: Pixel Ding Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 4e4a476593e8..6738df836a70 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -114,18 +114,19 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev) uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) { signed long r; + unsigned long flags; uint32_t val, seq; struct amdgpu_kiq *kiq = &adev->gfx.kiq; struct amdgpu_ring *ring = &kiq->ring; BUG_ON(!ring->funcs->emit_rreg); - spin_lock(&kiq->ring_lock); + spin_lock_irqsave(&kiq->ring_lock, flags); amdgpu_ring_alloc(ring, 32); amdgpu_ring_emit_rreg(ring, reg); amdgpu_fence_emit_polling(ring, &seq); amdgpu_ring_commit(ring); - spin_unlock(&kiq->ring_lock); + spin_unlock_irqrestore(&kiq->ring_lock, flags); r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); if (r < 1) { @@ -140,18 +141,19 @@ uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) { signed long r; + unsigned long flags; uint32_t seq; struct amdgpu_kiq *kiq = &adev->gfx.kiq; struct amdgpu_ring *ring = &kiq->ring; BUG_ON(!ring->funcs->emit_wreg); - spin_lock(&kiq->ring_lock); + spin_lock_irqsave(&kiq->ring_lock, flags); amdgpu_ring_alloc(ring, 32); amdgpu_ring_emit_wreg(ring, reg, v); amdgpu_fence_emit_polling(ring, &seq); amdgpu_ring_commit(ring); - spin_unlock(&kiq->ring_lock); + spin_unlock_irqrestore(&kiq->ring_lock, flags); r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); if (r < 1) -- cgit v1.2.3 From 5d266692372dfb412150006df420185b666658f9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Oct 2017 22:32:36 +0100 Subject: drm/i915: Filter out spurious execlists context-switch interrupts Back in commit a4b2b01523a8 ("drm/i915: Don't mark an execlists context-switch when idle") we noticed the presence of late context-switch interrupts. We were able to filter those out by looking at whether the ELSP remained active, but in commit beecec901790 ("drm/i915/execlists: Preemption!") that became problematic as we now anticipate receiving a context-switch event for preemption while ELSP may be empty. To restore the spurious interrupt suppression, add a counter for the expected number of pending context-switches and skip if we do not need to handle this interrupt to make forward progress. v2: Don't forget to switch on for preempt. v3: Reduce the counter to a on/off boolean tracker. Declare the HW as active when we first submit, and idle after the final completion event (with which we confirm the HW says it is idle), and track each source of activity separately. With a finite number of sources, it should aide us in debugging which gets stuck. Fixes: beecec901790 ("drm/i915/execlists: Preemption!") Signed-off-by: Chris Wilson Cc: Michal Winiarski Cc: Tvrtko Ursulin Cc: Arkadiusz Hiler Cc: Mika Kuoppala Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171023213237.26536-3-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala (cherry picked from commit 4a118ecbe99c93cf9f9582e83a88d03f18d6cb84) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_guc_submission.c | 3 +++ drivers/gpu/drm/i915/i915_irq.c | 6 ++++-- drivers/gpu/drm/i915/intel_engine_cs.c | 5 +++-- drivers/gpu/drm/i915/intel_lrc.c | 27 ++++++++++++++++++------ drivers/gpu/drm/i915/intel_ringbuffer.h | 34 ++++++++++++++++++++++++++++-- 5 files changed, 62 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index a2e8114b739d..f84c267728fd 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -610,6 +610,7 @@ done: execlists->first = rb; if (submit) { port_assign(port, last); + execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); i915_guc_submit(engine); } spin_unlock_irq(&engine->timeline->lock); @@ -633,6 +634,8 @@ static void i915_guc_irq_handler(unsigned long data) rq = port_request(&port[0]); } + if (!rq) + execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); if (!port_isset(last_port)) i915_guc_dequeue(engine); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b1296a55c1e4..f8205841868b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1388,8 +1388,10 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) bool tasklet = false; if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) { - __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); - tasklet = true; + if (READ_ONCE(engine->execlists.active)) { + __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); + tasklet = true; + } } if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) { diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index a47a9c6bea52..ab5bf4e2e28e 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1548,8 +1548,8 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine) if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) return false; - /* Both ports drained, no more ELSP submission? */ - if (port_request(&engine->execlists.port[0])) + /* Waiting to drain ELSP? */ + if (READ_ONCE(engine->execlists.active)) return false; /* ELSP is empty, but there are ready requests? */ @@ -1749,6 +1749,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) idx); } } + drm_printf(m, "\t\tHW active? 0x%x\n", execlists->active); rcu_read_unlock(); } else if (INTEL_GEN(dev_priv) > 6) { drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n", diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7f45dd7dc3e5..5b87d5284a84 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -575,7 +575,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) * the state of the GPU is known (idle). */ inject_preempt_context(engine); - execlists->preempt = true; + execlists_set_active(execlists, + EXECLISTS_ACTIVE_PREEMPT); goto unlock; } else { /* @@ -683,8 +684,10 @@ done: unlock: spin_unlock_irq(&engine->timeline->lock); - if (submit) + if (submit) { + execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); execlists_submit_ports(engine); + } } static void @@ -696,6 +699,7 @@ execlist_cancel_port_requests(struct intel_engine_execlists *execlists) while (num_ports-- && port_isset(port)) { struct drm_i915_gem_request *rq = port_request(port); + GEM_BUG_ON(!execlists->active); execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_PREEMPTED); i915_gem_request_put(rq); @@ -861,15 +865,21 @@ static void intel_lrc_irq_handler(unsigned long data) unwind_incomplete_requests(engine); spin_unlock_irq(&engine->timeline->lock); - GEM_BUG_ON(!execlists->preempt); - execlists->preempt = false; + GEM_BUG_ON(!execlists_is_active(execlists, + EXECLISTS_ACTIVE_PREEMPT)); + execlists_clear_active(execlists, + EXECLISTS_ACTIVE_PREEMPT); continue; } if (status & GEN8_CTX_STATUS_PREEMPTED && - execlists->preempt) + execlists_is_active(execlists, + EXECLISTS_ACTIVE_PREEMPT)) continue; + GEM_BUG_ON(!execlists_is_active(execlists, + EXECLISTS_ACTIVE_USER)); + /* Check the context/desc id for this event matches */ GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); @@ -892,6 +902,9 @@ static void intel_lrc_irq_handler(unsigned long data) /* After the final element, the hw should be idle */ GEM_BUG_ON(port_count(port) == 0 && !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); + if (port_count(port) == 0) + execlists_clear_active(execlists, + EXECLISTS_ACTIVE_USER); } if (head != execlists->csb_head) { @@ -901,7 +914,7 @@ static void intel_lrc_irq_handler(unsigned long data) } } - if (!execlists->preempt) + if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)) execlists_dequeue(engine); intel_uncore_forcewake_put(dev_priv, execlists->fw_domains); @@ -1460,7 +1473,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift); clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); execlists->csb_head = -1; - execlists->preempt = false; + execlists->active = 0; /* After a GPU reset, we may have requests to replay */ if (!i915_modparams.enable_guc_submission && execlists->first) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 17186f067408..6a42ed618a28 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -241,9 +241,17 @@ struct intel_engine_execlists { } port[EXECLIST_MAX_PORTS]; /** - * @preempt: are we currently handling a preempting context switch? + * @active: is the HW active? We consider the HW as active after + * submitting any context for execution and until we have seen the + * last context completion event. After that, we do not expect any + * more events until we submit, and so can park the HW. + * + * As we have a small number of different sources from which we feed + * the HW, we track the state of each inside a single bitfield. */ - bool preempt; + unsigned int active; +#define EXECLISTS_ACTIVE_USER 0 +#define EXECLISTS_ACTIVE_PREEMPT 1 /** * @port_mask: number of execlist ports - 1 @@ -525,6 +533,27 @@ struct intel_engine_cs { u32 (*get_cmd_length_mask)(u32 cmd_header); }; +static inline void +execlists_set_active(struct intel_engine_execlists *execlists, + unsigned int bit) +{ + __set_bit(bit, (unsigned long *)&execlists->active); +} + +static inline void +execlists_clear_active(struct intel_engine_execlists *execlists, + unsigned int bit) +{ + __clear_bit(bit, (unsigned long *)&execlists->active); +} + +static inline bool +execlists_is_active(const struct intel_engine_execlists *execlists, + unsigned int bit) +{ + return test_bit(bit, (unsigned long *)&execlists->active); +} + static inline unsigned int execlists_num_ports(const struct intel_engine_execlists * const execlists) { @@ -538,6 +567,7 @@ execlists_port_complete(struct intel_engine_execlists * const execlists, const unsigned int m = execlists->port_mask; GEM_BUG_ON(port_index(port, execlists) != 0); + GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_USER)); memmove(port, port + 1, m * sizeof(struct execlist_port)); memset(port + m, 0, sizeof(struct execlist_port)); -- cgit v1.2.3 From a2487174af332f46456048f96ddd2a8c28a3839e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 24 Oct 2017 12:55:01 +0100 Subject: drm/i915/execlists: Remove the priority "optimisation" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Originally we set the priority to max upon inserting the request into the execlists queue (and removing it from the scheduler lists). We could then use the prio==INT_MAX as a shortcut within execlists_schedule() to detect the end of the dependency chain. Since commit 1f181225f8ec ("drm/i915/execlists: Keep request->priority for its lifetime") this is no longer true as we use the request completion as an indicator the schedule dependency chain is complete instead. (This allows us to then reschedule requests even when its context is in flight.) However, this makes the GEM_BUG_ON() inside execlists_schedule() racy as we may change the rq->prio at the same time. As the assertion is useful, let's keep the assertion and remove the micro-optimisation. Fixes: 1f181225f8ec ("drm/i915/execlists: Keep request->priority for its lifetime") Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171024115501.21033-1-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski (cherry picked from commit 64b80085dd3603d401fc05879f700b86a3a5c8e8) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_lrc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5b87d5284a84..d36e25607435 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -734,7 +734,6 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) list_for_each_entry_safe(rq, rn, &p->requests, priotree.link) { INIT_LIST_HEAD(&rq->priotree.link); - rq->priotree.priority = INT_MAX; dma_fence_set_error(&rq->fence, -EIO); __i915_gem_request_submit(rq); @@ -891,7 +890,6 @@ static void intel_lrc_irq_handler(unsigned long data) execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); trace_i915_gem_request_out(rq); - rq->priotree.priority = INT_MAX; i915_gem_request_put(rq); execlists_port_complete(execlists, port); -- cgit v1.2.3 From b58d4bef1070c6ca57008756d86f79a687d2bbea Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Mon, 23 Oct 2017 18:32:09 +0300 Subject: drm/i915: Disable lazy PPGTT page table optimization for vGPU When running under virtualization (vGPU active), we must disable the lazy PPGTT page table initialization optimization introduced by commit 14826673247e ("drm/i915: Only initialize partially filled pagetables"). We must do this because GVT-g makes unduly assumptions about guest behaviour, which this optimization breaks. This results in following looking errors in the host: ERROR gvt: guest page write error -22, gfn 0x7ada8, pa 0x7ada89a8, var 0x6, len 1 The real fix is to not to depend on i915 driver behaviour, but instead either rely on only the contracts that i915 has with the hardware, or add some paravirtualization. While the real fix is en route, it won't be finished in time for 4.15, so the best option is to disable the optimization for now when vGPU is active to avoid breaking 4.15 guests in existing VM environments. Fixes: 14826673247e ("drm/i915: Only initialize partially filled pagetables") Suggested-by: Xiaolin Zhang Signed-off-by: Xiaolin Zhang [Joonas: Rewrote the commit message and added tags.] Signed-off-by: Joonas Lahtinen Cc: Zhenyu Wang Cc: Zhi Wang Cc: Chris Wilson Cc: Matthew Auld Cc: Joonas Lahtinen Cc: Jani Nikula Cc: Rodrigo Vivi Acked-by: Chris Wilson Acked-by: Zhenyu Wang Link: https://patchwork.freedesktop.org/patch/msgid/20171023153209.10527-1-joonas.lahtinen@linux.intel.com (cherry picked from commit 22a8a4fc93b14b5a8cfc785edbdc6f7bd98bffb6) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 527a2d2d6281..5eaa6893daaa 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1341,7 +1341,7 @@ static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm, if (IS_ERR(pt)) goto unwind; - if (count < GEN8_PTES) + if (count < GEN8_PTES || intel_vgpu_active(vm->i915)) gen8_initialize_pt(vm, pt); gen8_ppgtt_set_pde(vm, pd, pt, pde); -- cgit v1.2.3 From 90c702b88e5b5bbe2be53848aa3aba7c2b64223f Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 19 Oct 2017 17:13:41 +0200 Subject: drm/i915: Calculate ironlake intermediate watermarks correctly, v2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The watermarks it should calculate against are the old optimal watermarks. The currently active crtc watermarks are pure fiction, and are invalid in case of a nonblocking modeset, page flip enabling/disabling planes or any other reason. When the crtc is disabled or during a modeset the intermediate watermarks don't need to be programmed separately, and could be directly assigned to the optimal watermarks. Changes since v1: - Use intel_atomic_get_old_crtc_state. (ville) Signed-off-by: Maarten Lankhorst Reviewed-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20171019151341.4579-2-maarten.lankhorst@linux.intel.com [mlankhorst: Add cc stable and bugzilla link, since previous patch doesn't fix issue by itself] Cc: stable@vger.kernel.org #v4.8+ Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102373 (cherry picked from commit b6b178a77210055b153dbc175e4468bd3c7122df) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_pm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c42a65a93b3a..7d2ecabc5de5 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3133,7 +3133,11 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev, struct intel_crtc_state *newstate) { struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate; - struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk; + struct intel_atomic_state *intel_state = + to_intel_atomic_state(newstate->base.state); + const struct intel_crtc_state *oldstate = + intel_atomic_get_old_crtc_state(intel_state, intel_crtc); + const struct intel_pipe_wm *b = &oldstate->wm.ilk.optimal; int level, max_level = ilk_wm_max_level(to_i915(dev)); /* @@ -3142,6 +3146,9 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev, * and after the vblank. */ *a = newstate->wm.ilk.optimal; + if (!newstate->base.active || drm_atomic_crtc_needs_modeset(&newstate->base)) + return 0; + a->pipe_enabled |= b->pipe_enabled; a->sprites_enabled |= b->sprites_enabled; a->sprites_scaled |= b->sprites_scaled; -- cgit v1.2.3 From 0f763ff370a538c07f8f266a787ebc1a63d5c7dc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Nov 2017 11:15:08 +0000 Subject: drm/i915: Lock llist_del_first() vs llist_del_all() An oversight in commit 87701b4b5593 ("drm/i915: Only free the oldest stale object before a fresh allocation") was that not only do we have to serialise concurrent users of llist_del_first(), but we also have to lock llist_del_first() vs llist_del_all(). From llist.h, * This can be summarized as follows: * * | add | del_first | del_all * add | - | - | - * del_first | | L | L * del_all | | | - * * Where, a particular row's operation can happen concurrently with a column's * operation, with "-" being no lock needed, while "L" being lock is needed. This should hopefully explain: <4>[ 89.287106] general protection fault: 0000 [#1] PREEMPT SMP <4>[ 89.287126] Modules linked in: snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal intel_powerclamp coretemp i915 crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core r8169 mii mei_me mei snd_pcm prime_numbers i2c_hid pinctrl_geminilake pinctrl_intel <4>[ 89.287226] CPU: 2 PID: 23 Comm: ksoftirqd/2 Tainted: G U 4.14.0-rc8-CI-CI_DRM_3315+ #1 <4>[ 89.287247] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017 <4>[ 89.287270] task: ffff88017ab34ec0 task.stack: ffffc90000128000 <4>[ 89.287290] RIP: 0010:llist_add_batch+0x4/0x20 <4>[ 89.287301] RSP: 0018:ffffc9000012bdb8 EFLAGS: 00010296 <4>[ 89.287314] RAX: ffffffff811017ad RBX: 6e468801a1560000 RCX: ef3e53fceecdeb81 <4>[ 89.287330] RDX: 6e468801a1566130 RSI: ffff880103d73d98 RDI: ffff880103d73d98 <4>[ 89.287346] RBP: ffffc9000012bdb8 R08: ffff88017ab35780 R09: 0000000000000000 <4>[ 89.287361] R10: ffffc9000012bd68 R11: 00000000abb18c3d R12: ffffffffa01369e0 <4>[ 89.287377] R13: ffff88017fd1b8f8 R14: ffff88017ab34ec0 R15: 000000000000000a <4>[ 89.287393] FS: 0000000000000000(0000) GS:ffff88017fd00000(0000) knlGS:0000000000000000 <4>[ 89.287411] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4>[ 89.287424] CR2: 00007ff0c0755018 CR3: 000000016df9b000 CR4: 00000000003406e0 <4>[ 89.287440] Call Trace: <4>[ 89.287511] __i915_gem_free_object_rcu+0x20/0x40 [i915] <4>[ 89.287527] rcu_process_callbacks+0x27a/0x730 <4>[ 89.287544] __do_softirq+0xc0/0x4ae <4>[ 89.287559] ? smpboot_thread_fn+0x2d/0x280 <4>[ 89.287571] run_ksoftirqd+0x1f/0x70 <4>[ 89.287582] smpboot_thread_fn+0x18a/0x280 <4>[ 89.287595] kthread+0x114/0x150 <4>[ 89.287605] ? sort_range+0x30/0x30 <4>[ 89.287615] ? kthread_create_on_node+0x40/0x40 <4>[ 89.287628] ret_from_fork+0x27/0x40 <4>[ 89.287641] Code: 0d 48 83 ea 01 4c 89 c1 48 83 fa ff 74 12 48 23 0c d7 74 ed 48 c1 e2 06 48 0f bd c9 48 8d 04 0a 5d c3 90 90 90 90 90 55 48 89 e5 <48> 8b 0a 48 89 0e 48 89 c8 f0 48 0f b1 3a 48 39 c1 75 ed 48 85 <1>[ 89.287774] RIP: llist_add_batch+0x4/0x20 RSP: ffffc9000012bdb8 <4>[ 89.287826] ---[ end trace e775d15174d8ae02 ]--- (Lockless lists are only easy (and lockless) when only using llist_add/llist_del_all!) Fixes: 87701b4b5593 ("drm/i915: Only free the oldest stale object before a fresh allocation") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171106111508.11941-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala (cherry picked from commit f991c492aa55fb1c6834882c5d786d5bb3b25f07) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 026cb52ece0b..94b23fcbc989 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4603,11 +4603,17 @@ static void __i915_gem_free_work(struct work_struct *work) * unbound now. */ + spin_lock(&i915->mm.free_lock); while ((freed = llist_del_all(&i915->mm.free_list))) { + spin_unlock(&i915->mm.free_lock); + __i915_gem_free_objects(i915, freed); if (need_resched()) - break; + return; + + spin_lock(&i915->mm.free_lock); } + spin_unlock(&i915->mm.free_lock); } static void __i915_gem_free_object_rcu(struct rcu_head *head) -- cgit v1.2.3 From 0676e79415a1e1a2186ba2529abad3d3329bea95 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Nov 2017 09:44:00 +0000 Subject: drm/i915: Idle the GPU before shinking everything The handling of contexts are peculiar. Instead of tieing their vma to activity, we pin the context. This means that we cannot simply unbind the context object itself at will (which would normally cause us to wait for the vma to be idle), but must manually idle the GPU and retire requests first. A consequence of this peculiarity is when doing a last desperate attempt to recover memory. If the memory is tied up inside active context objects, we will fail to recover any memory simply by trying to unbind the objects without first doing a wait-for-idle. A side-effect of removing the call to shrinker_lock_uninterruptible() from i915_gem_shrinker_oom() was that we removed an unlocked wait-for-idle, and so lost the "natural" shrinkage of context objects. By replacing that with a locked wait from inside i915_gem_shrink(), we not only replace it with the ability to recover all context objects, but do so for all i915_gem_shrink_all() callers. v2: Switching requires request allocation, which is not permitted from inside the shrinker as it only uses ordinary allocations. References: https://bugs.freedesktop.org/show_bug.cgi?id=102936 Fixes: f2123818ffad ("drm/i915: Move dev_priv->mm.[un]bound_list to its own lock") Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171108094400.1386-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen (cherry picked from commit 2f6a3783833dde63f1c08982943a8b2229b97afb) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_shrinker.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index eb31f8aa5c21..3770e3323fc8 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -162,6 +162,18 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, if (!shrinker_lock(dev_priv, &unlock)) return 0; + /* + * When shrinking the active list, also consider active contexts. + * Active contexts are pinned until they are retired, and so can + * not be simply unbound to retire and unpin their pages. To shrink + * the contexts, we must wait until the gpu is idle. + * + * We don't care about errors here; if we cannot wait upon the GPU, + * we will free as much as we can and hope to get a second chance. + */ + if (flags & I915_SHRINK_ACTIVE) + i915_gem_wait_for_idle(dev_priv, I915_WAIT_LOCKED); + trace_i915_gem_shrink(dev_priv, target, flags); i915_gem_retire_requests(dev_priv); -- cgit v1.2.3 From 398c13b9632027d044a0ab41538743214284c2a2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 7 Nov 2017 22:06:56 +0000 Subject: drm/i915: Prune the reservation shared fence array The shared fence array is not autopruning and may continue to grow as an object is shared between new timelines. Take the opportunity when we think the object is idle (we have to confirm that any external fence is also signaled) to decouple all the fences. We apply a similar trick after waiting on an object, see commit e54ca9774777 ("drm/i915: Remove completed fences after a wait") v2: No longer need to handle the batch pool as a special case. v3: Need to trylock from within i915_vma_retire as this may be called form the shrinker - and we may later try to allocate underneath the reservation lock, so a deadlock is possible. References: https://bugs.freedesktop.org/show_bug.cgi?id=102936 Fixes: d07f0e59b2c7 ("drm/i915: Move GEM activity tracking into a common struct reservation_object") Fixes: 80b204bce8f2 ("drm/i915: Enable multiple timelines") Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20171107220656.5020-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen (cherry picked from commit 1ab22356b37ab08a391d6f007fda4c822bef9fb5) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_vma.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index fc77e8191eb5..fbfab2f33023 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -54,6 +54,13 @@ i915_vma_retire(struct i915_gem_active *active, if (--obj->active_count) return; + /* Prune the shared fence arrays iff completely idle (inc. external) */ + if (reservation_object_trylock(obj->resv)) { + if (reservation_object_test_signaled_rcu(obj->resv, true)) + reservation_object_add_excl_fence(obj->resv, NULL); + reservation_object_unlock(obj->resv); + } + /* Bump our place on the bound list to keep it roughly in LRU order * so that we don't steal from recently used but inactive objects * (unless we are forced to ofc!) -- cgit v1.2.3 From 6ac43272768ca901daac4076a66c2c4e3c7b9321 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 8 Nov 2017 15:35:55 +0200 Subject: drm/i915: Move init_clock_gating() back to where it was MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently setting up a bunch of GT registers before we've properly initialized the rest of the GT hardware leads to these setting being lost. So looks like I broke HSW with commit b7048ea12fbb ("drm/i915: Do .init_clock_gating() earlier to avoid it clobbering watermarks") by doing init_clock_gating() too early. This should actually affect other platforms as well, but apparently not to such a great degree. What I was ultimately after in that commit was to move the ilk_init_lp_watermarks() call earlier. So let's undo the damage and move init_clock_gating() back to where it was, and call ilk_init_lp_watermarks() just before the watermark state readout. This highlights how fragile and messed up our init order really is. I wonder why we even initialize the display before gem. The opposite order would make much more sense to me... v2: Keep WaRsPkgCStateDisplayPMReq:hsw early as it really must be done before all planes might get disabled. Cc: stable@vger.kernel.org Cc: Chris Wilson Cc: Mark Janes Cc: Maarten Lankhorst Cc: Daniel Vetter Cc: Joonas Lahtinen Cc: Oscar Mateo Cc: Mika Kuoppala Reported-by: Mark Janes Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103549 Fixes: b7048ea12fbb ("drm/i915: Do .init_clock_gating() earlier to avoid it clobbering watermarks") References: https://lists.freedesktop.org/archives/intel-gfx/2017-November/145432.html Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171108133555.14091-1-ville.syrjala@linux.intel.com Tested-by: Chris Wilson Reviewed-by: Chris Wilson (cherry picked from commit f72b84c677d61f201b869223a8d6e389c7bb7d3d) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 14 ++++++++++-- drivers/gpu/drm/i915/intel_pm.c | 44 +++++++++++++++--------------------- 2 files changed, 30 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e2ac976844d8..f4a9a182868f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3676,6 +3676,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) intel_pps_unlock_regs_wa(dev_priv); intel_modeset_init_hw(dev); + intel_init_clock_gating(dev_priv); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display.hpd_irq_setup) @@ -14350,8 +14351,6 @@ void intel_modeset_init_hw(struct drm_device *dev) intel_update_cdclk(dev_priv); dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw; - - intel_init_clock_gating(dev_priv); } /* @@ -15063,6 +15062,15 @@ intel_modeset_setup_hw_state(struct drm_device *dev, struct intel_encoder *encoder; int i; + if (IS_HASWELL(dev_priv)) { + /* + * WaRsPkgCStateDisplayPMReq:hsw + * System hang if this isn't done before disabling all planes! + */ + I915_WRITE(CHICKEN_PAR1_1, + I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES); + } + intel_modeset_readout_hw_state(dev); /* HW state is read out, now we need to sanitize this mess. */ @@ -15160,6 +15168,8 @@ void intel_modeset_gem_init(struct drm_device *dev) intel_init_gt_powersave(dev_priv); + intel_init_clock_gating(dev_priv); + intel_setup_overlay(dev_priv); } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7d2ecabc5de5..aa12a44e9a76 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5762,12 +5762,30 @@ void vlv_wm_sanitize(struct drm_i915_private *dev_priv) mutex_unlock(&dev_priv->wm.wm_mutex); } +/* + * FIXME should probably kill this and improve + * the real watermark readout/sanitation instead + */ +static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) +{ + I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN); + I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN); + I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); + + /* + * Don't touch WM1S_LP_EN here. + * Doing so could cause underruns. + */ +} + void ilk_wm_get_hw_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); struct ilk_wm_values *hw = &dev_priv->wm.hw; struct drm_crtc *crtc; + ilk_init_lp_watermarks(dev_priv); + for_each_crtc(dev, crtc) ilk_pipe_wm_get_hw_state(crtc); @@ -8214,18 +8232,6 @@ static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) } } -static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) -{ - I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN); - I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN); - I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); - - /* - * Don't touch WM1S_LP_EN here. - * Doing so could cause underruns. - */ -} - static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) { uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; @@ -8259,8 +8265,6 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) (I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS)); - ilk_init_lp_watermarks(dev_priv); - /* * Based on the document from hardware guys the following bits * should be set unconditionally in order to enable FBC. @@ -8373,8 +8377,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_GT_MODE, _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); - ilk_init_lp_watermarks(dev_priv); - I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); @@ -8601,8 +8603,6 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) I915_GTT_PAGE_SIZE_2M); enum pipe pipe; - ilk_init_lp_watermarks(dev_priv); - /* WaSwitchSolVfFArbitrationPriority:bdw */ I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); @@ -8653,8 +8653,6 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) { - ilk_init_lp_watermarks(dev_priv); - /* L3 caching of data atomics doesn't work -- disable it. */ I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); I915_WRITE(HSW_ROW_CHICKEN3, @@ -8698,10 +8696,6 @@ static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) /* WaSwitchSolVfFArbitrationPriority:hsw */ I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); - /* WaRsPkgCStateDisplayPMReq:hsw */ - I915_WRITE(CHICKEN_PAR1_1, - I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES); - lpt_init_clock_gating(dev_priv); } @@ -8709,8 +8703,6 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) { uint32_t snpcr; - ilk_init_lp_watermarks(dev_priv); - I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); /* WaDisableEarlyCull:ivb */ -- cgit v1.2.3 From e8c49fa96838101435b9e4884d49b30da7a4e0c6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 9 Nov 2017 08:55:40 +0000 Subject: drm/i915: Reorder context-close to avoid calling i915_vma_close() under RCU When we close the VMA, we unbind it from the ppgtt and tear down the page directory pointing at it. That may trigger us to return WC pages back to the system, requiring conversion back to WB which itself may sleep. That makes i915_vma_close() unsuitable for use inside the RCU read lock, which we need to hold to iterate the radixtree. The fix is quite simple, we can close all the VMA as we close the ppgtt, we only need to do that instead of closing them during destruction of the LUT. v2: Order between closing the LUT and the ppgtt is important; we use the vma inside the LUT as a means of retrieving the object, and so we must clear the LUT before freeing the VMA when closing the ppgtt. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103638 Fixes: 547da76b5777 ("drm/i915: Hold rcu_read_lock when iterating over the radixtree (vma idr)") Fixes: d1b48c1e7184 ("drm/i915: Replace execbuf vma ht with an idr") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Cc: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20171109085540.32264-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin (cherry picked from commit 94dec87159af6f3dcc0b78d3f909aefa9e29c01a) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_context.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5bf96a258509..e304dcbc6042 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -106,14 +106,9 @@ static void lut_close(struct i915_gem_context *ctx) radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) { struct i915_vma *vma = rcu_dereference_raw(*slot); - struct drm_i915_gem_object *obj = vma->obj; radix_tree_iter_delete(&ctx->handles_vma, &iter, slot); - - if (!i915_vma_is_ggtt(vma)) - i915_vma_close(vma); - - __i915_gem_object_release_unless_active(obj); + __i915_gem_object_release_unless_active(vma->obj); } } @@ -198,6 +193,11 @@ static void context_close(struct i915_gem_context *ctx) { i915_gem_context_set_closed(ctx); + /* + * The LUT uses the VMA as a backpointer to unref the object, + * so we need to clear the LUT before we close all the VMA (inside + * the ppgtt). + */ lut_close(ctx); if (ctx->ppgtt) i915_ppgtt_close(&ctx->ppgtt->base); -- cgit v1.2.3 From e7e62c7ef382f5db0de5e492e558efc9c3d60943 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 9 Nov 2017 09:35:04 +1000 Subject: drm/mode_object: fix documentation for object lookups. The lease updates missed a few bits of docs, fixed up the wrong name on the property lookup fn as well. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_framebuffer.c | 1 + drivers/gpu/drm/drm_mode_object.c | 1 + include/drm/drm_connector.h | 1 + include/drm/drm_crtc.h | 1 + include/drm/drm_encoder.h | 1 + include/drm/drm_plane.h | 1 + include/drm/drm_property.h | 3 ++- 7 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 2affe53f3fda..279c1035c12d 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -681,6 +681,7 @@ EXPORT_SYMBOL(drm_framebuffer_init); /** * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference * @dev: drm device + * @file_priv: drm file to check for lease against. * @id: id of the fb object * * If successful, this grabs an additional reference to the framebuffer - diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 7c8b2698c6a7..ce4d2fb32810 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -151,6 +151,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, /** * drm_mode_object_find - look up a drm object with static lifetime + * @dev: drm device * @file_priv: drm file * @id: id of the mode object * @type: type of the mode object diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index b4285c40e1e4..7a7140543012 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -933,6 +933,7 @@ static inline unsigned drm_connector_index(struct drm_connector *connector) /** * drm_connector_lookup - lookup connector object * @dev: DRM device + * @file_priv: drm file to check for lease against. * @id: connector object id * * This function looks up the connector object specified by id diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f7fcceef46d9..a2d81d2907a9 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -952,6 +952,7 @@ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx); /** * drm_crtc_find - look up a CRTC object from its ID * @dev: DRM device + * @file_priv: drm file to check for lease against. * @id: &drm_mode_object ID * * This can be used to look up a CRTC from its userspace ID. Only used by diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 86db0da8bdcb..ee4cfbe63c52 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -208,6 +208,7 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, /** * drm_encoder_find - find a &drm_encoder * @dev: DRM device + * @file_priv: drm file to check for lease against. * @id: encoder id * * Returns the encoder with @id, NULL if it doesn't exist. Simple wrapper around diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 069c4c8ce360..571615079230 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -591,6 +591,7 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane, /** * drm_plane_find - find a &drm_plane * @dev: DRM device + * @file_priv: drm file to check for lease against. * @id: plane id * * Returns the plane with @id, NULL if it doesn't exist. Simple wrapper around diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h index 429d8218f740..8a522b4bed40 100644 --- a/include/drm/drm_property.h +++ b/include/drm/drm_property.h @@ -305,8 +305,9 @@ drm_property_unreference_blob(struct drm_property_blob *blob) } /** - * drm_connector_find - find property object + * drm_property_find - find property object * @dev: DRM device + * @file_priv: drm file to check for lease against. * @id: property object id * * This function looks up the property object specified by id and returns it. -- cgit v1.2.3 From 44419ce7d77e03692ed8fe799688d8dc43f9266e Mon Sep 17 00:00:00 2001 From: Emil Renner Berthing Date: Wed, 4 Oct 2017 19:53:46 +0200 Subject: drm/rockchip: analogix_dp: Use mutex rather than spinlock On the Samsung Chromebook Plus I get this error with 4.14-rc3: BUG: scheduling while atomic: kworker/3:1/50/0x00000002 Modules linked in: CPU: 3 PID: 50 Comm: kworker/3:1 Not tainted 4.14.0-0.rc3-kevin #2 Hardware name: Google Kevin (DT) Workqueue: events analogix_dp_psr_work Call trace: [] dump_backtrace+0x0/0x320 [] show_stack+0x14/0x20 [] dump_stack+0x9c/0xbc [] __schedule_bug+0x4c/0x70 [] __schedule+0x3f0/0x458 [] schedule+0x38/0xa0 [] schedule_hrtimeout_range_clock+0x84/0xe8 [] schedule_hrtimeout_range+0x10/0x18 [] usleep_range+0x64/0x78 [] analogix_dp_transfer+0x16c/0x340 [] analogix_dpaux_transfer+0x10/0x18 [] drm_dp_dpcd_access+0x4c/0xf0 [] drm_dp_dpcd_write+0x1c/0x28 [] analogix_dp_disable_psr+0x60/0xa8 [] analogix_dp_psr_work+0x4c/0x90 [] process_one_work+0x1d4/0x348 [] worker_thread+0x48/0x478 [] kthread+0x12c/0x130 [] ret_from_fork+0x10/0x18 Changing rockchip_dp_device::psr_lock to a mutex rather than spinlock seems to fix the issue. Signed-off-by: Emil Renner Berthing Tested-by: Enric Balletbo i Serra Signed-off-by: Mark Yao Link: https://patchwork.freedesktop.org/patch/msgid/20171004175346.11956-1-kernel@esmil.dk --- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 9606121fa185..d8f72d87ef08 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -72,7 +72,7 @@ struct rockchip_dp_device { struct reset_control *rst; struct work_struct psr_work; - spinlock_t psr_lock; + struct mutex psr_lock; unsigned int psr_state; const struct rockchip_dp_chip_data *data; @@ -83,21 +83,20 @@ struct rockchip_dp_device { static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled) { struct rockchip_dp_device *dp = to_dp(encoder); - unsigned long flags; if (!analogix_dp_psr_supported(dp->dev)) return; dev_dbg(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); - spin_lock_irqsave(&dp->psr_lock, flags); + mutex_lock(&dp->psr_lock); if (enabled) dp->psr_state = EDP_VSC_PSR_STATE_ACTIVE; else dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE; schedule_work(&dp->psr_work); - spin_unlock_irqrestore(&dp->psr_lock, flags); + mutex_unlock(&dp->psr_lock); } static void analogix_dp_psr_work(struct work_struct *work) @@ -105,7 +104,6 @@ static void analogix_dp_psr_work(struct work_struct *work) struct rockchip_dp_device *dp = container_of(work, typeof(*dp), psr_work); int ret; - unsigned long flags; ret = rockchip_drm_wait_vact_end(dp->encoder.crtc, PSR_WAIT_LINE_FLAG_TIMEOUT_MS); @@ -114,12 +112,12 @@ static void analogix_dp_psr_work(struct work_struct *work) return; } - spin_lock_irqsave(&dp->psr_lock, flags); + mutex_lock(&dp->psr_lock); if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE) analogix_dp_enable_psr(dp->dev); else analogix_dp_disable_psr(dp->dev); - spin_unlock_irqrestore(&dp->psr_lock, flags); + mutex_unlock(&dp->psr_lock); } static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) @@ -381,7 +379,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, dp->plat_data.power_off = rockchip_dp_powerdown; dp->plat_data.get_modes = rockchip_dp_get_modes; - spin_lock_init(&dp->psr_lock); + mutex_init(&dp->psr_lock); dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE; INIT_WORK(&dp->psr_work, analogix_dp_psr_work); -- cgit v1.2.3